diff --git a/cmd/nerdctl/namespace/namespace_update.go b/cmd/nerdctl/namespace/namespace_update.go index b390dc26792..3aab2b117d1 100644 --- a/cmd/nerdctl/namespace/namespace_update.go +++ b/cmd/nerdctl/namespace/namespace_update.go @@ -17,6 +17,8 @@ package namespace import ( + "errors" + "github.com/spf13/cobra" "github.com/containerd/nerdctl/v2/cmd/nerdctl/helpers" @@ -26,7 +28,7 @@ import ( ) func newNamespacelabelUpdateCommand() *cobra.Command { - namespaceLableCommand := &cobra.Command{ + namespaceLabelCommand := &cobra.Command{ Use: "update [flags] NAMESPACE", Short: "Update labels for a namespace", RunE: labelUpdateAction, @@ -34,8 +36,8 @@ func newNamespacelabelUpdateCommand() *cobra.Command { SilenceUsage: true, SilenceErrors: true, } - namespaceLableCommand.Flags().StringArrayP("label", "l", nil, "Set labels for a namespace") - return namespaceLableCommand + namespaceLabelCommand.Flags().StringArrayP("label", "l", nil, "Set labels for a namespace (required)") + return namespaceLabelCommand } func processNamespaceUpdateCommandOption(cmd *cobra.Command) (types.NamespaceUpdateOptions, error) { @@ -47,6 +49,11 @@ func processNamespaceUpdateCommandOption(cmd *cobra.Command) (types.NamespaceUpd if err != nil { return types.NamespaceUpdateOptions{}, err } + + if (len(labels) == 0) { + return types.NamespaceUpdateOptions{}, errors.New("use \"--label\" or \"-l\" to specify labels for namespace"); + } + return types.NamespaceUpdateOptions{ GOptions: globalOptions, Labels: labels, diff --git a/pkg/cmd/namespace/common.go b/pkg/cmd/namespace/common.go index e08939e0427..2285dc30fdd 100644 --- a/pkg/cmd/namespace/common.go +++ b/pkg/cmd/namespace/common.go @@ -16,7 +16,11 @@ package namespace -import "strings" +import ( + "strings" + "unicode" + "errors" +) func objectWithLabelArgs(args []string) map[string]string { if len(args) >= 1 { @@ -39,3 +43,19 @@ func labelArgs(labelStrings []string) map[string]string { return labels } + +// Returns an error if name is invalid. +func validateNamespaceName(name string) error { + for _, c := range(name) { + if ( + c == ' ' || + unicode.IsLower(c) || + unicode.IsNumber(c)) { + continue + } + + return errors.New("invalid namespace name - use only lowercase alphanumeric characters and hyphens") + } + + return nil +} diff --git a/pkg/cmd/namespace/create.go b/pkg/cmd/namespace/create.go index f07b9f007e6..6541cd85502 100644 --- a/pkg/cmd/namespace/create.go +++ b/pkg/cmd/namespace/create.go @@ -25,6 +25,10 @@ import ( ) func Create(ctx context.Context, client *containerd.Client, namespace string, options types.NamespaceCreateOptions) error { + if err := validateNamespaceName(namespace); err != nil { + return err + } + labelsArg := objectWithLabelArgs(options.Labels) namespaces := client.NamespaceService() return namespaces.Create(ctx, namespace, labelsArg) diff --git a/pkg/cmd/namespace/inspect.go b/pkg/cmd/namespace/inspect.go index 3a7a4932815..e9ff77a616f 100644 --- a/pkg/cmd/namespace/inspect.go +++ b/pkg/cmd/namespace/inspect.go @@ -30,6 +30,10 @@ import ( func Inspect(ctx context.Context, client *containerd.Client, inspectedNamespaces []string, options types.NamespaceInspectOptions) error { result := make([]interface{}, len(inspectedNamespaces)) for index, ns := range inspectedNamespaces { + if err := validateNamespaceName(ns); err != nil { + return err + } + ctx = namespaces.WithNamespace(ctx, ns) labels, err := client.NamespaceService().Labels(ctx, ns) if err != nil { diff --git a/pkg/cmd/namespace/update.go b/pkg/cmd/namespace/update.go index 63d2d8a5971..881db23b6ff 100644 --- a/pkg/cmd/namespace/update.go +++ b/pkg/cmd/namespace/update.go @@ -25,6 +25,10 @@ import ( ) func Update(ctx context.Context, client *containerd.Client, namespace string, options types.NamespaceUpdateOptions) error { + if err := validateNamespaceName(namespace); err != nil { + return err + } + labelsArg := objectWithLabelArgs(options.Labels) namespaces := client.NamespaceService() for k, v := range labelsArg {