add feature license management
This commit is contained in:
@@ -745,3 +745,49 @@ func (h *Handler) ListAllInitiatorGroups(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"groups": groups})
|
||||
}
|
||||
|
||||
// GetConfigFile reads the SCST configuration file content
|
||||
func (h *Handler) GetConfigFile(c *gin.Context) {
|
||||
configPath := c.DefaultQuery("path", "/etc/scst.conf")
|
||||
|
||||
content, err := h.service.ReadConfigFile(c.Request.Context(), configPath)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to read config file", "error", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"content": content,
|
||||
"path": configPath,
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateConfigFile writes content to SCST configuration file
|
||||
func (h *Handler) UpdateConfigFile(c *gin.Context) {
|
||||
var req struct {
|
||||
Content string `json:"content" binding:"required"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
|
||||
return
|
||||
}
|
||||
|
||||
configPath := req.Path
|
||||
if configPath == "" {
|
||||
configPath = "/etc/scst.conf"
|
||||
}
|
||||
|
||||
if err := h.service.WriteConfigFile(c.Request.Context(), configPath, req.Content); err != nil {
|
||||
h.logger.Error("Failed to write config file", "error", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Configuration file updated successfully",
|
||||
"path": configPath,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1830,6 +1830,59 @@ func (s *Service) WriteConfig(ctx context.Context, configPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadConfigFile reads the SCST configuration file content
|
||||
func (s *Service) ReadConfigFile(ctx context.Context, configPath string) (string, error) {
|
||||
// First, write current config to temp file to get the actual config
|
||||
tempPath := "/tmp/scst_config_read.conf"
|
||||
cmd := exec.CommandContext(ctx, "sudo", "scstadmin", "-write_config", tempPath)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to write SCST config: %s: %w", string(output), err)
|
||||
}
|
||||
|
||||
// Read the config file
|
||||
configData, err := os.ReadFile(tempPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read config file: %w", err)
|
||||
}
|
||||
|
||||
return string(configData), nil
|
||||
}
|
||||
|
||||
// WriteConfigFile writes content to SCST configuration file
|
||||
func (s *Service) WriteConfigFile(ctx context.Context, configPath string, content string) error {
|
||||
// Write content to temp file first
|
||||
tempPath := "/tmp/scst_config_write.conf"
|
||||
if err := os.WriteFile(tempPath, []byte(content), 0644); err != nil {
|
||||
return fmt.Errorf("failed to write temp config file: %w", err)
|
||||
}
|
||||
|
||||
// Use scstadmin to load the config (this validates and applies it)
|
||||
cmd := exec.CommandContext(ctx, "sudo", "scstadmin", "-config", tempPath)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load SCST config: %s: %w", string(output), err)
|
||||
}
|
||||
|
||||
// Write to the actual config path using sudo
|
||||
if configPath != tempPath {
|
||||
// Use sudo cp to copy temp file to actual config path
|
||||
cpCmd := exec.CommandContext(ctx, "sudo", "cp", tempPath, configPath)
|
||||
cpOutput, cpErr := cpCmd.CombinedOutput()
|
||||
if cpErr != nil {
|
||||
return fmt.Errorf("failed to copy config file: %s: %w", string(cpOutput), cpErr)
|
||||
}
|
||||
// Set proper permissions
|
||||
chmodCmd := exec.CommandContext(ctx, "sudo", "chmod", "644", configPath)
|
||||
if chmodErr := chmodCmd.Run(); chmodErr != nil {
|
||||
s.logger.Warn("Failed to set config file permissions", "error", chmodErr)
|
||||
}
|
||||
}
|
||||
|
||||
s.logger.Info("SCST configuration file written", "path", configPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandlerInfo represents SCST handler information
|
||||
type HandlerInfo struct {
|
||||
Name string `json:"name"`
|
||||
|
||||
Reference in New Issue
Block a user