diff --git a/sermant-injector/src/main/java/com/huaweicloud/sermant/injection/controller/SermantInjectorController.java b/sermant-injector/src/main/java/com/huaweicloud/sermant/injection/controller/SermantInjectorController.java index f5c3a36634..f1b0fbe4d3 100644 --- a/sermant-injector/src/main/java/com/huaweicloud/sermant/injection/controller/SermantInjectorController.java +++ b/sermant-injector/src/main/java/com/huaweicloud/sermant/injection/controller/SermantInjectorController.java @@ -70,6 +70,10 @@ public class SermantInjectorController { private static final String VOLUMES_PATH = "volumes"; + private static final String METADATA_PATH = "metadata"; + + private static final String ANNOTATION_PATH = "annotations"; + private static final String VOLUMES_INJECT_PATH = PATH_SEPARATOR + SPEC_PATH + PATH_SEPARATOR + VOLUMES_PATH; private static final String REQUEST_PATH = "request"; @@ -174,6 +178,8 @@ public class SermantInjectorController { private static final String SERMANT_SERVICE_CENTER_TYPE_KEY = "REGISTER_SERVICE_REGISTERTYPE"; + private static final String SERMANT_ENV_PREFIX = "env.sermant.io/"; + @Autowired private ObjectMapper om; @@ -240,6 +246,11 @@ private Optional inject(ObjectNode body) { // 缓存容器的env setEnv(containersNode, containerEnv); + // 根据labels计算需要新增env + Map annotationEnv = new HashMap<>(); + JsonNode annotationNode = body.path(REQUEST_PATH).path(OBJECT_PATH).path(METADATA_PATH).path(ANNOTATION_PATH); + setEnvByMap(annotationNode, annotationEnv); + // 建一个json节点 ArrayNode arrayNode = om.createArrayNode(); @@ -265,7 +276,7 @@ private Optional inject(ObjectNode body) { injectEnvFrom(arrayNode, env, containerNode, containerPath); // 向容器新增env节点 - injectEnv(arrayNode, env, containerNode, containerPath); + injectEnv(arrayNode, env, containerNode, containerPath, annotationEnv); // 向容器新增volumeMounts节点 injectVolumeMounts(arrayNode, env, containerNode, containerPath); @@ -274,6 +285,27 @@ private Optional inject(ObjectNode body) { return Optional.of(arrayNode.toString()); } + /** + * 根据labels/annotations计算需要增加的环境变量,如下以labels为例: + * labels: + * env.sermant.io/[key1]:[value1] + * env.sermant.io/[key2]:[value2] + * 则在环境变量map中添加 key1:value1 和 key2:value2,共两个环境变量 + * 本函数本真不强制是否使用labels还是annotations,只需要srcMap代表label/annotations下的map即可。 + */ + private void setEnvByMap(JsonNode srcMap, Map tgtEnv) { + Iterator labelIter = srcMap.fieldNames(); + int prefixLength = SERMANT_ENV_PREFIX.length(); + while (labelIter.hasNext()) { + String labelName = labelIter.next(); + if (labelName.startsWith(SERMANT_ENV_PREFIX)) { + String envKey = labelName.substring(prefixLength); + String envValue = srcMap.findValue(labelName).textValue(); + tgtEnv.put(envKey, envValue); + } + } + } + private void setEnv(JsonNode containersPath, Map> containerEnv) { Iterator containerIterator = containersPath.elements(); int index = 0; @@ -416,7 +448,8 @@ private void injectEnvFrom(ArrayNode arrayNode, Map env, JsonNod configMapRefNode.put(NAME_KEY, configMap); } - private void injectEnv(ArrayNode arrayNode, Map env, JsonNode containerNode, String containerPath) { + private void injectEnv(ArrayNode arrayNode, Map env, JsonNode containerNode, String containerPath, + Map annotationEnv) { // 覆盖容器的env节点 ObjectNode envNode = arrayNode.addObject(); envNode.put(JSON_OPERATION_KEY, JSON_OPERATION_ADD); @@ -456,6 +489,12 @@ private void injectEnv(ArrayNode arrayNode, Map env, JsonNode co if (!StringUtils.hasText(env.get(SERMANT_SERVICE_CENTER_TYPE_KEY))) { addEnv(envArray, SERMANT_SERVICE_CENTER_TYPE_KEY, serviceType); } + + // 增加通过在 /metadata/annotations 上指定的env + // 这里默认,如果annotations中有新的设置,则覆盖原有的env设置。 + for (Map.Entry entry : annotationEnv.entrySet()) { + addEnv(envArray, entry.getKey(), entry.getValue()); + } } private void injectVolumeMounts(ArrayNode arrayNode, Map env, JsonNode containerNode, diff --git a/sermant-injector/src/test/java/com/huaweicloud/sermant/injection/controller/SermantInjectorControllerTest.java b/sermant-injector/src/test/java/com/huaweicloud/sermant/injection/controller/SermantInjectorControllerTest.java index 0e276993d4..5e8f85798e 100644 --- a/sermant-injector/src/test/java/com/huaweicloud/sermant/injection/controller/SermantInjectorControllerTest.java +++ b/sermant-injector/src/test/java/com/huaweicloud/sermant/injection/controller/SermantInjectorControllerTest.java @@ -12,6 +12,9 @@ import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Iterator; /** * controller单元测试 @@ -33,5 +36,25 @@ public void injectSermant() throws IOException { Assertions.assertNotNull(response); Assertions.assertNotNull(response.getResponse()); Assertions.assertTrue(response.getResponse().isAllowed()); + + // Test Annotations environment feature. + byte[] decodedBytes = Base64.getDecoder().decode(response.getResponse().getPatch()); + String decodedString = new String(decodedBytes); + JsonNode rs = mapper.readTree(decodedString); + Iterator iter = rs.elements(); + while ( iter.hasNext() ) + { + JsonNode node = iter.next(); + if (node.get("path").asText().equals("/spec/containers/0/env")) + { + JsonNode jn = node.findValue("value"); + Assertions.assertTrue(jn.toString().indexOf("key1") > 0); + break; + } + if ( iter.hasNext() == false ) + { + Assertions.fail("should not get here"); + } + } } } \ No newline at end of file diff --git a/sermant-injector/src/test/resources/test.json b/sermant-injector/src/test/resources/test.json index 55f3e597f3..f274436404 100644 --- a/sermant-injector/src/test/resources/test.json +++ b/sermant-injector/src/test/resources/test.json @@ -46,7 +46,9 @@ "sermant-injection": "enabled" }, "annotations": { - "kubernetes.io/psp": "psp-global" + "kubernetes.io/psp": "psp-global", + "env.sermant.io/key1": "value1", + "env.sermant.io/key2": "value2" }, "ownerReferences": [ {