Swagger-baser server REST API interface
[ric-plt/appmgr.git] / pkg / cm / cm.go
similarity index 51%
rename from cmd/appmgr/desc.go
rename to pkg/cm/cm.go
index 8cc39a5..af5372d 100755 (executable)
@@ -17,7 +17,7 @@
 ==================================================================================
 */
 
-package main
+package cm
 
 import (
        "encoding/json"
@@ -27,52 +27,32 @@ import (
        "github.com/valyala/fastjson"
        "github.com/xeipuuv/gojsonschema"
        "io/ioutil"
-       "log"
        "os"
        "path"
        "regexp"
        "strings"
        "time"
-)
-
-type ConfigMetadata struct {
-       Name       string `json:"name"`
-       ConfigName string `json:"configName, omitempty"`
-       Namespace  string `json:"namespace, omitempty"`
-}
 
-type XAppConfig struct {
-       Metadata      ConfigMetadata `json:"metadata"`
-       Descriptor    interface{}    `json:"descriptor, omitempty"`
-       Configuration interface{}    `json:"config, omitempty"`
-}
-
-type ConfigMap struct {
-       Kind       string      `json:"kind"`
-       ApiVersion string      `json:"apiVersion"`
-       Data       interface{} `json:"data"`
-       Metadata   CMMetadata  `json:"metadata"`
-}
+       "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/appmgr"
+       "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/models"
+       "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/util"
+)
 
-type CMMetadata struct {
-       Name      string `json:"name"`
-       Namespace string `json:"namespace"`
-}
+type CM struct{}
 
-type CMError struct {
-       Field       string `json:"field"`
-       Description string `json:"description"`
+func NewCM() *CM {
+       return &CM{}
 }
 
-func (cm *ConfigMap) UploadConfig() (cfg []XAppConfig) {
+func (cm *CM) UploadConfig() (cfg models.AllXappConfig) {
        ns := cm.GetNamespace("")
        for _, name := range cm.GetNamesFromHelmRepo() {
                if name == "appmgr" {
                        continue
                }
 
-               c := XAppConfig{
-                       Metadata: ConfigMetadata{Name: name, Namespace: ns, ConfigName: cm.GetConfigMapName(name, ns)},
+               c := models.XAppConfig{
+                       Metadata: &models.ConfigMetadata{Name: &name, Namespace: ns, ConfigName: cm.GetConfigMapName(name, ns)},
                }
 
                err := cm.ReadSchema(name, &c)
@@ -80,17 +60,17 @@ func (cm *ConfigMap) UploadConfig() (cfg []XAppConfig) {
                        continue
                }
 
-               err = cm.ReadConfigMap(c.Metadata.ConfigName, ns, &c.Configuration)
+               err = cm.ReadConfigMap(c.Metadata.ConfigName, ns, &c.Config)
                if err != nil {
-                       log.Println("No active configMap found, using default!")
+                       appmgr.Logger.Info("No active configMap found, using default!")
                }
 
-               cfg = append(cfg, c)
+               cfg = append(cfg, &c)
        }
        return
 }
 
-func (cm *ConfigMap) ReadSchema(name string, c *XAppConfig) (err error) {
+func (cm *CM) ReadSchema(name string, c *models.XAppConfig) (err error) {
        if err = cm.FetchChart(name); err != nil {
                return
        }
@@ -101,21 +81,21 @@ func (cm *ConfigMap) ReadSchema(name string, c *XAppConfig) (err error) {
                return
        }
 
-       err = cm.ReadFile(path.Join(tarDir, name, viper.GetString("xapp.config")), &c.Configuration)
+       err = cm.ReadFile(path.Join(tarDir, name, viper.GetString("xapp.config")), &c.Config)
        if err != nil {
                return
        }
 
        if err = os.RemoveAll(path.Join(tarDir, name)); err != nil {
-               log.Println("RemoveAll failed", err)
+               appmgr.Logger.Info("RemoveAll failed: %v", err)
        }
 
        return
 }
 
-func (cm *ConfigMap) ReadConfigMap(ConfigName string, ns string, c *interface{}) (err error) {
+func (cm *CM) ReadConfigMap(ConfigName string, ns string, c *interface{}) (err error) {
        args := fmt.Sprintf("get configmap -o jsonpath='{.data.config-file\\.json}' -n %s %s", ns, ConfigName)
-       configMapJson, err := KubectlExec(args)
+       configMapJson, err := util.KubectlExec(args)
        if err != nil {
                return
        }
@@ -128,46 +108,43 @@ func (cm *ConfigMap) ReadConfigMap(ConfigName string, ns string, c *interface{})
        return
 }
 
-func (cm *ConfigMap) ApplyConfigMap(r XAppConfig, action string) (err error) {
-       c := ConfigMap{
+func (cm *CM) ApplyConfigMap(r models.XAppConfig, action string) (err error) {
+       c := appmgr.ConfigMap{
                Kind:       "ConfigMap",
                ApiVersion: "v1",
-               Metadata:   CMMetadata{Name: r.Metadata.Name, Namespace: r.Metadata.Namespace},
-               Data:       r.Configuration,
+               Metadata:   appmgr.CMMetadata{Name: *r.Metadata.Name, Namespace: r.Metadata.Namespace},
+               Data:       r.Config,
        }
 
        cmJson, err := json.Marshal(c.Data)
        if err != nil {
-               log.Println("Config marshalling failed: ", err)
+               appmgr.Logger.Info("Config marshalling failed: %v", err)
                return
        }
 
        cmFile := viper.GetString("xapp.tmpConfig")
        err = ioutil.WriteFile(cmFile, cmJson, 0644)
        if err != nil {
-               log.Println("WriteFile failed: ", err)
+               appmgr.Logger.Info("WriteFile failed: %v", err)
                return
        }
 
        cmd := " create configmap -n %s %s --from-file=%s -o json --dry-run | kubectl %s -f -"
        args := fmt.Sprintf(cmd, r.Metadata.Namespace, r.Metadata.ConfigName, cmFile, action)
-       _, err = KubectlExec(args)
+       _, err = util.KubectlExec(args)
        if err != nil {
                return
        }
-       log.Println("Configmap changes done!")
+       appmgr.Logger.Info("Configmap changes done!")
 
        return
 }
 
-func (cm *ConfigMap) GetConfigMap(m XappDeploy, c *interface{}) (err error) {
-       if m.ConfigName == "" {
-               m.ConfigName = cm.GetConfigMapName(m.Name, m.Namespace)
-       }
-       return cm.ReadConfigMap(m.ConfigName, m.Namespace, c)
+func (cm *CM) GetConfigMap(m models.XappDescriptor, c *interface{}) (err error) {
+       return cm.ReadConfigMap(cm.GetConfigMapName(*m.XappName, m.Namespace), m.Namespace, c)
 }
 
-func (cm *ConfigMap) CreateConfigMap(r XAppConfig) (errList []CMError, err error) {
+func (cm *CM) CreateConfigMap(r models.XAppConfig) (errList models.ConfigValidationErrors, err error) {
        if errList, err = cm.Validate(r); err != nil {
                return
        }
@@ -175,7 +152,7 @@ func (cm *ConfigMap) CreateConfigMap(r XAppConfig) (errList []CMError, err error
        return
 }
 
-func (cm *ConfigMap) UpdateConfigMap(r XAppConfig) (errList []CMError, err error) {
+func (cm *CM) UpdateConfigMap(r models.XAppConfig) (errList models.ConfigValidationErrors, err error) {
        if errList, err = cm.Validate(r); err != nil {
                return
        }
@@ -185,39 +162,33 @@ func (cm *ConfigMap) UpdateConfigMap(r XAppConfig) (errList []CMError, err error
        return
 }
 
-func (cm *ConfigMap) DeleteConfigMap(r XAppConfig) (c interface{}, err error) {
-       err = cm.ReadConfigMap(r.Metadata.ConfigName, r.Metadata.Namespace, &c)
+func (cm *CM) DeleteConfigMap(r models.ConfigMetadata) (c interface{}, err error) {
+       err = cm.ReadConfigMap(r.ConfigName, r.Namespace, &c)
        if err == nil {
-               args := fmt.Sprintf(" delete configmap --namespace=%s %s", r.Metadata.Namespace, r.Metadata.ConfigName)
-               _, err = KubectlExec(args)
+               args := fmt.Sprintf(" delete configmap --namespace=%s %s", r.Namespace, r.ConfigName)
+               _, err = util.KubectlExec(args)
        }
        return
 }
 
-func (cm *ConfigMap) PurgeConfigMap(m XappDeploy) (c interface{}, err error) {
-       if m.ConfigName == "" {
-               m.ConfigName = cm.GetConfigMapName(m.Name, m.Namespace)
-       }
-       md := ConfigMetadata{Name: m.Name, Namespace: m.Namespace, ConfigName: m.ConfigName}
+func (cm *CM) PurgeConfigMap(m models.XappDescriptor) (c interface{}, err error) {
+       md := models.ConfigMetadata{Name: m.XappName, Namespace: m.Namespace, ConfigName: cm.GetConfigMapName(*m.XappName, m.Namespace)}
 
-       return cm.DeleteConfigMap(XAppConfig{Metadata: md})
+       return cm.DeleteConfigMap(md)
 }
 
-func (cm *ConfigMap) RestoreConfigMap(m XappDeploy, c interface{}) (err error) {
-       if m.ConfigName == "" {
-               m.ConfigName = cm.GetConfigMapName(m.Name, m.Namespace)
-       }
-       md := ConfigMetadata{Name: m.Name, Namespace: m.Namespace, ConfigName: m.ConfigName}
+func (cm *CM) RestoreConfigMap(m models.XappDescriptor, c interface{}) (err error) {
+       md := &models.ConfigMetadata{Name: m.XappName, Namespace: m.Namespace, ConfigName: cm.GetConfigMapName(*m.XappName, m.Namespace)}
        time.Sleep(time.Duration(10 * time.Second))
 
-       return cm.ApplyConfigMap(XAppConfig{Metadata: md, Configuration: c}, "create")
+       return cm.ApplyConfigMap(models.XAppConfig{Metadata: md, Config: c}, "create")
 }
 
-func (cm *ConfigMap) GetNamesFromHelmRepo() (names []string) {
+func (cm *CM) GetNamesFromHelmRepo() (names []string) {
        rname := viper.GetString("helm.repo-name")
 
        cmdArgs := strings.Join([]string{"search ", rname}, "")
-       out, err := HelmExec(cmdArgs)
+       out, err := util.HelmExec(cmdArgs)
        if err != nil {
                return
        }
@@ -234,67 +205,69 @@ func (cm *ConfigMap) GetNamesFromHelmRepo() (names []string) {
        return names
 }
 
-func (cm *ConfigMap) Validate(req XAppConfig) (errList []CMError, err error) {
-       c := XAppConfig{}
-       err = cm.ReadSchema(req.Metadata.Name, &c)
+func (cm *CM) Validate(req models.XAppConfig) (errList models.ConfigValidationErrors, err error) {
+       c := models.XAppConfig{}
+       err = cm.ReadSchema(*req.Metadata.Name, &c)
        if err != nil {
-               log.Printf("No schema file found for '%s', aborting ...", req.Metadata.Name)
+               appmgr.Logger.Info("No schema file found for '%s', aborting ...", *req.Metadata.Name)
                return
        }
-       return cm.doValidate(c.Descriptor, req.Configuration)
+       return cm.doValidate(c.Descriptor, req.Config)
 }
 
-func (cm *ConfigMap) doValidate(schema, cfg interface{}) (errList []CMError, err error) {
+func (cm *CM) doValidate(schema, cfg interface{}) (errList models.ConfigValidationErrors, err error) {
        schemaLoader := gojsonschema.NewGoLoader(schema)
        documentLoader := gojsonschema.NewGoLoader(cfg)
 
        result, err := gojsonschema.Validate(schemaLoader, documentLoader)
        if err != nil {
-               log.Println("Validation failed: ", err)
+               appmgr.Logger.Info("Validation failed: %v", err)
                return
        }
 
        if result.Valid() == false {
-               log.Println("The document is not valid, Errors: ", result.Errors())
+               appmgr.Logger.Info("The document is not valid, Errors: %v", result.Errors())
                for _, desc := range result.Errors() {
-                       errList = append(errList, CMError{Field: desc.Field(), Description: desc.Description()})
+                       field := desc.Field()
+                       validationError := desc.Description()
+                       errList = append(errList, &models.ConfigValidationError{Field: &field, Error: &validationError})
                }
                return errList, errors.New("Validation failed!")
        }
        return
 }
 
-func (cm *ConfigMap) ReadFile(name string, data interface{}) (err error) {
+func (cm *CM) ReadFile(name string, data interface{}) (err error) {
        f, err := ioutil.ReadFile(name)
        if err != nil {
-               log.Printf("Reading '%s' file failed: %v", name, err)
+               appmgr.Logger.Info("Reading '%s' file failed: %v", name, err)
                return
        }
 
        err = json.Unmarshal(f, &data)
        if err != nil {
-               log.Printf("Unmarshalling '%s' file failed: %v", name, err)
+               appmgr.Logger.Info("Unmarshalling '%s' file failed: %v", name, err)
                return
        }
 
        return
 }
 
-func (cm *ConfigMap) FetchChart(name string) (err error) {
+func (cm *CM) FetchChart(name string) (err error) {
        tarDir := viper.GetString("xapp.tarDir")
        repo := viper.GetString("helm.repo-name")
        fetchArgs := fmt.Sprintf("--untar --untardir %s %s/%s", tarDir, repo, name)
 
-       _, err = HelmExec(strings.Join([]string{"fetch ", fetchArgs}, ""))
+       _, err = util.HelmExec(strings.Join([]string{"fetch ", fetchArgs}, ""))
        return
 }
 
-func (cm *ConfigMap) GetMessages(name string) (msgs MessageTypes) {
-       log.Println("Fetching tx/rx messages for: ", name)
+func (cm *CM) GetMessages(name string) (msgs appmgr.MessageTypes) {
+       appmgr.Logger.Info("Fetching tx/rx messages for: %s", name)
 
        ns := cm.GetNamespace("")
        args := fmt.Sprintf("get configmap -o jsonpath='{.data.config-file\\.json}' -n %s %s", ns, cm.GetConfigMapName(name, ns))
-       out, err := KubectlExec(args)
+       out, err := util.KubectlExec(args)
        if err != nil {
                return
        }
@@ -302,7 +275,7 @@ func (cm *ConfigMap) GetMessages(name string) (msgs MessageTypes) {
        var p fastjson.Parser
        v, err := p.Parse(string(out))
        if err != nil {
-               log.Printf("fastjson.Parser for '%s' failed: %v", name, err)
+               appmgr.Logger.Info("fastjson.Parser for '%s' failed: %v", name, err)
                return
        }
 
@@ -316,11 +289,11 @@ func (cm *ConfigMap) GetMessages(name string) (msgs MessageTypes) {
        return
 }
 
-func (cm *ConfigMap) GetConfigMapName(xappName, namespace string) string {
+func (cm *CM) GetConfigMapName(xappName, namespace string) string {
        return " configmap-" + namespace + "-" + xappName + "-appconfig"
 }
 
-func (cm *ConfigMap) GetNamespace(ns string) string {
+func (cm *CM) GetNamespace(ns string) string {
        if ns != "" {
                return ns
        }