Add support for so integration
[multicloud/k8s.git] / src / k8splugin / api / brokerhandler.go
1 /*
2 Copyright 2018 Intel Corporation.
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6     http://www.apache.org/licenses/LICENSE-2.0
7 Unless required by applicable law or agreed to in writing, software
8 distributed under the License is distributed on an "AS IS" BASIS,
9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 See the License for the specific language governing permissions and
11 limitations under the License.
12 */
13
14 package api
15
16 import (
17         "encoding/json"
18         "io"
19         "net/http"
20
21         "k8splugin/internal/app"
22
23         "github.com/gorilla/mux"
24 )
25
26 // Used to store the backend implementation objects
27 // Also simplifies the mocking needed for unit testing
28 type brokerInstanceHandler struct {
29         // Interface that implements the Instance operations
30         client app.InstanceManager
31 }
32
33 type brokerRequest struct {
34         GenericVnfID                 string                 `json:"generic-vnf-id"`
35         VFModuleID                   string                 `json:"vf-module-id"`
36         VFModuleModelInvariantID     string                 `json:"vf-module-model-invariant-id"`
37         VFModuleModelVersionID       string                 `json:"vf-module-model-version-id"`
38         VFModuleModelCustomizationID string                 `json:"vf-module-model-customization-id"`
39         OOFDirectives                map[string]interface{} `json:"oof_directives"`
40         SDNCDirections               map[string]interface{} `json:"sdnc_directives"`
41         UserDirectives               map[string]interface{} `json:"user_directives"`
42         TemplateType                 string                 `json:"template_type"`
43         TemplateData                 map[string]interface{} `json:"template_data"`
44 }
45
46 type brokerPOSTResponse struct {
47         TemplateType     string              `json:"template_type"`
48         WorkloadID       string              `json:"workload_id"`
49         TemplateResponse map[string][]string `json:"template_response"`
50 }
51
52 type brokerGETResponse struct {
53         TemplateType   string `json:"template_type"`
54         WorkloadID     string `json:"workload_id"`
55         WorkloadStatus string `json:"workload_status"`
56 }
57
58 func (b brokerInstanceHandler) createHandler(w http.ResponseWriter, r *http.Request) {
59         vars := mux.Vars(r)
60         cloudRegion := vars["cloud-region"]
61
62         var req brokerRequest
63         err := json.NewDecoder(r.Body).Decode(&req)
64         switch {
65         case err == io.EOF:
66                 http.Error(w, "Body empty", http.StatusBadRequest)
67                 return
68         case err != nil:
69                 http.Error(w, err.Error(), http.StatusUnprocessableEntity)
70                 return
71         }
72
73         // Check body for expected parameters
74         if req.VFModuleModelCustomizationID == "" {
75                 http.Error(w, "vf-module-model-customization-id is empty", http.StatusBadRequest)
76                 return
77         }
78
79         rbName, ok := req.UserDirectives["definition-name"]
80         if !ok {
81                 http.Error(w, "definition-name is missing from user-directives", http.StatusBadRequest)
82                 return
83         }
84
85         rbVersion, ok := req.UserDirectives["definition-version"]
86         if !ok {
87                 http.Error(w, "definition-version is missing from user-directives", http.StatusBadRequest)
88                 return
89         }
90
91         profileName, ok := req.UserDirectives["profile-name"]
92         if !ok {
93                 http.Error(w, "profile-name is missing from user-directives", http.StatusBadRequest)
94                 return
95         }
96
97         // Setup the resource parameters for making the request
98         var instReq app.InstanceRequest
99         instReq.RBName = rbName.(string)
100         instReq.RBVersion = rbVersion.(string)
101         instReq.ProfileName = profileName.(string)
102         instReq.CloudRegion = cloudRegion
103
104         resp, err := b.client.Create(instReq)
105         if err != nil {
106                 http.Error(w, err.Error(), http.StatusInternalServerError)
107                 return
108         }
109
110         brokerResp := brokerPOSTResponse{
111                 TemplateType:     "heat",
112                 WorkloadID:       resp.ID,
113                 TemplateResponse: resp.Resources,
114         }
115
116         w.Header().Set("Content-Type", "application/json")
117         w.WriteHeader(http.StatusCreated)
118         err = json.NewEncoder(w).Encode(brokerResp)
119         if err != nil {
120                 http.Error(w, err.Error(), http.StatusInternalServerError)
121                 return
122         }
123 }
124
125 // getHandler retrieves information about an instance via the ID
126 func (b brokerInstanceHandler) getHandler(w http.ResponseWriter, r *http.Request) {
127         vars := mux.Vars(r)
128         instanceID := vars["instID"]
129
130         resp, err := b.client.Get(instanceID)
131         if err != nil {
132                 http.Error(w, err.Error(), http.StatusInternalServerError)
133                 return
134         }
135
136         brokerResp := brokerGETResponse{
137                 TemplateType:   "heat",
138                 WorkloadID:     resp.ID,
139                 WorkloadStatus: "CREATED",
140         }
141
142         w.Header().Set("Content-Type", "application/json")
143         w.WriteHeader(http.StatusOK)
144         err = json.NewEncoder(w).Encode(brokerResp)
145         if err != nil {
146                 http.Error(w, err.Error(), http.StatusInternalServerError)
147                 return
148         }
149 }
150
151 // deleteHandler method terminates an instance via the ID
152 func (b brokerInstanceHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
153         vars := mux.Vars(r)
154         instanceID := vars["instID"]
155
156         err := b.client.Delete(instanceID)
157         if err != nil {
158                 http.Error(w, err.Error(), http.StatusInternalServerError)
159                 return
160         }
161
162         w.Header().Set("Content-Type", "application/json")
163         w.WriteHeader(http.StatusAccepted)
164 }