From e9eab678a38a6d304975f14d6051981428bbffa0 Mon Sep 17 00:00:00 2001 From: Lars Wander Date: Wed, 15 Nov 2017 18:30:56 -0500 Subject: [PATCH] feat(provider/kubernetes): search result hydrators (#2124) --- .../kubernetes/v2/caching/Keys.java | 4 + .../caching/KubernetesV2SearchProvider.java | 80 +++++++++++++++---- .../view/model/KubernetesV2SecurityGroup.java | 3 +- .../KubernetesSpinnakerKindMap.java | 10 +++ .../v2/op/deployer/KubernetesHandler.java | 11 +++ .../op/deployer/KubernetesIngressHandler.java | 11 +++ .../v2/op/deployer/KubernetesPodHandler.java | 12 +++ .../deployer/KubernetesReplicaSetHandler.java | 10 +++ .../op/deployer/KubernetesServiceHandler.java | 10 +++ .../KubernetesStatefulSetHandler.java | 10 +++ 10 files changed, 143 insertions(+), 18 deletions(-) diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/Keys.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/Keys.java index 6275ad7b451..6430715fd6b 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/Keys.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/Keys.java @@ -17,6 +17,7 @@ package com.netflix.spinnaker.clouddriver.kubernetes.v2.caching; +import com.fasterxml.jackson.annotation.JsonCreator; import com.netflix.spinnaker.clouddriver.kubernetes.KubernetesCloudProvider; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest; @@ -46,6 +47,7 @@ public String toString() { return name().toLowerCase(); } + @JsonCreator public static Kind fromString(String name) { return Arrays.stream(values()) .filter(k -> k.toString().equalsIgnoreCase(name)) @@ -72,6 +74,7 @@ public String singular() { return name.substring(0, name.length() - 1); } + @JsonCreator public static LogicalKind fromString(String name) { return Arrays.stream(values()) .filter(k -> k.toString().equalsIgnoreCase(name)) @@ -159,6 +162,7 @@ public static abstract class CacheKey { public abstract String getName(); } + @EqualsAndHashCode(callSuper = true) @Data public static abstract class LogicalKey extends CacheKey { private Kind kind = Kind.LOGICAL; diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/KubernetesV2SearchProvider.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/KubernetesV2SearchProvider.java index b061b4954fd..c6dc3dcb464 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/KubernetesV2SearchProvider.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/KubernetesV2SearchProvider.java @@ -23,6 +23,8 @@ import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys.LogicalKey; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys.LogicalKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.view.provider.KubernetesCacheUtils; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesResourceProperties; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesResourcePropertyRegistry; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesSpinnakerKindMap; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import com.netflix.spinnaker.clouddriver.search.SearchProvider; @@ -51,21 +53,31 @@ public class KubernetesV2SearchProvider implements SearchProvider { final private KubernetesCacheUtils cacheUtils; final private ObjectMapper mapper; final private KubernetesSpinnakerKindMap kindMap; + final private KubernetesResourcePropertyRegistry registry; final private List defaultTypes; - final private Set logicalTypes; + final private Set logicalTypes; + final private Set allCaches; @Autowired - public KubernetesV2SearchProvider(KubernetesCacheUtils cacheUtils, KubernetesSpinnakerKindMap kindMap, ObjectMapper mapper) { + public KubernetesV2SearchProvider(KubernetesCacheUtils cacheUtils, + KubernetesSpinnakerKindMap kindMap, + ObjectMapper mapper, + KubernetesResourcePropertyRegistry registry) { this.cacheUtils = cacheUtils; this.mapper = mapper; this.kindMap = kindMap; + this.registry = registry; this.defaultTypes = kindMap.allKubernetesKinds() .stream() .map(KubernetesKind::toString) .collect(Collectors.toList()); this.logicalTypes = Arrays.stream(LogicalKind.values()) + .map(LogicalKind::toString) .collect(Collectors.toSet()); + + this.allCaches = new HashSet<>(defaultTypes); + this.allCaches.addAll(logicalTypes); } @Override @@ -110,28 +122,43 @@ private Map convertKeyToMap(String key) { } Keys.CacheKey parsedKey = optional.get(); - Map result = mapper.convertValue(parsedKey, new TypeReference>() {}); + Map result; + String type; if (parsedKey instanceof Keys.InfrastructureCacheKey) { Keys.InfrastructureCacheKey infraKey = (Keys.InfrastructureCacheKey) parsedKey; - result.put("type", kindMap.translateKubernetesKind(infraKey.getKubernetesKind()).toString()); - result.put("region", infraKey.getNamespace()); + type = kindMap.translateKubernetesKind(infraKey.getKubernetesKind()).toString(); + + KubernetesResourceProperties properties = registry.get(infraKey.getKubernetesKind()); + if (properties == null) { + log.warn("No hydrator for type {}, this is possibly a developer error", infraKey.getKubernetesKind()); + return null; + } + + result = properties.getHandler().hydrateSearchResult(infraKey, cacheUtils); + } else if (parsedKey instanceof Keys.LogicalKey) { + Keys.LogicalKey logicalKey = (Keys.LogicalKey) parsedKey; + + result = mapper.convertValue(parsedKey, new TypeReference>() {}); + result.put(logicalKey.getLogicalKind().singular(), logicalKey.getName()); + type = parsedKey.getGroup(); } else { - result.put("type", parsedKey.getGroup()); + log.warn("Unknown key type " + parsedKey + ", ignoring."); + return null; } + result.put("type", type); return result; } private Map> getKeysRelatedToLogicalMatches(String matchQuery) { return logicalTypes.stream() - .map(type -> cacheUtils.getAllDataMatchingPattern(type.toString(), matchQuery) + .map(type -> cacheUtils.getAllDataMatchingPattern(type, matchQuery) .stream() .map(e -> e.getRelationships() .values() .stream() - .map(Collection::stream) - .flatMap(x -> x) + .flatMap(Collection::stream) .filter(Objects::nonNull) .map(k -> new ImmutablePair<>(k, e.getId())) ).flatMap(x -> x) @@ -152,18 +179,38 @@ private Map> getKeysRelatedToLogicalMatches(String matchQue ); } + // TODO(lwander): use filters private List> getMatches(String query, List types, Map filters) { String matchQuery = String.format("*%s*", query.toLowerCase()); Set typeSet = new HashSet<>(types); - List> results = types.stream() + // We add k8s versions of Spinnaker types here to ensure that (for example) replica sets are returned when server groups are requested. + typeSet.addAll(types.stream() + .map(t -> { + try { + return KubernetesSpinnakerKindMap.SpinnakerKind.fromString(t); + } catch (IllegalArgumentException e) { + return null; + } + }).filter(Objects::nonNull) + .map(kindMap::translateSpinnakerKind) + .flatMap(Collection::stream) + .map(KubernetesKind::toString) + .collect(Collectors.toSet()) + ); + + // Remove caches that we can't search + typeSet.retainAll(allCaches); + + // Search caches directly + List> results = typeSet.stream() .map(type -> cacheUtils.getAllKeysMatchingPattern(type, matchQuery)) - .map(Collection::stream) - .flatMap(x -> x) + .flatMap(Collection::stream) .map(this::convertKeyToMap) .filter(Objects::nonNull) .collect(Collectors.toList()); + // Search 'logical' caches (clusters, apps) for indirect matches Map> keyToAllLogicalKeys = getKeysRelatedToLogicalMatches(matchQuery); results.addAll(keyToAllLogicalKeys.entrySet().stream() .map(kv -> { @@ -178,18 +225,17 @@ private List> getMatches(String query, List types, M .map(Optional::get) .filter(LogicalKey.class::isInstance) .map(k -> (LogicalKey) k) - .forEach(k -> { - result.put(k.getLogicalKind().singular(), k.getName()); - }); + .forEach(k -> result.put(k.getLogicalKind().singular(), k.getName())); return result; } ) - .filter(r -> typeSet.contains(r.get("type"))) .collect(Collectors.toList())); - log.info("Found {} keys matching {}", results.size(), query); + results = results.stream() + .filter(r -> typeSet.contains(r.get("type")) || typeSet.contains(r.get("group"))) + .collect(Collectors.toList()); return results; } diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/view/model/KubernetesV2SecurityGroup.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/view/model/KubernetesV2SecurityGroup.java index c09df0077c3..d6ac57ed10e 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/view/model/KubernetesV2SecurityGroup.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/view/model/KubernetesV2SecurityGroup.java @@ -136,11 +136,12 @@ private static class KubernetesV2SecurityGroupSummary implements SecurityGroupSu } @Data - public static class PortRule implements Rule { + private static class PortRule implements Rule { private SortedSet portRanges; private String protocol; } + @EqualsAndHashCode(callSuper = true) @Data public static class StringPortRange extends Rule.PortRange { protected String startPortName; diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/description/KubernetesSpinnakerKindMap.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/description/KubernetesSpinnakerKindMap.java index 5369a10c20a..61c12337ed5 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/description/KubernetesSpinnakerKindMap.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/description/KubernetesSpinnakerKindMap.java @@ -17,9 +17,11 @@ package com.netflix.spinnaker.clouddriver.kubernetes.v2.description; +import com.fasterxml.jackson.annotation.JsonCreator; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import org.springframework.stereotype.Component; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -45,6 +47,14 @@ public enum SpinnakerKind { public String toString() { return id; } + + @JsonCreator + public static SpinnakerKind fromString(String name) { + return Arrays.stream(values()) + .filter(k -> k.toString().equalsIgnoreCase(name)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("No matching kind with name " + name + " exists")); + } } private Map> spinnakerToKubernetes = new HashMap<>(); diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesHandler.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesHandler.java index ed27b64ae90..ce89f9300b7 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesHandler.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesHandler.java @@ -17,10 +17,13 @@ package com.netflix.spinnaker.clouddriver.kubernetes.v2.op.deployer; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.netflix.spinnaker.clouddriver.deploy.DeploymentResult; import com.netflix.spinnaker.clouddriver.kubernetes.v2.artifact.ArtifactReplacer; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesV2CachingAgent; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.view.provider.KubernetesCacheUtils; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesSpinnakerKindMap.SpinnakerKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest; @@ -35,6 +38,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; public abstract class KubernetesHandler { @Autowired @@ -73,4 +77,11 @@ public DeploymentResult deployAugmentedManifest(KubernetesV2Credentials credenti protected void deploy(KubernetesV2Credentials credentials, KubernetesManifest manifest) { credentials.deploy(manifest); } + + public Map hydrateSearchResult(Keys.InfrastructureCacheKey key, KubernetesCacheUtils cacheUtils) { + Map result = objectMapper.convertValue(key, new TypeReference>() {}); + result.put("region", key.getNamespace()); + result.put("name", KubernetesManifest.getFullResourceName(key.getKubernetesKind(), key.getName())); + return result; + } } diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesIngressHandler.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesIngressHandler.java index d11e119c9ce..fd03a743898 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesIngressHandler.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesIngressHandler.java @@ -17,9 +17,11 @@ package com.netflix.spinnaker.clouddriver.kubernetes.v2.op.deployer; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesCacheDataConverter; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesIngressCachingAgent; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesV2CachingAgent; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.view.provider.KubernetesCacheUtils; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesSpinnakerKindMap.SpinnakerKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest; @@ -33,6 +35,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; @Component @@ -92,4 +95,12 @@ private static List attachedServices(V1beta1Ingress ingress) { return new ArrayList<>(result); } + + @Override + public Map hydrateSearchResult(Keys.InfrastructureCacheKey key, KubernetesCacheUtils cacheUtils) { + Map result = super.hydrateSearchResult(key, cacheUtils); + result.put("loadBalancer", result.get("name")); + + return result; + } } diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesPodHandler.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesPodHandler.java index 3ef6da4eb19..23e6cf74c17 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesPodHandler.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesPodHandler.java @@ -17,14 +17,18 @@ package com.netflix.spinnaker.clouddriver.kubernetes.v2.op.deployer; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesPodCachingAgent; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesV2CachingAgent; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.view.provider.KubernetesCacheUtils; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesSpinnakerKindMap.SpinnakerKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest; import com.netflix.spinnaker.clouddriver.model.Manifest.Status; import org.springframework.stereotype.Component; +import java.util.Map; + @Component public class KubernetesPodHandler extends KubernetesHandler implements CanDelete { @Override @@ -47,6 +51,14 @@ public Status status(KubernetesManifest manifest) { return Status.stable(); } + @Override + public Map hydrateSearchResult(Keys.InfrastructureCacheKey key, KubernetesCacheUtils cacheUtils) { + Map result = super.hydrateSearchResult(key, cacheUtils); + result.put("instanceId", result.get("name")); + + return result; + } + @Override public Class cachingAgentClass() { return KubernetesPodCachingAgent.class; diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesReplicaSetHandler.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesReplicaSetHandler.java index e5e9e314f86..d8c96e9f195 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesReplicaSetHandler.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesReplicaSetHandler.java @@ -19,9 +19,11 @@ import com.netflix.spinnaker.clouddriver.kubernetes.v2.artifact.ArtifactReplacer.Replacer; import com.netflix.spinnaker.clouddriver.kubernetes.v2.artifact.ArtifactTypes; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesCacheDataConverter; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesReplicaSetCachingAgent; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesV2CachingAgent; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.view.provider.KubernetesCacheUtils; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesSpinnakerKindMap.SpinnakerKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest; @@ -150,4 +152,12 @@ private static Map getPodTemplateLabels(V1beta1ReplicaSet replic private static Map getPodTemplateLabels(V1beta2ReplicaSet replicaSet) { return replicaSet.getSpec().getTemplate().getMetadata().getLabels(); } + + @Override + public Map hydrateSearchResult(Keys.InfrastructureCacheKey key, KubernetesCacheUtils cacheUtils) { + Map result = super.hydrateSearchResult(key, cacheUtils); + result.put("serverGroup", result.get("name")); + + return result; + } } diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesServiceHandler.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesServiceHandler.java index 5edafa11397..14ce4c62b42 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesServiceHandler.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesServiceHandler.java @@ -17,9 +17,11 @@ package com.netflix.spinnaker.clouddriver.kubernetes.v2.op.deployer; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesCacheDataConverter; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesServiceCachingAgent; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesV2CachingAgent; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.view.provider.KubernetesCacheUtils; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesSpinnakerKindMap.SpinnakerKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest; @@ -65,4 +67,12 @@ public static Map getSelector(KubernetesManifest manifest) { throw new IllegalArgumentException("No services with version " + manifest.getApiVersion() + " supported"); } } + + @Override + public Map hydrateSearchResult(Keys.InfrastructureCacheKey key, KubernetesCacheUtils cacheUtils) { + Map result = super.hydrateSearchResult(key, cacheUtils); + result.put("loadBalancer", result.get("name")); + + return result; + } } diff --git a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesStatefulSetHandler.java b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesStatefulSetHandler.java index 083477f1275..046cd34c190 100644 --- a/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesStatefulSetHandler.java +++ b/clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/op/deployer/KubernetesStatefulSetHandler.java @@ -17,8 +17,10 @@ package com.netflix.spinnaker.clouddriver.kubernetes.v2.op.deployer; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.Keys; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesStatefulSetCachingAgent; import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.agent.KubernetesV2CachingAgent; +import com.netflix.spinnaker.clouddriver.kubernetes.v2.caching.view.provider.KubernetesCacheUtils; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.KubernetesSpinnakerKindMap.SpinnakerKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesKind; import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest; @@ -60,4 +62,12 @@ public static String serviceName(KubernetesManifest manifest) { Map spec = (Map) manifest.get("spec"); return (String) spec.get("serviceName"); } + + @Override + public Map hydrateSearchResult(Keys.InfrastructureCacheKey key, KubernetesCacheUtils cacheUtils) { + Map result = super.hydrateSearchResult(key, cacheUtils); + result.put("serverGroup", result.get("name")); + + return result; + } }