From c86dbaf3c6f764cf348e59c0acf4d12c3fda0eac Mon Sep 17 00:00:00 2001 From: Jose Date: Fri, 14 Apr 2023 14:48:39 +0200 Subject: [PATCH] Ensure the ServiceAccount/Role/ClusterRole resourcs are created in order Fix https://github.com/quarkusio/quarkus/issues/32640 Partially reverts https://github.com/quarkusio/quarkus/pull/32208 --- .../AddClusterRoleResourceDecorator.java | 6 -- .../deployment/AddRoleResourceDecorator.java | 6 -- .../AddServiceAccountResourceDecorator.java | 6 -- .../deployment/KubernetesProcessor.java | 3 +- .../deployment/QuarkusFileWriter.java | 59 +++++++++++++++++++ .../KubernetesWithRbacFullTest.java | 6 ++ 6 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/QuarkusFileWriter.java diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddClusterRoleResourceDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddClusterRoleResourceDecorator.java index d13091514834bf..2074e4fd122f10 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddClusterRoleResourceDecorator.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddClusterRoleResourceDecorator.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Map; -import io.dekorate.kubernetes.decorator.Decorator; import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator; import io.fabric8.kubernetes.api.model.KubernetesListBuilder; import io.fabric8.kubernetes.api.model.ObjectMeta; @@ -46,9 +45,4 @@ public void visit(KubernetesListBuilder list) { .endMetadata() .withRules(rules)); } - - @Override - public Class[] before() { - return new Class[] { AddRoleBindingResourceDecorator.class }; - } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddRoleResourceDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddRoleResourceDecorator.java index 632b3bca7bcefc..752efe7fd2b035 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddRoleResourceDecorator.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddRoleResourceDecorator.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Map; -import io.dekorate.kubernetes.decorator.Decorator; import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator; import io.fabric8.kubernetes.api.model.KubernetesListBuilder; import io.fabric8.kubernetes.api.model.ObjectMeta; @@ -49,9 +48,4 @@ public void visit(KubernetesListBuilder list) { .endMetadata() .withRules(rules)); } - - @Override - public Class[] before() { - return new Class[] { AddRoleBindingResourceDecorator.class }; - } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddServiceAccountResourceDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddServiceAccountResourceDecorator.java index f6f90801b3608b..b8fb1f0eb8dc48 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddServiceAccountResourceDecorator.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddServiceAccountResourceDecorator.java @@ -5,7 +5,6 @@ import java.util.HashMap; import java.util.Map; -import io.dekorate.kubernetes.decorator.Decorator; import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator; import io.fabric8.kubernetes.api.model.KubernetesListBuilder; import io.fabric8.kubernetes.api.model.ObjectMeta; @@ -44,9 +43,4 @@ public void visit(KubernetesListBuilder list) { .endMetadata() .endServiceAccountItem(); } - - @Override - public Class[] before() { - return new Class[] { AddRoleBindingResourceDecorator.class }; - } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java index cce484f5534c97..fa4d58dad98251 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java @@ -30,7 +30,6 @@ import io.dekorate.kubernetes.decorator.Decorator; import io.dekorate.logger.NoopLogger; import io.dekorate.processor.SimpleFileReader; -import io.dekorate.processor.SimpleFileWriter; import io.dekorate.project.Project; import io.dekorate.utils.Maps; import io.dekorate.utils.Strings; @@ -146,7 +145,7 @@ public void build(ApplicationInfoBuildItem applicationInfo, .map(DeploymentTargetEntry::getName) .collect(Collectors.toSet())); final Map generatedResourcesMap; - final SessionWriter sessionWriter = new SimpleFileWriter(project, false); + final SessionWriter sessionWriter = new QuarkusFileWriter(project); final SessionReader sessionReader = new SimpleFileReader( project.getRoot().resolve("src").resolve("main").resolve("kubernetes"), targets); sessionWriter.setProject(project); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/QuarkusFileWriter.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/QuarkusFileWriter.java new file mode 100644 index 00000000000000..e5ffdc7fe95ea3 --- /dev/null +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/QuarkusFileWriter.java @@ -0,0 +1,59 @@ +package io.quarkus.kubernetes.deployment; + +import static io.quarkus.kubernetes.deployment.Constants.CLUSTER_ROLE; +import static io.quarkus.kubernetes.deployment.Constants.ROLE; +import static io.quarkus.kubernetes.deployment.Constants.SERVICE_ACCOUNT; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import io.dekorate.processor.SimpleFileWriter; +import io.dekorate.project.Project; +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.KubernetesList; +import io.fabric8.kubernetes.api.model.KubernetesListBuilder; + +public class QuarkusFileWriter extends SimpleFileWriter { + + private static final List RESOURCE_KIND_ORDER = List.of(SERVICE_ACCOUNT, ROLE, CLUSTER_ROLE); + + public QuarkusFileWriter(Project project) { + super(project, false); + } + + @Override + public Map write(String group, KubernetesList list) { + // sort resources in list by: ServiceAccount, Role, ClusterRole, the rest... + return super.write(group, new KubernetesListBuilder().addAllToItems(sort(list.getItems())).build()); + } + + private List sort(List items) { + // Resources that we need the order. + Map> groups = new HashMap<>(); + // List of resources with unknown order: we preserve the order of creation in this case + List rest = new LinkedList<>(); + for (HasMetadata item : items) { + String kind = item.getKind(); + if (RESOURCE_KIND_ORDER.contains(kind)) { + groups.computeIfAbsent(kind, k -> new LinkedList()) + .add(item); + } else { + rest.add(item); + } + } + + List sorted = new LinkedList<>(); + // we first add the resources with order + for (String kind : RESOURCE_KIND_ORDER) { + List group = groups.get(kind); + if (group != null) { + sorted.addAll(group); + } + } + + sorted.addAll(rest); + return sorted; + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithRbacFullTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithRbacFullTest.java index 41bdd6c3e594f0..83be5e5411d865 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithRbacFullTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithRbacFullTest.java @@ -53,6 +53,12 @@ public void assertGeneratedResources() throws IOException { assertTrue(lastIndexOfRoleRefKind < firstIndexOfRoleBinding, "RoleBinding resource is created before " + "the Role/ClusterRole/ServiceAccount resource!"); + // ensure service account resource is generated before the Deployment resource: + int lastIndexOfServiceAccount = lastIndexOfKind(kubernetesFileContent, "ServiceAccount"); + int firstIndexOfDeployment = kubernetesFileContent.indexOf("kind: Deployment"); + assertTrue(lastIndexOfServiceAccount < firstIndexOfDeployment, "ServiceAccount resource is created after " + + "the Deployment resource!"); + List kubernetesList = DeserializationUtil.deserializeAsList(kubernetesFile); Deployment deployment = getDeploymentByName(kubernetesList, APP_NAME);