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.oran-osc.org/r/ric-plt/appmgr/pkg/appmgr"
34 "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/cm"
35 "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/models"
36 "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/util"
44 func NewHelm() *Helm {
45 return &Helm{initDone: false, cm: cm.NewCM()}
48 func (h *Helm) Initialize() {
49 if h.initDone == true {
54 if _, err := h.Init(); err == nil {
55 appmgr.Logger.Info("Helm init done successfully!")
58 appmgr.Logger.Info("helm init failed, retyring ...")
59 time.Sleep(time.Duration(10) * time.Second)
63 if _, err := h.AddRepo(); err == nil {
64 appmgr.Logger.Info("Helm repo added successfully")
67 appmgr.Logger.Info("Helm repo addition failed, retyring ...")
68 time.Sleep(time.Duration(10) * time.Second)
73 func (h *Helm) Run(args string) (out []byte, err error) {
74 return util.HelmExec(args)
78 func (h *Helm) Init() (out []byte, err error) {
79 if err := h.AddTillerEnv(); err != nil {
83 return util.HelmExec(strings.Join([]string{"init -c --skip-refresh"}, ""))
86 func (h *Helm) AddRepo() (out []byte, err error) {
87 // Get helm repo user name and password from files mounted by secret object
88 username, err := ioutil.ReadFile(viper.GetString("helm.helm-username-file"))
90 appmgr.Logger.Info("helm_repo_username ReadFile failed: %v", err.Error())
94 password, err := ioutil.ReadFile(viper.GetString("helm.helm-password-file"))
96 appmgr.Logger.Info("helm_repo_password ReadFile failed: %v", err.Error())
100 repoArgs := fmt.Sprintf(" %s %s ", viper.GetString("helm.repo-name"), viper.GetString("helm.repo"))
101 credentials := fmt.Sprintf(" --username %s --password %s", string(username), string(password))
103 return util.HelmExec(strings.Join([]string{"repo add ", repoArgs, credentials}, ""))
106 func (h *Helm) Install(m models.XappDescriptor) (xapp models.Xapp, err error) {
107 m.Namespace = h.cm.GetNamespace(m.Namespace)
109 out, err := h.Run(strings.Join([]string{"repo update "}, ""))
114 out, err = h.Run(h.GetInstallArgs(m, false))
118 return h.ParseStatus(*m.XappName, string(out))
121 func (h *Helm) Status(name string) (xapp models.Xapp, err error) {
122 out, err := h.Run(strings.Join([]string{"status ", name}, ""))
124 appmgr.Logger.Info("Getting xapps status: %v", err.Error())
128 return h.ParseStatus(name, string(out))
131 func (h *Helm) StatusAll() (xapps models.AllDeployedXapps, err error) {
132 xappNameList, err := h.List()
134 appmgr.Logger.Info("Helm list failed: %v", err.Error())
138 return h.parseAllStatus(xappNameList)
141 func (h *Helm) List() (names []string, err error) {
142 ns := h.cm.GetNamespace("")
143 out, err := h.Run(strings.Join([]string{"list --all --deployed --output yaml --namespace=", ns}, ""))
145 appmgr.Logger.Info("Listing deployed xapps failed: %v", err.Error())
149 return h.GetNames(string(out))
152 func (h *Helm) SearchAll() models.AllDeployableXapps {
153 return h.cm.GetNamesFromHelmRepo()
156 func (h *Helm) Delete(name string) (xapp models.Xapp, err error) {
157 xapp, err = h.Status(name)
159 appmgr.Logger.Info("Fetching xapp status failed: %v", err.Error())
163 _, err = h.Run(strings.Join([]string{"del --purge ", name}, ""))
167 func (h *Helm) Fetch(name, tarDir string) error {
168 if strings.HasSuffix(os.Args[0], ".test") {
172 rname := viper.GetString("helm.repo-name") + "/"
174 _, err := h.Run(strings.Join([]string{"fetch --untar --untardir ", tarDir, " ", rname, name}, ""))
179 func (h *Helm) GetVersion(name string) (version string) {
180 ns := h.cm.GetNamespace("")
181 out, err := h.Run(strings.Join([]string{"list --deployed --output yaml --namespace=", ns, " ", name}, ""))
186 var re = regexp.MustCompile(`AppVersion: .*`)
187 ver := re.FindStringSubmatch(string(out))
189 version = strings.Split(ver[0], ": ")[1]
190 version, _ = strconv.Unquote(version)
196 func (h *Helm) GetState(out string) (status string) {
197 re := regexp.MustCompile(`STATUS: .*`)
198 result := re.FindStringSubmatch(string(out))
200 status = strings.ToLower(strings.Split(result[0], ": ")[1])
206 func (h *Helm) GetAddress(out string) (ip, port string) {
208 re := regexp.MustCompile(`ClusterIP.*`)
209 addr := re.FindStringSubmatch(string(out))
211 fmt.Sscanf(addr[0], "%s %s %s %s", &tmp, &ip, &tmp, &port)
217 func (h *Helm) GetEndpointInfo(name string) (ip string, port int) {
218 ns := h.cm.GetNamespace("")
219 args := fmt.Sprintf(" get endpoints -o=jsonpath='{.subsets[*].addresses[*].ip}' service-%s-%s-rmr -n %s", ns, name, ns)
220 out, err := util.KubectlExec(args)
224 appmgr.Logger.Info("Endpoint IP address of %s: %s", name, string(out))
225 return fmt.Sprintf("service-%s-%s-rmr.%s", ns, name, ns), 4560
228 func (h *Helm) GetNames(out string) (names []string, err error) {
229 re := regexp.MustCompile(`Name: .*`)
230 result := re.FindAllStringSubmatch(out, -1)
235 for _, v := range result {
236 xappName := strings.Split(v[0], ": ")[1]
237 if strings.Contains(xappName, "appmgr") == false {
238 names = append(names, xappName)
244 func (h *Helm) FillInstanceData(name string, out string, xapp *models.Xapp, rtData appmgr.RtmData) {
245 ip, port := h.GetEndpointInfo(name)
247 appmgr.Logger.Info("Endpoint IP address not found, using CluserIP")
248 ip, _ = h.GetAddress(out)
252 r := regexp.MustCompile(`.*(?s)(Running|Pending|Succeeded|Failed|Unknown).*?\r?\n\r?\n`)
253 result := r.FindStringSubmatch(string(out))
258 re := regexp.MustCompile(name + "-(\\w+-\\w+).*")
259 resources := re.FindAllStringSubmatch(string(result[0]), -1)
260 if resources != nil {
261 for _, v := range resources {
262 var x models.XappInstance
264 fmt.Sscanf(v[0], "%s %s %s", &name, &tmp, &x.Status)
266 x.Status = strings.ToLower(x.Status)
269 x.TxMessages = rtData.TxMessages
270 x.RxMessages = rtData.RxMessages
271 x.Policies = rtData.Policies
272 xapp.Instances = append(xapp.Instances, &x)
277 func (h *Helm) ParseStatus(name string, out string) (xapp models.Xapp, err error) {
279 xapp.Version = h.GetVersion(name)
280 xapp.Status = h.GetState(out)
282 h.FillInstanceData(name, out, &xapp, h.cm.GetRtmData(name))
286 func (h *Helm) parseAllStatus(names []string) (xapps models.AllDeployedXapps, err error) {
287 xapps = models.AllDeployedXapps{}
288 for _, name := range names {
290 err := h.cm.ReadSchema(name, &desc)
295 x, err := h.Status(name)
297 xapps = append(xapps, &x)
303 func (h *Helm) AddTillerEnv() (err error) {
304 service := viper.GetString("helm.tiller-service")
305 namespace := viper.GetString("helm.tiller-namespace")
306 port := viper.GetString("helm.tiller-port")
308 if err = os.Setenv("HELM_HOST", service+"."+namespace+":"+port); err != nil {
309 appmgr.Logger.Info("Tiller Env Setting Failed: %v", err.Error())
314 func (h *Helm) GetInstallArgs(x models.XappDescriptor, cmOverride bool) (args string) {
315 args = fmt.Sprintf("%s --namespace=%s", args, x.Namespace)
316 if x.HelmVersion != "" {
317 args = fmt.Sprintf("%s --version=%s", args, x.HelmVersion)
320 if x.ReleaseName != "" {
321 args = fmt.Sprintf("%s --name=%s", args, x.ReleaseName)
323 args = fmt.Sprintf("%s --name=%s", args, *x.XappName)
326 if cmOverride == true {
327 args = fmt.Sprintf("%s ---set ricapp.appconfig.override=%s-appconfig", args, *x.XappName)
330 if x.OverrideFile != nil {
331 if overrideYaml, err := yaml.JSONToYAML([]byte(x.OverrideFile.(string))); err == nil {
332 err = ioutil.WriteFile("/tmp/appmgr_override.yaml", overrideYaml, 0644)
334 appmgr.Logger.Info("ioutil.WriteFile(/tmp/appmgr_override.yaml) failed: %v", err)
336 args = args + " -f=/tmp/appmgr_override.yaml"
339 appmgr.Logger.Info("yaml.JSONToYAML failed: %v", err)
343 repoName := viper.GetString("helm.repo-name")
345 repoName = "helm-repo"
347 return fmt.Sprintf("install %s/%s %s", repoName, *x.XappName, args)