This is an automated email from the ASF dual-hosted git repository. astefanutti pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 55afb23dad687f63c88a4430772e5889e0592cf1 Author: Antonin Stefanutti <anto...@stefanutti.fr> AuthorDate: Fri Feb 12 11:45:24 2021 +0100 chore(rbac): Manage ClusterRoleBinding resources during operator install --- pkg/install/cluster.go | 23 ---------------- pkg/install/operator.go | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 23 deletions(-) diff --git a/pkg/install/cluster.go b/pkg/install/cluster.go index da05291..401ff8f 100644 --- a/pkg/install/cluster.go +++ b/pkg/install/cluster.go @@ -159,16 +159,6 @@ func SetupClusterWideResourcesOrCollect(ctx context.Context, clientProvider clie return err } } - ok, err = isClusterRoleBindingInstalled(ctx, c, "camel-k-operator-openshift") - if err != nil { - return err - } - if !ok || collection != nil { - err := installResource(ctx, c, collection, "/rbac/operator-cluster-role-binding-openshift.yaml") - if err != nil { - return err - } - } } return nil @@ -294,19 +284,6 @@ func isClusterRoleInstalled(ctx context.Context, c client.Client, name string) ( return isResourceInstalled(ctx, c, &clusterRole) } -func isClusterRoleBindingInstalled(ctx context.Context, c client.Client, name string) (bool, error) { - clusterRoleBinding := rbacv1.ClusterRoleBinding{ - TypeMeta: metav1.TypeMeta{ - Kind: "ClusterRoleBinding", - APIVersion: "rbac.authorization.k8s.io/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - } - return isResourceInstalled(ctx, c, &clusterRoleBinding) -} - func isResourceInstalled(ctx context.Context, c client.Client, object runtime.Object) (bool, error) { key, err := k8sclient.ObjectKeyFromObject(object) if err != nil { diff --git a/pkg/install/operator.go b/pkg/install/operator.go index ef95cee..1187332 100644 --- a/pkg/install/operator.go +++ b/pkg/install/operator.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/types" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -33,6 +34,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" + ctrl "sigs.k8s.io/controller-runtime/pkg/client" + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/client" "github.com/apache/camel-k/pkg/resources" @@ -40,6 +43,7 @@ import ( "github.com/apache/camel-k/pkg/util/knative" "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/apache/camel-k/pkg/util/minikube" + "github.com/apache/camel-k/pkg/util/patch" ) // OperatorConfiguration -- @@ -159,6 +163,13 @@ func OperatorOrCollect(ctx context.Context, c client.Client, cfg OperatorConfigu if err := installOpenShiftRoles(ctx, c, cfg.Namespace, customizer, collection, force); err != nil { return err } + if err := installOpenShiftClusterRoleBinding(ctx, c, collection, cfg.Namespace); err != nil { + if k8serrors.IsForbidden(err) { + fmt.Println("Warning: the operator will not be able to manage ConsoleCLIDownload resources. Try installing the operator as cluster-admin.") + } else { + return err + } + } } // Deploy the operator @@ -227,6 +238,66 @@ func OperatorOrCollect(ctx context.Context, c client.Client, cfg OperatorConfigu return nil } +func installOpenShiftClusterRoleBinding(ctx context.Context, c client.Client, collection *kubernetes.Collection, namespace string) error { + var target *rbacv1.ClusterRoleBinding + existing, err := c.RbacV1().ClusterRoleBindings().Get(ctx, "camel-k-operator-openshift", metav1.GetOptions{}) + if k8serrors.IsNotFound(err) { + existing = nil + obj, err := kubernetes.LoadResourceFromYaml(c.GetScheme(), resources.ResourceAsString("/rbac/operator-cluster-role-binding-openshift.yaml")) + if err != nil { + return err + } + target = obj.(*rbacv1.ClusterRoleBinding) + } else if err != nil { + return err + } else { + target = existing.DeepCopy() + } + + bound := false + for i, subject := range target.Subjects { + if subject.Name == "camel-k-operator" { + if subject.Namespace == namespace { + bound = true + break + } else if subject.Namespace == "" { + target.Subjects[i].Namespace = namespace + bound = true + break + } + } + } + + if !bound { + target.Subjects = append(target.Subjects, rbacv1.Subject{ + Kind: "ServiceAccount", + Namespace: namespace, + Name: "camel-k-operator", + }) + } + + if collection != nil { + collection.Add(target) + return nil + } + + if existing == nil { + return c.Create(ctx, target) + } else { + // 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.PositiveMergePatch(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)) + } +} + func installOpenShiftRoles(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, collection *kubernetes.Collection, force bool) error { return ResourcesOrCollect(ctx, c, namespace, collection, force, customizer, "/rbac/operator-role-openshift.yaml",