K8s Profile Upload 68/99968/3
authorLukasz Rajewski <lukasz.rajewski@orange.com>
Wed, 1 Jan 2020 22:09:26 +0000 (23:09 +0100)
committerLukasz Rajewski <lukasz.rajewski@orange.com>
Wed, 8 Jan 2020 10:12:22 +0000 (11:12 +0100)
Modification of vFW CNF CBA package to upload
K8s profile automatically just after resource
assigment phase. Profile is created for each vf-module
and in this version only upload of static profile is
possible. Profile files must be included in the CBA in
Templates/k8s-profiles folder. Profile file must be valid
tar.gz file accepted by multicloud-k8s plugin.

Change-Id: I30c268e9867fbb86d997b2091ce2eed204a7df2a
Issue-ID: INT-1406
Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com>
16 files changed:
heat/vFW_CNF_CDS/templates/cba/Definitions/data_types.json
heat/vFW_CNF_CDS/templates/cba/Definitions/node_types.json
heat/vFW_CNF_CDS/templates/cba/Definitions/resources_definition_types.json
heat/vFW_CNF_CDS/templates/cba/Definitions/vFW_CNF_CDS.json
heat/vFW_CNF_CDS/templates/cba/Scripts/kotlin/KotlinK8sProfileUpload.kt [new file with mode: 0644]
heat/vFW_CNF_CDS/templates/cba/Scripts/kotlin/README.md [new file with mode: 0644]
heat/vFW_CNF_CDS/templates/cba/Templates/base_template-mapping.json
heat/vFW_CNF_CDS/templates/cba/Templates/base_template-template.vtl
heat/vFW_CNF_CDS/templates/cba/Templates/vfw-mapping.json
heat/vFW_CNF_CDS/templates/cba/Templates/vfw-template.vtl
heat/vFW_CNF_CDS/templates/cba/Templates/vnf-mapping.json
heat/vFW_CNF_CDS/templates/cba/Templates/vnf-template.vtl
heat/vFW_CNF_CDS/templates/cba/Templates/vpkg-mapping.json
heat/vFW_CNF_CDS/templates/cba/Templates/vpkg-template.vtl
heat/vFW_CNF_CDS/templates/cba/Templates/vsn-mapping.json
heat/vFW_CNF_CDS/templates/cba/Templates/vsn-template.vtl

index 82d4a04..60b89b7 100644 (file)
           "description" : "Profile name used in multicloud/k8s plugin to identify Helm chart(s) where this mapping is providing override values.",
           "type" : "string"
         },
+        "k8s-rb-profile-namespace" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "default": "default",
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
         "vsn_name_0" : {
           "description" : "",
           "required" : false,
index 91ecafe..12eb1bc 100644 (file)
       "description" : "TOSCA base type for Resource Sources",
       "version" : "1.0.0",
       "derived_from" : "tosca.nodes.Root"
+    },
+    "component-script-executor":{
+      "description": "This is CLI Transaction Configuration Component API",
+      "version": "1.0.0",
+      "attributes": {
+        "response-data": {
+          "required": false,
+          "type": "json"
+        }
+      },
+      "capabilities": {
+        "component-node": {
+          "type": "tosca.capabilities.Node"
+        }
+      },
+      "interfaces": {
+        "ComponentScriptExecutor": {
+          "operations": {
+            "process": {
+              "inputs": {
+                "script-type": {
+                  "description": "Script type, kotlin type is supported",
+                  "required": true,
+                  "type": "string",
+                  "default": "internal",
+                  "constraints": [
+                    {
+                      "valid_values": [
+                        "kotlin",
+                        "jython",
+                        "internal"
+                      ]
+                    }
+                  ]
+                },
+                "script-class-reference": {
+                  "description": "Kotlin Script class name or jython script name.",
+                  "required": true,
+                  "type": "string"
+                },
+                "dynamic-properties": {
+                  "description": "Dynamic Json Content or DSL Json reference.",
+                  "required": false,
+                  "type": "json"
+                }
+              },
+              "outputs": {
+                "response-data": {
+                  "description": "Execution Response Data.",
+                  "required": false,
+                  "type": "string"
+                },
+                "status": {
+                  "description": "Status of the Component Execution ( success or failure )",
+                  "required": true,
+                  "type": "string"
+                }
+              }
+            }
+          }
+        }
+      },
+      "derived_from": "tosca.nodes.Component"
     }
   }
 }
\ No newline at end of file
index ea053c3..1fb6e75 100644 (file)
       }
     }
   },
+  "k8s-rb-profile-namespace" : {
+    "tags" : "k8s-rb-profile-namespace",
+    "name" : "k8s-rb-profile-namespace",
+    "property" : {
+      "description" : "k8s-rb-profile-namespace",
+      "type" : "string"
+    },
+    "updated-by" : "Rajewski, Lukasz <lukasz.rajewski@orange.com>",
+    "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
+      "sdnc" : {
+        "type" : "source-rest",
+        "properties" : {
+          "verb" : "GET",
+          "type" : "JSON",
+          "url-path" : "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/k8s-rb-profile-namespace",
+          "path" : "/param/0/value",
+          "input-key-mapping" : {
+            "service-instance-id" : "service-instance-id",
+            "vnf-id" : "vnf-id"
+          },
+          "output-key-mapping" : {
+            "k8s-rb-profile-namespace" : "value"
+          },
+          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
+        }
+      }
+    }
+  },
   "key_name" : {
     "tags" : "key_name",
     "name" : "key_name",
index 405df54..c4b6516 100644 (file)
       "username" : "admin",
       "password" : "admin"
     },
+    "multicloud-k8s-api" : {
+      "type" : "basic-auth",
+      "username" : "admin",
+      "password" : "admin",
+      "url" : "http://multicloud-k8s:9015"
+    },
+    "profile-upload-properties" : {
+      "resolution-key" : {
+        "get_input" : "resolution-key"
+      },
+      "api-access": "*multicloud-k8s-api"
+    },
     "config-deploy-properties" : {
       "resolution-key" : {
         "get_input" : "resolution-key"
         "steps" : {
           "resource-assignment" : {
             "description" : "Resource Assign Workflow",
-            "target" : "resource-assignment"
+            "target" : "resource-assignment",
+            "activities": [
+              {
+                "call_operation": "ResourceResolutionComponent.process"
+              }
+            ],
+            "on_success": [
+              "profile-upload"
+            ]
+          },
+          "profile-upload" : {
+            "description" : "Upload K8s Profile",
+            "target" : "profile-upload",
+            "activities": [
+              {
+                "call_operation": "ComponentScriptExecutor.process"
+              }
+            ]
           }
         },
         "inputs" : {
               "type" : "string"
             }
           },
+          "resolution-key" : {
+            "required" : false,
+            "type" : "string",
+            "entry_schema" : {
+              "type" : ""
+            }
+          },
           "resource-assignment-properties" : {
             "description" : "Dynamic PropertyDefinition for workflow(resource-assignment).",
             "required" : true,
                   "artifact-prefix-names" : {
                     "get_input" : "template-prefix"
                   }
+                },
+                "store-result": true,
+                "resolution-key": {
+                  "get_input" : "resolution-key"
                 }
               }
             }
           }
         }
       },
+      "profile-upload" : {
+        "type" : "component-script-executor",
+        "interfaces" : {
+          "ComponentScriptExecutor" : {
+            "operations" : {
+              "process" : {
+                "inputs" : {
+                  "script-type" : "kotlin",
+                  "script-class-reference" : "org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts.K8sProfileUpload",
+                  "instance-dependencies" : [ ],
+                  "dynamic-properties" : "*profile-upload-properties"
+                }
+              }
+            }
+          }
+        }
+      },
       "config-deploy-process" : {
         "type" : "component-resource-resolution",
         "interfaces" : {
diff --git a/heat/vFW_CNF_CDS/templates/cba/Scripts/kotlin/KotlinK8sProfileUpload.kt b/heat/vFW_CNF_CDS/templates/cba/Scripts/kotlin/KotlinK8sProfileUpload.kt
new file mode 100644 (file)
index 0000000..81b0c3e
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Copyright © 2019 Orange
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts
+
+import com.fasterxml.jackson.databind.node.ObjectNode
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.storedContentFromResolvedArtifactNB
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.BasicAuthRestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BasicAuthRestClientService
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.RestLoggerService
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.apache.commons.io.IOUtils
+import org.apache.commons.io.FilenameUtils
+import org.apache.http.client.entity.EntityBuilder
+import org.apache.http.entity.ContentType
+import org.apache.http.message.BasicHeader
+import org.apache.http.client.methods.HttpPost
+import org.apache.http.client.methods.HttpUriRequest
+import org.apache.http.client.ClientProtocolException
+import org.slf4j.LoggerFactory
+import org.springframework.http.HttpMethod
+import org.springframework.web.client.RestTemplate
+import com.fasterxml.jackson.annotation.JsonIgnore
+import com.fasterxml.jackson.annotation.JsonProperty
+import java.util.ArrayList
+import java.io.IOException
+import java.io.File
+import java.nio.file.Files
+import java.nio.file.Paths
+import java.nio.file.Path
+import org.springframework.http.HttpHeaders
+import org.springframework.http.MediaType
+import java.nio.charset.Charset
+import java.util.Base64
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+
+import java.io.BufferedInputStream
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.util.zip.GZIPInputStream
+
+open class K8sProfileUpload : AbstractScriptComponentFunction() {
+
+    private val log = LoggerFactory.getLogger(K8sProfileUpload::class.java)!!
+
+    override fun getName(): String {
+        return "K8sProfileUpload"
+    }
+
+    override suspend fun processNB(executionRequest: ExecutionServiceInput) {
+        log.info("executing K8s Profile Upload script")
+        val resolution_key = getDynamicProperties("resolution-key").asText()
+        log.info("resolution_key: $resolution_key")
+
+        val baseK8sApiUrl = getDynamicProperties("api-access").get("url").asText()
+        val k8sApiUsername = getDynamicProperties("api-access").get("username").asText()
+        val k8sApiPassword = getDynamicProperties("api-access").get("password").asText()
+
+        val prefixList: ArrayList<String> = getTemplatePrefixList(executionRequest)
+
+        for (prefix in prefixList) {
+            if (prefix.toLowerCase().equals("vnf"))
+                continue
+
+            val payload = storedContentFromResolvedArtifactNB(resolution_key, prefix)
+            log.info("Uploading K8S profile for template prefix $prefix")
+
+            val payloadObject = JacksonUtils.jsonNode(payload) as ObjectNode
+
+            val vfModuleModelInvariantUuid: String = getResolvedParameter(payloadObject, "vf_module_model_invariant_uuid")
+            val vfModuleModelUuid: String = getResolvedParameter(payloadObject, "vf_module_model_version")
+            val k8sRbProfileName: String = getResolvedParameter(payloadObject, "k8s-rb-profile-name")
+            val k8sRbProfileNamespace: String = getResolvedParameter(payloadObject, "k8s-rb-profile-namespace")
+
+            val api = K8sApi(k8sApiUsername, k8sApiPassword, baseK8sApiUrl, vfModuleModelInvariantUuid, vfModuleModelUuid)
+
+            if (!api.hasDefinition()) {
+                throw BluePrintProcessorException("K8s RB Definition (${vfModuleModelInvariantUuid}/${vfModuleModelUuid}) not found ")
+            }
+
+            log.info("k8s-rb-profile-name: $k8sRbProfileName")
+            if (k8sRbProfileName.equals("")) {
+                log.info("Profile Name Not Defined - skipping upload")
+            } else {
+                if (api.hasProfile(k8sRbProfileName)) {
+                    log.info("Profile Already Existing - skipping upload")
+                } else {
+                    profileFilePath = prepareProfileFile(k8sRbProfileName)
+
+                    var profile = K8sProfile()
+                    profile.profileName = k8sRbProfileName
+                    profile.rbName = vfModuleModelInvariantUuid
+                    profile.rbVersion = vfModuleModelUuid
+                    profile.namespace = k8sRbProfileNamespace
+                    api.createProfile(profile)
+                    api.uploadProfileContent(profile, profileFilePath)
+
+                    log.info("K8s Profile Upload Completed")
+                }
+            }
+        }
+    }
+
+    fun prepareProfileFile(k8sRbProfileName: String): Path {
+        val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
+        val bluePrintBasePath: String = bluePrintContext.rootPath
+        var profileFilePath: Path = Paths.get(bluePrintBasePath.plus(File.separator).plus("Templates").plus(File.separator).plus("k8s-profiles").plus(File.separator).plus("${k8sRbProfileName}.tar.gz"))
+        log.info("Reading K8s profile file: ${profileFilePath}")
+
+        val profileFile = profileFilePath.toFile()
+
+        if (!profileFile.exists())
+            throw BluePrintProcessorException("K8s Profile template file ${profileFilePath} does not exists")
+
+        return profileFilePath
+    }
+
+    fun getTemplatePrefixList(executionRequest: ExecutionServiceInput): ArrayList<String> {
+        val result = ArrayList<String>()
+        for (prefix in executionRequest.payload.get("resource-assignment-request").get("template-prefix").elements())
+            result.add(prefix.asText())
+        return result
+    }
+
+    fun getResolvedParameter(payload: ObjectNode, keyName: String): String {
+        for (node in payload.get("resource-accumulator-resolved-data").elements()) {
+            if (node.get("param-name").asText().equals(keyName)) {
+                return node.get("param-value").asText()
+            }
+        }
+        return ""
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
+        log.info("Executing Recovery")
+        bluePrintRuntimeService.getBluePrintError().addError("${runtimeException.message}")
+    }
+
+    inner class K8sApi(val username: String, val password: String, val baseUrl: String, val definition: String,
+                       val definitionVersion: String) {
+        private val service: UploadFileRestClientService //BasicAuthRestClientService
+
+        init {
+            var mapOfHeaders = hashMapOf<String, String>()
+            mapOfHeaders.put("Accept", "application/json")
+            mapOfHeaders.put("Content-Type", "application/json")
+            mapOfHeaders.put("cache-control", " no-cache")
+            mapOfHeaders.put("Accept", "application/json")
+            var basicAuthRestClientProperties: BasicAuthRestClientProperties = BasicAuthRestClientProperties()
+            basicAuthRestClientProperties.username = username
+            basicAuthRestClientProperties.password = password
+            basicAuthRestClientProperties.url = "$baseUrl/api/multicloud-k8s/v1/v1/rb/definition/${definition}/${definitionVersion}"
+            basicAuthRestClientProperties.additionalHeaders = mapOfHeaders
+
+            this.service = UploadFileRestClientService(basicAuthRestClientProperties)
+        }
+
+        fun hasDefinition(): Boolean {
+            try {
+                val result: BlueprintWebClientService.WebClientResponse<String> = service.exchangeResource(HttpMethod.GET.name, "", "")
+                print(result)
+                if (result.status >= 200 && result.status < 300)
+                    return true
+                else
+                    return false
+            } catch (e: Exception) {
+                log.info("Caught exception trying to get k8s rb definition")
+                throw BluePrintProcessorException("${e.message}")
+            }
+        }
+
+        fun hasProfile(profileName: String): Boolean {
+            try {
+                val result: BlueprintWebClientService.WebClientResponse<String> = service.exchangeResource(HttpMethod.GET.name,
+                        "/profile/$profileName", "")
+                if (result.status >= 200 && result.status < 300)
+                    return true
+                else {
+                    print(result)
+                    return false
+                }
+            } catch (e: Exception) {
+                log.info("Caught exception trying to get k8s rb profile")
+                throw BluePrintProcessorException("${e.message}")
+            }
+        }
+
+        fun createProfile(profile: K8sProfile) {
+            val objectMapper = ObjectMapper()
+            val profileJsonString: String = objectMapper.writeValueAsString(profile)
+            try {
+                val result: BlueprintWebClientService.WebClientResponse<String> = service.exchangeResource(HttpMethod.POST.name,
+                        "/profile", profileJsonString)
+                if (result.status < 200 || result.status >= 300) {
+                    throw Exception(result.body)
+                }
+            } catch (e: Exception) {
+                log.info("Caught exception trying to create k8s rb profile ${profile.profileName}")
+                throw BluePrintProcessorException("${e.message}")
+            }
+        }
+
+        fun uploadProfileContent(profile: K8sProfile, filePath: Path) {
+            try {
+                val result: BlueprintWebClientService.WebClientResponse<String> = service.uploadBinaryFile(
+                        "/profile/${profile.profileName}/content", filePath)
+                if (result.status < 200 || result.status >= 300) {
+                    throw Exception(result.body)
+                }
+            } catch (e: Exception) {
+                log.info("Caught exception trying to upload k8s rb profile ${profile.profileName}")
+                throw BluePrintProcessorException("${e.message}")
+            }
+        }
+    }
+}
+
+class UploadFileRestClientService(
+        private val restClientProperties:
+        BasicAuthRestClientProperties
+) : BlueprintWebClientService {
+
+    override fun defaultHeaders(): Map<String, String> {
+
+        val encodedCredentials = setBasicAuth(
+                restClientProperties.username,
+                restClientProperties.password
+        )
+        return mapOf(
+                HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE,
+                HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE,
+                HttpHeaders.AUTHORIZATION to "Basic $encodedCredentials"
+        )
+    }
+
+    override fun host(uri: String): String {
+        return restClientProperties.url + uri
+    }
+
+    override fun convertToBasicHeaders(headers: Map<String, String>):
+            Array<BasicHeader> {
+        val customHeaders: MutableMap<String, String> = headers.toMutableMap()
+        // inject additionalHeaders
+        customHeaders.putAll(verifyAdditionalHeaders(restClientProperties))
+
+        if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) {
+            val encodedCredentials = setBasicAuth(
+                    restClientProperties.username,
+                    restClientProperties.password
+            )
+            customHeaders[HttpHeaders.AUTHORIZATION] =
+                    "Basic $encodedCredentials"
+        }
+        return super.convertToBasicHeaders(customHeaders)
+    }
+
+    private fun setBasicAuth(username: String, password: String): String {
+        val credentialsString = "$username:$password"
+        return Base64.getEncoder().encodeToString(
+                credentialsString.toByteArray(Charset.defaultCharset())
+        )
+    }
+
+    @Throws(IOException::class, ClientProtocolException::class)
+    private fun performHttpCall(httpUriRequest: HttpUriRequest): BlueprintWebClientService.WebClientResponse<String> {
+        val httpResponse = httpClient().execute(httpUriRequest)
+        val statusCode = httpResponse.statusLine.statusCode
+        httpResponse.entity.content.use {
+            val body = IOUtils.toString(it, Charset.defaultCharset())
+            return BlueprintWebClientService.WebClientResponse(statusCode, body)
+        }
+    }
+
+    fun uploadBinaryFile(path: String, filePath: Path): BlueprintWebClientService.WebClientResponse<String> {
+        val convertedHeaders: Array<BasicHeader> = convertToBasicHeaders(defaultHeaders())
+        val httpPost = HttpPost(host(path))
+        val entity = EntityBuilder.create().setBinary(Files.readAllBytes(filePath)).build()
+        httpPost.setEntity(entity)
+        RestLoggerService.httpInvoking(convertedHeaders)
+        httpPost.setHeaders(convertedHeaders)
+        return performHttpCall(httpPost)
+    }
+}
+
+class K8sProfile {
+    @get:JsonProperty("rb-name")
+    var rbName: String? = null
+    @get:JsonProperty("rb-version")
+    var rbVersion: String? = null
+    @get:JsonProperty("profile-name")
+    var profileName: String? = null
+    @get:JsonProperty("namespace")
+    var namespace: String? = "default"
+
+    override fun toString(): String {
+        return "$rbName:$rbVersion:$profileName"
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+        return true
+    }
+
+    override fun hashCode(): Int {
+        return javaClass.hashCode()
+    }
+}
\ No newline at end of file
diff --git a/heat/vFW_CNF_CDS/templates/cba/Scripts/kotlin/README.md b/heat/vFW_CNF_CDS/templates/cba/Scripts/kotlin/README.md
new file mode 100644 (file)
index 0000000..29b7978
--- /dev/null
@@ -0,0 +1 @@
+kotlin Folder
\ No newline at end of file
index b4cadd3..615bbae 100644 (file)
       "vnf-id"
     ]
   },
+  {
+    "name": "k8s-rb-profile-namespace",
+    "property": {
+      "description": "K8s namespace to create helm chart for specified profile",
+      "type": "string",
+      "default": "default"
+    },
+    "input-param": false,
+    "dictionary-name": "k8s-rb-profile-namespace",
+    "dictionary-source": "default",
+    "dependencies": [
+      "service-instance-id",
+      "vnf-id"
+    ]
+  },
   {
     "name": "int_private1_gw_ip",
     "property": {
index 226f4a5..d5ee720 100644 (file)
       "param-name": "k8s-rb-profile-name",
       "param-value": "${k8s-rb-profile-name}"
     },
+    {
+      "param-name": "k8s-rb-profile-namespace",
+      "param-value": "${k8s-rb-profile-namespace}"
+    },
     {
       "param-name": "int_private1_gw_ip",
       "param-value": "${int_private1_gw_ip}"
index c78d34c..9775a80 100644 (file)
       "vnf-id"
     ]
   },
+  {
+    "name": "k8s-rb-profile-namespace",
+    "property": {
+      "description": "K8s namespace to create helm chart for specified profile",
+      "type": "string",
+      "default": "default"
+    },
+    "input-param": false,
+    "dictionary-name": "k8s-rb-profile-namespace",
+    "dictionary-source": "default",
+    "dependencies": [
+      "service-instance-id",
+      "vnf-id"
+    ]
+  },
   {
     "name": "int_private1_net_id",
     "property": {
index d81d961..8b8d19a 100644 (file)
       "param-name": "k8s-rb-profile-name",
       "param-value": "${k8s-rb-profile-name}"
     },
+    {
+      "param-name": "k8s-rb-profile-namespace",
+      "param-value": "${k8s-rb-profile-namespace}"
+    },    
     {
       "param-name": "int_private1_net_id",
       "param-value": "${int_private1_net_id}"
index 1a1ca27..a1d4119 100644 (file)
     "dependencies": [
     ]
   },
+  {
+    "name": "k8s-rb-profile-namespace",
+    "property": {
+      "description": "K8s namespace to create helm chart for specified profile",
+      "type": "string",
+      "default": "default"
+    },
+    "input-param": false,
+    "dictionary-name": "k8s-rb-profile-namespace",
+    "dictionary-source": "default",
+    "dependencies": [
+      "service-instance-id",
+      "vnf-id"
+    ]
+  },
   {
     "name": "int_private1_gw_ip",
     "property": {
index 37b4b94..617f0b9 100644 (file)
       "param-name": "k8s-rb-profile-name",
       "param-value": "${k8s-rb-profile-name}"
     },
+    {
+      "param-name": "k8s-rb-profile-namespace",
+      "param-value": "${k8s-rb-profile-namespace}"
+    },    
     {
       "param-name": "int_private1_gw_ip",
       "param-value": "${int_private1_gw_ip}"
index 801d339..40f60c0 100644 (file)
       "vnf-id"
     ]
   },
+  {
+    "name": "k8s-rb-profile-namespace",
+    "property": {
+      "description": "K8s namespace to create helm chart for specified profile",
+      "type": "string",
+      "default": "default"
+    },
+    "input-param": false,
+    "dictionary-name": "k8s-rb-profile-namespace",
+    "dictionary-source": "default",
+    "dependencies": [
+      "service-instance-id",
+      "vnf-id"
+    ]
+  },
   {
     "name": "int_private1_net_id",
     "property": {
index bec8cfb..1de5c82 100644 (file)
       "param-name": "k8s-rb-profile-name",
       "param-value": "${k8s-rb-profile-name}"
     },
+    {
+      "param-name": "k8s-rb-profile-namespace",
+      "param-value": "${k8s-rb-profile-namespace}"
+    },    
     {
       "param-name": "int_private1_net_id",
       "param-value": "${int_private1_net_id}"
index a4b7450..533ad9a 100644 (file)
       "vnf-id"
     ]
   },
+  {
+    "name": "k8s-rb-profile-namespace",
+    "property": {
+      "description": "K8s namespace to create helm chart for specified profile",
+      "type": "string",
+      "default": "default"
+    },
+    "input-param": false,
+    "dictionary-name": "k8s-rb-profile-namespace",
+    "dictionary-source": "default",
+    "dependencies": [
+      "service-instance-id",
+      "vnf-id"
+    ]
+  },
   {
     "name": "int_private2_gw_ip",
     "property": {
index 60b8ecd..0d368e2 100644 (file)
       "param-name": "k8s-rb-profile-name",
       "param-value": "${k8s-rb-profile-name}"
     },
+    {
+      "param-name": "k8s-rb-profile-namespace",
+      "param-value": "${k8s-rb-profile-namespace}"
+    },    
     {
       "param-name": "int_private2_gw_ip",
       "param-value": "${int_private2_gw_ip}"