Skip to content

Commit

Permalink
K8s client staging (#1831)
Browse files Browse the repository at this point in the history
* feature(provider/kubernetes) : Adding support for Stateful set for new Caching agent using new java client library (splited the code)

* feature(provider/kubernetes) : Adding support for Stateful set for new Caching agent using new java client library (Statefulset Part 1)

* feature(provider/kubernetes) : Adding support for Stateful set for new Caching agent using new java client library (Statefulset Part 1)

* feature(provider/kubernetes) : Adding support for Stateful set for new Caching agent using new java client library (Statefulset Part 1) Removed Unwanted code

* feature(provider/kubernetes) : Indentation Issue Fixed

* feature(provider/kubernetes) : Adding support for Stateful set for new Caching agent using new java client library (Statefulset Part 2)

* feature(provider/kubernetes) : Adding support for Stateful set for new Caching agent using new java client library (Statefulset Part 2)

* feature(provider/kubernetes) : Adding support for Stateful set for new Caching agent using new java client library (Statefulset Part 2)

* feature(provider/kubernetes) : In order to see Statefulset in Spinnaker UI we need to have loadbalancer details also as its throw null pointer at com.netflix.spinnaker.clouddriver.controllers.ApplicationsController on line no: 101 (result.clusters[account] << new ApplicationClusterViewModel(name: cluster.name, loadBalancers: cluster.loadBalancers.name as TreeSet, serverGroups: cluster.serverGroups*.name as TreeSet, provider: cluster.type) at this call 'cluster.loadBalancers.name')

* feature(provider/kubernetes) : Added Persistance Volume Claim for StatefulSet

* feature(provider/kubernetes) : 1) Removed V1PersistentVolumeClaim (Added the right implementation) 2) Removed extra Space

* feature(provider/kubernetes) : 1) Adding DaemonSets Support (Part 1)2) in order to accommodate new controller , created new generic  KubernatesController in KubernetesControllersCachingAgent

* feature(provider/kubernetes) : 1) Incorporated the Review comments (Pull Request 1831) 2) DaemonSetsSpec doesnot support Replicas : Checked the Documentation (V1beta1DaemonSetSpec.md)
  • Loading branch information
prashantvicky authored and lwander committed Aug 24, 2017
1 parent c3e4a82 commit 98ec60e
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import io.kubernetes.client.ApiException
import io.kubernetes.client.Configuration
import io.kubernetes.client.apis.AppsV1beta1Api
import io.kubernetes.client.models.*
import io.kubernetes.client.apis.ExtensionsV1beta1Api

import java.util.concurrent.TimeUnit

Expand All @@ -40,6 +41,7 @@ class KubernetesClientApiAdapter {
final Clock spectatorClock
final ApiClient client
final AppsV1beta1Api apiInstance
final ExtensionsV1beta1Api extApi

public spectatorRegistry() { return spectatorRegistry }

Expand All @@ -55,6 +57,7 @@ class KubernetesClientApiAdapter {
client = config.getApiCient()
Configuration.setDefaultApiClient(client)
apiInstance = new AppsV1beta1Api();
extApi = new ExtensionsV1beta1Api()
}

KubernetesOperationException formatException(String operation, String namespace, ApiException e) {
Expand Down Expand Up @@ -134,4 +137,11 @@ class KubernetesClientApiAdapter {
return statefulSets
}
}

List<V1beta1StatefulSet> getDaemonSets(String namespace) {
exceptionWrapper("daemonSets.list", "Get Daemon Sets", namespace) {
V1beta1DaemonSetList list = extApi.listNamespacedDaemonSet(namespace, null, null, null, null, API_CALL_TIMEOUT_SECONDS, null)
return list.items
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import com.netflix.spinnaker.clouddriver.kubernetes.deploy.description.servergro
import com.netflix.spinnaker.clouddriver.kubernetes.deploy.description.servergroup.KubernetesHttpGetAction
import com.netflix.spinnaker.clouddriver.kubernetes.deploy.description.servergroup.KeyValuePair
import com.netflix.spinnaker.clouddriver.kubernetes.deploy.description.servergroup.KubernetesTcpSocketAction
import io.fabric8.kubernetes.api.model.KeyToPath
import io.kubernetes.client.models.V1KeyToPath
import io.kubernetes.client.models.V1Container
import io.kubernetes.client.models.V1Probe
import io.kubernetes.client.models.V1Volume
Expand Down Expand Up @@ -209,8 +209,8 @@ class KubernetesClientApiConverter {
res.secret = new KubernetesSecretVolumeSource(secretName: volume.secret.secretName)
} else if (volume.configMap) {
res.type = KubernetesVolumeSourceType.ConfigMap
def items = volume.configMap.items?.collect { KeyToPath item ->
new KubernetesKeyToPath(key: item.key, path: item.path)
def items = volume.configMap.items?.collect { V1KeyToPath item ->
new KubernetesKeyToPath(key: item.key, path: item.path)
}
res.configMap = new KubernetesConfigMapVolumeSource(configMapName: volume.configMap.name, items: items)
} else if (volume.awsElasticBlockStore) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import io.fabric8.kubernetes.api.model.ReplicationController
import io.fabric8.kubernetes.api.model.HorizontalPodAutoscaler
import io.fabric8.kubernetes.api.model.extensions.ReplicaSet
import io.fabric8.kubernetes.client.internal.SerializationUtils
import io.kubernetes.client.models.V1beta1DaemonSet
import io.kubernetes.client.models.V1beta1StatefulSet

@CompileStatic
Expand Down Expand Up @@ -126,6 +127,31 @@ class KubernetesServerGroup implements ServerGroup, Serializable {
}
}

KubernetesServerGroup(V1beta1DaemonSet daemonSet, String account, List<Event> events) {
this.name = daemonSet.metadata?.name
this.account = account
this.region = daemonSet.metadata?.namespace
this.namespace = this.region
this.createdTime = daemonSet.metadata?.creationTimestamp?.getMillis()
this.zones = [this.region] as Set
this.securityGroups = []
/**
* DaemonSetsSpec doesnot support Replicas : Checked the Documentation (V1beta1DaemonSetSpec.md)
* Thats why i think its not required
*/
//this.replicas = daemonSet.spec?.replicas ?: 0
this.launchConfig = [:]
this.labels = daemonSet.spec?.template?.metadata?.labels
/**
* Will fetch this valu in next Pull Request
*/
//this.deployDescription = KubernetesClientApiConverter.fromStatefulSet(daemonSet)
this.kind = daemonSet.kind
this.events = events?.collect {
new KubernetesEvent(it)
}
}

KubernetesServerGroup(ReplicaSet replicaSet, String account, List<Event> events, HorizontalPodAutoscaler autoscaler) {
this.name = replicaSet.metadata?.name
this.account = account
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import com.netflix.spinnaker.clouddriver.kubernetes.cache.Keys
import com.netflix.spectator.api.Registry
import groovy.util.logging.Slf4j
import io.fabric8.kubernetes.api.model.Event
import io.kubernetes.client.models.V1beta1DaemonSet
import io.kubernetes.client.models.V1beta1StatefulSet

/**
Expand Down Expand Up @@ -89,8 +90,12 @@ class KubernetesControllersCachingAgent extends KubernetesCachingAgent implement
loadStatefulSets()
}

V1beta1DaemonSet daemonSet = metricsSupport.readData {
loadDaemonSets()
}

CacheResult result = metricsSupport.transformData {
buildCacheResult([new StateFulSet(statefulSet: statefulSet)], [:], [], Long.MAX_VALUE)
buildCacheResult([new KubernetesController(controller: statefulSet,controller1: daemonSet)], [:], [], Long.MAX_VALUE)
}
def jsonResult = objectMapper.writeValueAsString(result.cacheResults)

Expand All @@ -115,7 +120,7 @@ class KubernetesControllersCachingAgent extends KubernetesCachingAgent implement
}
}
// Evict this server group if it no longer exists.
Map<String, Collection<String>> evictions = statefulSet ? [:] : [
Map<String, Collection<String>> evictions = statefulSet | daemonSet ? [:] : [
(Keys.Namespace.SERVER_GROUPS.ns): [
Keys.getServerGroupKey(accountName, namespace, serverGroupName)
]
Expand Down Expand Up @@ -154,8 +159,11 @@ class KubernetesControllersCachingAgent extends KubernetesCachingAgent implement
reloadNamespaces()
Long start = System.currentTimeMillis()
List<V1beta1StatefulSet> statefulSet = loadStatefulSets()
List<StateFulSet> serverGroups = (statefulSet.collect {
it ? new StateFulSet(statefulSet: it) : null
List<V1beta1DaemonSet> daemonSet = loadDaemonSets()
List<KubernetesController> serverGroups = (statefulSet.collect {
it ? new KubernetesController(controller: it) : null
}+ daemonSet.collect {
it ? new KubernetesController(controller: it) : null
}
) - null
List<CacheData> evictFromOnDemand = []
Expand Down Expand Up @@ -198,7 +206,13 @@ class KubernetesControllersCachingAgent extends KubernetesCachingAgent implement
}.flatten()
}

private CacheResult buildCacheResult(List<StateFulSet> serverGroups, Map<String, CacheData> onDemandKeep, List<String> onDemandEvict, Long start) {
List<V1beta1DaemonSet> loadDaemonSets() {
namespaces.collect { String namespace ->
credentials.apiClientAdaptor.getDaemonSets(namespace)
}.flatten()
}

private CacheResult buildCacheResult(List<KubernetesController> serverGroups, Map<String, CacheData> onDemandKeep, List<String> onDemandEvict, Long start) {
log.info("Describing items in ${agentType}")

Map<String, MutableCacheData> cachedApplications = MutableCacheData.mutableCacheMap()
Expand All @@ -208,17 +222,19 @@ class KubernetesControllersCachingAgent extends KubernetesCachingAgent implement
Map<String, MutableCacheData> cachedLoadBalancers = MutableCacheData.mutableCacheMap()

Map<String, Map<String, Event>> stateFulsetEvents = [:].withDefault { _ -> [:] }
Map<String, Map<String, Event>> daemonsetEvents = [:].withDefault { _ -> [:] }

try {
namespaces.each { String namespace ->
stateFulsetEvents[namespace] = credentials.apiAdaptor.getEvents(namespace, "V1beta1StatefulSet")
daemonsetEvents[namespace] = credentials.apiAdaptor.getEvents(namespace, "V1beta1DaemonSet")

}
} catch (Exception e) {
log.warn "Failure fetching events for all server groups in $namespaces", e
}

for (StateFulSet serverGroup: serverGroups) {
for (KubernetesController serverGroup: serverGroups) {
if (!serverGroup.exists()) {
continue
}
Expand Down Expand Up @@ -262,11 +278,12 @@ class KubernetesControllersCachingAgent extends KubernetesCachingAgent implement
def events = null
attributes.name = serverGroupName

if (serverGroup.statefulSet) {

if (serverGroup.controller instanceof V1beta1StatefulSet) {
events = stateFulsetEvents[serverGroup.namespace][serverGroupName]
} else if (serverGroup.controller instanceof V1beta1DaemonSet) {
events = daemonsetEvents[serverGroup.namespace][serverGroupName]
}
attributes.serverGroup = new KubernetesServerGroup(serverGroup.statefulSet, accountName, events)
attributes.serverGroup = new KubernetesServerGroup(serverGroup.controller, accountName, events)
relationships[Keys.Namespace.APPLICATIONS.ns].add(applicationKey)
relationships[Keys.Namespace.CLUSTERS.ns].add(clusterKey)
relationships[Keys.Namespace.INSTANCES.ns].addAll(instanceKeys)
Expand Down Expand Up @@ -307,28 +324,27 @@ class KubernetesControllersCachingAgent extends KubernetesCachingAgent implement
}
}

class StateFulSet{
class KubernetesController{

V1beta1StatefulSet statefulSet
def controller
String getName() {
statefulSet.metadata.name
controller.metadata.name
}

String getNamespace() {
statefulSet.metadata.namespace
controller.metadata.namespace
}

Map<String, String> getSelector() {
statefulSet.spec.selector.matchLabels
controller.spec.selector.matchLabels
}

boolean exists() {
statefulSet
controller
}

List<String> getLoadBalancers() {
KubernetesUtil.getLoadBalancers(statefulSet.spec?.template?.metadata?.labels ?: [:])
KubernetesUtil.getLoadBalancers(controller.spec?.template?.metadata?.labels ?: [:])
}

}
}

0 comments on commit 98ec60e

Please sign in to comment.