2 * Copyright 2020 Intel Corporation, Inc
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
25 "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
26 "github.com/onap/multicloud-k8s/src/orchestrator/pkg/state"
28 pkgerrors "github.com/pkg/errors"
31 // DeploymentIntentGroup shall have 2 fields - MetaData and Spec
32 type DeploymentIntentGroup struct {
33 MetaData DepMetaData `json:"metadata"`
34 Spec DepSpecData `json:"spec"`
37 // DepMetaData has Name, description, userdata1, userdata2
38 type DepMetaData struct {
39 Name string `json:"name"`
40 Description string `json:"description"`
41 UserData1 string `json:"userData1"`
42 UserData2 string `json:"userData2"`
45 // DepSpecData has profile, version, OverrideValuesObj
46 type DepSpecData struct {
47 Profile string `json:"profile"`
48 Version string `json:"version"`
49 OverrideValuesObj []OverrideValues `json:"override-values"`
50 LogicalCloud string `json:"logical-cloud"`
53 // OverrideValues has appName and ValuesObj
54 type OverrideValues struct {
55 AppName string `json:"app-name"`
56 ValuesObj map[string]string `json:"values"`
59 // Values has ImageRepository
60 // type Values struct {
61 // ImageRepository string `json:"imageRepository"`
64 // DeploymentIntentGroupManager is an interface which exposes the DeploymentIntentGroupManager functionality
65 type DeploymentIntentGroupManager interface {
66 CreateDeploymentIntentGroup(d DeploymentIntentGroup, p string, ca string, v string) (DeploymentIntentGroup, error)
67 GetDeploymentIntentGroup(di string, p string, ca string, v string) (DeploymentIntentGroup, error)
68 GetDeploymentIntentGroupState(di string, p string, ca string, v string) (state.StateInfo, error)
69 DeleteDeploymentIntentGroup(di string, p string, ca string, v string) error
70 GetAllDeploymentIntentGroups(p string, ca string, v string) ([]DeploymentIntentGroup, error)
73 // DeploymentIntentGroupKey consists of Name of the deployment group, project name, CompositeApp name, CompositeApp version
74 type DeploymentIntentGroupKey struct {
75 Name string `json:"deploymentintentgroup"`
76 Project string `json:"project"`
77 CompositeApp string `json:"compositeapp"`
78 Version string `json:"compositeappversion"`
81 // We will use json marshalling to convert to string to
82 // preserve the underlying structure.
83 func (dk DeploymentIntentGroupKey) String() string {
84 out, err := json.Marshal(dk)
91 // DeploymentIntentGroupClient implements the DeploymentIntentGroupManager interface
92 type DeploymentIntentGroupClient struct {
98 // NewDeploymentIntentGroupClient return an instance of DeploymentIntentGroupClient which implements DeploymentIntentGroupManager
99 func NewDeploymentIntentGroupClient() *DeploymentIntentGroupClient {
100 return &DeploymentIntentGroupClient{
101 storeName: "orchestrator",
102 tagMetaData: "deploymentintentgroupmetadata",
103 tagState: "stateInfo",
107 // CreateDeploymentIntentGroup creates an entry for a given DeploymentIntentGroup in the database. Other Input parameters for it - projectName, compositeAppName, version
108 func (c *DeploymentIntentGroupClient) CreateDeploymentIntentGroup(d DeploymentIntentGroup, p string, ca string,
109 v string) (DeploymentIntentGroup, error) {
111 res, err := c.GetDeploymentIntentGroup(d.MetaData.Name, p, ca, v)
112 if !reflect.DeepEqual(res, DeploymentIntentGroup{}) {
113 return DeploymentIntentGroup{}, pkgerrors.New("DeploymentIntent already exists")
116 //Check if project exists
117 _, err = NewProjectClient().GetProject(p)
119 return DeploymentIntentGroup{}, pkgerrors.New("Unable to find the project")
122 //check if compositeApp exists
123 _, err = NewCompositeAppClient().GetCompositeApp(ca, v, p)
125 return DeploymentIntentGroup{}, pkgerrors.New("Unable to find the composite-app")
128 gkey := DeploymentIntentGroupKey{
129 Name: d.MetaData.Name,
135 err = db.DBconn.Insert(c.storeName, gkey, nil, c.tagMetaData, d)
137 return DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Create DB entry error")
140 // Add the stateInfo record
141 s := state.StateInfo{}
142 a := state.ActionEntry{
143 State: state.StateEnum.Created,
145 TimeStamp: time.Now(),
147 s.Actions = append(s.Actions, a)
149 err = db.DBconn.Insert(c.storeName, gkey, nil, c.tagState, s)
151 return DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Error updating the stateInfo of the DeploymentIntentGroup: "+d.MetaData.Name)
157 // GetDeploymentIntentGroup returns the DeploymentIntentGroup with a given name, project, compositeApp and version of compositeApp
158 func (c *DeploymentIntentGroupClient) GetDeploymentIntentGroup(di string, p string, ca string, v string) (DeploymentIntentGroup, error) {
160 key := DeploymentIntentGroupKey{
167 result, err := db.DBconn.Find(c.storeName, key, c.tagMetaData)
169 return DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Get DeploymentIntentGroup error")
173 d := DeploymentIntentGroup{}
174 err = db.DBconn.Unmarshal(result[0], &d)
176 return DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Unmarshalling DeploymentIntentGroup")
181 return DeploymentIntentGroup{}, pkgerrors.New("Error getting DeploymentIntentGroup")
185 // GetAllDeploymentIntentGroups returns all the deploymentIntentGroups under a specific project, compositeApp and version
186 func (c *DeploymentIntentGroupClient) GetAllDeploymentIntentGroups(p string, ca string, v string) ([]DeploymentIntentGroup, error) {
188 key := DeploymentIntentGroupKey{
195 //Check if project exists
196 _, err := NewProjectClient().GetProject(p)
198 return []DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Unable to find the project")
201 //check if compositeApp exists
202 _, err = NewCompositeAppClient().GetCompositeApp(ca, v, p)
204 return []DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Unable to find the composite-app, check CompositeAppName and Version")
206 var diList []DeploymentIntentGroup
207 result, err := db.DBconn.Find(c.storeName, key, c.tagMetaData)
209 return []DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Get DeploymentIntentGroup error")
212 for _, value := range result {
213 di := DeploymentIntentGroup{}
214 err = db.DBconn.Unmarshal(value, &di)
216 return []DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Unmarshaling DeploymentIntentGroup")
218 diList = append(diList, di)
225 // GetDeploymentIntentGroupState returns the AppContent with a given DeploymentIntentname, project, compositeAppName and version of compositeApp
226 func (c *DeploymentIntentGroupClient) GetDeploymentIntentGroupState(di string, p string, ca string, v string) (state.StateInfo, error) {
228 key := DeploymentIntentGroupKey{
235 result, err := db.DBconn.Find(c.storeName, key, c.tagState)
237 return state.StateInfo{}, pkgerrors.Wrap(err, "Get DeploymentIntentGroup StateInfo error")
241 s := state.StateInfo{}
242 err = db.DBconn.Unmarshal(result[0], &s)
244 return state.StateInfo{}, pkgerrors.Wrap(err, "Unmarshalling DeploymentIntentGroup StateInfo")
249 return state.StateInfo{}, pkgerrors.New("Error getting DeploymentIntentGroup StateInfo")
252 // DeleteDeploymentIntentGroup deletes a DeploymentIntentGroup
253 func (c *DeploymentIntentGroupClient) DeleteDeploymentIntentGroup(di string, p string, ca string, v string) error {
254 k := DeploymentIntentGroupKey{
260 s, err := c.GetDeploymentIntentGroupState(di, p, ca, v)
262 return pkgerrors.Errorf("Error getting stateInfo from DeploymentIntentGroup: " + di)
265 stateVal, err := state.GetCurrentStateFromStateInfo(s)
267 return pkgerrors.Errorf("Error getting current state from DeploymentIntentGroup stateInfo: " + di)
270 if stateVal == state.StateEnum.Instantiated {
271 return pkgerrors.Errorf("DeploymentIntentGroup must be terminated before it can be deleted " + di)
274 // remove the app contexts associated with thie Deployment Intent Group
275 if stateVal == state.StateEnum.Terminated {
276 // Verify that the appcontext has completed terminating
277 ctxid := state.GetLastContextIdFromStateInfo(s)
278 acStatus, err := state.GetAppContextStatus(ctxid)
280 !(acStatus.Status == appcontext.AppContextStatusEnum.Terminated || acStatus.Status == appcontext.AppContextStatusEnum.TerminateFailed) {
281 return pkgerrors.Errorf("DeploymentIntentGroup has not completed terminating: " + di)
284 for _, id := range state.GetContextIdsFromStateInfo(s) {
285 context, err := state.GetAppContextFromId(id)
287 return pkgerrors.Wrap(err, "Error getting appcontext from Deployment Intent Group StateInfo")
289 err = context.DeleteCompositeApp()
291 return pkgerrors.Wrap(err, "Error deleting appcontext for Deployment Intent Group")
296 err = db.DBconn.Remove(c.storeName, k)
298 return pkgerrors.Wrap(err, "Error deleting DeploymentIntentGroup entry")