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 e8f7555ea6f10f3c81b68a42fee3c617ffa5102b
Author: Antonin Stefanutti <anto...@stefanutti.fr>
AuthorDate: Mon Feb 24 18:54:08 2020 +0100

    feat: Auto-configure image builder role binding for OpenShift internal 
registry
---
 pkg/controller/build/initialize_pod.go | 23 ------------
 pkg/controller/build/schedule_pod.go   |  4 +-
 pkg/install/builder.go                 |  8 ++--
 pkg/platform/defaults.go               | 68 ++++++++++++++++++++++++++++++++--
 4 files changed, 71 insertions(+), 32 deletions(-)

diff --git a/pkg/controller/build/initialize_pod.go 
b/pkg/controller/build/initialize_pod.go
index 3eb84ef..948a47e 100644
--- a/pkg/controller/build/initialize_pod.go
+++ b/pkg/controller/build/initialize_pod.go
@@ -29,7 +29,6 @@ import (
        k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 
        v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-       "github.com/apache/camel-k/pkg/install"
 )
 
 // NewInitializePodAction creates a new initialize action
@@ -53,12 +52,6 @@ func (action *initializePodAction) CanHandle(build 
*v1.Build) bool {
 
 // Handle handles the builds
 func (action *initializePodAction) Handle(ctx context.Context, build 
*v1.Build) (*v1.Build, error) {
-       // Ensure service account is present
-       // TODO: maybe this should be done by the platform trait ??
-       if err := action.ensureServiceAccount(ctx, build); err != nil {
-               return nil, errors.Wrap(err, "cannot ensure service account is 
present")
-       }
-
        if err := deleteBuilderPod(ctx, action.client, build); err != nil {
                return nil, errors.Wrap(err, "cannot delete build pod")
        }
@@ -74,22 +67,6 @@ func (action *initializePodAction) Handle(ctx 
context.Context, build *v1.Build)
        return build, nil
 }
 
-func (action *initializePodAction) ensureServiceAccount(ctx context.Context, 
build *v1.Build) error {
-       sa := corev1.ServiceAccount{}
-       saKey := k8sclient.ObjectKey{
-               Name:      "camel-k-builder",
-               Namespace: build.Namespace,
-       }
-
-       err := action.client.Get(ctx, saKey, &sa)
-       if err != nil && k8serrors.IsNotFound(err) {
-               // Create a proper service account
-               return install.BuilderServiceAccountRoles(ctx, action.client, 
build.Namespace)
-       }
-
-       return err
-}
-
 func deleteBuilderPod(ctx context.Context, client k8sclient.Writer, build 
*v1.Build) error {
        pod := corev1.Pod{
                TypeMeta: metav1.TypeMeta{
diff --git a/pkg/controller/build/schedule_pod.go 
b/pkg/controller/build/schedule_pod.go
index f26f92e..d4b7c45 100644
--- a/pkg/controller/build/schedule_pod.go
+++ b/pkg/controller/build/schedule_pod.go
@@ -21,7 +21,6 @@ import (
        "context"
        "sync"
 
-       "github.com/apache/camel-k/pkg/util/kubernetes"
        "github.com/pkg/errors"
 
        corev1 "k8s.io/api/core/v1"
@@ -33,6 +32,7 @@ import (
        v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
        "github.com/apache/camel-k/pkg/platform"
        "github.com/apache/camel-k/pkg/util/defaults"
+       "github.com/apache/camel-k/pkg/util/kubernetes"
 )
 
 // NewSchedulePodAction creates a new schedule action
@@ -125,7 +125,7 @@ func (action *schedulePodAction) newBuildPod(ctx 
context.Context, build *v1.Buil
                        },
                },
                Spec: corev1.PodSpec{
-                       ServiceAccountName: "camel-k-builder",
+                       ServiceAccountName: platform.BuilderServiceAccount,
                        RestartPolicy:      corev1.RestartPolicyNever,
                },
        }
diff --git a/pkg/install/builder.go b/pkg/install/builder.go
index d9f0d17..9a43999 100644
--- a/pkg/install/builder.go
+++ b/pkg/install/builder.go
@@ -26,12 +26,12 @@ import (
 
 // BuilderServiceAccountRoles installs the builder service account and related 
roles in the given namespace
 func BuilderServiceAccountRoles(ctx context.Context, c client.Client, 
namespace string) error {
-       isOpenshift, err := openshift.IsOpenShift(c)
+       isOpenShift, err := openshift.IsOpenShift(c)
        if err != nil {
                return err
        }
-       if isOpenshift {
-               if err := installBuilderServiceAccountRolesOpenshift(ctx, c, 
namespace); err != nil {
+       if isOpenShift {
+               if err := installBuilderServiceAccountRolesOpenShift(ctx, c, 
namespace); err != nil {
                        return err
                }
        } else {
@@ -42,7 +42,7 @@ func BuilderServiceAccountRoles(ctx context.Context, c 
client.Client, namespace
        return nil
 }
 
-func installBuilderServiceAccountRolesOpenshift(ctx context.Context, c 
client.Client, namespace string) error {
+func installBuilderServiceAccountRolesOpenShift(ctx context.Context, c 
client.Client, namespace string) error {
        return ResourcesOrCollect(ctx, c, namespace, nil, true, 
IdentityResourceCustomizer,
                "builder-service-account.yaml",
                "builder-role-openshift.yaml",
diff --git a/pkg/platform/defaults.go b/pkg/platform/defaults.go
index e04d3ef..9afd250 100644
--- a/pkg/platform/defaults.go
+++ b/pkg/platform/defaults.go
@@ -23,21 +23,29 @@ import (
        "strings"
        "time"
 
+       "github.com/pkg/errors"
+
        corev1 "k8s.io/api/core/v1"
+       rbacv1 "k8s.io/api/rbac/v1"
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/types"
 
+       k8sclient "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/install"
        "github.com/apache/camel-k/pkg/util/defaults"
        "github.com/apache/camel-k/pkg/util/log"
        "github.com/apache/camel-k/pkg/util/maven"
        "github.com/apache/camel-k/pkg/util/openshift"
 )
 
+const BuilderServiceAccount = "camel-k-builder"
+
 // ConfigureDefaults fills with default values all missing details about the 
integration platform.
-// Defaults are set in the status->appliedConfiguration fields, not in the 
spec.
+// Defaults are set in the status fields, not in the spec.
 func ConfigureDefaults(ctx context.Context, c client.Client, p 
*v1.IntegrationPlatform, verbose bool) error {
        // Reset the state to initial values
        p.ResyncStatusFullConfig()
@@ -84,6 +92,12 @@ func ConfigureDefaults(ctx context.Context, c client.Client, 
p *v1.IntegrationPl
                return err
        }
 
+       if p.Status.Build.BuildStrategy == 
v1.IntegrationPlatformBuildStrategyPod {
+               if err := createBuilderServiceAccount(ctx, c, p); err != nil {
+                       return errors.Wrap(err, "cannot ensure service account 
is present")
+               }
+       }
+
        // Default to using OpenShift internal container images registry when 
using a strategy other than S2I
        if p.Status.Cluster == v1.IntegrationPlatformClusterOpenShift &&
                p.Status.Build.PublishStrategy != 
v1.IntegrationPlatformBuildPublishStrategyS2I &&
@@ -99,8 +113,14 @@ func ConfigureDefaults(ctx context.Context, c 
client.Client, p *v1.IntegrationPl
 
                // Default to using the registry secret that's configured for 
the builder service account
                if p.Status.Build.Registry.Secret == "" {
+                       // Bind the required role to push images to the registry
+                       err := createBuilderRegistryRoleBinding(ctx, c, p)
+                       if err != nil {
+                               return err
+                       }
+
                        sa := corev1.ServiceAccount{}
-                       err := c.Get(ctx, types.NamespacedName{Namespace: 
p.Namespace, Name: "camel-k-builder"}, &sa)
+                       err = c.Get(ctx, types.NamespacedName{Namespace: 
p.Namespace, Name: BuilderServiceAccount}, &sa)
                        if err != nil {
                                return err
                        }
@@ -240,7 +260,7 @@ func createDefaultMavenSettingsConfigMap(ctx 
context.Context, client client.Clie
 func createServiceCaBundleConfigMap(ctx context.Context, client client.Client, 
p *v1.IntegrationPlatform) (*corev1.ConfigMap, error) {
        cm := &corev1.ConfigMap{
                ObjectMeta: metav1.ObjectMeta{
-                       Name:      "camel-k-builder-ca",
+                       Name:      BuilderServiceAccount + "-ca",
                        Namespace: p.Namespace,
                        Annotations: map[string]string{
                                "service.beta.openshift.io/inject-cabundle": 
"true",
@@ -255,3 +275,45 @@ func createServiceCaBundleConfigMap(ctx context.Context, 
client client.Client, p
 
        return cm, nil
 }
+
+func createBuilderServiceAccount(ctx context.Context, client client.Client, p 
*v1.IntegrationPlatform) error {
+       sa := corev1.ServiceAccount{}
+       key := k8sclient.ObjectKey{
+               Name:      BuilderServiceAccount,
+               Namespace: p.Namespace,
+       }
+
+       err := client.Get(ctx, key, &sa)
+       if err != nil && k8serrors.IsNotFound(err) {
+               return install.BuilderServiceAccountRoles(ctx, client, 
p.Namespace)
+       }
+
+       return err
+}
+
+func createBuilderRegistryRoleBinding(ctx context.Context, client 
client.Client, p *v1.IntegrationPlatform) error {
+       rb := &rbacv1.RoleBinding{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      BuilderServiceAccount + "-registry",
+                       Namespace: p.Namespace,
+               },
+               Subjects: []rbacv1.Subject{
+                       {
+                               Kind: "ServiceAccount",
+                               Name: BuilderServiceAccount,
+                       },
+               },
+               RoleRef: rbacv1.RoleRef{
+                       Kind:     "ClusterRole",
+                       APIGroup: "rbac.authorization.k8s.io",
+                       Name:     "system:image-builder",
+               },
+       }
+
+       err := client.Create(ctx, rb)
+       if err != nil && !k8serrors.IsAlreadyExists(err) {
+               return err
+       }
+
+       return nil
+}

Reply via email to