2 * Copyright 2020 Huawei Technologies Co., Ltd.
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.
20 "broker/pkg/handlers/adapter/dbAdapter"
21 "broker/pkg/handlers/adapter/pluginAdapter"
22 "broker/pkg/handlers/common"
23 "broker/pkg/handlers/model"
27 "github.com/buger/jsonparser"
28 "github.com/ghodss/yaml"
29 "github.com/google/uuid"
30 "github.com/gorilla/mux"
31 "github.com/jinzhu/gorm"
41 func UploadFileHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
43 file, header, err := r.FormFile("file")
46 common.RespondError(w, http.StatusBadRequest, err.Error())
50 buf := bytes.NewBuffer(nil)
51 if _, err := io.Copy(buf, file); err != nil {
52 common.RespondError(w, http.StatusBadRequest, err.Error())
57 f := strings.Split(header.Filename, ".")
61 fmt.Println(packageName)
63 pkgPath := PackageFolderPath + header.Filename
64 newFile, err := os.Create(pkgPath)
66 common.RespondError(w, http.StatusInternalServerError, err.Error())
71 if _, err := newFile.Write(buf.Bytes()); err != nil {
72 common.RespondError(w, http.StatusInternalServerError, err.Error())
76 /* Unzip package to decode appDescriptor */
77 openPackage(w, pkgPath)
79 var yamlFile = PackageFolderPath + packageName + "/Definitions/" + "MainServiceTemplate.yaml"
80 appPkgInfo := decodeApplicationDescriptor(w, yamlFile)
81 appPkgInfo.AppPackage = header.Filename
82 appPkgInfo.OnboardingState = "ONBOARDED"
84 log.Println("Application package info from package")
87 dbAdapter.InsertAppPackageInfo(db, appPkgInfo)
90 common.RespondJSON(w, http.StatusCreated, appPkgInfo)
93 func openPackage(w http.ResponseWriter, packagePath string) {
94 zipReader, _ := zip.OpenReader(packagePath)
95 for _, file := range zipReader.Reader.File {
97 zippedFile, err := file.Open()
99 common.RespondError(w, http.StatusBadRequest, err.Error())
101 defer zippedFile.Close()
103 targetDir := PackageFolderPath + "/"
104 extractedFilePath := filepath.Join(
109 if file.FileInfo().IsDir() {
110 os.MkdirAll(extractedFilePath, file.Mode())
112 outputFile, err := os.OpenFile(
114 os.O_WRONLY|os.O_CREATE|os.O_TRUNC,
118 common.RespondError(w, http.StatusBadRequest, err.Error())
120 defer outputFile.Close()
122 _, err = io.Copy(outputFile, zippedFile)
124 common.RespondError(w, http.StatusBadRequest, err.Error())
130 func decodeApplicationDescriptor(w http.ResponseWriter, serviceTemplate string) model.AppPackageInfo {
132 yamlFile, err := ioutil.ReadFile(serviceTemplate)
134 common.RespondError(w, http.StatusBadRequest, err.Error())
137 jsondata, err := yaml.YAMLToJSON(yamlFile)
139 common.RespondError(w, http.StatusBadRequest, err.Error())
142 appDId, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appDId")
143 appProvider, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appProvider")
144 appInfoName, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appInfoName")
145 appSoftVersion, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appSoftVersion")
146 appDVersion, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appDVersion")
147 deployType, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "type")
149 appPkgInfo := model.AppPackageInfo{
151 AppDID: string(appDId),
152 AppProvider: string(appProvider),
153 AppName: string(appInfoName),
154 AppSoftwareVersion: string(appSoftVersion),
155 AppDVersion: string(appDVersion),
156 DeployType: string(deployType),
159 //return appPackageInfo
163 func QueryAppPackageInfo(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
164 params := mux.Vars(r)
165 appPkgId := params["appPkgId"]
166 appPkgInfo := dbAdapter.GetAppPackageInfo(db, appPkgId)
167 if appPkgInfo.ID == "" {
168 common.RespondJSON(w, http.StatusNotFound, "ID not exist")
171 common.RespondJSON(w, http.StatusAccepted, json.NewEncoder(w).Encode(appPkgInfo))
174 func DeleteAppPackage(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
175 params := mux.Vars(r)
176 appPkgId := params["appPkgId"]
177 appPackageInfo := dbAdapter.GetAppPackageInfo(db, appPkgId)
178 if appPackageInfo.ID == "" {
179 common.RespondJSON(w, http.StatusNotFound, "ID not exist")
182 dbAdapter.DeleteAppPackageInfo(db, appPkgId)
184 deletePackage := PackageFolderPath + appPackageInfo.AppPackage
187 os.Remove(deletePackage)
188 f := strings.Split(appPackageInfo.AppPackage, ".")
192 os.Remove(packageName)
194 common.RespondJSON(w, http.StatusAccepted, json.NewEncoder(w).Encode(""))
197 func CreateAppInstanceHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
198 var req model.CreateApplicationReq
199 err := json.NewDecoder(r.Body).Decode(&req)
201 common.RespondError(w, http.StatusInternalServerError, err.Error())
205 appPkgInfo := dbAdapter.GetAppPackageInfo(db, req.AppDID)
206 if appPkgInfo.ID == "" {
207 common.RespondJSON(w, http.StatusNotFound, "ID not exist")
210 fmt.Println("Query appPkg Info:", appPkgInfo)
212 appInstanceId, err := uuid.NewUUID()
214 common.RespondError(w, http.StatusInternalServerError, err.Error())
217 appInstanceInfo := model.AppInstanceInfo{
219 ID: appInstanceId.String(),
220 AppInstanceName: req.AppInstancename,
221 AppInstanceDescription: req.AppInstanceDescriptor,
223 AppProvider: appPkgInfo.AppProvider,
224 AppName: appPkgInfo.AppName,
225 AppSoftVersion: appPkgInfo.AppSoftwareVersion,
226 AppDVersion: appPkgInfo.AppDVersion,
227 AppPkgID: appPkgInfo.AppDID,
228 InstantiationState: "NOT_INSTANTIATED",
230 dbAdapter.InsertAppInstanceInfo(db, appInstanceInfo)
231 fmt.Println("CreateAppInstanceHldr:", req)
233 common.RespondJSON(w, http.StatusCreated, json.NewEncoder(w).Encode(appInstanceInfo))
236 func InstantiateAppInstanceHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
237 var req model.InstantiateApplicationReq
238 err := json.NewDecoder(r.Body).Decode(&req)
240 common.RespondError(w, http.StatusInternalServerError, err.Error())
244 params := mux.Vars(r)
245 appInstanceId := params["appInstanceId"]
247 appInstanceInfo := dbAdapter.GetAppInstanceInfo(db, appInstanceId)
248 appPackageInfo := dbAdapter.GetAppPackageInfo(db, appInstanceInfo.AppDID)
249 if appInstanceInfo.ID == "" || appPackageInfo.ID == "" {
250 common.RespondJSON(w, http.StatusNotFound, "ID not exist")
254 if appInstanceInfo.InstantiationState == "INSTANTIATED" {
255 common.RespondError(w, http.StatusInternalServerError, "Application already instantiated")
261 f := strings.Split(appPackageInfo.AppPackage, ".")
265 fmt.Println(packageName)
268 var pluginInfo string
270 switch appPackageInfo.DeployType {
272 pkgPath := PackageFolderPath + packageName + PackageArtifactPath + "Charts"
273 artifact = getDeploymentArtifact(pkgPath, ".tar")
275 common.RespondError(w, http.StatusInternalServerError, "artifact not available in application package")
278 pluginInfo = "helm.plugin" + ":" + os.Getenv("HELM_PLUGIN_PORT")
280 pkgPath := PackageFolderPath + packageName + PackageArtifactPath + "Kubernetes"
281 artifact = getDeploymentArtifact(pkgPath, "*.yaml")
283 common.RespondError(w, http.StatusInternalServerError, "artifact not available in application package")
286 pluginInfo = "kubernetes.plugin" + ":" + os.Getenv("KUBERNETES_PLUGIN_PORT")
288 common.RespondError(w, http.StatusInternalServerError, "Deployment type not supported")
291 fmt.Println("Artifact to deploy:", artifact)
293 workloadId, err := pluginAdapter.Instantiate(pluginInfo, req.SelectedMECHostInfo.HostID, artifact)
295 common.RespondError(w, http.StatusInternalServerError, err.Error())
298 dbAdapter.UpdateAppInstanceInfoInstStatusHostAndWorkloadId(db, appInstanceId, "INSTANTIATED", req.SelectedMECHostInfo.HostID, workloadId)
300 common.RespondJSON(w, http.StatusAccepted, json.NewEncoder(w).Encode(""))
303 func getDeploymentArtifact(dir string, ext string) string {
304 d, err := os.Open(dir)
311 files, err := d.Readdir(-1)
317 fmt.Println("Directory to read " + dir)
319 for _, file := range files {
320 if file.Mode().IsRegular() {
321 if filepath.Ext(file.Name()) == ext || filepath.Ext(file.Name()) == ".gz" {
322 fmt.Println(file.Name())
323 fmt.Println(dir + "/" + file.Name())
324 return dir + "/" + file.Name()
331 func QueryAppInstanceInfoHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
333 params := mux.Vars(r)
334 appInstanceId := params["appInstanceId"]
336 appInstanceInfo := dbAdapter.GetAppInstanceInfo(db, appInstanceId)
337 appPackageInfo := dbAdapter.GetAppPackageInfo(db, appInstanceInfo.AppDID)
338 if appInstanceInfo.ID == "" || appPackageInfo.ID == "" {
339 common.RespondJSON(w, http.StatusNotFound, "ID not exist")
342 var instantiatedAppState string
343 if appInstanceInfo.InstantiationState == "INSTANTIATED" {
345 var pluginInfo string
347 switch appPackageInfo.DeployType {
349 pluginInfo = "helm.plugin" + ":" + os.Getenv("HELM_PLUGIN_PORT")
351 pluginInfo = "kubernetes.plugin" + ":" + os.Getenv("KUBERNETES_PLUGIN_PORT")
353 common.RespondError(w, http.StatusInternalServerError, "Deployment type not supported")
357 state, err := pluginAdapter.Query(pluginInfo, appInstanceInfo.Host, appInstanceInfo.WorkloadID)
359 common.RespondError(w, http.StatusInternalServerError, err.Error())
362 instantiatedAppState = state
364 appInstanceInfo.InstantiatedAppState = instantiatedAppState
366 common.RespondJSON(w, http.StatusCreated, json.NewEncoder(w).Encode(appInstanceInfo))
369 func QueryAppLcmOperationStatusHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
370 var req model.QueryApplicationLCMOperStatusReq
371 err := json.NewDecoder(r.Body).Decode(&req)
373 common.RespondError(w, http.StatusInternalServerError, err.Error())
377 fmt.Fprintf(w, "QueryApplicationLCMOperStatus: %+v", req)
380 func TerminateAppInsHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
381 log.Println("TerminateAppInsHldr...")
382 params := mux.Vars(r)
383 appInstanceId := params["appInstanceId"]
385 appInstanceInfo := dbAdapter.GetAppInstanceInfo(db, appInstanceId)
386 appPackageInfo := dbAdapter.GetAppPackageInfo(db, appInstanceInfo.AppDID)
387 if appInstanceInfo.ID == "" || appPackageInfo.ID == "" {
388 common.RespondJSON(w, http.StatusNotFound, "ID not exist")
392 if appInstanceInfo.InstantiationState == "NOT_INSTANTIATED" {
393 common.RespondError(w, http.StatusNotAcceptable, "instantiationState: NOT_INSTANTIATED")
397 var pluginInfo string
398 switch appPackageInfo.DeployType {
400 pluginInfo = "helm.plugin" + ":" + os.Getenv("HELM_PLUGIN_PORT")
402 pluginInfo = "kubernetes.plugin" + ":" + os.Getenv("KUBERNETES_PLUGIN_PORT")
404 common.RespondError(w, http.StatusInternalServerError, "Deployment type not supported")
408 _, err := pluginAdapter.Terminate(pluginInfo, appInstanceInfo.Host, appInstanceInfo.WorkloadID)
410 common.RespondError(w, http.StatusInternalServerError, err.Error())
413 dbAdapter.UpdateAppInstanceInfoInstStatusAndWorkload(db, appInstanceId, "NOT_INSTANTIATED", "")
415 common.RespondJSON(w, http.StatusAccepted, json.NewEncoder(w).Encode(""))
417 func DeleteAppInstanceIdentifierHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) {
418 fmt.Println("DeleteAppInstanceIdentifierHldr:")
419 params := mux.Vars(r)
420 appInstanceId := params["appInstanceId"]
422 dbAdapter.DeleteAppInstanceInfo(db, appInstanceId)
423 common.RespondJSON(w, http.StatusOK, json.NewEncoder(w).Encode(""))