3939import java .util .UUID ;
4040import java .util .function .BiConsumer ;
4141import java .util .stream .Collectors ;
42+ import javax .json .JsonPatch ;
4243
4344import javax .inject .Inject ;
4445
4546import org .apache .commons .io .IOUtils ;
4647
4748import com .fasterxml .jackson .core .JsonParseException ;
49+ import com .fasterxml .jackson .core .JsonProcessingException ;
4850import com .fasterxml .jackson .databind .JsonMappingException ;
4951import com .fasterxml .jackson .databind .MapperFeature ;
5052import com .fasterxml .jackson .databind .ObjectMapper ;
5153import com .fasterxml .jackson .databind .SerializationFeature ;
5254import com .fasterxml .jackson .dataformat .yaml .YAMLFactory ;
55+ import com .fasterxml .jackson .datatype .jsr353 .JSR353Module ;
5356import com .google .common .base .Charsets ;
5457import com .google .common .base .Splitter ;
5558
5962import eu .openanalytics .containerproxy .model .runtime .Container ;
6063import eu .openanalytics .containerproxy .model .runtime .Proxy ;
6164import eu .openanalytics .containerproxy .model .spec .ContainerSpec ;
65+ import eu .openanalytics .containerproxy .spec .expression .SpecExpressionContext ;
66+ import eu .openanalytics .containerproxy .spec .expression .SpecExpressionResolver ;
6267import eu .openanalytics .containerproxy .util .Retrying ;
6368import io .fabric8 .kubernetes .api .model .ContainerBuilder ;
6469import io .fabric8 .kubernetes .api .model .ContainerPort ;
@@ -258,8 +263,10 @@ protected Container startContainer(ContainerSpec spec, Proxy proxy) throws Excep
258263 podSpec .setNodeSelector (Splitter .on ("," ).withKeyValueSeparator ("=" ).split (nodeSelectorString ));
259264 }
260265
266+ JsonPatch patch = readPatchFromSpec (spec , proxy );
267+
261268 Pod startupPod = podBuilder .withSpec (podSpec ).build ();
262- Pod patchedPod = podPatcher .patchWithDebug (startupPod , proxy . getSpec (). getKubernetesPodPatchAsJsonpatch () );
269+ Pod patchedPod = podPatcher .patchWithDebug (startupPod , patch );
263270 final String effectiveKubeNamespace = patchedPod .getMetadata ().getNamespace (); // use the namespace of the patched Pod, in case the patch changes the namespace.
264271 container .getParameters ().put (PARAM_NAMESPACE , effectiveKubeNamespace );
265272
@@ -322,6 +329,20 @@ protected Container startContainer(ContainerSpec spec, Proxy proxy) throws Excep
322329 return container ;
323330 }
324331
332+ private JsonPatch readPatchFromSpec (ContainerSpec containerSpec , Proxy proxy ) throws JsonMappingException , JsonProcessingException {
333+ String patchAsString = proxy .getSpec ().getKubernetesPodPatch ();
334+ if (patchAsString == null ) {
335+ return null ;
336+ }
337+
338+ // resolve expressions
339+ SpecExpressionContext context = SpecExpressionContext .create (containerSpec , proxy , proxy .getSpec ());
340+ String expressionAwarePatch = expressionResolver .evaluateToString (patchAsString , context );
341+
342+ ObjectMapper yamlReader = new ObjectMapper (new YAMLFactory ());
343+ yamlReader .registerModule (new JSR353Module ());
344+ return yamlReader .readValue (expressionAwarePatch , JsonPatch .class );
345+ }
325346
326347 /**
327348 * Creates the extra manifests/resources defined in the ProxySpec.
@@ -342,11 +363,14 @@ private void createAdditionalManifstes(Proxy proxy, String namespace) {
342363 * parameter will be used.
343364 */
344365 private List <HasMetadata > getAdditionManifestsAsObjects (Proxy proxy , String namespace ) {
366+ SpecExpressionContext context = SpecExpressionContext .create (proxy , proxy .getSpec ());
367+
345368 ArrayList <HasMetadata > result = new ArrayList <HasMetadata >();
346369 for (String manifest : proxy .getSpec ().getKubernetesAdditionalManifests ()) {
347- HasMetadata object = Serialization .unmarshal (new ByteArrayInputStream (manifest .getBytes ())); // used to determine whether the manifest has specified a namespace
370+ String expressionManifest = expressionResolver .evaluateToString (manifest , context );
371+ HasMetadata object = Serialization .unmarshal (new ByteArrayInputStream (expressionManifest .getBytes ())); // used to determine whether the manifest has specified a namespace
348372
349- HasMetadata fullObject = kubeClient .load (new ByteArrayInputStream (manifest .getBytes ())).get ().get (0 );
373+ HasMetadata fullObject = kubeClient .load (new ByteArrayInputStream (expressionManifest .getBytes ())).get ().get (0 );
350374 if (object .getMetadata ().getNamespace () == null ) {
351375 // the load method (in some cases) automatically sets a namepsace when no namespace is provided
352376 // therefore we overwrite this namespace with the namsepace of the pod.
0 commit comments