summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilip Krzywka <filip.krzywka@nokia.com>2019-03-20 14:53:57 +0100
committerFilip Krzywka <filip.krzywka@nokia.com>2019-03-21 13:33:27 +0100
commit1eed57cfa680a6dcce80f05d57e69d61e947bb69 (patch)
tree0a32aec375fbb8e6f5c134948098d18c78205cad
parentd418dd43e7812ea2cdebf188bf5ab51a997df90c (diff)
Make security keys optional with SSL disabled
Change-Id: I0b0dd63cb3609cddf6aa5e63cf0a0f147a0aca91 Issue-ID: DCAEGEN2-1340 Signed-off-by: Filip Krzywka <filip.krzywka@nokia.com>
-rw-r--r--sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt10
-rw-r--r--sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt4
-rw-r--r--sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapter.kt22
-rw-r--r--sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt75
-rw-r--r--sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityKeysAdapter.kt51
-rw-r--r--sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapterTest.kt77
-rw-r--r--sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapterTest.kt135
7 files changed, 300 insertions, 74 deletions
diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt
index 83f56924..90be3dbd 100644
--- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt
+++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt
@@ -52,8 +52,7 @@ internal class ConfigurationValidator {
val cbsConfiguration = partialConfig.cbs.bind()
.let { createCbsConfiguration(it).bind() }
- val securityConfiguration = partialConfig.security.bind()
- .let { createSecurityConfiguration(it) }
+ val securityConfiguration = SecurityConfiguration(partialConfig.security.bind().keys)
val collectorConfiguration = partialConfig.collector.bind()
.let { createCollectorConfig(it).bind() }
@@ -93,13 +92,6 @@ internal class ConfigurationValidator {
)
}
- private fun createSecurityConfiguration(partial: PartialSecurityConfig) =
- partial.keys
- .fold(
- { SecurityConfiguration(None) },
- { SecurityConfiguration(Some(it)) }
- )
-
private fun createCollectorConfig(partial: PartialCollectorConfig) =
partial.mapBinding {
CollectorConfiguration(
diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt
index 452b9215..1e77dde5 100644
--- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt
+++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt
@@ -27,7 +27,7 @@ import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.AddressAdapter
import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.OptionAdapter
import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.RouteAdapter
import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.RoutingAdapter
-import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.SecurityKeysAdapter
+import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.SecurityAdapter
import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys
import java.io.Reader
import java.net.InetSocketAddress
@@ -42,7 +42,7 @@ internal class FileConfigurationReader {
.registerTypeAdapter(Route::class.java, RouteAdapter())
.registerTypeAdapter(Routing::class.java, RoutingAdapter())
.registerTypeAdapter(Option::class.java, OptionAdapter())
- .registerTypeAdapter(SecurityKeys::class.java, SecurityKeysAdapter())
+ .registerTypeAdapter(PartialSecurityConfig::class.java, SecurityAdapter())
.create()
fun loadConfig(input: Reader): PartialConfiguration =
diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapter.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapter.kt
index 6d20da4a..255be03a 100644
--- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapter.kt
+++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapter.kt
@@ -22,10 +22,10 @@ package org.onap.dcae.collectors.veshv.config.impl.gsonadapters
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
+import com.google.gson.JsonParseException
import java.lang.reflect.Type
import java.net.InetSocketAddress
-
/**
* @author Pawel Biniek <pawel.biniek@nokia.com>
* @since February 2019
@@ -34,17 +34,15 @@ internal class AddressAdapter : JsonDeserializer<InetSocketAddress> {
override fun deserialize(
json: JsonElement,
typeOfT: Type,
- context: JsonDeserializationContext?): InetSocketAddress
- {
- val portStart = json.asString.lastIndexOf(":")
- if (portStart > 0) {
- val address = json.asString.substring(0, portStart)
- val port = json.asString.substring(portStart + 1)
- return InetSocketAddress(address, port.toInt())
- } else throw InvalidAddressException("Cannot parse '" + json.asString + "' to address")
- }
+ context: JsonDeserializationContext): InetSocketAddress {
+ val portStart = json.asString.lastIndexOf(":")
+ if (portStart > 0) {
+ val address = json.asString.substring(0, portStart)
+ val port = json.asString.substring(portStart + 1)
+ return InetSocketAddress(address, port.toInt())
+ } else throw InvalidAddressException("Cannot parse '" + json.asString + "' to address")
+ }
- class InvalidAddressException(reason:String) : RuntimeException(reason)
+ class InvalidAddressException(reason: String) : RuntimeException(reason)
}
-
diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt
new file mode 100644
index 00000000..859fd700
--- /dev/null
+++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt
@@ -0,0 +1,75 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dcae.collectors.veshv.config.impl.gsonadapters
+
+import arrow.core.Option
+import com.google.gson.JsonDeserializationContext
+import com.google.gson.JsonDeserializer
+import com.google.gson.JsonElement
+import com.google.gson.JsonObject
+import org.onap.dcae.collectors.veshv.config.impl.PartialSecurityConfig
+import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeys
+import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeysStore
+import org.onap.dcaegen2.services.sdk.security.ssl.Passwords
+import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys
+import java.io.File
+import java.lang.reflect.Type
+
+/**
+ * @author Pawel Biniek <pawel.biniek@nokia.com>
+ * @since March 2019
+ */
+internal class SecurityAdapter : JsonDeserializer<PartialSecurityConfig> {
+
+ override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext?) =
+ json.asJsonObject.let { security ->
+ if (security.entrySet().isEmpty() || hasSslDisableSet(security)) {
+ PartialSecurityConfig(Option.empty())
+ } else {
+ PartialSecurityConfig(Option.just(security.securityKeys(::asImmutableSecurityKeys)))
+ }
+ }
+
+ private fun hasSslDisableSet(security: JsonObject) =
+ security.has(SSL_DISABLE_KEY) && security[SSL_DISABLE_KEY].asBoolean
+
+ private fun JsonObject.securityKeys(f: (JsonObject) -> SecurityKeys) = f(getAsJsonObject(KEYS_OBJECT_KEY))
+
+ private fun asImmutableSecurityKeys(keys: JsonObject) = ImmutableSecurityKeys.builder()
+ .keyStore(ImmutableSecurityKeysStore.of(
+ File(keys[KEY_STORE_FILE_KEY].asString).toPath()))
+ .keyStorePassword(
+ Passwords.fromString(keys[KEY_STORE_PASSWORD_KEY].asString))
+ .trustStore(ImmutableSecurityKeysStore.of(
+ File(keys[TRUST_STORE_FILE_KEY].asString).toPath()))
+ .trustStorePassword(
+ Passwords.fromString(keys[TRUST_STORE_PASSWORD_KEY].asString))
+ .build()
+
+ companion object {
+ private val SSL_DISABLE_KEY = "sslDisable"
+ private val KEYS_OBJECT_KEY = "keys"
+ private val KEY_STORE_FILE_KEY = "keyStoreFile"
+ private val KEY_STORE_PASSWORD_KEY = "keyStorePassword"
+ private val TRUST_STORE_FILE_KEY = "trustStoreFile"
+ private val TRUST_STORE_PASSWORD_KEY = "trustStorePassword"
+ }
+}
+
diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityKeysAdapter.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityKeysAdapter.kt
deleted file mode 100644
index f9c0b4db..00000000
--- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityKeysAdapter.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * dcaegen2-collectors-veshv
- * ================================================================================
- * Copyright (C) 2019 NOKIA
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-package org.onap.dcae.collectors.veshv.config.impl.gsonadapters
-
-import com.google.gson.JsonDeserializationContext
-import com.google.gson.JsonDeserializer
-import com.google.gson.JsonElement
-import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeys
-import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeysStore
-import org.onap.dcaegen2.services.sdk.security.ssl.Passwords
-import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys
-import java.io.File
-import java.lang.reflect.Type
-
-/**
- * @author Pawel Biniek <pawel.biniek@nokia.com>
- * @since March 2019
- */
-internal class SecurityKeysAdapter : JsonDeserializer<SecurityKeys> {
- override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext?): SecurityKeys {
- val obj = json.asJsonObject
- return ImmutableSecurityKeys.builder()
- .keyStore(ImmutableSecurityKeysStore.of(
- File(obj["keyStoreFile"].asString).toPath()))
- .keyStorePassword(
- Passwords.fromString(obj["keyStorePassword"].asString))
- .trustStore(ImmutableSecurityKeysStore.of(
- File(obj["trustStoreFile"].asString).toPath()))
- .trustStorePassword(
- Passwords.fromString(obj["trustStorePassword"].asString))
- .build()
- }
-
-}
diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapterTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapterTest.kt
new file mode 100644
index 00000000..f70c4337
--- /dev/null
+++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/AddressAdapterTest.kt
@@ -0,0 +1,77 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dcae.collectors.veshv.config.impl.gsonadapters
+
+import com.google.gson.Gson
+import com.google.gson.JsonDeserializationContext
+import com.google.gson.JsonParseException
+import com.google.gson.reflect.TypeToken
+import com.nhaarman.mockitokotlin2.mock
+import org.assertj.core.api.Assertions.assertThat
+import org.jetbrains.spek.api.Spek
+import org.jetbrains.spek.api.dsl.describe
+import org.jetbrains.spek.api.dsl.given
+import org.jetbrains.spek.api.dsl.it
+import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.AddressAdapter.InvalidAddressException
+import java.lang.NumberFormatException
+import kotlin.test.assertFailsWith
+
+
+internal object AddressAdapterTest : Spek({
+
+ describe("deserialization") {
+ val gson = Gson()
+ val context = mock<JsonDeserializationContext>()
+ val addressAdapterType = TypeToken.get(AddressAdapter::class.java).type
+
+ val cut = AddressAdapter()
+
+ given("valid string") {
+ val address = "hostname:9000"
+ val json = gson.toJsonTree(address)
+
+ it("should return address") {
+ val deserialized = cut.deserialize(json, addressAdapterType, context)
+
+ assertThat(deserialized.hostName).isEqualTo("hostname")
+ assertThat(deserialized.port).isEqualTo(9000)
+ }
+ }
+
+ val invalidAddresses = mapOf(
+ Pair("missingPort", InvalidAddressException::class),
+ Pair("NaNPort:Hey", NumberFormatException::class),
+ Pair(":6036", InvalidAddressException::class))
+
+ invalidAddresses.forEach { address, exception ->
+ given("invalid address string: $address") {
+
+ val json = gson.toJsonTree(address)
+ it("should throw exception") {
+ assertFailsWith(exception) {
+ cut.deserialize(json, addressAdapterType, context)
+ }
+ }
+ }
+ }
+ }
+})
+
+
diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapterTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapterTest.kt
new file mode 100644
index 00000000..a466896b
--- /dev/null
+++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapterTest.kt
@@ -0,0 +1,135 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dcae.collectors.veshv.config.impl.gsonadapters
+
+import com.google.gson.JsonDeserializationContext
+import com.google.gson.JsonParser
+import com.google.gson.reflect.TypeToken
+import com.nhaarman.mockitokotlin2.mock
+import org.assertj.core.api.Assertions
+import org.jetbrains.spek.api.Spek
+import org.jetbrains.spek.api.dsl.describe
+import org.jetbrains.spek.api.dsl.given
+import org.jetbrains.spek.api.dsl.it
+
+internal object SecurityAdapterTest : Spek({
+
+ describe("deserialization") {
+ val gson = JsonParser()
+ val context = mock<JsonDeserializationContext>()
+ val someType = TypeToken.get(SecurityAdapter::class.java).type
+
+ val cut = SecurityAdapter()
+
+ given("empty security object") {
+ val json = gson.parse("{}")
+
+ it("should parse json to security configuration without keys") {
+ val deserialized = cut.deserialize(json, someType, context)
+
+ Assertions.assertThat(deserialized.keys.isEmpty()).isTrue()
+ }
+ }
+
+ given("valid security object with ssl disabled") {
+
+ given("security keys missing") {
+ val json = gson.parse(SECURITY_WITH_SSL_DISABLED_AND_KEYS_MISSING)
+
+ it("should parse json to security configuration without keys") {
+ val deserialized = cut.deserialize(json, someType, context)
+
+ Assertions.assertThat(deserialized.keys.isEmpty()).isTrue()
+ }
+ }
+
+ given("security keys provided") {
+ val json = gson.parse(SECURITY_WITH_SSL_DISABLED_AND_KEYS_PROVIDED)
+
+ it("should parse json to security configuration without keys") {
+ val deserialized = cut.deserialize(json, someType, context)
+
+ Assertions.assertThat(deserialized.keys.isEmpty()).isTrue()
+ }
+ }
+ }
+
+ given("valid security object with missing sslDisable key") {
+ val json = gson.parse(MISSING_SSL_DISABLE_ENTRY)
+
+ it("should return parse json to security configuration") {
+ val deserialized = cut.deserialize(json, someType, context)
+
+ Assertions.assertThat(deserialized.keys.isDefined()).isTrue()
+ }
+ }
+
+ given("valid security object with ssl enabled") {
+ val json = gson.parse(VALID_SECURITY_WITH_SSL_ENABLED)
+
+ it("should return parse json to security configuration") {
+ val deserialized = cut.deserialize(json, someType, context)
+
+ Assertions.assertThat(deserialized.keys.isDefined()).isTrue()
+ }
+ }
+ }
+})
+
+val SECURITY_WITH_SSL_DISABLED_AND_KEYS_MISSING = """
+{
+ "sslDisable": true
+}
+"""
+
+val SECURITY_WITH_SSL_DISABLED_AND_KEYS_PROVIDED = """
+{
+ "sslDisable": true,
+ "keys": {
+ "keyStoreFile": "test.ks.pkcs12",
+ "keyStorePassword": "changeMe",
+ "trustStoreFile": "trust.ks.pkcs12",
+ "trustStorePassword": "changeMeToo"
+ }
+}
+"""
+
+val MISSING_SSL_DISABLE_ENTRY = """
+{
+ "keys": {
+ "keyStoreFile": "test.ks.pkcs12",
+ "keyStorePassword": "changeMe",
+ "trustStoreFile": "trust.ks.pkcs12",
+ "trustStorePassword": "changeMeToo"
+ }
+}
+"""
+
+val VALID_SECURITY_WITH_SSL_ENABLED = """
+{
+ "sslDisable": false,
+ "keys": {
+ "keyStoreFile": "test.ks.pkcs12",
+ "keyStorePassword": "changeMe",
+ "trustStoreFile": "trust.ks.pkcs12",
+ "trustStorePassword": "changeMeToo"
+ }
+}
+"""