Provide capability to specify release-name during instantiation 67/112167/3
authorKonrad Bańka <k.banka@samsung.com>
Fri, 4 Sep 2020 12:44:45 +0000 (14:44 +0200)
committerKonrad Banka <k.banka@samsung.com>
Tue, 8 Sep 2020 11:29:55 +0000 (11:29 +0000)
Allow release-name property to be provided during instantiation that, if
provided, overrides release-name specified in profile.
Additionally updated Makefile to allow easy compilation with different
go version easily.

Issue-ID: MULTICLOUD-1175
Signed-off-by: Konrad Bańka <k.banka@samsung.com>
Change-Id: Id8db484369045cfb0bc99543a80317644fc838f9

kud/tests/plugin_fw.sh
src/k8splugin/Makefile
src/k8splugin/api/brokerhandler.go
src/k8splugin/internal/app/instance.go
src/k8splugin/internal/rb/profile.go
src/k8splugin/internal/rb/profile_test.go

index 9c98177..28df372 100755 (executable)
@@ -63,7 +63,7 @@ payload="$(cat <<EOF
     "rb-name": "${rb_name}",
     "rb-version": "${rb_version}",
     "profile-name": "${profile_name}",
-    "release-name": "${release_name}",
+    "release-name": "dummy",
     "namespace": "${namespace}"
 }
 EOF
@@ -92,6 +92,7 @@ payload="$(cat <<EOF
     "rb-name": "${rb_name}",
     "rb-version": "${rb_version}",
     "profile-name": "${profile_name}",
+    "release-name": "${release_name}",
     "cloud-region": "${cloud_region_id}",
     "labels": {"testCaseName": "plugin_fw.sh"},
     "override-values": {"global.onapPrivateNetworkName": "onap-private-net-test"}
@@ -120,6 +121,8 @@ response="$(call_api "${base_url}/instance/${vnf_id}")"
 echo "$response"
 print_msg "Assert additional label has been assigned to rb instance"
 test "$(jq -r .request.labels.testCaseName <<< "${response}")" == plugin_fw.sh
+print_msg "Assert ReleaseName has been correctly overriden"
+test "$(jq -r .request.release-name <<< "${response}")" == "${release_name}"
 
 #Teardown
 print_msg "Deleting VNF Instance"
index 77196af..a1cda8d 100644 (file)
@@ -8,13 +8,14 @@
 ##############################################################################
 
 export GO111MODULE=on
+GO ?= go
 
 .PHONY: plugins
 
 
 all: clean plugins
        CGO_ENABLED=1 GOOS=linux GOARCH=amd64
-       @go build -tags netgo -o ./k8plugin ./cmd/main.go
+       @$(GO) build -tags netgo -o ./k8plugin ./cmd/main.go
 
 # The following is done this way as each patch on CI runs build and each merge runs deploy. So for build we don't need to build binary and hence
 # no need to create a static binary with additional flags. However, for generating binary, additional build flags are necessary. This if used with
@@ -25,14 +26,14 @@ deploy: build
 
 .PHONY: test
 test: clean
-       @go build -race -buildmode=plugin -o ./mock_files/mock_plugins/mockplugin.so ./mock_files/mock_plugins/mockplugin.go
-       @go test -race ./...
+       @$(GO) build -race -buildmode=plugin -o ./mock_files/mock_plugins/mockplugin.so ./mock_files/mock_plugins/mockplugin.go
+       @$(GO) test -race ./...
 
 format:
-       @go fmt ./...
+       @$(GO) fmt ./...
 
 plugins:
-       @find plugins -maxdepth 1 -type d -not -path plugins -exec sh -c "ls {}/plugin.go | xargs go build -buildmode=plugin -tags netgo -o $(basename {}).so" \;
+       @find plugins -maxdepth 1 -type d -not -path plugins -exec sh -c "ls {}/plugin.go | xargs $(GO) build -buildmode=plugin -tags netgo -o $(basename {}).so" \;
 
 clean:
        @find . -name "*so" -delete
@@ -40,5 +41,5 @@ clean:
 
 .PHONY: cover
 cover:
-       @go test -race ./... -coverprofile=coverage.out
-       @go tool cover -html=coverage.out -o coverage.html
+       @$(GO) test -race ./... -coverprofile=coverage.out
+       @$(GO) tool cover -html=coverage.out -o coverage.html
index c98e1c4..05f94b7 100644 (file)
@@ -153,12 +153,20 @@ func (b brokerInstanceHandler) createHandler(w http.ResponseWriter, r *http.Requ
                return
        }
 
+       releaseName, ok := directives["k8s-rb-instance-release-name"]
+       if !ok {
+               //Release name is not mandatory argument, but we're not using profile's default
+               //as it could conflict if someone wanted to instantiate single profile multiple times
+               releaseName = req.VFModuleID
+       }
+
        // Setup the resource parameters for making the request
        var instReq app.InstanceRequest
        instReq.RBName = req.VFModuleModelInvariantID
        instReq.RBVersion = req.VFModuleModelVersionID
        instReq.ProfileName = profileName
        instReq.CloudRegion = cloudRegion
+       instReq.ReleaseName = releaseName
        instReq.Labels = map[string]string{
                "stack-name": req.TemplateData.StackName,
        }
index ad67764..220c82d 100644 (file)
@@ -35,6 +35,7 @@ type InstanceRequest struct {
        RBName         string            `json:"rb-name"`
        RBVersion      string            `json:"rb-version"`
        ProfileName    string            `json:"profile-name"`
+       ReleaseName    string            `json:"release-name"`
        CloudRegion    string            `json:"cloud-region"`
        Labels         map[string]string `json:"labels"`
        OverrideValues map[string]string `json:"override-values"`
@@ -42,19 +43,21 @@ type InstanceRequest struct {
 
 // InstanceResponse contains the response from instantiation
 type InstanceResponse struct {
-       ID             string                    `json:"id"`
-       Request        InstanceRequest           `json:"request"`
-       Namespace      string                    `json:"namespace"`
-       Resources      []helm.KubernetesResource `json:"resources"`
+       ID          string                    `json:"id"`
+       Request     InstanceRequest           `json:"request"`
+       Namespace   string                    `json:"namespace"`
+       ReleaseName string                    `json:"release-name"`
+       Resources   []helm.KubernetesResource `json:"resources"`
 }
 
 // InstanceMiniResponse contains the response from instantiation
 // It does NOT include the created resources.
 // Use the regular GET to get the created resources for a particular instance
 type InstanceMiniResponse struct {
-       ID        string          `json:"id"`
-       Request   InstanceRequest `json:"request"`
-       Namespace string          `json:"namespace"`
+       ID          string          `json:"id"`
+       Request     InstanceRequest `json:"request"`
+       ReleaseName string          `json:"release-name"`
+       Namespace   string          `json:"namespace"`
 }
 
 // PodStatus defines the observed state of ResourceBundleState
@@ -144,7 +147,7 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) {
        }
 
        //Execute the kubernetes create command
-       sortedTemplates, err := rb.NewProfileClient().Resolve(i.RBName, i.RBVersion, i.ProfileName, overrideValues)
+       sortedTemplates, releaseName, err := rb.NewProfileClient().Resolve(i.RBName, i.RBVersion, i.ProfileName, overrideValues, i.ReleaseName)
        if err != nil {
                return InstanceResponse{}, pkgerrors.Wrap(err, "Error resolving helm charts")
        }
@@ -165,10 +168,11 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) {
 
        //Compose the return response
        resp := InstanceResponse{
-               ID:        id,
-               Request:   i,
-               Namespace: profile.Namespace,
-               Resources: createdResources,
+               ID:          id,
+               Request:     i,
+               Namespace:   profile.Namespace,
+               ReleaseName: releaseName,
+               Resources:   createdResources,
        }
 
        key := InstanceKey{
@@ -252,9 +256,10 @@ func (v *InstanceClient) List(rbname, rbversion, profilename string) ([]Instance
                        }
 
                        miniresp := InstanceMiniResponse{
-                               ID:        resp.ID,
-                               Request:   resp.Request,
-                               Namespace: resp.Namespace,
+                               ID:          resp.ID,
+                               Request:     resp.Request,
+                               Namespace:   resp.Namespace,
+                               ReleaseName: resp.ReleaseName,
                        }
 
                        //Filter based on the accepted keys
index 6efa23b..f8b07ab 100644 (file)
@@ -268,50 +268,51 @@ func (v *ProfileClient) Download(rbName, rbVersion, prName string) ([]byte, erro
 }
 
 //Resolve returns the path where the helm chart merged with
-//configuration overrides resides.
+//configuration overrides resides and final ReleaseName picked for instantiation
 func (v *ProfileClient) Resolve(rbName string, rbVersion string,
-       profileName string, values []string) ([]helm.KubernetesResourceTemplate, error) {
+       profileName string, values []string, overrideReleaseName string) ([]helm.KubernetesResourceTemplate, string, error) {
 
        var sortedTemplates []helm.KubernetesResourceTemplate
+       var finalReleaseName string
 
        //Download and process the profile first
        //If everything seems okay, then download the definition
        prData, err := v.Download(rbName, rbVersion, profileName)
        if err != nil {
-               return sortedTemplates, pkgerrors.Wrap(err, "Downloading Profile")
+               return sortedTemplates, finalReleaseName, pkgerrors.Wrap(err, "Downloading Profile")
        }
 
        prPath, err := ExtractTarBall(bytes.NewBuffer(prData))
        if err != nil {
-               return sortedTemplates, pkgerrors.Wrap(err, "Extracting Profile Content")
+               return sortedTemplates, finalReleaseName, pkgerrors.Wrap(err, "Extracting Profile Content")
        }
 
        prYamlClient, err := ProcessProfileYaml(prPath, v.manifestName)
        if err != nil {
-               return sortedTemplates, pkgerrors.Wrap(err, "Processing Profile Manifest")
+               return sortedTemplates, finalReleaseName, pkgerrors.Wrap(err, "Processing Profile Manifest")
        }
 
        definitionClient := NewDefinitionClient()
 
        definition, err := definitionClient.Get(rbName, rbVersion)
        if err != nil {
-               return sortedTemplates, pkgerrors.Wrap(err, "Getting Definition Metadata")
+               return sortedTemplates, finalReleaseName, pkgerrors.Wrap(err, "Getting Definition Metadata")
        }
 
        defData, err := definitionClient.Download(rbName, rbVersion)
        if err != nil {
-               return sortedTemplates, pkgerrors.Wrap(err, "Downloading Definition")
+               return sortedTemplates, finalReleaseName, pkgerrors.Wrap(err, "Downloading Definition")
        }
 
        chartBasePath, err := ExtractTarBall(bytes.NewBuffer(defData))
        if err != nil {
-               return sortedTemplates, pkgerrors.Wrap(err, "Extracting Definition Charts")
+               return sortedTemplates, finalReleaseName, 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 sortedTemplates, pkgerrors.Wrap(err, "Getting Profile")
+               return sortedTemplates, finalReleaseName, pkgerrors.Wrap(err, "Getting Profile")
        }
 
        //Copy the profile configresources to the chart locations
@@ -321,22 +322,28 @@ func (v *ProfileClient) Resolve(rbName string, rbVersion string,
        //   chartpath: chart/config/resources/config.yaml
        err = prYamlClient.CopyConfigurationOverrides(chartBasePath)
        if err != nil {
-               return sortedTemplates, pkgerrors.Wrap(err, "Copying configresources to chart")
+               return sortedTemplates, finalReleaseName, pkgerrors.Wrap(err, "Copying configresources to chart")
+       }
+
+       if overrideReleaseName == "" {
+               finalReleaseName = profile.ReleaseName
+       } else {
+               finalReleaseName = overrideReleaseName
        }
 
        helmClient := helm.NewTemplateClient(profile.KubernetesVersion,
                profile.Namespace,
-               profile.ReleaseName)
+               finalReleaseName)
 
        chartPath := filepath.Join(chartBasePath, definition.ChartName)
        sortedTemplates, err = helmClient.GenerateKubernetesArtifacts(chartPath,
                []string{prYamlClient.GetValues()},
                values)
        if err != nil {
-               return sortedTemplates, pkgerrors.Wrap(err, "Generate final k8s yaml")
+               return sortedTemplates, finalReleaseName, pkgerrors.Wrap(err, "Generate final k8s yaml")
        }
 
-       return sortedTemplates, nil
+       return sortedTemplates, finalReleaseName, nil
 }
 
 // Returns an empty profile with the following contents
index 26b0161..a434e5a 100644 (file)
@@ -18,12 +18,14 @@ package rb
 
 import (
        "bytes"
+       "os"
        "reflect"
        "sort"
        "strings"
        "testing"
 
        "github.com/onap/multicloud-k8s/src/k8splugin/internal/db"
+       "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm"
 
        pkgerrors "github.com/pkg/errors"
 )
@@ -597,19 +599,142 @@ func TestDownloadProfile(t *testing.T) {
 }
 
 func TestResolveProfile(t *testing.T) {
+       profileContent := []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=")
+       defContent := []byte("H4sICEetS1wAA3ZhdWx0LWNvbnN1bC1kZXYudGFyAO0c7XLbNjK/+R" +
+               "QYujdJehatb+V4czPnOmnPk9bO2Gk7nbaTgUhIxpgiGAK0o3P9QPca92S3C5AU9GXZiax" +
+               "c7rA/LJEAFovdxX4AK1/RIlGNSKSySBoxuzp4sn1oAgx6Pf0JsPipv7c63XZ70O61W4Mn" +
+               "zVZ7MGg9Ib1HoGUJCqloTsiTXAh1V79N7V8oXC3K/+iC5iqY0kmytTlQwP1ud538W51Wf" +
+               "0H+3QF8kObWKLgD/s/lv0eORDbN+fhCkXaz9YIcp4ol8DLPRE4VF+k+vIq8PW+PfM8jlk" +
+               "oWkyKNWU7UBSOHGY3go2zZJz+xXMIY0g6a5Bl28Msm//lfAcNUFGRCpyQVihSSAQouyYg" +
+               "njLAPEcsU4SmJxCRLOE0jRq65utDTlEgCQPFLiUIMFYXeFPpn8DSy+xGqNMEGLpTKwoOD" +
+               "6+vrgGpyA5GPDxLTVR58f3z06uT8VQNI1oN+TBMmJcnZ+4LnsNjhlNAMKIroEOhM6DURO" +
+               "aHjnEGbEkjxdc4VT8f7RIqRuqY5Aywxlyrnw0LNsauiD1ZtdwCG0ZT4h+fk+Nwn3xyeH5" +
+               "/vA46fj9/+4/THt+Tnw7Ozw5O3x6/OyekZOTo9eXn89vj0BJ6+JYcnv5DXxycv9wkDZsE" +
+               "07EOWI/1AJEdGshi5ds7YHAEjYQiSGYv4iEewrnRc0DEjY3HF8hSWQzKWT7hEcUogLwYs" +
+               "CZ9wpZVCLi8q8Dya8VIBQnLV8mImo5xnSj9ru4IMS2iRRhfkJzQ8iJcY44OMBPtDJiJmX" +
+               "konDFAs2CbAn9X4m8Ffgp53VT2C9EB+n3s3fXmwZP+vaFIwuVUHsMH+d1vd3oL977X6TW" +
+               "f/dwHO/jv7vzX7v/epAHN8l4ghTdApjPi4MCoIjmGEdkoGW5hirCcIPQJaGLM3Ildvcjb" +
+               "iH0LSabbhbYYqLBUDBQzJzS2sqpK/JoVPgEue/os4jOUMq88WuKE+vNZmtfRgYTNooXPK" +
+               "iiR5IwDRNCSHyTWdSsQ9SugY9YilWr9iNizGY2R/Y25aWWSwIVWtlp7u+EoPikMyoolk2" +
+               "xHAoTXr40nBYLY46OFWlSwH7QuJygumXyRi/C5hVww4fHzy7enqTjFV9F3M4dXTA4PtAF" +
+               "891Y3INWmwl6aAvOg1m9YLGZJGy6uFZuZQYP2MhBFsGhFoHOMmC4G+iCYXQqrQQgqTUnV" +
+               "RSt8sQysUEF32UFG2AtnTX8Pw9/BFu9l8WjeqRMLSJIrZXrF5824C81+W79HoGAGRtJgM" +
+               "YXOCUeQpuDfQZOnlTIv1SBQpKCasF7X/nCUsgqUaRaejEU+5mlZqn+ViyBZ0IKM5xGYK9" +
+               "oiX8CtYk9TMxXGcJi9ZQqfnDIbEsJ5W02wnLuL5d3skZUCTpPkUVb9cDakQlhNfXzDQe6" +
+               "bQtpJhzuhlJniqpEago0XcKrBOKcjrF2BRBZPpU9wi6NLBwaTwLQPJAVpcBfoLlsNoVu0" +
+               "awzfAHPOPWYhnm4olvKBPIikm7IxFCeWTauefMaQDWmmELPgBpIAvafwzeBF2CqigTfJ/" +
+               "wtv2dxy+T1Bib7RCHcQgbpajcjfSkawaz4uhaZcTaW8Az8Otwg1xapoBypPS5KH1W4qxP" +
+               "bNbTlY1AOPBLdAEB8MOamtlrwxoSLpdzwMx5SUX2bxd+txBjoO1sBT/KwZRA1UQGG1tjo" +
+               "ef/3UH/YE7/9sF3CH/GDyGmE5Y+qnHgZvyv2Z7MC9/sC6dvsv/dgF7Lv9z+d9jnP8Bz+T" +
+               "BVcu75CnEAS9rW+JB9EgxOgnrGOTmBrgYJUUM6gLSn4g0GEGuhI0+CcjtbdlTgvRWd69b" +
+               "6/4JHbKkjPuBlLWj6gEQ5OMJpe4YmEsQDISgsTF7U6n3HwTDaZiP+H/2if/Or3DkEFBTa" +
+               "YgMzsxDhUd3ABEBC8cLPc5NnIadUCJIdhmvS9PxJ3MqZwfxBqOsIniNfUJVdPG9tfR7Lr" +
+               "4y+iUWS0I6e5lDeG9+3osf1XLLLMvE6PVcDZNuh8S3mKBfBdpxARa/nmutMq2gS+N4YyX" +
+               "kFn5zQBDM0nUQd5VZVX2sRgsrzkdR3X/1NXn+vm+SVfiCztX/fZYh2mkpLrRevAmoLXrK" +
+               "ID6wQ3B7VpNm/IA6MYfRThyYig50rqr4hNV9Kp6tasGs6DRNplWWtFEg5TH+AyXSGFJIa" +
+               "cC67Ewyhk6QCMyTqntIxqwCvYjFngVxzWX/OxGIPdUKcldhwHMKPb31rjqrWCDoc4clDn" +
+               "YEd8T/ld355KugDfF/u99avP8ZdNz9/27Axf8u/n+s+38T+pex7f3i/tLmPHrov5Rf/Le" +
+               "F/+a4dkUUiA0GWx2oNGb8XOxdnedW89/c8BFh71dj9avTYZ80yv7ZQ4LR2XHwcsw2f9dm" +
+               "xW1+p9lG/q2YoxozI75BQLJsM3XswzJ1YObHTD0outYTpnE1Wy6UiEQSkrdHb5ZSr3smR" +
+               "XdqyGew/0v+X2+DLR7+Pvmo8982dHfnvzuAdfI32rsdNXi4/Hu9rpP/TmCD/LdSDbwh/m" +
+               "+1+93F+L876Ln4fxdgx////hemAANyOIlFJPfJNyyBTICmELa5+N/F/59Y/6sNSn3SLDU" +
+               "JOljSCgNsFJp+Y3/KCmBjhVyV7+PBBvu/lWrgjec/gyX7P+i2nP3fBTj77+z/F1P/S4w5" +
+               "glmpIhGwbAisTPWZihYUluqCyspiaKzYdsuF9/A3LCmwCKQOcxdpgXtBV+Vm5lQjr5rh+" +
+               "YqlyjTiUkB9ysJFrdPG1dXFmSQvUs1ybASF0pLBM4HLF5Kgh1S6bnFVvbIphsQ7MzyTEp" +
+               "IrkXMmzQWyeZyGJGUfCtkJREozVP6whWG3GVtXP4LnZdGlR2ZvziwMQkyAGLv12FwE1s8" +
+               "NPT40LlqjToSpZNYXbR6pnm20pqAxYAmVikdBJGbdSvxDRsEdoY3Ab2Ev6FXozarxvg/4" +
+               "jBd+eCa2osYa+1YKpK/g9JUXQYMOuzDXZzhTWMeI5VjJGesBsOvr6k5VXbPpnysBedpky" +
+               "YVacXN1vr5YU6P92GpvQubrvfUV4Dbs/wb/v5VqwIfn/4Net+Py/13AveX/rj5oD1T2sG" +
+               "BwU/7f73cW6v/anb7L/3cCNzcHX3suCHRB4LaCwK8Pbm89T6sVIWdMiuTKzFrbDx0/ATP" +
+               "1bz+oSfgD8vaCzX6/UneVxQhCHfz9gayRVHKuB0JbGQwi2TmPY5YSPrJ+ZPKMjQO93Do0" +
+               "fA44C4krRFQjkSTiGp90hBl6+latuiJKZXlrRcJqBns5JvgzC8cbI1gFBESrLijNvVXZx" +
+               "1Qt2VdABt3SrI0SL4Pgo7HtW6L72/9ZPPlQB7DB/nc6ve6i/e93Xf3HTsDZf2f/d2f/a9" +
+               "NtDoMX8tZpAEPQD2gjrMmzCp/LPsg2nXiDSEoruo+23AisXH9tpScM7FnK5aQaFsyb9rI" +
+               "6wUJv2/jKSi/SqUnDkwbdIOcwznqdVmgsjGY+nUeuRY6KgHwvW4YUUsy13mU2buZewPXd" +
+               "QY1V25DlPFUj4v9J+neNqPBi7YU1erHy1lrCevbWuHRZhe3WVirNEnMki3KG/0fkkqXr1" +
+               "WVp3iPcxKUKhHOHI9hicndoy0P915R7UCmvRQ7JdvWtLLHnSUgYfpBnQl9u0OT5PeQTGN" +
+               "LtKOArbCXh35aKRmyplqUjun+Ey4D+d69z1l9TCf3rYpu/+wZJoFtmHWkBRhY6zjQiRKU" +
+               "wfZEl5deKFeQPMux3WRrNcFRDb36D0b/5IXziQNz28GRe7v/mVxjsd5qb9gskp36+vfVL" +
+               "Tq0nx6zULKMm7VEDp/8RuH/8V5eKPTD733z/01zO/6G/i/92AS7+c/HfbuO/MuN/KkllU" +
+               "bzSj1de6pqDyg3ZLMk3Y59ZDh5f1PEJxDuSqecYDhyCqcdhqFditFxRqmkox0kM4Rbiwb" +
+               "mOq0LBsgN5xllgiHuuqasCAL3sVx8yWhJS9dcIddhYnlusjRjmSqCtWEFjsHy5XaW8ki3" +
+               "Lpw0Gx8q1/oFXCuAz+x39lU/O9ckL8Rv+oh/93CbLwRbhYef/H+H8n2z2/612e8H/w5P7" +
+               "/287Aef/nf9/PP9vOcIF97/e/y06vnv7uwe4sJpAyJfBugFR1Sz4w6ApeV/QBDgCUrFv5" +
+               "bUFxFgFp6EoM6pwNlyQhIAloqjOUgCBr4shMJBhnaPx/JwlMXAwZ4Z/Rm205j8D3UIGvQ" +
+               "RZQl9kOgrk+XoOzX68tJ3wYJb0N/RJ0NzPUr5y4YEDBw4cOHDgwIEDBw4cOHDgwIEDBw4" +
+               "cOHDgwIEDB18K/AcxEDJDAHgAAA==")
        testCases := []struct {
                label                     string
                rbname, rbversion, prname string
+               releaseName               string
                expected                  map[string][]string
+               expectedReleaseName       string
                expectedError             string
                mockdb                    *db.MockDB
        }{
                {
-                       label:     "Resolve Resource Bundle Profile",
-                       rbname:    "testresourcebundle",
-                       rbversion: "v1",
-                       prname:    "profile1",
-                       expected:  map[string][]string{},
+                       label:               "Resolve Resource Bundle Profile with override release name",
+                       rbname:              "testresourcebundle",
+                       rbversion:           "v1",
+                       prname:              "profile1",
+                       expectedReleaseName: "testprofilereleasename",
+                       expected:            map[string][]string{},
+                       mockdb: &db.MockDB{
+                               Items: map[string]map[string][]byte{
+                                       ProfileKey{RBName: "testresourcebundle", RBVersion: "v1",
+                                               ProfileName: "profile1"}.String(): {
+                                               "profilemetadata": []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
+                                               "profilecontent": profileContent,
+                                       },
+                                       DefinitionKey{RBName: "testresourcebundle", RBVersion: "v1"}.String(): {
+                                               "defmetadata": []byte(
+                                                       "{\"rb-name\":\"testresourcebundle\"," +
+                                                               "\"rb-version\":\"v1\"," +
+                                                               "\"chart-name\":\"vault-consul-dev\"," +
+                                                               "\"description\":\"testresourcebundle\"}"),
+                                               // base64 encoding of vagrant/tests/vnfs/testrb/helm/vault-consul-dev
+                                               "defcontent": defContent,
+                                       },
+                               },
+                       },
+               },
+               {
+                       label:               "Resolve Resource Bundle Profile",
+                       rbname:              "testresourcebundle",
+                       rbversion:           "v1",
+                       prname:              "profile1",
+                       releaseName:         "overwritereleasename",
+                       expectedReleaseName: "overwritereleasename",
+                       expected:            map[string][]string{},
                        mockdb: &db.MockDB{
                                Items: map[string]map[string][]byte{
                                        ProfileKey{RBName: "testresourcebundle", RBVersion: "v1",
@@ -622,29 +747,7 @@ func TestResolveProfile(t *testing.T) {
                                                                "\"rb-version\":\"v1\"," +
                                                                "\"kubernetesversion\":\"1.12.3\"}"),
                                                // base64 encoding of vagrant/tests/vnfs/testrb/helm/profile
-                                               "profilecontent": []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="),
+                                               "profilecontent": profileContent,
                                        },
                                        DefinitionKey{RBName: "testresourcebundle", RBVersion: "v1"}.String(): {
                                                "defmetadata": []byte(
@@ -653,81 +756,26 @@ func TestResolveProfile(t *testing.T) {
                                                                "\"chart-name\":\"vault-consul-dev\"," +
                                                                "\"description\":\"testresourcebundle\"}"),
                                                // base64 encoding of vagrant/tests/vnfs/testrb/helm/vault-consul-dev
-                                               "defcontent": []byte("H4sICEetS1wAA3ZhdWx0LWNvbnN1bC1kZXYudGFyAO0c7XLbNjK/+R" +
-                                                       "QYujdJehatb+V4czPnOmnPk9bO2Gk7nbaTgUhIxpgiGAK0o3P9QPca92S3C5AU9GXZiax" +
-                                                       "c7rA/LJEAFovdxX4AK1/RIlGNSKSySBoxuzp4sn1oAgx6Pf0JsPipv7c63XZ70O61W4Mn" +
-                                                       "zVZ7MGg9Ib1HoGUJCqloTsiTXAh1V79N7V8oXC3K/+iC5iqY0kmytTlQwP1ud538W51Wf" +
-                                                       "0H+3QF8kObWKLgD/s/lv0eORDbN+fhCkXaz9YIcp4ol8DLPRE4VF+k+vIq8PW+PfM8jlk" +
-                                                       "oWkyKNWU7UBSOHGY3go2zZJz+xXMIY0g6a5Bl28Msm//lfAcNUFGRCpyQVihSSAQouyYg" +
-                                                       "njLAPEcsU4SmJxCRLOE0jRq65utDTlEgCQPFLiUIMFYXeFPpn8DSy+xGqNMEGLpTKwoOD" +
-                                                       "6+vrgGpyA5GPDxLTVR58f3z06uT8VQNI1oN+TBMmJcnZ+4LnsNjhlNAMKIroEOhM6DURO" +
-                                                       "aHjnEGbEkjxdc4VT8f7RIqRuqY5Aywxlyrnw0LNsauiD1ZtdwCG0ZT4h+fk+Nwn3xyeH5" +
-                                                       "/vA46fj9/+4/THt+Tnw7Ozw5O3x6/OyekZOTo9eXn89vj0BJ6+JYcnv5DXxycv9wkDZsE" +
-                                                       "07EOWI/1AJEdGshi5ds7YHAEjYQiSGYv4iEewrnRc0DEjY3HF8hSWQzKWT7hEcUogLwYs" +
-                                                       "CZ9wpZVCLi8q8Dya8VIBQnLV8mImo5xnSj9ru4IMS2iRRhfkJzQ8iJcY44OMBPtDJiJmX" +
-                                                       "konDFAs2CbAn9X4m8Ffgp53VT2C9EB+n3s3fXmwZP+vaFIwuVUHsMH+d1vd3oL977X6TW" +
-                                                       "f/dwHO/jv7vzX7v/epAHN8l4ghTdApjPi4MCoIjmGEdkoGW5hirCcIPQJaGLM3Ildvcjb" +
-                                                       "iH0LSabbhbYYqLBUDBQzJzS2sqpK/JoVPgEue/os4jOUMq88WuKE+vNZmtfRgYTNooXPK" +
-                                                       "iiR5IwDRNCSHyTWdSsQ9SugY9YilWr9iNizGY2R/Y25aWWSwIVWtlp7u+EoPikMyoolk2" +
-                                                       "xHAoTXr40nBYLY46OFWlSwH7QuJygumXyRi/C5hVww4fHzy7enqTjFV9F3M4dXTA4PtAF" +
-                                                       "891Y3INWmwl6aAvOg1m9YLGZJGy6uFZuZQYP2MhBFsGhFoHOMmC4G+iCYXQqrQQgqTUnV" +
-                                                       "RSt8sQysUEF32UFG2AtnTX8Pw9/BFu9l8WjeqRMLSJIrZXrF5824C81+W79HoGAGRtJgM" +
-                                                       "YXOCUeQpuDfQZOnlTIv1SBQpKCasF7X/nCUsgqUaRaejEU+5mlZqn+ViyBZ0IKM5xGYK9" +
-                                                       "oiX8CtYk9TMxXGcJi9ZQqfnDIbEsJ5W02wnLuL5d3skZUCTpPkUVb9cDakQlhNfXzDQe6" +
-                                                       "bQtpJhzuhlJniqpEago0XcKrBOKcjrF2BRBZPpU9wi6NLBwaTwLQPJAVpcBfoLlsNoVu0" +
-                                                       "awzfAHPOPWYhnm4olvKBPIikm7IxFCeWTauefMaQDWmmELPgBpIAvafwzeBF2CqigTfJ/" +
-                                                       "wtv2dxy+T1Bib7RCHcQgbpajcjfSkawaz4uhaZcTaW8Az8Otwg1xapoBypPS5KH1W4qxP" +
-                                                       "bNbTlY1AOPBLdAEB8MOamtlrwxoSLpdzwMx5SUX2bxd+txBjoO1sBT/KwZRA1UQGG1tjo" +
-                                                       "ef/3UH/YE7/9sF3CH/GDyGmE5Y+qnHgZvyv2Z7MC9/sC6dvsv/dgF7Lv9z+d9jnP8Bz+T" +
-                                                       "BVcu75CnEAS9rW+JB9EgxOgnrGOTmBrgYJUUM6gLSn4g0GEGuhI0+CcjtbdlTgvRWd69b" +
-                                                       "6/4JHbKkjPuBlLWj6gEQ5OMJpe4YmEsQDISgsTF7U6n3HwTDaZiP+H/2if/Or3DkEFBTa" +
-                                                       "YgMzsxDhUd3ABEBC8cLPc5NnIadUCJIdhmvS9PxJ3MqZwfxBqOsIniNfUJVdPG9tfR7Lr" +
-                                                       "4y+iUWS0I6e5lDeG9+3osf1XLLLMvE6PVcDZNuh8S3mKBfBdpxARa/nmutMq2gS+N4YyX" +
-                                                       "kFn5zQBDM0nUQd5VZVX2sRgsrzkdR3X/1NXn+vm+SVfiCztX/fZYh2mkpLrRevAmoLXrK" +
-                                                       "ID6wQ3B7VpNm/IA6MYfRThyYig50rqr4hNV9Kp6tasGs6DRNplWWtFEg5TH+AyXSGFJIa" +
-                                                       "cC67Ewyhk6QCMyTqntIxqwCvYjFngVxzWX/OxGIPdUKcldhwHMKPb31rjqrWCDoc4clDn" +
-                                                       "YEd8T/ld355KugDfF/u99avP8ZdNz9/27Axf8u/n+s+38T+pex7f3i/tLmPHrov5Rf/Le" +
-                                                       "F/+a4dkUUiA0GWx2oNGb8XOxdnedW89/c8BFh71dj9avTYZ80yv7ZQ4LR2XHwcsw2f9dm" +
-                                                       "xW1+p9lG/q2YoxozI75BQLJsM3XswzJ1YObHTD0outYTpnE1Wy6UiEQSkrdHb5ZSr3smR" +
-                                                       "XdqyGew/0v+X2+DLR7+Pvmo8982dHfnvzuAdfI32rsdNXi4/Hu9rpP/TmCD/LdSDbwh/m" +
-                                                       "+1+93F+L876Ln4fxdgx////hemAANyOIlFJPfJNyyBTICmELa5+N/F/59Y/6sNSn3SLDU" +
-                                                       "JOljSCgNsFJp+Y3/KCmBjhVyV7+PBBvu/lWrgjec/gyX7P+i2nP3fBTj77+z/F1P/S4w5" +
-                                                       "glmpIhGwbAisTPWZihYUluqCyspiaKzYdsuF9/A3LCmwCKQOcxdpgXtBV+Vm5lQjr5rh+" +
-                                                       "YqlyjTiUkB9ysJFrdPG1dXFmSQvUs1ybASF0pLBM4HLF5Kgh1S6bnFVvbIphsQ7MzyTEp" +
-                                                       "IrkXMmzQWyeZyGJGUfCtkJREozVP6whWG3GVtXP4LnZdGlR2ZvziwMQkyAGLv12FwE1s8" +
-                                                       "NPT40LlqjToSpZNYXbR6pnm20pqAxYAmVikdBJGbdSvxDRsEdoY3Ab2Ev6FXozarxvg/4" +
-                                                       "jBd+eCa2osYa+1YKpK/g9JUXQYMOuzDXZzhTWMeI5VjJGesBsOvr6k5VXbPpnysBedpky" +
-                                                       "YVacXN1vr5YU6P92GpvQubrvfUV4Dbs/wb/v5VqwIfn/4Net+Py/13AveX/rj5oD1T2sG" +
-                                                       "BwU/7f73cW6v/anb7L/3cCNzcHX3suCHRB4LaCwK8Pbm89T6sVIWdMiuTKzFrbDx0/ATP" +
-                                                       "1bz+oSfgD8vaCzX6/UneVxQhCHfz9gayRVHKuB0JbGQwi2TmPY5YSPrJ+ZPKMjQO93Do0" +
-                                                       "fA44C4krRFQjkSTiGp90hBl6+latuiJKZXlrRcJqBns5JvgzC8cbI1gFBESrLijNvVXZx" +
-                                                       "1Qt2VdABt3SrI0SL4Pgo7HtW6L72/9ZPPlQB7DB/nc6ve6i/e93Xf3HTsDZf2f/d2f/a9" +
-                                                       "NtDoMX8tZpAEPQD2gjrMmzCp/LPsg2nXiDSEoruo+23AisXH9tpScM7FnK5aQaFsyb9rI" +
-                                                       "6wUJv2/jKSi/SqUnDkwbdIOcwznqdVmgsjGY+nUeuRY6KgHwvW4YUUsy13mU2buZewPXd" +
-                                                       "QY1V25DlPFUj4v9J+neNqPBi7YU1erHy1lrCevbWuHRZhe3WVirNEnMki3KG/0fkkqXr1" +
-                                                       "WVp3iPcxKUKhHOHI9hicndoy0P915R7UCmvRQ7JdvWtLLHnSUgYfpBnQl9u0OT5PeQTGN" +
-                                                       "LtKOArbCXh35aKRmyplqUjun+Ey4D+d69z1l9TCf3rYpu/+wZJoFtmHWkBRhY6zjQiRKU" +
-                                                       "wfZEl5deKFeQPMux3WRrNcFRDb36D0b/5IXziQNz28GRe7v/mVxjsd5qb9gskp36+vfVL" +
-                                                       "Tq0nx6zULKMm7VEDp/8RuH/8V5eKPTD733z/01zO/6G/i/92AS7+c/HfbuO/MuN/KkllU" +
-                                                       "bzSj1de6pqDyg3ZLMk3Y59ZDh5f1PEJxDuSqecYDhyCqcdhqFditFxRqmkox0kM4Rbiwb" +
-                                                       "mOq0LBsgN5xllgiHuuqasCAL3sVx8yWhJS9dcIddhYnlusjRjmSqCtWEFjsHy5XaW8ki3" +
-                                                       "Lpw0Gx8q1/oFXCuAz+x39lU/O9ckL8Rv+oh/93CbLwRbhYef/H+H8n2z2/612e8H/w5P7" +
-                                                       "/287Aef/nf9/PP9vOcIF97/e/y06vnv7uwe4sJpAyJfBugFR1Sz4w6ApeV/QBDgCUrFv5" +
-                                                       "bUFxFgFp6EoM6pwNlyQhIAloqjOUgCBr4shMJBhnaPx/JwlMXAwZ4Z/Rm205j8D3UIGvQ" +
-                                                       "RZQl9kOgrk+XoOzX68tJ3wYJb0N/RJ0NzPUr5y4YEDBw4cOHDgwIEDBw4cOHDgwIEDBw4" +
-                                                       "cOHDgwIEDB18K/AcxEDJDAHgAAA=="),
+                                               "defcontent": defContent,
                                        },
                                },
                        },
                },
        }
 
+       cleanup := func(krts []helm.KubernetesResourceTemplate) {
+               for _, krt := range krts {
+                       os.RemoveAll(krt.FilePath)
+               }
+       }
+
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        db.DBconn = testCase.mockdb
                        impl := NewProfileClient()
-                       data, err := impl.Resolve(testCase.rbname, testCase.rbversion, testCase.prname,
-                               []string{})
+                       data, releaseName, err := impl.Resolve(testCase.rbname,
+                               testCase.rbversion, testCase.prname, []string{}, testCase.releaseName)
+                       defer cleanup(data)
                        if err != nil {
                                if testCase.expectedError == "" {
                                        t.Errorf("Resolve returned an unexpected error %s", err)
@@ -736,7 +784,10 @@ func TestResolveProfile(t *testing.T) {
                                        t.Errorf("Resolve returned an unexpected error %s", err)
                                }
                        }
-                       t.Log(data)
+                       if testCase.expectedReleaseName != releaseName {
+                               t.Errorf("Resolve returned unexpected release name '%s', expected '%s'",
+                                       releaseName, testCase.expectedReleaseName)
+                       }
                })
        }
 }