You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2019/11/28 07:40:52 UTC
[camel-k] 05/07: Fix #613: Add pull-secret trait
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 a7fa8de9605d0b7d76c61f520d8b6324442b353c
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Tue Nov 26 13:26:04 2019 +0100
Fix #613: Add pull-secret trait
---
docs/modules/ROOT/nav.adoc | 1 +
docs/modules/ROOT/pages/traits/pull-secret.adoc | 46 +++++++++++++
docs/modules/ROOT/pages/traits/traits.adoc | 1 +
pkg/trait/pull_secret.go | 88 +++++++++++++++++++++++++
pkg/trait/pull_secret_test.go | 81 +++++++++++++++++++++++
pkg/trait/trait_catalog.go | 6 ++
pkg/util/kubernetes/collection.go | 10 +++
7 files changed, 233 insertions(+)
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index 732df79..468165c 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -35,6 +35,7 @@
** xref:traits/owner.adoc[Owner]
** xref:traits/probes.adoc[Probes]
** xref:traits/prometheus.adoc[Prometheus]
+** xref:traits/pull-secret.adoc[Pull Secret]
** xref:traits/quarkus.adoc[Quarkus]
** xref:traits/rest-dsl.adoc[Rest Dsl]
** xref:traits/route.adoc[Route]
diff --git a/docs/modules/ROOT/pages/traits/pull-secret.adoc b/docs/modules/ROOT/pages/traits/pull-secret.adoc
new file mode 100755
index 0000000..bfafe02
--- /dev/null
+++ b/docs/modules/ROOT/pages/traits/pull-secret.adoc
@@ -0,0 +1,46 @@
+= Pull Secret Trait
+
+// Start of autogenerated code - DO NOT EDIT! (description)
+The Pull Secret trait sets a pull secret on the pod,
+to allow Kubernetes to retrieve the container image from an external registry.
+
+The pull secret can be specified manually or, in case you've configured authentication for an external container registry
+on the `IntegrationPlatform`, the same secret is used to pull images.
+
+It's enabled by default whenever you configure authentication for an external container registry,
+so it assumes that external registries are private.
+
+If your registry does not need authentication for pulling images, you can disable this trait.
+
+
+This trait is available in the following profiles: **Kubernetes, Knative, OpenShift**.
+
+// End of autogenerated code - DO NOT EDIT! (description)
+// Start of autogenerated code - DO NOT EDIT! (configuration)
+== Configuration
+
+Trait properties can be specified when running any integration with the CLI:
+```
+kamel run --trait pull-secret.[key]=[value] integration.groovy
+```
+The following configuration options are available:
+
+[cols="2,1,5a"]
+|===
+|Property | Type | Description
+
+| pull-secret.enabled
+| bool
+| Can be used to enable or disable a trait. All traits share this common property.
+
+| pull-secret.secret-name
+| string
+| The pull secret name to set on the Pod. If left empty this is automatically taken from the `IntegrationPlatform` registry configuration.
+
+| pull-secret.auto
+| bool
+| Automatically configures the platform registry secret on the pod if it is of type `kubernetes.io/dockerconfigjson`.
+
+|===
+
+// End of autogenerated code - DO NOT EDIT! (configuration)
diff --git a/docs/modules/ROOT/pages/traits/traits.adoc b/docs/modules/ROOT/pages/traits/traits.adoc
index ce8e90b..3a3d043 100644
--- a/docs/modules/ROOT/pages/traits/traits.adoc
+++ b/docs/modules/ROOT/pages/traits/traits.adoc
@@ -53,6 +53,7 @@ See the trait description pages for more information on a specific trait:
* xref:traits/owner.adoc[Owner Trait]
* xref:traits/probes.adoc[Probes Trait]
* xref:traits/prometheus.adoc[Prometheus Trait]
+* xref:traits/pull-secret.adoc[Pull Secret Trait]
* xref:traits/quarkus.adoc[Quarkus Trait]
* xref:traits/rest-dsl.adoc[Rest Dsl Trait]
* xref:traits/route.adoc[Route Trait]
diff --git a/pkg/trait/pull_secret.go b/pkg/trait/pull_secret.go
new file mode 100644
index 0000000..db79632
--- /dev/null
+++ b/pkg/trait/pull_secret.go
@@ -0,0 +1,88 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package trait
+
+import (
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ v1 "k8s.io/api/core/v1"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+// The Pull Secret trait sets a pull secret on the pod,
+// to allow Kubernetes to retrieve the container image from an external registry.
+//
+// The pull secret can be specified manually or, in case you've configured authentication for an external container registry
+// on the `IntegrationPlatform`, the same secret is used to pull images.
+//
+// It's enabled by default whenever you configure authentication for an external container registry,
+// so it assumes that external registries are private.
+//
+// If your registry does not need authentication for pulling images, you can disable this trait.
+//
+// +camel-k:trait=pull-secret
+type pullSecretTrait struct {
+ BaseTrait `property:",squash"`
+ // The pull secret name to set on the Pod. If left empty this is automatically taken from the `IntegrationPlatform` registry configuration.
+ SecretName string `property:"secret-name"`
+ // Automatically configures the platform registry secret on the pod if it is of type `kubernetes.io/dockerconfigjson`.
+ Auto *bool `property:"auto"`
+}
+
+func newPullSecretTrait() *pullSecretTrait {
+ return &pullSecretTrait{
+ BaseTrait: newBaseTrait("pull-secret"),
+ }
+}
+
+func (t *pullSecretTrait) Configure(e *Environment) (bool, error) {
+ if t.Enabled != nil && !*t.Enabled {
+ return false, nil
+ }
+
+ if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+ return false, nil
+ }
+
+ if t.Auto == nil || *t.Auto {
+ if t.SecretName == "" {
+ secret := e.Platform.Spec.Build.Registry.Secret
+ if secret != "" {
+ key := client.ObjectKey{Namespace: e.Platform.Namespace, Name: secret}
+ obj := v1.Secret{}
+ if err := t.client.Get(t.ctx, key, &obj); err != nil {
+ return false, err
+ }
+ if obj.Type == v1.SecretTypeDockerConfigJson {
+ t.SecretName = secret
+ }
+ }
+ }
+ }
+
+ return t.SecretName != "", nil
+}
+
+func (t *pullSecretTrait) Apply(e *Environment) error {
+ e.Resources.VisitPodSpec(func(p *v1.PodSpec) {
+ p.ImagePullSecrets = append(p.ImagePullSecrets, v1.LocalObjectReference{
+ Name: t.SecretName,
+ })
+ })
+
+ return nil
+}
diff --git a/pkg/trait/pull_secret_test.go b/pkg/trait/pull_secret_test.go
new file mode 100644
index 0000000..1321dd2
--- /dev/null
+++ b/pkg/trait/pull_secret_test.go
@@ -0,0 +1,81 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package trait
+
+import (
+ "testing"
+
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "github.com/apache/camel-k/pkg/util/kubernetes"
+ appsv1 "k8s.io/api/apps/v1"
+ v1 "k8s.io/api/core/v1"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPullSecret(t *testing.T) {
+ e := &Environment{}
+ e.Integration = &v1alpha1.Integration{
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseDeploying,
+ },
+ }
+
+ deployment := appsv1.Deployment{
+ Spec: appsv1.DeploymentSpec{
+ Template: v1.PodTemplateSpec{
+ Spec: v1.PodSpec{},
+ },
+ },
+ }
+ e.Resources = kubernetes.NewCollection(&deployment)
+
+ trait := newPullSecretTrait()
+ trait.SecretName = "xxxy"
+ enabled, err := trait.Configure(e)
+ assert.Nil(t, err)
+ assert.True(t, enabled)
+
+ err = trait.Apply(e)
+ assert.Nil(t, err)
+ assert.Contains(t, deployment.Spec.Template.Spec.ImagePullSecrets, v1.LocalObjectReference{Name: "xxxy"})
+}
+
+func TestPullSecretDoesNothingWhenNotSetOnPlatform(t *testing.T) {
+ e := &Environment{}
+ e.Integration = &v1alpha1.Integration{
+ Status: v1alpha1.IntegrationStatus{
+ Phase: v1alpha1.IntegrationPhaseDeploying,
+ },
+ }
+ e.Platform = &v1alpha1.IntegrationPlatform{}
+
+ deployment := appsv1.Deployment{
+ Spec: appsv1.DeploymentSpec{
+ Template: v1.PodTemplateSpec{
+ Spec: v1.PodSpec{},
+ },
+ },
+ }
+ e.Resources = kubernetes.NewCollection(&deployment)
+
+ trait := newPullSecretTrait()
+ enabled, err := trait.Configure(e)
+ assert.Nil(t, err)
+ assert.False(t, enabled)
+}
diff --git a/pkg/trait/trait_catalog.go b/pkg/trait/trait_catalog.go
index ee7f698..57c5880 100644
--- a/pkg/trait/trait_catalog.go
+++ b/pkg/trait/trait_catalog.go
@@ -54,6 +54,7 @@ type Catalog struct {
tProbes Trait
tQuarkus Trait
tContainer Trait
+ tPullSecret Trait
}
// NewCatalog creates a new trait Catalog
@@ -83,6 +84,7 @@ func NewCatalog(ctx context.Context, c client.Client) *Catalog {
tProbes: newProbesTrait(),
tQuarkus: newQuarkusTrait(),
tContainer: newContainerTrait(),
+ tPullSecret: newPullSecretTrait(),
}
for _, t := range catalog.allTraits() {
@@ -121,6 +123,7 @@ func (c *Catalog) allTraits() []Trait {
c.tProbes,
c.tQuarkus,
c.tContainer,
+ c.tPullSecret,
}
}
@@ -152,6 +155,7 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
c.tAffinity,
c.tService,
c.tContainer,
+ c.tPullSecret,
c.tJolokia,
c.tPrometheus,
c.tClasspath,
@@ -175,6 +179,7 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
c.tAffinity,
c.tService,
c.tContainer,
+ c.tPullSecret,
c.tJolokia,
c.tPrometheus,
c.tClasspath,
@@ -199,6 +204,7 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
c.tAffinity,
c.tKnativeService,
c.tContainer,
+ c.tPullSecret,
c.tJolokia,
c.tPrometheus,
c.tClasspath,
diff --git a/pkg/util/kubernetes/collection.go b/pkg/util/kubernetes/collection.go
index eb6a00d..4c10184 100644
--- a/pkg/util/kubernetes/collection.go
+++ b/pkg/util/kubernetes/collection.go
@@ -306,6 +306,16 @@ func (c *Collection) VisitContainer(visitor func(container *corev1.Container)) {
})
}
+// VisitPodSpec executes the visitor function on all PodSpec inside deployments or other resources
+func (c *Collection) VisitPodSpec(visitor func(container *corev1.PodSpec)) {
+ c.VisitDeployment(func(d *appsv1.Deployment) {
+ visitor(&d.Spec.Template.Spec)
+ })
+ c.VisitKnativeConfigurationSpec(func(cs *servingv1.ConfigurationSpec) {
+ visitor(&cs.Template.Spec.PodSpec)
+ })
+}
+
// VisitKnativeConfigurationSpec executes the visitor function on all knative ConfigurationSpec inside serving Services
func (c *Collection) VisitKnativeConfigurationSpec(visitor func(container *servingv1.ConfigurationSpec)) {
c.VisitKnativeService(func(s *serving.Service) {