16
16
17
17
package cd .go .contrib .elasticagent ;
18
18
19
- import cd .go .contrib .elasticagent .requests .CreateAgentRequest ;
20
- import cd .go .contrib .elasticagent .utils .Size ;
21
- import cd .go .contrib .elasticagent .utils .Util ;
22
- import com .fasterxml .jackson .databind .ObjectMapper ;
23
- import com .fasterxml .jackson .dataformat .yaml .YAMLFactory ;
24
- import com .github .mustachejava .DefaultMustacheFactory ;
25
- import com .github .mustachejava .Mustache ;
26
- import com .github .mustachejava .MustacheFactory ;
27
- import io .fabric8 .kubernetes .api .model .*;
28
19
import io .fabric8 .kubernetes .client .KubernetesClient ;
29
- import org .apache .commons .lang3 .StringUtils ;
30
20
import org .joda .time .DateTime ;
31
21
import org .joda .time .DateTimeZone ;
32
22
33
- import java .io .IOException ;
34
- import java .io .StringReader ;
35
- import java .io .StringWriter ;
36
- import java .text .ParseException ;
37
- import java .text .SimpleDateFormat ;
38
- import java .util .*;
39
-
40
- import static cd .go .contrib .elasticagent .Constants .KUBERNETES_POD_CREATION_TIME_FORMAT ;
41
- import static cd .go .contrib .elasticagent .KubernetesPlugin .LOG ;
42
- import static cd .go .contrib .elasticagent .executors .GetProfileMetadataExecutor .POD_CONFIGURATION ;
43
- import static cd .go .contrib .elasticagent .utils .Util .getSimpleDateFormat ;
44
- import static org .apache .commons .lang3 .StringUtils .isBlank ;
23
+ import java .util .Map ;
45
24
46
25
public class KubernetesInstance {
47
26
private final DateTime createdAt ;
48
27
private final String environment ;
28
+ private final String name ;
49
29
private final Map <String , String > properties ;
50
- private String name ;
30
+ private final Long jobId ;
51
31
52
- private KubernetesInstance (String name , Date createdAt , String environment , Map <String , String > properties ) {
53
- this .name = name ;
54
- this .createdAt = new DateTime (createdAt ).withZone (DateTimeZone .UTC );
32
+ public KubernetesInstance (DateTime createdAt , String environment , String name , Map <String , String > properties , Long jobId ) {
33
+ this .createdAt = createdAt .withZone (DateTimeZone .UTC );
55
34
this .environment = environment ;
35
+ this .name = name ;
56
36
this .properties = properties ;
37
+ this .jobId = jobId ;
57
38
}
58
39
59
- public static KubernetesInstance create (CreateAgentRequest request , PluginSettings settings , KubernetesClient client , PluginRequest pluginRequest ) {
60
- String containerName = Constants .KUBERNETES_POD_NAME + UUID .randomUUID ().toString ();
61
-
62
- Container container = new Container ();
63
- container .setName (containerName );
64
- container .setImage (image (request .properties ()));
65
- container .setImagePullPolicy ("IfNotPresent" );
66
-
67
- ResourceRequirements resources = new ResourceRequirements ();
68
- resources .setLimits (new HashMap <String , Quantity >() {{
69
- String maxMemory = request .properties ().get ("MaxMemory" );
70
- if (StringUtils .isNotBlank (maxMemory )) {
71
- LOG .debug (String .format ("[Create Agent] Setting memory resource limit on k8s pod:%s" , maxMemory ));
72
- Size mem = Size .parse (maxMemory );
73
- put ("memory" , new Quantity (String .valueOf (mem .toMegabytes ()), "Mi" ));
74
- }
75
-
76
- String maxCPU = request .properties ().get ("MaxCPU" );
77
- if (StringUtils .isNotBlank (maxCPU )) {
78
- LOG .debug (String .format ("[Create Agent] Setting cpu resource limit on k8s pod:%s" , maxCPU ));
79
- put ("cpu" , new Quantity (maxCPU ));
80
- }
81
- }});
82
- container .setResources (resources );
83
-
84
- ObjectMeta podMetadata = new ObjectMeta ();
85
- podMetadata .setName (containerName );
86
-
87
- PodSpec podSpec = new PodSpec ();
88
- podSpec .setContainers (Arrays .asList (container ));
89
-
90
- Pod elasticAgentPod = new Pod ("v1" , "Pod" , podMetadata , podSpec , new PodStatus ());
91
-
92
- setContainerEnvVariables (elasticAgentPod , request , settings , pluginRequest );
93
- setAnnotations (elasticAgentPod , request );
94
- setLabels (elasticAgentPod , request );
95
-
96
- return createKubernetesPod (client , elasticAgentPod );
97
- }
98
-
99
- private static void setLabels (Pod pod , CreateAgentRequest request ) {
100
- Map <String , String > existingLabels = (pod .getMetadata ().getLabels () != null ) ? pod .getMetadata ().getLabels () : new HashMap <>();
101
- existingLabels .putAll (labelsFrom (request ));
102
- pod .getMetadata ().setLabels (existingLabels );
103
- }
104
-
105
- private static void setAnnotations (Pod pod , CreateAgentRequest request ) {
106
- Map <String , String > existingAnnotations = (pod .getMetadata ().getAnnotations () != null ) ? pod .getMetadata ().getAnnotations () : new HashMap <>();
107
- existingAnnotations .putAll (request .properties ());
108
- pod .getMetadata ().setAnnotations (existingAnnotations );
109
- }
110
-
111
- private static KubernetesInstance createKubernetesPod (KubernetesClient client , Pod elasticAgentPod ) {
112
- LOG .info (String .format ("[Create Agent] Creating K8s pod with spec:%s" , elasticAgentPod .toString ()));
113
- client .pods ().inNamespace (Constants .KUBERNETES_NAMESPACE_KEY ).create (elasticAgentPod );
114
- return fromInstanceInfo (elasticAgentPod );
115
- }
116
-
117
- static KubernetesInstance fromInstanceInfo (Pod elasticAgentPod ) {
118
- try {
119
- ObjectMeta metadata = elasticAgentPod .getMetadata ();
120
- String containerName = metadata .getName ();
121
- String environment = metadata .getLabels ().get (Constants .ENVIRONMENT_LABEL_KEY );
122
-
123
- Date date = new Date ();
124
- if (StringUtils .isNotBlank (metadata .getCreationTimestamp ())) {
125
- date = getSimpleDateFormat ().parse (metadata .getCreationTimestamp ());
126
- }
127
- return new KubernetesInstance (containerName , date , environment , metadata .getAnnotations ());
128
- } catch (ParseException e ) {
129
- throw new RuntimeException (e );
130
- }
131
- }
132
-
133
- private static List <EnvVar > environmentFrom (CreateAgentRequest request , PluginSettings settings , String podName , PluginRequest pluginRequest ) {
134
- ArrayList <EnvVar > env = new ArrayList <>();
135
- String goServerUrl = StringUtils .isBlank (settings .getGoServerUrl ()) ? pluginRequest .getSeverInfo ().getSecureSiteUrl () : settings .getGoServerUrl ();
136
- env .add (new EnvVar ("GO_EA_SERVER_URL" , goServerUrl , null ));
137
- String environment = request .properties ().get ("Environment" );
138
- if (StringUtils .isNotBlank (environment )) {
139
- env .addAll (parseEnvironments (environment ));
140
- }
141
- env .addAll (request .autoregisterPropertiesAsEnvironmentVars (podName ));
142
-
143
- return new ArrayList <>(env );
144
- }
145
-
146
- private static void setContainerEnvVariables (Pod pod , CreateAgentRequest request , PluginSettings settings , PluginRequest pluginRequest ) {
147
- for (Container container : pod .getSpec ().getContainers ()) {
148
- List <EnvVar > existingEnv = (container .getEnv () != null ) ? container .getEnv () : new ArrayList <>();
149
- existingEnv .addAll (environmentFrom (request , settings , pod .getMetadata ().getName (), pluginRequest ));
150
- container .setEnv (existingEnv );
151
- }
152
- }
153
-
154
- private static Collection <? extends EnvVar > parseEnvironments (String environment ) {
155
- ArrayList <EnvVar > envVars = new ArrayList <>();
156
- for (String env : environment .split ("\n " )) {
157
- String [] parts = env .split ("=" );
158
- envVars .add (new EnvVar (parts [0 ], parts [1 ], null ));
159
- }
160
-
161
- return envVars ;
162
- }
163
-
164
- private static HashMap <String , String > labelsFrom (CreateAgentRequest request ) {
165
- HashMap <String , String > labels = new HashMap <>();
166
-
167
- labels .put (Constants .CREATED_BY_LABEL_KEY , Constants .PLUGIN_ID );
168
- if (StringUtils .isNotBlank (request .environment ())) {
169
- labels .put (Constants .ENVIRONMENT_LABEL_KEY , request .environment ());
170
- }
171
-
172
- labels .put (Constants .KUBERNETES_POD_KIND_LABEL_KEY , Constants .KUBERNETES_POD_KIND_LABEL_VALUE );
173
-
174
- return labels ;
175
- }
176
-
177
- private static String image (Map <String , String > properties ) {
178
- String image = properties .get ("Image" );
179
-
180
- if (isBlank (image )) {
181
- throw new IllegalArgumentException ("Must provide `Image` attribute." );
182
- }
183
-
184
- if (!image .contains (":" )) {
185
- return image + ":latest" ;
186
- }
187
- return image ;
40
+ public void terminate (KubernetesClient client ) {
41
+ client .pods ().inNamespace (Constants .KUBERNETES_NAMESPACE_KEY ).withName (name ).delete ();
188
42
}
189
43
190
44
public String name () {
@@ -199,62 +53,11 @@ public String environment() {
199
53
return environment ;
200
54
}
201
55
202
- @ Override
203
- public boolean equals (Object o ) {
204
- if (this == o ) return true ;
205
- if (o == null || getClass () != o .getClass ()) return false ;
206
-
207
- KubernetesInstance that = (KubernetesInstance ) o ;
208
-
209
- return name != null ? name .equals (that .name ) : that .name == null ;
210
- }
211
-
212
- @ Override
213
- public int hashCode () {
214
- return name != null ? name .hashCode () : 0 ;
215
- }
216
-
217
- public void terminate (KubernetesClient client ) {
218
- client .pods ().inNamespace (Constants .KUBERNETES_NAMESPACE_KEY ).withName (name ).delete ();
219
- }
220
-
221
56
public Map <String , String > getInstanceProperties () {
222
57
return properties ;
223
58
}
224
59
225
- public static KubernetesInstance createUsingPodYaml (CreateAgentRequest request , PluginSettings settings , KubernetesClient client , PluginRequest pluginRequest ) {
226
- ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
227
- String podYaml = request .properties ().get (POD_CONFIGURATION .getKey ());
228
-
229
- StringWriter writer = new StringWriter ();
230
- MustacheFactory mf = new DefaultMustacheFactory ();
231
- Mustache mustache = mf .compile (new StringReader (podYaml ), "templatePod" );
232
- mustache .execute (writer , KubernetesInstance .getJinJavaContext ());
233
- String templatizedPodYaml = writer .toString ();
234
-
235
- Pod elasticAgentPod = new Pod ();
236
- try {
237
- elasticAgentPod = mapper .readValue (templatizedPodYaml , Pod .class );
238
- } catch (IOException e ) {
239
- //ignore error here, handle this inside validate profile!
240
- e .printStackTrace ();
241
- }
242
-
243
- elasticAgentPod .getMetadata ().setCreationTimestamp (getSimpleDateFormat ().format (new Date ()));
244
-
245
- setContainerEnvVariables (elasticAgentPod , request , settings , pluginRequest );
246
- setAnnotations (elasticAgentPod , request );
247
- setLabels (elasticAgentPod , request );
248
-
249
- return createKubernetesPod (client , elasticAgentPod );
250
- }
251
-
252
- public static Map <String , String > getJinJavaContext () {
253
- HashMap <String , String > context = new HashMap <>();
254
- context .put (Constants .POD_POSTFIX , UUID .randomUUID ().toString ());
255
- context .put (Constants .CONTAINER_POSTFIX , UUID .randomUUID ().toString ());
256
- context .put (Constants .GOCD_AGENT_IMAGE , "gocd/gocd-agent-alpine-3.5" );
257
- context .put (Constants .LATEST_VERSION , "v17.10.0" );
258
- return context ;
60
+ public Long jobId () {
61
+ return jobId ;
259
62
}
260
63
}
0 commit comments