diff --git a/src/main/java/org/etsi/osl/osom/lcm/LcmBaseExecutor.java b/src/main/java/org/etsi/osl/osom/lcm/LcmBaseExecutor.java index fbe909d3890cda193653f99f58d8c1837f349567..39aea66b32d44685f160eecc9fdf6430048fe7c9 100644 --- a/src/main/java/org/etsi/osl/osom/lcm/LcmBaseExecutor.java +++ b/src/main/java/org/etsi/osl/osom/lcm/LcmBaseExecutor.java @@ -150,14 +150,23 @@ public abstract class LcmBaseExecutor { if (c.getName().equals(charName)) { if (c.getValue() != null) { if (c.getValue().getValue() != null) { + // Unseal secrets as needed + if (c.getValueType().equals(EValueType.SECRET.getValue())) { + final var secretsClient = this.vars.getServiceOrderManager().getSecretsClient(); + if (secretsClient.isPresent()) { + c.getValue().setValue( + secretsClient.get().unseal(c.getValue().getValue(), c.getName())); + } + } + return Optional.of(c); } } } } } - Characteristic z = null; - return Optional.ofNullable(z); + + return Optional.empty(); } public void setCharValFromStringType(String charName, String newValue) { diff --git a/src/main/java/org/etsi/osl/osom/lcm/SecretsClient.java b/src/main/java/org/etsi/osl/osom/lcm/SecretsClient.java new file mode 100644 index 0000000000000000000000000000000000000000..6912c7dd3b33b751c0e8773bc32dbd1a0f97584a --- /dev/null +++ b/src/main/java/org/etsi/osl/osom/lcm/SecretsClient.java @@ -0,0 +1,63 @@ +package org.etsi.osl.osom.lcm; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.camel.ProducerTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.stereotype.Service; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + + +@Service +@ConditionalOnExpression("${SECRETS_CONTROLLER_ENABLE:false}") +public class SecretsClient { + + private static final transient Log logger = LogFactory.getLog( SecretsClient.class.getName() ); + + private final ProducerTemplate producerTemplate; + + private final String unsealSecretQueue; + + private final ObjectMapper mapper = new ObjectMapper(); + + @Autowired + public SecretsClient( + ProducerTemplate producerTemplate, + @Value("${SECRETS_CHARACTERISTIC_UNSEAL}") String unsealSecretQueue + ) { + this.producerTemplate = producerTemplate; + this.unsealSecretQueue = unsealSecretQueue; + } + + public String unseal(String uri, String characteristic) { + try { + final var cmd = new UnsealCharacteristicCommand(uri, characteristic); + final var payload = this.mapper.writeValueAsString(cmd); + final var responseRaw = this.producerTemplate.requestBody(this.unsealSecretQueue, payload, String.class); + + if (responseRaw == null || responseRaw.isEmpty()) { + return uri; + } + + final var response = this.mapper.readValue(responseRaw, String.class); + + if (response == null || response.isEmpty()) { + return uri; + } + + return response; + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } catch (Exception e) { + // controller is enabled by the request failed (no route, timeout, broker down) + logger.warn("Secrets controller did not respond for " + uri, e); + return uri; + } + } + + private record UnsealCharacteristicCommand(String secretURI, String characteristic) { + } +} diff --git a/src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java b/src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java index 91729c3d26c37543df3b2da0afd62d484eea62a3..9bcb0d5f19d4297c08adf58464234a7b24c3f938 100644 --- a/src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java +++ b/src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java @@ -20,11 +20,7 @@ package org.etsi.osl.osom.management; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; @@ -35,6 +31,7 @@ import org.etsi.osl.model.nfv.DeploymentDescriptor; import org.etsi.osl.model.nfv.NetworkServiceDescriptor; import org.etsi.osl.model.nfv.ScaleDescriptor; import org.etsi.osl.osom.lcm.ChatClient; +import org.etsi.osl.osom.lcm.SecretsClient; import org.etsi.osl.osom.serviceactions.NSActionRequestPayload; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJob; import org.etsi.osl.tmf.pm628.model.MeasurementCollectionJobFVO; @@ -208,7 +205,9 @@ public class ServiceOrderManager { @Autowired private ChatClient chatClient; - + @Autowired + private Optional secretsClient; + @Transactional public void processOrder(ServiceOrder serviceOrder) { @@ -1209,12 +1208,11 @@ public class ServiceOrderManager { } public ChatClient getChatClient(String agentName) { - + return chatClient; } - - - - + public Optional getSecretsClient() { + return this.secretsClient; + } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index baeda0136ce55d5294b0f944dfa4adccf9e7c1d0..ee80945aaf5f65a35118afc9a0792eabfd40381b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -128,4 +128,8 @@ CRD_PATCH_CR_REQ: "jms:queue:CRD.PATCH.CR_REQ" #TMF628 ACTIONS PM_MEASUREMENT_COLLECTION_JOB_ADD: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.ADD" -PM_MEASUREMENT_COLLECTION_JOB_UPDATE: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.UPDATE" \ No newline at end of file +PM_MEASUREMENT_COLLECTION_JOB_UPDATE: "jms:queue:PM.MEASUREMENTCOLLECTIONJOB.UPDATE" + +# Secrets controller ACTIONS +SECRETS_CONTROLLER_ENABLE: false +SECRETS_CHARACTERISTIC_UNSEAL: "jms:queue:SECRETS.CHARACTERISTIC.UNSEAL?exchangePattern=InOut"