"errors"
"fmt"
"github.com/spf13/viper"
+ "github.com/valyala/fastjson"
"github.com/xeipuuv/gojsonschema"
"io/ioutil"
"log"
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!")
}
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
}
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
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
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)
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}, "")
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)
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)
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
+}