Loading pom.xml +4 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,10 @@ <artifactId>org.etsi.osl.model.tmf</artifactId> <version>${org.etsi.osl.model.tmf.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <build> Loading src/main/java/org/etsi/osl/secretcontroller/CatalogClient.java +14 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ public class CatalogClient { @Value("${topics.CATALOG_UPD_SERVICE}") private String CATALOG_UPD_SERVICE; @Value("${topics.CATALOG_UPD_RESOURCE}") private String CATALOG_UPD_RESOURCE; @Autowired public CatalogClient(JmsClient jmsClient, ObjectMapper objectMapper) { this.jmsClient = jmsClient; Loading @@ -32,4 +35,15 @@ public class CatalogClient { jmsClient.destination(CATALOG_UPD_SERVICE) .send(payload, map); } public void updateResource(String resourceId, org.etsi.osl.tmf.ri639.model.ResourceUpdate resourceUpdate) { final var map = new HashMap<String, Object>(); map.put("resourceId", resourceId); map.put("triggerServiceActionQueue", false); final var payload = this.objectMapper.writeValueAsString(resourceUpdate); jmsClient.destination(CATALOG_UPD_RESOURCE) .send(payload, map); } } src/main/java/org/etsi/osl/secretcontroller/ResourceRulesService.java 0 → 100644 +114 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller; import org.etsi.osl.secretcontroller.config.RulesConfig; import org.etsi.osl.secretcontroller.rules.CharacteristicRule; import org.etsi.osl.secretcontroller.rules.ResourceRule; import org.etsi.osl.secretcontroller.rules.RuleEvaluatorService; import org.etsi.osl.tmf.ri639.model.Characteristic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import tools.jackson.core.exc.StreamReadException; import tools.jackson.databind.JsonNode; import tools.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; import java.util.Optional; @Service public class ResourceRulesService { private static final Logger log = LoggerFactory.getLogger(ResourceRulesService.class); private final RulesConfig rulesConfig; private final RuleEvaluatorService ruleEvaluatorService; private final ObjectMapper mapper; @Autowired public ResourceRulesService(RulesConfig rulesConfig, RuleEvaluatorService ruleEvaluatorService, ObjectMapper mapper) { this.rulesConfig = rulesConfig; this.ruleEvaluatorService = ruleEvaluatorService; this.mapper = mapper; } public Optional<ResourceRulesApplier> getResourceRules(org.etsi.osl.tmf.ri639.model.Resource resource) { final var cat = resource.getCategory(); final var rule = this.rulesConfig.getResourceRules().get(cat); if (rule == null) return Optional.empty(); return Optional.of(new ResourceRulesApplier(this.mapper, this.ruleEvaluatorService, resource, rule)); } public static class ResourceRulesApplier { private final ResourceRule rule; private final RuleEvaluatorService ruleEvaluatorService; private final Map<String, CharacteristicRule> extraRules = new HashMap<>(); public ResourceRulesApplier(ObjectMapper mapper, RuleEvaluatorService ruleEvaluatorService, org.etsi.osl.tmf.ri639.model.Resource resource, ResourceRule rule) { this.rule = rule; this.ruleEvaluatorService = ruleEvaluatorService; if (!rule.isKubernetesSecret()) return; // Kubernetes secret extra handling final var rawSecret = resource.getResourceCharacteristicByName("json").getValue().getValue(); final JsonNode json; try { json = mapper.readTree(rawSecret); } catch (StreamReadException e) { // If reading fails the secret most likely has already been erased log.debug(e.getMessage()); return; } final var secretData = json.get("data"); // The secret may have already been erased if (secretData == null || !secretData.isObject()) return; final var replaceRule = new CharacteristicRule(); replaceRule.setAction(SecretApplyResult.Action.Replace); replaceRule.setBase64Decode(true); // Convert all characteristics with secret data into secrets for (final var field : secretData.propertyNames()) this.extraRules.put(field, replaceRule); final var eraseRule = new CharacteristicRule(); eraseRule.setAction(SecretApplyResult.Action.Erase); // All these fields contain the secret data in one way or another and must be erased this.extraRules.put("data", eraseRule); this.extraRules.put("json", eraseRule); this.extraRules.put("metadata", eraseRule); } public SecretApplyResult saveCharacteristic(Characteristic characteristic) { final var name = characteristic.getName(); final var extraRule = this.extraRules.get(name); if (extraRule != null) return this.ruleEvaluatorService.evaluateRule(characteristic.getValue().getValue(), extraRule); for (final var cRule : this.rule.getCharacteristics()) { final var m = cRule.getMatch().matcher(name); if (!m.matches()) continue; final var value = characteristic.getValue().getValue(); return this.ruleEvaluatorService.evaluateRule(value, cRule); } return SecretApplyResult.ignore(); } } } src/main/java/org/etsi/osl/secretcontroller/SecretApplyResult.java 0 → 100644 +35 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller; public class SecretApplyResult { public final Action action; private final String value; private SecretApplyResult(Action action, String value) { this.action = action; this.value = value; } public static SecretApplyResult replace(String value) { return new SecretApplyResult(Action.Replace, value); } public static SecretApplyResult erase() { return new SecretApplyResult(Action.Erase, null); } public static SecretApplyResult ignore() { return new SecretApplyResult(Action.Ignore, null); } public String getValue() { if (this.action != Action.Replace) throw new IllegalStateException("Value is only available when replacing"); return this.value; } public enum Action { Replace, Erase, Ignore, } } src/main/java/org/etsi/osl/secretcontroller/ServiceRulesService.java 0 → 100644 +57 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller; import org.etsi.osl.secretcontroller.config.RulesConfig; import org.etsi.osl.secretcontroller.rules.RuleEvaluatorService; import org.etsi.osl.secretcontroller.rules.ServiceRule; import org.etsi.osl.tmf.common.model.service.Characteristic; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Optional; @Service public class ServiceRulesService { private final RulesConfig rulesConfig; private final RuleEvaluatorService ruleEvaluatorService; @Autowired public ServiceRulesService(RulesConfig rulesConfig, RuleEvaluatorService ruleEvaluatorService) { this.rulesConfig = rulesConfig; this.ruleEvaluatorService = ruleEvaluatorService; } public Optional<ServiceRulesApplier> getServiceRules(org.etsi.osl.tmf.sim638.model.Service svc) { final var name = svc.getName(); final var rule = this.rulesConfig.getServiceRules().get(name); if (rule == null) return Optional.empty(); return Optional.of(new ServiceRulesApplier(this.ruleEvaluatorService, rule)); } public static class ServiceRulesApplier { private final ServiceRule rule; private final RuleEvaluatorService ruleEvaluatorService; public ServiceRulesApplier(RuleEvaluatorService ruleEvaluatorService, ServiceRule rule) { this.rule = rule; this.ruleEvaluatorService = ruleEvaluatorService; } public SecretApplyResult saveCharacteristic(Characteristic characteristic) { final var name = characteristic.getName(); for (final var cRule : this.rule.characteristics()) { final var m = cRule.getMatch().matcher(name); if (!m.matches()) continue; var value = characteristic.getValue().getValue(); return this.ruleEvaluatorService.evaluateRule(value, cRule); } return SecretApplyResult.ignore(); } } } Loading
pom.xml +4 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,10 @@ <artifactId>org.etsi.osl.model.tmf</artifactId> <version>${org.etsi.osl.model.tmf.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <build> Loading
src/main/java/org/etsi/osl/secretcontroller/CatalogClient.java +14 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ public class CatalogClient { @Value("${topics.CATALOG_UPD_SERVICE}") private String CATALOG_UPD_SERVICE; @Value("${topics.CATALOG_UPD_RESOURCE}") private String CATALOG_UPD_RESOURCE; @Autowired public CatalogClient(JmsClient jmsClient, ObjectMapper objectMapper) { this.jmsClient = jmsClient; Loading @@ -32,4 +35,15 @@ public class CatalogClient { jmsClient.destination(CATALOG_UPD_SERVICE) .send(payload, map); } public void updateResource(String resourceId, org.etsi.osl.tmf.ri639.model.ResourceUpdate resourceUpdate) { final var map = new HashMap<String, Object>(); map.put("resourceId", resourceId); map.put("triggerServiceActionQueue", false); final var payload = this.objectMapper.writeValueAsString(resourceUpdate); jmsClient.destination(CATALOG_UPD_RESOURCE) .send(payload, map); } }
src/main/java/org/etsi/osl/secretcontroller/ResourceRulesService.java 0 → 100644 +114 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller; import org.etsi.osl.secretcontroller.config.RulesConfig; import org.etsi.osl.secretcontroller.rules.CharacteristicRule; import org.etsi.osl.secretcontroller.rules.ResourceRule; import org.etsi.osl.secretcontroller.rules.RuleEvaluatorService; import org.etsi.osl.tmf.ri639.model.Characteristic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import tools.jackson.core.exc.StreamReadException; import tools.jackson.databind.JsonNode; import tools.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; import java.util.Optional; @Service public class ResourceRulesService { private static final Logger log = LoggerFactory.getLogger(ResourceRulesService.class); private final RulesConfig rulesConfig; private final RuleEvaluatorService ruleEvaluatorService; private final ObjectMapper mapper; @Autowired public ResourceRulesService(RulesConfig rulesConfig, RuleEvaluatorService ruleEvaluatorService, ObjectMapper mapper) { this.rulesConfig = rulesConfig; this.ruleEvaluatorService = ruleEvaluatorService; this.mapper = mapper; } public Optional<ResourceRulesApplier> getResourceRules(org.etsi.osl.tmf.ri639.model.Resource resource) { final var cat = resource.getCategory(); final var rule = this.rulesConfig.getResourceRules().get(cat); if (rule == null) return Optional.empty(); return Optional.of(new ResourceRulesApplier(this.mapper, this.ruleEvaluatorService, resource, rule)); } public static class ResourceRulesApplier { private final ResourceRule rule; private final RuleEvaluatorService ruleEvaluatorService; private final Map<String, CharacteristicRule> extraRules = new HashMap<>(); public ResourceRulesApplier(ObjectMapper mapper, RuleEvaluatorService ruleEvaluatorService, org.etsi.osl.tmf.ri639.model.Resource resource, ResourceRule rule) { this.rule = rule; this.ruleEvaluatorService = ruleEvaluatorService; if (!rule.isKubernetesSecret()) return; // Kubernetes secret extra handling final var rawSecret = resource.getResourceCharacteristicByName("json").getValue().getValue(); final JsonNode json; try { json = mapper.readTree(rawSecret); } catch (StreamReadException e) { // If reading fails the secret most likely has already been erased log.debug(e.getMessage()); return; } final var secretData = json.get("data"); // The secret may have already been erased if (secretData == null || !secretData.isObject()) return; final var replaceRule = new CharacteristicRule(); replaceRule.setAction(SecretApplyResult.Action.Replace); replaceRule.setBase64Decode(true); // Convert all characteristics with secret data into secrets for (final var field : secretData.propertyNames()) this.extraRules.put(field, replaceRule); final var eraseRule = new CharacteristicRule(); eraseRule.setAction(SecretApplyResult.Action.Erase); // All these fields contain the secret data in one way or another and must be erased this.extraRules.put("data", eraseRule); this.extraRules.put("json", eraseRule); this.extraRules.put("metadata", eraseRule); } public SecretApplyResult saveCharacteristic(Characteristic characteristic) { final var name = characteristic.getName(); final var extraRule = this.extraRules.get(name); if (extraRule != null) return this.ruleEvaluatorService.evaluateRule(characteristic.getValue().getValue(), extraRule); for (final var cRule : this.rule.getCharacteristics()) { final var m = cRule.getMatch().matcher(name); if (!m.matches()) continue; final var value = characteristic.getValue().getValue(); return this.ruleEvaluatorService.evaluateRule(value, cRule); } return SecretApplyResult.ignore(); } } }
src/main/java/org/etsi/osl/secretcontroller/SecretApplyResult.java 0 → 100644 +35 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller; public class SecretApplyResult { public final Action action; private final String value; private SecretApplyResult(Action action, String value) { this.action = action; this.value = value; } public static SecretApplyResult replace(String value) { return new SecretApplyResult(Action.Replace, value); } public static SecretApplyResult erase() { return new SecretApplyResult(Action.Erase, null); } public static SecretApplyResult ignore() { return new SecretApplyResult(Action.Ignore, null); } public String getValue() { if (this.action != Action.Replace) throw new IllegalStateException("Value is only available when replacing"); return this.value; } public enum Action { Replace, Erase, Ignore, } }
src/main/java/org/etsi/osl/secretcontroller/ServiceRulesService.java 0 → 100644 +57 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller; import org.etsi.osl.secretcontroller.config.RulesConfig; import org.etsi.osl.secretcontroller.rules.RuleEvaluatorService; import org.etsi.osl.secretcontroller.rules.ServiceRule; import org.etsi.osl.tmf.common.model.service.Characteristic; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Optional; @Service public class ServiceRulesService { private final RulesConfig rulesConfig; private final RuleEvaluatorService ruleEvaluatorService; @Autowired public ServiceRulesService(RulesConfig rulesConfig, RuleEvaluatorService ruleEvaluatorService) { this.rulesConfig = rulesConfig; this.ruleEvaluatorService = ruleEvaluatorService; } public Optional<ServiceRulesApplier> getServiceRules(org.etsi.osl.tmf.sim638.model.Service svc) { final var name = svc.getName(); final var rule = this.rulesConfig.getServiceRules().get(name); if (rule == null) return Optional.empty(); return Optional.of(new ServiceRulesApplier(this.ruleEvaluatorService, rule)); } public static class ServiceRulesApplier { private final ServiceRule rule; private final RuleEvaluatorService ruleEvaluatorService; public ServiceRulesApplier(RuleEvaluatorService ruleEvaluatorService, ServiceRule rule) { this.rule = rule; this.ruleEvaluatorService = ruleEvaluatorService; } public SecretApplyResult saveCharacteristic(Characteristic characteristic) { final var name = characteristic.getName(); for (final var cRule : this.rule.characteristics()) { final var m = cRule.getMatch().matcher(name); if (!m.matches()) continue; var value = characteristic.getValue().getValue(); return this.ruleEvaluatorService.evaluateRule(value, cRule); } return SecretApplyResult.ignore(); } } }