Cleans up renew kube flags and adds --namespace validation
Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
This commit is contained in:
parent
28639c366b
commit
28f7e7bc78
@ -8,7 +8,12 @@ go_library(
|
||||
deps = [
|
||||
"//cmd/ctl/cmd:go_default_library",
|
||||
"//pkg/util/cmd:go_default_library",
|
||||
<<<<<<< HEAD
|
||||
"@io_k8s_klog//:go_default_library",
|
||||
=======
|
||||
"@com_github_spf13_cobra//:go_default_library",
|
||||
"@io_k8s_cli_runtime//pkg/genericclioptions:go_default_library",
|
||||
>>>>>>> 65e8ff5db... Cleans up renew kube flags and adds --namespace validation
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@ -17,13 +17,18 @@ limitations under the License.
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
|
||||
// Load all auth plugins
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
"k8s.io/klog"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
|
||||
"github.com/jetstack/cert-manager/cmd/ctl/pkg/convert"
|
||||
"github.com/jetstack/cert-manager/cmd/ctl/pkg/renew"
|
||||
@ -45,10 +50,19 @@ cert-manager-ctl is a CLI tool manage and configure cert-manager resources for K
|
||||
matchVersionKubeConfigFlags.AddFlags(cmds.PersistentFlags())
|
||||
factory := cmdutil.NewFactory(matchVersionKubeConfigFlags)
|
||||
|
||||
cmds.Flags().AddGoFlagSet(flag.CommandLine)
|
||||
flag.CommandLine.Parse([]string{})
|
||||
fakefs := flag.NewFlagSet("fake", flag.ExitOnError)
|
||||
klog.InitFlags(fakefs)
|
||||
if err := fakefs.Parse([]string{"-logtostderr=false"}); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
ioStreams := genericclioptions.IOStreams{In: in, Out: out, ErrOut: err}
|
||||
cmds.AddCommand(version.NewCmdVersion(ioStreams))
|
||||
cmds.AddCommand(convert.NewCmdConvert(ioStreams))
|
||||
cmds.AddCommand(renew.NewCmdRenew(ioStreams, factory))
|
||||
cmds.AddCommand(renew.NewCmdRenew(ioStreams))
|
||||
|
||||
return cmds
|
||||
}
|
||||
|
||||
@ -17,27 +17,16 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
ctlcmd "github.com/jetstack/cert-manager/cmd/ctl/cmd"
|
||||
utilcmd "github.com/jetstack/cert-manager/pkg/util/cmd"
|
||||
"github.com/jetstack/cert-manager/pkg/util/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
stopCh := utilcmd.SetupSignalHandler()
|
||||
cmd := ctlcmd.NewCertManagerCtlCommand(os.Stdin, os.Stdout, os.Stderr, stopCh)
|
||||
cmd.Flags().AddGoFlagSet(flag.CommandLine)
|
||||
flag.CommandLine.Parse([]string{})
|
||||
fakefs := flag.NewFlagSet("fake", flag.ExitOnError)
|
||||
klog.InitFlags(fakefs)
|
||||
if err := fakefs.Parse([]string{"-logtostderr=false"}); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
stopCh := cmd.SetupSignalHandler()
|
||||
cmd := NewCertManagerCtlCommand(os.Stdin, os.Stdout, os.Stderr, stopCh)
|
||||
|
||||
if err := cmd.Execute(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
}
|
||||
|
||||
@ -15,7 +15,9 @@ go_library(
|
||||
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
|
||||
"@io_k8s_cli_runtime//pkg/genericclioptions:go_default_library",
|
||||
"@io_k8s_client_go//kubernetes:go_default_library",
|
||||
"@io_k8s_client_go//plugin/pkg/client/auth:go_default_library",
|
||||
"@io_k8s_client_go//rest:go_default_library",
|
||||
"@io_k8s_klog//:go_default_library",
|
||||
"@io_k8s_kubectl//pkg/cmd/util:go_default_library",
|
||||
"@io_k8s_kubectl//pkg/util/i18n:go_default_library",
|
||||
"@io_k8s_kubectl//pkg/util/templates:go_default_library",
|
||||
@ -40,4 +42,5 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["renew_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["@io_k8s_cli_runtime//pkg/genericclioptions:go_default_library"],
|
||||
)
|
||||
|
||||
@ -19,14 +19,19 @@ package renew
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
// Load all auth plugins
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/klog"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
@ -39,27 +44,27 @@ import (
|
||||
|
||||
var (
|
||||
long = templates.LongDesc(i18n.T(`
|
||||
Mark cert-manager Certificate resources for manual renewal.
|
||||
`))
|
||||
Mark cert-manager Certificate resources for manual renewal.`))
|
||||
|
||||
example = templates.Examples(i18n.T(`
|
||||
# Renew the Certificates named 'my-app' and 'vault' in the current context namespace.
|
||||
ctl renew my-app vault
|
||||
# Renew the Certificates named 'my-app' and 'vault' in the current context namespace.
|
||||
ctl renew my-app vault
|
||||
|
||||
# Renew all Certificates in the 'kube-system' namespace.
|
||||
ctl renew --namespace kube-system --all
|
||||
# Renew all Certificates in the 'kube-system' namespace.
|
||||
ctl renew --namespace kube-system --all
|
||||
|
||||
# Renew all Certificates in all namespaces that have the label 'app=my-service'.
|
||||
ctl renew --all-namespaces -l app=my-service`))
|
||||
# Renew all Certificates in all namespaces, provided those Certificates have the label 'app=my-service
|
||||
ctl renew --all-namespaces -l app=my-service`))
|
||||
)
|
||||
|
||||
// Options is a struct to support renew command
|
||||
type Options struct {
|
||||
// The Namespace that the Certificate to be renewed resided in
|
||||
Namespace string
|
||||
CMClient cmclient.Interface
|
||||
RestConfig *restclient.Config
|
||||
RESTConfig *restclient.Config
|
||||
|
||||
// The Namespace that the Certificate to be renewed resided in.
|
||||
// This flag registration is handled by cmdutil.Factory
|
||||
Namespace string
|
||||
LabelSelector string
|
||||
All bool
|
||||
AllNamespaces bool
|
||||
@ -75,17 +80,18 @@ func NewOptions(ioStreams genericclioptions.IOStreams) *Options {
|
||||
}
|
||||
|
||||
// NewCmdRenew returns a cobra command for renewing Certificates
|
||||
func NewCmdRenew(ioStreams genericclioptions.IOStreams, factory cmdutil.Factory) *cobra.Command {
|
||||
func NewCmdRenew(ioStreams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := NewOptions(ioStreams)
|
||||
var factory cmdutil.Factory
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "renew",
|
||||
Short: "Mark a Certificate for manual renewal",
|
||||
Long: "Mark a Certificate for manual renewal",
|
||||
Long: long,
|
||||
Example: example,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(factory))
|
||||
cmdutil.CheckErr(o.Validate(args))
|
||||
cmdutil.CheckErr(o.Validate(cmd, args))
|
||||
cmdutil.CheckErr(o.Run(args))
|
||||
},
|
||||
}
|
||||
@ -94,11 +100,26 @@ func NewCmdRenew(ioStreams genericclioptions.IOStreams, factory cmdutil.Factory)
|
||||
cmd.Flags().BoolVarP(&o.AllNamespaces, "all-namespaces", "A", o.AllNamespaces, "If present, mark Certificates across namespaces for manual renewal. Namespace in current context is ignored even if specified with --namespace.")
|
||||
cmd.Flags().BoolVar(&o.All, "all", o.All, "Renew all Certificates in the given Namespace, or all namespaces with --all-namespaces enabled.")
|
||||
|
||||
kubeConfigFlags := genericclioptions.NewConfigFlags(true)
|
||||
kubeConfigFlags.AddFlags(cmd.PersistentFlags())
|
||||
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)
|
||||
matchVersionKubeConfigFlags.AddFlags(cmd.PersistentFlags())
|
||||
factory = cmdutil.NewFactory(matchVersionKubeConfigFlags)
|
||||
|
||||
cmd.Flags().AddGoFlagSet(flag.CommandLine)
|
||||
flag.CommandLine.Parse([]string{})
|
||||
fakefs := flag.NewFlagSet("fake", flag.ExitOnError)
|
||||
klog.InitFlags(fakefs)
|
||||
if err := fakefs.Parse([]string{"-logtostderr=false"}); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Validate validates the provided options
|
||||
func (o *Options) Validate(args []string) error {
|
||||
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")
|
||||
}
|
||||
@ -111,6 +132,10 @@ func (o *Options) Validate(args []string) error {
|
||||
return errors.New("cannot specify Certificate names in conjunction with --all flag")
|
||||
}
|
||||
|
||||
if o.All && cmd.PersistentFlags().Changed("namespace") {
|
||||
return errors.New("cannot specify --namespace flag in conjunction with --all flag")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -122,12 +147,12 @@ func (o *Options) Complete(f cmdutil.Factory) error {
|
||||
return err
|
||||
}
|
||||
|
||||
o.RestConfig, err = f.ToRESTConfig()
|
||||
o.RESTConfig, err = f.ToRESTConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.CMClient, err = cmclient.NewForConfig(o.RestConfig)
|
||||
o.CMClient, err = cmclient.NewForConfig(o.RESTConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -141,10 +166,8 @@ func (o *Options) Run(args []string) error {
|
||||
|
||||
nss := []corev1.Namespace{{ObjectMeta: metav1.ObjectMeta{Name: o.Namespace}}}
|
||||
|
||||
// TODO: handle network context
|
||||
|
||||
if o.AllNamespaces {
|
||||
kubeClient, err := kubernetes.NewForConfig(o.RestConfig)
|
||||
kubeClient, err := kubernetes.NewForConfig(o.RESTConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -18,13 +18,20 @@ package renew
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
)
|
||||
|
||||
type stringFlag struct {
|
||||
name, value string
|
||||
}
|
||||
|
||||
func TestValidate(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
options *Options
|
||||
args []string
|
||||
expErr bool
|
||||
options *Options
|
||||
args []string
|
||||
setStringFlags []stringFlag
|
||||
expErr bool
|
||||
}{
|
||||
"If there are arguments, as well as label selector, error": {
|
||||
options: &Options{
|
||||
@ -55,12 +62,30 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
expErr: false,
|
||||
},
|
||||
"If --namespace and --all namespace specified, error": {
|
||||
options: &Options{
|
||||
All: true,
|
||||
},
|
||||
setStringFlags: []stringFlag{
|
||||
{name: "namespace", value: "foo"},
|
||||
},
|
||||
expErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
err := test.options.Validate(test.args)
|
||||
cmd := NewCmdRenew(genericclioptions.IOStreams{})
|
||||
|
||||
if test.setStringFlags != nil {
|
||||
for _, s := range test.setStringFlags {
|
||||
if err := cmd.PersistentFlags().Set(s.name, s.value); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := test.options.Validate(cmd, test.args)
|
||||
if test.expErr != (err != nil) {
|
||||
t.Errorf("expected error=%t got=%v",
|
||||
test.expErr, err)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user