From 67271348c373a262fd37dc9b6c83e609481edd4d Mon Sep 17 00:00:00 2001 From: Daniel Peach Date: Fri, 12 Jan 2018 12:50:57 -0500 Subject: [PATCH] feat(provider/kubernetes): look up namer by class name --- .../clouddriver/core/CloudDriverConfig.groovy | 8 ++++++++ .../spinnaker/clouddriver/names/NamerRegistry.java | 13 +++++++++++++ .../spinnaker/clouddriver/names/NamingStrategy.java | 7 +++++++ .../config/KubernetesConfigurationProperties.groovy | 3 ++- .../security/KubernetesNamedAccountCredentials.java | 11 +++++++++-- ...ernetesNamedAccountCredentialsInitializer.groovy | 3 +++ .../caching/agent/KubernetesCacheDataConverter.java | 12 +++++++++++- .../v2/names/KubernetesManifestNamer.java | 11 +++++++++-- .../agent/KubernetesCacheDataConvertSpec.groovy | 10 ++++++++++ 9 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/names/NamingStrategy.java diff --git a/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/core/CloudDriverConfig.groovy b/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/core/CloudDriverConfig.groovy index 01ecdddfc91..ea552ff9a1f 100644 --- a/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/core/CloudDriverConfig.groovy +++ b/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/core/CloudDriverConfig.groovy @@ -56,6 +56,8 @@ import com.netflix.spinnaker.clouddriver.model.SecurityGroupProvider import com.netflix.spinnaker.clouddriver.model.ServerGroupManager import com.netflix.spinnaker.clouddriver.model.ServerGroupManagerProvider import com.netflix.spinnaker.clouddriver.model.SubnetProvider +import com.netflix.spinnaker.clouddriver.names.NamerRegistry +import com.netflix.spinnaker.clouddriver.names.NamingStrategy import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperationConverter import com.netflix.spinnaker.clouddriver.search.ApplicationSearchProvider import com.netflix.spinnaker.clouddriver.search.NoopSearchProvider @@ -66,6 +68,7 @@ import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository import com.netflix.spinnaker.clouddriver.security.DefaultAccountCredentialsProvider import com.netflix.spinnaker.clouddriver.security.MapBackedAccountCredentialsRepository import com.netflix.spinnaker.kork.core.RetrySupport +import com.netflix.spinnaker.moniker.Namer import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.ConfigurationProperties @@ -256,4 +259,9 @@ class CloudDriverConfig { public RetrySupport retrySupport() { return new RetrySupport(); } + + @Bean + NamerRegistry namerRegistry(List namingStrategies) { + new NamerRegistry(namingStrategies) + } } diff --git a/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/names/NamerRegistry.java b/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/names/NamerRegistry.java index c6b6d5142e0..2c1ad51f67e 100644 --- a/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/names/NamerRegistry.java +++ b/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/names/NamerRegistry.java @@ -21,6 +21,7 @@ import com.netflix.spinnaker.moniker.frigga.FriggaReflectiveNamer; import lombok.extern.slf4j.Slf4j; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; /** @@ -31,6 +32,7 @@ * must happen within Spinnaker. */ public class NamerRegistry { + final private List namingStrategies; private static Namer defaultNamer = new FriggaReflectiveNamer(); private static ProviderLookup providerLookup = new ProviderLookup(); @@ -42,6 +44,17 @@ public static ProviderLookup lookup() { return providerLookup; } + public NamerRegistry(List namingStrategies) { + this.namingStrategies = namingStrategies; + } + + public Namer getNamingStrategy(String strategyName) { + return this.namingStrategies.stream() + .filter(strategy -> strategy.getName().equalsIgnoreCase(strategyName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Could not find naming strategy '" + strategyName + "'")); + } + @Slf4j public static class ResourceLookup { private ConcurrentHashMap map = new ConcurrentHashMap<>(); diff --git a/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/names/NamingStrategy.java b/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/names/NamingStrategy.java new file mode 100644 index 00000000000..96a8562793e --- /dev/null +++ b/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/names/NamingStrategy.java @@ -0,0 +1,7 @@ +package com.netflix.spinnaker.clouddriver.names; + +import com.netflix.spinnaker.moniker.Namer; + +public interface NamingStrategy extends Namer { + String getName(); +} diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/config/KubernetesConfigurationProperties.groovy b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/config/KubernetesConfigurationProperties.groovy index afcbd12f7fd..61666269f46 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/config/KubernetesConfigurationProperties.groovy +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/config/KubernetesConfigurationProperties.groovy @@ -42,7 +42,8 @@ class KubernetesConfigurationProperties { List dockerRegistries List requiredGroupMembership Permissions.Builder permissions = new Permissions.Builder() - Boolean debug = false; + String namingStrategy = "kubernetesAnnotations" + Boolean debug = false } List accounts = [] diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/security/KubernetesNamedAccountCredentials.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/security/KubernetesNamedAccountCredentials.java index a67be6472a9..90a84e6179e 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/security/KubernetesNamedAccountCredentials.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/security/KubernetesNamedAccountCredentials.java @@ -29,6 +29,7 @@ import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository; import com.netflix.spinnaker.clouddriver.security.ProviderVersion; import com.netflix.spinnaker.fiat.model.resources.Permissions; +import com.netflix.spinnaker.moniker.Namer; import groovy.util.logging.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -175,6 +176,7 @@ static class Builder { Registry spectatorRegistry; AccountCredentialsRepository accountCredentialsRepository; KubectlJobExecutor jobExecutor; + Namer namer; boolean debug; Builder name(String name) { @@ -233,7 +235,7 @@ Builder kubeconfigFile(String kubeconfigFile) { } Builder serviceAccount(Boolean serviceAccount) { - this.serviceAccount = serviceAccount;; + this.serviceAccount = serviceAccount; return this; } @@ -300,6 +302,11 @@ Builder debug(boolean debug) { return this; } + Builder namer(Namer namer) { + this.namer = namer; + return this; + } + private C buildCredentials() { switch (providerVersion) { case v1: @@ -322,7 +329,7 @@ private C buildCredentials() { NamerRegistry.lookup() .withProvider(KubernetesCloudProvider.getID()) .withAccount(name) - .setNamer(KubernetesManifest.class, new KubernetesManifestNamer()); + .setNamer(KubernetesManifest.class, namer); return (C) new KubernetesV2Credentials.Builder() .accountName(name) .kubeconfigFile(kubeconfigFile) diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/security/KubernetesNamedAccountCredentialsInitializer.groovy b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/security/KubernetesNamedAccountCredentialsInitializer.groovy index cf269baa8b9..b0c6192ae62 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/security/KubernetesNamedAccountCredentialsInitializer.groovy +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/security/KubernetesNamedAccountCredentialsInitializer.groovy @@ -21,6 +21,7 @@ import com.netflix.spinnaker.cats.module.CatsModule import com.netflix.spinnaker.cats.provider.ProviderSynchronizerTypeWrapper import com.netflix.spinnaker.clouddriver.kubernetes.config.KubernetesConfigurationProperties import com.netflix.spinnaker.clouddriver.kubernetes.v2.op.job.KubectlJobExecutor +import com.netflix.spinnaker.clouddriver.names.NamerRegistry import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository import com.netflix.spinnaker.clouddriver.security.CredentialsInitializerSynchronizable import com.netflix.spinnaker.clouddriver.security.ProviderUtils @@ -39,6 +40,7 @@ class KubernetesNamedAccountCredentialsInitializer implements CredentialsInitial @Autowired Registry spectatorRegistry @Autowired KubectlJobExecutor jobExecutor + @Autowired NamerRegistry namerRegistry @Bean List kubernetesNamedAccountCredentials( @@ -96,6 +98,7 @@ class KubernetesNamedAccountCredentialsInitializer implements CredentialsInitial .permissions(managedAccount.permissions.build()) .spectatorRegistry(spectatorRegistry) .jobExecutor(jobExecutor) + .namer(namerRegistry.getNamingStrategy(managedAccount.namingStrategy)) .debug(managedAccount.debug) .build() diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/agent/KubernetesCacheDataConverter.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/agent/KubernetesCacheDataConverter.java index 4af9d351c7f..2fcfcaede8c 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/agent/KubernetesCacheDataConverter.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/agent/KubernetesCacheDataConverter.java @@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableMap; import com.netflix.spinnaker.cats.cache.CacheData; import com.netflix.spinnaker.cats.cache.DefaultCacheData; +import com.netflix.spinnaker.clouddriver.kubernetes.KubernetesCloudProvider; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesApiVersion; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesCachingProperties; @@ -29,8 +30,11 @@ import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifestAnnotater; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifestMetadata; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifestSpinnakerRelationships; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.names.KubernetesManifestNamer; +import com.netflix.spinnaker.clouddriver.names.NamerRegistry; import com.netflix.spinnaker.kork.artifacts.model.Artifact; import com.netflix.spinnaker.moniker.Moniker; +import com.netflix.spinnaker.moniker.Namer; import io.kubernetes.client.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -152,7 +156,13 @@ public static CacheData convertAsResource(String account, KubernetesManifest man KubernetesApiVersion apiVersion = manifest.getApiVersion(); String name = manifest.getName(); String namespace = manifest.getNamespace(); - Moniker moniker = KubernetesManifestAnnotater.getMoniker(manifest); + Namer namer = account == null + ? new KubernetesManifestNamer() + : NamerRegistry.lookup() + .withProvider(KubernetesCloudProvider.getID()) + .withAccount(account) + .withResource(KubernetesManifest.class); + Moniker moniker = namer.deriveMoniker(manifest); Map attributes = new ImmutableMap.Builder() .put("kind", kind) diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/names/KubernetesManifestNamer.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/names/KubernetesManifestNamer.java index a16763c6d05..6c795ecbc2d 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/names/KubernetesManifestNamer.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/names/KubernetesManifestNamer.java @@ -19,10 +19,17 @@ import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifestAnnotater; +import com.netflix.spinnaker.clouddriver.names.NamingStrategy; import com.netflix.spinnaker.moniker.Moniker; -import com.netflix.spinnaker.moniker.Namer; +import org.springframework.stereotype.Component; + +@Component +public class KubernetesManifestNamer implements NamingStrategy { + @Override + public String getName() { + return "kubernetesAnnotations"; + } -public class KubernetesManifestNamer implements Namer { @Override public void applyMoniker(KubernetesManifest obj, Moniker moniker) { KubernetesManifestAnnotater.annotateManifest(obj, moniker); diff --git a/clouddriver-kubernetes/src/test/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/agent/KubernetesCacheDataConvertSpec.groovy b/clouddriver-kubernetes/src/test/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/agent/KubernetesCacheDataConvertSpec.groovy index aa2b98db1b8..28faef49424 100644 --- a/clouddriver-kubernetes/src/test/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/agent/KubernetesCacheDataConvertSpec.groovy +++ b/clouddriver-kubernetes/src/test/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/agent/KubernetesCacheDataConvertSpec.groovy @@ -19,6 +19,7 @@ package com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent import com.fasterxml.jackson.databind.ObjectMapper import com.netflix.spinnaker.cats.cache.DefaultCacheData +import com.netflix.spinnaker.clouddriver.kubernetes.KubernetesCloudProvider import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesApiVersion import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind @@ -26,6 +27,8 @@ import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.Kube import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifestAnnotater import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifestMetadata import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifestSpinnakerRelationships +import com.netflix.spinnaker.clouddriver.kubernetes.v2.names.KubernetesManifestNamer +import com.netflix.spinnaker.clouddriver.names.NamerRegistry import com.netflix.spinnaker.kork.artifacts.model.Artifact import com.netflix.spinnaker.moniker.Moniker import org.apache.commons.lang3.tuple.Pair @@ -58,6 +61,13 @@ metadata: .cluster(cluster) .build() + if (account != null) { + NamerRegistry.lookup() + .withProvider(KubernetesCloudProvider.ID) + .withAccount(account) + .setNamer(KubernetesManifest, new KubernetesManifestNamer()) + } + def manifest = stringToManifest(rawManifest) KubernetesManifestAnnotater.annotateManifest(manifest, moniker)