Adding cluster meta data and saving in etcd
[multicloud/k8s.git] / src / orchestrator / pkg / module / instantiation_appcontext_helper.go
1 /*
2  * Copyright 2020 Intel Corporation, Inc
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package module
18
19 /*
20 This file deals with the interaction of instantiation flow and etcd.
21 It contains methods for creating appContext, saving cluster and resource details to etcd.
22
23 */
24 import (
25         "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
26         gpic "github.com/onap/multicloud-k8s/src/orchestrator/pkg/gpic"
27         log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
28         "github.com/onap/multicloud-k8s/src/orchestrator/utils"
29         "github.com/onap/multicloud-k8s/src/orchestrator/utils/helm"
30         pkgerrors "github.com/pkg/errors"
31         "io/ioutil"
32 )
33
34 // resource consists of name of reource
35 type resource struct {
36         name        string
37         filecontent []byte
38 }
39
40 type contextForCompositeApp struct {
41         context            appcontext.AppContext
42         ctxval             interface{}
43         compositeAppHandle interface{}
44 }
45
46 // makeAppContext creates an appContext for a compositeApp and returns the output as contextForCompositeApp
47 func makeAppContextForCompositeApp(p, ca, v, rName string) (contextForCompositeApp, error) {
48         context := appcontext.AppContext{}
49         ctxval, err := context.InitAppContext()
50         if err != nil {
51                 return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating AppContext CompositeApp")
52         }
53         compositeHandle, err := context.CreateCompositeApp()
54         if err != nil {
55                 return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating CompositeApp handle")
56         }
57         err = context.AddCompositeAppMeta(appcontext.CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rName})
58         if err != nil {
59                 return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error Adding CompositeAppMeta")
60         }
61
62         m, err := context.GetCompositeAppMeta()
63
64         log.Info(":: The meta data stored in the runtime context :: ", log.Fields{"Project": m.Project, "CompositeApp": m.CompositeApp, "Version": m.Version, "Release": m.Release})
65
66         cca := contextForCompositeApp{context: context, ctxval: ctxval, compositeAppHandle: compositeHandle}
67
68         return cca, nil
69
70 }
71
72 // getResources shall take in the sorted templates and output the resources
73 // which consists of name(name+kind) and filecontent
74 func getResources(st []helm.KubernetesResourceTemplate) ([]resource, error) {
75         var resources []resource
76         for _, t := range st {
77                 yamlStruct, err := utils.ExtractYamlParameters(t.FilePath)
78                 yamlFile, err := ioutil.ReadFile(t.FilePath)
79                 if err != nil {
80                         return nil, pkgerrors.Wrap(err, "Failed to get the resources..")
81                 }
82                 n := yamlStruct.Metadata.Name + SEPARATOR + yamlStruct.Kind
83
84                 resources = append(resources, resource{name: n, filecontent: yamlFile})
85
86                 log.Info(":: Added resource into resource-order ::", log.Fields{"ResourceName": n})
87         }
88         return resources, nil
89 }
90
91 func addResourcesToCluster(ct appcontext.AppContext, ch interface{}, resources []resource, resourceOrder []string) error {
92
93         for _, resource := range resources {
94                 resourceOrder = append(resourceOrder, resource.name)
95                 _, err := ct.AddResource(ch, resource.name, resource.filecontent)
96                 if err != nil {
97                         cleanuperr := ct.DeleteCompositeApp()
98                         if cleanuperr != nil {
99                                 log.Info(":: Error Cleaning up AppContext after add resource failure ::", log.Fields{"Resource": resource.name, "Error": cleanuperr.Error})
100                         }
101                         return pkgerrors.Wrapf(err, "Error adding resource ::%s to AppContext", resource.name)
102                 }
103                 _, err = ct.AddInstruction(ch, "resource", "order", resourceOrder)
104                 if err != nil {
105                         cleanuperr := ct.DeleteCompositeApp()
106                         if cleanuperr != nil {
107                                 log.Info(":: Error Cleaning up AppContext after add instruction failure ::", log.Fields{"Resource": resource.name, "Error": cleanuperr.Error})
108                         }
109                         return pkgerrors.Wrapf(err, "Error adding instruction for resource ::%s to AppContext", resource.name)
110                 }
111         }
112         return nil
113 }
114
115 //addClustersToAppContext method shall add cluster details save into etcd
116 func addClustersToAppContext(l gpic.ClusterList, ct appcontext.AppContext, appHandle interface{}, resources []resource) error {
117         mc := l.MandatoryClusters
118         gc := l.ClusterGroups
119
120         for _, c := range mc {
121                 p := c.ProviderName
122                 n := c.ClusterName
123                 var resourceOrder []string
124                 clusterhandle, err := ct.AddCluster(appHandle, p+SEPARATOR+n)
125                 if err != nil {
126                         cleanuperr := ct.DeleteCompositeApp()
127                         if cleanuperr != nil {
128                                 log.Info(":: Error Cleaning up AppContext after add cluster failure ::", log.Fields{"cluster-provider": p, "cluster-name": n, "Error": cleanuperr.Error})
129                         }
130                         return pkgerrors.Wrapf(err, "Error adding Cluster(provider::%s and name::%s) to AppContext", p, n)
131                 }
132
133                 err = addResourcesToCluster(ct, clusterhandle, resources, resourceOrder)
134                 if err != nil {
135                         return pkgerrors.Wrapf(err, "Error adding Resources to Cluster(provider::%s and name::%s) to AppContext", p, n)
136                 }
137         }
138
139         for _, eachGrp := range gc {
140                 oc := eachGrp.OptionalClusters
141                 gn := eachGrp.GroupNumber
142
143                 for _, eachCluster := range oc {
144                         p := eachCluster.ProviderName
145                         n := eachCluster.ClusterName
146
147                         var resourceOrder []string
148                         clusterhandle, err := ct.AddCluster(appHandle, p+SEPARATOR+n)
149
150                         if err != nil {
151                                 cleanuperr := ct.DeleteCompositeApp()
152                                 if cleanuperr != nil {
153                                         log.Info(":: Error Cleaning up AppContext after add cluster failure ::", log.Fields{"cluster-provider": p, "cluster-name": n, "GroupName": gn, "Error": cleanuperr.Error})
154                                 }
155                                 return pkgerrors.Wrapf(err, "Error adding Cluster(provider::%s and name::%s) to AppContext", p, n)
156                         }
157
158                         err = ct.AddClusterMetaGrp(clusterhandle, gn)
159                         if err != nil {
160                                 cleanuperr := ct.DeleteCompositeApp()
161                                 if cleanuperr != nil {
162                                         log.Info(":: Error Cleaning up AppContext after add cluster failure ::", log.Fields{"cluster-provider": p, "cluster-name": n, "GroupName": gn, "Error": cleanuperr.Error})
163                                 }
164                                 return pkgerrors.Wrapf(err, "Error adding Cluster(provider::%s and name::%s) to AppContext", p, n)
165                         }
166
167                         err = addResourcesToCluster(ct, clusterhandle, resources, resourceOrder)
168                         if err != nil {
169                                 return pkgerrors.Wrapf(err, "Error adding Resources to Cluster(provider::%s, name::%s and groupName:: %s) to AppContext", p, n, gn)
170                         }
171                 }
172         }
173         return nil
174 }
175
176 /*
177 verifyResources method is just to check if the resource handles are correctly saved.
178 */
179 func verifyResources(l gpic.ClusterList, ct appcontext.AppContext, resources []resource, appName string) error {
180
181         for _, cg := range l.ClusterGroups {
182                 gn := cg.GroupNumber
183                 oc := cg.OptionalClusters
184                 for _, eachCluster := range oc {
185                         p := eachCluster.ProviderName
186                         n := eachCluster.ClusterName
187                         cn := p + SEPARATOR + n
188
189                         for _, res := range resources {
190                                 rh, err := ct.GetResourceHandle(appName, cn, res.name)
191                                 if err != nil {
192                                         return pkgerrors.Wrapf(err, "Error getting resoure handle for resource :: %s, app:: %s, cluster :: %s, groupName :: %s", appName, res.name, cn, gn)
193                                 }
194                                 log.Info(":: GetResourceHandle ::", log.Fields{"ResourceHandler": rh, "appName": appName, "Cluster": cn, "Resource": res.name})
195                         }
196                 }
197                 grpMap, err := ct.GetClusterGroupMap(appName)
198                 if err != nil {
199                         return pkgerrors.Wrapf(err, "Error getting GetGroupMap for app:: %s, groupName :: %s", appName, gn)
200                 }
201                 log.Info(":: GetGroupMapReults ::", log.Fields{"GroupMap": grpMap})
202         }
203
204         for _, mc := range l.MandatoryClusters {
205                 p := mc.ProviderName
206                 n := mc.ClusterName
207                 cn := p + SEPARATOR + n
208                 for _, res := range resources {
209                         rh, err := ct.GetResourceHandle(appName, cn, res.name)
210                         if err != nil {
211                                 return pkgerrors.Wrapf(err, "Error getting resoure handle for resource :: %s, app:: %s, cluster :: %s", appName, res.name, cn)
212                         }
213                         log.Info(":: GetResourceHandle ::", log.Fields{"ResourceHandler": rh, "appName": appName, "Cluster": cn, "Resource": res.name})
214                 }
215         }
216         return nil
217 }