From: Jozsef Csongvai Date: Thu, 19 Dec 2019 16:05:33 +0000 (-0500) Subject: Refactoring log-protect for hiding sensitive data in logs X-Git-Tag: 0.7.0~102 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=0a7d68420e7b95dfffb043ebbe2f52ec24effae4;p=ccsdk%2Fcds.git Refactoring log-protect for hiding sensitive data in logs Issue-ID: CCSDK-2010 Signed-off-by: Jozsef Csongvai Change-Id: I72a4d8d49a202cea0fa1a200c7466300de1ff0b0 --- diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt index 0726d2871..c39933dc8 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt @@ -29,5 +29,4 @@ object ResourceResolutionConstants { const val RESOURCE_RESOLUTION_INPUT_OCCURRENCE = "occurrence" const val RESOURCE_RESOLUTION_INPUT_RESOURCE_ID = "resource-id" const val RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE = "resource-type" - const val RESOURCE_RESOLUTION_LOG_PROTECTED_METADATA = "log-protect" } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt index 14e60bc95..51e93a3c1 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt @@ -32,9 +32,11 @@ import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.common.ApplicationConstants.LOG_REDACTED import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.controllerblueprints.core.utils.PropertyDefinitionUtils.Companion.hasLogProtect import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition import org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils.BulkResourceSequencingUtils @@ -395,7 +397,8 @@ open class ResourceResolutionServiceImpl( if (resourceResolution.status == BluePrintConstants.STATUS_SUCCESS) { resourceAssignmentList.forEach { if (compareOne(resourceResolution, it)) { - log.info("Resource ({}) already resolve: value=({})", it.name, resourceResolution.value) + log.info("Resource ({}) already resolved: value=({})", it.name, + if (hasLogProtect(it.property)) LOG_REDACTED else resourceResolution.value) // Make sure to recreate value as per the defined type. val value = resourceResolution.value!!.asJsonType(it.property!!.type) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt index b818cc2b1..a813c00ca 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt @@ -31,6 +31,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType import org.onap.ccsdk.cds.controllerblueprints.core.checkFileExists import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.common.ApplicationConstants.LOG_REDACTED import org.onap.ccsdk.cds.controllerblueprints.core.isComplexType import org.onap.ccsdk.cds.controllerblueprints.core.isNotEmpty import org.onap.ccsdk.cds.controllerblueprints.core.isNullOrMissing @@ -40,6 +41,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.rootFieldsToMap import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonReactorUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.controllerblueprints.core.utils.PropertyDefinitionUtils.Companion.hasLogProtect import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition import org.slf4j.LoggerFactory @@ -159,9 +161,7 @@ class ResourceAssignmentUtils { val type = nullToEmpty(it.property?.type).toLowerCase() val value = useDefaultValueIfNull(it, rName) val valueToPrint = getValueToLog(metadata, value) - if (checkIfLogIsProtected(metadata)) { - containsLogProtected = true - } + containsLogProtected = hasLogProtect(metadata) logger.trace("Generating Resource name ($rName), type ($type), value ($valueToPrint)") root.set(rName, value) } @@ -593,25 +593,7 @@ class ResourceAssignmentUtils { return (outputKeyMapping.size == 1) } - fun getValueToLog(metadata: MutableMap?, value: Any): Any { - return if (checkIfLogIsProtected(metadata)) { - "******REDACTED******" - } else { - value - } - } - - private fun checkIfLogIsProtected(metadata: MutableMap?): Boolean { - var checkProtected = false - if (metadata != null && - metadata.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_LOG_PROTECTED_METADATA) - ) { - val protectedMetadata = metadata[ResourceResolutionConstants.RESOURCE_RESOLUTION_LOG_PROTECTED_METADATA] - if (protectedMetadata == "yes" || protectedMetadata == "y") { - checkProtected = true - } - } - return checkProtected - } + fun getValueToLog(metadata: MutableMap?, value: Any): Any = + if (hasLogProtect(metadata)) LOG_REDACTED else value } } diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt index 571f0a176..5aaf6ccd9 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt @@ -218,6 +218,8 @@ object BluePrintConstants { val USE_SCRIPT_COMPILE_CACHE: Boolean = (System.getenv("USE_SCRIPT_COMPILE_CACHE") ?: "true").toBoolean() + const val LOG_PROTECT: String = "log-protect" + /** Cluster Properties */ val CLUSTER_ENABLED = (System.getenv("CLUSTER_ENABLED") ?: "false").toBoolean() const val PROPERTY_CLUSTER_ID = "CLUSTER_ID" diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/common/ApplicationConstants.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/common/ApplicationConstants.kt index 66bc3b3cb..35f7ef184 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/common/ApplicationConstants.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/common/ApplicationConstants.kt @@ -20,4 +20,5 @@ object ApplicationConstants { const val ACTIVE_Y = "Y" const val ACTIVE_N = "N" const val ASDC_ARTIFACT_TYPE_SDNC_MODEL = "SDNC_MODEL" + const val LOG_REDACTED = "****REDACTED****" } diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt index a6d2de476..a7ed577dd 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt @@ -26,12 +26,14 @@ import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintError import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType +import org.onap.ccsdk.cds.controllerblueprints.core.common.ApplicationConstants.LOG_REDACTED import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition import org.onap.ccsdk.cds.controllerblueprints.core.returnNullIfMissing import org.onap.ccsdk.cds.controllerblueprints.core.rootFieldsToMap import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils +import org.onap.ccsdk.cds.controllerblueprints.core.utils.PropertyDefinitionUtils.Companion.hasLogProtect import org.slf4j.LoggerFactory import java.io.File @@ -452,7 +454,6 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl override fun setInputValue(propertyName: String, value: JsonNode) { val path = """${BluePrintConstants.PATH_INPUTS}${BluePrintConstants.PATH_DIVIDER}$propertyName""" - log.trace("setting input path ({}), values ({})", path, value) put(path, value) } @@ -594,34 +595,31 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl } override fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode) { - log.info("For workflow ($workflowName) driving input data from ($jsonNode)") + log.info("Deriving input data for workflow: ($workflowName)") + val dynamicInputPropertiesName = "$workflowName-properties" bluePrintContext.workflowByName(workflowName).inputs - ?.forEach { propertyName, property -> - if (propertyName != dynamicInputPropertiesName) { - val valueNode: JsonNode = - jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing() - ?: property.defaultValue - ?: NullNode.getInstance() - log.trace("Setting input data - attribute:($propertyName) value:($valueNode)") - setInputValue(propertyName, valueNode) - } - } + ?.filter { (propertyName, property) -> propertyName != dynamicInputPropertiesName } + ?.forEach { propertyName, property -> findAndSetInputValue(propertyName, property, jsonNode) } // Load Dynamic data Types jsonNode.get(dynamicInputPropertiesName)?.let { - bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName")?.properties - ?.forEach { propertyName, property -> - val valueNode: JsonNode = - it.at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing() - ?: property.defaultValue - ?: NullNode.getInstance() - log.trace("Setting input data - attribute:($propertyName) value:($valueNode)") - setInputValue(propertyName, valueNode) - } + bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName") + ?.properties + ?.forEach { propertyName, property -> findAndSetInputValue(propertyName, property, it) } } } + private fun findAndSetInputValue(propertyName: String, property: PropertyDefinition, jsonNode: JsonNode) { + val valueNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName) + .returnNullIfMissing() + ?: property.defaultValue + ?: NullNode.getInstance() + val loggableValue = if (hasLogProtect(property)) LOG_REDACTED else valueNode.toString() + log.info("Setting input data - attribute:($propertyName) value:($loggableValue)") + setInputValue(propertyName, valueNode) + } + override fun resolveWorkflowOutputs(workflowName: String): MutableMap { log.info("resolveWorkflowOutputs for workflow($workflowName)") val outputs = bluePrintContext.workflowByName(workflowName).outputs ?: mutableMapOf() diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/PropertyDefinitionUtils.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/PropertyDefinitionUtils.kt new file mode 100644 index 000000000..35f2f6d83 --- /dev/null +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/PropertyDefinitionUtils.kt @@ -0,0 +1,37 @@ +/* + * Copyright © 2019 Bell Canada. + * + * 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.controllerblueprints.core.utils + +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.LOG_PROTECT +import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition + +class PropertyDefinitionUtils { + companion object { + fun hasLogProtect(metadata: MutableMap?) = metadata?.get(LOG_PROTECT) + ?.let { + when (it.toLowerCase()) { + "true" -> true + "yes" -> true + "y" -> true + else -> false + } + } ?: false + + fun hasLogProtect(propertyDefinition: PropertyDefinition?) = propertyDefinition + ?.let { p -> hasLogProtect(p.metadata) } ?: false + } +} diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/PropertyDefinitionUtilsTest.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/PropertyDefinitionUtilsTest.kt new file mode 100644 index 000000000..83764c517 --- /dev/null +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/PropertyDefinitionUtilsTest.kt @@ -0,0 +1,68 @@ +/* + * Copyright © 2019 Bell Canada. + * + * 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.controllerblueprints.core.utils + +import org.junit.Test +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.LOG_PROTECT +import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition +import org.onap.ccsdk.cds.controllerblueprints.core.utils.PropertyDefinitionUtils.Companion.hasLogProtect +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class PropertyDefinitionUtilsTest { + + @Test + fun testLogProtectMetadata() { + val metadata = mutableMapOf() + + assertFalse { hasLogProtect(metadata) } + + metadata[LOG_PROTECT] = "true" + assertTrue { hasLogProtect(metadata) } + metadata.clear() + + metadata[LOG_PROTECT] = "yes" + assertTrue { hasLogProtect(metadata) } + metadata.clear() + + metadata[LOG_PROTECT] = "y" + assertTrue { hasLogProtect(metadata) } + metadata.clear() + + metadata[LOG_PROTECT] = "false" + assertFalse { hasLogProtect(metadata) } + metadata.clear() + + val nullMetadata: MutableMap? = null + assertFalse { hasLogProtect(nullMetadata) } + } + + @Test + fun testHasLogProtectPropertyDefinition() { + var propertyDefinition: PropertyDefinition? = null + assertFalse { hasLogProtect(propertyDefinition) } + + propertyDefinition = PropertyDefinition() + assertFalse { hasLogProtect(propertyDefinition) } + + val metadata = mutableMapOf() + metadata[LOG_PROTECT] = "TRUE" + propertyDefinition.metadata = metadata + + assertTrue { hasLogProtect(propertyDefinition) } + } +}