mirror of https://gerrit.hackerspace.pl/hscloud
kartongips: implement proper diffing of aggregated ClusterRoles
For a while now we've had spurious diffs against Ceph on k0 because of a ClusterRole with an aggregationRule. The way these behave is that the config object has an empty rule list, and instead populates an aggregationRule which combines other existing ClusterRoles into that ClusterRole. The control plane then populates the rule field when the object is read/acted on, which caused us to always see a diff between the configuration of that ClusterRole. This hacks together a hardcoded fix for this particular behaviour. Porting kubecfg over to SSA would probably also fix this - but that's too much work for now. Change-Id: I357c1417d4023691e5809f1af23f58f364353388changes/86/1086/1
parent
eed9afe210
commit
72d7574536
|
@ -91,6 +91,7 @@ func (c DiffCmd) Run(ctx context.Context, apiObjects []*unstructured.Unstructure
|
|||
liveObjObject := liveObj.Object
|
||||
if c.DiffStrategy == "subset" {
|
||||
liveObjObject = removeMapFields(obj.Object, liveObjObject)
|
||||
liveObjObject = removeClusterRoleAggregatedRules(liveObjObject)
|
||||
}
|
||||
|
||||
liveObjText, _ := json.MarshalIndent(liveObjObject, "", " ")
|
||||
|
@ -211,6 +212,38 @@ func removeMapFields(config, live map[string]interface{}) map[string]interface{}
|
|||
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.
|
||||
|
|
Loading…
Reference in New Issue