Skip to content

Commit

Permalink
fix(cmd): rebuild KameletBindings
Browse files Browse the repository at this point in the history
Closes #4208
  • Loading branch information
squakez committed Apr 3, 2023
1 parent c6dd6f3 commit c427f8d
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 14 deletions.
92 changes: 90 additions & 2 deletions pkg/cmd/rebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ import (

"github.com/pkg/errors"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"

k8sclient "sigs.k8s.io/controller-runtime/pkg/client"

v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
"github.com/apache/camel-k/v2/pkg/apis/camel/v1alpha1"
"github.com/apache/camel-k/v2/pkg/client"
"github.com/apache/camel-k/v2/pkg/util/kubernetes"
)

func newCmdRebuild(rootCmdOptions *RootCmdOptions) (*cobra.Command, *rebuildCmdOptions) {
Expand Down Expand Up @@ -68,11 +72,80 @@ func (o *rebuildCmdOptions) validate(args []string) error {
}

func (o *rebuildCmdOptions) run(cmd *cobra.Command, args []string) error {
errKlbs := o.rebuildKameletBindingType(cmd, args)
errIts := o.rebuildIntegrationType(cmd, args)

if errIts != nil && errKlbs != nil {
return errors.Wrap(errIts, errKlbs.Error())
}

return nil
}

func (o *rebuildCmdOptions) rebuildKameletBindingType(cmd *cobra.Command, args []string) error {
c, err := o.GetCmdClient()
if err != nil {
return err
}
var kameletBindings []v1alpha1.KameletBinding
if o.RebuildAll {
if kameletBindings, err = o.listAllKameletBindings(c); err != nil {
return err
}
} else if len(args) > 0 {
if kameletBindings, err = o.getKameletBindings(c, args); err != nil {
return err
}
}

if err = o.rebuildKameletBindings(c, kameletBindings); err != nil {
return err
}

fmt.Fprintln(cmd.OutOrStdout(), len(kameletBindings), "kamelet bindings have been rebuilt")
return nil
}

func (o *rebuildCmdOptions) listAllKameletBindings(c client.Client) ([]v1alpha1.KameletBinding, error) {
list := v1alpha1.NewKameletBindingList()
if err := c.List(o.Context, &list, k8sclient.InNamespace(o.Namespace)); err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("could not retrieve kamelet bindings from namespace %s", o.Namespace))
}
return list.Items, nil
}

func (o *rebuildCmdOptions) getKameletBindings(c client.Client, names []string) ([]v1alpha1.KameletBinding, error) {
klbs := make([]v1alpha1.KameletBinding, 0, len(names))
for _, n := range names {
klb := v1alpha1.NewKameletBinding(o.Namespace, n)
key := k8sclient.ObjectKey{
Name: n,
Namespace: o.Namespace,
}
if err := c.Get(o.Context, key, &klb); err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("could not find kamelet binding %s in namespace %s", klb.Name, o.Namespace))
}
klbs = append(klbs, klb)
}
return klbs, nil
}

func (o *rebuildCmdOptions) rebuildKameletBindings(c k8sclient.StatusClient, kameletbindings []v1alpha1.KameletBinding) error {
for _, i := range kameletbindings {
klb := i
klb.Status = v1alpha1.KameletBindingStatus{}
if err := c.Status().Update(o.Context, &klb); err != nil {
return errors.Wrap(err, fmt.Sprintf("could not rebuild kamelet binding %s in namespace %s", klb.Name, o.Namespace))
}
}
return nil
}

func (o *rebuildCmdOptions) rebuildIntegrationType(cmd *cobra.Command, args []string) error {
c, err := o.GetCmdClient()
if err != nil {
return err
}
var integrations []v1.Integration
if o.RebuildAll {
if integrations, err = o.listAllIntegrations(c); err != nil {
Expand All @@ -94,7 +167,19 @@ func (o *rebuildCmdOptions) run(cmd *cobra.Command, args []string) error {

func (o *rebuildCmdOptions) listAllIntegrations(c client.Client) ([]v1.Integration, error) {
list := v1.NewIntegrationList()
if err := c.List(o.Context, &list, k8sclient.InNamespace(o.Namespace)); err != nil {
// Integrations controlled by KameletBindings are not included
excludeItsFromKlbs, err := labels.NewRequirement(kubernetes.CamelCreatorLabelKind, selection.NotEquals, []string{
"KameletBinding",
})
if err != nil {
return list.Items, err
}
if err := c.List(o.Context, &list,
k8sclient.InNamespace(o.Namespace),
k8sclient.MatchingLabelsSelector{
Selector: labels.NewSelector().Add(*excludeItsFromKlbs),
},
); err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("could not retrieve integrations from namespace %s", o.Namespace))
}
return list.Items, nil
Expand All @@ -111,7 +196,10 @@ func (o *rebuildCmdOptions) getIntegrations(c client.Client, names []string) ([]
if err := c.Get(o.Context, key, &it); err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("could not find integration %s in namespace %s", it.Name, o.Namespace))
}
ints = append(ints, it)
// Integrations controlled by KameletBindings are not included
if it.Labels[kubernetes.CamelCreatorLabelKind] != "KameletBinding" {
ints = append(ints, it)
}
}
return ints, nil
}
Expand Down
82 changes: 70 additions & 12 deletions pkg/cmd/rebuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,47 +20,105 @@ package cmd
import (
"testing"

"github.com/apache/camel-k/v2/pkg/util/kubernetes"
"github.com/apache/camel-k/v2/pkg/util/test"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/runtime"
)

const cmdRebuild = "rebuild"

// nolint: unparam
func initializeRebuildCmdOptions(t *testing.T) (*rebuildCmdOptions, *cobra.Command, RootCmdOptions) {
func initializeRebuildOptions(t *testing.T, initObjs ...runtime.Object) (*rebuildCmdOptions, *cobra.Command, RootCmdOptions) {
t.Helper()

options, rootCmd := kamelTestPreAddCommandInit()
fakeClient, err := test.NewFakeClient(initObjs...)
assert.Nil(t, err)
options, rootCmd := kamelTestPreAddCommandInitWithClient(fakeClient)
options.Namespace = "default"
rebuildCmdOptions := addTestRebuildCmd(*options, rootCmd)
kamelTestPostAddCommandInit(t, rootCmd)

return rebuildCmdOptions, rootCmd, *options
}

func addTestRebuildCmd(options RootCmdOptions, rootCmd *cobra.Command) *rebuildCmdOptions {
// add a testing version of rebuild Command
rebuildCmd, rebuildOptions := newCmdRebuild(&options)
rebuildCmd.RunE = func(c *cobra.Command, args []string) error {
return nil
}
rebuildCmd.PostRunE = func(c *cobra.Command, args []string) error {
return nil
}
rebuildCmd.Args = test.ArbitraryArgs
rootCmd.AddCommand(rebuildCmd)
return rebuildOptions
}

func TestRebuildNonExistingFlag(t *testing.T) {
_, rootCmd, _ := initializeRebuildCmdOptions(t)
_, rootCmd, _ := initializeRebuildOptions(t)
_, err := test.ExecuteCommand(rootCmd, cmdRebuild, "--nonExistingFlag")
assert.NotNil(t, err)
}

func TestRebuildAllFlag(t *testing.T) {
rebuildCmdOptions, rootCmd, _ := initializeRebuildCmdOptions(t)
rebuildCmdOptions, rootCmd, _ := initializeRebuildOptions(t)
_, err := test.ExecuteCommand(rootCmd, cmdRebuild, "--all")
assert.Nil(t, err)
assert.Equal(t, true, rebuildCmdOptions.RebuildAll)
}

func TestRebuildAllKameletBindingsAndIntegrations(t *testing.T) {
defaultIntegration := nominalIntegration("my-it-test")
defaultKB := nominalKameletBinding("my-kb-test")
itGeneratedByKlb := nominalIntegration("my-kb-test")
itGeneratedByKlb.Labels = map[string]string{
kubernetes.CamelCreatorLabelKind: "KameletBinding",
}

_, rebuildCmd, _ := initializeRebuildOptions(t, &defaultIntegration, &defaultKB, &itGeneratedByKlb)
output, err := test.ExecuteCommand(rebuildCmd, cmdRebuild, "--all")
assert.Nil(t, err)
assert.Contains(t, output, "1 kamelet bindings have been rebuilt")
assert.Contains(t, output, "1 integrations have been rebuilt")
}

func TestRebuildNone(t *testing.T) {
defaultIntegration := nominalIntegration("my-it-test")
defaultKB := nominalKameletBinding("my-kb-test")
itGeneratedByKlb := nominalIntegration("my-kb-test")
itGeneratedByKlb.Labels = map[string]string{
kubernetes.CamelCreatorLabelKind: "KameletBinding",
}

_, rebuildCmd, _ := initializeRebuildOptions(t, &defaultIntegration, &defaultKB, &itGeneratedByKlb)
output, err := test.ExecuteCommand(rebuildCmd, cmdRebuild, "my-missing")
assert.NotNil(t, err)
assert.NotContains(t, output, "have been rebuilt")
assert.Contains(t, output, "could not find kamelet binding my-missing in namespace default")
assert.Contains(t, output, "could not find integration my-missing in namespace default")
}

func TestRebuildKameletBindingOnly(t *testing.T) {
defaultIntegration := nominalIntegration("my-it-test")
defaultKB := nominalKameletBinding("my-kb-test")
itGeneratedByKlb := nominalIntegration("my-kb-test")
itGeneratedByKlb.Labels = map[string]string{
kubernetes.CamelCreatorLabelKind: "KameletBinding",
}

_, rebuildCmd, _ := initializeRebuildOptions(t, &defaultIntegration, &defaultKB, &itGeneratedByKlb)
output, err := test.ExecuteCommand(rebuildCmd, cmdRebuild, "my-kb-test")
assert.Nil(t, err)
assert.Contains(t, output, "1 kamelet bindings have been rebuilt")
assert.NotContains(t, output, "1 integrations have been rebuilt")
}

func TestRebuildIntegrationOnly(t *testing.T) {
defaultIntegration := nominalIntegration("my-it-test")
defaultKB := nominalKameletBinding("my-kb-test")
itGeneratedByKlb := nominalIntegration("my-kb-test")
itGeneratedByKlb.Labels = map[string]string{
kubernetes.CamelCreatorLabelKind: "KameletBinding",
}

_, rebuildCmd, _ := initializeRebuildOptions(t, &defaultIntegration, &defaultKB, &itGeneratedByKlb)
output, err := test.ExecuteCommand(rebuildCmd, cmdRebuild, "my-it-test")
assert.Nil(t, err)
assert.NotContains(t, output, "1 kamelet bindings have been rebuilt")
assert.Contains(t, output, "1 integrations have been rebuilt")
}

0 comments on commit c427f8d

Please sign in to comment.