Skip to content

Commit 3511578

Browse files
a-erdosbdpiprava
authored andcommitted
Add support for multiple containers on status report page.
1 parent 4672983 commit 3511578

File tree

4 files changed

+239
-88
lines changed

4 files changed

+239
-88
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package cd.go.contrib.elasticagent.model.reports.agent;
2+
3+
public class GoCDContainerLog {
4+
private String name;
5+
private String content;
6+
7+
public GoCDContainerLog(String name, String content) {
8+
this.name = name;
9+
this.content = content;
10+
}
11+
12+
public String getName() {
13+
return name;
14+
}
15+
16+
public String getContent() {
17+
return content;
18+
}
19+
}

src/main/java/cd/go/contrib/elasticagent/model/reports/agent/KubernetesElasticAgent.java

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.fasterxml.jackson.core.JsonProcessingException;
2222
import com.fasterxml.jackson.databind.ObjectMapper;
2323
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
24+
import io.fabric8.kubernetes.api.model.Container;
2425
import io.fabric8.kubernetes.api.model.ContainerStatus;
2526
import io.fabric8.kubernetes.api.model.Event;
2627
import io.fabric8.kubernetes.api.model.Pod;
@@ -32,10 +33,10 @@
3233
public class KubernetesElasticAgent {
3334
private JobIdentifier jobIdentifier;
3435
private KubernetesPodDetails podDetails;
35-
private GoCDContainerDetails agentDetails;
36+
private ArrayList<GoCDContainerDetails> containerDetails;
3637
private String elasticAgentId;
3738
private ArrayList<KubernetesPodEvent> events;
38-
private String logs;
39+
private ArrayList<GoCDContainerLog> containerLogs;
3940
private String configuration;
4041

4142
public static KubernetesElasticAgent fromPod(KubernetesClient client, Pod pod, JobIdentifier jobIdentifier) {
@@ -44,14 +45,33 @@ public static KubernetesElasticAgent fromPod(KubernetesClient client, Pod pod, J
4445
agent.elasticAgentId = pod.getMetadata().getName();
4546
agent.podDetails = KubernetesPodDetails.fromPod(pod);
4647
List<ContainerStatus> containerStatuses = pod.getStatus().getContainerStatuses();
47-
ContainerStatus containerStatus = containerStatuses.isEmpty() ? null : containerStatuses.get(0);
48-
agent.agentDetails = GoCDContainerDetails.fromContainer(pod.getSpec().getContainers().get(0), containerStatus);
48+
agent.containerDetails = getContainerDetails(pod.getSpec().getContainers(), containerStatuses);
4949
agent.events = getAllEventsForPod(pod, client);
50-
agent.logs = getPodLogs(pod, client);
50+
agent.containerLogs = getContainerLogs(client, pod, containerStatuses);
5151
agent.configuration = getPodConfiguration(pod);
5252
return agent;
5353
}
5454

55+
private static ArrayList<GoCDContainerDetails> getContainerDetails(List<Container> containers, List<ContainerStatus> containerStatuses) {
56+
ArrayList<GoCDContainerDetails> details = new ArrayList<>();
57+
for(ContainerStatus status: containerStatuses) {
58+
details.add(GoCDContainerDetails.fromContainer(getContainerSpecByName(containers, status.getName()), status));
59+
}
60+
return details;
61+
}
62+
63+
private static Container getContainerSpecByName(List<Container> containers, String name) {
64+
return containers.stream().filter(container -> container.getName().equals(name)).findFirst().get();
65+
}
66+
67+
private static ArrayList<GoCDContainerLog> getContainerLogs(KubernetesClient client, Pod pod, List<ContainerStatus> containerStatuses) {
68+
ArrayList<GoCDContainerLog> logs = new ArrayList<>();
69+
for(ContainerStatus containerStatus: containerStatuses) {
70+
logs.add(new GoCDContainerLog(containerStatus.getName(), getPodLogs(pod, client, containerStatus.getName())));
71+
}
72+
return logs;
73+
}
74+
5575
private static JobIdentifier getJobIdentifier(Pod pod, JobIdentifier jobIdentifier) {
5676
if (jobIdentifier != null) {
5777
return jobIdentifier;
@@ -68,12 +88,12 @@ public KubernetesPodDetails getPodDetails() {
6888
return podDetails;
6989
}
7090

71-
public GoCDContainerDetails getAgentDetails() {
72-
return agentDetails;
91+
public ArrayList<GoCDContainerDetails> getContainerDetails() {
92+
return containerDetails;
7393
}
7494

75-
public String getLogs() {
76-
return logs;
95+
public ArrayList<GoCDContainerLog> getContainerLogs() {
96+
return containerLogs;
7797
}
7898

7999
public String getConfiguration() {
@@ -108,9 +128,9 @@ private static ArrayList<KubernetesPodEvent> getAllEventsForPod(Pod pod, Kuberne
108128
return events;
109129
}
110130

111-
private static String getPodLogs(Pod pod, KubernetesClient client) {
131+
private static String getPodLogs(Pod pod, KubernetesClient client, String containerName) {
112132
return client.pods()
113-
.withName(pod.getMetadata().getName()).getLog(true);
133+
.withName(pod.getMetadata().getName()).inContainer(containerName).getLog(true);
114134
}
115135

116136
private static String getPodConfiguration(Pod pod) {

src/main/resources/agent-status-report.template.ftlh

Lines changed: 169 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,17 @@
5959
padding: 10px;
6060
}
6161

62-
[data-plugin-style-id="kubernetes-plugin"] .tab-content.pod-logs {
62+
[data-plugin-style-id="kubernetes-plugin"] .log-content {
6363
background-color: #383838;
6464
font-size: 13px;
65+
border-radius: 0px 0px 5px 5px;
6566
font-family: monaco;
6667
color: white;
6768
display: block;
6869
font-weight: 400;
6970
padding-left: 10px;
7071
max-height: 100%;
72+
height: calc(100vh - 280px);
7173
}
7274

7375
[data-plugin-style-id="kubernetes-plugin"] .pod-configuration {
@@ -84,6 +86,13 @@
8486
padding: 5px;
8587
}
8688

89+
[data-plugin-style-id="kubernetes-plugin"] .details-panel {
90+
background: #F6F6F6;
91+
border-radius: 4px;
92+
padding: 5px 15px 5px 15px;
93+
margin-top: 10px;
94+
}
95+
8796
[data-plugin-style-id="kubernetes-plugin"] .tab-content {
8897
margin-top: 0;
8998
height: calc(100vh - 280px);
@@ -228,6 +237,60 @@
228237
font-size: 13px;
229238
line-height: 25px;
230239
}
240+
241+
[data-plugin-style-id="kubernetes-plugin"] .container-log {
242+
border: none;
243+
width: 100%;
244+
background: #fff;
245+
border-radius: 5px;
246+
margin-bottom: 10px;
247+
overflow: hidden;
248+
}
249+
250+
[data-plugin-style-id="kubernetes-plugin"] .container-log-header {
251+
background: #d1c4e9;
252+
padding: 10px;
253+
font-size: 14px;
254+
font-weight: 600;
255+
cursor: pointer;
256+
}
257+
258+
[data-plugin-style-id="kubernetes-plugin"] .container-log-header .left {
259+
float: left;
260+
padding: 0px;
261+
}
262+
263+
[data-plugin-style-id="kubernetes-plugin"] .container-log-header .right {
264+
float: right;
265+
padding: 5px;
266+
padding-right: 10px;
267+
}
268+
269+
[data-plugin-style-id="kubernetes-plugin"] .container-name {
270+
padding: 5px 5px;
271+
margin: 0px 0px 0px 25px;
272+
color: #666 !important;
273+
font-weight: 600 !important;
274+
overflow: hidden;
275+
text-overflow: ellipsis;
276+
}
277+
278+
[data-plugin-style-id="kubernetes-plugin"] dl.name {
279+
overflow: hidden;
280+
margin: 0;
281+
font-size: 13px;
282+
display: inline-block;
283+
vertical-align: top;
284+
padding-left: 10px;
285+
}
286+
287+
[data-plugin-style-id="kubernetes-plugin"] dt {
288+
float: left;
289+
clear: both;
290+
padding: 5px 0px;
291+
margin: 0px 0px 0px 25px;
292+
font-weight: 600;
293+
}
231294
</style>
232295

233296
<div data-plugin-style-id="kubernetes-plugin">
@@ -286,79 +349,85 @@
286349
<div class="tab-content-outer">
287350
<div class="tab-content" ng-show="currenttab == 'pod-details'">
288351
<h4 class="header no-margin-top">Pod Details</h4>
289-
<ul class="name-value">
290-
<li class="name-value_pair">
291-
<label>Pod name</label>
292-
<span>${ podDetails.name !}</span>
293-
</li>
294-
<li class="name-value_pair">
295-
<label>Cluster Name</label>
296-
<span>${ podDetails.clusterName !}</span>
297-
</li>
298-
<li class="name-value_pair">
299-
<label>Node Name</label>
300-
<span>${ podDetails.nodeName !}</span>
301-
</li>
302-
<li class="name-value_pair">
303-
<label>Namespace</label>
304-
<span>${ podDetails.namespace !}</span>
305-
</li>
306-
<li class="name-value_pair">
307-
<label>Creation Timestamp</label>
308-
<span>${ podDetails.createdAt !}</span>
309-
</li>
310-
<li class="name-value_pair">
311-
<label>Start Timestamp</label>
312-
<span>${ podDetails.startedAt !}</span>
313-
</li>
314-
<li class="name-value_pair">
315-
<label>Conditions</label>
316-
<span>${ podDetails.conditions !}</span>
317-
</li>
318-
<li class="name-value_pair">
319-
<label>Status</label>
320-
<span>${ podDetails.phase !}</span>
321-
</li>
322-
<li class="name-value_pair">
323-
<label>Pod IP</label>
324-
<span>${ podDetails.podIP !}</span>
325-
</li>
326-
<li class="name-value_pair">
327-
<label>Host IP</label>
328-
<span>${ podDetails.hostIP !}</span>
329-
</li>
352+
<div class="details-panel">
353+
<ul class="name-value">
354+
<li class="name-value_pair">
355+
<label>Pod name</label>
356+
<span>${ podDetails.name !}</span>
357+
</li>
358+
<li class="name-value_pair">
359+
<label>Cluster Name</label>
360+
<span>${ podDetails.clusterName !}</span>
361+
</li>
362+
<li class="name-value_pair">
363+
<label>Node Name</label>
364+
<span>${ podDetails.nodeName !}</span>
365+
</li>
366+
<li class="name-value_pair">
367+
<label>Namespace</label>
368+
<span>${ podDetails.namespace !}</span>
369+
</li>
370+
<li class="name-value_pair">
371+
<label>Creation Timestamp</label>
372+
<span>${ podDetails.createdAt !}</span>
373+
</li>
374+
<li class="name-value_pair">
375+
<label>Start Timestamp</label>
376+
<span>${ podDetails.startedAt !}</span>
377+
</li>
378+
<li class="name-value_pair">
379+
<label>Conditions</label>
380+
<span>${ podDetails.conditions !}</span>
381+
</li>
382+
<li class="name-value_pair">
383+
<label>Status</label>
384+
<span>${ podDetails.phase !}</span>
385+
</li>
386+
<li class="name-value_pair">
387+
<label>Pod IP</label>
388+
<span>${ podDetails.podIP !}</span>
389+
</li>
390+
<li class="name-value_pair">
391+
<label>Host IP</label>
392+
<span>${ podDetails.hostIP !}</span>
393+
</li>
394+
</div>
330395
</ul>
331396
<h4 class="header">GoCD Agent Details</h4>
332-
<ul class="name-value">
333-
<li class="name-value_pair">
334-
<label>Name</label>
335-
<span>${ agentDetails.name !}</span>
336-
</li>
337-
<li class="name-value_pair">
338-
<label>Image</label>
339-
<span>${ agentDetails.image !}</span>
340-
</li>
341-
<li class="name-value_pair">
342-
<label>ImagePullPolicy</label>
343-
<span>${ agentDetails.imagePullPolicy !}</span>
344-
</li>
345-
<li class="name-value_pair">
346-
<label>Ready</label>
347-
<span>${ agentDetails.ready !}</span>
348-
</li>
349-
<li class="name-value_pair">
350-
<label>Restart Count</label>
351-
<span>${ agentDetails.restartCount !}</span>
352-
</li>
353-
<li class="name-value_pair">
354-
<label>Command</label>
355-
<span>${ agentDetails.command?html?replace("\n", "<br>") !}</span>
356-
</li>
357-
<li class="name-value_pair">
358-
<label>Environment Variables</label>
359-
<span>${ agentDetails.env?html?replace("\n", "<br>") !}</span>
360-
</li>
361-
</ul>
397+
<#list containerDetails as detail>
398+
<div class="details-panel">
399+
<ul class="name-value">
400+
<li class="name-value_pair">
401+
<label>Container Name</label>
402+
<span>${ detail.name !}</span>
403+
</li>
404+
<li class="name-value_pair">
405+
<label>Image</label>
406+
<span>${ detail.image !}</span>
407+
</li>
408+
<li class="name-value_pair">
409+
<label>ImagePullPolicy</label>
410+
<span>${ detail.imagePullPolicy !}</span>
411+
</li>
412+
<li class="name-value_pair">
413+
<label>Ready</label>
414+
<span>${ detail.ready !}</span>
415+
</li>
416+
<li class="name-value_pair">
417+
<label>Restart Count</label>
418+
<span>${ detail.restartCount !}</span>
419+
</li>
420+
<li class="name-value_pair">
421+
<label>Command</label>
422+
<span>${ detail.command?html?replace("\n", "<br>") !}</span>
423+
</li>
424+
<li class="name-value_pair">
425+
<label>Environment Variables</label>
426+
<span>${ detail.env?html?replace("\n", "<br>") !}</span>
427+
</li>
428+
</ul>
429+
</div>
430+
</#list>
362431
</div>
363432
<div class="tab-content pod-events" ng-show="currenttab == 'pod-events'">
364433
<#if events?size != 0>
@@ -392,8 +461,34 @@
392461
<div class="warning-message">No events available for the current pod.</div>
393462
</#if>
394463
</div>
395-
<textarea class="tab-content pod-logs" ng-show="currenttab == 'pod-logs'"
396-
readonly>${ logs?html?trim !}</textarea>
464+
<div class="tab-content pod-logs" ng-show="currenttab == 'pod-logs'">
465+
<#if containerLogs?size != 0>
466+
<#list containerLogs as containerLog>
467+
<#assign containerIndex = containerLog?index>
468+
<#assign ngModel = "containerLog${containerIndex}">
469+
<div class="container-log">
470+
<div class="container-log-header row" ng-click="${ngModel} = !${ngModel}" ngModel="${ngModel}"
471+
ng-value="false" ng-init="${ngModel} = ${(containerIndex == 0)?then('true','false')}">
472+
<div class="left">
473+
<dl class="name inline">
474+
<dt>Container Name:</dt>
475+
<dd class="container-name">${containerLog.name!}</dd>
476+
</dl>
477+
</div>
478+
<div class="right">
479+
<i class="fa fa-chevron-down" aria-hidden="true" ng-show="${ngModel}"></i>
480+
<i class="fa fa-chevron-right" aria-hidden="true" ng-hide="${ngModel}"></i>
481+
</div>
482+
</div>
483+
<div ng-show="${ngModel}">
484+
<textarea class="log-content" readonly>${ containerLog.content?html?trim !}</textarea>
485+
</div>
486+
</div>
487+
</#list>
488+
<#else>
489+
<div class="warning-message">No container logs in current pod.</div>
490+
</#if>
491+
</div>
397492
<div class="tab-content pod-configuration"
398493
ng-show="currenttab == 'pod-configuration'">${ configuration?html?trim?replace("\n", "<br>") !}
399494
</div>

0 commit comments

Comments
 (0)