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 +}