X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=cmd%2Fappmgr%2Fdesc.go;h=8cc39a59f80c478bd5a471bcc8a6e9ec5c460cd5;hb=4703b1a7457cf072640adbc0f5487a0675f5b6d3;hp=c3a27a3b797c7b4a10cde993a5ece91cc21a9965;hpb=57d2a61e41861321b263fdeff5679671e36143ae;p=ric-plt%2Fappmgr.git diff --git a/cmd/appmgr/desc.go b/cmd/appmgr/desc.go index c3a27a3..8cc39a5 100755 --- a/cmd/appmgr/desc.go +++ b/cmd/appmgr/desc.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "github.com/spf13/viper" + "github.com/valyala/fastjson" "github.com/xeipuuv/gojsonschema" "io/ioutil" "log" @@ -58,22 +59,28 @@ type CMMetadata struct { Namespace string `json:"namespace"` } -func UploadConfig() (cfg []XAppConfig) { - for _, name := range GetNamesFromHelmRepo() { +type CMError struct { + Field string `json:"field"` + Description string `json:"description"` +} + +func (cm *ConfigMap) UploadConfig() (cfg []XAppConfig) { + ns := cm.GetNamespace("") + for _, name := range cm.GetNamesFromHelmRepo() { if name == "appmgr" { continue } c := XAppConfig{ - Metadata: ConfigMetadata{Name: name, Namespace: "ricxapp", ConfigName: name + "-appconfig"}, + Metadata: ConfigMetadata{Name: name, Namespace: ns, ConfigName: cm.GetConfigMapName(name, ns)}, } - err := ReadSchema(name, &c) + err := cm.ReadSchema(name, &c) if err != nil { continue } - err = ReadConfigMap(name, "ricxapp", &c.Configuration) + err = cm.ReadConfigMap(c.Metadata.ConfigName, ns, &c.Configuration) if err != nil { log.Println("No active configMap found, using default!") } @@ -83,18 +90,18 @@ func UploadConfig() (cfg []XAppConfig) { return } -func ReadSchema(name string, c *XAppConfig) (err error) { - if err = FetchChart(name); err != nil { +func (cm *ConfigMap) ReadSchema(name string, c *XAppConfig) (err error) { + if err = cm.FetchChart(name); err != nil { return } tarDir := viper.GetString("xapp.tarDir") - err = ReadFile(path.Join(tarDir, name, viper.GetString("xapp.schema")), &c.Descriptor) + err = cm.ReadFile(path.Join(tarDir, name, viper.GetString("xapp.schema")), &c.Descriptor) if err != nil { return } - err = ReadFile(path.Join(tarDir, name, viper.GetString("xapp.config")), &c.Configuration) + err = cm.ReadFile(path.Join(tarDir, name, viper.GetString("xapp.config")), &c.Configuration) if err != nil { return } @@ -106,8 +113,8 @@ func ReadSchema(name string, c *XAppConfig) (err error) { return } -func ReadConfigMap(name string, ns string, c *interface{}) (err error) { - args := fmt.Sprintf("get configmap -o jsonpath='{.data.config-file\\.json}' -n %s %s-appconfig", ns, name) +func (cm *ConfigMap) 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) if err != nil { return @@ -121,15 +128,15 @@ func ReadConfigMap(name string, ns string, c *interface{}) (err error) { return } -func ApplyConfigMap(r XAppConfig) (err error) { - cm := ConfigMap{ +func (cm *ConfigMap) ApplyConfigMap(r XAppConfig, action string) (err error) { + c := ConfigMap{ Kind: "ConfigMap", ApiVersion: "v1", Metadata: CMMetadata{Name: r.Metadata.Name, Namespace: r.Metadata.Namespace}, Data: r.Configuration, } - cmJson, err := json.Marshal(cm) + cmJson, err := json.Marshal(c.Data) if err != nil { log.Println("Config marshalling failed: ", err) return @@ -142,26 +149,44 @@ func ApplyConfigMap(r XAppConfig) (err error) { return } - cmd := " create configmap -n %s %s --from-file=%s -o json --dry-run | kubectl apply -f -" - args := fmt.Sprintf(cmd, r.Metadata.Namespace, r.Metadata.ConfigName, cmFile) + 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) if err != nil { return } - log.Println("Configmap changes created!") + log.Println("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 *ConfigMap) CreateConfigMap(r XAppConfig) (errList []CMError, err error) { + if errList, err = cm.Validate(r); err != nil { + return + } + err = cm.ApplyConfigMap(r, "create") return } -func CreateConfigMap(r XAppConfig) (err error) { - if err = Validate(r); err != nil { +func (cm *ConfigMap) UpdateConfigMap(r XAppConfig) (errList []CMError, err error) { + if errList, err = cm.Validate(r); err != nil { return } - return ApplyConfigMap(r) + + // Re-create the configmap with the new parameters + err = cm.ApplyConfigMap(r, "apply") + return } -func DeleteConfigMap(r XAppConfig) (cm interface{}, err error) { - err = ReadConfigMap(r.Metadata.Name, r.Metadata.Namespace, &cm) +func (cm *ConfigMap) DeleteConfigMap(r XAppConfig) (c interface{}, err error) { + err = cm.ReadConfigMap(r.Metadata.ConfigName, r.Metadata.Namespace, &c) if err == nil { args := fmt.Sprintf(" delete configmap --namespace=%s %s", r.Metadata.Namespace, r.Metadata.ConfigName) _, err = KubectlExec(args) @@ -169,23 +194,26 @@ func DeleteConfigMap(r XAppConfig) (cm interface{}, err error) { return } -func PurgeConfigMap(m ConfigMetadata) (cm interface{}, err error) { +func (cm *ConfigMap) PurgeConfigMap(m XappDeploy) (c interface{}, err error) { if m.ConfigName == "" { - m.ConfigName = m.Name + "-appconfig" + m.ConfigName = cm.GetConfigMapName(m.Name, m.Namespace) } - return DeleteConfigMap(XAppConfig{Metadata: m}) + md := ConfigMetadata{Name: m.Name, Namespace: m.Namespace, ConfigName: m.ConfigName} + + return cm.DeleteConfigMap(XAppConfig{Metadata: md}) } -func RestoreConfigMap(m ConfigMetadata, cm interface{}) (err error) { +func (cm *ConfigMap) RestoreConfigMap(m XappDeploy, c interface{}) (err error) { if m.ConfigName == "" { - m.ConfigName = m.Name + "-appconfig" + m.ConfigName = cm.GetConfigMapName(m.Name, m.Namespace) } + md := ConfigMetadata{Name: m.Name, Namespace: m.Namespace, ConfigName: m.ConfigName} time.Sleep(time.Duration(10 * time.Second)) - return ApplyConfigMap(XAppConfig{Metadata: m, Configuration: cm}) + return cm.ApplyConfigMap(XAppConfig{Metadata: md, Configuration: c}, "create") } -func GetNamesFromHelmRepo() (names []string) { +func (cm *ConfigMap) GetNamesFromHelmRepo() (names []string) { rname := viper.GetString("helm.repo-name") cmdArgs := strings.Join([]string{"search ", rname}, "") @@ -206,37 +234,37 @@ func GetNamesFromHelmRepo() (names []string) { return names } -func Validate(req XAppConfig) (err error) { +func (cm *ConfigMap) Validate(req XAppConfig) (errList []CMError, err error) { c := XAppConfig{} - err = ReadSchema(req.Metadata.Name, &c) + err = cm.ReadSchema(req.Metadata.Name, &c) if err != nil { log.Printf("No schema file found for '%s', aborting ...", req.Metadata.Name) - return err + return } + return cm.doValidate(c.Descriptor, req.Configuration) +} - schemaLoader := gojsonschema.NewGoLoader(c.Descriptor) - documentLoader := gojsonschema.NewGoLoader(req.Configuration) +func (cm *ConfigMap) doValidate(schema, cfg interface{}) (errList []CMError, err error) { + schemaLoader := gojsonschema.NewGoLoader(schema) + documentLoader := gojsonschema.NewGoLoader(cfg) - log.Println("Starting validation ...") result, err := gojsonschema.Validate(schemaLoader, documentLoader) if err != nil { log.Println("Validation failed: ", err) return } - log.Println("validation done ...", err, result.Valid()) if result.Valid() == false { log.Println("The document is not valid, Errors: ", result.Errors()) - s := make([]string, 3) - for i, desc := range result.Errors() { - s = append(s, fmt.Sprintf(" (%d): %s.\n", i, desc.String())) + for _, desc := range result.Errors() { + errList = append(errList, CMError{Field: desc.Field(), Description: desc.Description()}) } - return errors.New(strings.Join(s, " ")) + return errList, errors.New("Validation failed!") } return } -func ReadFile(name string, data interface{}) (err error) { +func (cm *ConfigMap) ReadFile(name string, data interface{}) (err error) { f, err := ioutil.ReadFile(name) if err != nil { log.Printf("Reading '%s' file failed: %v", name, err) @@ -252,7 +280,7 @@ func ReadFile(name string, data interface{}) (err error) { return } -func FetchChart(name string) (err error) { +func (cm *ConfigMap) 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) @@ -261,7 +289,45 @@ func FetchChart(name string) (err error) { return } -func GetMessages(name string) (msgs MessageTypes, err error) { +func (cm *ConfigMap) GetMessages(name string) (msgs MessageTypes) { log.Println("Fetching tx/rx messages for: ", 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) + if err != nil { + return + } + + var p fastjson.Parser + v, err := p.Parse(string(out)) + if err != nil { + log.Printf("fastjson.Parser for '%s' failed: %v", name, err) + return + } + + for _, m := range v.GetArray("rmr", "txMessages") { + msgs.TxMessages = append(msgs.TxMessages, strings.Trim(m.String(), `"`)) + } + for _, m := range v.GetArray("rmr", "rxMessages") { + msgs.RxMessages = append(msgs.RxMessages, strings.Trim(m.String(), `"`)) + } + return } + +func (cm *ConfigMap) GetConfigMapName(xappName, namespace string) string { + return " configmap-" + namespace + "-" + xappName + "-appconfig" +} + +func (cm *ConfigMap) GetNamespace(ns string) string { + if ns != "" { + return ns + } + + ns = viper.GetString("xapp.namespace") + if ns == "" { + ns = "ricxapp" + } + return ns +}