diff --git a/scripts/manifest_apply.sh b/scripts/manifest_apply.sh index efa70bb0..af36d9c9 100755 --- a/scripts/manifest_apply.sh +++ b/scripts/manifest_apply.sh @@ -7,3 +7,4 @@ kubectl config use-context $1 kubectl apply -f $2/*alerts.json kubectl apply -f $2/*hpa.json kubectl apply -f $2/*security_group.json +kubectl apply -f $2/*dynamic_configuration.json \ No newline at end of file diff --git a/src/main/java/com/navi/infra/portal/domain/manifest/DynamicConfig.java b/src/main/java/com/navi/infra/portal/domain/manifest/DynamicConfig.java new file mode 100644 index 00000000..02a77463 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/domain/manifest/DynamicConfig.java @@ -0,0 +1,18 @@ +package com.navi.infra.portal.domain.manifest; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +public class DynamicConfig implements Serializable { + private static final long serialVersionUID = 1613809242868628632L; + + private String fileName; + private String data; + +} diff --git a/src/main/java/com/navi/infra/portal/domain/manifest/Manifest.java b/src/main/java/com/navi/infra/portal/domain/manifest/Manifest.java index 65e01da6..ed158160 100644 --- a/src/main/java/com/navi/infra/portal/domain/manifest/Manifest.java +++ b/src/main/java/com/navi/infra/portal/domain/manifest/Manifest.java @@ -38,6 +38,10 @@ public class Manifest extends JsonEntity { @Column private String environment; + @Type(type = "jsonb") + @Column(columnDefinition = "jsonb") + private List dynamicConfiguration; + @OneToOne(mappedBy = "manifest", cascade = CascadeType.ALL) @JsonManagedReference private ExtraResources extraResources; diff --git a/src/main/java/com/navi/infra/portal/service/kubernetes/KubernetesManifestService.java b/src/main/java/com/navi/infra/portal/service/kubernetes/KubernetesManifestService.java index 28061d8f..45938e12 100644 --- a/src/main/java/com/navi/infra/portal/service/kubernetes/KubernetesManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/kubernetes/KubernetesManifestService.java @@ -69,6 +69,8 @@ public class KubernetesManifestService { 15, "apply"); CompletableFuture alerts = asyncApplyWithTimeoutInSecond(manifest, kManifestPath, "alerts", 15, "apply"); + CompletableFuture dynamicConfiguration = asyncApplyWithTimeoutInSecond(manifest, kManifestPath, + "dynamic_configuration", 15, "apply"); if (environment.equals("dev") || environment.equals("qa") || environment.equals("perf")) { applyCronHpaAutoscaler(manifest, kManifestPath, hpa, alerts); } else { diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 7f664a75..dae17f9d 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -1,7 +1,11 @@ package com.navi.infra.portal.service.manifest; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.navi.infra.portal.domain.manifest.DynamicConfig; import com.navi.infra.portal.domain.manifest.Manifest; import com.navi.infra.portal.dto.manifest.ManifestResponse; import com.navi.infra.portal.dto.manifest.VaultResponse; @@ -12,11 +16,14 @@ import com.navi.infra.portal.security.authorization.AuthorizationContext; import com.navi.infra.portal.service.kubernetes.KubernetesManifestService; import com.navi.infra.portal.util.manifest.ValidationUtils; import com.networknt.schema.ValidationMessage; + import java.io.IOException; +import java.lang.reflect.Type; import java.nio.charset.Charset; import java.util.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.text.StrSubstitutor; import org.apache.commons.text.StringSubstitutor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; @@ -136,7 +143,21 @@ public class ManifestService { newManifest.addRedactedValuesToSuperSecrets(); newManifest.setInfraVertical(portalVertical); if (newManifest.hasDeployment()) { - kubernetesManifestService.generateManifestsAndApply(newManifest, securityGroupChange, rolloutCurrentWeight); + ObjectMapper mapper = new ObjectMapper(); + String newJsonData = ""; + try{ + newJsonData = mapper.writeValueAsString(newManifest.getDynamicConfiguration()); + Map envMap = new HashMap<>(); + envMap = newManifest.getEnvironmentAsMap(); + String updatedDCJsonStr = StrSubstitutor.replace(newJsonData, envMap); + Type listType = new TypeToken>(){}.getType(); + List updatedDynamicConfig = new Gson().fromJson(updatedDCJsonStr, listType); + newManifest.setDynamicConfiguration(updatedDynamicConfig); + } catch (JsonProcessingException e) { + e.printStackTrace(); + }finally { + kubernetesManifestService.generateManifestsAndApply(newManifest, securityGroupChange, rolloutCurrentWeight); + } } else { log.info("Deployment not found for manifest {}", newManifest.fullName()); } diff --git a/src/main/resources/db/migration/V1.17__Add_dynamicConfig_field_manifest.sql b/src/main/resources/db/migration/V1.17__Add_dynamicConfig_field_manifest.sql new file mode 100644 index 00000000..b2677a34 --- /dev/null +++ b/src/main/resources/db/migration/V1.17__Add_dynamicConfig_field_manifest.sql @@ -0,0 +1 @@ +ALTER TABLE "public"."manifest" ADD COLUMN "dynamic_configuration" jsonb; \ No newline at end of file diff --git a/src/test/java/com/navi/infra/portal/service/ManifestServiceTest.java b/src/test/java/com/navi/infra/portal/service/ManifestServiceTest.java index 4c77f24a..ae864173 100644 --- a/src/test/java/com/navi/infra/portal/service/ManifestServiceTest.java +++ b/src/test/java/com/navi/infra/portal/service/ManifestServiceTest.java @@ -53,6 +53,25 @@ public class ManifestServiceTest extends ExternalIntegrationProvider { () -> JSONAssert.assertEquals(expectedManifestUpdateOutputJson, ActualManifestResponseJson, false)); } + @Test + @WithMockUser(value = "admin_user", username = "admin@navi.com", authorities = {"secret.write.dev", "secret.read.dev", + "manifest.write", "supersecret.write", "supersecret.read", "manifest.read", "manifest" + + ".write", "manifest.write.dev", "manifest.read.dev", "substitute.environment"}, password = "admin") + @Transactional + @DisplayName("Test Manifest Create and Update for dynamicConfig") + void ManifestCreateWithDynamicConfigTest() throws IOException { + JsonNode manifestData = readFileToJsonNode("fixtures/manifest/dev-testapp-dynamicConfig.json"); + JsonNode manifestNode = objectMapper.readTree(manifestData.toString()); + ManifestResponse manifestResponse = manifestService.createOrUpdate(manifestNode); + String ActualManifestResponseJson = manifestResponse.getManifest().convertToString(); + Manifest manifest = manifestService.fetchByNameAndEnvironment("testapp-dynamicConfig", "dev"); + String actualManifestJson = manifest.convertToString(); + String expectedManifestGetOutputJson = readFile("fixtures/manifest/expected_output/dev-testapp-dynamicConfig-get.json"); + String expectedManifestUpdateOutputJson = readFile("fixtures/manifest/expected_output/dev-testapp-dynamicConfig-update.json"); + assertAll(() -> JSONAssert.assertEquals(expectedManifestGetOutputJson, actualManifestJson, false), + () -> JSONAssert.assertEquals(expectedManifestUpdateOutputJson, ActualManifestResponseJson, false)); + } + @Test @WithMockUser(value = "admin_user", username = "admin@navi.com", authorities = {"secret.read.dev" , "supersecret.read"}, password = "admin") diff --git a/src/test/resources/fixtures/manifest/dev-testapp-dynamicConfig.json b/src/test/resources/fixtures/manifest/dev-testapp-dynamicConfig.json new file mode 100644 index 00000000..66f9f1de --- /dev/null +++ b/src/test/resources/fixtures/manifest/dev-testapp-dynamicConfig.json @@ -0,0 +1,183 @@ +{ + "name": "testapp-dynamicConfig", + "environment": "dev", + "dynamicConfiguration": [ + { + "fileName":"abc.txt", + "data":"new text\nSomeUrl: ${SOME_URL}" + } + ], + "extraResources": { + "aws_access": { + "policies": [ + { + "actions": [ + "s3:*" + ], + "resource": "*" + } + ] + } + }, + "notification": { + "notification": { + "slack": [ + "#test-slackgroup-alert" + ] + } + }, + "environmentVariables": [ + { + "name": "secretVar1", + "value": "secretVar1Value", + "type": "SECRET" + }, + { + "name": "configVar1", + "value": "configVar1Value", + "type": "CONFIG" + }, + { + "name": "superSecretVar1", + "value": "superSecretVar1Value", + "type": "SUPER_SECRET" + }, + { + "name": "SOME_URL", + "value": "https://google.com", + "type": "CONFIG", + "allowEgress": true + } + ], + "deployment": { + "loadBalancers": [ + { + "endpoint": "test-app.spike.np.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "endpoint": "test-app.spike.np.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "endpoint": "dev-test.spike.navi-tech.in", + "extraSecurityGroups": [ + "testapp-sg-1" + ], + "accessPolicies": [ + "internetFacing" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + } + ], + "alerts": { + "elb4xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "1" + }, + "elb5xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "1" + }, + "http4xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "15" + }, + "http5xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "2" + }, + "latency": { + "duration": "3m", + "severity": "warning", + "thresholdPercent": "800" + }, + "prometheusRecordingRule": [] + }, + "cluster": "spike.np.navi-tech.in", + "instance": { + "cpu": 0.3, + "memory": "300Mi" + }, + "exposedPorts": [ + { + "name": "serviceport", + "port": 8080 + }, + { + "name": "metrics", + "port": 4001 + } + ], + "allowEgress": [ + "https://wow.com", + "https://google.com" + ], + "healthCheck": { + "livenessCheck": { + "path": "/actuator/health", + "port": "metrics", + "type": "http", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + }, + "readinessCheck": { + "port": "serviceport", + "type": "tcp", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + } + }, + "hpa": { + "maxReplicas": 4, + "minReplicas": 2 + }, + "namespace": "dev", + "securityGroup": [ + { + "ids": [ + "sg-08fa3d4297d46a0f4" + ], + "name": "testapp-sg-1", + "rules": [ + { + "toPort": 443, + "fromPort": 443, + "protocol": "tcp", + "description": "Allow https traffic", + "ingressCidr": [ + "1.1.1.1/32" + ] + } + ] + } + ], + "timeout": 1500 + }, + "team": { + "name": "Infra" + }, + "labels": { + "micrometer-prometheus": "disabled" + } +} \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-get.json b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-get.json new file mode 100644 index 00000000..de38218a --- /dev/null +++ b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-get.json @@ -0,0 +1,190 @@ +{ + "name": "testapp-dynamicConfig", + "environment": "dev", + "dynamicConfiguration": [ + { + "fileName": "abc.txt", + "data": "new text\nSomeUrl: https://google.com" + } + ], + "extraResources": { + "aws_access": { + "policies": [ + { + "actions": [ + "s3:*" + ], + "resource": "*" + } + ] + } + }, + "notification": { + "notification": { + "slack": [ + "#test-slackgroup-alert" + ] + } + }, + "environmentVariables": [ + { + "name": "configVar1", + "value": "configVar1Value", + "type": "CONFIG", + "allowEgress": null, + "sha256": "b6859769570bed880d650b23043d468c15653733f3406e75795f246f646cb43c" + }, + { + "name": "secretVar1", + "value": "secretVar1Value", + "type": "SECRET", + "allowEgress": null, + "sha256": "f07c00a0d61b8c1b1c379005b810c975ea92d5fa5d53883ec4f091c2d19d8b70" + }, + { + "name": "SOME_URL", + "value": "https://google.com", + "type": "CONFIG", + "allowEgress": true, + "sha256": "05046f26c83e8c88b3ddab2eab63d0d16224ac1e564535fc75cdceee47a0938d" + }, + { + "name": "superSecretVar1", + "value": "superSecretVar1Value", + "type": "SUPER_SECRET", + "allowEgress": null, + "sha256": "ce28916cdd22a8beb2d207f3af6adf817ee68d75f0f49fed4aa8c8de156ff4d6" + } + ], + "deployment": { + "loadBalancers": [ + { + "endpoint": "test-app.spike.np.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "endpoint": "test-app.spike.np.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "endpoint": "dev-test.spike.navi-tech.in", + "extraSecurityGroups": [ + "testapp-sg-1" + ], + "accessPolicies": [ + "internetFacing" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + } + ], + "alerts": { + "elb4xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "1" + }, + "elb5xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "1" + }, + "http4xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "15" + }, + "http5xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "2" + }, + "latency": { + "duration": "3m", + "severity": "warning", + "thresholdPercent": "800" + } + }, + "cluster": "spike.np.navi-tech.in", + "instance": { + "cpu": 0.3, + "memory": "300Mi" + }, + "exposedPorts": [ + { + "name": "serviceport", + "port": 8080 + }, + { + "name": "metrics", + "port": 4001 + } + ], + "allowEgress": [ + "https://wow.com", + "https://google.com" + ], + "healthCheck": { + "livenessCheck": { + "path": "/actuator/health", + "port": "metrics", + "type": "http", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + }, + "readinessCheck": { + "port": "serviceport", + "type": "tcp", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + } + }, + "hpa": { + "maxReplicas": 4, + "minReplicas": 2 + }, + "namespace": "dev", + "securityGroup": [ + { + "ids": [ + "sg-08fa3d4297d46a0f4" + ], + "name": "testapp-sg-1", + "rules": [ + { + "toPort": 443, + "fromPort": 443, + "protocol": "tcp", + "description": "Allow https traffic", + "ingressCidr": [ + "1.1.1.1/32" + ] + } + ] + } + ], + "timeout": 1500 + }, + "infraVertical": "lending", + "team": { + "name": "Infra" + }, + "labels": { + "micrometer-prometheus": "disabled" + } +} \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-update.json b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-update.json new file mode 100644 index 00000000..a69b022c --- /dev/null +++ b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-update.json @@ -0,0 +1,196 @@ +{ + "name": "testapp-dynamicConfig", + "environment": "dev", + "dynamicConfiguration": [ + { + "fileName": "abc.txt", + "data": "new text\nSomeUrl: https://google.com" + } + ], + "extraResources": { + "version": 0, + "aws_access": { + "policies": [ + { + "actions": [ + "s3:*" + ], + "resource": "*" + } + ] + } + }, + "notification": { + "version": 0, + "notification": { + "slack": [ + "#test-slackgroup-alert" + ] + } + }, + "environmentVariables": [ + { + "name": "configVar1", + "value": "configVar1Value", + "type": "CONFIG", + "allowEgress": null, + "sha256": "b6859769570bed880d650b23043d468c15653733f3406e75795f246f646cb43c" + }, + { + "name": "secretVar1", + "value": "secretVar1Value", + "type": "SECRET", + "allowEgress": null, + "sha256": "f07c00a0d61b8c1b1c379005b810c975ea92d5fa5d53883ec4f091c2d19d8b70" + }, + { + "name": "SOME_URL", + "value": "https://google.com", + "type": "CONFIG", + "allowEgress": true, + "sha256": "05046f26c83e8c88b3ddab2eab63d0d16224ac1e564535fc75cdceee47a0938d" + }, + { + "name": "superSecretVar1", + "value": "*****", + "type": "SUPER_SECRET", + "allowEgress": null, + "sha256": "ce28916cdd22a8beb2d207f3af6adf817ee68d75f0f49fed4aa8c8de156ff4d6" + } + ], + "deployment": { + "version": 0, + "loadBalancers": [ + { + "version": 0, + "endpoint": "test-app.spike.np.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "version": 0, + "endpoint": "test-app.spike.np.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "version": 0, + "endpoint": "dev-test.spike.navi-tech.in", + "extraSecurityGroups": [ + "testapp-sg-1" + ], + "accessPolicies": [ + "internetFacing" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + } + ], + "alerts": { + "elb4xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "1" + }, + "elb5xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "1" + }, + "http4xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "15" + }, + "http5xx": { + "duration": "3m", + "severity": "critical", + "thresholdPercent": "2" + }, + "latency": { + "duration": "3m", + "severity": "warning", + "thresholdPercent": "800" + } + }, + "cluster": "spike.np.navi-tech.in", + "instance": { + "cpu": 0.3, + "memory": "300Mi" + }, + "exposedPorts": [ + { + "name": "serviceport", + "port": 8080 + }, + { + "name": "metrics", + "port": 4001 + } + ], + "allowEgress": [ + "https://wow.com", + "https://google.com" + ], + "healthCheck": { + "livenessCheck": { + "path": "/actuator/health", + "port": "metrics", + "type": "http", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + }, + "readinessCheck": { + "port": "serviceport", + "type": "tcp", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + } + }, + "hpa": { + "maxReplicas": 4, + "minReplicas": 2 + }, + "namespace": "dev", + "securityGroup": [ + { + "ids": [ + "sg-08fa3d4297d46a0f4" + ], + "name": "testapp-sg-1", + "rules": [ + { + "toPort": 443, + "fromPort": 443, + "protocol": "tcp", + "description": "Allow https traffic", + "ingressCidr": [ + "1.1.1.1/32" + ] + } + ] + } + ], + "timeout": 1500 + }, + "infraVertical": "lending", + "team": { + "name": "Infra" + }, + "labels": { + "micrometer-prometheus": "disabled" + } +} \ No newline at end of file diff --git a/templates/dynamic_configuration.jsonnet b/templates/dynamic_configuration.jsonnet new file mode 100644 index 00000000..25434732 --- /dev/null +++ b/templates/dynamic_configuration.jsonnet @@ -0,0 +1,19 @@ +local chart = import 'chart.jsonnet'; +local deployment_manifest = import 'deployment_manifest.jsonnet'; +local manifest_util = import 'manifest_util.jsonnet'; +local dynamicConfiguration = if manifest_util.is_dynamic_config_present(deployment_manifest) then deployment_manifest.dynamicConfiguration else {}; + +if manifest_util.is_dynamic_config_present(deployment_manifest) then { + apiVersion: 'v1', + kind: 'Secret', + metadata: { + name: chart.full_service_name(deployment_manifest.deployment.name) + '-dynamic-secret', + namespace: 'dev', + }, + stringData: + { + [config.fileName] : config.data, + for config in dynamicConfiguration + }, + type: 'Opaque', +} \ No newline at end of file diff --git a/templates/main.jsonnet b/templates/main.jsonnet index fb666470..2c6f3460 100644 --- a/templates/main.jsonnet +++ b/templates/main.jsonnet @@ -19,6 +19,7 @@ local elasticsearch_sm_secrets = import 'elasticsearch_sm_secrets.jsonnet'; local elasticsearch_servicemonitor = import 'elasticsearch_servicemonitor.jsonnet'; local elasticsearch_alerts_default = import 'elasticsearch_alerts_default.jsonnet'; local elasticsearch_snapshots = import 'elasticsearch_snapshots.jsonnet'; +local dynamic_configuration = import 'dynamic_configuration.jsonnet'; { '0_secret.json': secret, @@ -39,7 +40,8 @@ local elasticsearch_snapshots = import 'elasticsearch_snapshots.jsonnet'; '16_elasticsearch_sm_secrets.json': elasticsearch_sm_secrets, '17_elasticsearch_servicemonitor.json': elasticsearch_servicemonitor, '18_elasticsearch_alerts_default.json': elasticsearch_alerts_default, - '19_elasticsearch_snapshots.json': elasticsearch_snapshots + '19_elasticsearch_snapshots.json': elasticsearch_snapshots, + '20_dynamic_configuration.json': dynamic_configuration } + if ingresses != null then diff --git a/templates/manifest_util.jsonnet b/templates/manifest_util.jsonnet index 1b9c5099..d861829e 100644 --- a/templates/manifest_util.jsonnet +++ b/templates/manifest_util.jsonnet @@ -9,4 +9,6 @@ 'instanceName' in database && database.instanceName != '' else false else false, + is_dynamic_config_present(deploymentManifest):: + if ('dynamicConfiguration' in deploymentManifest && deploymentManifest.dynamicConfiguration != null && deploymentManifest.dynamicConfiguration != []) then true else false, } diff --git a/templates/pod_template.jsonnet b/templates/pod_template.jsonnet index b8fb0481..14a7c430 100644 --- a/templates/pod_template.jsonnet +++ b/templates/pod_template.jsonnet @@ -8,6 +8,7 @@ local deployment = deployment_manifest.deployment; local readinessCheck = deployment.healthChecks.readinessCheck; local livenessCheck = deployment.healthChecks.livenessCheck; local exposedPorts = deployment_manifest.deployment.exposedPorts; +local manifest_util = import 'manifest_util.jsonnet'; local hasEnvironmentFile = if 'environmentFile' in deployment then true else false; @@ -90,6 +91,11 @@ local istioInboundPortsAnnotation = { mountPath: util.parent_dir(deployment.environmentFile.path), name: 'environment-file-volume', }] else []) + + (if manifest_util.is_dynamic_config_present(deployment_manifest) then + [{ + mountPath: "/var/navi/dynamic_configuration/", + name: chart.full_service_name(deployment_manifest.deployment.name) + '-dynamic-secret', + }] else []) + [{ mountPath: secret.path, name: secret.name } for secret in deployment.mountSecrets], } + if std.find(deployment.loadBalancers[0].type, ['alb', 'sharedAlb', 'elb', 'nginxLb']) != [] then { readinessProbe: health_check_values.generator(readinessCheck)[readinessCheck.type],