Giter Club home page Giter Club logo

k8s-objectmatcher's Introduction

Kubernetes object matcher

GitHub Workflow Status go.dev reference

K8S-ObjectMatcher is a Golang library which helps to match Kubernetes objects.

Motivation

Here at Banzai Cloud we love and write lots of Kubernetes operators. While writing some complex operators as the Istio , Vault or Kafka operator, we encountered a huge amount of unnecessary Kubernetes object updates. Most of the operators out there are using reflect.DeepEquals to match the given object's Spec. Unfortunately, this solution is not perfect because every Kubernetes object is amended with different default values while submitted. This library aims to provide finer object matching capabilities to avoid unnecessary updates and more observability on the client side.

Legacy version deprecation notice

There is a legacy version of the lib, that is now deprecated and documented here: docs/legacy.md

How does it work?

The library uses the same method that kubectl apply does under the hood to calculate a patch using the three way merge method. However for this to work properly we need to keep track of the last applied version of our object, let's call it the original. Unfortunately Kubernetes does not keep track of our previously submitted object versions, but we can put it into an annotation like kubectl apply does. Next time we query the current state of the object from the API Server we can extract the original version from the annotation.

Once we have the the original, the current and our new modified object in place the library will take care of the rest.

Example steps demonstrated on a v1.Service object

Create a new object, annotate it, then submit normally

original := &v1.Service{
  ...
}

if err := patch.DefaultAnnotator.SetLastAppliedAnnotation(original); err != nil {
  ...
}

client.CoreV1().Services(original.GetNamespace()).Create(original)

Next time we check the diff and set the last applied annotation in case we have to update

modified := &v1.Service{
  ...
}

current, err := client.CoreV1().Services(modified.GetNamespace()).Get(modified.GetName(), metav1.Getoptions{})

patchResult, err := patch.DefaultPatchMaker.Calculate(current, modified)
if err != nil {
  return err
}

if !patchResult.IsEmpty() {
  if err := patch.DefaultAnnotator.SetLastAppliedAnnotation(modified); err != nil {
  	...
  }
  client.CoreV1().Services(modified.GetNamespace()).Update(modified)
}

CalculateOptions

In certain cases there is a need to filter out certain fields when the patch generated by the library is false positive. To help in these scenarios there are the following options to be used when calculating diffs:

  • IgnoreStatusFields
  • IgnoreVolumeClaimTemplateTypeMetaAndStatus
  • IgnoreField("field-name-to-ignore")

Example:

	opts := []patch.CalculateOption{
		patch.IgnoreStatusFields(),
	}

	patchResult, err := patch.DefaultPatchMaker.Calculate(existing.(runtime.Object), newObject.(runtime.Object), opts...)
	if err != nil {
		return err
	}

IgnoreStatusFields

This CalculateOptions removes status fields from both objects before comparing.

IgnoreVolumeClaimTemplateTypeMetaAndStatus

This CalculateOption clears volumeClaimTemplate fields from both objects before comparing (applies to statefulsets).

IgnoreField("field-name-to-ignore")

This CalculateOption removes the field provided (as a string) in the call before comparing them. A common usage might be to remove the metadata fields by using the IgnoreField("metadata") option.

Contributing

If you find this project useful here's how you can help:

  • Send a pull request with your new features and bug fixes
  • Help new users with issues they may encounter
  • Support the development of this project and star this repo!

License

Copyright (c) 2017-2019 Banzai Cloud, 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.

k8s-objectmatcher's People

Contributors

baluchicken avatar bonifaido avatar bweston92 avatar dependabot[bot] avatar eachirei avatar john-a-joyce avatar laci21 avatar lelia avatar matyix avatar pepov avatar sagikazarmark avatar waynz0r avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

k8s-objectmatcher's Issues

Is it possible to support ignoring nested fields?

I want to ignore the env field of the first container of the POD in the StatefulSet
for example: spec.template.spec.containers[0].env

But it doesn't work if I set it like this:
patch.IgnoreField("spec.template.spec.containers[0].env")

patch.IgnoreField() can only ignore the fields of the first layer.

Can you support fields that ignore nested levels?

Client-go dependency

Describe the bug
The pinned version of client-go is incompatible with kubebuilder pinned versions

Steps to reproduce the issue:
Create a kubebuilder project, add k8s-objectmatcher as a dependency and try to use it, you'll get the following error:

go vet ./...
# k8s.io/client-go/rest
../../../go/pkg/mod/k8s.io/[email protected]+incompatible/rest/request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
        have (*versioned.Decoder)
        want (watch.Decoder, watch.Reporter)

Expected behavior
Pinned version should have parity with popular frameworks

Additional context
Using k8s-objectmatcher v1.0.0 with kubebuilder alphav4. My go.mod diff once imported:

+       github.com/banzaicloud/k8s-objectmatcher v1.0.0
        github.com/go-logr/logr v0.1.0
-       github.com/onsi/ginkgo v1.6.0
-       github.com/onsi/gomega v1.4.2
-       golang.org/x/net v0.0.0-20180906233101-161cd47e91fd
-       k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b
-       k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d
-       k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
+       github.com/onsi/ginkgo v1.8.0
+       github.com/onsi/gomega v1.5.0
+       golang.org/x/net v0.0.0-20190311183353-d8887717615a
+       k8s.io/api v0.0.0-20190528154508-67ef80593b24
+       k8s.io/apimachinery v0.0.0-20190528154326-e59c2fb0a8e5
+       k8s.io/client-go v11.0.1-0.20190516230509-ae8359b20417+incompatible
        sigs.k8s.io/controller-runtime v0.2.0-beta.2

DefaultPatchMaker patch deployment result error

Describe the bug
A clear and concise description of what the bug is.

Steps to reproduce the issue:
Please describe the steps to reproduce the issue.
1、The following test code:

package test

import (
	"testing"

	"github.com/banzaicloud/k8s-objectmatcher/patch"
	"github.com/stretchr/testify/assert"
	"github.com/xdf/rocketmq-operator/pkg/k8sutil"
	appsv1 "k8s.io/api/apps/v1"
	"k8s.io/apimachinery/pkg/util/json"
)

var (
	 currentDepJson = `
{
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {
        "annotations": {
            "deployment.kubernetes.io/revision": "1",
            "prometheus.io/port": "5557",
            "prometheus.io/scrape": "true"
        },
        "creationTimestamp": "2021-06-11T06:28:55Z",
        "generation": 1,
        "labels": {
            "app": "exporter",
            "exporterName": "zz-480",
            "mq_cr": "zz-480"
        },
        "managedFields": [
            {
                "apiVersion": "apps/v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            ".": {},
                            "f:prometheus.io/port": {},
                            "f:prometheus.io/scrape": {}
                        },
                        "f:labels": {
                            ".": {},
                            "f:app": {},
                            "f:exporterName": {},
                            "f:mq_cr": {}
                        },
                        "f:ownerReferences": {
                            ".": {},
                            "k:{\"uid\":\"16abf70c-f889-448c-8873-b48880cd4a35\"}": {
                                ".": {},
                                "f:apiVersion": {},
                                "f:blockOwnerDeletion": {},
                                "f:controller": {},
                                "f:kind": {},
                                "f:name": {},
                                "f:uid": {}
                            }
                        }
                    },
                    "f:spec": {
                        "f:progressDeadlineSeconds": {},
                        "f:replicas": {},
                        "f:revisionHistoryLimit": {},
                        "f:selector": {
                            "f:matchLabels": {
                                ".": {},
                                "f:app": {},
                                "f:exporterName": {}
                            }
                        },
                        "f:strategy": {
                            "f:rollingUpdate": {
                                ".": {},
                                "f:maxSurge": {},
                                "f:maxUnavailable": {}
                            },
                            "f:type": {}
                        },
                        "f:template": {
                            "f:metadata": {
                                "f:annotations": {
                                    ".": {},
                                    "f:prometheus.io/port": {},
                                    "f:prometheus.io/scrape": {}
                                },
                                "f:labels": {
                                    ".": {},
                                    "f:app": {},
                                    "f:exporterName": {},
                                    "f:mq_cr": {}
                                }
                            },
                            "f:spec": {
                                "f:containers": {
                                    "k:{\"name\":\"mq-exporter\"}": {
                                        ".": {},
                                        "f:args": {},
                                        "f:image": {},
                                        "f:imagePullPolicy": {},
                                        "f:livenessProbe": {
                                            ".": {},
                                            "f:failureThreshold": {},
                                            "f:initialDelaySeconds": {},
                                            "f:periodSeconds": {},
                                            "f:successThreshold": {},
                                            "f:tcpSocket": {
                                                ".": {},
                                                "f:port": {}
                                            },
                                            "f:timeoutSeconds": {}
                                        },
                                        "f:name": {},
                                        "f:ports": {
                                            ".": {},
                                            "k:{\"containerPort\":5557,\"protocol\":\"TCP\"}": {
                                                ".": {},
                                                "f:containerPort": {},
                                                "f:name": {},
                                                "f:protocol": {}
                                            }
                                        },
                                        "f:readinessProbe": {
                                            ".": {},
                                            "f:failureThreshold": {},
                                            "f:initialDelaySeconds": {},
                                            "f:periodSeconds": {},
                                            "f:successThreshold": {},
                                            "f:tcpSocket": {
                                                ".": {},
                                                "f:port": {}
                                            },
                                            "f:timeoutSeconds": {}
                                        },
                                        "f:resources": {
                                            ".": {},
                                            "f:limits": {
                                                ".": {},
                                                "f:cpu": {},
                                                "f:memory": {}
                                            },
                                            "f:requests": {
                                                ".": {},
                                                "f:cpu": {},
                                                "f:memory": {}
                                            }
                                        },
                                        "f:terminationMessagePath": {},
                                        "f:terminationMessagePolicy": {},
                                        "f:volumeMounts": {
                                            ".": {},
                                            "k:{\"mountPath\":\"/home/rocketmq/rocketmq-4.8.0/bin/runbroker.sh\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {},
                                                "f:subPath": {}
                                            },
                                            "k:{\"mountPath\":\"/home/rocketmq/rocketmq-4.8.0/bin/runserver.sh\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {},
                                                "f:subPath": {}
                                            },
                                            "k:{\"mountPath\":\"/tmp/rocketmq-exporter/data/\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {}
                                            }
                                        }
                                    }
                                },
                                "f:dnsPolicy": {},
                                "f:restartPolicy": {},
                                "f:schedulerName": {},
                                "f:securityContext": {
                                    ".": {},
                                    "f:fsGroup": {}
                                },
                                "f:terminationGracePeriodSeconds": {},
                                "f:volumes": {
                                    ".": {},
                                    "k:{\"name\":\"config\"}": {
                                        ".": {},
                                        "f:configMap": {
                                            ".": {},
                                            "f:defaultMode": {},
                                            "f:name": {}
                                        },
                                        "f:name": {}
                                    },
                                    "k:{\"name\":\"mq-run-script\"}": {
                                        ".": {},
                                        "f:configMap": {
                                            ".": {},
                                            "f:defaultMode": {},
                                            "f:name": {}
                                        },
                                        "f:name": {}
                                    }
                                }
                            }
                        }
                    }
                },
                "manager": "___go_build_github_com_smaller_rocketmq_operator",
                "operation": "Update",
                "time": "2021-06-11T06:28:55Z"
            },
            {
                "apiVersion": "apps/v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            "f:deployment.kubernetes.io/revision": {}
                        }
                    },
                    "f:status": {
                        "f:availableReplicas": {},
                        "f:conditions": {
                            ".": {},
                            "k:{\"type\":\"Available\"}": {
                                ".": {},
                                "f:lastTransitionTime": {},
                                "f:lastUpdateTime": {},
                                "f:message": {},
                                "f:reason": {},
                                "f:status": {},
                                "f:type": {}
                            },
                            "k:{\"type\":\"Progressing\"}": {
                                ".": {},
                                "f:lastTransitionTime": {},
                                "f:lastUpdateTime": {},
                                "f:message": {},
                                "f:reason": {},
                                "f:status": {},
                                "f:type": {}
                            }
                        },
                        "f:observedGeneration": {},
                        "f:readyReplicas": {},
                        "f:replicas": {},
                        "f:updatedReplicas": {}
                    }
                },
                "manager": "kube-controller-manager",
                "operation": "Update",
                "time": "2021-06-11T06:29:20Z"
            }
        ],
        "name": "zz-480-exporter",
        "namespace": "rocketmq",
        "ownerReferences": [
            {
                "apiVersion": "rocketmq.apache.org/v1alpha1",
                "blockOwnerDeletion": true,
                "controller": true,
                "kind": "RocketMQCluster",
                "name": "zz-480",
                "uid": "16abf70c-f889-448c-8873-b48880cd4a35"
            }
        ],
        "resourceVersion": "227460798",
        "selfLink": "/apis/apps/v1/namespaces/rocketmq/deployments/zz-480-exporter",
        "uid": "d7d05f49-6c3e-4f46-a352-f5c3af89547f"
    },
    "spec": {
        "progressDeadlineSeconds": 600,
        "replicas": 1,
        "revisionHistoryLimit": 10,
        "selector": {
            "matchLabels": {
                "app": "exporter",
                "exporterName": "zz-480"
            }
        },
        "strategy": {
            "rollingUpdate": {
                "maxSurge": "25%",
                "maxUnavailable": "25%"
            },
            "type": "RollingUpdate"
        },
        "template": {
            "metadata": {
                "annotations": {
                    "prometheus.io/port": "5557",
                    "prometheus.io/scrape": "true"
                },
                "labels": {
                    "app": "exporter",
                    "exporterName": "zz-480",
                    "mq_cr": "zz-480"
                }
            },
            "spec": {
                "containers": [
                    {
                        "args": [
                            "--spring.config.location=/tmp/rocketmq-exporter/data/"
                        ],
                        "image": "harbor-xadd.staff.smaller.cn/library/rocketmq-exporter:v1.0.1",
                        "imagePullPolicy": "IfNotPresent",
                        "livenessProbe": {
                            "failureThreshold": 3,
                            "initialDelaySeconds": 15,
                            "periodSeconds": 20,
                            "successThreshold": 1,
                            "tcpSocket": {
                                "port": "mq-exporter"
                            },
                            "timeoutSeconds": 1
                        },
                        "name": "mq-exporter",
                        "ports": [
                            {
                                "containerPort": 5557,
                                "name": "mq-exporter",
                                "protocol": "TCP"
                            }
                        ],
                        "readinessProbe": {
                            "failureThreshold": 3,
                            "initialDelaySeconds": 15,
                            "periodSeconds": 20,
                            "successThreshold": 1,
                            "tcpSocket": {
                                "port": "mq-exporter"
                            },
                            "timeoutSeconds": 1
                        },
                        "resources": {
                            "limits": {
                                "cpu": "2",
                                "memory": "4Gi"
                            },
                            "requests": {
                                "cpu": "500m",
                                "memory": "2Gi"
                            }
                        },
                        "terminationMessagePath": "/dev/termination-log",
                        "terminationMessagePolicy": "File",
                        "volumeMounts": [
                            {
                                "mountPath": "/home/rocketmq/rocketmq-4.8.0/bin/runbroker.sh",
                                "name": "mq-run-script",
                                "subPath": "runbroker.sh"
                            },
                            {
                                "mountPath": "/home/rocketmq/rocketmq-4.8.0/bin/runserver.sh",
                                "name": "mq-run-script",
                                "subPath": "runserver.sh"
                            },
                            {
                                "mountPath": "/tmp/rocketmq-exporter/data/",
                                "name": "config"
                            }
                        ]
                    }
                ],
                "dnsPolicy": "ClusterFirst",
                "restartPolicy": "Always",
                "schedulerName": "xlss-scheduler",
                "securityContext": {
                    "fsGroup": 1000
                },
                "terminationGracePeriodSeconds": 30,
                "volumes": [
                    {
                        "configMap": {
                            "defaultMode": 493,
                            "name": "mq-run-script"
                        },
                        "name": "mq-run-script"
                    },
                    {
                        "configMap": {
                            "defaultMode": 493,
                            "name": "zz-480-exporter-config"
                        },
                        "name": "config"
                    }
                ]
            }
        }
    }
}`

	 modifiedDepJson = `
{
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {
        "annotations": {
            "prometheus.io/port": "5557",
            "prometheus.io/scrape": "true"
        },
        "creationTimestamp": "2021-06-11T06:28:55Z",
        "generation": 1,
        "labels": {
            "app": "exporter",
            "exporterName": "zz-480",
            "mq_cr": "zz-480"
        },
        "managedFields": [
            {
                "apiVersion": "apps/v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            ".": {},
                            "f:prometheus.io/port": {},
                            "f:prometheus.io/scrape": {}
                        },
                        "f:labels": {
                            ".": {},
                            "f:app": {},
                            "f:exporterName": {},
                            "f:mq_cr": {}
                        },
                        "f:ownerReferences": {
                            ".": {},
                            "k:{\"uid\":\"16abf70c-f889-448c-8873-b48880cd4a35\"}": {
                                ".": {},
                                "f:apiVersion": {},
                                "f:blockOwnerDeletion": {},
                                "f:controller": {},
                                "f:kind": {},
                                "f:name": {},
                                "f:uid": {}
                            }
                        }
                    },
                    "f:spec": {
                        "f:progressDeadlineSeconds": {},
                        "f:replicas": {},
                        "f:revisionHistoryLimit": {},
                        "f:selector": {
                            "f:matchLabels": {
                                ".": {},
                                "f:app": {},
                                "f:exporterName": {}
                            }
                        },
                        "f:strategy": {
                            "f:rollingUpdate": {
                                ".": {},
                                "f:maxSurge": {},
                                "f:maxUnavailable": {}
                            },
                            "f:type": {}
                        },
                        "f:template": {
                            "f:metadata": {
                                "f:annotations": {
                                    ".": {},
                                    "f:prometheus.io/port": {},
                                    "f:prometheus.io/scrape": {}
                                },
                                "f:labels": {
                                    ".": {},
                                    "f:app": {},
                                    "f:exporterName": {},
                                    "f:mq_cr": {}
                                }
                            },
                            "f:spec": {
                                "f:containers": {
                                    "k:{\"name\":\"mq-exporter\"}": {
                                        ".": {},
                                        "f:args": {},
                                        "f:image": {},
                                        "f:imagePullPolicy": {},
                                        "f:livenessProbe": {
                                            ".": {},
                                            "f:failureThreshold": {},
                                            "f:initialDelaySeconds": {},
                                            "f:periodSeconds": {},
                                            "f:successThreshold": {},
                                            "f:tcpSocket": {
                                                ".": {},
                                                "f:port": {}
                                            },
                                            "f:timeoutSeconds": {}
                                        },
                                        "f:name": {},
                                        "f:ports": {
                                            ".": {},
                                            "k:{\"containerPort\":5557,\"protocol\":\"TCP\"}": {
                                                ".": {},
                                                "f:containerPort": {},
                                                "f:name": {},
                                                "f:protocol": {}
                                            }
                                        },
                                        "f:readinessProbe": {
                                            ".": {},
                                            "f:failureThreshold": {},
                                            "f:initialDelaySeconds": {},
                                            "f:periodSeconds": {},
                                            "f:successThreshold": {},
                                            "f:tcpSocket": {
                                                ".": {},
                                                "f:port": {}
                                            },
                                            "f:timeoutSeconds": {}
                                        },
                                        "f:resources": {
                                            ".": {},
                                            "f:limits": {
                                                ".": {},
                                                "f:cpu": {},
                                                "f:memory": {}
                                            },
                                            "f:requests": {
                                                ".": {},
                                                "f:cpu": {},
                                                "f:memory": {}
                                            }
                                        },
                                        "f:terminationMessagePath": {},
                                        "f:terminationMessagePolicy": {},
                                        "f:volumeMounts": {
                                            ".": {},
                                            "k:{\"mountPath\":\"/home/rocketmq/rocketmq-4.8.0/bin/runbroker.sh\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {},
                                                "f:subPath": {}
                                            },
                                            "k:{\"mountPath\":\"/home/rocketmq/rocketmq-4.8.0/bin/runserver.sh\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {},
                                                "f:subPath": {}
                                            },
                                            "k:{\"mountPath\":\"/tmp/rocketmq-exporter/data/\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {}
                                            }
                                        }
                                    }
                                },
                                "f:dnsPolicy": {},
                                "f:restartPolicy": {},
                                "f:schedulerName": {},
                                "f:securityContext": {
                                    ".": {},
                                    "f:fsGroup": {}
                                },
                                "f:terminationGracePeriodSeconds": {},
                                "f:volumes": {
                                    ".": {},
                                    "k:{\"name\":\"config\"}": {
                                        ".": {},
                                        "f:configMap": {
                                            ".": {},
                                            "f:defaultMode": {},
                                            "f:name": {}
                                        },
                                        "f:name": {}
                                    },
                                    "k:{\"name\":\"mq-run-script\"}": {
                                        ".": {},
                                        "f:configMap": {
                                            ".": {},
                                            "f:defaultMode": {},
                                            "f:name": {}
                                        },
                                        "f:name": {}
                                    }
                                }
                            }
                        }
                    }
                },
                "manager": "___go_build_github_com_smaller_rocketmq_operator",
                "operation": "Update",
                "time": "2021-06-11T06:28:55Z"
            },
            {
                "apiVersion": "apps/v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            "f:deployment.kubernetes.io/revision": {}
                        }
                    },
                    "f:status": {
                        "f:availableReplicas": {},
                        "f:conditions": {
                            ".": {},
                            "k:{\"type\":\"Available\"}": {
                                ".": {},
                                "f:lastTransitionTime": {},
                                "f:lastUpdateTime": {},
                                "f:message": {},
                                "f:reason": {},
                                "f:status": {},
                                "f:type": {}
                            },
                            "k:{\"type\":\"Progressing\"}": {
                                ".": {},
                                "f:lastTransitionTime": {},
                                "f:lastUpdateTime": {},
                                "f:message": {},
                                "f:reason": {},
                                "f:status": {},
                                "f:type": {}
                            }
                        },
                        "f:observedGeneration": {},
                        "f:readyReplicas": {},
                        "f:replicas": {},
                        "f:updatedReplicas": {}
                    }
                },
                "manager": "kube-controller-manager",
                "operation": "Update",
                "time": "2021-06-11T06:29:20Z"
            }
        ],
        "name": "zz-480-exporter",
        "namespace": "rocketmq",
        "ownerReferences": [
            {
                "apiVersion": "rocketmq.apache.org/v1alpha1",
                "blockOwnerDeletion": true,
                "controller": true,
                "kind": "RocketMQCluster",
                "name": "zz-480",
                "uid": "16abf70c-f889-448c-8873-b48880cd4a35"
            }
        ],
        "resourceVersion": "227460798",
        "selfLink": "/apis/apps/v1/namespaces/rocketmq/deployments/zz-480-exporter",
        "uid": "d7d05f49-6c3e-4f46-a352-f5c3af89547f"
    },
    "spec": {
        "replicas": 1,
        "selector": {
            "matchLabels": {
                "app": "exporter",
                "exporterName": "zz-480"
            }
        },
        "strategy": {
            "rollingUpdate": {
                "maxSurge": "25%",
                "maxUnavailable": "25%"
            },
            "type": "RollingUpdate"
        },
        "template": {
            "metadata": {
                "annotations": {
                    "prometheus.io/port": "5557",
                    "prometheus.io/scrape": "true"
                },
                "labels": {
                    "app": "exporter",
                    "exporterName": "zz-480",
                    "mq_cr": "zz-480"
                }
            },
            "spec": {
                "containers": [
                    {
                        "args": [
                            "--spring.config.location=/tmp/rocketmq-exporter/data/"
                        ],
                        "image": "harbor-xadd.staff.smaller.cn/library/rocketmq-exporter:v1.0.1",
                        "livenessProbe": {
                            "initialDelaySeconds": 15,
                            "periodSeconds": 20,
                            "tcpSocket": {
                                "port": "mq-exporter"
                            }
                        },
                        "name": "mq-exporter",
                        "ports": [
                            {
                                "containerPort": 5557,
                                "name": "mq-exporter",
                                "protocol": "TCP"
                            }
                        ],
                        "readinessProbe": {
                            "initialDelaySeconds": 15,
                            "periodSeconds": 20,
                            "tcpSocket": {
                                "port": "mq-exporter"
                            }
                        },
                        "resources": {
                            "limits": {
                                "cpu": "2",
                                "memory": "4Gi"
                            },
                            "requests": {
                                "cpu": "500m",
                                "memory": "2Gi"
                            }
                        },
                        "volumeMounts": [
                            {
                                "mountPath": "/tmp/rocketmq-exporter/data/",
                                "name": "config"
                            }
                        ]
                    }
                ],
                "schedulerName": "xlss-scheduler",
                "securityContext": {
                    "fsGroup": 1000
                },
                "volumes": [
                    {
                        "configMap": {
                            "defaultMode": 493,
                            "name": "zz-480-exporter-config"
                        },
                        "name": "config"
                    }
                ]
            }
        }
    }
}`
)

func TestDeploymentPatchResult(t *testing.T) {
	currentDep, modifiedDep :=  &appsv1.Deployment{}, &appsv1.Deployment{}
	err := json.Unmarshal([]byte(currentDepJson), currentDep)
	if err != nil {
		t.Fatalf(err.Error())
	}

	err = json.Unmarshal([]byte(modifiedDepJson), modifiedDep)
	if err != nil {
		t.Fatalf(err.Error())
	}

	assert.True(t, len(currentDep.Spec.Template.Spec.Containers[0].VolumeMounts) != len(modifiedDep.Spec.Template.Spec.Containers[0].VolumeMounts))
	assert.True(t, len(currentDep.Spec.Template.Spec.Volumes) != len(modifiedDep.Spec.Template.Spec.Volumes))
	patchResult, err := patch.DefaultPatchMaker.Calculate(currentDep, modifiedDep, k8sutil.PatchOptions...)
	if err != nil {
		t.Fatalf(err.Error())
	}

	assert.False(t, patchResult.IsEmpty())
}

Expected behavior

Expected is False,but output is True

Screenshots

output

Additional context
Add any other context about the problem like release numberm version, branch, etc.

IgnoreVolumeClaimTemplateTypeMetaAndStatus looks not work

Describe the bug
IgnoreVolumeClaimTemplateTypeMetaAndStatus looks not work

Steps to reproduce the issue:
I tried to compare the two statefulsets like this

opts := []patch.CalculateOption{
    patch.IgnoreStatusFields(), 
    patch.IgnoreVolumeClaimTemplateTypeMetaAndStatus(),
}
patchResult, err := patch.DefaultPatchMaker.Calculate(old, new, opts...)
fmt.Printf("==========================%+v\n", patchResult.String())

I got this

Patch: {"spec":{"volumeClaimTemplates":[{"metadata":{"name":"emqx-data","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"20Mi"}},"storageClassName":"standard"},"status":{"phase":"Pending"}},{"metadata":{"name":"emqx-log","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"20Mi"}},"storageClassName":"standard"},"status":{"phase":"Pending"}}]}} 

volumeClaimTemplates is not ignored

Expected behavior
volumeClaimTemplates should be ignored

Additional context
k8s-objectmatcher version: v1.7.0
go version: go1.17.3 darwin/amd64

Deployment meta annotations order broken

Describe the bug
Since banzaicloud@4236369, every timeSetLastAppliedAnnotation() is applied the .metadata.annotations of my Deployment has a different order.

See, the first iteration:

2020-03-23 13:50:13.544252 I | ceph-object-controller: deployment.Meta.Annotations is map[banzaicloud.com/last-applied:{"status":{},"metadata":{"name":"rook-ceph-rgw-my-store-b","namespace":"rook-ceph","labels":{"rgw":"my-store","rook_object_store":"my-store","rook-version":"v1.1.0-beta.0.1104.g803f3bced-dirty","ceph-version":"14.2.8-0","app":"rook-ceph-rgw","rook_cluster":"rook-ceph","ceph_daemon_id":"my-store"},"ownerReferences":[{"kind":"CephObjectStore","name":"my-store","uid":"9d7fe2b7-34fa-4d3a-9133-2ba94a9b9b44","controller":true,"blockOwnerDeletion":true,"apiVersion":"ceph.rook.io/v1"}]},"spec":{"selector":{"matchLabels":{"app":"rook-ceph-rgw","rook_cluster":"rook-ceph","ceph_daemon_id":"my-store","rgw":"my-store","rook_object_store":"my-store"}},"template":{"metadata":{"labels":{"rgw":"my-store","rook_object_store":"my-store","app":"rook-ceph-rgw","rook_cluster":"rook-ceph","ceph_daemon_id":"my-store"},"name":"rook-ceph-rgw-my-store-b"},"spec":{"volumes":[{"name":"rook-config-override","configMap":{"name":"rook-config-override","items":[{"path":"ceph.conf","mode":292,"key":"config"}]}},{"name":"rook-ceph-rgw-my-store-b-keyring","secret":{"secretName":"rook-ceph-rgw-my-store-b-keyring"}},{"hostPath":{"path":"/var/lib/rook/rook-ceph/log"},"name":"rook-ceph-log"},{"name":"rook-ceph-crash","hostPath":{"path":"/var/lib/rook/rook-ceph/crash"}},{"name":"ceph-daemon-data","emptyDir":{}},{"name":"rook-ceph-rgw-my-store-mime-types","configMap":{"name":"rook-ceph-rgw-my-store-mime-types"}}],"initContainers":[{"command":["chown"],"args":["--verbose","--recursive","ceph:ceph","/var/log/ceph","/var/lib/ceph/crash","/var/lib/ceph/rgw/ceph-my-store"],"resources":{},"volumeMounts":[{"name":"rook-config-override","readOnly":true,"mountPath":"/etc/ceph"},{"readOnly":true,"mountPath":"/etc/ceph/keyring-store/","name":"rook-ceph-rgw-my-store-b-keyring"},{"name":"rook-ceph-log","mountPath":"/var/log/ceph"},{"name":"rook-ceph-crash","mountPath":"/var/lib/ceph/crash"},{"name":"ceph-daemon-data","mountPath":"/var/lib/ceph/rgw/ceph-my-store"}],"name":"chown-container-data-dir","image":"ceph/ceph:v14.2.8"}],"containers":[{"image":"ceph/ceph:v14.2.8","command":["radosgw"],"env":[{"name":"CONTAINER_IMAGE","value":"ceph/ceph:v14.2.8"},{"name":"POD_NAME","valueFrom":{"fieldRef":{"fieldPath":"metadata.name"}}},{"name":"POD_NAMESPACE","valueFrom":{"fieldRef":{"fieldPath":"metadata.namespace"}}},{"name":"NODE_NAME","valueFrom":{"fieldRef":{"fieldPath":"spec.nodeName"}}},{"name":"POD_MEMORY_LIMIT","valueFrom":{"resourceFieldRef":{"resource":"limits.memory","divisor":"0"}}},{"valueFrom":{"resourceFieldRef":{"resource":"requests.memory","divisor":"0"}},"name":"POD_MEMORY_REQUEST"},{"name":"POD_CPU_LIMIT","valueFrom":{"resourceFieldRef":{"resource":"limits.cpu","divisor":"1"}}},{"valueFrom":{"resourceFieldRef":{"divisor":"0","resource":"requests.cpu"}},"name":"POD_CPU_REQUEST"},{"name":"ROOK_CEPH_MON_HOST","valueFrom":{"secretKeyRef":{"name":"rook-ceph-config","key":"mon_host"}}},{"name":"ROOK_CEPH_MON_INITIAL_MEMBERS","valueFrom":{"secretKeyRef":{"name":"rook-ceph-config","key":"mon_initial_members"}}}],"livenessProbe":{"httpGet":{"path":"/swift/healthcheck","port":80},"initialDelaySeconds":10},"name":"rgw","args":["--fsid=2a769bde-4386-46ce-a23e-0b634a591a40","--keyring=/etc/ceph/keyring-store/keyring","--log-to-stderr=true","--err-to-stderr=true","--mon-cluster-log-to-stderr=true","--log-stderr-prefix=debug ","--default-log-to-file=false","--default-mon-cluster-log-to-file=false","--mon-host=$(ROOK_CEPH_MON_HOST)","--mon-initial-members=$(ROOK_CEPH_MON_INITIAL_MEMBERS)","--id=rgw.my.store.b","--setuser=ceph","--setgroup=ceph","--foreground","--rgw-frontends=beast port=80","--host=$(POD_NAME)","--rgw-mime-types-file=/etc/ceph/rgw/mime.types"],"resources":{},"volumeMounts":[{"mountPath":"/etc/ceph","name":"rook-config-override","readOnly":true},{"mountPath":"/etc/ceph/keyring-store/","name":"rook-ceph-rgw-my-store-b-keyring","readOnly":true},{"name":"rook-ceph-log","mountPath":"/var/log/ceph"},{"name":"rook-ceph-crash","mountPath":"/var/lib/ceph/crash"},{"name":"ceph-daemon-data","mountPath":"/var/lib/ceph/rgw/ceph-my-store"},{"readOnly":true,"mountPath":"/etc/ceph/rgw","name":"rook-ceph-rgw-my-store-mime-types"}]}],"restartPolicy":"Always","affinity":{"podAntiAffinity":{}},"tolerations":[{"tolerationSeconds":5,"key":"node.kubernetes.io/unreachable","operator":"Exists","effect":"NoExecute"}]}},"strategy":{"type":"Recreate"},"replicas":1}}]

Second iteration:

2020-03-23 13:50:10.838079 I | ceph-object-controller: deployment.Meta.Annotations is map[banzaicloud.com/last-applied:{"metadata":{"labels":{"ceph-version":"14.2.8-0","app":"rook-ceph-rgw","rook_cluster":"rook-ceph","ceph_daemon_id":"my-store","rgw":"my-store","rook_object_store":"my-store","rook-version":"v1.1.0-beta.0.1104.g803f3bced-dirty"},"ownerReferences":[{"kind":"CephObjectStore","name":"my-store","uid":"9d7fe2b7-34fa-4d3a-9133-2ba94a9b9b44","controller":true,"blockOwnerDeletion":true,"apiVersion":"ceph.rook.io/v1"}],"name":"rook-ceph-rgw-my-store-a","namespace":"rook-ceph"},"spec":{"strategy":{"type":"Recreate"},"replicas":1,"selector":{"matchLabels":{"ceph_daemon_id":"my-store","rgw":"my-store","rook_object_store":"my-store","app":"rook-ceph-rgw","rook_cluster":"rook-ceph"}},"template":{"metadata":{"name":"rook-ceph-rgw-my-store-a","labels":{"app":"rook-ceph-rgw","rook_cluster":"rook-ceph","ceph_daemon_id":"my-store","rgw":"my-store","rook_object_store":"my-store"}},"spec":{"volumes":[{"name":"rook-config-override","configMap":{"items":[{"mode":292,"key":"config","path":"ceph.conf"}],"name":"rook-config-override"}},{"secret":{"secretName":"rook-ceph-rgw-my-store-a-keyring"},"name":"rook-ceph-rgw-my-store-a-keyring"},{"name":"rook-ceph-log","hostPath":{"path":"/var/lib/rook/rook-ceph/log"}},{"hostPath":{"path":"/var/lib/rook/rook-ceph/crash"},"name":"rook-ceph-crash"},{"emptyDir":{},"name":"ceph-daemon-data"},{"name":"rook-ceph-rgw-my-store-mime-types","configMap":{"name":"rook-ceph-rgw-my-store-mime-types"}}],"initContainers":[{"volumeMounts":[{"mountPath":"/etc/ceph","name":"rook-config-override","readOnly":true},{"readOnly":true,"mountPath":"/etc/ceph/keyring-store/","name":"rook-ceph-rgw-my-store-a-keyring"},{"name":"rook-ceph-log","mountPath":"/var/log/ceph"},{"name":"rook-ceph-crash","mountPath":"/var/lib/ceph/crash"},{"name":"ceph-daemon-data","mountPath":"/var/lib/ceph/rgw/ceph-my-store"}],"name":"chown-container-data-dir","image":"ceph/ceph:v14.2.8","command":["chown"],"args":["--verbose","--recursive","ceph:ceph","/var/log/ceph","/var/lib/ceph/crash","/var/lib/ceph/rgw/ceph-my-store"],"resources":{}}],"containers":[{"name":"rgw","image":"ceph/ceph:v14.2.8","command":["radosgw"],"env":[{"name":"CONTAINER_IMAGE","value":"ceph/ceph:v14.2.8"},{"name":"POD_NAME","valueFrom":{"fieldRef":{"fieldPath":"metadata.name"}}},{"valueFrom":{"fieldRef":{"fieldPath":"metadata.namespace"}},"name":"POD_NAMESPACE"},{"valueFrom":{"fieldRef":{"fieldPath":"spec.nodeName"}},"name":"NODE_NAME"},{"name":"POD_MEMORY_LIMIT","valueFrom":{"resourceFieldRef":{"resource":"limits.memory","divisor":"0"}}},{"name":"POD_MEMORY_REQUEST","valueFrom":{"resourceFieldRef":{"resource":"requests.memory","divisor":"0"}}},{"name":"POD_CPU_LIMIT","valueFrom":{"resourceFieldRef":{"resource":"limits.cpu","divisor":"1"}}},{"name":"POD_CPU_REQUEST","valueFrom":{"resourceFieldRef":{"resource":"requests.cpu","divisor":"0"}}},{"valueFrom":{"secretKeyRef":{"name":"rook-ceph-config","key":"mon_host"}},"name":"ROOK_CEPH_MON_HOST"},{"name":"ROOK_CEPH_MON_INITIAL_MEMBERS","valueFrom":{"secretKeyRef":{"name":"rook-ceph-config","key":"mon_initial_members"}}}],"resources":{},"livenessProbe":{"initialDelaySeconds":10,"httpGet":{"path":"/swift/healthcheck","port":80}},"args":["--fsid=2a769bde-4386-46ce-a23e-0b634a591a40","--keyring=/etc/ceph/keyring-store/keyring","--log-to-stderr=true","--err-to-stderr=true","--mon-cluster-log-to-stderr=true","--log-stderr-prefix=debug ","--default-log-to-file=false","--default-mon-cluster-log-to-file=false","--mon-host=$(ROOK_CEPH_MON_HOST)","--mon-initial-members=$(ROOK_CEPH_MON_INITIAL_MEMBERS)","--id=rgw.my.store.a","--setuser=ceph","--setgroup=ceph","--foreground","--rgw-frontends=beast port=80","--host=$(POD_NAME)","--rgw-mime-types-file=/etc/ceph/rgw/mime.types"],"volumeMounts":[{"name":"rook-config-override","readOnly":true,"mountPath":"/etc/ceph"},{"readOnly":true,"mountPath":"/etc/ceph/keyring-store/","name":"rook-ceph-rgw-my-store-a-keyring"},{"name":"rook-ceph-log","mountPath":"/var/log/ceph"},{"mountPath":"/var/lib/ceph/crash","name":"rook-ceph-crash"},{"mountPath":"/var/lib/ceph/rgw/ceph-my-store","name":"ceph-daemon-data"},{"mountPath":"/etc/ceph/rgw","name":"rook-ceph-rgw-my-store-mime-types","readOnly":true}]}],"restartPolicy":"Always","affinity":{"podAntiAffinity":{}},"tolerations":[{"tolerationSeconds":5,"key":"node.kubernetes.io/unreachable","operator":"Exists","effect":"NoExecute"}]}}},"status":{}}]

Basically .metadata.labels and .metadata.name are reversed.

Steps to reproduce the issue:

Deploy a Deployment resource with Labels.

Expected behavior

Annotations will get the same order all the time so that I don't get an endless reconcile loop.

Additional context

v1.1.0 worked well, the bug was introduced in v1.1.1 with banzaicloud@4236369.

Thanks in advance for your help.

Looks statefulSet always be update

Describe the bug

When I use patch.DefaultPatchMaker.Calculate(u, obj, opts...) to compare statefulSet, I always get the difference.

Looks in Current and Modified , the .spec.template is string, but in Original, it is struct.

Steps to reproduce the issue:

When I running code like this:

	patchResult, err := patch.DefaultPatchMaker.Calculate(u, obj, opts...)
	if err != nil {
		return emperror.Wrapf(err, "failed to calculate patch for %s %s", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName())
	}
	if !patchResult.IsEmpty() {
		if _, ok := obj.(*appsv1.StatefulSet); ok {
			fmt.Println(patchResult.String())
		}
		return handler.Update(obj, postFun)
	}

I found the patchResult always is not empty,the patchResult.String() is this:


Patch: {"spec":{"template":"{\"metadata\":{\"creationTimestamp\":null,\"labels\":{\"apps.emqx.io/instance\":\"emqx-ee\"},\"annotations\":{\"ACL/Base64EncodeConfig\":\"e2FsbG93LCBhbGx9Lgo=\",\"LoadedModules/Base64EncodeConfig\":\"W3sibmFtZSI6ImludGVybmFsX2FjbCIsImVuYWJsZSI6dHJ1ZSwiY29uZmlncyI6eyJhY2xfcnVsZV9maWxlIjoiL21vdW50ZWQvYWNsL2FjbC5jb25mIn19LHsibmFtZSI6InJldGFpbmVyIiwiZW5hYmxlIjp0cnVlLCJjb25maWdzIjp7ImV4cGlyeV9pbnRlcnZhbCI6MCwibWF4X3BheWxvYWRfc2l6ZSI6IjFNQiIsIm1heF9yZXRhaW5lZF9tZXNzYWdlcyI6MCwic3RvcmFnZV90eXBlIjoicmFtIn19XQ==\",\"apps.emqx.io/manage-containers\":\"emqx,reloader\"}},\"spec\":{\"volumes\":[{\"name\":\"fake-volume\",\"emptyDir\":{}},{\"name\":\"emqx-ee-data\",\"emptyDir\":{}},{\"name\":\"emqx-ee-plugins-config\",\"configMap\":{\"name\":\"emqx-ee-plugins-config\"}},{\"name\":\"emqx-ee-acl\",\"configMap\":{\"name\":\"emqx-ee-acl\"}},{\"name\":\"emqx-ee-loaded-modules\",\"configMap\":{\"name\":\"emqx-ee-loaded-modules\"}},{\"name\":\"emqx-ee-license\",\"secret\":{\"secretName\":\"emqx-ee-license\"}}],\"containers\":[{\"name\":\"emqx\",\"image\":\"emqx/emqx-ee:4.4.8\",\"args\":[\"bash\",\"-c\",\"printenv | grep \\\"^EMQX_\\\"\\nemqx foreground\\n\"],\"env\":[{\"name\":\"EMQX_CLUSTER__DISCOVERY\",\"value\":\"dns\"},{\"name\":\"EMQX_CLUSTER__DNS__APP\",\"value\":\"emqx-ee\"},{\"name\":\"EMQX_CLUSTER__DNS__NAME\",\"value\":\"emqx-ee-headless.default.svc.cluster.local\"},{\"name\":\"EMQX_CLUSTER__DNS__TYPE\",\"value\":\"srv\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\",\"value\":\"admin\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\",\"value\":\"public\"},{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\",\"value\":\"1883\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\",\"value\":\"admin\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\",\"value\":\"public\"},{\"name\":\"EMQX_NAME\",\"value\":\"emqx-ee\"},{\"name\":\"Foo\",\"value\":\"Bar\"},{\"name\":\"EMQX_PLUGINS__ETC_DIR\",\"value\":\"/mounted/plugins/etc\"},{\"name\":\"EMQX_ACL_FILE\",\"value\":\"/mounted/acl/acl.conf\"},{\"name\":\"EMQX_MODULES__LOADED_FILE\",\"value\":\"/mounted/modules/loaded_modules\"},{\"name\":\"EMQX_LICENSE__FILE\",\"value\":\"/mounted/license/emqx.lic\"}],\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1Gi\"},\"requests\":{\"cpu\":\"125m\",\"memory\":\"64Mi\"}},\"volumeMounts\":[{\"name\":\"fake-volume\",\"mountPath\":\"/tmp/fake\"},{\"name\":\"emqx-ee-data\",\"mountPath\":\"/opt/emqx/data\"},{\"name\":\"emqx-ee-plugins-config\",\"mountPath\":\"/mounted/plugins/etc\"},{\"name\":\"emqx-ee-acl\",\"mountPath\":\"/mounted/acl\"},{\"name\":\"emqx-ee-loaded-modules\",\"mountPath\":\"/mounted/modules\"},{\"name\":\"emqx-ee-license\",\"readOnly\":true,\"mountPath\":\"/mounted/license\"}],\"livenessProbe\":{\"httpGet\":{\"path\":\"/status\",\"port\":8081},\"initialDelaySeconds\":60,\"periodSeconds\":30,\"failureThreshold\":3},\"readinessProbe\":{\"httpGet\":{\"path\":\"/status\",\"port\":8081},\"initialDelaySeconds\":10,\"periodSeconds\":5,\"failureThreshold\":12},\"imagePullPolicy\":\"IfNotPresent\"},{\"name\":\"reloader\",\"image\":\"emqx/emqx-operator-reloader:0.0.2\",\"args\":[\"-u\",\"admin\",\"-p\",\"public\",\"-P\",\"8081\"],\"env\":[{\"name\":\"EMQX_CLUSTER__DISCOVERY\",\"value\":\"dns\"},{\"name\":\"EMQX_CLUSTER__DNS__APP\",\"value\":\"emqx-ee\"},{\"name\":\"EMQX_CLUSTER__DNS__NAME\",\"value\":\"emqx-ee-headless.default.svc.cluster.local\"},{\"name\":\"EMQX_CLUSTER__DNS__TYPE\",\"value\":\"srv\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\",\"value\":\"admin\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\",\"value\":\"public\"},{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\",\"value\":\"1883\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\",\"value\":\"admin\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\",\"value\":\"public\"},{\"name\":\"EMQX_NAME\",\"value\":\"emqx-ee\"},{\"name\":\"Foo\",\"value\":\"Bar\"},{\"name\":\"EMQX_PLUGINS__ETC_DIR\",\"value\":\"/mounted/plugins/etc\"},{\"name\":\"EMQX_ACL_FILE\",\"value\":\"/mounted/acl/acl.conf\"},{\"name\":\"EMQX_MODULES__LOADED_FILE\",\"value\":\"/mounted/modules/loaded_modules\"},{\"name\":\"EMQX_LICENSE__FILE\",\"value\":\"/mounted/license/emqx.lic\"}],\"resources\":{},\"volumeMounts\":[{\"name\":\"fake-volume\",\"mountPath\":\"/tmp/fake\"},{\"name\":\"emqx-ee-data\",\"mountPath\":\"/opt/emqx/data\"},{\"name\":\"emqx-ee-plugins-config\",\"mountPath\":\"/mounted/plugins/etc\"},{\"name\":\"emqx-ee-acl\",\"mountPath\":\"/mounted/acl\"},{\"name\":\"emqx-ee-loaded-modules\",\"mountPath\":\"/mounted/modules\"},{\"name\":\"emqx-ee-license\",\"readOnly\":true,\"mountPath\":\"/mounted/license\"}],\"imagePullPolicy\":\"IfNotPresent\"}],\"securityContext\":{\"runAsUser\":1000,\"runAsGroup\":1000,\"fsGroup\":1000,\"fsGroupChangePolicy\":\"Always\"}}}"}} 
Current: {"apiVersion":"apps/v1","kind":"StatefulSet","metadata":{"annotations":{"banzaicloud.com/last-applied":"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"},"creationTimestamp":"2022-11-02T07:31:19Z","generation":1,"labels":{"apps.emqx.io/instance":"emqx-ee"},"managedFields":[{"apiVersion":"apps/v1","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:banzaicloud.com/last-applied":{}},"f:labels":{".":{},"f:apps.emqx.io/instance":{}},"f:ownerReferences":{".":{},"k:{\"uid\":\"cf09ca06-297e-433d-a889-4e7d64a535b1\"}":{}}},"f:spec":{"f:podManagementPolicy":{},"f:replicas":{},"f:revisionHistoryLimit":{},"f:selector":{},"f:serviceName":{},"f:template":{"f:metadata":{"f:annotations":{".":{},"f:ACL/Base64EncodeConfig":{},"f:LoadedModules/Base64EncodeConfig":{},"f:apps.emqx.io/manage-containers":{}},"f:labels":{".":{},"f:apps.emqx.io/instance":{}}},"f:spec":{"f:containers":{"k:{\"name\":\"emqx\"}":{".":{},"f:args":{},"f:env":{".":{},"k:{\"name\":\"EMQX_ACL_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DISCOVERY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__APP\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__TYPE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LICENSE__FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MODULES__LOADED_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_PLUGINS__ETC_DIR\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"Foo\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:livenessProbe":{".":{},"f:failureThreshold":{},"f:httpGet":{".":{},"f:path":{},"f:port":{},"f:scheme":{}},"f:initialDelaySeconds":{},"f:periodSeconds":{},"f:successThreshold":{},"f:timeoutSeconds":{}},"f:name":{},"f:readinessProbe":{".":{},"f:failureThreshold":{},"f:httpGet":{".":{},"f:path":{},"f:port":{},"f:scheme":{}},"f:initialDelaySeconds":{},"f:periodSeconds":{},"f:successThreshold":{},"f:timeoutSeconds":{}},"f:resources":{".":{},"f:limits":{".":{},"f:cpu":{},"f:memory":{}},"f:requests":{".":{},"f:cpu":{},"f:memory":{}}},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{},"f:volumeMounts":{".":{},"k:{\"mountPath\":\"/mounted/acl\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/license\"}":{".":{},"f:mountPath":{},"f:name":{},"f:readOnly":{}},"k:{\"mountPath\":\"/mounted/modules\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/plugins/etc\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/opt/emqx/data\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/tmp/fake\"}":{".":{},"f:mountPath":{},"f:name":{}}}},"k:{\"name\":\"reloader\"}":{".":{},"f:args":{},"f:env":{".":{},"k:{\"name\":\"EMQX_ACL_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DISCOVERY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__APP\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__TYPE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LICENSE__FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MODULES__LOADED_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_PLUGINS__ETC_DIR\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"Foo\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:resources":{},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{},"f:volumeMounts":{".":{},"k:{\"mountPath\":\"/mounted/acl\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/license\"}":{".":{},"f:mountPath":{},"f:name":{},"f:readOnly":{}},"k:{\"mountPath\":\"/mounted/modules\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/plugins/etc\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/opt/emqx/data\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/tmp/fake\"}":{".":{},"f:mountPath":{},"f:name":{}}}}},"f:dnsPolicy":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{".":{},"f:fsGroup":{},"f:fsGroupChangePolicy":{},"f:runAsGroup":{},"f:runAsUser":{}},"f:terminationGracePeriodSeconds":{},"f:volumes":{".":{},"k:{\"name\":\"emqx-ee-acl\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"emqx-ee-data\"}":{".":{},"f:emptyDir":{},"f:name":{}},"k:{\"name\":\"emqx-ee-license\"}":{".":{},"f:name":{},"f:secret":{".":{},"f:defaultMode":{},"f:secretName":{}}},"k:{\"name\":\"emqx-ee-loaded-modules\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"emqx-ee-plugins-config\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"fake-volume\"}":{".":{},"f:emptyDir":{},"f:name":{}}}}},"f:updateStrategy":{"f:rollingUpdate":{".":{},"f:partition":{}},"f:type":{}}}},"manager":"__debug_bin","operation":"Update","time":"2022-11-02T07:31:19Z"},{"apiVersion":"apps/v1","fieldsType":"FieldsV1","fieldsV1":{"f:status":{"f:availableReplicas":{},"f:collisionCount":{},"f:currentReplicas":{},"f:currentRevision":{},"f:observedGeneration":{},"f:readyReplicas":{},"f:replicas":{},"f:updateRevision":{},"f:updatedReplicas":{}}},"manager":"kube-controller-manager","operation":"Update","subresource":"status","time":"2022-11-03T07:27:23Z"}],"name":"emqx-ee","namespace":"default","ownerReferences":[{"apiVersion":"apps.emqx.io/v1beta3","blockOwnerDeletion":true,"controller":true,"kind":"EmqxEnterprise","name":"emqx-ee","uid":"cf09ca06-297e-433d-a889-4e7d64a535b1"}],"resourceVersion":"64951","uid":"91885156-8947-4707-ae70-dd47ac8c308b"},"spec":{"podManagementPolicy":"Parallel","replicas":1,"revisionHistoryLimit":10,"selector":{"matchLabels":{"apps.emqx.io/instance":"emqx-ee"}},"serviceName":"emqx-ee-headless","template":"{\"metadata\":{\"creationTimestamp\":null,\"labels\":{\"apps.emqx.io/instance\":\"emqx-ee\"},\"annotations\":{\"ACL/Base64EncodeConfig\":\"e2FsbG93LCBhbGx9Lgo=\",\"LoadedModules/Base64EncodeConfig\":\"W3sibmFtZSI6ImludGVybmFsX2FjbCIsImVuYWJsZSI6dHJ1ZSwiY29uZmlncyI6eyJhY2xfcnVsZV9maWxlIjoiL21vdW50ZWQvYWNsL2FjbC5jb25mIn19LHsibmFtZSI6InJldGFpbmVyIiwiZW5hYmxlIjp0cnVlLCJjb25maWdzIjp7ImV4cGlyeV9pbnRlcnZhbCI6MCwibWF4X3BheWxvYWRfc2l6ZSI6IjFNQiIsIm1heF9yZXRhaW5lZF9tZXNzYWdlcyI6MCwic3RvcmFnZV90eXBlIjoicmFtIn19XQ==\",\"apps.emqx.io/manage-containers\":\"emqx,reloader\"}},\"spec\":{\"volumes\":[{\"name\":\"fake-volume\",\"emptyDir\":{}},{\"name\":\"emqx-ee-data\",\"emptyDir\":{}},{\"name\":\"emqx-ee-plugins-config\",\"configMap\":{\"name\":\"emqx-ee-plugins-config\",\"defaultMode\":420}},{\"name\":\"emqx-ee-acl\",\"configMap\":{\"name\":\"emqx-ee-acl\",\"defaultMode\":420}},{\"name\":\"emqx-ee-loaded-modules\",\"configMap\":{\"name\":\"emqx-ee-loaded-modules\",\"defaultMode\":420}},{\"name\":\"emqx-ee-license\",\"secret\":{\"secretName\":\"emqx-ee-license\",\"defaultMode\":420}}],\"containers\":[{\"name\":\"emqx\",\"image\":\"emqx/emqx-ee:4.4.8\",\"args\":[\"bash\",\"-c\",\"printenv | grep \\\"^EMQX_\\\"\\nemqx foreground\\n\"],\"env\":[{\"name\":\"EMQX_CLUSTER__DISCOVERY\",\"value\":\"dns\"},{\"name\":\"EMQX_CLUSTER__DNS__APP\",\"value\":\"emqx-ee\"},{\"name\":\"EMQX_CLUSTER__DNS__NAME\",\"value\":\"emqx-ee-headless.default.svc.cluster.local\"},{\"name\":\"EMQX_CLUSTER__DNS__TYPE\",\"value\":\"srv\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\",\"value\":\"admin\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\",\"value\":\"public\"},{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\",\"value\":\"1883\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\",\"value\":\"admin\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\",\"value\":\"public\"},{\"name\":\"EMQX_NAME\",\"value\":\"emqx-ee\"},{\"name\":\"Foo\",\"value\":\"Bar\"},{\"name\":\"EMQX_PLUGINS__ETC_DIR\",\"value\":\"/mounted/plugins/etc\"},{\"name\":\"EMQX_ACL_FILE\",\"value\":\"/mounted/acl/acl.conf\"},{\"name\":\"EMQX_MODULES__LOADED_FILE\",\"value\":\"/mounted/modules/loaded_modules\"},{\"name\":\"EMQX_LICENSE__FILE\",\"value\":\"/mounted/license/emqx.lic\"}],\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1Gi\"},\"requests\":{\"cpu\":\"125m\",\"memory\":\"64Mi\"}},\"volumeMounts\":[{\"name\":\"fake-volume\",\"mountPath\":\"/tmp/fake\"},{\"name\":\"emqx-ee-data\",\"mountPath\":\"/opt/emqx/data\"},{\"name\":\"emqx-ee-plugins-config\",\"mountPath\":\"/mounted/plugins/etc\"},{\"name\":\"emqx-ee-acl\",\"mountPath\":\"/mounted/acl\"},{\"name\":\"emqx-ee-loaded-modules\",\"mountPath\":\"/mounted/modules\"},{\"name\":\"emqx-ee-license\",\"readOnly\":true,\"mountPath\":\"/mounted/license\"}],\"livenessProbe\":{\"httpGet\":{\"path\":\"/status\",\"port\":8081,\"scheme\":\"HTTP\"},\"initialDelaySeconds\":60,\"timeoutSeconds\":1,\"periodSeconds\":30,\"successThreshold\":1,\"failureThreshold\":3},\"readinessProbe\":{\"httpGet\":{\"path\":\"/status\",\"port\":8081,\"scheme\":\"HTTP\"},\"initialDelaySeconds\":10,\"timeoutSeconds\":1,\"periodSeconds\":5,\"successThreshold\":1,\"failureThreshold\":12},\"terminationMessagePath\":\"/dev/termination-log\",\"terminationMessagePolicy\":\"File\",\"imagePullPolicy\":\"IfNotPresent\"},{\"name\":\"reloader\",\"image\":\"emqx/emqx-operator-reloader:0.0.2\",\"args\":[\"-u\",\"admin\",\"-p\",\"public\",\"-P\",\"8081\"],\"env\":[{\"name\":\"EMQX_CLUSTER__DISCOVERY\",\"value\":\"dns\"},{\"name\":\"EMQX_CLUSTER__DNS__APP\",\"value\":\"emqx-ee\"},{\"name\":\"EMQX_CLUSTER__DNS__NAME\",\"value\":\"emqx-ee-headless.default.svc.cluster.local\"},{\"name\":\"EMQX_CLUSTER__DNS__TYPE\",\"value\":\"srv\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\",\"value\":\"admin\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\",\"value\":\"public\"},{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\",\"value\":\"1883\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\",\"value\":\"admin\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\",\"value\":\"public\"},{\"name\":\"EMQX_NAME\",\"value\":\"emqx-ee\"},{\"name\":\"Foo\",\"value\":\"Bar\"},{\"name\":\"EMQX_PLUGINS__ETC_DIR\",\"value\":\"/mounted/plugins/etc\"},{\"name\":\"EMQX_ACL_FILE\",\"value\":\"/mounted/acl/acl.conf\"},{\"name\":\"EMQX_MODULES__LOADED_FILE\",\"value\":\"/mounted/modules/loaded_modules\"},{\"name\":\"EMQX_LICENSE__FILE\",\"value\":\"/mounted/license/emqx.lic\"}],\"resources\":{},\"volumeMounts\":[{\"name\":\"fake-volume\",\"mountPath\":\"/tmp/fake\"},{\"name\":\"emqx-ee-data\",\"mountPath\":\"/opt/emqx/data\"},{\"name\":\"emqx-ee-plugins-config\",\"mountPath\":\"/mounted/plugins/etc\"},{\"name\":\"emqx-ee-acl\",\"mountPath\":\"/mounted/acl\"},{\"name\":\"emqx-ee-loaded-modules\",\"mountPath\":\"/mounted/modules\"},{\"name\":\"emqx-ee-license\",\"readOnly\":true,\"mountPath\":\"/mounted/license\"}],\"terminationMessagePath\":\"/dev/termination-log\",\"terminationMessagePolicy\":\"File\",\"imagePullPolicy\":\"IfNotPresent\"}],\"restartPolicy\":\"Always\",\"terminationGracePeriodSeconds\":30,\"dnsPolicy\":\"ClusterFirst\",\"securityContext\":{\"runAsUser\":1000,\"runAsGroup\":1000,\"fsGroup\":1000,\"fsGroupChangePolicy\":\"Always\"},\"schedulerName\":\"default-scheduler\"}}","updateStrategy":{"rollingUpdate":{"partition":0},"type":"RollingUpdate"}}}
Modified: {"apiVersion":"apps/v1","kind":"StatefulSet","metadata":{"annotations":{"banzaicloud.com/last-applied":"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"},"creationTimestamp":"2022-11-02T07:31:19Z","labels":{"apps.emqx.io/instance":"emqx-ee"},"managedFields":[{"apiVersion":"apps/v1","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:banzaicloud.com/last-applied":{}},"f:labels":{".":{},"f:apps.emqx.io/instance":{}},"f:ownerReferences":{".":{},"k:{\"uid\":\"cf09ca06-297e-433d-a889-4e7d64a535b1\"}":{}}},"f:spec":{"f:podManagementPolicy":{},"f:replicas":{},"f:revisionHistoryLimit":{},"f:selector":{},"f:serviceName":{},"f:template":{"f:metadata":{"f:annotations":{".":{},"f:ACL/Base64EncodeConfig":{},"f:LoadedModules/Base64EncodeConfig":{},"f:apps.emqx.io/manage-containers":{}},"f:labels":{".":{},"f:apps.emqx.io/instance":{}}},"f:spec":{"f:containers":{"k:{\"name\":\"emqx\"}":{".":{},"f:args":{},"f:env":{".":{},"k:{\"name\":\"EMQX_ACL_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DISCOVERY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__APP\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__TYPE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LICENSE__FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MODULES__LOADED_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_PLUGINS__ETC_DIR\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"Foo\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:livenessProbe":{".":{},"f:failureThreshold":{},"f:httpGet":{".":{},"f:path":{},"f:port":{},"f:scheme":{}},"f:initialDelaySeconds":{},"f:periodSeconds":{},"f:successThreshold":{},"f:timeoutSeconds":{}},"f:name":{},"f:readinessProbe":{".":{},"f:failureThreshold":{},"f:httpGet":{".":{},"f:path":{},"f:port":{},"f:scheme":{}},"f:initialDelaySeconds":{},"f:periodSeconds":{},"f:successThreshold":{},"f:timeoutSeconds":{}},"f:resources":{".":{},"f:limits":{".":{},"f:cpu":{},"f:memory":{}},"f:requests":{".":{},"f:cpu":{},"f:memory":{}}},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{},"f:volumeMounts":{".":{},"k:{\"mountPath\":\"/mounted/acl\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/license\"}":{".":{},"f:mountPath":{},"f:name":{},"f:readOnly":{}},"k:{\"mountPath\":\"/mounted/modules\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/plugins/etc\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/opt/emqx/data\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/tmp/fake\"}":{".":{},"f:mountPath":{},"f:name":{}}}},"k:{\"name\":\"reloader\"}":{".":{},"f:args":{},"f:env":{".":{},"k:{\"name\":\"EMQX_ACL_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DISCOVERY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__APP\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__TYPE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LICENSE__FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MODULES__LOADED_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_PLUGINS__ETC_DIR\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"Foo\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:resources":{},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{},"f:volumeMounts":{".":{},"k:{\"mountPath\":\"/mounted/acl\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/license\"}":{".":{},"f:mountPath":{},"f:name":{},"f:readOnly":{}},"k:{\"mountPath\":\"/mounted/modules\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/plugins/etc\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/opt/emqx/data\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/tmp/fake\"}":{".":{},"f:mountPath":{},"f:name":{}}}}},"f:dnsPolicy":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{".":{},"f:fsGroup":{},"f:fsGroupChangePolicy":{},"f:runAsGroup":{},"f:runAsUser":{}},"f:terminationGracePeriodSeconds":{},"f:volumes":{".":{},"k:{\"name\":\"emqx-ee-acl\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"emqx-ee-data\"}":{".":{},"f:emptyDir":{},"f:name":{}},"k:{\"name\":\"emqx-ee-license\"}":{".":{},"f:name":{},"f:secret":{".":{},"f:defaultMode":{},"f:secretName":{}}},"k:{\"name\":\"emqx-ee-loaded-modules\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"emqx-ee-plugins-config\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"fake-volume\"}":{".":{},"f:emptyDir":{},"f:name":{}}}}},"f:updateStrategy":{"f:rollingUpdate":{".":{},"f:partition":{}},"f:type":{}}}},"manager":"__debug_bin","operation":"Update","time":"2022-11-02T07:31:19Z"},{"apiVersion":"apps/v1","fieldsType":"FieldsV1","fieldsV1":{"f:status":{"f:availableReplicas":{},"f:collisionCount":{},"f:currentReplicas":{},"f:currentRevision":{},"f:observedGeneration":{},"f:readyReplicas":{},"f:replicas":{},"f:updateRevision":{},"f:updatedReplicas":{}}},"manager":"kube-controller-manager","operation":"Update","subresource":"status","time":"2022-11-03T07:27:23Z"}],"name":"emqx-ee","namespace":"default","ownerReferences":[{"apiVersion":"apps.emqx.io/v1beta3","blockOwnerDeletion":true,"controller":true,"kind":"EmqxEnterprise","name":"emqx-ee","uid":"cf09ca06-297e-433d-a889-4e7d64a535b1"}],"resourceVersion":"64951"},"spec":{"podManagementPolicy":"Parallel","replicas":1,"selector":{"matchLabels":{"apps.emqx.io/instance":"emqx-ee"}},"serviceName":"emqx-ee-headless","template":"{\"metadata\":{\"creationTimestamp\":null,\"labels\":{\"apps.emqx.io/instance\":\"emqx-ee\"},\"annotations\":{\"ACL/Base64EncodeConfig\":\"e2FsbG93LCBhbGx9Lgo=\",\"LoadedModules/Base64EncodeConfig\":\"W3sibmFtZSI6ImludGVybmFsX2FjbCIsImVuYWJsZSI6dHJ1ZSwiY29uZmlncyI6eyJhY2xfcnVsZV9maWxlIjoiL21vdW50ZWQvYWNsL2FjbC5jb25mIn19LHsibmFtZSI6InJldGFpbmVyIiwiZW5hYmxlIjp0cnVlLCJjb25maWdzIjp7ImV4cGlyeV9pbnRlcnZhbCI6MCwibWF4X3BheWxvYWRfc2l6ZSI6IjFNQiIsIm1heF9yZXRhaW5lZF9tZXNzYWdlcyI6MCwic3RvcmFnZV90eXBlIjoicmFtIn19XQ==\",\"apps.emqx.io/manage-containers\":\"emqx,reloader\"}},\"spec\":{\"volumes\":[{\"name\":\"fake-volume\",\"emptyDir\":{}},{\"name\":\"emqx-ee-data\",\"emptyDir\":{}},{\"name\":\"emqx-ee-plugins-config\",\"configMap\":{\"name\":\"emqx-ee-plugins-config\"}},{\"name\":\"emqx-ee-acl\",\"configMap\":{\"name\":\"emqx-ee-acl\"}},{\"name\":\"emqx-ee-loaded-modules\",\"configMap\":{\"name\":\"emqx-ee-loaded-modules\"}},{\"name\":\"emqx-ee-license\",\"secret\":{\"secretName\":\"emqx-ee-license\"}}],\"containers\":[{\"name\":\"emqx\",\"image\":\"emqx/emqx-ee:4.4.8\",\"args\":[\"bash\",\"-c\",\"printenv | grep \\\"^EMQX_\\\"\\nemqx foreground\\n\"],\"env\":[{\"name\":\"EMQX_CLUSTER__DISCOVERY\",\"value\":\"dns\"},{\"name\":\"EMQX_CLUSTER__DNS__APP\",\"value\":\"emqx-ee\"},{\"name\":\"EMQX_CLUSTER__DNS__NAME\",\"value\":\"emqx-ee-headless.default.svc.cluster.local\"},{\"name\":\"EMQX_CLUSTER__DNS__TYPE\",\"value\":\"srv\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\",\"value\":\"admin\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\",\"value\":\"public\"},{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\",\"value\":\"1883\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\",\"value\":\"admin\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\",\"value\":\"public\"},{\"name\":\"EMQX_NAME\",\"value\":\"emqx-ee\"},{\"name\":\"Foo\",\"value\":\"Bar\"},{\"name\":\"EMQX_PLUGINS__ETC_DIR\",\"value\":\"/mounted/plugins/etc\"},{\"name\":\"EMQX_ACL_FILE\",\"value\":\"/mounted/acl/acl.conf\"},{\"name\":\"EMQX_MODULES__LOADED_FILE\",\"value\":\"/mounted/modules/loaded_modules\"},{\"name\":\"EMQX_LICENSE__FILE\",\"value\":\"/mounted/license/emqx.lic\"}],\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1Gi\"},\"requests\":{\"cpu\":\"125m\",\"memory\":\"64Mi\"}},\"volumeMounts\":[{\"name\":\"fake-volume\",\"mountPath\":\"/tmp/fake\"},{\"name\":\"emqx-ee-data\",\"mountPath\":\"/opt/emqx/data\"},{\"name\":\"emqx-ee-plugins-config\",\"mountPath\":\"/mounted/plugins/etc\"},{\"name\":\"emqx-ee-acl\",\"mountPath\":\"/mounted/acl\"},{\"name\":\"emqx-ee-loaded-modules\",\"mountPath\":\"/mounted/modules\"},{\"name\":\"emqx-ee-license\",\"readOnly\":true,\"mountPath\":\"/mounted/license\"}],\"livenessProbe\":{\"httpGet\":{\"path\":\"/status\",\"port\":8081},\"initialDelaySeconds\":60,\"periodSeconds\":30,\"failureThreshold\":3},\"readinessProbe\":{\"httpGet\":{\"path\":\"/status\",\"port\":8081},\"initialDelaySeconds\":10,\"periodSeconds\":5,\"failureThreshold\":12},\"imagePullPolicy\":\"IfNotPresent\"},{\"name\":\"reloader\",\"image\":\"emqx/emqx-operator-reloader:0.0.2\",\"args\":[\"-u\",\"admin\",\"-p\",\"public\",\"-P\",\"8081\"],\"env\":[{\"name\":\"EMQX_CLUSTER__DISCOVERY\",\"value\":\"dns\"},{\"name\":\"EMQX_CLUSTER__DNS__APP\",\"value\":\"emqx-ee\"},{\"name\":\"EMQX_CLUSTER__DNS__NAME\",\"value\":\"emqx-ee-headless.default.svc.cluster.local\"},{\"name\":\"EMQX_CLUSTER__DNS__TYPE\",\"value\":\"srv\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\",\"value\":\"admin\"},{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\",\"value\":\"public\"},{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\",\"value\":\"1883\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\",\"value\":\"admin\"},{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\",\"value\":\"public\"},{\"name\":\"EMQX_NAME\",\"value\":\"emqx-ee\"},{\"name\":\"Foo\",\"value\":\"Bar\"},{\"name\":\"EMQX_PLUGINS__ETC_DIR\",\"value\":\"/mounted/plugins/etc\"},{\"name\":\"EMQX_ACL_FILE\",\"value\":\"/mounted/acl/acl.conf\"},{\"name\":\"EMQX_MODULES__LOADED_FILE\",\"value\":\"/mounted/modules/loaded_modules\"},{\"name\":\"EMQX_LICENSE__FILE\",\"value\":\"/mounted/license/emqx.lic\"}],\"resources\":{},\"volumeMounts\":[{\"name\":\"fake-volume\",\"mountPath\":\"/tmp/fake\"},{\"name\":\"emqx-ee-data\",\"mountPath\":\"/opt/emqx/data\"},{\"name\":\"emqx-ee-plugins-config\",\"mountPath\":\"/mounted/plugins/etc\"},{\"name\":\"emqx-ee-acl\",\"mountPath\":\"/mounted/acl\"},{\"name\":\"emqx-ee-loaded-modules\",\"mountPath\":\"/mounted/modules\"},{\"name\":\"emqx-ee-license\",\"readOnly\":true,\"mountPath\":\"/mounted/license\"}],\"imagePullPolicy\":\"IfNotPresent\"}],\"securityContext\":{\"runAsUser\":1000,\"runAsGroup\":1000,\"fsGroup\":1000,\"fsGroupChangePolicy\":\"Always\"}}}","updateStrategy":{}}}
Original: {"apiVersion":"apps/v1","kind":"StatefulSet","metadata":{"creationTimestamp":"2022-11-02T07:31:19Z","labels":{"apps.emqx.io/instance":"emqx-ee"},"managedFields":[{"apiVersion":"apps/v1","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:banzaicloud.com/last-applied":{}},"f:labels":{".":{},"f:apps.emqx.io/instance":{}},"f:ownerReferences":{".":{},"k:{\"uid\":\"cf09ca06-297e-433d-a889-4e7d64a535b1\"}":{}}},"f:spec":{"f:podManagementPolicy":{},"f:replicas":{},"f:revisionHistoryLimit":{},"f:selector":{},"f:serviceName":{},"f:template":{"f:metadata":{"f:annotations":{".":{},"f:ACL/Base64EncodeConfig":{},"f:LoadedModules/Base64EncodeConfig":{},"f:apps.emqx.io/manage-containers":{}},"f:labels":{".":{},"f:apps.emqx.io/instance":{}}},"f:spec":{"f:containers":{"k:{\"name\":\"emqx\"}":{".":{},"f:args":{},"f:env":{".":{},"k:{\"name\":\"EMQX_ACL_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DISCOVERY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__APP\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__TYPE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LICENSE__FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MODULES__LOADED_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_PLUGINS__ETC_DIR\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"Foo\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:livenessProbe":{".":{},"f:failureThreshold":{},"f:httpGet":{".":{},"f:path":{},"f:port":{},"f:scheme":{}},"f:initialDelaySeconds":{},"f:periodSeconds":{},"f:successThreshold":{},"f:timeoutSeconds":{}},"f:name":{},"f:readinessProbe":{".":{},"f:failureThreshold":{},"f:httpGet":{".":{},"f:path":{},"f:port":{},"f:scheme":{}},"f:initialDelaySeconds":{},"f:periodSeconds":{},"f:successThreshold":{},"f:timeoutSeconds":{}},"f:resources":{".":{},"f:limits":{".":{},"f:cpu":{},"f:memory":{}},"f:requests":{".":{},"f:cpu":{},"f:memory":{}}},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{},"f:volumeMounts":{".":{},"k:{\"mountPath\":\"/mounted/acl\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/license\"}":{".":{},"f:mountPath":{},"f:name":{},"f:readOnly":{}},"k:{\"mountPath\":\"/mounted/modules\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/plugins/etc\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/opt/emqx/data\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/tmp/fake\"}":{".":{},"f:mountPath":{},"f:name":{}}}},"k:{\"name\":\"reloader\"}":{".":{},"f:args":{},"f:env":{".":{},"k:{\"name\":\"EMQX_ACL_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DISCOVERY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__APP\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_CLUSTER__DNS__TYPE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__LOGIN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LICENSE__FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_LISTENER__TCP__EXTERNAL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_MODULES__LOADED_FILE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"EMQX_PLUGINS__ETC_DIR\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"Foo\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:resources":{},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{},"f:volumeMounts":{".":{},"k:{\"mountPath\":\"/mounted/acl\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/license\"}":{".":{},"f:mountPath":{},"f:name":{},"f:readOnly":{}},"k:{\"mountPath\":\"/mounted/modules\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/mounted/plugins/etc\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/opt/emqx/data\"}":{".":{},"f:mountPath":{},"f:name":{}},"k:{\"mountPath\":\"/tmp/fake\"}":{".":{},"f:mountPath":{},"f:name":{}}}}},"f:dnsPolicy":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{".":{},"f:fsGroup":{},"f:fsGroupChangePolicy":{},"f:runAsGroup":{},"f:runAsUser":{}},"f:terminationGracePeriodSeconds":{},"f:volumes":{".":{},"k:{\"name\":\"emqx-ee-acl\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"emqx-ee-data\"}":{".":{},"f:emptyDir":{},"f:name":{}},"k:{\"name\":\"emqx-ee-license\"}":{".":{},"f:name":{},"f:secret":{".":{},"f:defaultMode":{},"f:secretName":{}}},"k:{\"name\":\"emqx-ee-loaded-modules\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"emqx-ee-plugins-config\"}":{".":{},"f:configMap":{".":{},"f:defaultMode":{},"f:name":{}},"f:name":{}},"k:{\"name\":\"fake-volume\"}":{".":{},"f:emptyDir":{},"f:name":{}}}}},"f:updateStrategy":{"f:rollingUpdate":{".":{},"f:partition":{}},"f:type":{}}}},"manager":"__debug_bin","operation":"Update","time":"2022-11-02T07:31:19Z"},{"apiVersion":"apps/v1","fieldsType":"FieldsV1","fieldsV1":{"f:status":{"f:availableReplicas":{},"f:collisionCount":{},"f:currentReplicas":{},"f:currentRevision":{},"f:observedGeneration":{},"f:readyReplicas":{},"f:replicas":{},"f:updateRevision":{},"f:updatedReplicas":{}}},"manager":"kube-controller-manager","operation":"Update","subresource":"status","time":"2022-11-03T07:27:23Z"}],"name":"emqx-ee","namespace":"default","ownerReferences":[{"apiVersion":"apps.emqx.io/v1beta3","blockOwnerDeletion":true,"controller":true,"kind":"EmqxEnterprise","name":"emqx-ee","uid":"cf09ca06-297e-433d-a889-4e7d64a535b1"}],"resourceVersion":"60452"},"spec":{"podManagementPolicy":"Parallel","replicas":1,"selector":{"matchLabels":{"apps.emqx.io/instance":"emqx-ee"}},"serviceName":"emqx-ee-headless","template":{"metadata":{"annotations":{"ACL/Base64EncodeConfig":"e2FsbG93LCBhbGx9Lgo=","LoadedModules/Base64EncodeConfig":"W3sibmFtZSI6ImludGVybmFsX2FjbCIsImVuYWJsZSI6dHJ1ZSwiY29uZmlncyI6eyJhY2xfcnVsZV9maWxlIjoiL21vdW50ZWQvYWNsL2FjbC5jb25mIn19LHsibmFtZSI6InJldGFpbmVyIiwiZW5hYmxlIjp0cnVlLCJjb25maWdzIjp7ImV4cGlyeV9pbnRlcnZhbCI6MCwibWF4X3BheWxvYWRfc2l6ZSI6IjFNQiIsIm1heF9yZXRhaW5lZF9tZXNzYWdlcyI6MCwic3RvcmFnZV90eXBlIjoicmFtIn19XQ==","apps.emqx.io/manage-containers":"emqx,reloader"},"labels":{"apps.emqx.io/instance":"emqx-ee"}},"spec":{"containers":[{"args":["bash","-c","printenv | grep \"^EMQX_\"\nemqx foreground\n"],"env":[{"name":"EMQX_CLUSTER__DISCOVERY","value":"dns"},{"name":"EMQX_CLUSTER__DNS__APP","value":"emqx-ee"},{"name":"EMQX_CLUSTER__DNS__NAME","value":"emqx-ee-headless.default.svc.cluster.local"},{"name":"EMQX_CLUSTER__DNS__TYPE","value":"srv"},{"name":"EMQX_DASHBOARD__DEFAULT_USER__LOGIN","value":"admin"},{"name":"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD","value":"public"},{"name":"EMQX_LISTENER__TCP__EXTERNAL","value":"1883"},{"name":"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID","value":"admin"},{"name":"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET","value":"public"},{"name":"EMQX_NAME","value":"emqx-ee"},{"name":"Foo","value":"Bar"},{"name":"EMQX_PLUGINS__ETC_DIR","value":"/mounted/plugins/etc"},{"name":"EMQX_ACL_FILE","value":"/mounted/acl/acl.conf"},{"name":"EMQX_MODULES__LOADED_FILE","value":"/mounted/modules/loaded_modules"},{"name":"EMQX_LICENSE__FILE","value":"/mounted/license/emqx.lic"}],"image":"emqx/emqx-ee:4.4.8","imagePullPolicy":"IfNotPresent","livenessProbe":{"failureThreshold":3,"httpGet":{"path":"/status","port":8081},"initialDelaySeconds":60,"periodSeconds":30},"name":"emqx","readinessProbe":{"failureThreshold":12,"httpGet":{"path":"/status","port":8081},"initialDelaySeconds":10,"periodSeconds":5},"resources":{"limits":{"cpu":"500m","memory":"1Gi"},"requests":{"cpu":"125m","memory":"64Mi"}},"volumeMounts":[{"mountPath":"/tmp/fake","name":"fake-volume"},{"mountPath":"/opt/emqx/data","name":"emqx-ee-data"},{"mountPath":"/mounted/plugins/etc","name":"emqx-ee-plugins-config"},{"mountPath":"/mounted/acl","name":"emqx-ee-acl"},{"mountPath":"/mounted/modules","name":"emqx-ee-loaded-modules"},{"mountPath":"/mounted/license","name":"emqx-ee-license","readOnly":true}]},{"args":["-u","admin","-p","public","-P","8081"],"env":[{"name":"EMQX_CLUSTER__DISCOVERY","value":"dns"},{"name":"EMQX_CLUSTER__DNS__APP","value":"emqx-ee"},{"name":"EMQX_CLUSTER__DNS__NAME","value":"emqx-ee-headless.default.svc.cluster.local"},{"name":"EMQX_CLUSTER__DNS__TYPE","value":"srv"},{"name":"EMQX_DASHBOARD__DEFAULT_USER__LOGIN","value":"admin"},{"name":"EMQX_DASHBOARD__DEFAULT_USER__PASSWORD","value":"public"},{"name":"EMQX_LISTENER__TCP__EXTERNAL","value":"1883"},{"name":"EMQX_MANAGEMENT__DEFAULT_APPLICATION__ID","value":"admin"},{"name":"EMQX_MANAGEMENT__DEFAULT_APPLICATION__SECRET","value":"public"},{"name":"EMQX_NAME","value":"emqx-ee"},{"name":"Foo","value":"Bar"},{"name":"EMQX_PLUGINS__ETC_DIR","value":"/mounted/plugins/etc"},{"name":"EMQX_ACL_FILE","value":"/mounted/acl/acl.conf"},{"name":"EMQX_MODULES__LOADED_FILE","value":"/mounted/modules/loaded_modules"},{"name":"EMQX_LICENSE__FILE","value":"/mounted/license/emqx.lic"}],"image":"emqx/emqx-operator-reloader:0.0.2","imagePullPolicy":"IfNotPresent","name":"reloader","resources":{},"volumeMounts":[{"mountPath":"/tmp/fake","name":"fake-volume"},{"mountPath":"/opt/emqx/data","name":"emqx-ee-data"},{"mountPath":"/mounted/plugins/etc","name":"emqx-ee-plugins-config"},{"mountPath":"/mounted/acl","name":"emqx-ee-acl"},{"mountPath":"/mounted/modules","name":"emqx-ee-loaded-modules"},{"mountPath":"/mounted/license","name":"emqx-ee-license","readOnly":true}]}],"securityContext":{"fsGroup":1000,"fsGroupChangePolicy":"Always","runAsGroup":1000,"runAsUser":1000},"volumes":[{"emptyDir":{},"name":"fake-volume"},{"emptyDir":{},"name":"emqx-ee-data"},{"configMap":{"name":"emqx-ee-plugins-config"},"name":"emqx-ee-plugins-config"},{"configMap":{"name":"emqx-ee-acl"},"name":"emqx-ee-acl"},{"configMap":{"name":"emqx-ee-loaded-modules"},"name":"emqx-ee-loaded-modules"},{"name":"emqx-ee-license","secret":{"secretName":"emqx-ee-license"}}]}},"updateStrategy":{}},"status":{"availableReplicas":0,"replicas":0}}

Expected behavior
The patchResult should be empty

Other
Maybe this is reason: https://github.com/banzaicloud/k8s-objectmatcher/blob/a7fe438786b4ddeaf76c56d430ac725cdfa3cfc7/patch/deletenull.go#L107

The .spec.template converted to a string
image

patch.IgnoreField() should take the path to the entity to be ignored

Is your feature request related to a problem? Please describe.

I have this env in deployment spec

spec:
replicas: 3
selector:
matchLabels:
app: gcs
mciroservice: athena
realm: production
template:
metadata:
annotations:
vaultproject.io/policies: default, mongodb-athena
vaultproject.io/ttl: 72h
labels:
app: gcs
mciroservice: athena
realm: production
spec:
containers:
- env:
- name: KUBE_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name

when it is deployed, this env is expanded to:

"env":[{"name":"KUBE_POD_NAME","valueFrom":{"fieldRef":{"apiVersion":"v1","fieldPath":"metadata.name"}}}

which is always different from the spec.

Describe the solution you'd like to see
ignore field should use the path, such as the following:
spec.template.spec.env.name:KUBE_POD_NAME

Since the kubernetes resource is changed to map[string]interface{}, it can find the key/value by using the path and remove the item in this example

Look into why unnecessary setElementOrder directives are generated for Volumes and VolumeMounts in case of pods

Description of the problem

When matching pods (and possibly other types of objects) a typical issue is that the patch will contain unnecessary $setElementOrder directives, most probably caused by the automatically generated Volumes and VolumeMounts of the service account token.

Current mitigation

Right now this is mitigated by actually applying the patch locally and checking it against the current version to see if it is a false positive or not.

It is possibly a bug or a limitation in the package k8s.io/apimachinery/pkg/util/strategicpatch but would need more investigation to find out.

How to reproduce

Remove the code responsible for double checking the patch and run the integration tests go test -integration -v to see pod matches with original to fail with the following unwanted patch:

 {"spec":{"$setElementOrder/volumes":[{"name":"empty"}]}}

The original pod spec:

&v1.Pod{
				ObjectMeta: standardObjectMeta(),
				Spec: v1.PodSpec{
					Containers: []v1.Container{
						{
							Name: "test-container", Image: "test-image",
						},
					},
					Volumes: []v1.Volume{
						{
							Name: "empty",
							VolumeSource: v1.VolumeSource{
								EmptyDir: &v1.EmptyDirVolumeSource{},
							},
						},
					},
				},
			})

Error when using the Calculate

Describe the bug
we generate the deployment for the first time and then apply the annotation with

...
err := objectMatcher.DefaultAnnotator.SetLastAppliedAnnotation(deployment)
if err != nil {
    return err
}
return r.createResource(owner, deployment, reqLogger)
...

when using the calculator we see this error

Failed to generate strategic merge patch: map: map[apiVersion:mattermost.com/v1alpha1 blockOwnerDeletion:true controller:true kind:ClusterInstallation name:foo] does not contain declared merge key: uid"

am i doing something wrong?

thanks!

k8s object fields with false value are removed

Describe the bug
Inside function PatchMaker.Calculate, right before the three way patch calculation logic, DeleteNullInJson(modified) is called. The function removes not only nil fields but boolean fields with value false (code path). It causes a problem that we are unable to set a field, that has true as default value, to false. For example, in gloo edge service, this field has true as default but we want to set it as false.

Also wonder why we are removing all zero valued fields before 3 way diff. It causes problems when service have a different default value than zero value in golang.

Support for Node v1 core

Feature request
It would be nice to be able to compare nodes.

Describe the solution you'd like to see
Further development effort towards supporting the Node API object.

Additional context
Great library 👍

DefaultPatchMaker patch deployment result error

Describe the bug
A clear and concise description of what the bug is.

Steps to reproduce the issue:
Please describe the steps to reproduce the issue.
1、The following test code:

package test

import (
	"testing"

	"github.com/banzaicloud/k8s-objectmatcher/patch"
	"github.com/stretchr/testify/assert"
	"github.com/xdf/rocketmq-operator/pkg/k8sutil"
	appsv1 "k8s.io/api/apps/v1"
	"k8s.io/apimachinery/pkg/util/json"
)

var (
	 currentDepJson = `
{
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {
        "annotations": {
            "deployment.kubernetes.io/revision": "1",
            "prometheus.io/port": "5557",
            "prometheus.io/scrape": "true"
        },
        "creationTimestamp": "2021-06-11T06:28:55Z",
        "generation": 1,
        "labels": {
            "app": "exporter",
            "exporterName": "zz-480",
            "mq_cr": "zz-480"
        },
        "managedFields": [
            {
                "apiVersion": "apps/v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            ".": {},
                            "f:prometheus.io/port": {},
                            "f:prometheus.io/scrape": {}
                        },
                        "f:labels": {
                            ".": {},
                            "f:app": {},
                            "f:exporterName": {},
                            "f:mq_cr": {}
                        },
                        "f:ownerReferences": {
                            ".": {},
                            "k:{\"uid\":\"16abf70c-f889-448c-8873-b48880cd4a35\"}": {
                                ".": {},
                                "f:apiVersion": {},
                                "f:blockOwnerDeletion": {},
                                "f:controller": {},
                                "f:kind": {},
                                "f:name": {},
                                "f:uid": {}
                            }
                        }
                    },
                    "f:spec": {
                        "f:progressDeadlineSeconds": {},
                        "f:replicas": {},
                        "f:revisionHistoryLimit": {},
                        "f:selector": {
                            "f:matchLabels": {
                                ".": {},
                                "f:app": {},
                                "f:exporterName": {}
                            }
                        },
                        "f:strategy": {
                            "f:rollingUpdate": {
                                ".": {},
                                "f:maxSurge": {},
                                "f:maxUnavailable": {}
                            },
                            "f:type": {}
                        },
                        "f:template": {
                            "f:metadata": {
                                "f:annotations": {
                                    ".": {},
                                    "f:prometheus.io/port": {},
                                    "f:prometheus.io/scrape": {}
                                },
                                "f:labels": {
                                    ".": {},
                                    "f:app": {},
                                    "f:exporterName": {},
                                    "f:mq_cr": {}
                                }
                            },
                            "f:spec": {
                                "f:containers": {
                                    "k:{\"name\":\"mq-exporter\"}": {
                                        ".": {},
                                        "f:args": {},
                                        "f:image": {},
                                        "f:imagePullPolicy": {},
                                        "f:livenessProbe": {
                                            ".": {},
                                            "f:failureThreshold": {},
                                            "f:initialDelaySeconds": {},
                                            "f:periodSeconds": {},
                                            "f:successThreshold": {},
                                            "f:tcpSocket": {
                                                ".": {},
                                                "f:port": {}
                                            },
                                            "f:timeoutSeconds": {}
                                        },
                                        "f:name": {},
                                        "f:ports": {
                                            ".": {},
                                            "k:{\"containerPort\":5557,\"protocol\":\"TCP\"}": {
                                                ".": {},
                                                "f:containerPort": {},
                                                "f:name": {},
                                                "f:protocol": {}
                                            }
                                        },
                                        "f:readinessProbe": {
                                            ".": {},
                                            "f:failureThreshold": {},
                                            "f:initialDelaySeconds": {},
                                            "f:periodSeconds": {},
                                            "f:successThreshold": {},
                                            "f:tcpSocket": {
                                                ".": {},
                                                "f:port": {}
                                            },
                                            "f:timeoutSeconds": {}
                                        },
                                        "f:resources": {
                                            ".": {},
                                            "f:limits": {
                                                ".": {},
                                                "f:cpu": {},
                                                "f:memory": {}
                                            },
                                            "f:requests": {
                                                ".": {},
                                                "f:cpu": {},
                                                "f:memory": {}
                                            }
                                        },
                                        "f:terminationMessagePath": {},
                                        "f:terminationMessagePolicy": {},
                                        "f:volumeMounts": {
                                            ".": {},
                                            "k:{\"mountPath\":\"/home/rocketmq/rocketmq-4.8.0/bin/runbroker.sh\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {},
                                                "f:subPath": {}
                                            },
                                            "k:{\"mountPath\":\"/home/rocketmq/rocketmq-4.8.0/bin/runserver.sh\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {},
                                                "f:subPath": {}
                                            },
                                            "k:{\"mountPath\":\"/tmp/rocketmq-exporter/data/\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {}
                                            }
                                        }
                                    }
                                },
                                "f:dnsPolicy": {},
                                "f:restartPolicy": {},
                                "f:schedulerName": {},
                                "f:securityContext": {
                                    ".": {},
                                    "f:fsGroup": {}
                                },
                                "f:terminationGracePeriodSeconds": {},
                                "f:volumes": {
                                    ".": {},
                                    "k:{\"name\":\"config\"}": {
                                        ".": {},
                                        "f:configMap": {
                                            ".": {},
                                            "f:defaultMode": {},
                                            "f:name": {}
                                        },
                                        "f:name": {}
                                    },
                                    "k:{\"name\":\"mq-run-script\"}": {
                                        ".": {},
                                        "f:configMap": {
                                            ".": {},
                                            "f:defaultMode": {},
                                            "f:name": {}
                                        },
                                        "f:name": {}
                                    }
                                }
                            }
                        }
                    }
                },
                "manager": "___go_build_github_com_smaller_rocketmq_operator",
                "operation": "Update",
                "time": "2021-06-11T06:28:55Z"
            },
            {
                "apiVersion": "apps/v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            "f:deployment.kubernetes.io/revision": {}
                        }
                    },
                    "f:status": {
                        "f:availableReplicas": {},
                        "f:conditions": {
                            ".": {},
                            "k:{\"type\":\"Available\"}": {
                                ".": {},
                                "f:lastTransitionTime": {},
                                "f:lastUpdateTime": {},
                                "f:message": {},
                                "f:reason": {},
                                "f:status": {},
                                "f:type": {}
                            },
                            "k:{\"type\":\"Progressing\"}": {
                                ".": {},
                                "f:lastTransitionTime": {},
                                "f:lastUpdateTime": {},
                                "f:message": {},
                                "f:reason": {},
                                "f:status": {},
                                "f:type": {}
                            }
                        },
                        "f:observedGeneration": {},
                        "f:readyReplicas": {},
                        "f:replicas": {},
                        "f:updatedReplicas": {}
                    }
                },
                "manager": "kube-controller-manager",
                "operation": "Update",
                "time": "2021-06-11T06:29:20Z"
            }
        ],
        "name": "zz-480-exporter",
        "namespace": "rocketmq",
        "ownerReferences": [
            {
                "apiVersion": "rocketmq.apache.org/v1alpha1",
                "blockOwnerDeletion": true,
                "controller": true,
                "kind": "RocketMQCluster",
                "name": "zz-480",
                "uid": "16abf70c-f889-448c-8873-b48880cd4a35"
            }
        ],
        "resourceVersion": "227460798",
        "selfLink": "/apis/apps/v1/namespaces/rocketmq/deployments/zz-480-exporter",
        "uid": "d7d05f49-6c3e-4f46-a352-f5c3af89547f"
    },
    "spec": {
        "progressDeadlineSeconds": 600,
        "replicas": 1,
        "revisionHistoryLimit": 10,
        "selector": {
            "matchLabels": {
                "app": "exporter",
                "exporterName": "zz-480"
            }
        },
        "strategy": {
            "rollingUpdate": {
                "maxSurge": "25%",
                "maxUnavailable": "25%"
            },
            "type": "RollingUpdate"
        },
        "template": {
            "metadata": {
                "annotations": {
                    "prometheus.io/port": "5557",
                    "prometheus.io/scrape": "true"
                },
                "labels": {
                    "app": "exporter",
                    "exporterName": "zz-480",
                    "mq_cr": "zz-480"
                }
            },
            "spec": {
                "containers": [
                    {
                        "args": [
                            "--spring.config.location=/tmp/rocketmq-exporter/data/"
                        ],
                        "image": "harbor-xadd.staff.smaller.cn/library/rocketmq-exporter:v1.0.1",
                        "imagePullPolicy": "IfNotPresent",
                        "livenessProbe": {
                            "failureThreshold": 3,
                            "initialDelaySeconds": 15,
                            "periodSeconds": 20,
                            "successThreshold": 1,
                            "tcpSocket": {
                                "port": "mq-exporter"
                            },
                            "timeoutSeconds": 1
                        },
                        "name": "mq-exporter",
                        "ports": [
                            {
                                "containerPort": 5557,
                                "name": "mq-exporter",
                                "protocol": "TCP"
                            }
                        ],
                        "readinessProbe": {
                            "failureThreshold": 3,
                            "initialDelaySeconds": 15,
                            "periodSeconds": 20,
                            "successThreshold": 1,
                            "tcpSocket": {
                                "port": "mq-exporter"
                            },
                            "timeoutSeconds": 1
                        },
                        "resources": {
                            "limits": {
                                "cpu": "2",
                                "memory": "4Gi"
                            },
                            "requests": {
                                "cpu": "500m",
                                "memory": "2Gi"
                            }
                        },
                        "terminationMessagePath": "/dev/termination-log",
                        "terminationMessagePolicy": "File",
                        "volumeMounts": [
                            {
                                "mountPath": "/home/rocketmq/rocketmq-4.8.0/bin/runbroker.sh",
                                "name": "mq-run-script",
                                "subPath": "runbroker.sh"
                            },
                            {
                                "mountPath": "/home/rocketmq/rocketmq-4.8.0/bin/runserver.sh",
                                "name": "mq-run-script",
                                "subPath": "runserver.sh"
                            },
                            {
                                "mountPath": "/tmp/rocketmq-exporter/data/",
                                "name": "config"
                            }
                        ]
                    }
                ],
                "dnsPolicy": "ClusterFirst",
                "restartPolicy": "Always",
                "schedulerName": "xlss-scheduler",
                "securityContext": {
                    "fsGroup": 1000
                },
                "terminationGracePeriodSeconds": 30,
                "volumes": [
                    {
                        "configMap": {
                            "defaultMode": 493,
                            "name": "mq-run-script"
                        },
                        "name": "mq-run-script"
                    },
                    {
                        "configMap": {
                            "defaultMode": 493,
                            "name": "zz-480-exporter-config"
                        },
                        "name": "config"
                    }
                ]
            }
        }
    }
}`

	 modifiedDepJson = `
{
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {
        "annotations": {
            "prometheus.io/port": "5557",
            "prometheus.io/scrape": "true"
        },
        "creationTimestamp": "2021-06-11T06:28:55Z",
        "generation": 1,
        "labels": {
            "app": "exporter",
            "exporterName": "zz-480",
            "mq_cr": "zz-480"
        },
        "managedFields": [
            {
                "apiVersion": "apps/v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            ".": {},
                            "f:prometheus.io/port": {},
                            "f:prometheus.io/scrape": {}
                        },
                        "f:labels": {
                            ".": {},
                            "f:app": {},
                            "f:exporterName": {},
                            "f:mq_cr": {}
                        },
                        "f:ownerReferences": {
                            ".": {},
                            "k:{\"uid\":\"16abf70c-f889-448c-8873-b48880cd4a35\"}": {
                                ".": {},
                                "f:apiVersion": {},
                                "f:blockOwnerDeletion": {},
                                "f:controller": {},
                                "f:kind": {},
                                "f:name": {},
                                "f:uid": {}
                            }
                        }
                    },
                    "f:spec": {
                        "f:progressDeadlineSeconds": {},
                        "f:replicas": {},
                        "f:revisionHistoryLimit": {},
                        "f:selector": {
                            "f:matchLabels": {
                                ".": {},
                                "f:app": {},
                                "f:exporterName": {}
                            }
                        },
                        "f:strategy": {
                            "f:rollingUpdate": {
                                ".": {},
                                "f:maxSurge": {},
                                "f:maxUnavailable": {}
                            },
                            "f:type": {}
                        },
                        "f:template": {
                            "f:metadata": {
                                "f:annotations": {
                                    ".": {},
                                    "f:prometheus.io/port": {},
                                    "f:prometheus.io/scrape": {}
                                },
                                "f:labels": {
                                    ".": {},
                                    "f:app": {},
                                    "f:exporterName": {},
                                    "f:mq_cr": {}
                                }
                            },
                            "f:spec": {
                                "f:containers": {
                                    "k:{\"name\":\"mq-exporter\"}": {
                                        ".": {},
                                        "f:args": {},
                                        "f:image": {},
                                        "f:imagePullPolicy": {},
                                        "f:livenessProbe": {
                                            ".": {},
                                            "f:failureThreshold": {},
                                            "f:initialDelaySeconds": {},
                                            "f:periodSeconds": {},
                                            "f:successThreshold": {},
                                            "f:tcpSocket": {
                                                ".": {},
                                                "f:port": {}
                                            },
                                            "f:timeoutSeconds": {}
                                        },
                                        "f:name": {},
                                        "f:ports": {
                                            ".": {},
                                            "k:{\"containerPort\":5557,\"protocol\":\"TCP\"}": {
                                                ".": {},
                                                "f:containerPort": {},
                                                "f:name": {},
                                                "f:protocol": {}
                                            }
                                        },
                                        "f:readinessProbe": {
                                            ".": {},
                                            "f:failureThreshold": {},
                                            "f:initialDelaySeconds": {},
                                            "f:periodSeconds": {},
                                            "f:successThreshold": {},
                                            "f:tcpSocket": {
                                                ".": {},
                                                "f:port": {}
                                            },
                                            "f:timeoutSeconds": {}
                                        },
                                        "f:resources": {
                                            ".": {},
                                            "f:limits": {
                                                ".": {},
                                                "f:cpu": {},
                                                "f:memory": {}
                                            },
                                            "f:requests": {
                                                ".": {},
                                                "f:cpu": {},
                                                "f:memory": {}
                                            }
                                        },
                                        "f:terminationMessagePath": {},
                                        "f:terminationMessagePolicy": {},
                                        "f:volumeMounts": {
                                            ".": {},
                                            "k:{\"mountPath\":\"/home/rocketmq/rocketmq-4.8.0/bin/runbroker.sh\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {},
                                                "f:subPath": {}
                                            },
                                            "k:{\"mountPath\":\"/home/rocketmq/rocketmq-4.8.0/bin/runserver.sh\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {},
                                                "f:subPath": {}
                                            },
                                            "k:{\"mountPath\":\"/tmp/rocketmq-exporter/data/\"}": {
                                                ".": {},
                                                "f:mountPath": {},
                                                "f:name": {}
                                            }
                                        }
                                    }
                                },
                                "f:dnsPolicy": {},
                                "f:restartPolicy": {},
                                "f:schedulerName": {},
                                "f:securityContext": {
                                    ".": {},
                                    "f:fsGroup": {}
                                },
                                "f:terminationGracePeriodSeconds": {},
                                "f:volumes": {
                                    ".": {},
                                    "k:{\"name\":\"config\"}": {
                                        ".": {},
                                        "f:configMap": {
                                            ".": {},
                                            "f:defaultMode": {},
                                            "f:name": {}
                                        },
                                        "f:name": {}
                                    },
                                    "k:{\"name\":\"mq-run-script\"}": {
                                        ".": {},
                                        "f:configMap": {
                                            ".": {},
                                            "f:defaultMode": {},
                                            "f:name": {}
                                        },
                                        "f:name": {}
                                    }
                                }
                            }
                        }
                    }
                },
                "manager": "___go_build_github_com_smaller_rocketmq_operator",
                "operation": "Update",
                "time": "2021-06-11T06:28:55Z"
            },
            {
                "apiVersion": "apps/v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            "f:deployment.kubernetes.io/revision": {}
                        }
                    },
                    "f:status": {
                        "f:availableReplicas": {},
                        "f:conditions": {
                            ".": {},
                            "k:{\"type\":\"Available\"}": {
                                ".": {},
                                "f:lastTransitionTime": {},
                                "f:lastUpdateTime": {},
                                "f:message": {},
                                "f:reason": {},
                                "f:status": {},
                                "f:type": {}
                            },
                            "k:{\"type\":\"Progressing\"}": {
                                ".": {},
                                "f:lastTransitionTime": {},
                                "f:lastUpdateTime": {},
                                "f:message": {},
                                "f:reason": {},
                                "f:status": {},
                                "f:type": {}
                            }
                        },
                        "f:observedGeneration": {},
                        "f:readyReplicas": {},
                        "f:replicas": {},
                        "f:updatedReplicas": {}
                    }
                },
                "manager": "kube-controller-manager",
                "operation": "Update",
                "time": "2021-06-11T06:29:20Z"
            }
        ],
        "name": "zz-480-exporter",
        "namespace": "rocketmq",
        "ownerReferences": [
            {
                "apiVersion": "rocketmq.apache.org/v1alpha1",
                "blockOwnerDeletion": true,
                "controller": true,
                "kind": "RocketMQCluster",
                "name": "zz-480",
                "uid": "16abf70c-f889-448c-8873-b48880cd4a35"
            }
        ],
        "resourceVersion": "227460798",
        "selfLink": "/apis/apps/v1/namespaces/rocketmq/deployments/zz-480-exporter",
        "uid": "d7d05f49-6c3e-4f46-a352-f5c3af89547f"
    },
    "spec": {
        "replicas": 1,
        "selector": {
            "matchLabels": {
                "app": "exporter",
                "exporterName": "zz-480"
            }
        },
        "strategy": {
            "rollingUpdate": {
                "maxSurge": "25%",
                "maxUnavailable": "25%"
            },
            "type": "RollingUpdate"
        },
        "template": {
            "metadata": {
                "annotations": {
                    "prometheus.io/port": "5557",
                    "prometheus.io/scrape": "true"
                },
                "labels": {
                    "app": "exporter",
                    "exporterName": "zz-480",
                    "mq_cr": "zz-480"
                }
            },
            "spec": {
                "containers": [
                    {
                        "args": [
                            "--spring.config.location=/tmp/rocketmq-exporter/data/"
                        ],
                        "image": "harbor-xadd.staff.smaller.cn/library/rocketmq-exporter:v1.0.1",
                        "livenessProbe": {
                            "initialDelaySeconds": 15,
                            "periodSeconds": 20,
                            "tcpSocket": {
                                "port": "mq-exporter"
                            }
                        },
                        "name": "mq-exporter",
                        "ports": [
                            {
                                "containerPort": 5557,
                                "name": "mq-exporter",
                                "protocol": "TCP"
                            }
                        ],
                        "readinessProbe": {
                            "initialDelaySeconds": 15,
                            "periodSeconds": 20,
                            "tcpSocket": {
                                "port": "mq-exporter"
                            }
                        },
                        "resources": {
                            "limits": {
                                "cpu": "2",
                                "memory": "4Gi"
                            },
                            "requests": {
                                "cpu": "500m",
                                "memory": "2Gi"
                            }
                        },
                        "volumeMounts": [
                            {
                                "mountPath": "/tmp/rocketmq-exporter/data/",
                                "name": "config"
                            }
                        ]
                    }
                ],
                "schedulerName": "xlss-scheduler",
                "securityContext": {
                    "fsGroup": 1000
                },
                "volumes": [
                    {
                        "configMap": {
                            "defaultMode": 493,
                            "name": "zz-480-exporter-config"
                        },
                        "name": "config"
                    }
                ]
            }
        }
    }
}`
)

func TestDeploymentPatchResult(t *testing.T) {
	currentDep, modifiedDep :=  &appsv1.Deployment{}, &appsv1.Deployment{}
	err := json.Unmarshal([]byte(currentDepJson), currentDep)
	if err != nil {
		t.Fatalf(err.Error())
	}

	err = json.Unmarshal([]byte(modifiedDepJson), modifiedDep)
	if err != nil {
		t.Fatalf(err.Error())
	}

	assert.True(t, len(currentDep.Spec.Template.Spec.Containers[0].VolumeMounts) != len(modifiedDep.Spec.Template.Spec.Containers[0].VolumeMounts))
	assert.True(t, len(currentDep.Spec.Template.Spec.Volumes) != len(modifiedDep.Spec.Template.Spec.Volumes))
	patchResult, err := patch.DefaultPatchMaker.Calculate(currentDep, modifiedDep, k8sutil.PatchOptions...)
	if err != nil {
		t.Fatalf(err.Error())
	}

	assert.False(t, patchResult.IsEmpty())
}

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem like release numberm version, branch, etc.

objectmatcher tries to update status on PodDisruptionBudget

Describe the bug
using objectmatcher on a v1beta.PodDisruptionBudget causes unnecessary patches because it is trying to update the status field of PDR which is dynamic

"patch": "{"status":{"currentHealthy":0,"disruptionsAllowed":0,"expectedPods":0}}",

"current": "{"apiVersion":"policy/v1beta1","metadata":{"annotations":{"banzaicloud.com/last-applied":"{"spec":{"selector":{"matchLabels":{"app":"webapptestwgroup1"}},"maxUnavailable":1},"status":{"currentHealthy":0,"desiredHealthy":0,"expectedPods":0,"disruptionsAllowed":0},"metadata":{"name":"webapptestwgroup1","namespace":"teamtest-appgrouptest","ownerReferences":[{"name":"webapptestwgroup1","uid":"f778f2ff-4911-11ea-9c67-08002786ed12","controller":true,"apiVersion":"app.grnds.com/v1","kind":"WebApp"}]}}"},"namespace":"teamtest-appgrouptest","selfLink":"/apis/policy/v1beta1/namespaces/teamtest-appgrouptest/poddisruptionbudgets/webapptestwgroup1","resourceVersion":"15164","name":"webapptestwgroup1","generation":1,"creationTimestamp":"2020-02-06T19:26:21Z","uid":"8e265972-4916-11ea-9c67-08002786ed12","ownerReferences":[{"name":"webapptestwgroup1","uid":"f778f2ff-4911-11ea-9c67-08002786ed12","controller":true,"apiVersion":"app.grnds.com/v1","kind":"WebApp"}]},"spec":{"selector":{"matchLabels":{"app":"webapptestwgroup1"}},"maxUnavailable":1},"status":{"desiredHealthy":0,"expectedPods":1,"observedGeneration":1,"disruptionsAllowed":1,"currentHealthy":1},"kind":"PodDisruptionBudget"}",

"modified": "{"metadata":{"ownerReferences":[{"controller":true,"apiVersion":"app.grnds.com/v1","kind":"WebApp","name":"webapptestwgroup1","uid":"f778f2ff-4911-11ea-9c67-08002786ed12"}],"name":"webapptestwgroup1","namespace":"teamtest-appgrouptest"},"spec":{"selector":{"matchLabels":{"app":"webapptestwgroup1"}},"maxUnavailable":1},"status":{"disruptionsAllowed":0,"currentHealthy":0,"desiredHealthy":0,"expectedPods":0}}",

"original": "{"spec":{"selector":{"matchLabels":{"app":"webapptestwgroup1"}},"maxUnavailable":1},"status":{"currentHealthy":0,"desiredHealthy":0,"expectedPods":0,"disruptionsAllowed":0},"metadata":{"name":"webapptestwgroup1","namespace":"teamtest-appgrouptest","ownerReferences":[{"name":"webapptestwgroup1","uid":"f778f2ff-4911-11ea-9c67-08002786ed12","controller":true,"apiVersion":"app.grnds.com/v1","kind":"WebApp"}]}}"}

Steps to reproduce the issue:
create a PDB and use objectmatch to update it.

Expected behavior

PDB status should not be updated as it is dynamic based off of pods

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem like release numberm version, branch, etc.

Three-way merge not ignoring fields changed in current but shared between modified and original

Describe the bug

Let's use an example of a Deployment that has a HorizontalPodAutoscaler acting on it. When an operator creates the deployment, it sets some number of initial replicas, in this example, spec.replicas = 1. The HPA then adds a replica, to make it spec.replicas = 2. I would expect this library to ignore this field from the patch, because modified == original and therefore, whatever the value of current, it is assumed to be changed externally.

Therefore:

original[spec.replicas] = 1 (generated by an operator)
current[spec.replicas] = 2 (from HPA)
modified[spec.replicas] = 1 (generated identically by same operator later)

Steps to reproduce the issue:

Here is a simple reproducer:

package main

import (
	"github.com/banzaicloud/k8s-objectmatcher/patch"
	v1 "k8s.io/api/apps/v1"
	"log"
)

func main() {
	origReplicas := int32(1)
	currReplicas := int32(2)

	modified := &v1.Deployment{
		Spec: v1.DeploymentSpec{
			Replicas: &origReplicas,
		},
	}

	current := modified.DeepCopy()
	_ = patch.DefaultAnnotator.SetLastAppliedAnnotation(current)

	current.Spec.Replicas = &currReplicas

	patchResult, _ := patch.DefaultPatchMaker.Calculate(current, modified, patch.IgnoreStatusFields())
	if !patchResult.IsEmpty() {
		log.Printf("DIFF: " + string(patchResult.Patch))
	}
}

This will output:

DIFF: {"spec":{"replicas":1}}

Expected behavior

I expected spec.replicas to not appear in the diff, because it is changed in current but original == modified and so should be assumed to be changed externally.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.