func computeReconciledRole()

in auth/rbac/reconciliation/reconcile_role.go [178:241]


func computeReconciledRole(existing, expected RuleOwner, removeExtraPermissions bool) (*ReconcileClusterRoleResult, error) {
	result := &ReconcileClusterRoleResult{Operation: ReconcileNone}

	result.Protected = (existing.GetAnnotations()[rbacv1.AutoUpdateAnnotationKey] == "false")

	// Start with a copy of the existing object
	result.Role = existing.DeepCopyRuleOwner()

	// Merge expected annotations and labels
	result.Role.SetAnnotations(merge(expected.GetAnnotations(), result.Role.GetAnnotations()))
	if !reflect.DeepEqual(result.Role.GetAnnotations(), existing.GetAnnotations()) {
		result.Operation = ReconcileUpdate
	}
	result.Role.SetLabels(merge(expected.GetLabels(), result.Role.GetLabels()))
	if !reflect.DeepEqual(result.Role.GetLabels(), existing.GetLabels()) {
		result.Operation = ReconcileUpdate
	}

	// Compute extra and missing rules
	// Don't compute extra permissions if expected and existing roles are both aggregated
	if expected.GetAggregationRule() == nil || existing.GetAggregationRule() == nil {
		_, result.ExtraRules = validation.Covers(expected.GetRules(), existing.GetRules())
	}
	_, result.MissingRules = validation.Covers(existing.GetRules(), expected.GetRules())

	switch {
	case !removeExtraPermissions && len(result.MissingRules) > 0:
		// add missing rules in the union case
		result.Role.SetRules(append(result.Role.GetRules(), result.MissingRules...))
		result.Operation = ReconcileUpdate

	case removeExtraPermissions && (len(result.MissingRules) > 0 || len(result.ExtraRules) > 0):
		// stomp to expected rules in the non-union case
		result.Role.SetRules(expected.GetRules())
		result.Operation = ReconcileUpdate
	}

	// Compute extra and missing rules
	_, result.ExtraAggregationRuleSelectors = aggregationRuleCovers(expected.GetAggregationRule(), existing.GetAggregationRule())
	_, result.MissingAggregationRuleSelectors = aggregationRuleCovers(existing.GetAggregationRule(), expected.GetAggregationRule())

	switch {
	case expected.GetAggregationRule() == nil && existing.GetAggregationRule() != nil:
		// we didn't expect this to be an aggregated role at all, remove the existing aggregation
		result.Role.SetAggregationRule(nil)
		result.Operation = ReconcileUpdate

	case !removeExtraPermissions && len(result.MissingAggregationRuleSelectors) > 0:
		// add missing rules in the union case
		aggregationRule := result.Role.GetAggregationRule()
		if aggregationRule == nil {
			aggregationRule = &rbacv1.AggregationRule{}
		}
		aggregationRule.ClusterRoleSelectors = append(aggregationRule.ClusterRoleSelectors, result.MissingAggregationRuleSelectors...)
		result.Role.SetAggregationRule(aggregationRule)
		result.Operation = ReconcileUpdate

	case removeExtraPermissions && (len(result.MissingAggregationRuleSelectors) > 0 || len(result.ExtraAggregationRuleSelectors) > 0):
		result.Role.SetAggregationRule(expected.GetAggregationRule())
		result.Operation = ReconcileUpdate
	}

	return result, nil
}