From d3a366b709e8f9dc53ce8b87c6642c6e0e018954 Mon Sep 17 00:00:00 2001 From: Jose Date: Fri, 4 Mar 2022 08:04:51 +0100 Subject: [PATCH] feat: Kubernetes support of SecurityContext configuration Allow to configure the security context section in the pods for Kubernetes, OpenShift and Knative. Fix https://github.com/quarkusio/quarkus/issues/23866 --- .../asciidoc/deploying-to-kubernetes.adoc | 35 ++++ .../ApplySecuritySettingsDecorator.java | 78 +++++++++ .../kubernetes/deployment/KnativeConfig.java | 11 ++ .../deployment/KubernetesCommonHelper.java | 4 + .../deployment/KubernetesConfig.java | 13 +- .../deployment/OpenshiftConfig.java | 11 ++ .../deployment/PlatformConfiguration.java | 6 +- .../deployment/SecurityContextConfig.java | 151 ++++++++++++++++++ .../it/kubernetes/BasicKubernetesTest.java | 1 + .../KubernetesWithSecurityContextTest.java | 70 ++++++++ ...ubernetes-with-security-context.properties | 14 ++ .../verify.groovy | 3 +- 12 files changed, 392 insertions(+), 5 deletions(-) create mode 100644 extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplySecuritySettingsDecorator.java create mode 100644 extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/SecurityContextConfig.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithSecurityContextTest.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-security-context.properties diff --git a/docs/src/main/asciidoc/deploying-to-kubernetes.adoc b/docs/src/main/asciidoc/deploying-to-kubernetes.adoc index 2161f2e7b24a8..4bbcddc569b2b 100644 --- a/docs/src/main/asciidoc/deploying-to-kubernetes.adoc +++ b/docs/src/main/asciidoc/deploying-to-kubernetes.adoc @@ -712,6 +712,7 @@ The table below describe all the available configuration options. | quarkus.kubernetes.resources.requests.memory | String | | | quarkus.kubernetes.resources.limits.cpu | String | | | quarkus.kubernetes.resources.limits.memory | String | | +| quarkus.kubernetes.security-context | SecurityContext | | ( see SecurityContext ) |==== Properties that use non-standard types, can be referenced by expanding the property. @@ -796,6 +797,38 @@ Allowed values: `cluster-ip`, `node-port`, `load-balancer`, `external-name` | hostnames | String[] | list of hostnames | |==== +.SecurityContext +|==== +| Property | Type | Description | Default Value +| se-linux-options | SeLinuxOptions | | +| windows-options | WindowsOptions | | +| run-as-user | long | | +| run-as-group | long | | +| run-as-non-root | boolean | | +| supplemental-groups | long[] | | +| fs-group | long | | +| sysctls | Map | | +| fs-group-change-policy | String | | +|==== + +.SeLinuxOptions +|==== +| Property | Type | Description | Default Value +| level | String | | +| role | String | | +| user | String | | +| type | String | | +|==== + +.WindowsOptions +|==== +| Property | Type | Description | Default Value +| gmsa-credential-spec-name | String | | +| gmsa-credential-spec | String | | +| run-as-user-name | String | | +| host-process | boolean | | +|==== + ==== Mounts and Volumes .Mount @@ -994,6 +1027,7 @@ The OpenShift resources can be customized in a similar approach with Kubernetes. | quarkus.openshift.route.host | String | | | quarkus.openshift.route.annotations | Map | | | quarkus.openshift.headless | boolean | | false +| quarkus.openshift.security-context | SecurityContext | | ( see SecurityContext ) |==== [#knative] @@ -1097,6 +1131,7 @@ The generated service can be customized using the following properties: | quarkus.knative.scale-to-zero-enabled | boolean | See link:https://knative.dev/docs/serving/autoscaling/scale-to-zero/#enable-scale-to-zero[link] | true | quarkus.knative.revision-auto-scaling | AutoScalingConfig | | ( see AutoScalingConfig ) | quarkus.knative.global-auto-scaling | GlobalAutoScalingConfig | | ( see GlobalAutoScalingConfig ) +| quarkus.knative.security-context | SecurityContext | | ( see SecurityContext ) |==== .Traffic diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplySecuritySettingsDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplySecuritySettingsDecorator.java new file mode 100644 index 0000000000000..fb499b2bd1238 --- /dev/null +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplySecuritySettingsDecorator.java @@ -0,0 +1,78 @@ +package io.quarkus.kubernetes.deployment; + +import java.util.Optional; + +import io.dekorate.kubernetes.decorator.Decorator; +import io.dekorate.kubernetes.decorator.NamedResourceDecorator; +import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator; +import io.fabric8.kubernetes.api.model.ObjectMeta; +import io.fabric8.kubernetes.api.model.PodSecurityContextBuilder; +import io.fabric8.kubernetes.api.model.PodSpecFluent; +import io.fabric8.kubernetes.api.model.SELinuxOptions; +import io.fabric8.kubernetes.api.model.SELinuxOptionsBuilder; +import io.fabric8.kubernetes.api.model.SysctlBuilder; +import io.fabric8.kubernetes.api.model.WindowsSecurityContextOptions; +import io.fabric8.kubernetes.api.model.WindowsSecurityContextOptionsBuilder; + +public class ApplySecuritySettingsDecorator extends NamedResourceDecorator { + + private final SecurityContextConfig securityContext; + + public ApplySecuritySettingsDecorator(String resourceName, SecurityContextConfig securityContext) { + super(resourceName); + this.securityContext = securityContext; + } + + @Override + public void andThenVisit(PodSpecFluent podSpec, ObjectMeta resourceMeta) { + PodSecurityContextBuilder securityContextBuilder = new PodSecurityContextBuilder(); + + securityContext.runAsUser.ifPresent(securityContextBuilder::withRunAsUser); + securityContext.runAsGroup.ifPresent(securityContextBuilder::withRunAsGroup); + securityContext.runAsNonRoot.ifPresent(securityContextBuilder::withRunAsNonRoot); + securityContext.supplementalGroups.ifPresent(securityContextBuilder::addAllToSupplementalGroups); + securityContext.fsGroup.ifPresent(securityContextBuilder::withFsGroup); + securityContext.sysctls.ifPresent(map -> map.entrySet().stream() + .map(entry -> new SysctlBuilder().withName(entry.getKey()).withValue(entry.getValue()).build()) + .forEach(securityContextBuilder::addToSysctls)); + securityContext.fsGroupChangePolicy.map(e -> e.name()).ifPresent(securityContextBuilder::withFsGroupChangePolicy); + buildSeLinuxOptions().ifPresent(securityContextBuilder::withSeLinuxOptions); + buildWindowsOptions().ifPresent(securityContextBuilder::withWindowsOptions); + + podSpec.withSecurityContext(securityContextBuilder.build()); + } + + @Override + public Class[] after() { + return new Class[] { ResourceProvidingDecorator.class }; + } + + private Optional buildWindowsOptions() { + WindowsSecurityContextOptions item = null; + if (securityContext.windowsOptions.isAnyPropertySet()) { + WindowsSecurityContextOptionsBuilder builder = new WindowsSecurityContextOptionsBuilder(); + securityContext.windowsOptions.gmsaCredentialSpec.ifPresent(builder::withGmsaCredentialSpec); + securityContext.windowsOptions.gmsaCredentialSpecName.ifPresent(builder::withGmsaCredentialSpecName); + securityContext.windowsOptions.hostProcess.ifPresent(builder::withHostProcess); + securityContext.windowsOptions.runAsUserName.ifPresent(builder::withRunAsUserName); + item = builder.build(); + } + + return Optional.ofNullable(item); + } + + private Optional buildSeLinuxOptions() { + SELinuxOptions item = null; + if (securityContext.seLinuxOptions.isAnyPropertySet()) { + SELinuxOptionsBuilder builder = new SELinuxOptionsBuilder(); + securityContext.seLinuxOptions.user.ifPresent(builder::withUser); + securityContext.seLinuxOptions.role.ifPresent(builder::withRole); + securityContext.seLinuxOptions.level.ifPresent(builder::withLevel); + securityContext.seLinuxOptions.type.ifPresent(builder::withType); + item = builder.build(); + } + + return Optional.ofNullable(item); + } + +} diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java index d686dfdfee434..0d979fe4ef81a 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java @@ -435,6 +435,12 @@ public EnvVarsConfig getEnv() { @ConfigItem Optional appConfigMap; + /** + * If set, it will copy the security context configuration provided into the generated pod settings. + */ + @ConfigItem + SecurityContextConfig securityContext; + public Optional getAppSecret() { return this.appSecret; } @@ -442,4 +448,9 @@ public Optional getAppSecret() { public Optional getAppConfigMap() { return this.appConfigMap; } + + @Override + public SecurityContextConfig getSecurityContext() { + return securityContext; + } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java index 39c096938b6d3..20ca37f526a12 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java @@ -317,6 +317,10 @@ private static List createPodDecorators(Optional pr result.add(new DecoratorBuildItem(target, new ApplyRequestsMemoryDecorator(name, m))); }); + if (config.getSecurityContext().isAnyPropertySet()) { + result.add(new DecoratorBuildItem(target, new ApplySecuritySettingsDecorator(name, config.getSecurityContext()))); + } + return result; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java index c1b7283b53837..639a96a91c1cd 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java @@ -286,12 +286,18 @@ public enum DeploymentResourceKind { Optional appSecret; /** - * If set, the config amp will mounted to the application container and its contents will be used for application + * If set, the config map will be mounted to the application container and its contents will be used for application * configuration. */ @ConfigItem Optional appConfigMap; + /** + * If set, it will copy the security context configuration provided into the generated pod settings. + */ + @ConfigItem + SecurityContextConfig securityContext; + public Optional getPartOf() { return partOf; } @@ -485,4 +491,9 @@ public Optional getAppConfigMap() { public Optional getExposition() { return Optional.of(ingress); } + + @Override + public SecurityContextConfig getSecurityContext() { + return securityContext; + } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java index 7537cc4f45945..6a2b1a7c401cb 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java @@ -497,6 +497,12 @@ public EnvVarsConfig getEnv() { @ConfigItem Optional appConfigMap; + /** + * If set, it will copy the security context configuration provided into the generated pod settings. + */ + @ConfigItem + SecurityContextConfig securityContext; + public Optional getAppSecret() { return this.appSecret; } @@ -510,6 +516,11 @@ public Optional getExposition() { return Optional.of(route); } + @Override + public SecurityContextConfig getSecurityContext() { + return securityContext; + } + public static boolean isOpenshiftBuildEnabled(ContainerImageConfig containerImageConfig, Capabilities capabilities) { boolean implictlyEnabled = ContainerImageCapabilitiesUtil.getActiveContainerImageCapability(capabilities) .filter(c -> c.contains(OPENSHIFT) || c.contains(S2I)).isPresent(); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/PlatformConfiguration.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/PlatformConfiguration.java index f761be37836a8..16c871b957854 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/PlatformConfiguration.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/PlatformConfiguration.java @@ -84,8 +84,10 @@ default String getConfigName() { return getClass().getSimpleName().replaceAll("Config$", "").toLowerCase(); } - public Optional getAppSecret(); + Optional getAppSecret(); - public Optional getAppConfigMap(); + Optional getAppConfigMap(); + + SecurityContextConfig getSecurityContext(); } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/SecurityContextConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/SecurityContextConfig.java new file mode 100644 index 0000000000000..a91e0a8014c2f --- /dev/null +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/SecurityContextConfig.java @@ -0,0 +1,151 @@ +package io.quarkus.kubernetes.deployment; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class SecurityContextConfig { + + /** + * SELinuxOptions to be applied to the container. + */ + SeLinuxOptions seLinuxOptions; + + /** + * The Windows specific settings applied to all containers. + */ + WindowsOptions windowsOptions; + + /** + * The UID to run the entrypoint of the container process. + */ + @ConfigItem + Optional runAsUser; + + /** + * The GID to run the entrypoint of the container process. + */ + @ConfigItem + Optional runAsGroup; + + /** + * Indicates that the container must run as a non-root user. + */ + @ConfigItem + Optional runAsNonRoot; + + /** + * A list of groups applied to the first process run in each container, in addition to the container's primary GID. + * If unspecified, no groups will be added to any container. + */ + @ConfigItem + Optional> supplementalGroups; + + /** + * A special supplemental group that applies to all containers in a pod. + */ + @ConfigItem + Optional fsGroup; + + /** + * Sysctls hold a list of namespaced sysctls used for the pod. + */ + @ConfigItem + Optional> sysctls; + + /** + * It holds policies that will be used for applying fsGroup to a volume when volume is mounted. + * Values: OnRootMismatch, Always + */ + @ConfigItem + Optional fsGroupChangePolicy; + + protected boolean isAnyPropertySet() { + return seLinuxOptions.isAnyPropertySet() || windowsOptions.isAnyPropertySet() || runAsUser.isPresent() + || runAsGroup.isPresent() || runAsNonRoot.isPresent() || supplementalGroups.isPresent() + || fsGroup.isPresent() || sysctls.isPresent() || fsGroupChangePolicy.isPresent(); + } + + @ConfigGroup + public static class SeLinuxOptions { + + /** + * The SELinux level label that applies to the container. + */ + @ConfigItem + Optional level; + + /** + * The SELinux role label that applies to the container. + */ + @ConfigItem + Optional role; + + /** + * The SELinux type label that applies to the container. + */ + @ConfigItem + Optional type; + + /** + * The SELinux user label that applies to the container. + */ + @ConfigItem + Optional user; + + protected boolean isAnyPropertySet() { + return level.isPresent() || role.isPresent() || type.isPresent() || user.isPresent(); + } + } + + @ConfigGroup + public static class WindowsOptions { + + /** + * The name of the GMSA credential spec to use. + */ + @ConfigItem + Optional gmsaCredentialSpecName; + + /** + * GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the + * contents of the GMSA credential spec named by the GMSACredentialSpecName field. + */ + @ConfigItem + Optional gmsaCredentialSpec; + + /** + * The UserName in Windows to run the entrypoint of the container process. + */ + @ConfigItem + Optional runAsUserName; + + /** + * HostProcess determines if a container should be run as a 'Host Process' container. + */ + @ConfigItem + Optional hostProcess; + + protected boolean isAnyPropertySet() { + return gmsaCredentialSpecName.isPresent() || gmsaCredentialSpec.isPresent() || runAsUserName.isPresent() + || hostProcess.isPresent(); + } + } + + public enum PodFSGroupChangePolicy { + /** + * It indicates that volume's ownership and permissions will be changed only when permission and ownership of root + * directory does not match with expected permissions on the volume. + */ + OnRootMismatch, + /** + * It indicates that volume's ownership and permissions should always be changed whenever volume is mounted inside a + * Pod. This the default behavior. + */ + Always; + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicKubernetesTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicKubernetesTest.java index b58b30dea14ac..cf2c06f8dc640 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicKubernetesTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicKubernetesTest.java @@ -75,6 +75,7 @@ public void assertGeneratedResources() throws IOException { assertThat(deploymentSpec.getTemplate()).satisfies(t -> { assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getSecurityContext()).isNull(); assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { assertThat(container.getImagePullPolicy()).isEqualTo("Always"); // expect the default value assertThat(container.getPorts()).singleElement().satisfies(p -> { diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithSecurityContextTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithSecurityContextTest.java new file mode 100644 index 0000000000000..b75fbd1942e77 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithSecurityContextTest.java @@ -0,0 +1,70 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.PodSecurityContext; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithSecurityContextTest { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .withApplicationRoot((jar) -> jar.addClasses(GreetingResource.class)) + .setApplicationName("kubernetes-with-security-context") + .setApplicationVersion("0.1-SNAPSHOT") + .withConfigurationResource("kubernetes-with-security-context.properties"); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")); + List kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + + assertThat(kubernetesList).filteredOn(i -> "Deployment".equals(i.getKind())).singleElement().satisfies(i -> { + assertThat(i).isInstanceOfSatisfying(Deployment.class, d -> { + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + PodSecurityContext securityContext = podSpec.getSecurityContext(); + assertThat(securityContext).isNotNull(); + assertThat(securityContext.getSeLinuxOptions()).isNotNull(); + assertThat(securityContext.getSeLinuxOptions().getUser()).isEqualTo("user"); + assertThat(securityContext.getSeLinuxOptions().getRole()).isEqualTo("role"); + assertThat(securityContext.getSeLinuxOptions().getType()).isEqualTo("type"); + assertThat(securityContext.getSeLinuxOptions().getLevel()).isEqualTo("level"); + assertThat(securityContext.getWindowsOptions()).isNotNull(); + assertThat(securityContext.getWindowsOptions().getGmsaCredentialSpec()).isEqualTo("spec"); + assertThat(securityContext.getWindowsOptions().getGmsaCredentialSpecName()).isEqualTo("specName"); + assertThat(securityContext.getWindowsOptions().getHostProcess()).isTrue(); + assertThat(securityContext.getWindowsOptions().getRunAsUserName()).isEqualTo("user"); + assertThat(securityContext.getRunAsUser()).isEqualTo(123); + assertThat(securityContext.getRunAsGroup()).isEqualTo(124); + assertThat(securityContext.getRunAsNonRoot()).isTrue(); + assertThat(securityContext.getSupplementalGroups()).containsExactly(125l, 126l); + assertThat(securityContext.getFsGroup()).isEqualTo(127); + assertThat(securityContext.getFsGroupChangePolicy()).isEqualTo("OnRootMismatch"); + }); + }); + }); + }); + }); + } + +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-security-context.properties b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-security-context.properties new file mode 100644 index 0000000000000..05a70bee0fec5 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-security-context.properties @@ -0,0 +1,14 @@ +quarkus.kubernetes.security-context.se-linux-options.user=user +quarkus.kubernetes.security-context.se-linux-options.role=role +quarkus.kubernetes.security-context.se-linux-options.type=type +quarkus.kubernetes.security-context.se-linux-options.level=level +quarkus.kubernetes.security-context.windows-options.gmsa-credential-spec-name=specName +quarkus.kubernetes.security-context.windows-options.gmsa-credential-spec=spec +quarkus.kubernetes.security-context.windows-options.run-as-user-name=user +quarkus.kubernetes.security-context.windows-options.host-process=true +quarkus.kubernetes.security-context.run-as-user=123 +quarkus.kubernetes.security-context.run-as-group=124 +quarkus.kubernetes.security-context.run-as-non-root=true +quarkus.kubernetes.security-context.supplemental-groups=125,126 +quarkus.kubernetes.security-context.fs-group=127 +quarkus.kubernetes.security-context.fs-group-change-policy=OnRootMismatch \ No newline at end of file diff --git a/integration-tests/kubernetes/src/it/openshift-s2i-build-and-deploy/verify.groovy b/integration-tests/kubernetes/src/it/openshift-s2i-build-and-deploy/verify.groovy index 222f815140e0e..5da558a350b9a 100644 --- a/integration-tests/kubernetes/src/it/openshift-s2i-build-and-deploy/verify.groovy +++ b/integration-tests/kubernetes/src/it/openshift-s2i-build-and-deploy/verify.groovy @@ -1,6 +1,5 @@ import io.dekorate.utils.Serialization import io.fabric8.kubernetes.api.model.KubernetesList -import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.openshift.api.model.BuildConfig //Check that file exits @@ -14,7 +13,7 @@ openshiftYml.withInputStream { stream -> BuildConfig buildConfig = list.items.find{r -> r.kind == "BuildConfig"} - //Check that ti contains a Deployment named after the project + //Check that it contains a BuildConfig named after the project assert buildConfig != null assert buildConfig.metadata.name == "openshift-s2i-build-and-deploy" }