k8sdiff

package module
v0.0.0-...-80ae4d5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 14, 2020 License: MIT Imports: 4 Imported by: 1

README

K8S Diff Utilities

This project contains Kubernetes-oriented Golang diff utilities. The only function exposed so far is CompareIgnoreDesiredObjectEmpties(), which performs a recursive diff of two structs, but in a way that is customized to a particular situation within a Kubernetes operator.

The situation is this: Usually, Kubernetes controllers generate a "desired" state for some Kubernetes object (deployment, service, ingress, etc), and then periodically ensure that the "live" state of that object is updated to the desired state. The operator could simply call Update() via the Kubernetes API, but if the operator is dealing with a large number of objects, the number of API calls quickly gets out of control. So what is needed is the ability to diff the live object with the desired object, and only call Update() when they are different. The issue, however, is that the live object (fetched via the Kubernetes API) is populated with a ton of (potentially deeply nested) default values, filled in dynamically by Kubernetes. So a simple recursive diff between the live and desired objects will always return diffs (unless the operator code is somehow able to fill in every default value in the desired object, which is a lot of work).

The solution is to compare the live and desired objects using a customized recursive diff function: one that ignores "empty" values in the desired object. For our purposes here, "empty" means a Go "zero value" (0, false, "", nil), or an empty slice or map.

I couldn't find any existing utilities that accomplished the above. There were a few options for implementation approaches... One option was to take one of the open source DeepCompare utilities, fork it, and hack it up to ignore empty values in the target object. This seemed pretty messy and hard to maintain, so the option I ended up going with was this:

  • Run the diff through github.com/kylelemons/godebug/pretty, which itself produces predictable diff output.
  • Parse through the output of the above tool, filtering out the diffs we don't care about: those caused by empty values in the target object.

Contributions

Pull requests welcome. Also, any feedback on a better way to accomplish the above goals would be much appreciated!

Installing

go get github.com/dansimone/k8sdiff

Using

import (
        "github.com/dansimone/k8sdiff"
)

Fetch the live Kubernetes object in question, for example:

liveDeployment := deploymentsLister.Deployments(namespace).Get(deploymentName)

Construct your desired object:

desiredDeployment := createMyDeploymentObject()

Run the comparison:

diffs := k8sdiff.CompareIgnoreDesiredObjectEmpties(liveDeployment, desiredDeployment)
if diffs != "" {
	fmt.Println("Diffs: " + diffs)
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CompareIgnoreDesiredObjectEmpties

func CompareIgnoreDesiredObjectEmpties(liveObject interface{}, desiredObject interface{}) string

Diffs two Golang objects recursively, but treats any elements whose values are empty in the 'desiredObject' as "no diff". This is useful in a particular situation of comparing Kubernetes objects:

  1. The 'desiredObject' is constructed via code. It will almost certainly have many, many (nested) empty values.
  2. It is compared against a 'liveObject', which has been retrieved live from the Kubernetes API, and has many of these empty values populated with (k8s-generated) default values.

In this situation, to determine whether our desiredObject is truly different than the liveObject, we ignore processing of elements whose values are empty in the desiredObject.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL