Skip to content

Commit

Permalink
Merge pull request #43288 from metacosm/service-account-build-item-si…
Browse files Browse the repository at this point in the history
…mpler

Emit build item when the effective ServiceAccount name is computed
  • Loading branch information
geoand committed Sep 18, 2024
2 parents 7207670 + 7e33be0 commit cddc49d
Show file tree
Hide file tree
Showing 21 changed files with 540 additions and 503 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.quarkus.kubernetes.spi.KubernetesClusterRoleBuildItem;
import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem;
import io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem;
import io.quarkus.kubernetes.spi.KubernetesEffectiveServiceAccountBuildItem;
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
Expand Down Expand Up @@ -73,9 +74,7 @@ public void checkKind(ApplicationInfoBuildItem applicationInfo, KubernetesConfig

@BuildStep
public void createAnnotations(KubernetesConfig config, BuildProducer<KubernetesAnnotationBuildItem> annotations) {
config.getAnnotations().forEach((k, v) -> {
annotations.produce(new KubernetesAnnotationBuildItem(k, v, KIND));
});
config.getAnnotations().forEach((k, v) -> annotations.produce(new KubernetesAnnotationBuildItem(k, v, KIND)));
}

@BuildStep
Expand All @@ -97,6 +96,17 @@ public List<ConfiguratorBuildItem> createConfigurators(KubernetesConfig config,
return result;
}

@BuildStep
public KubernetesEffectiveServiceAccountBuildItem computeEffectiveServiceAccounts(ApplicationInfoBuildItem applicationInfo,
KubernetesConfig config, List<KubernetesServiceAccountBuildItem> serviceAccountsFromExtensions,
BuildProducer<DecoratorBuildItem> decorators) {
final String name = ResourceNameUtil.getResourceName(config, applicationInfo);
return KubernetesCommonHelper.computeEffectiveServiceAccount(name, KIND,
config, serviceAccountsFromExtensions,
decorators);
}

@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@BuildStep
public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applicationInfo,
OutputTargetBuildItem outputTarget,
Expand All @@ -120,7 +130,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
Optional<KubernetesHealthStartupPathBuildItem> startupPath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesClusterRoleBuildItem> clusterRoles,
List<KubernetesServiceAccountBuildItem> serviceAccounts,
List<KubernetesEffectiveServiceAccountBuildItem> serviceAccounts,
List<KubernetesRoleBindingBuildItem> roleBindings,
Optional<CustomProjectRootBuildItem> customProjectRoot) {

Expand All @@ -133,7 +143,8 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
}

@BuildStep
public void postBuild(ContainerImageInfoBuildItem image, List<ContainerImageBuilderBuildItem> builders,
public void postBuild(ContainerImageInfoBuildItem image,
@SuppressWarnings("unused") List<ContainerImageBuilderBuildItem> builders,
@SuppressWarnings("unused") BuildProducer<ArtifactResultBuildItem> artifactResults) {
//We used to only perform the action below when using known builders that play nicely with kind (e.g. docker)
//However, this excluded users that are just using external tools for building including the cli (e.g. quarkus image build docker).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import io.quarkus.kubernetes.spi.KubernetesClusterRoleBuildItem;
import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem;
import io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem;
import io.quarkus.kubernetes.spi.KubernetesEffectiveServiceAccountBuildItem;
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
Expand Down Expand Up @@ -69,9 +70,7 @@ public void checkMinikube(ApplicationInfoBuildItem applicationInfo, KubernetesCo

@BuildStep
public void createAnnotations(KubernetesConfig config, BuildProducer<KubernetesAnnotationBuildItem> annotations) {
config.getAnnotations().forEach((k, v) -> {
annotations.produce(new KubernetesAnnotationBuildItem(k, v, MINIKUBE));
});
config.getAnnotations().forEach((k, v) -> annotations.produce(new KubernetesAnnotationBuildItem(k, v, MINIKUBE)));
}

@BuildStep
Expand All @@ -87,12 +86,22 @@ public void createLabels(KubernetesConfig config, BuildProducer<KubernetesLabelB
public List<ConfiguratorBuildItem> createConfigurators(KubernetesConfig config,
List<KubernetesPortBuildItem> ports) {
List<ConfiguratorBuildItem> result = new ArrayList<>();
KubernetesCommonHelper.combinePorts(ports, config).values().forEach(value -> {
result.add(new ConfiguratorBuildItem(new AddPortToKubernetesConfig(value)));
});
KubernetesCommonHelper.combinePorts(ports, config).values()
.forEach(value -> result.add(new ConfiguratorBuildItem(new AddPortToKubernetesConfig(value))));
return result;
}

@BuildStep
public KubernetesEffectiveServiceAccountBuildItem computeEffectiveServiceAccounts(ApplicationInfoBuildItem applicationInfo,
KubernetesConfig config, List<KubernetesServiceAccountBuildItem> serviceAccountsFromExtensions,
BuildProducer<DecoratorBuildItem> decorators) {
final String name = ResourceNameUtil.getResourceName(config, applicationInfo);
return KubernetesCommonHelper.computeEffectiveServiceAccount(name, MINIKUBE,
config, serviceAccountsFromExtensions,
decorators);
}

@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@BuildStep
public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applicationInfo,
OutputTargetBuildItem outputTarget,
Expand All @@ -116,7 +125,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
Optional<KubernetesHealthStartupPathBuildItem> startupPath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesClusterRoleBuildItem> clusterRoles,
List<KubernetesServiceAccountBuildItem> serviceAccounts,
List<KubernetesEffectiveServiceAccountBuildItem> serviceAccounts,
List<KubernetesRoleBindingBuildItem> roleBindings,
Optional<CustomProjectRootBuildItem> customProjectRoot) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.quarkus.kubernetes.spi;

import io.quarkus.builder.item.MultiBuildItem;

class BaseTargetable extends MultiBuildItem implements Targetable {
private final String target;

protected BaseTargetable(String target) {
this.target = target;
}

@Override
public String getTarget() {
return target;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io.quarkus.builder.item.MultiBuildItem;

public final class KubernetesAnnotationBuildItem extends MultiBuildItem {
public final class KubernetesAnnotationBuildItem extends MultiBuildItem implements Targetable {

private final String key;
private final String value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

import java.util.List;

import io.quarkus.builder.item.MultiBuildItem;

/**
* Produce this build item to request the Kubernetes extension to generate
* a Kubernetes {@code ClusterRole} resource.
*/
public final class KubernetesClusterRoleBuildItem extends MultiBuildItem {
public final class KubernetesClusterRoleBuildItem extends BaseTargetable {
/**
* Name of the generated {@code ClusterRole} resource.
*/
Expand All @@ -18,15 +16,10 @@ public final class KubernetesClusterRoleBuildItem extends MultiBuildItem {
*/
private final List<PolicyRule> rules;

/**
* The target manifest that should include this role.
*/
private final String target;

public KubernetesClusterRoleBuildItem(String name, List<PolicyRule> rules, String target) {
super(target);
this.name = name;
this.rules = rules;
this.target = target;
}

public String getName() {
Expand All @@ -36,8 +29,4 @@ public String getName() {
public List<PolicyRule> getRules() {
return rules;
}

public String getTarget() {
return target;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.quarkus.kubernetes.spi;

/**
* This build item is produced once the effective service account used for the generated resources is computed. Useful for
* downstream
* extensions that need to know this information to wait until it is made available.
*/
public final class KubernetesEffectiveServiceAccountBuildItem extends BaseTargetable {
private final String serviceAccountName;
private final String namespace;
private final boolean wasSet;

public KubernetesEffectiveServiceAccountBuildItem(String serviceAccountName, String namespace, boolean wasSet) {
this(serviceAccountName, namespace, wasSet, null);
}

public KubernetesEffectiveServiceAccountBuildItem(String serviceAccountName, String namespace, boolean wasSet,
String target) {
super(target);
this.serviceAccountName = serviceAccountName;
this.namespace = namespace;
this.wasSet = wasSet;
}

/**
* The effective service account name after all the build time configuration has taken effect
*
* @return the effective service account name as used in the generated manifests for the main application deployment
*/
public String getServiceAccountName() {
return serviceAccountName;
}

/**
* The effective service account namespace
*
* @return the effective service account name as used in the generated manifests for the main application deployment
*/
public String getNamespace() {
return namespace;
}

/**
* Determines whether the service account name is automatically derived from the application name as opposed to explicitly
* set by the user
*
* @return {@code true} if the service account is automatically derived from the application name, {@code false} if
* explicitly set by the user
*/
public boolean wasSet() {
return wasSet;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

package io.quarkus.kubernetes.spi;

import org.jboss.logging.Logger;
import java.util.Objects;

import io.quarkus.builder.item.MultiBuildItem;
import org.jboss.logging.Logger;

public final class KubernetesEnvBuildItem extends MultiBuildItem {
public final class KubernetesEnvBuildItem extends BaseTargetable {
private static final Logger log = Logger.getLogger(KubernetesEnvBuildItem.class);

public enum EnvType {
Expand All @@ -27,22 +27,14 @@ public boolean mightConflictWith(EnvType type) {
return true;
}

switch (this) {
case field:
return type == var || type == keyFromConfigmap || type == keyFromSecret;
case var:
return type == field || type == keyFromConfigmap || type == keyFromSecret;
case secret:
return type == configmap;
case configmap:
return type == secret;
case keyFromConfigmap:
return type == field || type == var || type == keyFromSecret;
case keyFromSecret:
return type == field || type == var || type == keyFromConfigmap;
default:
return false;
}
return switch (this) {
case field -> type == var || type == keyFromConfigmap || type == keyFromSecret;
case var -> type == field || type == keyFromConfigmap || type == keyFromSecret;
case secret -> type == configmap;
case configmap -> type == secret;
case keyFromConfigmap -> type == field || type == var || type == keyFromSecret;
case keyFromSecret -> type == field || type == var || type == keyFromConfigmap;
};
}
}

Expand All @@ -52,7 +44,6 @@ public boolean mightConflictWith(EnvType type) {
private final String secret;
private final String field;
private final EnvType type;
private final String target;
private final boolean oldStyle;
private final String prefix;

Expand Down Expand Up @@ -81,6 +72,7 @@ public static KubernetesEnvBuildItem createFromConfigMapKey(String varName, Stri
return create(varName, key, null, configmap, null, target, prefix, isOldStyle(oldStyle));
}

@SuppressWarnings("unused")
public static KubernetesEnvBuildItem createFromSecretKey(String varName, String key, String secret, String target,
String prefix, boolean... oldStyle) {
return create(varName, key, secret, null, null, target, prefix, isOldStyle(oldStyle));
Expand Down Expand Up @@ -146,13 +138,13 @@ private static boolean isOldStyle(boolean[] oldStyle) {

KubernetesEnvBuildItem(String name, String value, String configmap, String secret, String field, EnvType type,
String target, String prefix, boolean oldStyle) {
super(target);
this.name = name;
this.value = value;
this.configmap = configmap;
this.secret = secret;
this.field = field;
this.type = type;
this.target = target;
this.prefix = prefix;
this.oldStyle = oldStyle;
}
Expand Down Expand Up @@ -185,36 +177,27 @@ public EnvType getType() {
return type;
}

public String getTarget() {
return target;
}

public String getPrefix() {
return prefix;
}

@SuppressWarnings("unused")
public KubernetesEnvBuildItem newWithTarget(String newTarget) {
return new KubernetesEnvBuildItem(this.name, this.value, this.configmap, this.secret, this.field, this.type, newTarget,
this.prefix, this.oldStyle);
}

public String toString() {
switch (type) {
case var:
return String.format("'%s' env var with value '%s'", name, value);
case field:
return String.format("'%s' env var with value from field '%s'", name, field);
case secret:
return "all values from '" + secret + "' secret";
case configmap:
return "all values from '" + configmap + "' configmap";
case keyFromConfigmap:
return String.format("'%s' env var with value from '%s' key of '%s' configmap", name, value, configmap);
case keyFromSecret:
return String.format("'%s' env var with value from '%s' key of '%s' secret", name, value, secret);
default:
return "unknown type '" + type + "'";
}
return switch (type) {
case var -> String.format("'%s' env var with value '%s'", name, value);
case field -> String.format("'%s' env var with value from field '%s'", name, field);
case secret -> "all values from '" + secret + "' secret";
case configmap -> "all values from '" + configmap + "' configmap";
case keyFromConfigmap ->
String.format("'%s' env var with value from '%s' key of '%s' configmap", name, value, configmap);
case keyFromSecret ->
String.format("'%s' env var with value from '%s' key of '%s' secret", name, value, secret);
};
}

@Override
Expand All @@ -228,15 +211,15 @@ public boolean equals(Object o) {

if (!name.equals(that.name))
return false;
if (value != null ? !value.equals(that.value) : that.value != null)
if (!Objects.equals(value, that.value))
return false;
if (configmap != null ? !configmap.equals(that.configmap) : that.configmap != null)
if (!Objects.equals(configmap, that.configmap))
return false;
if (secret != null ? !secret.equals(that.secret) : that.secret != null)
if (!Objects.equals(secret, that.secret))
return false;
if (field != null ? !field.equals(that.field) : that.field != null)
if (!Objects.equals(field, that.field))
return false;
if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null)
if (!Objects.equals(prefix, that.prefix))
return false;
return type == that.type;
}
Expand Down
Loading

0 comments on commit cddc49d

Please sign in to comment.