Merge "kartongips: implement proper diffing of aggregated ClusterRoles"
diff --git a/cluster/tools/kartongips/pkg/kubecfg/diff.go b/cluster/tools/kartongips/pkg/kubecfg/diff.go
index f1136be..5d32b9e 100644
--- a/cluster/tools/kartongips/pkg/kubecfg/diff.go
+++ b/cluster/tools/kartongips/pkg/kubecfg/diff.go
@@ -91,6 +91,7 @@
liveObjObject := liveObj.Object
if c.DiffStrategy == "subset" {
liveObjObject = removeMapFields(obj.Object, liveObjObject)
+ liveObjObject = removeClusterRoleAggregatedRules(liveObjObject)
}
liveObjText, _ := json.MarshalIndent(liveObjObject, "", " ")
@@ -211,6 +212,38 @@
return result
}
+// removeClusterRoleAggregatedRules clears the rules field from live
+// ClusterRole objects which have an aggregationRule. This allows us to diff a
+// config object (which doesn't have these rules materialized) against a live
+// obejct (which does have these rules materialized) without spurious diffs.
+//
+// See the Aggregated ClusterRole section of the Kubernetes RBAC docuementation
+// for more information:
+//
+// https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles
+func removeClusterRoleAggregatedRules(live map[string]interface{}) map[string]interface{} {
+ if version, ok := live["apiVersion"].(string); !ok || version != "rbac.authorization.k8s.io/v1" {
+ return live
+ }
+
+ if kind, ok := live["kind"].(string); !ok || kind != "ClusterRole" {
+ return live
+ }
+
+ if _, ok := live["aggregationRule"].(map[string]interface{}); !ok {
+ return live
+ }
+
+ // Make copy of map.
+ res := make(map[string]interface{})
+ for k, v := range live {
+ res[k] = v
+ }
+ // Clear rules field.
+ res["rules"] = []interface{}{}
+ return res
+}
+
func removeListFields(config, live []interface{}) []interface{} {
// If live is longer than config, then the extra elements at the end of the
// list will be returned as is so they appear in the diff.