You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2023/08/01 08:03:38 UTC
[camel-k] branch main updated (2463f0b38 -> 3988ba34f)
This is an automated email from the ASF dual-hosted git repository.
pcongiusti pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
from 2463f0b38 chore: nightly SBOM update
new 35708255b fix(cmd): don't validate on dry-run
new 629e5ca67 feat(cmd): promote image only
new 3988ba34f feat(cmd): promote multi tenancy
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
pkg/cmd/promote.go | 100 ++++++++++++++++++++++++++++++++---------------
pkg/cmd/promote_test.go | 102 +++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 166 insertions(+), 36 deletions(-)
[camel-k] 01/03: fix(cmd): don't validate on dry-run
Posted by pc...@apache.org.
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 35708255bbe84dbe92538f33aee8101036dcf435
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Fri Jul 28 14:52:17 2023 +0200
fix(cmd): don't validate on dry-run
Closes #4534
---
pkg/cmd/promote.go | 52 ++++++++++++++++++++++++++++---------------------
pkg/cmd/promote_test.go | 7 ++-----
2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go
index b87170f73..e332f4da2 100644
--- a/pkg/cmd/promote.go
+++ b/pkg/cmd/promote.go
@@ -88,19 +88,23 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args []string) error {
if err != nil {
return fmt.Errorf("could not retrieve cluster client: %w", err)
}
- opSource, err := operatorInfo(o.Context, c, o.Namespace)
- if err != nil {
- return fmt.Errorf("could not retrieve info for Camel K operator source: %w", err)
- }
- opDest, err := operatorInfo(o.Context, c, o.To)
- if err != nil {
- return fmt.Errorf("could not retrieve info for Camel K operator destination: %w", err)
- }
+ if o.OutputFormat == "" {
+ // Skip these checks if in dry mode
+ opSource, err := operatorInfo(o.Context, c, o.Namespace)
+ if err != nil {
+ return fmt.Errorf("could not retrieve info for Camel K operator source: %w", err)
+ }
+ opDest, err := operatorInfo(o.Context, c, o.To)
+ if err != nil {
+ return fmt.Errorf("could not retrieve info for Camel K operator destination: %w", err)
+ }
- err = checkOpsCompatibility(cmd, opSource, opDest)
- if err != nil {
- return fmt.Errorf("could not verify operators compatibility: %w", err)
+ err = checkOpsCompatibility(cmd, opSource, opDest)
+ if err != nil {
+ return fmt.Errorf("could not verify operators compatibility: %w", err)
+ }
}
+
promotePipe := false
var sourceIntegration *v1.Integration
// We first look if a Pipe with the name exists
@@ -118,41 +122,45 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args []string) error {
if sourceIntegration.Status.Phase != v1.IntegrationPhaseRunning {
return fmt.Errorf("could not promote an Integration in %s status", sourceIntegration.Status.Phase)
}
- err = o.validateDestResources(c, sourceIntegration)
- if err != nil {
- return fmt.Errorf("could not validate destination resources: %w", err)
+
+ if o.OutputFormat == "" {
+ // Skip these checks if in dry mode
+ err = o.validateDestResources(c, sourceIntegration)
+ if err != nil {
+ return fmt.Errorf("could not validate destination resources: %w", err)
+ }
}
// Pipe promotion
if promotePipe {
destPipe := o.editPipe(sourcePipe, sourceIntegration)
+ if o.OutputFormat != "" {
+ return showPipeOutput(cmd, destPipe, o.OutputFormat, c.GetScheme())
+ }
// Ensure the destination namespace has access to the source namespace images
err = addSystemPullerRoleBinding(o.Context, c, sourceIntegration.Namespace, destPipe.Namespace)
if err != nil {
return err
}
replaced, err := o.replaceResource(destPipe)
- if o.OutputFormat != "" {
- return showPipeOutput(cmd, destPipe, o.OutputFormat, c.GetScheme())
- }
if !replaced {
- fmt.Fprintln(cmd.OutOrStdout(), `Promoted Integration "`+name+`" created`)
+ fmt.Fprintln(cmd.OutOrStdout(), `Promoted Pipe "`+name+`" created`)
} else {
- fmt.Fprintln(cmd.OutOrStdout(), `Promoted Integration "`+name+`" updated`)
+ fmt.Fprintln(cmd.OutOrStdout(), `Promoted Pipe "`+name+`" updated`)
}
return err
}
// Plain Integration promotion
destIntegration := o.editIntegration(sourceIntegration)
+ if o.OutputFormat != "" {
+ return showIntegrationOutput(cmd, destIntegration, o.OutputFormat)
+ }
// Ensure the destination namespace has access to the source namespace images
err = addSystemPullerRoleBinding(o.Context, c, sourceIntegration.Namespace, destIntegration.Namespace)
if err != nil {
return err
}
- if o.OutputFormat != "" {
- return showIntegrationOutput(cmd, destIntegration, o.OutputFormat)
- }
replaced, err := o.replaceResource(destIntegration)
if !replaced {
fmt.Fprintln(cmd.OutOrStdout(), `Promoted Integration "`+name+`" created`)
diff --git a/pkg/cmd/promote_test.go b/pkg/cmd/promote_test.go
index de35de413..22529788a 100644
--- a/pkg/cmd/promote_test.go
+++ b/pkg/cmd/promote_test.go
@@ -65,9 +65,8 @@ func TestIntegrationNotCompatible(t *testing.T) {
srcCatalog := createTestCamelCatalog(srcPlatform)
dstCatalog := createTestCamelCatalog(dstPlatform)
- promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog)
- _, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default")
- assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
+ _, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog)
+ _, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-n", "default")
assert.NotNil(t, err)
assert.Equal(t,
fmt.Sprintf("could not verify operators compatibility: source (%s) and destination (0.0.1) Camel K operator versions are not compatible", defaults.Version),
@@ -137,7 +136,6 @@ metadata:
creationTimestamp: null
name: my-kb-test
namespace: prod-namespace
- resourceVersion: "1"
spec:
integration:
traits:
@@ -238,7 +236,6 @@ metadata:
my-label: my-value
name: my-kb-test
namespace: prod-namespace
- resourceVersion: "1"
spec:
integration:
traits:
[camel-k] 02/03: feat(cmd): promote image only
Posted by pc...@apache.org.
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 629e5ca6774189cd02b1fa4dff917494554d6d57
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Fri Jul 28 15:21:24 2023 +0200
feat(cmd): promote image only
Ability to show the container image used in some integration
---
pkg/cmd/promote.go | 20 ++++++++++++++++++--
pkg/cmd/promote_test.go | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go
index e332f4da2..b12ebc948 100644
--- a/pkg/cmd/promote.go
+++ b/pkg/cmd/promote.go
@@ -58,6 +58,7 @@ func newCmdPromote(rootCmdOptions *RootCmdOptions) (*cobra.Command, *promoteCmdO
cmd.Flags().String("to", "", "The namespace where to promote the Integration")
cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml")
+ cmd.Flags().BoolP("image", "i", false, "Output the container image only")
return &cmd, &options
}
@@ -66,6 +67,7 @@ type promoteCmdOptions struct {
*RootCmdOptions
To string `mapstructure:"to" yaml:",omitempty"`
OutputFormat string `mapstructure:"output" yaml:",omitempty"`
+ Image bool `mapstructure:"image" yaml:",omitempty"`
}
func (o *promoteCmdOptions) validate(_ *cobra.Command, args []string) error {
@@ -88,7 +90,7 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args []string) error {
if err != nil {
return fmt.Errorf("could not retrieve cluster client: %w", err)
}
- if o.OutputFormat == "" {
+ if !o.isDryRun() {
// Skip these checks if in dry mode
opSource, err := operatorInfo(o.Context, c, o.Namespace)
if err != nil {
@@ -123,7 +125,13 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args []string) error {
return fmt.Errorf("could not promote an Integration in %s status", sourceIntegration.Status.Phase)
}
- if o.OutputFormat == "" {
+ // Image only mode
+ if o.Image {
+ showImageOnly(cmd, sourceIntegration)
+ return nil
+ }
+
+ if !o.isDryRun() {
// Skip these checks if in dry mode
err = o.validateDestResources(c, sourceIntegration)
if err != nil {
@@ -511,6 +519,10 @@ func (o *promoteCmdOptions) replaceResource(res k8sclient.Object) (bool, error)
return kubernetes.ReplaceResource(o.Context, o._client, res)
}
+func (o *promoteCmdOptions) isDryRun() bool {
+ return o.OutputFormat != "" || o.Image
+}
+
// RoleBinding is required to allow access to images in one namespace
// by another namespace. Without this on rbac-enabled clusters, the
// image cannot be pulled.
@@ -541,3 +553,7 @@ func addSystemPullerRoleBinding(ctx context.Context, c client.Client, sourceNS s
return err
}
+
+func showImageOnly(cmd *cobra.Command, integration *v1.Integration) {
+ fmt.Fprintln(cmd.OutOrStdout(), integration.Status.Image)
+}
diff --git a/pkg/cmd/promote_test.go b/pkg/cmd/promote_test.go
index 22529788a..f6817ecbe 100644
--- a/pkg/cmd/promote_test.go
+++ b/pkg/cmd/promote_test.go
@@ -246,3 +246,42 @@ spec:
status: {}
`, output)
}
+
+func TestItImageOnly(t *testing.T) {
+ srcPlatform := v1.NewIntegrationPlatform("default", platform.DefaultPlatformName)
+ srcPlatform.Status.Version = defaults.Version
+ srcPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ srcPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
+ dstPlatform := v1.NewIntegrationPlatform("prod-namespace", platform.DefaultPlatformName)
+ dstPlatform.Status.Version = defaults.Version
+ dstPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ dstPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
+ defaultIntegration := nominalIntegration("my-it-test")
+ srcCatalog := createTestCamelCatalog(srcPlatform)
+ dstCatalog := createTestCamelCatalog(dstPlatform)
+
+ _, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog)
+ output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-i", "-n", "default")
+ assert.Nil(t, err)
+ assert.Equal(t, fmt.Sprintf("my-special-image\n"), output)
+}
+
+func TestPipeImageOnly(t *testing.T) {
+ srcPlatform := v1.NewIntegrationPlatform("default", platform.DefaultPlatformName)
+ srcPlatform.Status.Version = defaults.Version
+ srcPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ srcPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
+ dstPlatform := v1.NewIntegrationPlatform("prod-namespace", platform.DefaultPlatformName)
+ dstPlatform.Status.Version = defaults.Version
+ dstPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ dstPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
+ defaultKB := nominalPipe("my-kb-test")
+ defaultIntegration := nominalIntegration("my-kb-test")
+ srcCatalog := createTestCamelCatalog(srcPlatform)
+ dstCatalog := createTestCamelCatalog(dstPlatform)
+
+ _, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultKB, &defaultIntegration, &srcCatalog, &dstCatalog)
+ output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-kb-test", "--to", "prod-namespace", "-i", "-n", "default")
+ assert.Nil(t, err)
+ assert.Equal(t, fmt.Sprintf("my-special-image\n"), output)
+}
[camel-k] 03/03: feat(cmd): promote multi tenancy
Posted by pc...@apache.org.
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 3988ba34fb7686a37ae941b99d1e733d9c4c74e3
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Fri Jul 28 16:19:48 2023 +0200
feat(cmd): promote multi tenancy
Closes #3890
---
pkg/cmd/promote.go | 32 ++++++++++++++++++--------
pkg/cmd/promote_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 81 insertions(+), 11 deletions(-)
diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go
index b12ebc948..b15cc0838 100644
--- a/pkg/cmd/promote.go
+++ b/pkg/cmd/promote.go
@@ -49,14 +49,15 @@ func newCmdPromote(rootCmdOptions *RootCmdOptions) (*cobra.Command, *promoteCmdO
RootCmdOptions: rootCmdOptions,
}
cmd := cobra.Command{
- Use: "promote my-it --to [namespace]",
+ Use: "promote my-it [--to <namespace>] [-x <promoted-operator-id>]",
Short: "Promote an Integration/Pipe from an environment to another",
Long: "Promote an Integration/Pipe from an environment to another, for example from a Development environment to a Production environment",
PreRunE: decode(&options),
RunE: options.run,
}
- cmd.Flags().String("to", "", "The namespace where to promote the Integration")
+ cmd.Flags().String("to", "", "The namespace where to promote the Integration/Pipe")
+ cmd.Flags().StringP("to-operator", "x", "", "The operator id which will reconcile the promoted Integration/Pipe")
cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml")
cmd.Flags().BoolP("image", "i", false, "Output the container image only")
@@ -66,16 +67,20 @@ func newCmdPromote(rootCmdOptions *RootCmdOptions) (*cobra.Command, *promoteCmdO
type promoteCmdOptions struct {
*RootCmdOptions
To string `mapstructure:"to" yaml:",omitempty"`
+ ToOperator string `mapstructure:"to-operator" yaml:",omitempty"`
OutputFormat string `mapstructure:"output" yaml:",omitempty"`
Image bool `mapstructure:"image" yaml:",omitempty"`
}
func (o *promoteCmdOptions) validate(_ *cobra.Command, args []string) error {
if len(args) != 1 {
- return errors.New("promote expects an Integration/Pipe name argument")
+ return errors.New("promote requires an Integration/Pipe name argument")
}
if o.To == "" {
- return errors.New("promote expects a destination namespace as --to argument")
+ return errors.New("promote requires a destination namespace as --to argument")
+ }
+ if o.To == o.Namespace {
+ return errors.New("source and destination namespaces must be different in order to avoid promoted Integration/Pipe clashes with the source Integration/Pipe")
}
return nil
}
@@ -457,7 +462,7 @@ func (o *promoteCmdOptions) editIntegration(it *v1.Integration) *v1.Integration
dst := v1.NewIntegration(o.To, it.Name)
contImage := it.Status.Image
dst.Spec = *it.Spec.DeepCopy()
- dst.Annotations = cloneAnnotations(it.Annotations)
+ dst.Annotations = cloneAnnotations(it.Annotations, o.ToOperator)
dst.Labels = cloneLabels(it.Labels)
if dst.Spec.Traits.Container == nil {
dst.Spec.Traits.Container = &traitv1.ContainerTrait{}
@@ -466,14 +471,23 @@ func (o *promoteCmdOptions) editIntegration(it *v1.Integration) *v1.Integration
return &dst
}
-// Return all annotations but the ones specific to source (ie, the operator).
-func cloneAnnotations(ann map[string]string) map[string]string {
+// Return all annotations overriding the operator Id if provided.
+func cloneAnnotations(ann map[string]string, operatorID string) map[string]string {
+ operatorIDAnnotationSet := false
newMap := make(map[string]string)
for k, v := range ann {
- if k != v1.OperatorIDAnnotation {
+ if k == v1.OperatorIDAnnotation {
+ if operatorID != "" {
+ newMap[v1.OperatorIDAnnotation] = operatorID
+ operatorIDAnnotationSet = true
+ }
+ } else {
newMap[k] = v
}
}
+ if !operatorIDAnnotationSet && operatorID != "" {
+ newMap[v1.OperatorIDAnnotation] = operatorID
+ }
return newMap
}
@@ -489,7 +503,7 @@ func cloneLabels(lbs map[string]string) map[string]string {
func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it *v1.Integration) *v1.Pipe {
dst := v1.NewPipe(o.To, kb.Name)
dst.Spec = *kb.Spec.DeepCopy()
- dst.Annotations = cloneAnnotations(kb.Annotations)
+ dst.Annotations = cloneAnnotations(kb.Annotations, o.ToOperator)
dst.Labels = cloneLabels(kb.Labels)
contImage := it.Status.Image
if dst.Spec.Integration == nil {
diff --git a/pkg/cmd/promote_test.go b/pkg/cmd/promote_test.go
index f6817ecbe..bc39d63de 100644
--- a/pkg/cmd/promote_test.go
+++ b/pkg/cmd/promote_test.go
@@ -263,7 +263,7 @@ func TestItImageOnly(t *testing.T) {
_, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog)
output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-i", "-n", "default")
assert.Nil(t, err)
- assert.Equal(t, fmt.Sprintf("my-special-image\n"), output)
+ assert.Equal(t, "my-special-image\n", output)
}
func TestPipeImageOnly(t *testing.T) {
@@ -283,5 +283,61 @@ func TestPipeImageOnly(t *testing.T) {
_, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultKB, &defaultIntegration, &srcCatalog, &dstCatalog)
output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-kb-test", "--to", "prod-namespace", "-i", "-n", "default")
assert.Nil(t, err)
- assert.Equal(t, fmt.Sprintf("my-special-image\n"), output)
+ assert.Equal(t, "my-special-image\n", output)
+}
+
+func TestIntegrationToOperatorId(t *testing.T) {
+ srcPlatform := v1.NewIntegrationPlatform("default", platform.DefaultPlatformName)
+ srcPlatform.Status.Version = defaults.Version
+ srcPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ srcPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
+ dstPlatform := v1.NewIntegrationPlatform("prod-namespace", platform.DefaultPlatformName)
+ dstPlatform.Status.Version = defaults.Version
+ dstPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
+ dstPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
+ defaultIntegration := nominalIntegration("my-it-test")
+ srcCatalog := createTestCamelCatalog(srcPlatform)
+ dstCatalog := createTestCamelCatalog(dstPlatform)
+
+ // Verify default (missing) operator Id
+ promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog)
+ output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "-x", "my-prod-operator", "-o", "yaml", "--to", "prod")
+ assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
+ assert.Nil(t, err)
+ assert.Equal(t, `apiVersion: camel.apache.org/v1
+kind: Integration
+metadata:
+ annotations:
+ camel.apache.org/operator.id: my-prod-operator
+ creationTimestamp: null
+ name: my-it-test
+ namespace: prod
+spec:
+ traits:
+ container:
+ image: my-special-image
+status: {}
+`, output)
+ // Verify also when the operator Id is set in the integration
+ defaultIntegration.Annotations = map[string]string{
+ "camel.apache.org/operator.id": "camel-k",
+ }
+ promoteCmdOptions, promoteCmd, _ = initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog)
+ output, err = test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "-x", "my-prod-operator", "-o", "yaml", "--to", "prod")
+ assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
+ assert.Nil(t, err)
+ assert.Equal(t, `apiVersion: camel.apache.org/v1
+kind: Integration
+metadata:
+ annotations:
+ camel.apache.org/operator.id: my-prod-operator
+ creationTimestamp: null
+ name: my-it-test
+ namespace: prod
+spec:
+ traits:
+ container:
+ image: my-special-image
+status: {}
+`, output)
}