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 ==================================================================================
24 "github.com/ghodss/yaml"
25 "github.com/spf13/viper"
33 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/appmgr"
34 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/cm"
35 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/models"
36 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/util"
39 var kubeExec = util.KubectlExec
40 var helmExec = util.HelmExec
47 func GetHelmVersion() {
49 temp = os.Getenv("HELMVERSION")
50 appmgr.Logger.Info("Inside new Helm")
51 temp = strings.TrimLeft(temp,"v")
52 cm.EnvHelmVersion = string(temp[0:1]) //s.TrimRight(temp, ".")
53 appmgr.Logger.Info(cm.EnvHelmVersion)
57 func NewHelm() *Helm {
59 return &Helm{initDone: false, cm: cm.NewCM()}
62 func (h *Helm) Initialize() {
63 if h.initDone == true {
66 appmgr.Logger.Info("START")
68 if _, err := h.Init(); err == nil {
69 appmgr.Logger.Info("Helm init done successfully!")
72 appmgr.Logger.Info("helm init failed, retyring ...")
73 time.Sleep(time.Duration(10) * time.Second)
75 if cm.EnvHelmVersion == cm.HELM_VERSION_3 {
76 appmgr.Logger.Info("Codintion met for HELM3")
77 util.HelmExec(strings.Join([]string{"repo add stable https://kubernetes-charts.storage.googleapis.com/ "}, ""))
81 if _, err := h.AddRepo(); err == nil {
82 appmgr.Logger.Info("Helm repo added successfully")
85 appmgr.Logger.Info("Helm repo addition failed, retyring ...")
86 time.Sleep(time.Duration(10) * time.Second)
91 func (h *Helm) Run(args string) (out []byte, err error) {
96 func (h *Helm) Init() (out []byte, err error) {
97 if err := h.AddTillerEnv(); err != nil {
100 if cm.EnvHelmVersion == cm.HELM_VERSION_2{
101 appmgr.Logger.Info("Init for Version 2")
102 return helmExec(strings.Join([]string{"init -c --skip-refresh"}, ""))
108 func (h *Helm) AddRepo() (out []byte, err error) {
109 // Get helm repo user name and password from files mounted by secret object
110 username, err := ioutil.ReadFile(viper.GetString("helm.helm-username-file"))
112 appmgr.Logger.Info("helm_repo_username ReadFile failed: %v", err.Error())
116 password, err := ioutil.ReadFile(viper.GetString("helm.helm-password-file"))
118 appmgr.Logger.Info("helm_repo_password ReadFile failed: %v", err.Error())
122 repoArgs := fmt.Sprintf(" %s %s ", viper.GetString("helm.repo-name"), viper.GetString("helm.repo"))
123 credentials := fmt.Sprintf(" --username %s --password %s", string(username), string(password))
125 return helmExec(strings.Join([]string{"repo add ", repoArgs, credentials}, ""))
128 func (h *Helm) Install(m models.XappDescriptor) (xapp models.Xapp, err error) {
129 m.Namespace = h.cm.GetNamespace(m.Namespace)
131 out, err := h.Run(strings.Join([]string{"repo update "}, ""))
136 out, err = h.Run(h.GetInstallArgs(m, false))
140 return h.ParseStatus(*m.XappName, string(out))
143 func (h *Helm) Status(name string) (xapp models.Xapp, err error) {
145 if cm.EnvHelmVersion == cm.HELM_VERSION_3 {
146 names := h.cm.GetNamespace("")
147 command = strings.Join([]string{"status ", name," --namespace ", names}, "")
148 appmgr.Logger.Info ("Status: Version 3")
150 command = strings.Join([]string{"status ", name}, "")
151 appmgr.Logger.Info ("Status: Version 2")
153 out, err := h.Run(command)
156 appmgr.Logger.Info("Getting xapps status: %v", err.Error())
159 return h.ParseStatus(name, string(out))
162 func (h *Helm) StatusAll() (xapps models.AllDeployedXapps, err error) {
163 xappNameList, err := h.List()
165 appmgr.Logger.Info("Helm list failed: %v", err.Error())
169 return h.parseAllStatus(xappNameList)
172 func (h *Helm) List() (names []string, err error) {
173 ns := h.cm.GetNamespace("")
174 out, err := h.Run(strings.Join([]string{"list --all --deployed --output yaml --namespace=", ns}, ""))
176 appmgr.Logger.Info("Listing deployed xapps failed: %v", err.Error())
180 return h.GetNames(string(out))
183 func (h *Helm) SearchAll() models.AllDeployableXapps {
184 return h.cm.GetNamesFromHelmRepo()
187 func (h *Helm) Delete(name string) (xapp models.Xapp, err error) {
188 xapp, err = h.Status(name)
189 var command string = ""
190 ns := h.cm.GetNamespace("")
193 appmgr.Logger.Info("Fetching xapp status failed: %v", err.Error())
196 if cm.EnvHelmVersion == cm.HELM_VERSION_3 {
197 command = strings.Join([]string{"uninstall ", name," -n ", ns}, "")
198 appmgr.Logger.Info ("DELETE: Version 3")
200 command = strings.Join([]string{"del --purge ", name}, "")
201 appmgr.Logger.Info ("DELETE: Version 2")
203 _, err = h.Run (command)
208 func (h *Helm) Fetch(name, tarDir string) error {
209 if strings.HasSuffix(os.Args[0], ".test") {
213 rname := viper.GetString("helm.repo-name") + "/"
215 _, err := h.Run(strings.Join([]string{"fetch --untar --untardir ", tarDir, " ", rname, name}, ""))
220 func (h *Helm) GetVersion(name string) (version string) {
221 ns := h.cm.GetNamespace("")
222 var command string = ""
223 if cm.EnvHelmVersion == cm.HELM_VERSION_3 {
224 command = strings.Join([]string{"list --deployed --output yaml --namespace=", ns, " ","-f ",name}, "")
225 appmgr.Logger.Info ("GetVersion: Version 3")
227 command = strings.Join([]string{"list --deployed --output yaml --namespace=", ns, " ", name}, "")
228 appmgr.Logger.Info ("GetVersion: Version 2")
230 out, err := h.Run(command)
236 var re = regexp.MustCompile(`AppVersion: .*`)
237 ver := re.FindStringSubmatch(string(out))
239 version = strings.Split(ver[0], ": ")[1]
240 version, _ = strconv.Unquote(version)
246 func (h *Helm) GetState(out string) (status string) {
247 re := regexp.MustCompile(`STATUS: .*`)
248 result := re.FindStringSubmatch(string(out))
250 status = strings.ToLower(strings.Split(result[0], ": ")[1])
256 func (h *Helm) GetAddress(out string) (ip, port string) {
258 re := regexp.MustCompile(`ClusterIP.*`)
259 addr := re.FindStringSubmatch(string(out))
261 fmt.Sscanf(addr[0], "%s %s %s %s", &tmp, &ip, &tmp, &port)
267 func (h *Helm) GetEndpointInfo(name string) (svc string, port int) {
268 port = 4560 // Default
269 ns := h.cm.GetNamespace("")
270 args := fmt.Sprintf(" get service -n %s service-%s-%s-rmr -o json", ns, ns, name)
271 out, err := kubeExec(args)
273 return fmt.Sprintf("service-%s-%s-rmr.%s", ns, name, ns), 4560
275 appmgr.Logger.Debug("Endpoint IP address of %s: %s", name, string(out))
277 v, err := h.cm.ParseJson(string(out))
279 return fmt.Sprintf("service-%s-%s-rmr.%s", ns, name, ns), 4560
282 for _, p := range v.GetArray("spec", "ports") {
283 if string(p.GetStringBytes("name")) == "rmrdata" {
284 port = int(p.GetInt("port"))
288 appmgr.Logger.Info("service-%s-%s-rmr.%s %d", ns, name, ns, port)
290 return fmt.Sprintf("service-%s-%s-rmr.%s", ns, name, ns), port
293 func (h *Helm) GetNames(out string) (names []string, err error) {
294 re := regexp.MustCompile(`Name: .*`)
295 result := re.FindAllStringSubmatch(out, -1)
300 for _, v := range result {
301 xappName := strings.Split(v[0], ": ")[1]
302 if strings.Contains(xappName, "appmgr") == false {
303 names = append(names, xappName)
309 func (h *Helm) FillInstanceData(name string, out string, xapp *models.Xapp, rtData appmgr.RtmData) {
310 ip, port := h.GetEndpointInfo(name)
312 appmgr.Logger.Info("Endpoint IP address not found, using CluserIP")
313 ip, _ = h.GetAddress(out)
317 r := regexp.MustCompile(`.*(?s)(Running|Pending|Succeeded|Failed|Unknown).*?\r?\n\r?\n`)
318 result := r.FindStringSubmatch(string(out))
323 re := regexp.MustCompile(name + "-(\\w+-\\w+).*")
324 resources := re.FindAllStringSubmatch(string(result[0]), -1)
325 if resources != nil {
326 for _, v := range resources {
327 var x models.XappInstance
329 fmt.Sscanf(v[0], "%s %s %s", &name, &tmp, &x.Status)
331 x.Status = strings.ToLower(x.Status)
334 x.TxMessages = rtData.TxMessages
335 x.RxMessages = rtData.RxMessages
336 x.Policies = rtData.Policies
337 xapp.Instances = append(xapp.Instances, &x)
342 func (h *Helm) ParseStatus(name string, out string) (xapp models.Xapp, err error) {
344 xapp.Version = h.GetVersion(name)
345 xapp.Status = h.GetState(out)
347 h.FillInstanceData(name, out, &xapp, h.cm.GetRtmData(name))
351 func (h *Helm) parseAllStatus(names []string) (xapps models.AllDeployedXapps, err error) {
352 xapps = models.AllDeployedXapps{}
353 for _, name := range names {
355 err := h.cm.ReadSchema(name, &desc)
360 x, err := h.Status(name)
362 xapps = append(xapps, &x)
368 func (h *Helm) AddTillerEnv() (err error) {
369 service := viper.GetString("helm.tiller-service")
370 namespace := viper.GetString("helm.tiller-namespace")
371 port := viper.GetString("helm.tiller-port")
373 if err = os.Setenv("HELM_HOST", service+"."+namespace+":"+port); err != nil {
374 appmgr.Logger.Info("Tiller Env Setting Failed: %v", err.Error())
379 func (h *Helm) GetInstallArgs(x models.XappDescriptor, cmOverride bool) (args string) {
380 args = fmt.Sprintf("%s--namespace=%s", args, x.Namespace)
381 if x.HelmVersion != "" {
382 args = fmt.Sprintf("%s --version=%s", args, x.HelmVersion)
386 if cm.EnvHelmVersion == cm.HELM_VERSION_2 {
387 if x.ReleaseName != "" {
388 args = fmt.Sprintf("%s --name=%s", args, x.ReleaseName)
390 args = fmt.Sprintf("%s --name=%s", args, *x.XappName)
391 appmgr.Logger.Info("")
393 appmgr.Logger.Info ("GetInstallArgs: Version 2")
396 if cmOverride == true {
397 args = fmt.Sprintf("%s --set ricapp.appconfig.override=%s-appconfig", args, *x.XappName)
400 if x.OverrideFile != nil {
401 if overrideYaml, err := yaml.JSONToYAML([]byte(x.OverrideFile.(string))); err == nil {
402 err = ioutil.WriteFile("/tmp/appmgr_override.yaml", overrideYaml, 0644)
404 appmgr.Logger.Info("ioutil.WriteFile(/tmp/appmgr_override.yaml) failed: %v", err)
406 args = args + " -f=/tmp/appmgr_override.yaml"
409 appmgr.Logger.Info("yaml.JSONToYAML failed: %v", err)
413 repoName := viper.GetString("helm.repo-name")
415 repoName = "helm-repo"
419 if cm.EnvHelmVersion == cm.HELM_VERSION_3 {
420 appmgr.Logger.Info ("GetInstallArgs last: Version 3")
421 return fmt.Sprintf("install %s %s/%s %s",*x.XappName, repoName, *x.XappName, args)
423 appmgr.Logger.Info ("GetInstallArgs last: Version 2")
424 return fmt.Sprintf("install %s/%s %s", repoName, *x.XappName, args)