Skip to content

Commit

Permalink
Support to add labels to actionset in kanctl create actionset comma…
Browse files Browse the repository at this point in the history
…nd (#2434)

* Add `--labels` flag to `kanctl create actionset` command

* Add another test case `a=`

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
viveksinghggits and mergify[bot] authored Oct 26, 2023
1 parent 7c924c3 commit b909ad0
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 4 deletions.
62 changes: 58 additions & 4 deletions pkg/kanctl/actionset.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ const (
namespaceTargetsFlagName = "namespacetargets"
objectsFlagName = "objects"
waitForRepositoryServerReadyFlagName = "wait-for-repository-server"
labelsFlagName = "labels"
)

var (
errMissingFieldActionName = fmt.Errorf("missing action name. use the --action flag to specify the action name")
errInvalidFieldLabels = fmt.Errorf("invalid --labels value. make sure the value for field --labels is correct")
)

type PerformParams struct {
Expand All @@ -78,6 +80,7 @@ type PerformParams struct {
RepositoryServer *crv1alpha1.ObjectReference
Secrets map[string]crv1alpha1.ObjectReference
ConfigMaps map[string]crv1alpha1.ObjectReference
Labels map[string]string
}

func newActionSetCmd() *cobra.Command {
Expand Down Expand Up @@ -109,6 +112,7 @@ func newActionSetCmd() *cobra.Command {
cmd.Flags().StringSliceP(namespaceTargetsFlagName, "T", []string{}, "namespaces for the action set, comma separated list of namespaces (eg: --namespacetargets namespace1,namespace2)")
cmd.Flags().StringSliceP(objectsFlagName, "O", []string{}, "objects for the action set, comma separated list of object references (eg: --objects group/version/resource/namespace1/name1,group/version/resource/namespace2/name2)")
cmd.Flags().BoolP(waitForRepositoryServerReadyFlagName, "w", false, "wait for repository server to be ready before creating actionset")
cmd.Flags().String(labelsFlagName, "", "Labels that should be added to the created actionset, space chars would be trimmed automatically. Multiple labels can be separate by comma(,) (eg: --labels key=value,foo=bar)")
return cmd
}

Expand Down Expand Up @@ -189,14 +193,19 @@ func newActionSet(params *PerformParams) (*crv1alpha1.ActionSet, error) {
return nil, err
}

return &crv1alpha1.ActionSet{
actionset := &crv1alpha1.ActionSet{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: &crv1alpha1.ActionSetSpec{
Actions: actions,
},
}, nil
}
if params.Labels != nil {
actionset.Labels = params.Labels
}

return actionset, nil
}

func ChildActionSet(parent *crv1alpha1.ActionSet, params *PerformParams) (*crv1alpha1.ActionSet, error) {
Expand Down Expand Up @@ -253,14 +262,19 @@ func ChildActionSet(parent *crv1alpha1.ActionSet, params *PerformParams) (*crv1a
return nil, err
}

return &crv1alpha1.ActionSet{
actionset := &crv1alpha1.ActionSet{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: &crv1alpha1.ActionSetSpec{
Actions: actions,
},
}, nil
}
if params.Labels != nil {
actionset.Labels = params.Labels
}

return actionset, nil
}

func createActionSet(ctx context.Context, crCli versioned.Interface, namespace string, as *crv1alpha1.ActionSet) error {
Expand Down Expand Up @@ -297,6 +311,7 @@ func extractPerformParams(cmd *cobra.Command, args []string, cli kubernetes.Inte
parentName, _ := cmd.Flags().GetString(sourceFlagName)
blueprint, _ := cmd.Flags().GetString(blueprintFlagName)
dryRun, _ := cmd.Flags().GetBool(dryRunFlag)
labels, _ := cmd.Flags().GetString(labelsFlagName)
profile, err := parseProfile(cmd, ns)
if err != nil {
return nil, err
Expand All @@ -321,6 +336,11 @@ func extractPerformParams(cmd *cobra.Command, args []string, cli kubernetes.Inte
if err != nil {
return nil, err
}
ls, err := parseLabels(labels)
if err != nil {
return nil, err
}

return &PerformParams{
Namespace: ns,
ActionName: actionName,
Expand All @@ -334,9 +354,43 @@ func extractPerformParams(cmd *cobra.Command, args []string, cli kubernetes.Inte
ConfigMaps: cms,
Profile: profile,
RepositoryServer: repositoryServer,
Labels: ls,
}, nil
}

// parseLabels parses the given string to labels, it does some basic
// validations, for example the key and value must be separated by `=`
// and neither key nor value can have `,` in it.
// If there are some issue even after this, that would be caught by apiserver
// when actionset is actually created.
func parseLabels(label string) (map[string]string, error) {
if label == "" {
return nil, nil
}
labels := strings.Split(label, ",")

parsed := map[string]string{}
for _, l := range labels {
if !strings.Contains(l, "=") {
return nil, errInvalidFieldLabels
}

kv := strings.Split(l, "=")
key := strings.TrimSpace(kv[0])
value := strings.TrimSpace(kv[1])

if strings.HasPrefix(key, ",") ||
strings.HasSuffix(key, ",") ||
strings.HasPrefix(value, ",") ||
strings.HasSuffix(value, ",") {
return nil, errInvalidFieldLabels
}

parsed[key] = value
}
return parsed, nil
}

func parseConfigMaps(cmd *cobra.Command) (map[string]crv1alpha1.ObjectReference, error) {
configMapsFromCmd, _ := cmd.Flags().GetStringSlice(configMapsFlagName)
cms, err := parseReferences(configMapsFromCmd)
Expand Down
70 changes: 70 additions & 0 deletions pkg/kanctl/actionset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,73 @@ func (k *KanctlTestSuite) TestGenerateActionSetName(c *C) {
}
}
}

func (k *KanctlTestSuite) TestParseLabels(c *C) {
for _, tc := range []struct {
flagValue string
expectedLabels map[string]string
expectedErr error
}{
{
flagValue: "a=b",
expectedLabels: map[string]string{"a": "b"},
},
{
flagValue: "a=b,c=d",
expectedLabels: map[string]string{"a": "b", "c": "d"},
},
{
flagValue: "a=b,c=d,e=f",
expectedLabels: map[string]string{"a": "b", "c": "d", "e": "f"},
},
{
flagValue: "a=b,c=d,",
expectedLabels: nil,
expectedErr: errInvalidFieldLabels,
},
{
flagValue: ",a=b,c=d,",
expectedLabels: nil,
expectedErr: errInvalidFieldLabels,
},
{
flagValue: ",a=b,c=d",
expectedLabels: nil,
expectedErr: errInvalidFieldLabels,
},
{
flagValue: "a",
expectedLabels: nil,
expectedErr: errInvalidFieldLabels,
},
{
flagValue: "",
expectedLabels: nil,
},
{
flagValue: "a,=b,c=d",
expectedLabels: nil,
expectedErr: errInvalidFieldLabels,
},
{
flagValue: "a=b ,c =d",
expectedLabels: map[string]string{"a": "b", "c": "d"},
},
{
flagValue: " a= b ,c = d ",
expectedLabels: map[string]string{"a": "b", "c": "d"},
},
{
flagValue: " a= b ",
expectedLabels: map[string]string{"a": "b"},
},
{
flagValue: "a=",
expectedLabels: map[string]string{"a": ""},
},
} {
op, err := parseLabels(tc.flagValue)
c.Assert(err, DeepEquals, tc.expectedErr)
c.Assert(op, DeepEquals, tc.expectedLabels)
}
}

0 comments on commit b909ad0

Please sign in to comment.