func installClusterRoleBinding()

in pkg/install/operator.go [390:464]


func installClusterRoleBinding(ctx context.Context, c client.Client, collection *kubernetes.Collection, namespace string, name string, path string) error {
	var target *rbacv1.ClusterRoleBinding
	existing, err := c.RbacV1().ClusterRoleBindings().Get(ctx, name, metav1.GetOptions{})
	switch {
	case k8serrors.IsNotFound(err):
		content, err := resources.ResourceAsString(path)
		if err != nil {
			return err
		}

		existing = nil
		if content == "" {
			return fmt.Errorf("resource file %v not found", path)
		}

		obj, err := kubernetes.LoadResourceFromYaml(c.GetScheme(), content)
		if err != nil {
			return err
		}
		var ok bool
		if target, ok = obj.(*rbacv1.ClusterRoleBinding); !ok {
			return fmt.Errorf("file %v does not contain a ClusterRoleBinding resource", path)
		}
	case err != nil:
		return err
	default:
		target = existing.DeepCopy()
	}

	bound := false
	for i, subject := range target.Subjects {
		if subject.Name == serviceAccountName {
			if subject.Namespace == namespace {
				bound = true

				break
			} else if subject.Namespace == "" || subject.Namespace == "placeholder" {
				target.Subjects[i].Namespace = namespace
				bound = true

				break
			}
		}
	}

	if !bound {
		target.Subjects = append(target.Subjects, rbacv1.Subject{
			Kind:      "ServiceAccount",
			Namespace: namespace,
			Name:      serviceAccountName,
		})
	}

	if collection != nil {
		collection.Add(target)
		return nil
	}

	if existing == nil {
		return c.Create(ctx, target)
	}

	// The ClusterRoleBinding.Subjects field does not have a patchStrategy key in its field tag,
	// so a strategic merge patch would use the default patch strategy, which is replace.
	// Let's compute a simple JSON merge patch from the existing resource, and patch it.
	p, err := patch.MergePatch(existing, target)
	if err != nil {
		return err
	} else if len(p) == 0 {
		// Avoid triggering a patch request for nothing
		return nil
	}

	return c.Patch(ctx, existing, ctrl.RawPatch(types.MergePatchType, p))
}