Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cmctl renew flags validation #20

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions pkg/renew/renew.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"strings"

"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -96,24 +97,37 @@ func NewCmdRenew(ctx context.Context, ioStreams genericclioptions.IOStreams) *co

// Validate validates the provided options
func (o *Options) Validate(cmd *cobra.Command, args []string) error {
if len(o.LabelSelector) > 0 && len(args) > 0 {
return errors.New("cannot specify Certificate names in conjunction with label selectors")
// The --all, --selector and args are mutually exclusive.
// - --all is equivalent to a match-all label selector
// - --selector filters by label selector
// - args are an explicit list of Certificate names
// However, there must always be one of the three specified.

var flags []string
if len(args) > 0 {
flags = append(flags, fmt.Sprintf("the Certificate resource names %q", args))
}

if len(o.LabelSelector) > 0 && o.All {
return errors.New("cannot specify label selectors in conjunction with --all flag")
if o.All {
flags = append(flags, "the --all flag")
}
if len(o.LabelSelector) > 0 {
flags = append(flags, "a label selector")
}

if o.All && len(args) > 0 {
return errors.New("cannot specify Certificate names in conjunction with --all flag")
// Ensure that only one of the three flags are specified
if len(flags) > 1 {
return fmt.Errorf("cannot specify %s in conjunction with %s", flags[0], strings.Join(flags[1:], " and "))
}

if o.All && cmd.PersistentFlags().Changed("namespace") {
return errors.New("cannot specify --namespace flag in conjunction with --all flag")
if len(flags) == 0 {
return errors.New("please either supply one or more Certificate resource names, label selectors, or use the --all flag to renew all Certificate resources")
}

if !o.All && len(args) == 0 {
return errors.New("please supply one or more Certificate resource names or use the --all flag to renew all Certificate resources")
// The --all-namespaces flag overrides the --namespace flag.
// Additionally, we can only use --all-namespaces when not specifying a list of Certificate names

if o.AllNamespaces && len(args) > 0 {
return errors.New("cannot specify Certificate names in conjunction with --all-namespaces flag")
}

return nil
Expand Down
35 changes: 32 additions & 3 deletions pkg/renew/renew_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,18 @@ func TestValidate(t *testing.T) {
args: []string{"abc"},
expErr: true,
},
"If there are arguments, as well as --all-namespaces, error": {
options: &Options{
AllNamespaces: true,
},
args: []string{"abc"},
expErr: true,
},
Comment on lines +44 to +50
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If arguments are specified:

  • You would get an Error from server (NotFound): error with --all-namespaces, unless the first namespace that is listed happens to contain the certificate(s) specified in the arguments.
    • This behaviour doesn't sound ideal so I think it's more intuitive to disallow use of arguments with --all-namespaces; arguments should really only be used with --namespace.

"If there are all certificates selected, as well as label selector, error": {
options: &Options{
LabelSelector: "foo=bar",
All: true,
},
args: []string{""},
Copy link
Contributor Author

@jace-ys jace-ys Feb 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a minor bug in the test case, as providing []string{""} as args is triggering a different error cannot specify Certificate names in conjunction with label selectors than intended (cannot specify label selectors in conjunction with --all flag)

expErr: true,
},
"If there are all certificates selected, as well as arguments, error": {
Expand All @@ -63,14 +69,14 @@ func TestValidate(t *testing.T) {
},
expErr: false,
},
"If --namespace and --all namespace specified, error": {
"If --namespace and --all specified, don't error": {
options: &Options{
All: true,
},
setStringFlags: []stringFlag{
{name: "namespace", value: "foo"},
},
expErr: true,
Comment on lines -66 to -73
Copy link
Contributor Author

@jace-ys jace-ys Feb 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test case doesn't seem right, as looking at the description for --all as well as the actual Run function, they seem to suggest that --all should work with --namespace.

I've updated the validation function accordingly too.

expErr: false,
},
"If --namespace specified without arguments, error": {
options: &Options{},
Expand All @@ -95,6 +101,29 @@ func TestValidate(t *testing.T) {
},
expErr: false,
},
"If --label-selector specified with --all, error": {
options: &Options{
LabelSelector: "foo=bar",
All: true,
},
expErr: true,
},
"If --label-selector specified with --all-namespaces, don't error": {
options: &Options{
AllNamespaces: true,
LabelSelector: "foo=bar",
},
expErr: false,
},
"If --label-selector specified with --namespace, don't error": {
options: &Options{
LabelSelector: "foo=bar",
},
setStringFlags: []stringFlag{
{name: "namespace", value: "foo"},
},
expErr: false,
},
}

for name, test := range tests {
Expand Down