Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure the ServiceAccount/Role/ClusterRole resources are created in order #32651

Merged
merged 1 commit into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,9 +45,4 @@ public void visit(KubernetesListBuilder list) {
.endMetadata()
.withRules(rules));
}

@Override
public Class<? extends Decorator>[] before() {
return new Class[] { AddRoleBindingResourceDecorator.class };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -49,9 +48,4 @@ public void visit(KubernetesListBuilder list) {
.endMetadata()
.withRules(rules));
}

@Override
public Class<? extends Decorator>[] before() {
return new Class[] { AddRoleBindingResourceDecorator.class };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -44,9 +43,4 @@ public void visit(KubernetesListBuilder list) {
.endMetadata()
.endServiceAccountItem();
}

@Override
public Class<? extends Decorator>[] before() {
return new Class[] { AddRoleBindingResourceDecorator.class };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -146,7 +145,7 @@ public void build(ApplicationInfoBuildItem applicationInfo,
.map(DeploymentTargetEntry::getName)
.collect(Collectors.toSet()));
final Map<String, String> 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);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package io.quarkus.kubernetes.deployment;

import static io.quarkus.kubernetes.deployment.Constants.CLUSTER_ROLE;
import static io.quarkus.kubernetes.deployment.Constants.CLUSTER_ROLE_BINDING;
import static io.quarkus.kubernetes.deployment.Constants.CRONJOB;
import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT;
import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT_CONFIG;
import static io.quarkus.kubernetes.deployment.Constants.INGRESS;
import static io.quarkus.kubernetes.deployment.Constants.JOB;
import static io.quarkus.kubernetes.deployment.Constants.ROLE;
import static io.quarkus.kubernetes.deployment.Constants.ROLE_BINDING;
import static io.quarkus.kubernetes.deployment.Constants.ROUTE;
import static io.quarkus.kubernetes.deployment.Constants.SERVICE_ACCOUNT;
import static io.quarkus.kubernetes.deployment.Constants.STATEFULSET;

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<String> RESOURCE_KIND_ORDER = List.of("Namespace",
"NetworkPolicy",
"ResourceQuota",
"LimitRange",
"PodSecurityPolicy",
"PodDisruptionBudget",
SERVICE_ACCOUNT,
"Secret",
"SecretList",
"ConfigMap",
"StorageClass",
"PersistentVolume",
"PersistentVolumeClaim",
"CustomResourceDefinition",
CLUSTER_ROLE,
"ClusterRoleList",
CLUSTER_ROLE_BINDING,
"ClusterRoleBindingList",
ROLE,
"RoleList",
ROLE_BINDING,
"RoleBindingList",
"Service",
Sgitario marked this conversation as resolved.
Show resolved Hide resolved
"ImageStream",
"BuildConfig",
"DaemonSet",
"Pod",
"ReplicationController",
"ReplicaSet",
DEPLOYMENT,
"HorizontalPodAutoscaler",
STATEFULSET,
DEPLOYMENT_CONFIG,
JOB,
CRONJOB,
INGRESS,
ROUTE,
"APIService");

public QuarkusFileWriter(Project project) {
super(project, false);
}

@Override
public Map<String, String> 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<HasMetadata> sort(List<HasMetadata> items) {
// Resources that we need the order.
Map<String, List<HasMetadata>> groups = new HashMap<>();
// List of resources with unknown order: we preserve the order of creation in this case
List<HasMetadata> 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<HasMetadata> sorted = new LinkedList<>();
// we first add the resources with order
for (String kind : RESOURCE_KIND_ORDER) {
List<HasMetadata> group = groups.get(kind);
if (group != null) {
sorted.addAll(group);
}
}

sorted.addAll(rest);
return sorted;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<HasMetadata> kubernetesList = DeserializationUtil.deserializeAsList(kubernetesFile);

Deployment deployment = getDeploymentByName(kubernetesList, APP_NAME);
Expand Down