Make GRPC calls and delete extra cluster handles
[multicloud/k8s.git] / src / orchestrator / pkg / module / instantiation_scheduler_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 import (
20         "container/heap"
21
22         "fmt"
23
24         "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
25         client "github.com/onap/multicloud-k8s/src/orchestrator/pkg/grpc/contextupdateclient"
26         log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
27         "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module/controller"
28         mtypes "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module/types"
29 )
30
31 // ControllerTypePlacement denotes "placement" Controller Type
32 const ControllerTypePlacement string = "placement"
33
34 // ControllerTypeAction denotes "action" Controller Type
35 const ControllerTypeAction string = "action"
36
37 // ControllerElement consists of controller and an internal field - index
38 type ControllerElement struct {
39         controller controller.Controller
40         index      int // used for indexing the HeapArray
41 }
42
43 // PrioritizedControlList contains PrioritizedList of PlacementControllers and ActionControllers
44 type PrioritizedControlList struct {
45         pPlaCont []controller.Controller
46         pActCont []controller.Controller
47 }
48
49 // PriorityQueue is the heapArray to store the Controllers
50 type PriorityQueue []*ControllerElement
51
52 func (pq PriorityQueue) Len() int { return len(pq) }
53
54 func (pq PriorityQueue) Less(i, j int) bool {
55         // We want Pop to give us highest Priority controller
56         // The lower the number, higher the priority
57         return pq[i].controller.Spec.Priority < pq[j].controller.Spec.Priority
58 }
59
60 // Pop method returns the controller with the highest priority
61 func (pq *PriorityQueue) Pop() interface{} {
62         old := *pq
63         n := len(old)
64         c := old[n-1]
65         c.index = -1
66         *pq = old[0 : n-1]
67         return c
68 }
69
70 // Push method add a controller into the heapArray
71 func (pq *PriorityQueue) Push(c interface{}) {
72         n := len(*pq)
73         controllerElement := c.(*ControllerElement)
74         controllerElement.index = n
75         *pq = append(*pq, controllerElement)
76 }
77
78 func (pq PriorityQueue) Swap(i, j int) {
79         pq[i], pq[j] = pq[j], pq[i]
80         pq[i].index = i
81         pq[j].index = j
82 }
83
84 func getPrioritizedControllerList(p, ca, v, di string) (PrioritizedControlList, map[string]string, error) {
85         listOfControllers := make([]string, 0) // shall contain the real controllerNames to be passed to controllerAPI
86         mapOfControllers := make(map[string]string)
87
88         iList, err := NewIntentClient().GetAllIntents(p, ca, v, di)
89         if err != nil {
90                 return PrioritizedControlList{}, map[string]string{}, err
91         }
92         for _, eachmap := range iList.ListOfIntents {
93                 for controller, controllerIntent := range eachmap {
94                         if controller != GenericPlacementIntentName {
95                                 listOfControllers = append(listOfControllers, controller)
96                                 mapOfControllers[controller] = controllerIntent
97                         }
98                 }
99         }
100
101         listPC := make([]*ControllerElement, 0)
102         listAC := make([]*ControllerElement, 0)
103
104         for _, cn := range listOfControllers {
105                 c, err := NewClient().Controller.GetController(cn)
106
107                 if err != nil {
108                         return PrioritizedControlList{}, map[string]string{}, err
109                 }
110                 if c.Spec.Type == ControllerTypePlacement {
111                         // Collect in listPC
112                         listPC = append(listPC, &ControllerElement{controller: controller.Controller{
113                                 Metadata: mtypes.Metadata{
114                                         Name:        c.Metadata.Name,
115                                         Description: c.Metadata.Description,
116                                         UserData1:   c.Metadata.UserData1,
117                                         UserData2:   c.Metadata.UserData2,
118                                 },
119                                 Spec: controller.ControllerSpec{
120                                         Host:     c.Spec.Host,
121                                         Port:     c.Spec.Port,
122                                         Type:     c.Spec.Type,
123                                         Priority: c.Spec.Priority,
124                                 },
125                         }})
126                 } else if c.Spec.Type == ControllerTypeAction {
127                         // Collect in listAC
128                         listAC = append(listAC, &ControllerElement{controller: controller.Controller{
129                                 Metadata: mtypes.Metadata{
130                                         Name:        c.Metadata.Name,
131                                         Description: c.Metadata.Description,
132                                         UserData1:   c.Metadata.UserData1,
133                                         UserData2:   c.Metadata.UserData2,
134                                 },
135                                 Spec: controller.ControllerSpec{
136                                         Host:     c.Spec.Host,
137                                         Port:     c.Spec.Port,
138                                         Type:     c.Spec.Type,
139                                         Priority: c.Spec.Priority,
140                                 },
141                         }})
142                 } else {
143                         log.Info("Controller type undefined", log.Fields{"Controller type": c.Spec.Type, "ControllerName": c.Metadata.Name})
144                 }
145         }
146
147         pqPlacementCont := make(PriorityQueue, len(listPC))
148         for i, eachPC := range listPC {
149                 pqPlacementCont[i] = &ControllerElement{controller: eachPC.controller, index: i}
150         }
151         prioritizedPlaControllerList := make([]controller.Controller, 0)
152         heap.Init(&pqPlacementCont)
153         for pqPlacementCont.Len() > 0 {
154                 ce := heap.Pop(&pqPlacementCont).(*ControllerElement)
155
156                 prioritizedPlaControllerList = append(prioritizedPlaControllerList, ce.controller)
157         }
158
159         pqActionCont := make(PriorityQueue, len(listAC))
160         for i, eachAC := range listAC {
161                 pqActionCont[i] = &ControllerElement{controller: eachAC.controller, index: i}
162         }
163         prioritizedActControllerList := make([]controller.Controller, 0)
164         heap.Init(&pqActionCont)
165         for pqActionCont.Len() > 0 {
166                 ce := heap.Pop(&pqActionCont).(*ControllerElement)
167                 prioritizedActControllerList = append(prioritizedActControllerList, ce.controller)
168         }
169
170         prioritizedControlList := PrioritizedControlList{pPlaCont: prioritizedPlaControllerList, pActCont: prioritizedActControllerList}
171
172         return prioritizedControlList, mapOfControllers, nil
173
174 }
175
176 /*
177 callGrpcForControllerList method shall take in a list of controllers, a map of contollers to controllerIntentNames and contextID. It invokes the context
178 updation through the grpc client for the given list of controllers.
179 */
180 func callGrpcForControllerList(cl []controller.Controller, mc map[string]string, contextid interface{}) error {
181         for _, c := range cl {
182                 controller := c.Metadata.Name
183                 controllerIntentName := mc[controller]
184                 appContextID := fmt.Sprintf("%v", contextid)
185                 err := client.InvokeContextUpdate(controller, controllerIntentName, appContextID)
186                 if err != nil {
187                         return err
188                 }
189         }
190         return nil
191 }
192
193 /*
194 deleteExtraClusters method shall delete the extra cluster handles for each AnyOf cluster present in the etcd after the grpc call for context updation.
195 */
196 func deleteExtraClusters(apps []App, ct appcontext.AppContext) error {
197         for _, app := range apps {
198                 an := app.Metadata.Name
199                 gmap, err := ct.GetClusterGroupMap(an)
200                 if err != nil {
201                         return err
202                 }
203                 for gr, cl := range gmap {
204                         for i, cn := range cl {
205                                 // avoids deleting the first cluster
206                                 if i > 0 {
207                                         ch, err := ct.GetClusterHandle(an, cn)
208                                         if err != nil {
209                                                 return err
210                                         }
211                                         err = ct.DeleteCluster(ch)
212                                         if err != nil {
213                                                 return err
214                                         }
215                                         log.Info("::Deleted cluster for::", log.Fields{"appName": an, "GroupNumber": gr, "ClusterName": cn})
216                                 }
217                         }
218
219                 }
220         }
221         return nil
222 }