Bug fixes for config template and config value components 26/119626/1
authorLukasz Rajewski <lukasz.rajewski@orange.com>
Mon, 22 Mar 2021 21:43:23 +0000 (22:43 +0100)
committerLukasz Rajewski <lukasz.rajewski@orange.com>
Tue, 23 Mar 2021 14:47:43 +0000 (14:47 +0000)
Issue-ID: CCSDK-3232
Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com>
Change-Id: I817d83001a76ba480472c7aa2da15eba65b39c20
(cherry picked from commit 91c1deec281ece8aa72b2afd9cc68b2d63c38189)

components/model-catalog/definition-type/starter-type/artifact_type/artifact-k8sconfig-content.json [new file with mode: 0644]
components/model-catalog/definition-type/starter-type/node_type/component-k8s-config-value.json
ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/K8sPluginDefinitionApi.kt
ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigTemplateComponent.kt
ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/definition/template/K8sConfigValueComponent.kt
ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sConfigValueResponse.kt
ms/blueprintsprocessor/functions/k8s-connection-plugin/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/k8s/instance/K8sPluginInstanceApi.kt
ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BlueprintConstants.kt
ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BlueprintDSL.kt
ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BlueprintDSLTest.kt

diff --git a/components/model-catalog/definition-type/starter-type/artifact_type/artifact-k8sconfig-content.json b/components/model-catalog/definition-type/starter-type/artifact_type/artifact-k8sconfig-content.json
new file mode 100644 (file)
index 0000000..d001d05
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "description": "K8s Config Folder Artifact",
+  "version": "1.0.0",
+  "derived_from": "tosca.artifacts.Implementation"
+}
\ No newline at end of file
index 901f322..2249d16 100644 (file)
       "operations": {
         "process": {
           "inputs": {
-            "k8s-template-name": {
+            "k8s-rb-config-template-name": {
                 "description": "K8s template name",
                 "required": false,
                 "type": "string"
             },
-            "k8s-config-name": {
+            "k8s-rb-config-name": {
                 "description": "K8s config name",
                 "required": false,
                 "type": "string"
                 "required": false,
                 "type": "string"
             },
-            "k8s-rb-template-value-source": {
+            "k8s-rb-config-value-source": {
                 "description": "Location of value source in CBA",
                 "required": false,
                 "type": "string"
             },
-            "k8s-operation-type" : {
-                "required" : false,
-                "type" : "string",
-                "constraints" : [{
-                   "valid_values" : [ "create", "update", "rollback" ]
-                }],
-                "default" : "create"
+            "k8s-config-operation-type": {
+                "required": false,
+                "type": "string",
+                "constraints": [
+                  {
+                    "valid_values": [
+                      "create",
+                      "update",
+                      "delete"
+                    ]
+                  }
+              ],
+              "default": "create"
             },
             "artifact-prefix-names": {
                 "description": "Resource Assignment Artifact Prefix names",
index 05c3021..ae2d1f6 100644 (file)
@@ -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}")
index cb759e5..0944c23 100644 (file)
@@ -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
index 2e7b34e..34b6ea1 100644 (file)
@@ -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
     }
 }
index 823009f..0106b81 100644 (file)
@@ -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 {
index 7663699..7834c05 100644 (file)
@@ -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(
index cfe4360..256339c 100644 (file)
@@ -232,6 +232,7 @@ object BlueprintConstants {
     const val MODEL_TYPE_ARTIFACT_DIRECTED_GRAPH = "artifact-directed-graph"
     const val MODEL_TYPE_ARTIFACT_COMPONENT_JAR = "artifact-component-jar"
     const val MODEL_TYPE_ARTIFACT_K8S_PROFILE = "artifact-k8sprofile-content"
+    const val MODEL_TYPE_ARTIFACT_K8S_CONFIG = "artifact-k8sconfig-content"
 
     const val TOSCA_SPEC = "TOSCA"
 
index 503e070..81593c9 100644 (file)
@@ -327,6 +327,22 @@ fun BlueprintTypes.artifactTypeK8sProfileFolder(): ArtifactType {
     }
 }
 
+fun ServiceTemplateBuilder.artifactTypeK8sConfigFolder() {
+    val artifactType = BlueprintTypes.artifactTypeK8sConfigFolder()
+    if (this.artifactTypes == null) this.artifactTypes = hashMapOf()
+    this.artifactTypes!![artifactType.id!!] = artifactType
+}
+
+fun BlueprintTypes.artifactTypeK8sConfigFolder(): ArtifactType {
+    return artifactType(
+        id = BlueprintConstants.MODEL_TYPE_ARTIFACT_K8S_CONFIG,
+        version = BlueprintConstants.DEFAULT_VERSION_NUMBER,
+        derivedFrom = BlueprintConstants.MODEL_TYPE_ARTIFACT_TYPE_IMPLEMENTATION,
+        description = "K8s Config Folder Artifact"
+    ) {
+    }
+}
+
 @Deprecated("CDS won't support, use implerative workflow definitions.")
 fun BlueprintTypes.artifactTypeDirectedGraph(): ArtifactType {
     return artifactType(
index 5143c9d..57f671d 100644 (file)
@@ -111,6 +111,7 @@ class BlueprintDSLTest {
             artifactTypeMappingResource()
             artifactTypeComponentJar()
             artifactTypeK8sProfileFolder()
+            artifactTypeK8sConfigFolder()
 
             relationshipTypeConnectsTo()
             relationshipTypeDependsOn()