feat(provider/kubernetes): split kubernetes pod logs by container
MODIFY
clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/view/AppengineInstanceProvider.groovy
clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/view/AppengineInstanceProvider.groovy
@@ -32,7 +32,7 @@ import static com.netflix.spinnaker.clouddriver.appengine.cache.Keys.Namespace.L
import static com.netflix.spinnaker.clouddriver.appengine.cache.Keys.Namespace.SERVER_GROUPS
@Component
-class AppengineInstanceProvider implements InstanceProvider<AppengineInstance> {
+class AppengineInstanceProvider implements InstanceProvider<AppengineInstance, String> {
@Autowired
Cache cacheView

MODIFY
clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonInstanceProvider.groovy
clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/provider/view/AmazonInstanceProvider.groovy
@@ -35,7 +35,7 @@ import static com.netflix.spinnaker.clouddriver.core.provider.agent.Namespace.IN
import static com.netflix.spinnaker.clouddriver.core.provider.agent.Namespace.SERVER_GROUPS
@Component
-class AmazonInstanceProvider implements InstanceProvider<AmazonInstance> {
+class AmazonInstanceProvider implements InstanceProvider<AmazonInstance, String> {
final String cloudProvider = AmazonCloudProvider.ID
private final Cache cacheView

MODIFY
clouddriver-azure/src/main/groovy/com/netflix/spinnaker/clouddriver/azure/resources/servergroup/view/AzureInstanceProvider.groovy
clouddriver-azure/src/main/groovy/com/netflix/spinnaker/clouddriver/azure/resources/servergroup/view/AzureInstanceProvider.groovy
@@ -29,7 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@Component
-class AzureInstanceProvider implements InstanceProvider<AzureInstance> {
+class AzureInstanceProvider implements InstanceProvider<AzureInstance, String> {
final String cloudProvider = AzureCloudProvider.ID
private final AzureCloudProvider azureCloudProvider
private final Cache cacheView

ADD
clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/model/ContainerLog.java
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.netflix.spinnaker.clouddriver.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@Data
+@NoArgsConstructor
+public class ContainerLog {
+ private String name;
+ private String output;
+}

MODIFY
clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/model/InstanceProvider.groovy
clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/model/InstanceProvider.groovy
package com.netflix.spinnaker.clouddriver.model
-interface InstanceProvider<T extends Instance> {
+interface InstanceProvider<T extends Instance, S> {
/**
* Returns the platform the instance provider
@@ -26,5 +26,5 @@ interface InstanceProvider<T extends Instance> {
T getInstance(String account, String region, String id)
- String getConsoleOutput(String account, String region, String id)
+ S getConsoleOutput(String account, String region, String id)
}

MODIFY
clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/model/NoopInstanceProvider.groovy
clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/model/NoopInstanceProvider.groovy
package com.netflix.spinnaker.clouddriver.model
-class NoopInstanceProvider implements InstanceProvider<Instance> {
+class NoopInstanceProvider implements InstanceProvider<Instance, String> {
final String cloudProvider = "none"

MODIFY
clouddriver-dcos/src/main/groovy/com/netflix/spinnaker/clouddriver/dcos/provider/view/DcosInstanceProvider.groovy
clouddriver-dcos/src/main/groovy/com/netflix/spinnaker/clouddriver/dcos/provider/view/DcosInstanceProvider.groovy
@@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@Component
-class DcosInstanceProvider implements InstanceProvider<DcosInstance> {
+class DcosInstanceProvider implements InstanceProvider<DcosInstance, String> {
private final Cache cacheView
private final ObjectMapper objectMapper

MODIFY
clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsInstanceProvider.java
clouddriver-ecs/src/main/java/com/netflix/spinnaker/clouddriver/ecs/view/EcsInstanceProvider.java
@@ -34,7 +34,7 @@ import java.util.List;
import java.util.Map;
@Component
-public class EcsInstanceProvider implements InstanceProvider<EcsTask> {
+public class EcsInstanceProvider implements InstanceProvider<EcsTask, String> {
private final TaskCacheClient taskCacheClient;
private final ContainerInstanceCacheClient containerInstanceCacheClient;

MODIFY
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/provider/view/GoogleInstanceProvider.groovy
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/provider/view/GoogleInstanceProvider.groovy
@@ -39,7 +39,7 @@ import static com.netflix.spinnaker.clouddriver.google.cache.Keys.Namespace.*
@Component
@Slf4j
-class GoogleInstanceProvider implements InstanceProvider<GoogleInstance.View>, GoogleExecutorTraits {
+class GoogleInstanceProvider implements InstanceProvider<GoogleInstance.View, String>, GoogleExecutorTraits {
@Autowired
final Cache cacheView

MODIFY
clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v1/provider/view/KubernetesV1InstanceProvider.groovy
clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v1/provider/view/KubernetesV1InstanceProvider.groovy
@@ -24,6 +24,7 @@ import com.netflix.spinnaker.clouddriver.kubernetes.security.KubernetesNamedAcco
import com.netflix.spinnaker.clouddriver.kubernetes.v1.caching.Keys
import com.netflix.spinnaker.clouddriver.kubernetes.v1.model.KubernetesV1Instance
import com.netflix.spinnaker.clouddriver.kubernetes.v1.security.KubernetesV1Credentials
+import com.netflix.spinnaker.clouddriver.model.ContainerLog
import com.netflix.spinnaker.clouddriver.model.InstanceProvider
import com.netflix.spinnaker.clouddriver.security.AccountCredentialsProvider
import com.netflix.spinnaker.clouddriver.security.ProviderVersion
@@ -33,7 +34,7 @@ import org.springframework.stereotype.Component
@Slf4j
@Component
-class KubernetesV1InstanceProvider implements InstanceProvider<KubernetesV1Instance> {
+class KubernetesV1InstanceProvider implements InstanceProvider<KubernetesV1Instance, List<ContainerLog>> {
private final Cache cacheView
private final ObjectMapper objectMapper
@@ -76,7 +77,7 @@ class KubernetesV1InstanceProvider implements InstanceProvider<KubernetesV1Insta
}
@Override
- String getConsoleOutput(String account, String region, String id) {
+ List<ContainerLog> getConsoleOutput(String account, String region, String id) {
KubernetesNamedAccountCredentials<KubernetesV1Credentials> credentials;
try {
credentials = (KubernetesNamedAccountCredentials) accountCredentialsProvider.getCredentials(account)
@@ -95,20 +96,21 @@ class KubernetesV1InstanceProvider implements InstanceProvider<KubernetesV1Insta
}
String podName = pod.getMetadata().getName()
- StringBuilder result = new StringBuilder()
+ List<ContainerLog> result = new ArrayList()
pod.getSpec().getContainers().collect { container ->
- result.append("===== ${container.getName()} =====\n\n")
+ ContainerLog log = new ContainerLog()
+ log.setName(container.getName())
try {
- String log = trueCredentials.apiAdaptor.getLog(region, podName, container.getName())
- result.append(log)
+ String logOutput = trueCredentials.apiAdaptor.getLog(region, podName, container.getName())
+ log.setOutput(logOutput)
} catch(Exception e){
- result.append(e.getMessage())
+ log.setOutput(e.getMessage())
}
- result.append("\n\n")
+ result.add(log)
}
- return result.toString()
+ return result
}
}

MODIFY
clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/view/provider/KubernetesV2InstanceProvider.java
clouddriver-kubernetes/src/main/groovy/com/netflix/spinnaker/clouddriver/kubernetes/v2/caching/view/provider/KubernetesV2InstanceProvider.java
@@ -28,6 +28,7 @@ import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.Kube
import com.netflix.spinnaker.clouddriver.kubernetes.v2.description.manifest.KubernetesManifest;
import com.netflix.spinnaker.clouddriver.kubernetes.v2.op.job.KubectlJobExecutor;
import com.netflix.spinnaker.clouddriver.kubernetes.v2.security.KubernetesV2Credentials;
+import com.netflix.spinnaker.clouddriver.model.ContainerLog;
import com.netflix.spinnaker.clouddriver.model.InstanceProvider;
import com.netflix.spinnaker.clouddriver.security.AccountCredentialsRepository;
import com.netflix.spinnaker.clouddriver.security.ProviderVersion;
@@ -38,11 +39,13 @@ import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
@Component
@Slf4j
-public class KubernetesV2InstanceProvider implements InstanceProvider<KubernetesV2Instance> {
+public class KubernetesV2InstanceProvider implements InstanceProvider<KubernetesV2Instance, List<ContainerLog>> {
private final KubernetesCacheUtils cacheUtils;
private final KubernetesSpinnakerKindMap kindMap;
private final AccountCredentialsRepository accountCredentialsRepository;
@@ -88,7 +91,7 @@ public class KubernetesV2InstanceProvider implements InstanceProvider<Kubernetes
}
@Override
- public String getConsoleOutput(String account, String location, String fullName) {
+ public List<ContainerLog> getConsoleOutput(String account, String location, String fullName) {
KubernetesNamedAccountCredentials<KubernetesV2Credentials> credentials;
try {
credentials = (KubernetesNamedAccountCredentials) accountCredentialsRepository.getOne(account);
@@ -115,20 +118,21 @@ public class KubernetesV2InstanceProvider implements InstanceProvider<Kubernetes
V1Pod.class
);
- StringBuilder result = new StringBuilder();
+ List<ContainerLog> result = new ArrayList();
// Make live calls rather than abuse the cache for storing all logs
for (V1Container container : pod.getSpec().getContainers()) {
- result.append("====== " + container.getName() + " ======\n\n");
+ ContainerLog log = new ContainerLog();
+ log.setName(container.getName());
try {
- result.append(credentials.getCredentials().logs(location, name, container.getName()));
+ log.setOutput(credentials.getCredentials().logs(location, name, container.getName()));
} catch (KubectlJobExecutor.KubectlException e) {
// Typically happens if the container/pod isn't running yet
- result.append(e.getMessage());
+ log.setOutput(e.getMessage());
}
- result.append("\n\n");
+ result.add(log);
}
- return result.toString();
+ return result;
}
}

MODIFY
clouddriver-openstack/src/main/groovy/com/netflix/spinnaker/clouddriver/openstack/provider/view/OpenstackInstanceProvider.groovy
clouddriver-openstack/src/main/groovy/com/netflix/spinnaker/clouddriver/openstack/provider/view/OpenstackInstanceProvider.groovy
@@ -35,7 +35,7 @@ import static com.netflix.spinnaker.clouddriver.openstack.cache.Keys.Namespace.I
import static com.netflix.spinnaker.clouddriver.openstack.cache.Keys.Namespace.LOAD_BALANCERS
@Component
-class OpenstackInstanceProvider implements InstanceProvider<OpenstackInstance.View> {
+class OpenstackInstanceProvider implements InstanceProvider<OpenstackInstance.View, String> {
final String cloudProvider = OpenstackCloudProvider.ID
final Cache cacheView
final AccountCredentialsProvider accountCredentialsProvider

MODIFY
clouddriver-oracle/src/main/groovy/com/netflix/spinnaker/clouddriver/oracle/provider/view/OracleInstanceProvider.groovy
clouddriver-oracle/src/main/groovy/com/netflix/spinnaker/clouddriver/oracle/provider/view/OracleInstanceProvider.groovy
@@ -28,7 +28,7 @@ import static com.netflix.spinnaker.clouddriver.oracle.cache.Keys.Namespace.INST
@Slf4j
@Component
-class OracleInstanceProvider implements InstanceProvider<OracleInstance> {
+class OracleInstanceProvider implements InstanceProvider<OracleInstance, String> {
private final Cache cacheView
final ObjectMapper objectMapper

MODIFY
clouddriver-titus/src/main/groovy/com/netflix/spinnaker/clouddriver/titus/caching/providers/TitusInstanceProvider.groovy
clouddriver-titus/src/main/groovy/com/netflix/spinnaker/clouddriver/titus/caching/providers/TitusInstanceProvider.groovy
@@ -40,7 +40,7 @@ import static com.netflix.spinnaker.clouddriver.core.provider.agent.Namespace.IN
import static com.netflix.spinnaker.clouddriver.titus.caching.Keys.Namespace.SERVER_GROUPS
@Component
-class TitusInstanceProvider implements InstanceProvider<TitusInstance> {
+class TitusInstanceProvider implements InstanceProvider<TitusInstance, String> {
final String cloudProvider = TitusCloudProvider.ID
private final Cache cacheView
private final ObjectMapper objectMapper

MODIFY
clouddriver-web/src/main/groovy/com/netflix/spinnaker/clouddriver/controllers/InstanceController.groovy
clouddriver-web/src/main/groovy/com/netflix/spinnaker/clouddriver/controllers/InstanceController.groovy
@@ -60,7 +60,7 @@ class InstanceController {
@PathVariable String region,
@PathVariable String id) {
String providerParam = cloudProvider ?: provider
- Collection<String> outputs = instanceProviders.findResults {
+ Collection outputs = instanceProviders.findResults {
if (!providerParam || it.cloudProvider == providerParam) {
return it.getConsoleOutput(account, region, id)
}

feat(provider/kubernetes): split kubernetes pod logs by container (#3017)