From 1e294a59489bf5900135f67cd87dab5d6a67fada Mon Sep 17 00:00:00 2001
From: Lukasz Rajewski <lukasz.rajewski@orange.com>
Date: Mon, 22 Mar 2021 22:43:23 +0100
Subject: Bug fixes for config template and config value components

Issue-ID: CCSDK-3232
Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com>
Change-Id: I817d83001a76ba480472c7aa2da15eba65b39c20
(cherry picked from commit 91c1deec281ece8aa72b2afd9cc68b2d63c38189)
---
 .../k8s/definition/K8sPluginDefinitionApi.kt       |  14 +-
 .../template/K8sConfigTemplateComponent.kt         |   4 +-
 .../definition/template/K8sConfigValueComponent.kt | 144 ++++++++++++++-------
 .../k8s/instance/K8sConfigValueResponse.kt         |  18 ++-
 .../functions/k8s/instance/K8sPluginInstanceApi.kt |  61 ++++++++-
 5 files changed, 182 insertions(+), 59 deletions(-)

(limited to 'ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main')

diff --git a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/K8sPluginDefinitionApi.kt b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/K8sPluginDefinitionApi.kt
index 05c3021d9..ae2d1f634 100644
--- a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/K8sPluginDefinitionApi.kt
+++ b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/K8sPluginDefinitionApi.kt
@@ -111,16 +111,18 @@ class K8sPluginDefinitionApi(
                 "/profile/${profile.profileName}/content",
                 filePath
             )
+            log.debug(result.toString())
             if (result.status !in 200..299) {
                 throw Exception(result.body)
             }
+            log.debug("Profile uploaded properly")
         } catch (e: Exception) {
             log.error("Caught exception trying to upload k8s rb profile ${profile.profileName}")
             throw BlueprintProcessorException("${e.message}")
         }
     }
 
-    fun createTemplate(definition: String, definitionVersion: String, template: K8sTemplate): Boolean {
+    fun createTemplate(definition: String, definitionVersion: String, template: K8sTemplate) {
         val rbDefinitionService = K8sDefinitionRestClient(k8sConfiguration, definition, definitionVersion)
         val templateJsonString: String = objectMapper.writeValueAsString(template)
         try {
@@ -130,20 +132,23 @@ class K8sPluginDefinitionApi(
                 templateJsonString
             )
             log.debug(result.toString())
-            return result.status in 200..299
+            if (result.status !in 200..299) {
+                throw Exception(result.body)
+            }
         } catch (e: Exception) {
             log.error("Caught exception during create template")
             throw BlueprintProcessorException("${e.message}")
         }
     }
 
-    fun uploadTemplate(definition: String, definitionVersion: String, template: K8sTemplate, filePath: Path) {
+    fun uploadConfigTemplateContent(definition: String, definitionVersion: String, template: K8sTemplate, filePath: Path) {
         val fileUploadService = K8sUploadFileRestClientService(k8sConfiguration, definition, definitionVersion)
         try {
             val result: BlueprintWebClientService.WebClientResponse<String> = fileUploadService.uploadBinaryFile(
                 "/config-template/${template.templateName}/content",
                 filePath
             )
+            log.debug(result.toString())
             if (result.status !in 200..299) {
                 throw Exception(result.body)
             }
@@ -162,6 +167,9 @@ class K8sPluginDefinitionApi(
                 ""
             )
             log.debug(result.toString())
+            if (result.status !in 200..299) {
+                throw Exception(result.body)
+            }
         } catch (e: Exception) {
             log.error("Caught exception during get template")
             throw BlueprintProcessorException("${e.message}")
diff --git a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigTemplateComponent.kt b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigTemplateComponent.kt
index cb759e534..0944c2359 100644
--- a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigTemplateComponent.kt
+++ b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigTemplateComponent.kt
@@ -141,7 +141,7 @@ open class K8sConfigTemplateComponent(
                 }
                 val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
                 val artifact: ArtifactDefinition = bluePrintContext.nodeTemplateArtifact(nodeTemplateName, templateSource)
-                if (artifact.type != BlueprintConstants.MODEL_TYPE_ARTIFACT_K8S_PROFILE)
+                if (artifact.type != BlueprintConstants.MODEL_TYPE_ARTIFACT_K8S_CONFIG)
                     throw BlueprintProcessorException(
                         "Unexpected template artifact type for template source $templateSource. Expecting: $artifact.type"
                     )
@@ -151,7 +151,7 @@ open class K8sConfigTemplateComponent(
 
                 val templateFilePath: Path = prepareTemplateFile(templateName, templateSource, artifact.file)
                 api.createTemplate(definitionName, definitionVersion, template)
-                api.uploadTemplate(definitionName, definitionVersion, template, templateFilePath)
+                api.uploadConfigTemplateContent(definitionName, definitionVersion, template, templateFilePath)
 
                 log.info("K8s Config Upload Completed")
                 outputPrefixStatuses[prefix] = OUTPUT_UPLOADED
diff --git a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigValueComponent.kt b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigValueComponent.kt
index 2e7b34e01..34b6ea187 100644
--- a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigValueComponent.kt
+++ b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigValueComponent.kt
@@ -11,12 +11,17 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInpu
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.k8s.K8sConnectionPluginConfiguration
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.k8s.instance.K8sConfigValueRequest
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.k8s.instance.K8sPluginInstanceApi
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionService
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction
 import org.onap.ccsdk.cds.controllerblueprints.core.BlueprintConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.BlueprintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode
 import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition
 import org.onap.ccsdk.cds.controllerblueprints.core.returnNullIfMissing
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BlueprintVelocityTemplateService
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.config.ConfigurableBeanFactory
 import org.springframework.context.annotation.Scope
@@ -28,7 +33,8 @@ import java.nio.file.Paths
 @Component("component-k8s-config-value")
 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 open class K8sConfigValueComponent(
-    private var bluePrintPropertiesService: BlueprintPropertiesService
+    private var bluePrintPropertiesService: BlueprintPropertiesService,
+    private val resourceResolutionService: ResourceResolutionService
 ) : AbstractComponentFunction() {
 
     private val log = LoggerFactory.getLogger(K8sConfigValueComponent::class.java)!!
@@ -36,11 +42,11 @@ open class K8sConfigValueComponent(
     companion object {
         const val INPUT_RESOURCE_ASSIGNMENT_MAP = "resource-assignment-map"
         const val INPUT_ARTIFACT_PREFIX_NAMES = "artifact-prefix-names"
-        const val INPUT_K8S_TEMPLATE_NAME = "k8s-template-name"
-        const val INPUT_K8S_CONFIG_NAME = "k8s-config-name"
+        const val INPUT_K8S_RB_CONFIG_TEMPLATE_NAME = "k8s-rb-config-template-name"
+        const val INPUT_K8S_RB_CONFIG_NAME = "k8s-rb-config-name"
         const val INPUT_K8S_INSTANCE_ID = "k8s-instance-id"
-        const val INPUT_K8S_TEMPLATE_VALUE_SOURCE = "k8s-rb-template-value-source"
-        const val INPUT_K8S_OPERATION_TYPE = "k8s-operation-type"
+        const val INPUT_K8S_CONFIG_VALUE_SOURCE = "k8s-rb-config-value-source"
+        const val INPUT_K8S_CONFIG_OPERATION_TYPE = "k8s-config-operation-type"
 
         const val OUTPUT_STATUSES = "statuses"
         const val OUTPUT_SKIPPED = "skipped"
@@ -51,11 +57,11 @@ open class K8sConfigValueComponent(
     override suspend fun processNB(executionRequest: ExecutionServiceInput) {
         log.info("Triggering K8s Config Value component logic.")
         val inputParameterNames = arrayOf(
-            INPUT_K8S_TEMPLATE_NAME,
-            INPUT_K8S_CONFIG_NAME,
+            INPUT_K8S_RB_CONFIG_TEMPLATE_NAME,
+            INPUT_K8S_RB_CONFIG_NAME,
             INPUT_K8S_INSTANCE_ID,
-            INPUT_K8S_OPERATION_TYPE,
-            INPUT_K8S_TEMPLATE_VALUE_SOURCE,
+            INPUT_K8S_CONFIG_OPERATION_TYPE,
+            INPUT_K8S_CONFIG_VALUE_SOURCE,
             INPUT_ARTIFACT_PREFIX_NAMES
         )
         val outputPrefixStatuses = mutableMapOf<String, String>()
@@ -82,74 +88,81 @@ open class K8sConfigValueComponent(
                 }
             }
 
-            val templateName: String? = prefixInputParamsMap[INPUT_K8S_TEMPLATE_NAME]?.returnNullIfMissing()?.asText()
-            val configName: String? = prefixInputParamsMap[INPUT_K8S_CONFIG_NAME]?.returnNullIfMissing()?.asText()
+            val templateName: String? = prefixInputParamsMap[INPUT_K8S_RB_CONFIG_TEMPLATE_NAME]?.returnNullIfMissing()?.asText()
+            val configName: String? = prefixInputParamsMap[INPUT_K8S_RB_CONFIG_NAME]?.returnNullIfMissing()?.asText()
             val instanceId: String? = prefixInputParamsMap[INPUT_K8S_INSTANCE_ID]?.returnNullIfMissing()?.asText()
-            val valueSource: String? = prefixInputParamsMap[INPUT_K8S_TEMPLATE_VALUE_SOURCE]?.returnNullIfMissing()?.asText()
-            val operationType = prefixInputParamsMap[INPUT_K8S_TEMPLATE_VALUE_SOURCE]?.returnNullIfMissing()?.asText()?.toUpperCase()
+            var valueSource: String? = prefixInputParamsMap[INPUT_K8S_CONFIG_VALUE_SOURCE]?.returnNullIfMissing()?.asText()
+            val operationType = prefixInputParamsMap[INPUT_K8S_CONFIG_OPERATION_TYPE]?.returnNullIfMissing()?.asText()?.toUpperCase()
 
+            if (valueSource == null) {
+                valueSource = configName
+                log.info("Config name used instead of value source")
+            }
             if (operationType == null || operationType == OperationType.CREATE.toString())
                 createOperation(templateName, instanceId, valueSource, outputPrefixStatuses, prefix, configName)
             else if (operationType == OperationType.UPDATE.toString())
                 updateOperation(templateName, instanceId, valueSource, outputPrefixStatuses, prefix, configName)
-            else if (operationType == OperationType.ROLLBACK.toString())
-                rollbackOperation(instanceId)
+            else if (operationType == OperationType.DELETE.toString())
+                deleteOperation(instanceId, configName)
             else
                 throw BlueprintProcessorException("Unknown operation type: $operationType")
         }
     }
 
-    private fun createOperation(templateName: String?, instanceId: String?, valueSource: String?, outputPrefixStatuses: MutableMap<String, String>, prefix: String, configName: String?) {
+    private suspend fun createOperation(templateName: String?, instanceId: String?, valueSource: String?, outputPrefixStatuses: MutableMap<String, String>, prefix: String, configName: String?) {
+        val api = K8sPluginInstanceApi(K8sConnectionPluginConfiguration(bluePrintPropertiesService))
         if (templateName == null || configName == null || instanceId == null || valueSource == null) {
-            log.warn("$INPUT_K8S_TEMPLATE_NAME or $INPUT_K8S_INSTANCE_ID or $INPUT_K8S_TEMPLATE_VALUE_SOURCE or $INPUT_K8S_CONFIG_NAME is null")
+            log.warn("$INPUT_K8S_RB_CONFIG_TEMPLATE_NAME or $INPUT_K8S_INSTANCE_ID or $INPUT_K8S_CONFIG_VALUE_SOURCE or $INPUT_K8S_RB_CONFIG_NAME is null - skipping create")
         } else if (templateName.isEmpty()) {
-            log.warn("$INPUT_K8S_TEMPLATE_NAME is empty")
+            log.warn("$INPUT_K8S_RB_CONFIG_TEMPLATE_NAME is empty - skipping create")
         } else if (configName.isEmpty()) {
-            log.warn("$INPUT_K8S_CONFIG_NAME is empty")
+            log.warn("$INPUT_K8S_RB_CONFIG_NAME is empty - skipping create")
+        } else if (api.hasConfigurationValues(instanceId, configName)) {
+            log.info("Configuration already exists - skipping create")
         } else {
-            log.info("Uploading K8s template value..")
+            log.info("Uploading K8s config..")
             outputPrefixStatuses[prefix] = OUTPUT_ERROR
             val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
             val artifact: ArtifactDefinition = bluePrintContext.nodeTemplateArtifact(nodeTemplateName, valueSource)
-            if (artifact.type != BlueprintConstants.MODEL_TYPE_ARTIFACT_K8S_PROFILE)
+            if (artifact.type != BlueprintConstants.MODEL_TYPE_ARTIFACT_K8S_CONFIG)
                 throw BlueprintProcessorException(
-                    "Unexpected profile artifact type for profile source $valueSource. Expecting: $artifact.type"
+                    "Unexpected config artifact type for config value source $valueSource. Expecting: $artifact.type"
                 )
-            // Creating API connector
-            val api = K8sPluginInstanceApi(K8sConnectionPluginConfiguration(bluePrintPropertiesService))
             val configValueRequest = K8sConfigValueRequest()
             configValueRequest.templateName = templateName
             configValueRequest.configName = configName
             configValueRequest.description = valueSource
-            configValueRequest.values = parseResult(valueSource)
+            configValueRequest.values = parseResult(valueSource, artifact.file)
             api.createConfigurationValues(configValueRequest, instanceId)
         }
     }
 
-    private fun updateOperation(templateName: String?, instanceId: String?, valueSource: String?, outputPrefixStatuses: MutableMap<String, String>, prefix: String, configName: String?) {
+    private suspend fun updateOperation(templateName: String?, instanceId: String?, valueSource: String?, outputPrefixStatuses: MutableMap<String, String>, prefix: String, configName: String?) {
+        val api = K8sPluginInstanceApi(K8sConnectionPluginConfiguration(bluePrintPropertiesService))
         if (templateName == null || configName == null || instanceId == null || valueSource == null) {
-            log.warn("$INPUT_K8S_TEMPLATE_NAME or $INPUT_K8S_INSTANCE_ID or $INPUT_K8S_TEMPLATE_VALUE_SOURCE or $INPUT_K8S_CONFIG_NAME is null")
+            log.warn("$INPUT_K8S_RB_CONFIG_TEMPLATE_NAME or $INPUT_K8S_INSTANCE_ID or $INPUT_K8S_CONFIG_VALUE_SOURCE or $INPUT_K8S_RB_CONFIG_NAME is null - skipping update")
         } else if (templateName.isEmpty()) {
-            log.warn("$INPUT_K8S_TEMPLATE_NAME is empty")
+            log.warn("$INPUT_K8S_RB_CONFIG_TEMPLATE_NAME is empty - skipping update")
         } else if (configName.isEmpty()) {
-            log.warn("$INPUT_K8S_CONFIG_NAME is empty")
+            log.warn("$INPUT_K8S_RB_CONFIG_NAME is empty - skipping update")
+        } else if (!api.hasConfigurationValues(instanceId, configName)) {
+            log.info("Configuration does not exist - doing create instead")
+            createOperation(templateName, instanceId, valueSource, outputPrefixStatuses, prefix, configName)
         } else {
-            log.info("Uploading K8s template value..")
+            log.info("Updating K8s config..")
             outputPrefixStatuses[prefix] = OUTPUT_ERROR
             val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
             val artifact: ArtifactDefinition = bluePrintContext.nodeTemplateArtifact(nodeTemplateName, valueSource)
-            if (artifact.type != BlueprintConstants.MODEL_TYPE_ARTIFACT_K8S_PROFILE)
+            if (artifact.type != BlueprintConstants.MODEL_TYPE_ARTIFACT_K8S_CONFIG)
                 throw BlueprintProcessorException(
-                    "Unexpected profile artifact type for profile source $valueSource. Expecting: $artifact.type"
+                    "Unexpected config artifact type for config value source $valueSource. Expecting: $artifact.type"
                 )
-            // Creating API connector
-            val api = K8sPluginInstanceApi(K8sConnectionPluginConfiguration(bluePrintPropertiesService))
             if (api.hasConfigurationValues(instanceId, configName)) {
                 val configValueRequest = K8sConfigValueRequest()
                 configValueRequest.templateName = templateName
                 configValueRequest.configName = configName
                 configValueRequest.description = valueSource
-                configValueRequest.values = parseResult(valueSource)
+                configValueRequest.values = parseResult(valueSource, artifact.file)
                 api.editConfigurationValues(configValueRequest, instanceId, configName)
             } else {
                 throw BlueprintProcessorException("Error while getting configuration value")
@@ -157,24 +170,67 @@ open class K8sConfigValueComponent(
         }
     }
 
-    private fun rollbackOperation(instanceId: String?) {
-        if (instanceId != null) {
-            val api = K8sPluginInstanceApi(K8sConnectionPluginConfiguration(bluePrintPropertiesService))
-            api.rollbackConfigurationValues(instanceId)
+    private fun deleteOperation(instanceId: String?, configName: String?) {
+        val api = K8sPluginInstanceApi(K8sConnectionPluginConfiguration(bluePrintPropertiesService))
+        if (instanceId == null || configName == null) {
+            log.warn("$INPUT_K8S_INSTANCE_ID or $INPUT_K8S_RB_CONFIG_NAME is null - skipping delete")
+        } else if (api.hasConfigurationValues(instanceId, configName)) {
+            log.info("Configuration does not exists - skipping delete")
         } else {
-            throw BlueprintProcessorException("$INPUT_K8S_INSTANCE_ID is null")
+            api.deleteConfigurationValues(instanceId, configName)
         }
     }
 
-    private fun parseResult(templateValueSource: String): Any {
-        val ymlSourceFile = getYmlSourceFile(templateValueSource)
+    private suspend fun parseResult(templateValueSource: String, k8sConfigLocation: String): Any {
+        val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
+        val bluePrintBasePath: String = bluePrintContext.rootPath
+        val configeValueSourceFilePath: Path = Paths.get(
+            bluePrintBasePath.plus(File.separator).plus(k8sConfigLocation)
+        )
+
+        if (!configeValueSourceFilePath.toFile().exists() || configeValueSourceFilePath.toFile().isDirectory)
+            throw BlueprintProcessorException("Specified config value source $k8sConfigLocation is not a file")
+
+        var obj: Any? = null
         val yamlReader = ObjectMapper(YAMLFactory())
-        val obj: Any = yamlReader.readValue(ymlSourceFile, Any::class.java)
+        if (configeValueSourceFilePath.toFile().extension.toLowerCase() == "vtl") {
+            log.info("Config building started from source $templateValueSource")
+            val properties: MutableMap<String, Any> = mutableMapOf()
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = false
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = ""
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = ""
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = ""
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = 1
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_SUMMARY] = false
+            val resolutionResult: Pair<String, MutableList<ResourceAssignment>> = resourceResolutionService.resolveResources(
+                bluePrintRuntimeService,
+                nodeTemplateName,
+                templateValueSource,
+                properties
+            )
+
+            val resolvedJsonContent = resolutionResult.second
+                .associateBy({ it.name }, { it.property?.value })
+                .asJsonNode()
 
+            val newContent: String = templateValues(configeValueSourceFilePath.toFile(), resolvedJsonContent)
+            obj = yamlReader.readValue(newContent, Any::class.java)
+        } else {
+            val ymlSourceFile = getYmlSourceFile(k8sConfigLocation)
+            obj = yamlReader.readValue(ymlSourceFile, Any::class.java)
+        }
         val jsonWriter = ObjectMapper()
         return jsonWriter.convertValue(obj)
     }
 
+    private fun templateValues(templateFile: File, params: JsonNode): String {
+        val fileContent = templateFile.bufferedReader().readText()
+        return BlueprintVelocityTemplateService.generateContent(
+            fileContent,
+            params, true
+        )
+    }
+
     private fun getYmlSourceFile(templateValueSource: String): File {
         val bluePrintBasePath: String = bluePrintRuntimeService.bluePrintContext().rootPath
         val profileSourceFileFolderPath: Path = Paths.get(bluePrintBasePath.plus(File.separator).plus(templateValueSource))
@@ -205,6 +261,6 @@ open class K8sConfigValueComponent(
     }
 
     private enum class OperationType {
-        CREATE, UPDATE, ROLLBACK
+        CREATE, UPDATE, DELETE
     }
 }
diff --git a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sConfigValueResponse.kt b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sConfigValueResponse.kt
index 823009fbb..0106b81a4 100644
--- a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sConfigValueResponse.kt
+++ b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sConfigValueResponse.kt
@@ -1,29 +1,39 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.k8s.instance
 
+import com.fasterxml.jackson.annotation.JsonAlias
 import com.fasterxml.jackson.annotation.JsonProperty
 
 class K8sConfigValueResponse {
-
     @get:JsonProperty("rb-name")
     var rbName: String? = null
 
     @get:JsonProperty("rb-version")
     var rbVersion: String? = null
 
+    @get:JsonProperty("instance-id")
+    var instanceId: String? = null
+
     @get:JsonProperty("profile-name")
     var profileName: String? = null
 
+    @get:JsonProperty("description")
+    var description: String? = null
+
     @get:JsonProperty("template-name")
     var templateName: String? = null
 
     @get:JsonProperty("config-name")
     var configName: String? = null
 
-    @get:JsonProperty("config-name")
-    var configVersion: String? = null
+    @get:JsonProperty("config-version")
+    @get:JsonAlias("config-verion")
+    var configVersion: Integer? = null
+
+    @get:JsonProperty("values")
+    var values: Map<String, Object>? = null
 
     override fun toString(): String {
-        return "$rbName:$rbVersion:$profileName:$templateName:$configName:$configVersion"
+        return "$templateName:$configName"
     }
 
     override fun equals(other: Any?): Boolean {
diff --git a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sPluginInstanceApi.kt b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sPluginInstanceApi.kt
index 7663699aa..7834c050d 100644
--- a/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sPluginInstanceApi.kt
+++ b/ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sPluginInstanceApi.kt
@@ -121,14 +121,24 @@ class K8sPluginInstanceApi(
         }
     }
 
-    fun queryInstanceStatus(instanceId: String, kind: String, apiVersion: String, name: String?, labels: String?): K8sRbInstanceStatus? {
+    fun queryInstanceStatus(
+        instanceId: String,
+        kind: String,
+        apiVersion: String,
+        name: String? = null,
+        labels: Map<String, String>? = null
+    ): K8sRbInstanceStatus? {
         val rbInstanceService = K8sRbInstanceRestClient(k8sConfiguration, instanceId)
         try {
             var path: String = "/query?ApiVersion=$apiVersion&Kind=$kind"
             if (name != null)
                 path = path.plus("&Name=$name")
-            if (labels != null)
-                path = path.plus("&Labels=$labels")
+            if (labels != null && labels.isNotEmpty()) {
+                path = path.plus("&Labels=")
+                for ((name, value) in labels)
+                    path = path.plus("$name%3D$value,")
+                path = path.trimEnd(',')
+            }
             val result: BlueprintWebClientService.WebClientResponse<String> = rbInstanceService.exchangeResource(
                 GET.name,
                 path,
@@ -240,7 +250,7 @@ class K8sPluginInstanceApi(
             } else
                 throw BlueprintProcessorException(result.body)
         } catch (e: Exception) {
-            log.error("Caught exception trying to get k8s rb instance")
+            log.error("Caught exception trying to create config instance")
             throw BlueprintProcessorException("${e.message}")
         }
     }
@@ -262,7 +272,7 @@ class K8sPluginInstanceApi(
             } else
                 throw BlueprintProcessorException(result.body)
         } catch (e: Exception) {
-            log.error("Caught exception trying to get k8s rb instance")
+            log.error("Caught exception trying to edit config instance")
             throw BlueprintProcessorException("${e.message}")
         }
     }
@@ -283,6 +293,45 @@ class K8sPluginInstanceApi(
         }
     }
 
+    fun getConfigurationValues(instanceId: String, configName: String): K8sConfigValueResponse? {
+        val rbInstanceService = K8sRbInstanceRestClient(k8sConfiguration, instanceId)
+        try {
+            val result: BlueprintWebClientService.WebClientResponse<String> = rbInstanceService.exchangeResource(
+                GET.name,
+                "/config/$configName",
+                ""
+            )
+            log.debug(result.toString())
+            return if (result.status in 200..299) {
+                val parsedObject: K8sConfigValueResponse? = JacksonUtils.readValue(
+                    result.body, K8sConfigValueResponse::class.java
+                )
+                parsedObject
+            } else
+                throw BlueprintProcessorException(result.body)
+        } catch (e: Exception) {
+            log.error("Caught exception trying to get config instance")
+            throw BlueprintProcessorException("${e.message}")
+        }
+    }
+
+    fun deleteConfigurationValues(instanceId: String, configName: String) {
+        val rbInstanceService = K8sRbInstanceRestClient(k8sConfiguration, instanceId)
+        try {
+            val result: BlueprintWebClientService.WebClientResponse<String> = rbInstanceService.exchangeResource(
+                DELETE.name,
+                "/config/$configName",
+                ""
+            )
+            log.debug(result.toString())
+            if (result.status !in 200..299)
+                throw BlueprintProcessorException(result.body)
+        } catch (e: Exception) {
+            log.error("Caught exception trying to delete config instance")
+            throw BlueprintProcessorException("${e.message}")
+        }
+    }
+
     fun rollbackConfigurationValues(instanceId: String): K8sConfigValueResponse? {
         val rbInstanceService = K8sRbInstanceRestClient(k8sConfiguration, instanceId)
         try {
@@ -305,7 +354,7 @@ class K8sPluginInstanceApi(
         }
     }
 
-    fun createConfigurationValues(instanceId: String): K8sConfigValueResponse? {
+    fun tagConfigurationValues(instanceId: String): K8sConfigValueResponse? {
         val rbInstanceService = K8sRbInstanceRestClient(k8sConfiguration, instanceId)
         try {
             val result: BlueprintWebClientService.WebClientResponse<String> = rbInstanceService.exchangeResource(
-- 
cgit 1.2.3-korg