This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 335c0248001de57169d2e3556ce97da9a89bc543
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Fri Feb 3 12:06:37 2023 +0100

    feat(kamelets): enable ServiceAccount for KameletBinding
    
    Closes #3797
---
 .../bases/camel.apache.org_kameletbindings.yaml    |  3 +++
 docs/modules/ROOT/partials/apis/kamelets-crds.adoc |  7 ++++++
 e2e/namespace/install/cli/bind_test.go             |  9 ++++++-
 e2e/support/test_support.go                        | 10 ++++++++
 helm/camel-k/crds/crd-kamelet-binding.yaml         |  3 +++
 pkg/apis/camel/v1alpha1/kamelet_binding_types.go   |  2 ++
 .../camel/v1alpha1/kameletbindingspec.go           | 21 +++++++++++-----
 pkg/cmd/bind.go                                    | 28 +++++++++++++---------
 pkg/cmd/bind_test.go                               | 10 ++++++++
 pkg/controller/kameletbinding/integration.go       |  4 ++++
 10 files changed, 79 insertions(+), 18 deletions(-)

diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml 
b/config/crd/bases/camel.apache.org_kameletbindings.yaml
index cf2213b68..e8f8ae8c5 100644
--- a/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -7660,6 +7660,9 @@ spec:
                 description: Replicas is the number of desired replicas for 
the binding
                 format: int32
                 type: integer
+              serviceAccountName:
+                description: Custom SA to use for the binding
+                type: string
               sink:
                 description: Sink is the destination of the integration 
defined by
                   this binding
diff --git a/docs/modules/ROOT/partials/apis/kamelets-crds.adoc 
b/docs/modules/ROOT/partials/apis/kamelets-crds.adoc
index 034fedd39..557e5f6ed 100644
--- a/docs/modules/ROOT/partials/apis/kamelets-crds.adoc
+++ b/docs/modules/ROOT/partials/apis/kamelets-crds.adoc
@@ -853,6 +853,13 @@ int32
 
 Replicas is the number of desired replicas for the binding
 
+|`serviceAccountName` +
+string
+|
+
+
+Custom SA to use for the binding
+
 
 |===
 
diff --git a/e2e/namespace/install/cli/bind_test.go 
b/e2e/namespace/install/cli/bind_test.go
index f2c831873..0e8fb84f4 100644
--- a/e2e/namespace/install/cli/bind_test.go
+++ b/e2e/namespace/install/cli/bind_test.go
@@ -25,7 +25,7 @@ package common
 import (
        "testing"
 
-       corev1 "k8s.io/api/core/v1"
+       //corev1 "k8s.io/api/core/v1"
 
        . "github.com/onsi/gomega"
 
@@ -60,5 +60,12 @@ func TestKamelCLIBind(t *testing.T) {
 
                        Expect(Kamel("delete", "--all", "-n", 
ns).Execute()).To(Succeed())
                })
+
+               t.Run("bind with custom SA", func(t *testing.T) {
+                       Expect(KamelBindWithID(operatorID, ns, "timer:foo", 
"log:bar", "--service-account", "my-service-account").Execute()).To(Succeed())
+                       Eventually(IntegrationSpecSA(ns, 
"timer-to-log")).Should(Equal("my-service-account"))
+
+                       Expect(Kamel("delete", "--all", "-n", 
ns).Execute()).To(Succeed())
+               })
        })
 }
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index d696e7d40..7bcbb29ad 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -970,6 +970,16 @@ func IntegrationSpecProfile(ns string, name string) func() 
v1.TraitProfile {
        }
 }
 
+func IntegrationSpecSA(ns string, name string) func() string {
+       return func() string {
+               it := Integration(ns, name)()
+               if it == nil {
+                       return ""
+               }
+               return it.Spec.ServiceAccountName
+       }
+}
+
 func IntegrationKit(ns string, name string) func() string {
        return func() string {
                it := Integration(ns, name)()
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml 
b/helm/camel-k/crds/crd-kamelet-binding.yaml
index cf2213b68..e8f8ae8c5 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -7660,6 +7660,9 @@ spec:
                 description: Replicas is the number of desired replicas for 
the binding
                 format: int32
                 type: integer
+              serviceAccountName:
+                description: Custom SA to use for the binding
+                type: string
               sink:
                 description: Sink is the destination of the integration 
defined by
                   this binding
diff --git a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go 
b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
index e5bf003a4..c2d86c542 100644
--- a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
+++ b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
@@ -59,6 +59,8 @@ type KameletBindingSpec struct {
        Steps []Endpoint `json:"steps,omitempty"`
        // Replicas is the number of desired replicas for the binding
        Replicas *int32 `json:"replicas,omitempty"`
+       // Custom SA to use for the binding
+       ServiceAccountName string `json:"serviceAccountName,omitempty"`
 }
 
 // Endpoint represents a source/sink external entity (could be any Kubernetes 
resource or Camel URI)
diff --git 
a/pkg/client/camel/applyconfiguration/camel/v1alpha1/kameletbindingspec.go 
b/pkg/client/camel/applyconfiguration/camel/v1alpha1/kameletbindingspec.go
index 23e74bcc0..491566627 100644
--- a/pkg/client/camel/applyconfiguration/camel/v1alpha1/kameletbindingspec.go
+++ b/pkg/client/camel/applyconfiguration/camel/v1alpha1/kameletbindingspec.go
@@ -26,12 +26,13 @@ import (
 // KameletBindingSpecApplyConfiguration represents an declarative 
configuration of the KameletBindingSpec type for use
 // with apply.
 type KameletBindingSpecApplyConfiguration struct {
-       Integration  *v1.IntegrationSpecApplyConfiguration 
`json:"integration,omitempty"`
-       Source       *EndpointApplyConfiguration           
`json:"source,omitempty"`
-       Sink         *EndpointApplyConfiguration           
`json:"sink,omitempty"`
-       ErrorHandler *ErrorHandlerSpecApplyConfiguration   
`json:"errorHandler,omitempty"`
-       Steps        []EndpointApplyConfiguration          
`json:"steps,omitempty"`
-       Replicas     *int32                                
`json:"replicas,omitempty"`
+       Integration        *v1.IntegrationSpecApplyConfiguration 
`json:"integration,omitempty"`
+       Source             *EndpointApplyConfiguration           
`json:"source,omitempty"`
+       Sink               *EndpointApplyConfiguration           
`json:"sink,omitempty"`
+       ErrorHandler       *ErrorHandlerSpecApplyConfiguration   
`json:"errorHandler,omitempty"`
+       Steps              []EndpointApplyConfiguration          
`json:"steps,omitempty"`
+       Replicas           *int32                                
`json:"replicas,omitempty"`
+       ServiceAccountName *string                               
`json:"serviceAccountName,omitempty"`
 }
 
 // KameletBindingSpecApplyConfiguration constructs an declarative 
configuration of the KameletBindingSpec type for use with
@@ -92,3 +93,11 @@ func (b *KameletBindingSpecApplyConfiguration) 
WithReplicas(value int32) *Kamele
        b.Replicas = &value
        return b
 }
+
+// WithServiceAccountName sets the ServiceAccountName field in the declarative 
configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" 
function invocations.
+// If called multiple times, the ServiceAccountName field is set to the value 
of the last call.
+func (b *KameletBindingSpecApplyConfiguration) WithServiceAccountName(value 
string) *KameletBindingSpecApplyConfiguration {
+       b.ServiceAccountName = &value
+       return b
+}
diff --git a/pkg/cmd/bind.go b/pkg/cmd/bind.go
index 6db6c6cd8..af67cafad 100644
--- a/pkg/cmd/bind.go
+++ b/pkg/cmd/bind.go
@@ -63,6 +63,7 @@ func newCmdBind(rootCmdOptions *RootCmdOptions) 
(*cobra.Command, *bindCmdOptions
        cmd.Flags().StringP("operator-id", "x", "camel-k", "Operator id 
selected to manage this Kamelet binding.")
        cmd.Flags().StringArray("annotation", nil, "Add an annotation to the 
Kamelet binding. E.g. \"--annotation my.company=hello\"")
        cmd.Flags().Bool("force", false, "Force creation of Kamelet binding 
regardless of potential misconfiguration.")
+       cmd.Flags().String("service-account", "", "The SA to use to run this 
binding")
 
        return &cmd, &options
 }
@@ -76,17 +77,18 @@ const (
 
 type bindCmdOptions struct {
        *RootCmdOptions
-       ErrorHandler string   `mapstructure:"error-handler" yaml:",omitempty"`
-       Name         string   `mapstructure:"name" yaml:",omitempty"`
-       Connects     []string `mapstructure:"connects" yaml:",omitempty"`
-       OutputFormat string   `mapstructure:"output" yaml:",omitempty"`
-       Properties   []string `mapstructure:"properties" yaml:",omitempty"`
-       SkipChecks   bool     `mapstructure:"skip-checks" yaml:",omitempty"`
-       Steps        []string `mapstructure:"steps" yaml:",omitempty"`
-       Traits       []string `mapstructure:"traits" yaml:",omitempty"`
-       OperatorID   string   `mapstructure:"operator-id" yaml:",omitempty"`
-       Annotations  []string `mapstructure:"annotations" yaml:",omitempty"`
-       Force        bool     `mapstructure:"force" yaml:",omitempty"`
+       ErrorHandler   string   `mapstructure:"error-handler" yaml:",omitempty"`
+       Name           string   `mapstructure:"name" yaml:",omitempty"`
+       Connects       []string `mapstructure:"connects" yaml:",omitempty"`
+       OutputFormat   string   `mapstructure:"output" yaml:",omitempty"`
+       Properties     []string `mapstructure:"properties" yaml:",omitempty"`
+       SkipChecks     bool     `mapstructure:"skip-checks" yaml:",omitempty"`
+       Steps          []string `mapstructure:"steps" yaml:",omitempty"`
+       Traits         []string `mapstructure:"traits" yaml:",omitempty"`
+       OperatorID     string   `mapstructure:"operator-id" yaml:",omitempty"`
+       Annotations    []string `mapstructure:"annotations" yaml:",omitempty"`
+       Force          bool     `mapstructure:"force" yaml:",omitempty"`
+       ServiceAccount string   `mapstructure:"service-account" 
yaml:",omitempty"`
 }
 
 func (o *bindCmdOptions) preRunE(cmd *cobra.Command, args []string) error {
@@ -237,6 +239,10 @@ func (o *bindCmdOptions) run(cmd *cobra.Command, args 
[]string) error {
                binding.Annotations = make(map[string]string)
        }
 
+       if o.ServiceAccount != "" {
+               binding.Spec.ServiceAccountName = o.ServiceAccount
+       }
+
        if !isOfflineCommand(cmd) && o.OperatorID != "" {
                if err := verifyOperatorID(o.Context, client, o.OperatorID); 
err != nil {
                        if o.Force {
diff --git a/pkg/cmd/bind_test.go b/pkg/cmd/bind_test.go
index a2729784a..a04436fc1 100644
--- a/pkg/cmd/bind_test.go
+++ b/pkg/cmd/bind_test.go
@@ -235,3 +235,13 @@ spec:
 status: {}
 `, output)
 }
+
+func TestBindServiceAccountName(t *testing.T) {
+       _, bindCmd, _ := initializeBindCmdOptions(t)
+       output, err := test.ExecuteCommand(bindCmd, cmdBind, "timer:foo", 
"log:bar",
+               "-o", "yaml",
+               "--service-account", "my-service-account")
+
+       assert.Nil(t, err)
+       assert.Contains(t, output, "serviceAccountName: my-service-account")
+}
diff --git a/pkg/controller/kameletbinding/integration.go 
b/pkg/controller/kameletbinding/integration.go
index e9e1add70..885cdcaa1 100644
--- a/pkg/controller/kameletbinding/integration.go
+++ b/pkg/controller/kameletbinding/integration.go
@@ -93,6 +93,10 @@ func CreateIntegrationFor(ctx context.Context, c 
client.Client, kameletbinding *
        }
        it.Spec.Profile = profile
 
+       if kameletbinding.Spec.ServiceAccountName != "" {
+               it.Spec.ServiceAccountName = 
kameletbinding.Spec.ServiceAccountName
+       }
+
        bindingContext := bindings.BindingContext{
                Ctx:       ctx,
                Client:    c,

Reply via email to