2 ==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 ==================================================================================
26 "github.com/spf13/viper"
27 "github.com/xeipuuv/gojsonschema"
37 type ConfigMetadata struct {
38 Name string `json:"name"`
39 ConfigName string `json:"configName, omitempty"`
40 Namespace string `json:"namespace, omitempty"`
43 type XAppConfig struct {
44 Metadata ConfigMetadata `json:"metadata"`
45 Descriptor interface{} `json:"descriptor, omitempty"`
46 Configuration interface{} `json:"config, omitempty"`
49 type ConfigMap struct {
50 Kind string `json:"kind"`
51 ApiVersion string `json:"apiVersion"`
52 Data interface{} `json:"data"`
53 Metadata CMMetadata `json:"metadata"`
56 type CMMetadata struct {
57 Name string `json:"name"`
58 Namespace string `json:"namespace"`
62 Field string `json:"field"`
63 Description string `json:"description"`
66 func (cm *ConfigMap) UploadConfig() (cfg []XAppConfig) {
67 for _, name := range cm.GetNamesFromHelmRepo() {
73 Metadata: ConfigMetadata{Name: name, Namespace: "ricxapp", ConfigName: name + "-appconfig"},
76 err := cm.ReadSchema(name, &c)
81 err = cm.ReadConfigMap(c.Metadata.ConfigName, "ricxapp", &c.Configuration)
83 log.Println("No active configMap found, using default!")
91 func (cm *ConfigMap) ReadSchema(name string, c *XAppConfig) (err error) {
92 if err = cm.FetchChart(name); err != nil {
96 tarDir := viper.GetString("xapp.tarDir")
97 err = cm.ReadFile(path.Join(tarDir, name, viper.GetString("xapp.schema")), &c.Descriptor)
102 err = cm.ReadFile(path.Join(tarDir, name, viper.GetString("xapp.config")), &c.Configuration)
107 if err = os.RemoveAll(path.Join(tarDir, name)); err != nil {
108 log.Println("RemoveAll failed", err)
114 func (cm *ConfigMap) ReadConfigMap(ConfigName string, ns string, c *interface{}) (err error) {
115 args := fmt.Sprintf("get configmap -o jsonpath='{.data.config-file\\.json}' -n %s %s", ns, ConfigName)
116 configMapJson, err := KubectlExec(args)
121 err = json.Unmarshal([]byte(configMapJson), &c)
129 func (cm *ConfigMap) ApplyConfigMap(r XAppConfig, action string) (err error) {
133 Metadata: CMMetadata{Name: r.Metadata.Name, Namespace: r.Metadata.Namespace},
134 Data: r.Configuration,
137 cmJson, err := json.Marshal(c)
139 log.Println("Config marshalling failed: ", err)
143 cmFile := viper.GetString("xapp.tmpConfig")
144 err = ioutil.WriteFile(cmFile, cmJson, 0644)
146 log.Println("WriteFile failed: ", err)
150 cmd := " create configmap -n %s %s --from-file=%s -o json --dry-run | kubectl %s -f -"
151 args := fmt.Sprintf(cmd, r.Metadata.Namespace, r.Metadata.ConfigName, cmFile, action)
152 _, err = KubectlExec(args)
156 log.Println("Configmap changes done!")
161 func (cm *ConfigMap) CreateConfigMap(r XAppConfig) (errList []CMError, err error) {
162 if errList, err = cm.Validate(r); err != nil {
165 err = cm.ApplyConfigMap(r, "create")
169 func (cm *ConfigMap) UpdateConfigMap(r XAppConfig) (errList []CMError, err error) {
170 if errList, err = cm.Validate(r); err != nil {
174 // Re-create the configmap with the new parameters
175 err = cm.ApplyConfigMap(r, "apply")
179 func (cm *ConfigMap) DeleteConfigMap(r XAppConfig) (c interface{}, err error) {
180 err = cm.ReadConfigMap(r.Metadata.ConfigName, r.Metadata.Namespace, &c)
182 args := fmt.Sprintf(" delete configmap --namespace=%s %s", r.Metadata.Namespace, r.Metadata.ConfigName)
183 _, err = KubectlExec(args)
188 func (cm *ConfigMap) PurgeConfigMap(m XappDeploy) (c interface{}, err error) {
189 if m.ConfigName == "" {
190 m.ConfigName = m.Name + "-appconfig"
192 md := ConfigMetadata{Name: m.Name, Namespace: m.Namespace, ConfigName: m.ConfigName}
194 return cm.DeleteConfigMap(XAppConfig{Metadata: md})
197 func (cm *ConfigMap) RestoreConfigMap(m XappDeploy, c interface{}) (err error) {
198 if m.ConfigName == "" {
199 m.ConfigName = m.Name + "-appconfig"
201 md := ConfigMetadata{Name: m.Name, Namespace: m.Namespace, ConfigName: m.ConfigName}
202 time.Sleep(time.Duration(10 * time.Second))
204 return cm.ApplyConfigMap(XAppConfig{Metadata: md, Configuration: c}, "create")
207 func (cm *ConfigMap) GetNamesFromHelmRepo() (names []string) {
208 rname := viper.GetString("helm.repo-name")
210 cmdArgs := strings.Join([]string{"search ", rname}, "")
211 out, err := HelmExec(cmdArgs)
216 re := regexp.MustCompile(rname + `/.*`)
217 result := re.FindAllStringSubmatch(string(out), -1)
220 for _, v := range result {
221 fmt.Sscanf(v[0], "%s", &tmp)
222 names = append(names, strings.Split(tmp, "/")[1])
228 func (cm *ConfigMap) Validate(req XAppConfig) (errList []CMError, err error) {
230 err = cm.ReadSchema(req.Metadata.Name, &c)
232 log.Printf("No schema file found for '%s', aborting ...", req.Metadata.Name)
235 return cm.doValidate(c.Descriptor, req.Configuration)
238 func (cm *ConfigMap) doValidate(schema, cfg interface{}) (errList []CMError, err error) {
239 schemaLoader := gojsonschema.NewGoLoader(schema)
240 documentLoader := gojsonschema.NewGoLoader(cfg)
242 result, err := gojsonschema.Validate(schemaLoader, documentLoader)
244 log.Println("Validation failed: ", err)
248 if result.Valid() == false {
249 log.Println("The document is not valid, Errors: ", result.Errors())
250 for _, desc := range result.Errors() {
251 errList = append(errList, CMError{Field: desc.Field(), Description: desc.Description()})
253 return errList, errors.New("Validation failed!")
258 func (cm *ConfigMap) ReadFile(name string, data interface{}) (err error) {
259 f, err := ioutil.ReadFile(name)
261 log.Printf("Reading '%s' file failed: %v", name, err)
265 err = json.Unmarshal(f, &data)
267 log.Printf("Unmarshalling '%s' file failed: %v", name, err)
274 func (cm *ConfigMap) FetchChart(name string) (err error) {
275 tarDir := viper.GetString("xapp.tarDir")
276 repo := viper.GetString("helm.repo-name")
277 fetchArgs := fmt.Sprintf("--untar --untardir %s %s/%s", tarDir, repo, name)
279 _, err = HelmExec(strings.Join([]string{"fetch ", fetchArgs}, ""))
283 func (cm *ConfigMap) GetMessages(name string) (msgs MessageTypes) {
284 log.Println("Fetching tx/rx messages for: ", name)