summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKiran Kamineni <kiran.k.kamineni@intel.com>2019-03-15 15:18:12 -0700
committerKiran Kamineni <kiran.k.kamineni@intel.com>2019-03-26 19:19:53 -0700
commitb2b175eae0f4e8b5b0cb9ccbeeca1e98065feeb5 (patch)
treee5a984dd156016b3b615acfd0b903f61e07655ea
parent1ab1af62578c1c2bf7b3b2e56827fe408cabdbb3 (diff)
Update definition and profile to latest spec
Bringing all the definition and profile code upto the latest spec. Integrated the end to end instance code changes that were made. P9: Added updated plugin.sh with updated uri paths based on spec Issue-ID: MULTICLOUD-291 Change-Id: Id6e3c6bc2cd02cfb7005e203ccf03e0793b97e95 Signed-off-by: Kiran Kamineni <kiran.k.kamineni@intel.com>
-rwxr-xr-xkud/tests/plugin.sh65
-rw-r--r--src/k8splugin/api/api.go22
-rw-r--r--src/k8splugin/api/defhandler.go30
-rw-r--r--src/k8splugin/api/defhandler_test.go96
-rw-r--r--src/k8splugin/api/handler.go18
-rw-r--r--src/k8splugin/api/handler_test.go240
-rw-r--r--src/k8splugin/api/model.go4
-rw-r--r--src/k8splugin/api/profilehandler.go57
-rw-r--r--src/k8splugin/api/profilehandler_test.go146
-rw-r--r--src/k8splugin/internal/app/vnfhelper.go18
-rw-r--r--src/k8splugin/internal/app/vnfhelper_test.go31
-rw-r--r--src/k8splugin/internal/db/consul_test.go14
-rw-r--r--src/k8splugin/internal/db/mongo_test.go22
-rw-r--r--src/k8splugin/internal/db/testing.go4
-rw-r--r--src/k8splugin/internal/rb/definition.go95
-rw-r--r--src/k8splugin/internal/rb/definition_test.go171
-rw-r--r--src/k8splugin/internal/rb/profile.go166
-rw-r--r--src/k8splugin/internal/rb/profile_test.go334
-rw-r--r--src/k8splugin/mock_files/mock_json/create_rbdefinition.json8
-rw-r--r--src/k8splugin/mock_files/mock_json/create_rbprofile.json14
20 files changed, 867 insertions, 688 deletions
diff --git a/kud/tests/plugin.sh b/kud/tests/plugin.sh
index d632f844..2de55b61 100755
--- a/kud/tests/plugin.sh
+++ b/kud/tests/plugin.sh
@@ -18,11 +18,12 @@ source _functions.sh
base_url="http://localhost:8081"
cloud_region_id="kud"
-namespace="testNS"
+namespace="testns"
csar_id="94e414f6-9ca4-11e8-bb6a-52540067263b"
-rbd_csar_id="7eb09e38-4363-9942-1234-3beb2e95fd85"
-definition_id="9d117af8-30b8-11e9-af94-525400277b3d"
-profile_id="ebe353d2-30b7-11e9-9515-525400277b3d"
+rb_name="test-rbdef"
+rb_version="v1"
+profile_name="profile1"
+vnf_customization_uuid="ebe353d2-30b7-11e9-9515-525400277b3d"
# _build_generic_sim() - Creates a generic simulator image in case that doesn't exist
function _build_generic_sim {
@@ -58,29 +59,31 @@ destroy_deployment $plugin_deployment_name
#start_aai_service
populate_CSAR_plugin $csar_id
-populate_CSAR_rbdefinition $rbd_csar_id
+populate_CSAR_rbdefinition $csar_id
# Test
print_msg "Create Resource Bundle Definition Metadata"
payload_raw="
{
- \"name\": \"test-rbdef\",
+ \"rb-name\": \"${rb_name}\",
+ \"rb-version\": \"${rb_version}\",
\"chart-name\": \"vault-consul-dev\",
\"description\": \"testing resource bundle definition api\",
- \"uuid\": \"$definition_id\",
- \"service-type\": \"firewall\"
+ \"labels\": {
+ \"vnf_customization_uuid\": \"${vnf_customization_uuid}\"
+ }
}
"
payload=$(echo $payload_raw | tr '\n' ' ')
-rbd_id=$(curl -s -d "$payload" -X POST "${base_url}/v1/rb/definition" | jq -r '.uuid')
+rb_ret_name=$(curl -s -d "$payload" -X POST "${base_url}/v1/rb/definition" | jq -r '."rb-name"')
print_msg "Upload Resource Bundle Definition Content"
-curl -s --data-binary @${CSAR_DIR}/${rbd_csar_id}/${rbd_content_tarball}.gz -X POST "${base_url}/v1/rb/definition/$rbd_id/content"
+curl -s --data-binary @${CSAR_DIR}/${csar_id}/${rbd_content_tarball}.gz -X POST "${base_url}/v1/rb/definition/$rb_name/$rb_version/content"
print_msg "Listing Resource Bundle Definitions"
-rbd_id_list=$(curl -s -X GET "${base_url}/v1/rb/definition")
-if [[ "$rbd_id_list" != *"${rbd_id}"* ]]; then
- echo $rbd_id_list
+rb_list=$(curl -s -X GET "${base_url}/v1/rb/definition/$rb_name")
+if [[ "$rb_list" != *"${rb_name}"* ]]; then
+ echo $rb_list
echo "Resource Bundle Definition not stored"
exit 1
fi
@@ -89,23 +92,27 @@ print_msg "Create Resource Bundle Profile Metadata"
kubeversion=$(kubectl version | grep 'Server Version' | awk -F '"' '{print $6}')
payload_raw="
{
- \"name\": \"test-rbprofile\",
+ \"profile-name\": \"${profile_name}\",
+ \"rb-name\": \"${rb_name}\",
+ \"rb-version\": \"${rb_version}\",
+ \"release-name\": \"testrelease\",
\"namespace\": \"$namespace\",
- \"rbdid\": \"$definition_id\",
- \"uuid\": \"$profile_id\",
- \"kubernetesversion\": \"$kubeversion\"
+ \"kubernetesversion\": \"$kubeversion\",
+ \"labels\": {
+ \"vnf_customization_uuid\": \"${vnf_customization_uuid}\"
+ }
}
"
payload=$(echo $payload_raw | tr '\n' ' ')
-rbp_id=$(curl -s -d "$payload" -X POST "${base_url}/v1/rb/profile" | jq -r '.uuid')
+rbp_ret_name=$(curl -s -d "$payload" -X POST "${base_url}/v1/rb/definition/$rb_name/$rb_version/profile" | jq -r '."profile-name"')
print_msg "Upload Resource Bundle Profile Content"
-curl -s --data-binary @${CSAR_DIR}/${rbd_csar_id}/${rbp_content_tarball}.gz -X POST "${base_url}/v1/rb/profile/$rbp_id/content"
+curl -s --data-binary @${CSAR_DIR}/${csar_id}/${rbp_content_tarball}.gz -X POST "${base_url}/v1/rb/definition/$rb_name/$rb_version/profile/$profile_name/content"
-print_msg "Listing Resource Bundle Profiles"
-rbp_id_list=$(curl -s -X GET "${base_url}/v1/rb/profile")
-if [[ "$rbp_id_list" != *"${rbp_id}"* ]]; then
- echo $rbd_id_list
+print_msg "Getting Resource Bundle Profile"
+rbp_ret=$(curl -s -X GET "${base_url}/v1/rb/definition/$rb_name/$rb_version/profile/$profile_name")
+if [[ "$rbp_ret" != *"${profile_name}"* ]]; then
+ echo $rbp_ret
echo "Resource Bundle Profile not stored"
exit 1
fi
@@ -114,7 +121,9 @@ print_msg "Instantiate Profile"
payload_raw="
{
\"cloud_region_id\": \"$cloud_region_id\",
- \"rb_profile_id\":\"$profile_id\",
+ \"rb-name\":\"$rb_name\",
+ \"rb-version\":\"$rb_version\",
+ \"profile-name\":\"$profile_name\",
\"csar_id\": \"$csar_id\"
}
"
@@ -122,7 +131,7 @@ payload=$(echo $payload_raw | tr '\n' ' ')
vnf_id=$(curl -s -d "$payload" "${base_url}/v1/vnf_instances/" | jq -r '.vnf_id')
print_msg "Validating Kubernetes"
-kubectl get --no-headers=true --namespace=${namespace} deployment ${cloud_region_id}-${namespace}-${vnf_id}-test-rbprofile-vault-consul-dev
+kubectl get --no-headers=true --namespace=${namespace} deployment ${cloud_region_id}-${namespace}-${vnf_id}-testrelease-vault-consul-dev
kubectl get --no-headers=true --namespace=${namespace} service ${cloud_region_id}-${namespace}-${vnf_id}-override-vault-consul
echo "VNF Instance created succesfully with id: $vnf_id"
@@ -142,9 +151,9 @@ if [[ -z "$vnf_details" ]]; then
fi
echo "VNF details $vnf_details"
-print_msg "Deleting $rbd_id Resource Bundle Definition"
-curl -X DELETE "${base_url}/v1/rb/definition/$rbd_id"
-if [[ 500 -ne $(curl -o /dev/null -w %{http_code} -s -X GET "${base_url}/v1/rb/definition/$rbd_id") ]]; then
+print_msg "Deleting $rb_name/$rb_version Resource Bundle Definition"
+curl -X DELETE "${base_url}/v1/rb/definition/$rb_name/$rb_version"
+if [[ 500 -ne $(curl -o /dev/null -w %{http_code} -s -X GET "${base_url}/v1/rb/definition/$rb_name/$rb_version") ]]; then
echo "Resource Bundle Definition not deleted"
# TODO: Change the HTTP code for 404 when the resource is not found in the API
exit 1
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go
index 67a91282..2862a999 100644
--- a/src/k8splugin/api/api.go
+++ b/src/k8splugin/api/api.go
@@ -30,29 +30,27 @@ func NewRouter(kubeconfig string, defClient rb.DefinitionManager,
vnfInstanceHandler.HandleFunc("/{cloudRegionID}/{namespace}/{externalVNFID}", DeleteHandler).Methods("DELETE")
vnfInstanceHandler.HandleFunc("/{cloudRegionID}/{namespace}/{externalVNFID}", GetHandler).Methods("GET")
- //rbd is resource bundle definition
+ //Setup resource bundle definition routes
if defClient == nil {
defClient = rb.NewDefinitionClient()
}
defHandler := rbDefinitionHandler{client: defClient}
resRouter := router.PathPrefix("/v1/rb").Subrouter()
resRouter.HandleFunc("/definition", defHandler.createHandler).Methods("POST")
- resRouter.HandleFunc("/definition/{rbdID}/content", defHandler.uploadHandler).Methods("POST")
- resRouter.HandleFunc("/definition", defHandler.listHandler).Methods("GET")
- resRouter.HandleFunc("/definition/{rbdID}", defHandler.getHandler).Methods("GET")
- resRouter.HandleFunc("/definition/{rbdID}", defHandler.deleteHandler).Methods("DELETE")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/content", defHandler.uploadHandler).Methods("POST")
+ resRouter.HandleFunc("/definition/{rbname}", defHandler.listVersionsHandler).Methods("GET")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}", defHandler.getHandler).Methods("GET")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}", defHandler.deleteHandler).Methods("DELETE")
- //rbp is resource bundle profile
+ //Setup resource bundle profile routes
if profileClient == nil {
profileClient = rb.NewProfileClient()
}
profileHandler := rbProfileHandler{client: profileClient}
- resRouter.HandleFunc("/profile", profileHandler.createHandler).Methods("POST")
- resRouter.HandleFunc("/profile/{rbpID}/content", profileHandler.uploadHandler).Methods("POST")
- resRouter.HandleFunc("/profile/help", profileHandler.helpHandler).Methods("GET")
- resRouter.HandleFunc("/profile", profileHandler.listHandler).Methods("GET")
- resRouter.HandleFunc("/profile/{rbpID}", profileHandler.getHandler).Methods("GET")
- resRouter.HandleFunc("/profile/{rbpID}", profileHandler.deleteHandler).Methods("DELETE")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile", profileHandler.createHandler).Methods("POST")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/content", profileHandler.uploadHandler).Methods("POST")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.getHandler).Methods("GET")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.deleteHandler).Methods("DELETE")
// (TODO): Fix update method
// vnfInstanceHandler.HandleFunc("/{vnfInstanceId}", UpdateHandler).Methods("PUT")
diff --git a/src/k8splugin/api/defhandler.go b/src/k8splugin/api/defhandler.go
index f72247ab..93bbba15 100644
--- a/src/k8splugin/api/defhandler.go
+++ b/src/k8splugin/api/defhandler.go
@@ -54,6 +54,12 @@ func (h rbDefinitionHandler) createHandler(w http.ResponseWriter, r *http.Reques
return
}
+ // Version is required.
+ if v.Version == "" {
+ http.Error(w, "Missing version in POST request", http.StatusBadRequest)
+ return
+ }
+
ret, err := h.client.Create(v)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -72,7 +78,8 @@ func (h rbDefinitionHandler) createHandler(w http.ResponseWriter, r *http.Reques
// uploadHandler handles upload of the bundle tar file into the database
func (h rbDefinitionHandler) uploadHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
- uuid := vars["rbdID"]
+ name := vars["rbname"]
+ version := vars["rbversion"]
inpBytes, err := ioutil.ReadAll(r.Body)
if err != nil {
@@ -85,7 +92,7 @@ func (h rbDefinitionHandler) uploadHandler(w http.ResponseWriter, r *http.Reques
return
}
- err = h.client.Upload(uuid, inpBytes)
+ err = h.client.Upload(name, version, inpBytes)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -94,10 +101,13 @@ func (h rbDefinitionHandler) uploadHandler(w http.ResponseWriter, r *http.Reques
w.WriteHeader(http.StatusOK)
}
-// listHandler handles GET (list) operations on the endpoint
+// listVersionsHandler handles GET (list) operations on the endpoint
// Returns a list of rb.Definitions
-func (h rbDefinitionHandler) listHandler(w http.ResponseWriter, r *http.Request) {
- ret, err := h.client.List()
+func (h rbDefinitionHandler) listVersionsHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ name := vars["rbname"]
+
+ ret, err := h.client.List(name)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -116,9 +126,10 @@ func (h rbDefinitionHandler) listHandler(w http.ResponseWriter, r *http.Request)
// Returns a rb.Definition
func (h rbDefinitionHandler) getHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
- id := vars["rbdID"]
+ name := vars["rbname"]
+ version := vars["rbversion"]
- ret, err := h.client.Get(id)
+ ret, err := h.client.Get(name, version)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -136,9 +147,10 @@ func (h rbDefinitionHandler) getHandler(w http.ResponseWriter, r *http.Request)
// deleteHandler handles DELETE operations on a particular bundle definition id
func (h rbDefinitionHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
- id := vars["rbdID"]
+ name := vars["rbname"]
+ version := vars["rbversion"]
- err := h.client.Delete(id)
+ err := h.client.Delete(name, version)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/k8splugin/api/defhandler_test.go b/src/k8splugin/api/defhandler_test.go
index ed5f298b..9d727fb7 100644
--- a/src/k8splugin/api/defhandler_test.go
+++ b/src/k8splugin/api/defhandler_test.go
@@ -49,7 +49,7 @@ func (m *mockRBDefinition) Create(inp rb.Definition) (rb.Definition, error) {
return m.Items[0], nil
}
-func (m *mockRBDefinition) List() ([]rb.Definition, error) {
+func (m *mockRBDefinition) List(name string) ([]rb.Definition, error) {
if m.Err != nil {
return []rb.Definition{}, m.Err
}
@@ -57,7 +57,7 @@ func (m *mockRBDefinition) List() ([]rb.Definition, error) {
return m.Items, nil
}
-func (m *mockRBDefinition) Get(id string) (rb.Definition, error) {
+func (m *mockRBDefinition) Get(name, version string) (rb.Definition, error) {
if m.Err != nil {
return rb.Definition{}, m.Err
}
@@ -65,11 +65,11 @@ func (m *mockRBDefinition) Get(id string) (rb.Definition, error) {
return m.Items[0], nil
}
-func (m *mockRBDefinition) Delete(id string) error {
+func (m *mockRBDefinition) Delete(name, version string) error {
return m.Err
}
-func (m *mockRBDefinition) Upload(id string, inp []byte) error {
+func (m *mockRBDefinition) Upload(name, version string, inp []byte) error {
return m.Err
}
@@ -87,30 +87,28 @@ func TestRBDefCreateHandler(t *testing.T) {
rbDefClient: &mockRBDefinition{},
},
{
- label: "Create without UUID",
+ label: "Create Definition",
expectedCode: http.StatusCreated,
reader: bytes.NewBuffer([]byte(`{
- "name":"testresourcebundle",
+ "rb-name":"testresourcebundle",
+ "rb-version":"v1",
"chart-name":"testchart",
- "description":"test description",
- "service-type":"firewall"
+ "description":"test description"
}`)),
expected: rb.Definition{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
Name: "testresourcebundle",
+ Version: "v1",
ChartName: "testchart",
Description: "test description",
- ServiceType: "firewall",
},
rbDefClient: &mockRBDefinition{
//Items that will be returned by the mocked Client
Items: []rb.Definition{
{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
Name: "testresourcebundle",
+ Version: "v1",
ChartName: "testchart",
Description: "test description",
- ServiceType: "firewall",
},
},
},
@@ -118,9 +116,19 @@ func TestRBDefCreateHandler(t *testing.T) {
{
label: "Missing Name in Request Body",
reader: bytes.NewBuffer([]byte(`{
+ "rb-version":"v1",
"chart-name":"testchart",
- "description":"test description",
- "service-type":"firewall"
+ "description":"test description"
+ }`)),
+ expectedCode: http.StatusBadRequest,
+ rbDefClient: &mockRBDefinition{},
+ },
+ {
+ label: "Missing Version in Request Body",
+ reader: bytes.NewBuffer([]byte(`{
+ "rb-name":"testresourcebundle",
+ "chart-name":"testchart",
+ "description":"test description"
}`)),
expectedCode: http.StatusBadRequest,
rbDefClient: &mockRBDefinition{},
@@ -154,7 +162,7 @@ func TestRBDefCreateHandler(t *testing.T) {
}
}
-func TestRBDefListHandler(t *testing.T) {
+func TestRBDefListVersionsHandler(t *testing.T) {
testCases := []struct {
label string
@@ -167,32 +175,32 @@ func TestRBDefListHandler(t *testing.T) {
expectedCode: http.StatusOK,
expected: []rb.Definition{
{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
Name: "testresourcebundle",
+ Version: "v1",
+ ChartName: "testchart",
Description: "test description",
- ServiceType: "firewall",
},
{
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- Name: "testresourcebundle2",
+ Name: "testresourcebundle",
+ Version: "v2",
+ ChartName: "testchart",
Description: "test description",
- ServiceType: "dns",
},
},
rbDefClient: &mockRBDefinition{
// list of definitions that will be returned by the mockclient
Items: []rb.Definition{
{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
Name: "testresourcebundle",
+ Version: "v1",
+ ChartName: "testchart",
Description: "test description",
- ServiceType: "firewall",
},
{
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- Name: "testresourcebundle2",
+ Name: "testresourcebundle",
+ Version: "v2",
+ ChartName: "testchart",
Description: "test description",
- ServiceType: "dns",
},
},
},
@@ -202,9 +210,9 @@ func TestRBDefListHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
vh := rbDefinitionHandler{client: testCase.rbDefClient}
- req := httptest.NewRequest("GET", "/v1/rb/definition", nil)
+ req := httptest.NewRequest("GET", "/v1/rb/definition/testresourcebundle", nil)
rr := httptest.NewRecorder()
- vh.listHandler(rr, req)
+ vh.listVersionsHandler(rr, req)
resp := rr.Result()
//Check returned code
@@ -220,12 +228,12 @@ func TestRBDefListHandler(t *testing.T) {
// Since the order of returned slice is not guaranteed
// Check both and return error if both don't match
sort.Slice(got, func(i, j int) bool {
- return got[i].UUID < got[j].UUID
+ return got[i].Version < got[j].Version
})
// Sort both as it is not expected that testCase.expected
// is sorted
sort.Slice(testCase.expected, func(i, j int) bool {
- return testCase.expected[i].UUID < testCase.expected[j].UUID
+ return testCase.expected[i].Version < testCase.expected[j].Version
})
if reflect.DeepEqual(testCase.expected, got) == false {
@@ -240,30 +248,31 @@ func TestRBDefListHandler(t *testing.T) {
func TestRBDefGetHandler(t *testing.T) {
testCases := []struct {
- label string
- expected rb.Definition
- inpUUID string
- expectedCode int
- rbDefClient *mockRBDefinition
+ label string
+ expected rb.Definition
+ name, version string
+ expectedCode int
+ rbDefClient *mockRBDefinition
}{
{
label: "Get Bundle Definition",
expectedCode: http.StatusOK,
expected: rb.Definition{
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- Name: "testresourcebundle2",
+ Name: "testresourcebundle",
+ Version: "v1",
+ ChartName: "testchart",
Description: "test description",
- ServiceType: "dns",
},
- inpUUID: "123e4567-e89b-12d3-a456-426655441111",
+ name: "testresourcebundle",
+ version: "v1",
rbDefClient: &mockRBDefinition{
// list of definitions that will be returned by the mockclient
Items: []rb.Definition{
{
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- Name: "testresourcebundle2",
+ Name: "testresourcebundle",
+ Version: "v1",
+ ChartName: "testchart",
Description: "test description",
- ServiceType: "dns",
},
},
},
@@ -271,7 +280,8 @@ func TestRBDefGetHandler(t *testing.T) {
{
label: "Get Non-Exiting Bundle Definition",
expectedCode: http.StatusInternalServerError,
- inpUUID: "123e4567-e89b-12d3-a456-426655440000",
+ name: "nonexistingbundle",
+ version: "v1",
rbDefClient: &mockRBDefinition{
// list of definitions that will be returned by the mockclient
Items: []rb.Definition{},
@@ -283,7 +293,7 @@ func TestRBDefGetHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
vh := rbDefinitionHandler{client: testCase.rbDefClient}
- req := httptest.NewRequest("GET", "/v1/rb/definition/"+testCase.inpUUID, nil)
+ req := httptest.NewRequest("GET", "/v1/rb/definition/"+testCase.name+"/"+testCase.version, nil)
rr := httptest.NewRecorder()
vh.getHandler(rr, req)
resp := rr.Result()
diff --git a/src/k8splugin/api/handler.go b/src/k8splugin/api/handler.go
index b1cc6709..31ffad90 100644
--- a/src/k8splugin/api/handler.go
+++ b/src/k8splugin/api/handler.go
@@ -63,8 +63,12 @@ func validateBody(body interface{}) error {
werr := pkgerrors.Wrap(errors.New("Invalid/Missing CsarID in POST request"), "CreateVnfRequest bad request")
return werr
}
- if b.RBProfileID == "" {
- werr := pkgerrors.Wrap(errors.New("Invalid/Missing RB ProfileID in POST request"), "CreateVnfRequest bad request")
+ if b.RBName == "" || b.RBVersion == "" {
+ werr := pkgerrors.Wrap(errors.New("Invalid/Missing resource bundle parameters in POST request"), "CreateVnfRequest bad request")
+ return werr
+ }
+ if b.ProfileName == "" {
+ werr := pkgerrors.Wrap(errors.New("Invalid/Missing profile name in POST request"), "CreateVnfRequest bad request")
return werr
}
if strings.Contains(b.CloudRegionID, "|") {
@@ -117,16 +121,20 @@ func CreateHandler(w http.ResponseWriter, r *http.Request) {
},
nil
*/
+ profile, err := rb.NewProfileClient().Get(resource.RBName, resource.RBVersion, resource.ProfileName)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
externalVNFID, resourceNameMap, err := helper.CreateVNF(resource.CsarID, resource.CloudRegionID,
- resource.RBProfileID, &kubeclient)
+ profile, &kubeclient)
if err != nil {
werr := pkgerrors.Wrap(err, "Read Kubernetes Data information error")
http.Error(w, werr.Error(), http.StatusInternalServerError)
return
}
- rbProfile, _ := rb.NewProfileClient().Get(resource.RBProfileID)
- namespace := rbProfile.Namespace
+ namespace := profile.Namespace
// cloud1-default-uuid
internalVNFID := resource.CloudRegionID + "-" + namespace + "-" + externalVNFID
diff --git a/src/k8splugin/api/handler_test.go b/src/k8splugin/api/handler_test.go
index d1e4de07..ee4a3005 100644
--- a/src/k8splugin/api/handler_test.go
+++ b/src/k8splugin/api/handler_test.go
@@ -29,6 +29,7 @@ import (
helper "k8splugin/internal/app"
"k8splugin/internal/db"
+ "k8splugin/internal/rb"
)
type mockCSAR struct {
@@ -37,7 +38,7 @@ type mockCSAR struct {
err error
}
-func (c *mockCSAR) CreateVNF(id, r, n string,
+func (c *mockCSAR) CreateVNF(id string, r string, profile rb.Profile,
kubeclient *kubernetes.Clientset) (string, map[string][]string, error) {
return c.externalVNFID, c.resourceYAMLNameMap, c.err
}
@@ -83,12 +84,14 @@ func TestCreateHandler(t *testing.T) {
label: "Missing parameter failure",
input: bytes.NewBuffer([]byte(`{
"csar_id": "testID",
- "oof_parameters": {
+ "rb-name": "test-rbdef",
+ "rb-version": "v1",
+ "oof_parameters": [{
"key_values": {
"key1": "value1",
"key2": "value2"
}
- },
+ }],
"vnf_instance_name": "test",
"vnf_instance_description": "vRouter_test_description"
}`)),
@@ -98,6 +101,9 @@ func TestCreateHandler(t *testing.T) {
label: "Fail to get the VNF client",
input: bytes.NewBuffer([]byte(`{
"cloud_region_id": "region1",
+ "rb-name": "test-rbdef",
+ "rb-version": "v1",
+ "profile-name": "profile1",
"rb_profile_id": "123e4567-e89b-12d3-a456-426655440000",
"csar_id": "UUID-1"
}`)),
@@ -108,6 +114,9 @@ func TestCreateHandler(t *testing.T) {
label: "Fail to create the VNF instance",
input: bytes.NewBuffer([]byte(`{
"cloud_region_id": "region1",
+ "rb-name": "test-rbdef",
+ "rb-version": "v1",
+ "profile-name": "profile1",
"rb_profile_id": "123e4567-e89b-12d3-a456-426655440000",
"csar_id": "UUID-1"
}`)),
@@ -115,11 +124,123 @@ func TestCreateHandler(t *testing.T) {
mockCreateVNF: &mockCSAR{
err: pkgerrors.New("Internal error"),
},
+ mockStore: &db.MockDB{
+ Items: map[string]map[string][]byte{
+ rb.ProfileKey{RBName: "testresourcebundle", RBVersion: "v1",
+ Name: "profile1"}.String(): {
+ "metadata": []byte(
+ "{\"profile-name\":\"profile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
+ "\"kubernetesversion\":\"1.12.3\"}"),
+ // base64 encoding of vagrant/tests/vnfs/testrb/helm/profile
+ "content": []byte("H4sICLmjT1wAA3Byb2ZpbGUudGFyAO1Y32/bNhD2s/6Kg/KyYZZsy" +
+ "78K78lLMsxY5gRxmqIYhoKWaJsYJWokZdfo+r/vSFmunCZNBtQJ1vF7sXX36e54vDN5T" +
+ "knGFlTpcEtS3jgO2ohBr2c/EXc/29Gg1+h0e1F32Ol1B1Gj3Ymifr8B7SPFc4BCaSIBG" +
+ "lII/SXeY/r/KIIg8NZUKiayEaw7nt7mdOQBrAkvqBqBL1ArWULflRJbJz4SYpEt2FJSJ" +
+ "QoZ21cAAlgwTnOiVyPQWFQLwVuqmCdMthKac7FNaVZWmqWjkRWRuuSvScF1gFZVwYOEr" +
+ "luapjknaOazd186Z98S7tver+3j0f5v1/q/18f+7w56bdf/zwFF5ZqV/WtbH6YioVdCa" +
+ "hRkJEVBVSFBvUNRmyNpesgwors0lmkqM8KNzRG8iqLIWN45GUGv57l+fkFUP9PH9GF6f" +
+ "IgH+kP9b76b/o+GUb9r5J1O1I0a0D9mUBX+5/1/55g+io9/sf+DnuF1sA4Gbv+fA1++p" +
+ "n0dH4+c/92oPaztv+n/fn84dOf/c+AETkW+lWy50hC1O69gguc1R6HEw5xoHAuaKIq9E" +
+ "+8ELvCikCmaQJElVIJeURjnJMaPnaYJt+UoAVHYhu8Mwd+p/O9/RAtbUUBKtnj+aygUR" +
+ "RNM2ZkB6PuY5hpvCzhY4L2fkSymsGF6Zd3sjIRo4u3OhJhrgmyC/ByfFnUeEG0DLrHSO" +
+ "h+1WpvNJiQ23FDIZYuXVNW6mJyeT2fnAYZsX3qdcaoUSPpXwSQudr4FkmNEMZljnJxsQ" +
+ "EggOPmgTgsT8UYyzbJlE5RY6A2RFK0kTGnJ5oU+SFcVH666TsCEkQz88QwmMx9+Gs8ms" +
+ "ybaeDO5+eXy9Q28GV9fj6c3k/MZXF7D6eX0bHIzuZzi088wnr6FXyfTsyZQTBa6oe9za" +
+ "eLHIJlJJE1M1maUHgSwEGVAKqcxW7AY15UtC7KksDS3uQyXAzmVKVNmOxWGl6AVzlKmb" +
+ "VGozxcVeh7J2W01S2LOVAsHyj9ZlozgbP+74qVUk4RoMtrfMD98wCzGvEiwXHD3U5GFi" +
+ "4Jzo/QhhI8fd0yFu3c/fa/d8zmZU67KsRRDefCt/Qu7YdQSw1PzNTS3W1QGnyRVef+N5" +
+ "YHDKZao/4MP/ju/siEpp0SVQYbX5UNlxxJwizCFyzuMWXkLNySzIyZs4wBrTpXE23I62" +
+ "wlPRZHp0qJCC7EWslxpSnS8uqgt/YmLr2btnZXaDhnwA4NPzueT8lEt126AyExPY44rS" +
+ "YA1bJPl15JgRaEdM9CKv/f1YDHdE5e1cYVFdiUwoduDJC+5mBMe5nstbndCF9Zfxakpa" +
+ "1aNP2LK/Xffhuc3fTNfUYlfzH8a/h97qhmVaikNPi2+nItq8exGtLA+SdW9rgUvUvqbq" +
+ "YkDi6mRXNk/V1pUxy0uYsI1S+meU+XsPo2kJLnMOKZGy4J6Xt3XgZuHTayEKv3XZLjy+" +
+ "yJ66WPQwcHBwcHBwcHBwcHBwcHBwcHhm8Q/mTHqWgAoAAA="),
+ },
+ rb.DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
+ "metadata": []byte(
+ "{\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"vault-consul-dev\"," +
+ "\"chart-name\":\"vault-consul-dev\"," +
+ "\"description\":\"testresourcebundle\"}"),
+ // base64 encoding of vagrant/tests/vnfs/testrb/helm/vault-consul-dev
+ "content": []byte("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" +
+ "cOHDgwIEDB18K/AcxEDJDAHgAAA=="),
+ },
+ },
+ },
},
{
label: "Fail to create a VNF DB record",
input: bytes.NewBuffer([]byte(`{
"cloud_region_id": "region1",
+ "rb-name": "test-rbdef",
+ "rb-version": "v1",
+ "profile-name": "profile1",
"rb_profile_id": "123e4567-e89b-12d3-a456-426655440000",
"csar_id": "UUID-1"
}`)),
@@ -135,6 +256,9 @@ func TestCreateHandler(t *testing.T) {
label: "Succesful create a VNF",
input: bytes.NewBuffer([]byte(`{
"cloud_region_id": "region1",
+ "rb-name": "test-rbdef",
+ "rb-version": "v1",
+ "profile-name": "profile1",
"rb_profile_id": "123e4567-e89b-12d3-a456-426655440000",
"csar_id": "UUID-1"
}`)),
@@ -145,7 +269,115 @@ func TestCreateHandler(t *testing.T) {
"service": []string{"cloud1-default-uuid-sisesvc"},
},
},
- mockStore: &db.MockDB{},
+ mockStore: &db.MockDB{
+ Items: map[string]map[string][]byte{
+ rb.ProfileKey{RBName: "test-rbdef", RBVersion: "v1",
+ Name: "profile1"}.String(): {
+ "metadata": []byte(
+ "{\"profile-name\":\"profile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"test-rbdef\"," +
+ "\"rb-version\":\"v1\"," +
+ "\"kubernetesversion\":\"1.12.3\"}"),
+ // base64 encoding of vagrant/tests/vnfs/testrb/helm/profile
+ "content": []byte("H4sICLmjT1wAA3Byb2ZpbGUudGFyAO1Y32/bNhD2s/6Kg/KyYZZsy" +
+ "78K78lLMsxY5gRxmqIYhoKWaJsYJWokZdfo+r/vSFmunCZNBtQJ1vF7sXX36e54vDN5T" +
+ "knGFlTpcEtS3jgO2ohBr2c/EXc/29Gg1+h0e1F32Ol1B1Gj3Ymifr8B7SPFc4BCaSIBG" +
+ "lII/SXeY/r/KIIg8NZUKiayEaw7nt7mdOQBrAkvqBqBL1ArWULflRJbJz4SYpEt2FJSJ" +
+ "QoZ21cAAlgwTnOiVyPQWFQLwVuqmCdMthKac7FNaVZWmqWjkRWRuuSvScF1gFZVwYOEr" +
+ "luapjknaOazd186Z98S7tver+3j0f5v1/q/18f+7w56bdf/zwFF5ZqV/WtbH6YioVdCa" +
+ "hRkJEVBVSFBvUNRmyNpesgwors0lmkqM8KNzRG8iqLIWN45GUGv57l+fkFUP9PH9GF6f" +
+ "IgH+kP9b76b/o+GUb9r5J1O1I0a0D9mUBX+5/1/55g+io9/sf+DnuF1sA4Gbv+fA1++p" +
+ "n0dH4+c/92oPaztv+n/fn84dOf/c+AETkW+lWy50hC1O69gguc1R6HEw5xoHAuaKIq9E" +
+ "+8ELvCikCmaQJElVIJeURjnJMaPnaYJt+UoAVHYhu8Mwd+p/O9/RAtbUUBKtnj+aygUR" +
+ "RNM2ZkB6PuY5hpvCzhY4L2fkSymsGF6Zd3sjIRo4u3OhJhrgmyC/ByfFnUeEG0DLrHSO" +
+ "h+1WpvNJiQ23FDIZYuXVNW6mJyeT2fnAYZsX3qdcaoUSPpXwSQudr4FkmNEMZljnJxsQ" +
+ "EggOPmgTgsT8UYyzbJlE5RY6A2RFK0kTGnJ5oU+SFcVH666TsCEkQz88QwmMx9+Gs8ms" +
+ "ybaeDO5+eXy9Q28GV9fj6c3k/MZXF7D6eX0bHIzuZzi088wnr6FXyfTsyZQTBa6oe9za" +
+ "eLHIJlJJE1M1maUHgSwEGVAKqcxW7AY15UtC7KksDS3uQyXAzmVKVNmOxWGl6AVzlKmb" +
+ "VGozxcVeh7J2W01S2LOVAsHyj9ZlozgbP+74qVUk4RoMtrfMD98wCzGvEiwXHD3U5GFi" +
+ "4Jzo/QhhI8fd0yFu3c/fa/d8zmZU67KsRRDefCt/Qu7YdQSw1PzNTS3W1QGnyRVef+N5" +
+ "YHDKZao/4MP/ju/siEpp0SVQYbX5UNlxxJwizCFyzuMWXkLNySzIyZs4wBrTpXE23I62" +
+ "wlPRZHp0qJCC7EWslxpSnS8uqgt/YmLr2btnZXaDhnwA4NPzueT8lEt126AyExPY44rS" +
+ "YA1bJPl15JgRaEdM9CKv/f1YDHdE5e1cYVFdiUwoduDJC+5mBMe5nstbndCF9Zfxakpa" +
+ "1aNP2LK/Xffhuc3fTNfUYlfzH8a/h97qhmVaikNPi2+nItq8exGtLA+SdW9rgUvUvqbq" +
+ "YkDi6mRXNk/V1pUxy0uYsI1S+meU+XsPo2kJLnMOKZGy4J6Xt3XgZuHTayEKv3XZLjy+" +
+ "yJ66WPQwcHBwcHBwcHBwcHBwcHBwcHhm8Q/mTHqWgAoAAA="),
+ },
+ rb.DefinitionKey{Name: "test-rbdef", Version: "v1"}.String(): {
+ "metadata": []byte(
+ "{\"rb-name\":\"test-rbdef\"," +
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"vault-consul-dev\"," +
+ "\"description\":\"testresourcebundle\"}"),
+ // base64 encoding of vagrant/tests/vnfs/testrb/helm/vault-consul-dev
+ "content": []byte("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" +
+ "cOHDgwIEDB18K/AcxEDJDAHgAAA=="),
+ },
+ },
+ },
},
}
diff --git a/src/k8splugin/api/model.go b/src/k8splugin/api/model.go
index 164143c2..1a3abed5 100644
--- a/src/k8splugin/api/model.go
+++ b/src/k8splugin/api/model.go
@@ -17,7 +17,9 @@ package api
type CreateVnfRequest struct {
CloudRegionID string `json:"cloud_region_id"`
CsarID string `json:"csar_id"`
- RBProfileID string `json:"rb_profile_id"`
+ RBName string `json:"rb-name"`
+ RBVersion string `json:"rb-version"`
+ ProfileName string `json:"profile-name"`
OOFParams []map[string]interface{} `json:"oof_parameters"`
NetworkParams NetworkParameters `json:"network_parameters"`
Name string `json:"vnf_instance_name"`
diff --git a/src/k8splugin/api/profilehandler.go b/src/k8splugin/api/profilehandler.go
index 267dae0e..2c15a440 100644
--- a/src/k8splugin/api/profilehandler.go
+++ b/src/k8splugin/api/profilehandler.go
@@ -36,9 +36,9 @@ type rbProfileHandler struct {
// createHandler handles creation of the definition entry in the database
func (h rbProfileHandler) createHandler(w http.ResponseWriter, r *http.Request) {
- var v rb.Profile
+ var p rb.Profile
- err := json.NewDecoder(r.Body).Decode(&v)
+ err := json.NewDecoder(r.Body).Decode(&p)
switch {
case err == io.EOF:
http.Error(w, "Empty body", http.StatusBadRequest)
@@ -49,18 +49,12 @@ func (h rbProfileHandler) createHandler(w http.ResponseWriter, r *http.Request)
}
// Name is required.
- if v.Name == "" {
+ if p.Name == "" {
http.Error(w, "Missing name in POST request", http.StatusBadRequest)
return
}
- // Definition ID is required
- if v.RBDID == "" {
- http.Error(w, "Missing Resource Bundle Definition ID in POST request", http.StatusBadRequest)
- return
- }
-
- ret, err := h.client.Create(v)
+ ret, err := h.client.Create(p)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -78,7 +72,9 @@ func (h rbProfileHandler) createHandler(w http.ResponseWriter, r *http.Request)
// uploadHandler handles upload of the bundle tar file into the database
func (h rbProfileHandler) uploadHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
- uuid := vars["rbpID"]
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
inpBytes, err := ioutil.ReadAll(r.Body)
if err != nil {
@@ -91,37 +87,12 @@ func (h rbProfileHandler) uploadHandler(w http.ResponseWriter, r *http.Request)
return
}
- err = h.client.Upload(uuid, inpBytes)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- w.WriteHeader(http.StatusOK)
-}
-
-// listHandler handles GET (list) operations on the endpoint
-// Returns a list of rb.Definitions
-func (h rbProfileHandler) listHandler(w http.ResponseWriter, r *http.Request) {
- ret, err := h.client.List()
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusOK)
- err = json.NewEncoder(w).Encode(ret)
+ err = h.client.Upload(rbName, rbVersion, prName, inpBytes)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
-}
-// helpHandler handles GET (list) operations on the endpoint
-// Returns a list of rb.Definitions
-func (h rbProfileHandler) helpHandler(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusOK)
}
@@ -129,9 +100,11 @@ func (h rbProfileHandler) helpHandler(w http.ResponseWriter, r *http.Request) {
// Returns a rb.Definition
func (h rbProfileHandler) getHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
- id := vars["rbpID"]
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
- ret, err := h.client.Get(id)
+ ret, err := h.client.Get(rbName, rbVersion, prName)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -149,9 +122,11 @@ func (h rbProfileHandler) getHandler(w http.ResponseWriter, r *http.Request) {
// deleteHandler handles DELETE operations on a particular bundle definition id
func (h rbProfileHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
- id := vars["rbpID"]
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
- err := h.client.Delete(id)
+ err := h.client.Delete(rbName, rbVersion, prName)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/k8splugin/api/profilehandler_test.go b/src/k8splugin/api/profilehandler_test.go
index f6b27fc4..4e346862 100644
--- a/src/k8splugin/api/profilehandler_test.go
+++ b/src/k8splugin/api/profilehandler_test.go
@@ -24,7 +24,6 @@ import (
"net/http"
"net/http/httptest"
"reflect"
- "sort"
"testing"
pkgerrors "github.com/pkg/errors"
@@ -49,15 +48,7 @@ func (m *mockRBProfile) Create(inp rb.Profile) (rb.Profile, error) {
return m.Items[0], nil
}
-func (m *mockRBProfile) List() ([]rb.Profile, error) {
- if m.Err != nil {
- return []rb.Profile{}, m.Err
- }
-
- return m.Items, nil
-}
-
-func (m *mockRBProfile) Get(id string) (rb.Profile, error) {
+func (m *mockRBProfile) Get(rbname, rbversion, prname string) (rb.Profile, error) {
if m.Err != nil {
return rb.Profile{}, m.Err
}
@@ -65,11 +56,11 @@ func (m *mockRBProfile) Get(id string) (rb.Profile, error) {
return m.Items[0], nil
}
-func (m *mockRBProfile) Delete(id string) error {
+func (m *mockRBProfile) Delete(rbname, rbversion, prname string) error {
return m.Err
}
-func (m *mockRBProfile) Upload(id string, inp []byte) error {
+func (m *mockRBProfile) Upload(rbname, rbversion, prname string, inp []byte) error {
return m.Err
}
@@ -85,20 +76,24 @@ func TestRBProfileCreateHandler(t *testing.T) {
label: "Missing Body Failure",
expectedCode: http.StatusBadRequest,
rbDefClient: &mockRBProfile{},
+ reader: nil,
},
{
- label: "Create without UUID",
+ label: "Create New Profile for Definition",
expectedCode: http.StatusCreated,
reader: bytes.NewBuffer([]byte(`{
- "rbdid":"abcde123-e89b-8888-a456-986655447236",
- "name":"testdomain",
+ "rb-name":"testresource_bundle_definition",
+ "rb-version":"v1",
+ "profile-name":"profile1",
+ "release-name":"testprofilereleasename",
"namespace":"default",
- "kubernetesversion":"1.12.3"
+ "kubernetes-version":"1.12.3"
}`)),
expected: rb.Profile{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle",
+ RBName: "testresource_bundle_definition",
+ RBVersion: "v1",
+ Name: "profile1",
+ ReleaseName: "testprofilereleasename",
Namespace: "default",
KubernetesVersion: "1.12.3",
},
@@ -106,9 +101,10 @@ func TestRBProfileCreateHandler(t *testing.T) {
//Items that will be returned by the mocked Client
Items: []rb.Profile{
{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle",
+ RBName: "testresource_bundle_definition",
+ RBVersion: "v1",
+ Name: "profile1",
+ ReleaseName: "testprofilereleasename",
Namespace: "default",
KubernetesVersion: "1.12.3",
},
@@ -120,7 +116,8 @@ func TestRBProfileCreateHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
vh := rbProfileHandler{client: testCase.rbDefClient}
- req := httptest.NewRequest("POST", "/v1/rb/profile", testCase.reader)
+ req := httptest.NewRequest("POST", "/v1/rb/profile/testresource_bundle_definition/v1/profile",
+ testCase.reader)
rr := httptest.NewRecorder()
vh.createHandler(rr, req)
resp := rr.Result()
@@ -144,93 +141,6 @@ func TestRBProfileCreateHandler(t *testing.T) {
}
}
-func TestRBProfileListHandler(t *testing.T) {
-
- testCases := []struct {
- label string
- expected []rb.Profile
- expectedCode int
- rbDefClient *mockRBProfile
- }{
- {
- label: "List Bundle Profiles",
- expectedCode: http.StatusOK,
- expected: []rb.Profile{
- {
- UUID: "123e4567-e89b-12d3-a456-426655440000",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle",
- Namespace: "default",
- KubernetesVersion: "1.12.3",
- },
- {
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- RBDID: "abcde123-e89b-8888-a456-986655441111",
- Name: "testresourcebundle2",
- Namespace: "default",
- KubernetesVersion: "1.12.3",
- },
- },
- rbDefClient: &mockRBProfile{
- // list of Profiles that will be returned by the mockclient
- Items: []rb.Profile{
- {
- UUID: "123e4567-e89b-12d3-a456-426655440000",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle",
- Namespace: "default",
- KubernetesVersion: "1.12.3",
- },
- {
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- RBDID: "abcde123-e89b-8888-a456-986655441111",
- Name: "testresourcebundle2",
- Namespace: "default",
- KubernetesVersion: "1.12.3",
- },
- },
- },
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- vh := rbProfileHandler{client: testCase.rbDefClient}
- req := httptest.NewRequest("GET", "/v1/rb/profile", nil)
- rr := httptest.NewRecorder()
- vh.listHandler(rr, req)
-
- resp := rr.Result()
- //Check returned code
- if resp.StatusCode != testCase.expectedCode {
- t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, resp.StatusCode)
- }
-
- //Check returned body only if statusOK
- if resp.StatusCode == http.StatusOK {
- got := []rb.Profile{}
- json.NewDecoder(resp.Body).Decode(&got)
-
- // Since the order of returned slice is not guaranteed
- // Check both and return error if both don't match
- sort.Slice(got, func(i, j int) bool {
- return got[i].UUID < got[j].UUID
- })
- // Sort both as it is not expected that testCase.expected
- // is sorted
- sort.Slice(testCase.expected, func(i, j int) bool {
- return testCase.expected[i].UUID < testCase.expected[j].UUID
- })
-
- if reflect.DeepEqual(testCase.expected, got) == false {
- t.Errorf("listHandler returned unexpected body: got %v;"+
- " expected %v", got, testCase.expected)
- }
- }
- })
- }
-}
-
func TestRBProfileGetHandler(t *testing.T) {
testCases := []struct {
@@ -244,20 +154,22 @@ func TestRBProfileGetHandler(t *testing.T) {
label: "Get Bundle Profile",
expectedCode: http.StatusOK,
expected: rb.Profile{
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle2",
+ RBName: "testresource_bundle_definition",
+ RBVersion: "v1",
+ Name: "profile1",
+ ReleaseName: "testprofilereleasename",
Namespace: "default",
KubernetesVersion: "1.12.3",
},
inpUUID: "123e4567-e89b-12d3-a456-426655441111",
rbDefClient: &mockRBProfile{
- // list of Profiles that will be returned by the mockclient
+ // Profile that will be returned by the mockclient
Items: []rb.Profile{
{
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle2",
+ RBName: "testresource_bundle_definition",
+ RBVersion: "v1",
+ Name: "profile1",
+ ReleaseName: "testprofilereleasename",
Namespace: "default",
KubernetesVersion: "1.12.3",
},
diff --git a/src/k8splugin/internal/app/vnfhelper.go b/src/k8splugin/internal/app/vnfhelper.go
index 5984bbd0..0a867090 100644
--- a/src/k8splugin/internal/app/vnfhelper.go
+++ b/src/k8splugin/internal/app/vnfhelper.go
@@ -70,23 +70,17 @@ func ensuresNamespace(namespace string, kubeclient kubernetes.Interface) error {
}
// CreateVNF reads the CSAR files from the files system and creates them one by one
-var CreateVNF = func(csarID string, cloudRegionID string, rbProfileID string, kubeclient *kubernetes.Clientset) (string, map[string][]string, error) {
+var CreateVNF = func(csarID string, cloudRegionID string, profile rb.Profile, kubeclient *kubernetes.Clientset) (string, map[string][]string, error) {
overrideValues := []string{}
- rbProfileClient := rb.NewProfileClient()
- rbProfile, err := rbProfileClient.Get(rbProfileID)
- if err != nil {
- return "", nil, pkgerrors.Wrap(err, "Error getting profile info")
- }
-
//Make sure that the namespace exists before trying to create any resources
- if err := ensuresNamespace(rbProfile.Namespace, kubeclient); err != nil {
- return "", nil, pkgerrors.Wrap(err, "Error while ensuring namespace: "+rbProfile.Namespace)
+ if err := ensuresNamespace(profile.Namespace, kubeclient); err != nil {
+ return "", nil, pkgerrors.Wrap(err, "Error while ensuring namespace: "+profile.Namespace)
}
externalVNFID := generateExternalVNFID()
- internalVNFID := cloudRegionID + "-" + rbProfile.Namespace + "-" + externalVNFID
+ internalVNFID := cloudRegionID + "-" + profile.Namespace + "-" + externalVNFID
- metaMap, err := rb.NewProfileClient().Resolve(rbProfileID, overrideValues)
+ metaMap, err := rb.NewProfileClient().Resolve(profile.RBName, profile.RBVersion, profile.Name, overrideValues)
if err != nil {
return "", nil, pkgerrors.Wrap(err, "Error resolving helm charts")
}
@@ -109,7 +103,7 @@ var CreateVNF = func(csarID string, cloudRegionID string, rbProfileID string, ku
//Populate the namespace from profile instead of instance body
genericKubeData := &utils.ResourceData{
YamlFilePath: filepath,
- Namespace: rbProfile.Namespace,
+ Namespace: profile.Namespace,
VnfId: internalVNFID,
}
diff --git a/src/k8splugin/internal/app/vnfhelper_test.go b/src/k8splugin/internal/app/vnfhelper_test.go
index 0bd21f72..06866150 100644
--- a/src/k8splugin/internal/app/vnfhelper_test.go
+++ b/src/k8splugin/internal/app/vnfhelper_test.go
@@ -28,6 +28,7 @@ import (
utils "k8splugin/internal"
"k8splugin/internal/db"
+ "k8splugin/internal/rb"
)
func LoadMockPlugins(krdLoadedPlugins *map[string]*plugin.Plugin) error {
@@ -84,12 +85,14 @@ func TestCreateVNF(t *testing.T) {
t.Run("Successfully create VNF", func(t *testing.T) {
db.DBconn = &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ rb.ProfileKey{RBName: "test-rbdef", RBVersion: "v1",
+ Name: "profile1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
+ "{\"profile-name\":\"profile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"test-rbdef\"," +
+ "\"rb-version\":\"v1\"," +
"\"kubernetesversion\":\"1.12.3\"}"),
// base64 encoding of vagrant/tests/vnfs/testrb/helm/profile
"content": []byte("H4sICLmjT1wAA3Byb2ZpbGUudGFyAO1Y32/bNhD2s/6Kg/KyYZZsy" +
@@ -116,13 +119,12 @@ func TestCreateVNF(t *testing.T) {
"YkDi6mRXNk/V1pUxy0uYsI1S+meU+XsPo2kJLnMOKZGy4J6Xt3XgZuHTayEKv3XZLjy+" +
"yJ66WPQwcHBwcHBwcHBwcHBwcHBwcHhm8Q/mTHqWgAoAAA="),
},
- "abcde123-e89b-8888-a456-986655447236": {
+ rb.DefinitionKey{Name: "test-rbdef", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"test-rbdef\"," +
+ "\"rb-version\":\"v1\"," +
"\"chart-name\":\"vault-consul-dev\"," +
- "\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"abcde123-e89b-8888-a456-986655447236\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"description\":\"testresourcebundle\"}"),
// base64 encoding of vagrant/tests/vnfs/testrb/helm/vault-consul-dev
"content": []byte("H4sICEetS1wAA3ZhdWx0LWNvbnN1bC1kZXYudGFyAO0c7XLbNjK/+R" +
"QYujdJehatb+V4czPnOmnPk9bO2Gk7nbaTgUhIxpgiGAK0o3P9QPca92S3C5AU9GXZiax" +
@@ -191,7 +193,14 @@ func TestCreateVNF(t *testing.T) {
},
}
externaluuid, data, err := CreateVNF("uuid", "cloudregion1",
- "123e4567-e89b-12d3-a456-426655440000", &kubeclient)
+ rb.Profile{
+ RBName: "test-rbdef",
+ RBVersion: "v1",
+ Name: "profile1",
+ ReleaseName: "testprofilereleasename",
+ Namespace: "testnamespace",
+ KubernetesVersion: "1.12.3",
+ }, &kubeclient)
if err != nil {
t.Fatalf("TestCreateVNF returned an error (%s)", err)
}
diff --git a/src/k8splugin/internal/db/consul_test.go b/src/k8splugin/internal/db/consul_test.go
index 6d127841..abd264c8 100644
--- a/src/k8splugin/internal/db/consul_test.go
+++ b/src/k8splugin/internal/db/consul_test.go
@@ -108,13 +108,13 @@ func TestConsulCreate(t *testing.T) {
}{
{
label: "Sucessful register a record to Consul Database",
- key: mockKey{Key: "test-key"},
+ key: MockKey{Key: "test-key"},
input: map[string]string{"root": "rbinst", "tag": "data", "value": "test-value"},
mock: &mockConsulKVStore{},
},
{
label: "Fail to create a new record in Consul Database",
- key: mockKey{Key: "test-key"},
+ key: MockKey{Key: "test-key"},
input: map[string]string{"root": "rbinst", "tag": "data", "value": "test-value"},
mock: &mockConsulKVStore{
Err: pkgerrors.New("DB error"),
@@ -151,7 +151,7 @@ func TestConsulRead(t *testing.T) {
}{
{
label: "Sucessful retrieve a record from Consul Database",
- key: mockKey{Key: "test"},
+ key: MockKey{Key: "test"},
input: map[string]string{"root": "rbinst", "tag": "data"},
mock: &mockConsulKVStore{
Items: api.KVPairs{
@@ -165,13 +165,13 @@ func TestConsulRead(t *testing.T) {
},
{
label: "Fail retrieve a non-existing record from Consul Database",
- key: mockKey{Key: "test-key"},
+ key: MockKey{Key: "test-key"},
input: map[string]string{"root": "rbinst", "tag": "data"},
mock: &mockConsulKVStore{},
},
{
label: "Fail retrieve a record from Consul Database",
- key: mockKey{Key: "test-key"},
+ key: MockKey{Key: "test-key"},
input: map[string]string{"root": "rbinst", "tag": "data"},
mock: &mockConsulKVStore{
Err: pkgerrors.New("DB error"),
@@ -215,13 +215,13 @@ func TestConsulDelete(t *testing.T) {
}{
{
label: "Sucessful delete a record to Consul Database",
- key: mockKey{Key: "test-key"},
+ key: MockKey{Key: "test-key"},
input: map[string]string{"root": "rbinst", "tag": "data"},
mock: &mockConsulKVStore{},
},
{
label: "Fail to delete a record in Consul Database",
- key: mockKey{Key: "test-key"},
+ key: MockKey{Key: "test-key"},
mock: &mockConsulKVStore{
Err: pkgerrors.New("DB error"),
},
diff --git a/src/k8splugin/internal/db/mongo_test.go b/src/k8splugin/internal/db/mongo_test.go
index deb51044..baa442ce 100644
--- a/src/k8splugin/internal/db/mongo_test.go
+++ b/src/k8splugin/internal/db/mongo_test.go
@@ -84,7 +84,7 @@ func TestCreate(t *testing.T) {
label: "Successfull creation of entry",
input: map[string]interface{}{
"coll": "collname",
- "key": mockKey{Key: "keyvalue"},
+ "key": MockKey{Key: "keyvalue"},
"tag": "tagName",
"data": "Data In String Format",
},
@@ -95,7 +95,7 @@ func TestCreate(t *testing.T) {
label: "UnSuccessfull creation of entry",
input: map[string]interface{}{
"coll": "collname",
- "key": mockKey{Key: "keyvalue"},
+ "key": MockKey{Key: "keyvalue"},
"tag": "tagName",
"data": "Data In String Format",
},
@@ -108,7 +108,7 @@ func TestCreate(t *testing.T) {
label: "Missing input fields",
input: map[string]interface{}{
"coll": "",
- "key": mockKey{Key: ""},
+ "key": MockKey{Key: ""},
"tag": "",
"data": "",
},
@@ -156,7 +156,7 @@ func TestRead(t *testing.T) {
label: "Successfull Read of entry",
input: map[string]interface{}{
"coll": "collname",
- "key": mockKey{Key: "keyvalue"},
+ "key": MockKey{Key: "keyvalue"},
"tag": "metadata",
},
// Binary form of
@@ -186,7 +186,7 @@ func TestRead(t *testing.T) {
label: "UnSuccessfull Read of entry: object not found",
input: map[string]interface{}{
"coll": "collname",
- "key": mockKey{Key: "keyvalue"},
+ "key": MockKey{Key: "keyvalue"},
"tag": "badtag",
},
// Binary form of
@@ -215,7 +215,7 @@ func TestRead(t *testing.T) {
label: "UnSuccessfull Read of entry",
input: map[string]interface{}{
"coll": "collname",
- "key": mockKey{Key: "keyvalue"},
+ "key": MockKey{Key: "keyvalue"},
"tag": "tagName",
},
mockColl: &mockCollection{
@@ -227,7 +227,7 @@ func TestRead(t *testing.T) {
label: "Missing input fields",
input: map[string]interface{}{
"coll": "",
- "key": mockKey{Key: ""},
+ "key": MockKey{Key: ""},
"tag": "",
},
expectedError: "Mandatory fields are missing",
@@ -277,7 +277,7 @@ func TestDelete(t *testing.T) {
label: "Successfull Delete of entry",
input: map[string]interface{}{
"coll": "collname",
- "key": mockKey{Key: "keyvalue"},
+ "key": MockKey{Key: "keyvalue"},
"tag": "metadata",
},
// Binary form of
@@ -305,7 +305,7 @@ func TestDelete(t *testing.T) {
label: "UnSuccessfull Delete of entry",
input: map[string]interface{}{
"coll": "collname",
- "key": mockKey{Key: "keyvalue"},
+ "key": MockKey{Key: "keyvalue"},
"tag": "tagName",
},
mockColl: &mockCollection{
@@ -317,7 +317,7 @@ func TestDelete(t *testing.T) {
label: "UnSuccessfull Delete, key not found",
input: map[string]interface{}{
"coll": "collname",
- "key": mockKey{Key: "keyvalue"},
+ "key": MockKey{Key: "keyvalue"},
"tag": "tagName",
},
// Binary form of
@@ -346,7 +346,7 @@ func TestDelete(t *testing.T) {
label: "Missing input fields",
input: map[string]interface{}{
"coll": "",
- "key": mockKey{Key: ""},
+ "key": MockKey{Key: ""},
"tag": "",
},
expectedError: "Mandatory fields are missing",
diff --git a/src/k8splugin/internal/db/testing.go b/src/k8splugin/internal/db/testing.go
index a411790e..e7e7436a 100644
--- a/src/k8splugin/internal/db/testing.go
+++ b/src/k8splugin/internal/db/testing.go
@@ -20,11 +20,11 @@ import (
pkgerrors "github.com/pkg/errors"
)
-type mockKey struct {
+type MockKey struct {
Key string
}
-func (m mockKey) String() string {
+func (m MockKey) String() string {
return m.Key
}
diff --git a/src/k8splugin/internal/rb/definition.go b/src/k8splugin/internal/rb/definition.go
index 2ebbb08a..1c6b1bc5 100644
--- a/src/k8splugin/internal/rb/definition.go
+++ b/src/k8splugin/internal/rb/definition.go
@@ -19,6 +19,7 @@ package rb
import (
"bytes"
"encoding/base64"
+ "encoding/json"
"io/ioutil"
"log"
"os"
@@ -26,35 +27,42 @@ import (
"k8splugin/internal/db"
- uuid "github.com/hashicorp/go-uuid"
pkgerrors "github.com/pkg/errors"
)
// Definition contains the parameters needed for resource bundle (rb) definitions
// It implements the interface for managing the definitions
type Definition struct {
- UUID string `json:"uuid,omitempty"`
- Name string `json:"name"`
- ChartName string `json:"chart-name"`
- Description string `json:"description"`
- ServiceType string `json:"service-type"`
+ Name string `json:"rb-name"`
+ Version string `json:"rb-version"`
+ ChartName string `json:"chart-name"`
+ Description string `json:"description"`
+ Labels map[string]string `json:"labels"`
}
-// DefinitionManager is an interface exposes the resource bundle definition functionality
-type DefinitionManager interface {
- Create(def Definition) (Definition, error)
- List() ([]Definition, error)
- Get(resID string) (Definition, error)
- Delete(resID string) error
- Upload(resID string, inp []byte) error
+type DefinitionKey struct {
+ Name string `json:"rb-name"`
+ Version string `json:"rb-version"`
}
-type definitionKey struct {
- Key string
+// We will use json marshalling to convert to string to
+// preserve the underlying structure.
+func (dk DefinitionKey) String() string {
+ out, err := json.Marshal(dk)
+ if err != nil {
+ return ""
+ }
+
+ return string(out)
}
-func (dk definitionKey) String() string {
- return dk.Key
+// DefinitionManager is an interface exposes the resource bundle definition functionality
+type DefinitionManager interface {
+ Create(def Definition) (Definition, error)
+ List(name string) ([]Definition, error)
+ Get(name string, version string) (Definition, error)
+ Delete(name string, version string) error
+ Upload(name string, version string, inp []byte) error
}
// DefinitionClient implements the DefinitionManager
@@ -77,13 +85,17 @@ func NewDefinitionClient() *DefinitionClient {
// Create an entry for the resource in the database
func (v *DefinitionClient) Create(def Definition) (Definition, error) {
- // If UUID is empty, we will generate one
- if def.UUID == "" {
- def.UUID, _ = uuid.GenerateUUID()
+
+ //Construct composite key consisting of name and version
+ key := DefinitionKey{Name: def.Name, Version: def.Version}
+
+ //Check if this definition already exists
+ _, err := v.Get(def.Name, def.Version)
+ if err == nil {
+ return Definition{}, pkgerrors.New("Definition already exists")
}
- key := definitionKey{Key: def.UUID}
- err := db.DBconn.Create(v.storeName, key, v.tagMeta, def)
+ err = db.DBconn.Create(v.storeName, key, v.tagMeta, def)
if err != nil {
return Definition{}, pkgerrors.Wrap(err, "Creating DB Entry")
}
@@ -91,8 +103,8 @@ func (v *DefinitionClient) Create(def Definition) (Definition, error) {
return def, nil
}
-// List all resource entries in the database
-func (v *DefinitionClient) List() ([]Definition, error) {
+// List all resource entry's versions in the database
+func (v *DefinitionClient) List(name string) ([]Definition, error) {
res, err := db.DBconn.ReadAll(v.storeName, v.tagMeta)
if err != nil || len(res) == 0 {
return []Definition{}, pkgerrors.Wrap(err, "Listing Resource Bundle Definitions")
@@ -108,7 +120,10 @@ func (v *DefinitionClient) List() ([]Definition, error) {
log.Printf("[Definition] Error Unmarshaling value for: %s", key)
continue
}
- results = append(results, def)
+ //Select only the definitions that match name provided
+ if def.Name == name {
+ results = append(results, def)
+ }
}
}
@@ -116,8 +131,10 @@ func (v *DefinitionClient) List() ([]Definition, error) {
}
// Get returns the Resource Bundle Definition for corresponding ID
-func (v *DefinitionClient) Get(id string) (Definition, error) {
- key := definitionKey{Key: id}
+func (v *DefinitionClient) Get(name string, version string) (Definition, error) {
+
+ //Construct the composite key to select the entry
+ key := DefinitionKey{Name: name, Version: version}
value, err := db.DBconn.Read(v.storeName, key, v.tagMeta)
if err != nil {
return Definition{}, pkgerrors.Wrap(err, "Get Resource Bundle definition")
@@ -137,8 +154,10 @@ func (v *DefinitionClient) Get(id string) (Definition, error) {
}
// Delete the Resource Bundle definition from database
-func (v *DefinitionClient) Delete(id string) error {
- key := definitionKey{Key: id}
+func (v *DefinitionClient) Delete(name string, version string) error {
+
+ //Construct the composite key to select the entry
+ key := DefinitionKey{Name: name, Version: version}
err := db.DBconn.Delete(v.storeName, key, v.tagMeta)
if err != nil {
return pkgerrors.Wrap(err, "Delete Resource Bundle Definition")
@@ -154,11 +173,10 @@ func (v *DefinitionClient) Delete(id string) error {
}
// Upload the contents of resource bundle into database
-func (v *DefinitionClient) Upload(id string, inp []byte) error {
+func (v *DefinitionClient) Upload(name string, version string, inp []byte) error {
- key := definitionKey{Key: id}
//Check if definition metadata exists
- def, err := v.Get(id)
+ def, err := v.Get(name, version)
if err != nil {
return pkgerrors.Errorf("Invalid Definition ID provided: %s", err.Error())
}
@@ -168,6 +186,9 @@ func (v *DefinitionClient) Upload(id string, inp []byte) error {
return pkgerrors.Errorf("Error in file format: %s", err.Error())
}
+ //Construct the composite key to select the entry
+ key := DefinitionKey{Name: name, Version: version}
+
//Detect chart name from data if it was not provided originally
if def.ChartName == "" {
path, err := ExtractTarBall(bytes.NewBuffer(inp))
@@ -195,7 +216,8 @@ func (v *DefinitionClient) Upload(id string, inp []byte) error {
return pkgerrors.New("Unable to detect chart name")
}
- _, err = v.Create(def)
+ //TODO: Use db update api once db supports it.
+ err = db.DBconn.Create(v.storeName, key, v.tagMeta, def)
if err != nil {
return pkgerrors.Wrap(err, "Storing updated chart metadata")
}
@@ -214,16 +236,17 @@ func (v *DefinitionClient) Upload(id string, inp []byte) error {
// Download the contents of the resource bundle definition from DB
// Returns a byte array of the contents which is used by the
// ExtractTarBall code to create the folder structure on disk
-func (v *DefinitionClient) Download(id string) ([]byte, error) {
+func (v *DefinitionClient) Download(name string, version string) ([]byte, error) {
- key := definitionKey{Key: id}
//ignore the returned data here
//Check if id is valid
- _, err := v.Get(id)
+ _, err := v.Get(name, version)
if err != nil {
return nil, pkgerrors.Errorf("Invalid Definition ID provided: %s", err.Error())
}
+ //Construct the composite key to select the entry
+ key := DefinitionKey{Name: name, Version: version}
value, err := db.DBconn.Read(v.storeName, key, v.tagContent)
if err != nil {
return nil, pkgerrors.Wrap(err, "Get Resource Bundle definition content")
diff --git a/src/k8splugin/internal/rb/definition_test.go b/src/k8splugin/internal/rb/definition_test.go
index b1875fd7..96aaafbe 100644
--- a/src/k8splugin/internal/rb/definition_test.go
+++ b/src/k8splugin/internal/rb/definition_test.go
@@ -40,16 +40,16 @@ func TestCreateDefinition(t *testing.T) {
{
label: "Create Resource Bundle Definition",
inp: Definition{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
Name: "testresourcebundle",
+ Version: "v1",
Description: "testresourcebundle",
- ServiceType: "firewall",
+ ChartName: "",
},
expected: Definition{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
Name: "testresourcebundle",
+ Version: "v1",
Description: "testresourcebundle",
- ServiceType: "firewall",
+ ChartName: "",
},
expectedError: "",
mockdb: &db.MockDB{},
@@ -89,42 +89,44 @@ func TestListDefinition(t *testing.T) {
testCases := []struct {
label string
+ name string
expectedError string
mockdb *db.MockDB
expected []Definition
}{
{
label: "List Resource Bundle Definition",
+ name: "testresourcebundle",
expected: []Definition{
{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
Name: "testresourcebundle",
+ Version: "v1",
Description: "testresourcebundle",
- ServiceType: "firewall",
+ ChartName: "testchart",
},
{
- UUID: "123e4567-e89b-12d3-a456-426655441111",
- Name: "testresourcebundle2",
- Description: "testresourcebundle2",
- ServiceType: "dns",
+ Name: "testresourcebundle",
+ Version: "v2",
+ Description: "testresourcebundle_version2",
+ ChartName: "testchart",
},
},
expectedError: "",
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"testchart\"}"),
},
- "123e4567-e89b-12d3-a456-426655441111": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v2"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle2\"," +
- "\"description\":\"testresourcebundle2\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655441111\"," +
- "\"service-type\":\"dns\"}"),
+ "{\"rb-name\":\"testresourcebundle\"," +
+ "\"description\":\"testresourcebundle_version2\"," +
+ "\"rb-version\":\"v2\"," +
+ "\"chart-name\":\"testchart\"}"),
},
},
},
@@ -142,7 +144,7 @@ func TestListDefinition(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewDefinitionClient()
- got, err := impl.List()
+ got, err := impl.List(testCase.name)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("List returned an unexpected error %s", err)
@@ -154,12 +156,12 @@ func TestListDefinition(t *testing.T) {
// Since the order of returned slice is not guaranteed
// Check both and return error if both don't match
sort.Slice(got, func(i, j int) bool {
- return got[i].UUID < got[j].UUID
+ return got[i].Version < got[j].Version
})
// Sort both as it is not expected that testCase.expected
// is sorted
sort.Slice(testCase.expected, func(i, j int) bool {
- return testCase.expected[i].UUID < testCase.expected[j].UUID
+ return testCase.expected[i].Version < testCase.expected[j].Version
})
if reflect.DeepEqual(testCase.expected, got) == false {
@@ -175,29 +177,32 @@ func TestGetDefinition(t *testing.T) {
testCases := []struct {
label string
+ name string
+ version string
expectedError string
mockdb *db.MockDB
inp string
expected Definition
}{
{
- label: "Get Resource Bundle Definition",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ label: "Get Resource Bundle Definition",
+ name: "testresourcebundle",
+ version: "v1",
expected: Definition{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
Name: "testresourcebundle",
+ Version: "v1",
Description: "testresourcebundle",
- ServiceType: "firewall",
+ ChartName: "testchart",
},
expectedError: "",
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"testchart\"}"),
},
},
},
@@ -215,7 +220,7 @@ func TestGetDefinition(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewDefinitionClient()
- got, err := impl.Get(testCase.inp)
+ got, err := impl.Get(testCase.name, testCase.version)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Get returned an unexpected error %s", err)
@@ -237,14 +242,16 @@ func TestDeleteDefinition(t *testing.T) {
testCases := []struct {
label string
- inp string
+ name string
+ version string
expectedError string
mockdb *db.MockDB
}{
{
- label: "Delete Resource Bundle Definition",
- inp: "123e4567-e89b-12d3-a456-426655440000",
- mockdb: &db.MockDB{},
+ label: "Delete Resource Bundle Definition",
+ name: "testresourcebundle",
+ version: "v1",
+ mockdb: &db.MockDB{},
},
{
label: "Delete Error",
@@ -259,7 +266,7 @@ func TestDeleteDefinition(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewDefinitionClient()
- err := impl.Delete(testCase.inp)
+ err := impl.Delete(testCase.name, testCase.version)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Delete returned an unexpected error %s", err)
@@ -275,14 +282,15 @@ func TestDeleteDefinition(t *testing.T) {
func TestUploadDefinition(t *testing.T) {
testCases := []struct {
label string
- inp string
+ name, version string
content []byte
expectedError string
mockdb *db.MockDB
}{
{
- label: "Upload With Chart Name Detection",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ label: "Upload With Chart Name Detection",
+ name: "testresourcebundle",
+ version: "v1",
//Binary format for testchart/Chart.yaml
content: []byte{
0x1f, 0x8b, 0x08, 0x08, 0xb3, 0xeb, 0x86, 0x5c,
@@ -319,19 +327,19 @@ func TestUploadDefinition(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"}"),
},
},
},
},
{
- label: "Upload With Chart Name",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ label: "Upload With Chart Name",
+ name: "testresourcebundle",
+ version: "v1",
content: []byte{
0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
@@ -355,20 +363,20 @@ func TestUploadDefinition(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"chart-name\":\"testchart\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"firewall\"}"),
},
},
},
},
{
label: "Upload Without Chart.yaml",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ name: "testresourcebundle",
+ version: "v1",
expectedError: "Unable to detect chart name",
content: []byte{
0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
@@ -393,19 +401,20 @@ func TestUploadDefinition(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"firewall\"}"),
},
},
},
},
{
label: "Upload with an Invalid Resource Bundle Definition",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ name: "testresourcebundle",
+ version: "v1",
expectedError: "Invalid Definition ID provided",
content: []byte{
0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
@@ -430,19 +439,20 @@ func TestUploadDefinition(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655441111": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655441111\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"firewall\"}"),
},
},
},
},
{
label: "Invalid File Format Error",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ name: "testresourcebundle",
+ version: "v1",
expectedError: "Error in file format",
content: []byte{
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -450,12 +460,12 @@ func TestUploadDefinition(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"firewall\"}"),
},
},
},
@@ -494,7 +504,7 @@ func TestUploadDefinition(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewDefinitionClient()
- err := impl.Upload(testCase.inp, testCase.content)
+ err := impl.Upload(testCase.name, testCase.version, testCase.content)
if err != nil {
if testCase.expectedError == "" {
t.Errorf("Upload returned an unexpected error %s", err)
@@ -510,14 +520,15 @@ func TestUploadDefinition(t *testing.T) {
func TestDownloadDefinition(t *testing.T) {
testCases := []struct {
label string
- inp string
+ name, version string
expected []byte
expectedError string
mockdb *db.MockDB
}{
{
- label: "Download Resource Bundle Definition",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ label: "Download Resource Bundle Definition",
+ name: "testresourcebundle",
+ version: "v1",
expected: []byte{
0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
@@ -541,12 +552,12 @@ func TestDownloadDefinition(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"firewall\"}"),
"content": []byte("H4sICLBr9FsAA3Rlc3QudGFyAO3OQQrCMBCF4aw9RU5" +
"QEtLE40igAUtSC+2IHt9IEVwIpYtShP/bvGFmFk/SLI08Re3IVCG077Rn" +
"b75zYZ2yztVV8N7XP9vWSWmzZ6mP+yxx0lrF7pJzjkN/Sz//1u5/6ppKG" +
@@ -557,16 +568,17 @@ func TestDownloadDefinition(t *testing.T) {
},
{
label: "Download with an Invalid Resource Bundle Definition",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ name: "testresourcebundle",
+ version: "v2",
expectedError: "Invalid Definition ID provided",
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655441111": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
"\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655441111\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"firewall\"}"),
},
},
},
@@ -574,7 +586,6 @@ func TestDownloadDefinition(t *testing.T) {
{
label: "Download Error",
expectedError: "DB Error",
- inp: "123e4567-e89b-12d3-a456-426655440000",
mockdb: &db.MockDB{
Err: pkgerrors.New("DB Error"),
},
@@ -585,7 +596,7 @@ func TestDownloadDefinition(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewDefinitionClient()
- data, err := impl.Download(testCase.inp)
+ data, err := impl.Download(testCase.name, testCase.version)
if err != nil {
if testCase.expectedError == "" {
t.Errorf("Download returned an unexpected error %s", err)
diff --git a/src/k8splugin/internal/rb/profile.go b/src/k8splugin/internal/rb/profile.go
index 006fa913..572a175c 100644
--- a/src/k8splugin/internal/rb/profile.go
+++ b/src/k8splugin/internal/rb/profile.go
@@ -19,11 +19,10 @@ package rb
import (
"bytes"
"encoding/base64"
+ "encoding/json"
"k8splugin/internal/db"
- "log"
"path/filepath"
- uuid "github.com/hashicorp/go-uuid"
pkgerrors "github.com/pkg/errors"
"k8splugin/internal/helm"
@@ -32,29 +31,38 @@ import (
// Profile contains the parameters needed for resource bundle (rb) profiles
// It implements the interface for managing the profiles
type Profile struct {
- UUID string `json:"uuid,omitempty"`
- RBDID string `json:"rbdid"`
- Name string `json:"name"`
- Namespace string `json:"namespace"`
- KubernetesVersion string `json:"kubernetesversion"`
+ RBName string `json:"rb-name"`
+ RBVersion string `json:"rb-version"`
+ Name string `json:"profile-name"`
+ ReleaseName string `json:"release-name"`
+ Namespace string `json:"namespace"`
+ KubernetesVersion string `json:"kubernetes-version"`
+ Labels map[string]string `json:"labels"`
}
// ProfileManager is an interface exposes the resource bundle profile functionality
type ProfileManager interface {
Create(def Profile) (Profile, error)
- List() ([]Profile, error)
- Get(resID string) (Profile, error)
- Help() map[string]string
- Delete(resID string) error
- Upload(resID string, inp []byte) error
+ Get(rbName, rbVersion, prName string) (Profile, error)
+ Delete(rbName, rbVersion, prName string) error
+ Upload(rbName, rbVersion, prName string, inp []byte) error
}
-type profileKey struct {
- Key string
+type ProfileKey struct {
+ RBName string `json:"rb-name"`
+ RBVersion string `json:"rb-version"`
+ Name string `json:"profile-name"`
}
-func (dk profileKey) String() string {
- return dk.Key
+// We will use json marshalling to convert to string to
+// preserve the underlying structure.
+func (dk ProfileKey) String() string {
+ out, err := json.Marshal(dk)
+ if err != nil {
+ return ""
+ }
+
+ return string(out)
}
// ProfileClient implements the ProfileManager
@@ -67,80 +75,61 @@ type ProfileClient struct {
// NewProfileClient returns an instance of the ProfileClient
// which implements the ProfileManager
-// Uses rb/def prefix
func NewProfileClient() *ProfileClient {
return &ProfileClient{
- storeName: "rbprofile",
+ storeName: "rbdef",
tagMeta: "metadata",
tagContent: "content",
manifestName: "manifest.yaml",
}
}
-// Help returns some information on how to create the content
-// for the profile in the form of html formatted page
-func (v *ProfileClient) Help() map[string]string {
- ret := make(map[string]string)
-
- return ret
-}
-
// Create an entry for the resource bundle profile in the database
func (v *ProfileClient) Create(p Profile) (Profile, error) {
- //Check if provided RBID is a valid resource bundle
- _, err := NewDefinitionClient().Get(p.RBDID)
- if err != nil {
- return Profile{}, pkgerrors.Errorf("Invalid Resource Bundle ID provided: %s", err.Error())
- }
-
// Name is required
if p.Name == "" {
return Profile{}, pkgerrors.New("Name is required for Resource Bundle Profile")
}
- // If UUID is empty, we will generate one
- if p.UUID == "" {
- p.UUID, _ = uuid.GenerateUUID()
+ //Check if profile already exists
+ _, err := v.Get(p.RBName, p.RBVersion, p.Name)
+ if err == nil {
+ return Profile{}, pkgerrors.New("Profile already exists for this Definition")
}
- key := profileKey{Key: p.UUID}
- err = db.DBconn.Create(v.storeName, key, v.tagMeta, p)
+ //Check if provided resource bundle information is valid
+ _, err = NewDefinitionClient().Get(p.RBName, p.RBVersion)
if err != nil {
- return Profile{}, pkgerrors.Wrap(err, "Creating Profile DB Entry")
+ return Profile{}, pkgerrors.Errorf("Invalid Resource Bundle ID provided: %s", err.Error())
}
- return p, nil
-}
+ //If release-name is not provided, we store name instead
+ if p.ReleaseName == "" {
+ p.ReleaseName = p.Name
+ }
-// List all resource entries in the database
-func (v *ProfileClient) List() ([]Profile, error) {
- res, err := db.DBconn.ReadAll(v.storeName, v.tagMeta)
- if err != nil || len(res) == 0 {
- return []Profile{}, pkgerrors.Wrap(err, "Listing Resource Bundle Profiles")
+ key := ProfileKey{
+ RBName: p.RBName,
+ RBVersion: p.RBVersion,
+ Name: p.Name,
}
- var retData []Profile
-
- for key, value := range res {
- //value is a byte array
- if len(value) > 0 {
- pr := Profile{}
- err = db.DBconn.Unmarshal(value, &pr)
- if err != nil {
- log.Printf("[Profile] Error Unmarshaling value for: %s", key)
- continue
- }
- retData = append(retData, pr)
- }
+ err = db.DBconn.Create(v.storeName, key, v.tagMeta, p)
+ if err != nil {
+ return Profile{}, pkgerrors.Wrap(err, "Creating Profile DB Entry")
}
- return retData, nil
+ return p, nil
}
// Get returns the Resource Bundle Profile for corresponding ID
-func (v *ProfileClient) Get(id string) (Profile, error) {
- key := profileKey{Key: id}
+func (v *ProfileClient) Get(rbName, rbVersion, prName string) (Profile, error) {
+ key := ProfileKey{
+ RBName: rbName,
+ RBVersion: rbVersion,
+ Name: prName,
+ }
value, err := db.DBconn.Read(v.storeName, key, v.tagMeta)
if err != nil {
return Profile{}, pkgerrors.Wrap(err, "Get Resource Bundle Profile")
@@ -160,8 +149,12 @@ func (v *ProfileClient) Get(id string) (Profile, error) {
}
// Delete the Resource Bundle Profile from database
-func (v *ProfileClient) Delete(id string) error {
- key := profileKey{Key: id}
+func (v *ProfileClient) Delete(rbName, rbVersion, prName string) error {
+ key := ProfileKey{
+ RBName: rbName,
+ RBVersion: rbVersion,
+ Name: prName,
+ }
err := db.DBconn.Delete(v.storeName, key, v.tagMeta)
if err != nil {
return pkgerrors.Wrap(err, "Delete Resource Bundle Profile")
@@ -176,13 +169,12 @@ func (v *ProfileClient) Delete(id string) error {
}
// Upload the contents of resource bundle into database
-func (v *ProfileClient) Upload(id string, inp []byte) error {
+func (v *ProfileClient) Upload(rbName, rbVersion, prName string, inp []byte) error {
- key := profileKey{Key: id}
//ignore the returned data here.
- _, err := v.Get(id)
+ _, err := v.Get(rbName, rbVersion, prName)
if err != nil {
- return pkgerrors.Errorf("Invalid Profile ID provided %s", err.Error())
+ return pkgerrors.Errorf("Invalid Profile Name provided %s", err.Error())
}
err = isTarGz(bytes.NewBuffer(inp))
@@ -190,6 +182,11 @@ func (v *ProfileClient) Upload(id string, inp []byte) error {
return pkgerrors.Errorf("Error in file format %s", err.Error())
}
+ key := ProfileKey{
+ RBName: rbName,
+ RBVersion: rbVersion,
+ Name: prName,
+ }
//Encode given byte stream to text for storage
encodedStr := base64.StdEncoding.EncodeToString(inp)
err = db.DBconn.Create(v.storeName, key, v.tagContent, encodedStr)
@@ -203,16 +200,20 @@ func (v *ProfileClient) Upload(id string, inp []byte) error {
// Download the contents of the resource bundle profile from DB
// Returns a byte array of the contents which is used by the
// ExtractTarBall code to create the folder structure on disk
-func (v *ProfileClient) Download(id string) ([]byte, error) {
+func (v *ProfileClient) Download(rbName, rbVersion, prName string) ([]byte, error) {
- key := profileKey{Key: id}
//ignore the returned data here
//Check if id is valid
- _, err := v.Get(id)
+ _, err := v.Get(rbName, rbVersion, prName)
if err != nil {
- return nil, pkgerrors.Errorf("Invalid Profile ID provided: %s", err.Error())
+ return nil, pkgerrors.Errorf("Invalid Profile Name provided: %s", err.Error())
}
+ key := ProfileKey{
+ RBName: rbName,
+ RBVersion: rbVersion,
+ Name: prName,
+ }
value, err := db.DBconn.Read(v.storeName, key, v.tagContent)
if err != nil {
return nil, pkgerrors.Wrap(err, "Get Resource Bundle Profile content")
@@ -234,13 +235,14 @@ func (v *ProfileClient) Download(id string) ([]byte, error) {
//Resolve returns the path where the helm chart merged with
//configuration overrides resides.
-func (v *ProfileClient) Resolve(id string, values []string) (map[string][]string, error) {
+func (v *ProfileClient) Resolve(rbName string, rbVersion string,
+ profileName string, values []string) (map[string][]string, error) {
var retMap map[string][]string
//Download and process the profile first
//If everything seems okay, then download the definition
- prData, err := v.Download(id)
+ prData, err := v.Download(rbName, rbVersion, profileName)
if err != nil {
return retMap, pkgerrors.Wrap(err, "Downloading Profile")
}
@@ -255,20 +257,14 @@ func (v *ProfileClient) Resolve(id string, values []string) (map[string][]string
return retMap, pkgerrors.Wrap(err, "Processing Profile Manifest")
}
- //Get the definition ID and download its contents
- profile, err := v.Get(id)
- if err != nil {
- return retMap, pkgerrors.Wrap(err, "Getting Profile")
- }
-
definitionClient := NewDefinitionClient()
- definition, err := definitionClient.Get(profile.RBDID)
+ definition, err := definitionClient.Get(rbName, rbVersion)
if err != nil {
return retMap, pkgerrors.Wrap(err, "Getting Definition Metadata")
}
- defData, err := definitionClient.Download(profile.RBDID)
+ defData, err := definitionClient.Download(rbName, rbVersion)
if err != nil {
return retMap, pkgerrors.Wrap(err, "Downloading Definition")
}
@@ -278,6 +274,12 @@ func (v *ProfileClient) Resolve(id string, values []string) (map[string][]string
return retMap, pkgerrors.Wrap(err, "Extracting Definition Charts")
}
+ //Get the definition ID and download its contents
+ profile, err := v.Get(rbName, rbVersion, profileName)
+ if err != nil {
+ return retMap, pkgerrors.Wrap(err, "Getting Profile")
+ }
+
//Copy the profile configresources to the chart locations
//Corresponds to the following from the profile yaml
// configresource:
@@ -290,7 +292,7 @@ func (v *ProfileClient) Resolve(id string, values []string) (map[string][]string
helmClient := helm.NewTemplateClient(profile.KubernetesVersion,
profile.Namespace,
- profile.Name)
+ profile.ReleaseName)
chartPath := filepath.Join(chartBasePath, definition.ChartName)
retMap, err = helmClient.GenerateKubernetesArtifacts(chartPath,
diff --git a/src/k8splugin/internal/rb/profile_test.go b/src/k8splugin/internal/rb/profile_test.go
index df0db18a..5d41b019 100644
--- a/src/k8splugin/internal/rb/profile_test.go
+++ b/src/k8splugin/internal/rb/profile_test.go
@@ -22,7 +22,6 @@ import (
"bytes"
"k8splugin/internal/db"
"reflect"
- "sort"
"strings"
"testing"
@@ -40,101 +39,62 @@ func TestCreateProfile(t *testing.T) {
{
label: "Create Resource Bundle Profile",
inp: Profile{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle",
- Namespace: "default",
+ Name: "testprofile1",
+ ReleaseName: "testprofilereleasename",
+ Namespace: "testnamespace",
KubernetesVersion: "1.12.3",
+ RBName: "testresourcebundle",
+ RBVersion: "v1",
},
expected: Profile{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle",
- Namespace: "default",
+ Name: "testprofile1",
+ ReleaseName: "testprofilereleasename",
+ Namespace: "testnamespace",
KubernetesVersion: "1.12.3",
+ RBName: "testresourcebundle",
+ RBVersion: "v1",
},
expectedError: "",
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "abcde123-e89b-8888-a456-986655447236": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"kubernetesversion\":\"1.12.3\"}"),
+ "{\"rb-name\":\"testresourcebundle\"," +
+ "\"description\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"testchart\"}"),
},
},
},
},
{
- label: "Failed Create Resource Bundle Profile",
- expectedError: "Error Creating Profile",
- mockdb: &db.MockDB{
- Err: pkgerrors.New("Error Creating Profile"),
- },
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- db.DBconn = testCase.mockdb
- impl := NewProfileClient()
- got, err := impl.Create(testCase.inp)
- if err != nil {
- if testCase.expectedError == "" {
- t.Fatalf("Create returned an unexpected error %s", err)
- }
- if strings.Contains(err.Error(), testCase.expectedError) == false {
- t.Fatalf("Create returned an unexpected error %s", err)
- }
- } else {
- if reflect.DeepEqual(testCase.expected, got) == false {
- t.Errorf("Create Resource Bundle returned unexpected body: got %v;"+
- " expected %v", got, testCase.expected)
- }
- }
- })
- }
-}
-
-func TestListProfiles(t *testing.T) {
-
- testCases := []struct {
- label string
- expectedError string
- mockdb *db.MockDB
- expected []Profile
- }{
- {
- label: "List Resource Bundle Profile",
- expected: []Profile{
- {
- UUID: "123e4567-e89b-12d3-a456-426655440000",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle",
- Namespace: "default",
- KubernetesVersion: "1.12.3",
- },
+ label: "Create Resource Bundle Profile With Non-Existing Definition",
+ inp: Profile{
+ Name: "testprofile1",
+ ReleaseName: "testprofilereleasename",
+ Namespace: "testnamespace",
+ KubernetesVersion: "1.12.3",
+ RBName: "testresourcebundle",
+ RBVersion: "v1",
},
- expectedError: "",
+ expectedError: "Error getting Resource Bundle Definition",
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v2"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
- "\"kubernetesversion\":\"1.12.3\"}"),
+ "{\"rb-name\":\"testresourcebundle\"," +
+ "\"description\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
+ "\"chart-name\":\"testchart\"}"),
},
},
},
},
{
- label: "List Error",
- expectedError: "DB Error",
+ label: "Failed Create Resource Bundle Profile",
+ expectedError: "Name is required",
mockdb: &db.MockDB{
- Err: pkgerrors.New("DB Error"),
+ Err: pkgerrors.New("Error Creating Profile"),
},
},
}
@@ -143,28 +103,17 @@ func TestListProfiles(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewProfileClient()
- got, err := impl.List()
+ got, err := impl.Create(testCase.inp)
if err != nil {
if testCase.expectedError == "" {
- t.Fatalf("List returned an unexpected error %s", err)
+ t.Fatalf("Create returned an unexpected error %s", err)
}
if strings.Contains(err.Error(), testCase.expectedError) == false {
- t.Fatalf("List returned an unexpected error %s", err)
+ t.Fatalf("Create returned an unexpected error %s", err)
}
} else {
- // Since the order of returned slice is not guaranteed
- // Check both and return error if both don't match
- sort.Slice(got, func(i, j int) bool {
- return got[i].UUID < got[j].UUID
- })
- // Sort both as it is not expected that testCase.expected
- // is sorted
- sort.Slice(testCase.expected, func(i, j int) bool {
- return testCase.expected[i].UUID < testCase.expected[j].UUID
- })
-
if reflect.DeepEqual(testCase.expected, got) == false {
- t.Errorf("List Resource Bundle returned unexpected body: got %v;"+
+ t.Errorf("Create Resource Bundle returned unexpected body: got %v;"+
" expected %v", got, testCase.expected)
}
}
@@ -175,32 +124,36 @@ func TestListProfiles(t *testing.T) {
func TestGetProfile(t *testing.T) {
testCases := []struct {
- label string
- expectedError string
- mockdb *db.MockDB
- inp string
- expected Profile
+ label string
+ rbname, rbversion, prname string
+ expectedError string
+ mockdb *db.MockDB
+ expected Profile
}{
{
- label: "Get Resource Bundle Profile",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ label: "Get Resource Bundle Profile",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "testprofile1",
expected: Profile{
- UUID: "123e4567-e89b-12d3-a456-426655440000",
- RBDID: "abcde123-e89b-8888-a456-986655447236",
- Name: "testresourcebundle",
- Namespace: "default",
+ Name: "testprofile1",
+ ReleaseName: "testprofilereleasename",
+ Namespace: "testnamespace",
KubernetesVersion: "1.12.3",
+ RBName: "testresourcebundle",
+ RBVersion: "v1",
},
expectedError: "",
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ ProfileKey{RBName: "testresourcebundle", RBVersion: "v1", Name: "testprofile1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
- "\"kubernetesversion\":\"1.12.3\"}"),
+ "{\"profile-name\":\"testprofile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
+ "\"kubernetes-version\":\"1.12.3\"}"),
},
},
},
@@ -218,7 +171,7 @@ func TestGetProfile(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewProfileClient()
- got, err := impl.Get(testCase.inp)
+ got, err := impl.Get(testCase.rbname, testCase.rbversion, testCase.prname)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Get returned an unexpected error %s", err)
@@ -239,15 +192,17 @@ func TestGetProfile(t *testing.T) {
func TestDeleteProfile(t *testing.T) {
testCases := []struct {
- label string
- inp string
- expectedError string
- mockdb *db.MockDB
+ label string
+ rbname, rbversion, prname string
+ expectedError string
+ mockdb *db.MockDB
}{
{
- label: "Delete Resource Bundle Profile",
- inp: "123e4567-e89b-12d3-a456-426655440000",
- mockdb: &db.MockDB{},
+ label: "Delete Resource Bundle Profile",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "testprofile1",
+ mockdb: &db.MockDB{},
},
{
label: "Delete Error",
@@ -262,7 +217,7 @@ func TestDeleteProfile(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewProfileClient()
- err := impl.Delete(testCase.inp)
+ err := impl.Delete(testCase.rbname, testCase.rbversion, testCase.prname)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Delete returned an unexpected error %s", err)
@@ -277,15 +232,17 @@ func TestDeleteProfile(t *testing.T) {
func TestUploadProfile(t *testing.T) {
testCases := []struct {
- label string
- inp string
- content []byte
- expectedError string
- mockdb *db.MockDB
+ label string
+ rbname, rbversion, prname string
+ content []byte
+ expectedError string
+ mockdb *db.MockDB
}{
{
- label: "Upload Resource Bundle Profile",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ label: "Upload Resource Bundle Profile",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "testprofile1",
content: []byte{
0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
@@ -309,12 +266,13 @@ func TestUploadProfile(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ ProfileKey{RBName: "testresourcebundle", RBVersion: "v1", Name: "testprofile1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
+ "{\"profile-name\":\"testprofile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
"\"kubernetesversion\":\"1.12.3\"}"),
},
},
@@ -322,8 +280,10 @@ func TestUploadProfile(t *testing.T) {
},
{
label: "Upload with an Invalid Resource Bundle Profile",
- inp: "123e4567-e89b-12d3-a456-426655440000",
- expectedError: "Invalid Profile ID provided",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "testprofile1",
+ expectedError: "Invalid Profile Name provided",
content: []byte{
0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
@@ -347,12 +307,13 @@ func TestUploadProfile(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655441111": {
+ ProfileKey{RBName: "testresourcebundle", RBVersion: "v1", Name: "testprofile2"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655441111\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
+ "{\"profile-name\":\"testprofile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
"\"kubernetesversion\":\"1.12.3\"}"),
},
},
@@ -360,7 +321,9 @@ func TestUploadProfile(t *testing.T) {
},
{
label: "Invalid File Format Error",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "testprofile1",
expectedError: "Error in file format",
content: []byte{
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -368,12 +331,13 @@ func TestUploadProfile(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ ProfileKey{RBName: "testresourcebundle", RBVersion: "v1", Name: "testprofile1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
+ "{\"profile-name\":\"testprofile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
"\"kubernetesversion\":\"1.12.3\"}"),
},
},
@@ -413,7 +377,7 @@ func TestUploadProfile(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewProfileClient()
- err := impl.Upload(testCase.inp, testCase.content)
+ err := impl.Upload(testCase.rbname, testCase.rbversion, testCase.prname, testCase.content)
if err != nil {
if testCase.expectedError == "" {
t.Errorf("Upload returned an unexpected error %s", err)
@@ -428,15 +392,17 @@ func TestUploadProfile(t *testing.T) {
func TestDownloadProfile(t *testing.T) {
testCases := []struct {
- label string
- inp string
- expected []byte
- expectedError string
- mockdb *db.MockDB
+ label string
+ rbname, rbversion, prname string
+ expected []byte
+ expectedError string
+ mockdb *db.MockDB
}{
{
- label: "Download Resource Bundle Profile",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ label: "Download Resource Bundle Profile",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "testprofile1",
expected: []byte{
0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
@@ -460,12 +426,13 @@ func TestDownloadProfile(t *testing.T) {
},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ ProfileKey{RBName: "testresourcebundle", RBVersion: "v1", Name: "testprofile1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
+ "{\"profile-name\":\"testprofile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
"\"kubernetesversion\":\"1.12.3\"}"),
"content": []byte("H4sICLBr9FsAA3Rlc3QudGFyAO3OQQrCMBCF4aw9RU5" +
"QEtLE40igAUtSC+2IHt9IEVwIpYtShP/bvGFmFk/SLI08Re3IVCG077Rn" +
@@ -477,16 +444,19 @@ func TestDownloadProfile(t *testing.T) {
},
{
label: "Download with an Invalid Resource Bundle Profile",
- inp: "123e4567-e89b-12d3-a456-426655440000",
- expectedError: "Invalid Profile ID provided",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "testprofile1",
+ expectedError: "Invalid Profile Name provided",
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655441111": {
+ ProfileKey{RBName: "testresourcebundle", RBVersion: "v1", Name: "testprofile2"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655441111\"," +
- "\"namespace\":\"default\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
+ "{\"profile-name\":\"testprofile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
"\"kubernetesversion\":\"1.12.3\"}"),
},
},
@@ -495,7 +465,9 @@ func TestDownloadProfile(t *testing.T) {
{
label: "Download Error",
expectedError: "DB Error",
- inp: "123e4567-e89b-12d3-a456-426655440000",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "testprofile1",
mockdb: &db.MockDB{
Err: pkgerrors.New("DB Error"),
},
@@ -506,7 +478,7 @@ func TestDownloadProfile(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewProfileClient()
- data, err := impl.Download(testCase.inp)
+ data, err := impl.Download(testCase.rbname, testCase.rbversion, testCase.prname)
if err != nil {
if testCase.expectedError == "" {
t.Errorf("Download returned an unexpected error %s", err)
@@ -526,24 +498,28 @@ func TestDownloadProfile(t *testing.T) {
func TestResolveProfile(t *testing.T) {
testCases := []struct {
- label string
- inp string
- expected map[string][]string
- expectedError string
- mockdb *db.MockDB
+ label string
+ rbname, rbversion, prname string
+ expected map[string][]string
+ expectedError string
+ mockdb *db.MockDB
}{
{
- label: "Resolve Resource Bundle Profile",
- inp: "123e4567-e89b-12d3-a456-426655440000",
- expected: map[string][]string{},
+ label: "Resolve Resource Bundle Profile",
+ rbname: "testresourcebundle",
+ rbversion: "v1",
+ prname: "profile1",
+ expected: map[string][]string{},
mockdb: &db.MockDB{
Items: map[string]map[string][]byte{
- "123e4567-e89b-12d3-a456-426655440000": {
+ ProfileKey{RBName: "testresourcebundle", RBVersion: "v1",
+ Name: "profile1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
- "\"namespace\":\"default\"," +
- "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," +
- "\"rbdid\":\"abcde123-e89b-8888-a456-986655447236\"," +
+ "{\"profile-name\":\"profile1\"," +
+ "\"release-name\":\"testprofilereleasename\"," +
+ "\"namespace\":\"testnamespace\"," +
+ "\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
"\"kubernetesversion\":\"1.12.3\"}"),
// base64 encoding of vagrant/tests/vnfs/testrb/helm/profile
"content": []byte("H4sICLmjT1wAA3Byb2ZpbGUudGFyAO1Y32/bNhD2s/6Kg/KyYZZsy" +
@@ -570,13 +546,12 @@ func TestResolveProfile(t *testing.T) {
"YkDi6mRXNk/V1pUxy0uYsI1S+meU+XsPo2kJLnMOKZGy4J6Xt3XgZuHTayEKv3XZLjy+" +
"yJ66WPQwcHBwcHBwcHBwcHBwcHBwcHhm8Q/mTHqWgAoAAA="),
},
- "abcde123-e89b-8888-a456-986655447236": {
+ DefinitionKey{Name: "testresourcebundle", Version: "v1"}.String(): {
"metadata": []byte(
- "{\"name\":\"testresourcebundle\"," +
+ "{\"rb-name\":\"testresourcebundle\"," +
+ "\"rb-version\":\"v1\"," +
"\"chart-name\":\"vault-consul-dev\"," +
- "\"description\":\"testresourcebundle\"," +
- "\"uuid\":\"abcde123-e89b-8888-a456-986655447236\"," +
- "\"service-type\":\"firewall\"}"),
+ "\"description\":\"testresourcebundle\"}"),
// base64 encoding of vagrant/tests/vnfs/testrb/helm/vault-consul-dev
"content": []byte("H4sICEetS1wAA3ZhdWx0LWNvbnN1bC1kZXYudGFyAO0c7XLbNjK/+R" +
"QYujdJehatb+V4czPnOmnPk9bO2Gk7nbaTgUhIxpgiGAK0o3P9QPca92S3C5AU9GXZiax" +
@@ -651,7 +626,8 @@ func TestResolveProfile(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewProfileClient()
- data, err := impl.Resolve(testCase.inp, []string{})
+ data, err := impl.Resolve(testCase.rbname, testCase.rbversion, testCase.prname,
+ []string{})
if err != nil {
if testCase.expectedError == "" {
t.Errorf("Resolve returned an unexpected error %s", err)
diff --git a/src/k8splugin/mock_files/mock_json/create_rbdefinition.json b/src/k8splugin/mock_files/mock_json/create_rbdefinition.json
index 370c3c79..0373113c 100644
--- a/src/k8splugin/mock_files/mock_json/create_rbdefinition.json
+++ b/src/k8splugin/mock_files/mock_json/create_rbdefinition.json
@@ -1,7 +1,9 @@
{
- "uuid": "7eb09e38-4363-9942-1234-3beb2e95fd85",
- "name": "test-rbdef",
+ "rb-name": "test-rbdef",
+ "rb-version": "v1",
"chart-name": "testchart",
"description": "testing resource bundle definition api",
- "service-type": "firewall"
+ "labels": {
+ "vnf_customization_module_uuid": "7eb09e38-4363-9942-1234-3beb2e95fd85"
+ }
} \ No newline at end of file
diff --git a/src/k8splugin/mock_files/mock_json/create_rbprofile.json b/src/k8splugin/mock_files/mock_json/create_rbprofile.json
index 5d439cf0..72111a4d 100644
--- a/src/k8splugin/mock_files/mock_json/create_rbprofile.json
+++ b/src/k8splugin/mock_files/mock_json/create_rbprofile.json
@@ -1,7 +1,11 @@
{
- "name": "test-rbprofile",
- "description": "testing resource bundle profile api",
- "rbdid": "7eb09e38-4363-9942-1234-3beb2e95fd85",
- "uuid": "12345678-8888-4578-3344-987654398731",
- "service-type": "firewall"
+ "rb-name": "test-rbdef",
+ "rb-version": "v1",
+ "profile-name": "profile1",
+ "release-name": "testrelease",
+ "namespace": "testnamespace",
+ "kubernetes-version": "1.12.3",
+ "labels": {
+ "vnf_customization_module_uuid": "7eb09e38-4363-9942-1234-3beb2e95fd85"
+ }
}