Does Fabric8io K8s java client support patch() or rollingupdate() using YAML snippets?

5/21/2020

I am trying to program the patching/rolling upgrade of k8s apps by taking deployment snippets as input. I use patch() method to apply the snippet onto an existing deployment as part of rollingupdate using fabric8io's k8s client APIS.. Fabric8.io kubernetes-client version 4.10.1 I'm also using some loadYaml helper methods from kubernetes-api 3.0.12.

Here is my sample snippet - adminpatch.yaml file:

kind: Deployment   
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0     
  template:
    spec:
      containers:
        - name: ${PATCH_IMAGE_NAME}
          image: ${PATCH_IMAGE_URL}
          imagePullPolicy: Always

I'm sending the above file content (with all the placeholders replaced) to patchDeployment() method as string. Here is my call to fabric8 patch() method:

 public static String patchDeployment(String deploymentName, String namespace, String deploymentYaml) {
try {
Deployment deploymentSnippet = (Deployment) getK8sObject(deploymentYaml);
if(deploymentSnippet instanceof Deployment) {
        logger.debug("Valid deployment object.");
Deployment deployment = getK8sClient().apps().deployments().inNamespace(namespace).withName(deploymentName)
    .rolling().patch(deploymentSnippet);
System.out.println(deployment.toString());
return getLastConfig(deployment.getMetadata(), deployment);
}
} catch (Exception Ex) {
  Ex.printStackTrace();
}
  return "Failed";

}

It throws the below exception:

io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: PATCH at: https://10.44.4.126:6443/apis/apps/v1/namespaces/default/deployments/patch-demo. Message: Deployment.apps "patch-demo" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"nginx", "deployment":"3470574ffdbd6e88d426a77dd951ed45"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable. Received status: Status(apiVersion=v1, code=422, details=StatusDetails(causes=[StatusCause(field=spec.selector, message=Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"nginx", "deployment":"3470574ffdbd6e88d426a77dd951ed45"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable, reason=FieldValueInvalid, additionalProperties={})], group=apps, kind=Deployment, name=patch-demo, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=Deployment.apps "patch-demo" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"nginx", "deployment":"3470574ffdbd6e88d426a77dd951ed45"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable, metadata=ListMeta(_continue=null, remainingItemCount=null, resourceVersion=null, selfLink=null, additionalProperties={}), reason=Invalid, status=Failure, additionalProperties={}).

I also tried the original snippet(with labels and selectors) with kubectl patch deployment <DEPLOYMENT_NAME> -n <MY_NAMESPACE> --patch "$(cat adminpatch.yaml) and this applies the same snippet fine.

I could not get much documentation on fabric8io k8s client patch() java API. Any help will be appreciated.

-- A.R.K.S
fabric8
kubernetes

0 Answers