add python compatibility module
[multicloud/k8s.git] / src / orchestrator / pkg / module / app.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 governinog permissions and
14  * limitations under the License.
15  */
16
17 package module
18
19 import (
20         "encoding/json"
21
22         "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
23
24         pkgerrors "github.com/pkg/errors"
25 )
26
27 // App contains metadata for Apps
28 type App struct {
29         Metadata AppMetaData `json:"metadata"`
30 }
31
32 //AppMetaData contains the parameters needed for Apps
33 type AppMetaData struct {
34         Name        string `json:"name"`
35         Description string `json:"description"`
36         UserData1   string `json:"userData1"`
37         UserData2   string `json:"userData2"`
38 }
39
40 //AppContent contains fileContent
41 type AppContent struct {
42         FileContent string
43 }
44
45 // AppKey is the key structure that is used in the database
46 type AppKey struct {
47         App                 string `json:"app"`
48         Project             string `json:"project"`
49         CompositeApp        string `json:"compositeapp"`
50         CompositeAppVersion string `json:"compositeappversion"`
51 }
52
53 // We will use json marshalling to convert to string to
54 // preserve the underlying structure.
55 func (aK AppKey) String() string {
56         out, err := json.Marshal(aK)
57         if err != nil {
58                 return ""
59         }
60         return string(out)
61 }
62
63 // AppManager is an interface exposes the App functionality
64 type AppManager interface {
65         CreateApp(a App, ac AppContent, p string, cN string, cV string) (App, error)
66         GetApp(name string, p string, cN string, cV string) (App, error)
67         GetAppContent(name string, p string, cN string, cV string) (AppContent, error)
68         GetApps(p string, cN string, cV string) ([]App, error)
69         DeleteApp(name string, p string, cN string, cV string) error
70 }
71
72 // AppClient implements the AppManager
73 // It will also be used to maintain some localized state
74 type AppClient struct {
75         storeName           string
76         tagMeta, tagContent string
77 }
78
79 // NewAppClient returns an instance of the AppClient
80 // which implements the AppManager
81 func NewAppClient() *AppClient {
82         return &AppClient{
83                 storeName:  "orchestrator",
84                 tagMeta:    "appmetadata",
85                 tagContent: "appcontent",
86         }
87 }
88
89 // CreateApp creates a new collection based on the App
90 func (v *AppClient) CreateApp(a App, ac AppContent, p string, cN string, cV string) (App, error) {
91
92         //Construct the composite key to select the entry
93         key := AppKey{
94                 App:                 a.Metadata.Name,
95                 Project:             p,
96                 CompositeApp:        cN,
97                 CompositeAppVersion: cV,
98         }
99
100         //Check if this App already exists
101         _, err := v.GetApp(a.Metadata.Name, p, cN, cV)
102         if err == nil {
103                 return App{}, pkgerrors.New("App already exists")
104         }
105
106         //Check if Project exists
107         _, err = NewProjectClient().GetProject(p)
108         if err != nil {
109                 return App{}, pkgerrors.New("Unable to find the project")
110         }
111
112         //check if CompositeApp with version exists
113         _, err = NewCompositeAppClient().GetCompositeApp(cN, cV, p)
114         if err != nil {
115                 return App{}, pkgerrors.New("Unable to find the composite app with version")
116         }
117
118         err = db.DBconn.Insert(v.storeName, key, nil, v.tagMeta, a)
119         if err != nil {
120                 return App{}, pkgerrors.Wrap(err, "Creating DB Entry")
121         }
122
123         err = db.DBconn.Insert(v.storeName, key, nil, v.tagContent, ac)
124         if err != nil {
125                 return App{}, pkgerrors.Wrap(err, "Creating DB Entry")
126         }
127
128         return a, nil
129 }
130
131 // GetApp returns the App for corresponding name
132 func (v *AppClient) GetApp(name string, p string, cN string, cV string) (App, error) {
133
134         //Construct the composite key to select the entry
135         key := AppKey{
136                 App:                 name,
137                 Project:             p,
138                 CompositeApp:        cN,
139                 CompositeAppVersion: cV,
140         }
141         value, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
142         if err != nil {
143                 return App{}, pkgerrors.Wrap(err, "Get app")
144         }
145
146         //value is a byte array
147         if value != nil {
148                 app := App{}
149                 err = db.DBconn.Unmarshal(value[0], &app)
150                 if err != nil {
151                         return App{}, pkgerrors.Wrap(err, "Unmarshaling Value")
152                 }
153                 return app, nil
154         }
155
156         return App{}, pkgerrors.New("Error getting app")
157 }
158
159 // GetAppContent returns content for corresponding app
160 func (v *AppClient) GetAppContent(name string, p string, cN string, cV string) (AppContent, error) {
161
162         //Construct the composite key to select the entry
163         key := AppKey{
164                 App:                 name,
165                 Project:             p,
166                 CompositeApp:        cN,
167                 CompositeAppVersion: cV,
168         }
169         value, err := db.DBconn.Find(v.storeName, key, v.tagContent)
170         if err != nil {
171                 return AppContent{}, pkgerrors.Wrap(err, "Get app content")
172         }
173
174         //value is a byte array
175         if value != nil {
176                 ac := AppContent{}
177                 err = db.DBconn.Unmarshal(value[0], &ac)
178                 if err != nil {
179                         return AppContent{}, pkgerrors.Wrap(err, "Unmarshaling Value")
180                 }
181                 return ac, nil
182         }
183
184         return AppContent{}, pkgerrors.New("Error getting app content")
185 }
186
187 // GetApps returns all Apps for given composite App
188 func (v *AppClient) GetApps(project, compositeApp, compositeAppVersion string) ([]App, error) {
189
190         key := AppKey{
191                 App:                 "",
192                 Project:             project,
193                 CompositeApp:        compositeApp,
194                 CompositeAppVersion: compositeAppVersion,
195         }
196
197         var resp []App
198         values, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
199         if err != nil {
200                 return []App{}, pkgerrors.Wrap(err, "Get Apps")
201         }
202
203         for _, value := range values {
204                 a := App{}
205                 err = db.DBconn.Unmarshal(value, &a)
206                 if err != nil {
207                         return []App{}, pkgerrors.Wrap(err, "Unmarshaling Value")
208                 }
209                 resp = append(resp, a)
210         }
211
212         return resp, nil
213 }
214
215 // DeleteApp deletes the  App from database
216 func (v *AppClient) DeleteApp(name string, p string, cN string, cV string) error {
217
218         //Construct the composite key to select the entry
219         key := AppKey{
220                 App:                 name,
221                 Project:             p,
222                 CompositeApp:        cN,
223                 CompositeAppVersion: cV,
224         }
225         err := db.DBconn.Remove(v.storeName, key)
226         if err != nil {
227                 return pkgerrors.Wrap(err, "Delete App Entry;")
228         }
229
230         return nil
231 }