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/02/13 08:33:14 UTC
[camel-k] branch main updated: feat(cli): promote dry run
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
The following commit(s) were added to refs/heads/main by this push:
new f0e0ea938 feat(cli): promote dry run
f0e0ea938 is described below
commit f0e0ea938cefb39add1629b02fbd208e3399477d
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Fri Feb 10 17:01:27 2023 +0100
feat(cli): promote dry run
Close #3888
---
pkg/cmd/bind.go | 4 +-
pkg/cmd/promote.go | 25 +++++---
pkg/cmd/promote_test.go | 151 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 171 insertions(+), 9 deletions(-)
diff --git a/pkg/cmd/bind.go b/pkg/cmd/bind.go
index af67cafad..59bce431a 100644
--- a/pkg/cmd/bind.go
+++ b/pkg/cmd/bind.go
@@ -264,7 +264,7 @@ func (o *bindCmdOptions) run(cmd *cobra.Command, args []string) error {
}
if o.OutputFormat != "" {
- return showOutput(cmd, &binding, o.OutputFormat, client.GetScheme())
+ return showKameletBindingOutput(cmd, &binding, o.OutputFormat, client.GetScheme())
}
replaced, err := kubernetes.ReplaceResource(o.Context, client, &binding)
@@ -280,7 +280,7 @@ func (o *bindCmdOptions) run(cmd *cobra.Command, args []string) error {
return nil
}
-func showOutput(cmd *cobra.Command, binding *v1alpha1.KameletBinding, outputFormat string, scheme runtime.ObjectTyper) error {
+func showKameletBindingOutput(cmd *cobra.Command, binding *v1alpha1.KameletBinding, outputFormat string, scheme runtime.ObjectTyper) error {
printer := printers.NewTypeSetter(scheme)
printer.Delegate = &kubernetes.CLIPrinter{
Format: outputFormat,
diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go
index 3ebd67bbc..fba185afb 100644
--- a/pkg/cmd/promote.go
+++ b/pkg/cmd/promote.go
@@ -51,7 +51,7 @@ func newCmdPromote(rootCmdOptions *RootCmdOptions) (*cobra.Command, *promoteCmdO
RootCmdOptions: rootCmdOptions,
}
cmd := cobra.Command{
- Use: "promote integration --to [namespace] ...",
+ Use: "promote my-it --to [namespace]",
Short: "Promote an Integration/KameletBinding from an environment to another",
Long: "Promote an Integration/KameletBinding from an environment to another, for example from a Development environment to a Production environment",
PreRunE: decode(&options),
@@ -59,13 +59,15 @@ 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")
return &cmd, &options
}
type promoteCmdOptions struct {
*RootCmdOptions
- To string `mapstructure:"to" yaml:",omitempty"`
+ To string `mapstructure:"to" yaml:",omitempty"`
+ OutputFormat string `mapstructure:"output" yaml:",omitempty"`
}
func (o *promoteCmdOptions) validate(_ *cobra.Command, args []string) error {
@@ -88,7 +90,6 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args []string) error {
if err != nil {
return errors.Wrap(err, "could not retrieve cluster client")
}
-
opSource, err := operatorInfo(o.Context, c, o.Namespace)
if err != nil {
return errors.Wrap(err, "could not retrieve info for Camel K operator source")
@@ -123,11 +124,19 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args []string) error {
if err != nil {
return errors.Wrap(err, "could not validate destination resources")
}
+
+ // KameletBinding promotion
if promoteKameletBinding {
- // KameletBinding promotion
destKameletBinding := o.editKameletBinding(sourceKameletBinding, sourceIntegration)
-
+ // Ensure the destination namespace has access to the source namespace images
+ err = addSystemPullerRoleBinding(o.Context, c, sourceIntegration.Namespace, destKameletBinding.Namespace)
+ if err != nil {
+ return err
+ }
replaced, err := o.replaceResource(destKameletBinding)
+ if o.OutputFormat != "" {
+ return showKameletBindingOutput(cmd, destKameletBinding, o.OutputFormat, c.GetScheme())
+ }
if !replaced {
fmt.Fprintln(cmd.OutOrStdout(), `Promoted Integration "`+name+`" created`)
} else {
@@ -135,15 +144,17 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args []string) error {
}
return err
}
+
// Plain Integration promotion
destIntegration := o.editIntegration(sourceIntegration)
-
// 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, c.GetScheme())
+ }
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
new file mode 100644
index 000000000..11524aefc
--- /dev/null
+++ b/pkg/cmd/promote_test.go
@@ -0,0 +1,151 @@
+/*
+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 cmd
+
+import (
+ "fmt"
+ "testing"
+
+ v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "github.com/apache/camel-k/pkg/platform"
+ "github.com/apache/camel-k/pkg/util/defaults"
+ "github.com/apache/camel-k/pkg/util/test"
+ "github.com/spf13/cobra"
+ "github.com/stretchr/testify/assert"
+ "k8s.io/apimachinery/pkg/runtime"
+)
+
+const cmdPromote = "promote"
+
+// nolint: unparam
+func initializePromoteCmdOptions(t *testing.T, initObjs ...runtime.Object) (*promoteCmdOptions, *cobra.Command, RootCmdOptions) {
+ t.Helper()
+ fakeClient, err := test.NewFakeClient(initObjs...)
+ assert.Nil(t, err)
+ options, rootCmd := kamelTestPreAddCommandInitWithClient(fakeClient)
+ options.Namespace = "default"
+ promoteCmdOptions := addTestPromoteCmd(*options, rootCmd)
+ kamelTestPostAddCommandInit(t, rootCmd)
+
+ return promoteCmdOptions, rootCmd, *options
+}
+
+func addTestPromoteCmd(options RootCmdOptions, rootCmd *cobra.Command) *promoteCmdOptions {
+ promoteCmd, promoteOptions := newCmdPromote(&options)
+ promoteCmd.Args = test.ArbitraryArgs
+ rootCmd.AddCommand(promoteCmd)
+ return promoteOptions
+}
+
+func TestIntegrationNotCompatible(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 = "0.0.1"
+ dstPlatform.Status.Build.RuntimeVersion = "0.0.1"
+ dstPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
+ defaultIntegration := nominalIntegration("my-it-test")
+
+ promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration)
+ _, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default")
+ assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
+ 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),
+ err.Error(),
+ )
+}
+
+func TestIntegrationDryRun(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")
+
+ promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration)
+ output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default")
+ assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
+ assert.Nil(t, err)
+ assert.Equal(t, `apiVersion: camel.apache.org/v1
+kind: Integration
+metadata:
+ creationTimestamp: null
+ name: my-it-test
+ namespace: prod-namespace
+spec:
+ traits:
+ container:
+ image: my-special-image
+status: {}
+`, output)
+}
+
+func nominalIntegration(name string) v1.Integration {
+ it := v1.NewIntegration("default", name)
+ it.Status.Phase = v1.IntegrationPhaseRunning
+ it.Status.Image = "my-special-image"
+ return it
+}
+
+func TestKameletBindingDryRun(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 := nominalKameletBinding("my-kb-test")
+ defaultIntegration := nominalIntegration("my-kb-test")
+
+ promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultKB, &defaultIntegration)
+ output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-kb-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default")
+ assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
+ assert.Nil(t, err)
+ assert.Equal(t, `apiVersion: camel.apache.org/v1alpha1
+kind: KameletBinding
+metadata:
+ creationTimestamp: null
+ name: my-kb-test
+ namespace: prod-namespace
+ resourceVersion: "1"
+spec:
+ integration:
+ traits:
+ container:
+ image: my-special-image
+ sink: {}
+ source: {}
+status: {}
+`, output)
+}
+
+func nominalKameletBinding(name string) v1alpha1.KameletBinding {
+ kb := v1alpha1.NewKameletBinding("default", name)
+ kb.Status.Phase = v1alpha1.KameletBindingPhaseReady
+ return kb
+}