You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2022/10/10 10:59:55 UTC
[camel-k] 01/01: feat(cli): Make add-repo and remove-repo compatible with a global op
This is an automated email from the ASF dual-hosted git repository.
nfilotto pushed a commit to branch 3667/make-add-repo-support-global-operator
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit b8212bc68c8435f1b296776992fd7ba3ed008f82
Author: Nicolas Filotto <nf...@talend.com>
AuthorDate: Mon Oct 10 12:58:53 2022 +0200
feat(cli): Make add-repo and remove-repo compatible with a global op
---
e2e/global/common/kamelet_test.go | 34 +++++++++----
pkg/cmd/kamelet.go | 1 +
pkg/cmd/kamelet_add_repo.go | 66 +++++++++++++++++++------
pkg/cmd/kamelet_remove_repo.go | 98 +++++++++++++++++++++++++++++++++++++
pkg/cmd/kamelet_remove_repo_test.go | 86 ++++++++++++++++++++++++++++++++
5 files changed, 261 insertions(+), 24 deletions(-)
diff --git a/e2e/global/common/kamelet_test.go b/e2e/global/common/kamelet_test.go
index e6b8834fb..ee15e1543 100644
--- a/e2e/global/common/kamelet_test.go
+++ b/e2e/global/common/kamelet_test.go
@@ -37,13 +37,11 @@ import (
* See https://github.com/apache/camel-k/issues/3667 for details
*/
func TestKameletClasspathLoading(t *testing.T) {
- if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
- t.Skip("WARNING: Test marked as problematic ... skipping")
- }
WithNewTestNamespace(t, func(ns string) {
- operatorID := "camel-k-kamelet"
- Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
+ ns = "4tests"
+ operatorID := "camel-k-4test"
+ //Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
kameletName := "timer-source"
removeKamelet(kameletName, ns)
@@ -62,14 +60,14 @@ func TestKameletClasspathLoading(t *testing.T) {
Eventually(IntegrationPodPhase(ns, "timer-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
Eventually(IntegrationLogs(ns, "timer-kamelet-integration")).Should(ContainSubstring("important message"))
-
- // Cleanup
- Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
})
// Custom repo
t.Run("test custom Kamelet repository", func(t *testing.T) {
-
+ globalTest := os.Getenv("CAMEL_K_FORCE_GLOBAL_TEST") == "true"
+ if globalTest {
+ t.Skip("Not compatible with global operator mode")
+ }
// Add the custom repository
Expect(Kamel("kamelet", "add-repo", "github:apache/camel-k/e2e/global/common/files/kamelets", "-n", ns, "-x", operatorID).Execute()).To(Succeed())
@@ -77,6 +75,24 @@ func TestKameletClasspathLoading(t *testing.T) {
Eventually(IntegrationPodPhase(ns, "timer-custom-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
Eventually(IntegrationLogs(ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("great message"))
+
+ // Remove the custom repository
+ Expect(Kamel("kamelet", "remove-repo", "github:apache/camel-k/e2e/global/common/files/kamelets", "-n", ns, "-x", operatorID).Execute()).To(Succeed())
+ })
+
+ // Custom repo without operator ID
+ t.Run("test custom Kamelet repository without operator ID", func(t *testing.T) {
+
+ // Add the custom repository
+ Expect(Kamel("kamelet", "add-repo", "github:apache/camel-k/e2e/global/common/files/kamelets", "-n", ns).Execute()).To(Succeed())
+
+ Expect(KamelRunWithID(operatorID, ns, "files/TimerCustomKameletIntegration.java").Execute()).To(Succeed())
+ Eventually(IntegrationPodPhase(ns, "timer-custom-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+ Eventually(IntegrationLogs(ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("great message"))
+
+ // Remove the custom repository
+ Expect(Kamel("kamelet", "remove-repo", "github:apache/camel-k/e2e/global/common/files/kamelets", "-n", ns).Execute()).To(Succeed())
})
})
}
diff --git a/pkg/cmd/kamelet.go b/pkg/cmd/kamelet.go
index 7645fd0c2..8b1f48b96 100644
--- a/pkg/cmd/kamelet.go
+++ b/pkg/cmd/kamelet.go
@@ -31,6 +31,7 @@ func newCmdKamelet(rootCmdOptions *RootCmdOptions) *cobra.Command {
cmd.AddCommand(cmdOnly(newKameletGetCmd(rootCmdOptions)))
cmd.AddCommand(cmdOnly(newKameletDeleteCmd(rootCmdOptions)))
cmd.AddCommand(cmdOnly(newKameletAddRepoCmd(rootCmdOptions)))
+ cmd.AddCommand(cmdOnly(newKameletRemoveRepoCmd(rootCmdOptions)))
return &cmd
}
diff --git a/pkg/cmd/kamelet_add_repo.go b/pkg/cmd/kamelet_add_repo.go
index 92591823d..804c400ff 100644
--- a/pkg/cmd/kamelet_add_repo.go
+++ b/pkg/cmd/kamelet_add_repo.go
@@ -23,6 +23,7 @@ import (
"regexp"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+ platformutil "github.com/apache/camel-k/pkg/platform"
"github.com/spf13/cobra"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -33,7 +34,9 @@ var kameletRepositoryURIRegexp = regexp.MustCompile(`^github:[^/]+/[^/]+((/[^/]+
func newKameletAddRepoCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kameletAddRepoCommandOptions) {
options := kameletAddRepoCommandOptions{
- RootCmdOptions: rootCmdOptions,
+ kameletUpdateRepoCommandOptions: &kameletUpdateRepoCommandOptions{
+ RootCmdOptions: rootCmdOptions,
+ },
}
cmd := cobra.Command{
@@ -49,23 +52,24 @@ func newKameletAddRepoCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kame
},
}
- cmd.Flags().StringP("operator-id", "x", "camel-k", "Id of the Operator to update.")
+ cmd.Flags().StringP("operator-id", "x", "", "Id of the Operator to update.")
return &cmd, &options
}
-type kameletAddRepoCommandOptions struct {
+type kameletUpdateRepoCommandOptions struct {
*RootCmdOptions
OperatorID string `mapstructure:"operator-id" yaml:",omitempty"`
}
+type kameletAddRepoCommandOptions struct {
+ *kameletUpdateRepoCommandOptions
+}
+
func (o *kameletAddRepoCommandOptions) validate(args []string) error {
if len(args) == 0 {
return errors.New("at least one Kamelet repository is expected")
}
- if o.OperatorID == "" {
- return fmt.Errorf("cannot use empty operator id")
- }
return nil
}
@@ -74,6 +78,30 @@ func (o *kameletAddRepoCommandOptions) run(cmd *cobra.Command, args []string) er
if err != nil {
return err
}
+ var platform *v1.IntegrationPlatform
+ if o.OperatorID == "" {
+ platform, err = o.findIntegrationPlatorm(cmd, c)
+ } else {
+ platform, err = o.getIntegrationPlatorm(cmd, c)
+ }
+ if err != nil {
+ return err
+ } else if platform == nil {
+ return nil
+ }
+ for _, uri := range args {
+ if err := checkURI(uri, platform.Spec.Kamelet.Repositories); err != nil {
+ return err
+ }
+ platform.Spec.Kamelet.Repositories = append(platform.Spec.Kamelet.Repositories, v1.IntegrationPlatformKameletRepositorySpec{
+ URI: uri,
+ })
+ }
+ return c.Update(o.Context, platform)
+}
+
+// getIntegrationPlatorm gives the integration plaform matching with the operator id in the provided namespace.
+func (o *kameletUpdateRepoCommandOptions) getIntegrationPlatorm(cmd *cobra.Command, c client.Client) (*v1.IntegrationPlatform, error) {
key := client.ObjectKey{
Namespace: o.Namespace,
Name: o.OperatorID,
@@ -83,19 +111,27 @@ func (o *kameletAddRepoCommandOptions) run(cmd *cobra.Command, args []string) er
if k8serrors.IsNotFound(err) {
// IntegrationPlatform may be in the operator namespace, but we currently don't have a way to determine it: we just warn
fmt.Fprintf(cmd.ErrOrStderr(), "Warning: IntegrationPlatform %q not found in namespace %q\n", key.Name, key.Namespace)
- return nil
+ return nil, nil
}
- return err
+ return nil, err
}
- for _, uri := range args {
- if err := checkURI(uri, platform.Spec.Kamelet.Repositories); err != nil {
- return err
+ return &platform, nil
+}
+
+// findIntegrationPlatorm gives the primary integration plaform that could be found in the provided namespace.
+func (o *kameletUpdateRepoCommandOptions) findIntegrationPlatorm(cmd *cobra.Command, c client.Client) (*v1.IntegrationPlatform, error) {
+ platforms, err := platformutil.ListPrimaryPlatforms(o.Context, c, o.Namespace)
+ if err != nil {
+ return nil, err
+ }
+ for _, p := range platforms.Items {
+ p := p // pin
+ if platformutil.IsActive(&p) {
+ return &p, nil
}
- platform.Spec.Kamelet.Repositories = append(platform.Spec.Kamelet.Repositories, v1.IntegrationPlatformKameletRepositorySpec{
- URI: uri,
- })
}
- return c.Update(o.Context, &platform)
+ fmt.Fprintf(cmd.ErrOrStderr(), "Warning: No active primary IntegrationPlatform could be found in namespace %q\n", o.Namespace)
+ return nil, nil
}
func checkURI(uri string, repositories []v1.IntegrationPlatformKameletRepositorySpec) error {
diff --git a/pkg/cmd/kamelet_remove_repo.go b/pkg/cmd/kamelet_remove_repo.go
new file mode 100644
index 000000000..b0a97347d
--- /dev/null
+++ b/pkg/cmd/kamelet_remove_repo.go
@@ -0,0 +1,98 @@
+/*
+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 (
+ "errors"
+ "fmt"
+
+ v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+ "github.com/spf13/cobra"
+)
+
+func newKameletRemoveRepoCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kameletRemoveRepoCommandOptions) {
+ options := kameletRemoveRepoCommandOptions{
+ kameletUpdateRepoCommandOptions: &kameletUpdateRepoCommandOptions{
+ RootCmdOptions: rootCmdOptions,
+ },
+ }
+
+ cmd := cobra.Command{
+ Use: "remove-repo github:owner/repo[/path_to_kamelets_folder][@version] ...",
+ Short: "Remove a Kamelet repository",
+ Long: `Remove a Kamelet repository.`,
+ PreRunE: decode(&options),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ if err := options.validate(args); err != nil {
+ return err
+ }
+ return options.run(cmd, args)
+ },
+ }
+
+ cmd.Flags().StringP("operator-id", "x", "", "Id of the Operator to update.")
+
+ return &cmd, &options
+}
+
+type kameletRemoveRepoCommandOptions struct {
+ *kameletUpdateRepoCommandOptions
+}
+
+func (o *kameletRemoveRepoCommandOptions) validate(args []string) error {
+ if len(args) == 0 {
+ return errors.New("at least one Kamelet repository is expected")
+ }
+ return nil
+}
+
+func (o *kameletRemoveRepoCommandOptions) run(cmd *cobra.Command, args []string) error {
+ c, err := o.GetCmdClient()
+ if err != nil {
+ return err
+ }
+ var platform *v1.IntegrationPlatform
+ if o.OperatorID == "" {
+ platform, err = o.findIntegrationPlatorm(cmd, c)
+ } else {
+ platform, err = o.getIntegrationPlatorm(cmd, c)
+ }
+ if err != nil {
+ return err
+ } else if platform == nil {
+ return nil
+ }
+ for _, uri := range args {
+ i, err := getURIIndex(uri, platform.Spec.Kamelet.Repositories)
+ if err != nil {
+ return err
+ }
+ platform.Spec.Kamelet.Repositories[i] = platform.Spec.Kamelet.Repositories[len(platform.Spec.Kamelet.Repositories)-1]
+ platform.Spec.Kamelet.Repositories = platform.Spec.Kamelet.Repositories[:len(platform.Spec.Kamelet.Repositories)-1]
+ }
+ return c.Update(o.Context, platform)
+}
+
+func getURIIndex(uri string, repositories []v1.IntegrationPlatformKameletRepositorySpec) (int, error) {
+ for i, repo := range repositories {
+ if repo.URI == uri {
+ return i, nil
+ }
+ }
+ return 0, fmt.Errorf("non existing Kamelet repository uri %s", uri)
+}
diff --git a/pkg/cmd/kamelet_remove_repo_test.go b/pkg/cmd/kamelet_remove_repo_test.go
new file mode 100644
index 000000000..0d77840c5
--- /dev/null
+++ b/pkg/cmd/kamelet_remove_repo_test.go
@@ -0,0 +1,86 @@
+/*
+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 (
+ "testing"
+
+ "github.com/spf13/cobra"
+ "github.com/stretchr/testify/assert"
+
+ v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/pkg/util/test"
+)
+
+const cmdKameletRemoveRepo = "remove-repo"
+
+// nolint: unparam
+func initializeKameletRemoveRepoCmdOptions(t *testing.T) (*kameletRemoveRepoCommandOptions, *cobra.Command, RootCmdOptions) {
+ t.Helper()
+
+ options, rootCmd := kamelTestPreAddCommandInit()
+ kameletRemoveRepoCommandOptions := addTestKameletRemoveRepoCmd(*options, rootCmd)
+ kamelTestPostAddCommandInit(t, rootCmd)
+
+ return kameletRemoveRepoCommandOptions, rootCmd, *options
+}
+
+func addTestKameletRemoveRepoCmd(options RootCmdOptions, rootCmd *cobra.Command) *kameletRemoveRepoCommandOptions {
+ // Add a testing version of kamelet remove-repo Command
+ kameletRemoveRepoCmd, kameletRemoveRepoOptions := newKameletRemoveRepoCmd(&options)
+ kameletRemoveRepoCmd.RunE = func(c *cobra.Command, args []string) error {
+ return nil
+ }
+ kameletRemoveRepoCmd.PostRunE = func(c *cobra.Command, args []string) error {
+ return nil
+ }
+ kameletRemoveRepoCmd.Args = test.ArbitraryArgs
+ rootCmd.AddCommand(kameletRemoveRepoCmd)
+ return kameletRemoveRepoOptions
+}
+
+func TestKameletRemoveRepoNoFlag(t *testing.T) {
+ _, rootCmd, _ := initializeKameletRemoveRepoCmdOptions(t)
+ _, err := test.ExecuteCommand(rootCmd, cmdKameletRemoveRepo, "foo")
+ assert.Nil(t, err)
+}
+
+func TestKameletRemoveRepoNonExistingFlag(t *testing.T) {
+ _, rootCmd, _ := initializeKameletRemoveRepoCmdOptions(t)
+ _, err := test.ExecuteCommand(rootCmd, cmdKameletRemoveRepo, "--nonExistingFlag", "foo")
+ assert.NotNil(t, err)
+}
+
+func TestKameletRemoveRepoURINotFoundEmpty(t *testing.T) {
+ repositories := []v1.IntegrationPlatformKameletRepositorySpec{}
+ _, err := getURIIndex("foo", repositories)
+ assert.NotNil(t, err)
+}
+
+func TestKameletRemoveRepoURINotFoundNotEmpty(t *testing.T) {
+ repositories := []v1.IntegrationPlatformKameletRepositorySpec{{URI: "github:foo/bar"}}
+ _, err := getURIIndex("foo", repositories)
+ assert.NotNil(t, err)
+}
+
+func TestKameletRemoveRepoURIFound(t *testing.T) {
+ repositories := []v1.IntegrationPlatformKameletRepositorySpec{{URI: "github:foo/bar1"}, {URI: "github:foo/bar2"}, {URI: "github:foo/bar3"}}
+ i, err := getURIIndex("github:foo/bar2", repositories)
+ assert.Nil(t, err)
+ assert.Equal(t, 1, i)
+}