Skip to content

Commit 883fd73

Browse files
cleanup kubectl-minio plugin (#923)
1 parent d5fadfe commit 883fd73

29 files changed

+205
-681
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ clean:
5656
@rm -rf dist/
5757

5858
regen-crd:
59-
@GO111MODULE=on go install github.com/minio/controller-tools/cmd/[email protected]
59+
@go install -v github.com/minio/controller-tools/cmd/[email protected]
6060
@echo "WARNING: installing our fork github.com/minio/controller-tools/cmd/[email protected]"
6161
@echo "Any other controller-gen will cause the generated CRD to lose the volumeClaimTemplate metadata to be lost"
6262
@controller-gen crd:maxDescLen=0,generateEmbeddedObjectMeta=true paths="./..." output:crd:artifacts:config=$(KUSTOMIZE_CRDS)

kubectl-minio/cmd/delete.go

+4-10
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package cmd
2020

2121
import (
2222
"bufio"
23-
"errors"
2423
"fmt"
2524
"io"
2625
"os"
@@ -56,18 +55,13 @@ func newDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
5655

5756
cmd := &cobra.Command{
5857
Use: "delete",
59-
Short: "Delete MinIO Operator",
58+
Short: "Delete MinIO Operator and all MinIO tenants",
6059
Long: deleteDesc,
6160
Example: deleteExample,
62-
PreRunE: func(cmd *cobra.Command, args []string) error {
63-
if !helpers.Ask("Are you sure you want to delete ALL the MinIO Tenants and MinIO Operator?") {
64-
return fmt.Errorf(Bold("Aborting Operator deletion\n"))
65-
}
66-
return nil
67-
},
61+
Args: cobra.MaximumNArgs(0),
6862
RunE: func(cmd *cobra.Command, args []string) error {
69-
if len(args) != 0 {
70-
return errors.New("delete command does not accept arguments")
63+
if !helpers.Ask("Are you sure you want to delete ALL the MinIO Tenants and MinIO Operator, this is not a reversible operation") {
64+
return fmt.Errorf(Bold("Aborting Operator deletion"))
7165
}
7266
klog.Info("delete command started")
7367
err := o.run(out)

kubectl-minio/cmd/helpers/helpers.go

+5-21
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ package helpers
2121
import (
2222
"bytes"
2323
"context"
24-
"fmt"
2524
"io"
2625
"os"
2726
"os/exec"
@@ -226,26 +225,11 @@ func DisableHelp(cmd *cobra.Command) *cobra.Command {
226225

227226
// Ask user for Y/N input. Return true if response is "y"
228227
func Ask(label string) bool {
229-
validate := func(input string) error {
230-
s := strings.Trim(input, "\n\r")
231-
s = strings.ToLower(s)
232-
if strings.Compare(s, "n") != 0 && strings.Compare(s, "y") != 0 {
233-
return errors.New("Please enter y/n")
234-
}
235-
return nil
236-
}
237-
238228
prompt := promptui.Prompt{
239-
Label: label,
240-
Validate: validate,
241-
}
242-
fmt.Println()
243-
result, err := prompt.Run()
244-
if err != nil {
245-
return false
246-
}
247-
if strings.Compare(result, "n") == 0 {
248-
return false
229+
Label: label,
230+
IsConfirm: true,
231+
Default: "n",
249232
}
250-
return true
233+
_, err := prompt.Run()
234+
return err == nil
251235
}

kubectl-minio/cmd/init.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ package cmd
2121
import (
2222
"bufio"
2323
"encoding/json"
24-
"errors"
2524
"fmt"
2625
"io"
2726
"os"
@@ -66,10 +65,8 @@ func newInitCmd(out io.Writer, errOut io.Writer) *cobra.Command {
6665
Short: "Initialize MinIO Operator",
6766
Long: operatorInitDesc,
6867
Example: operatorInitExample,
68+
Args: cobra.MaximumNArgs(0),
6969
RunE: func(cmd *cobra.Command, args []string) error {
70-
if len(args) != 0 {
71-
return errors.New("this command does not accept arguments")
72-
}
7370
klog.Info("init command started")
7471
err := o.run(out)
7572
if err != nil {

kubectl-minio/cmd/kubectl-minio.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232
)
3333

3434
const (
35-
minioDesc = `Deploy and manage the multi tenant, S3 API compatible object storage on Kubernetes`
35+
minioDesc = `Manage and deploy MinIO object storage tenants on k8s`
3636
kubeconfig = "kubeconfig"
3737
)
3838

@@ -50,14 +50,14 @@ func init() {
5050

5151
}
5252

53-
// NewCmdMinIO creates a new root command for kubectl-minio
54-
func NewCmdMinIO(streams genericclioptions.IOStreams) *cobra.Command {
53+
// New creates a new root command for kubectl-minio
54+
func New(streams genericclioptions.IOStreams) *cobra.Command {
5555
rootCmd = helpers.DisableHelp(rootCmd)
5656
cobra.EnableCommandSorting = false
5757
rootCmd.AddCommand(newInitCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
58+
rootCmd.AddCommand(newProxyCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
5859
rootCmd.AddCommand(newTenantCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
5960
rootCmd.AddCommand(newDeleteCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
60-
rootCmd.AddCommand(newProxyCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
6161
rootCmd.AddCommand(newVersionCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
6262
return rootCmd
6363
}

kubectl-minio/cmd/proxy.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,8 @@ func newProxyCmd(out io.Writer, errOut io.Writer) *cobra.Command {
5757
Short: "Open a port-forward to Console UI",
5858
Long: operatorProxyDesc,
5959
Example: operatorProxyExample,
60+
Args: cobra.MaximumNArgs(0),
6061
RunE: func(cmd *cobra.Command, args []string) error {
61-
if len(args) != 0 {
62-
return errors.New("this command does not accept arguments")
63-
}
6462
klog.Info("proxy command started")
6563
err := o.run()
6664
if err != nil {

kubectl-minio/cmd/tenant-create.go

+10-9
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ func newTenantCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command {
5858
c := &createCmd{out: out, errOut: errOut}
5959

6060
cmd := &cobra.Command{
61-
Use: "create <string> --servers <int> --volumes <int> --capacity <str> --namespace <str>",
61+
Use: "create <TENANTNAME> --servers <NSERVERS> --volumes <NVOLUMES> --capacity <SIZE> --namespace <TENANTNS>",
6262
Short: "Create a MinIO tenant",
6363
Long: createDesc,
6464
Example: createExample,
65+
Args: func(cmd *cobra.Command, args []string) error {
66+
return c.validate(args)
67+
},
6568
RunE: func(cmd *cobra.Command, args []string) error {
66-
if err := c.validate(args); err != nil {
67-
return err
68-
}
6969
klog.Info("create tenant command started")
7070
err := c.run(args)
7171
if err != nil {
@@ -80,16 +80,17 @@ func newTenantCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command {
8080
f.Int32Var(&c.tenantOpts.Servers, "servers", 0, "total number of pods in MinIO tenant")
8181
f.Int32Var(&c.tenantOpts.Volumes, "volumes", 0, "total number of volumes in the MinIO tenant")
8282
f.StringVar(&c.tenantOpts.Capacity, "capacity", "", "total raw capacity of MinIO tenant in this pool, e.g. 16Ti")
83-
f.StringVarP(&c.tenantOpts.NS, "namespace", "n", helpers.DefaultNamespace, "namespace scope for this request")
83+
f.StringVarP(&c.tenantOpts.NS, "namespace", "n", "", "k8s namespace for this MinIO tenant")
8484
f.StringVarP(&c.tenantOpts.StorageClass, "storage-class", "s", helpers.DefaultStorageclass, "storage class for this MinIO tenant")
85-
f.StringVarP(&c.tenantOpts.Image, "image", "i", helpers.DefaultTenantImage, "MinIO image for this tenant")
86-
f.BoolVar(&c.tenantOpts.DisableAntiAffinity, "enable-host-sharing", false, "disable anti-affinity to allow pods to be co-located on a single node. Not recommended for production.")
87-
f.StringVar(&c.tenantOpts.KmsSecret, "kes-config", "", "name of secret with details for enabling encryption, refer example https://github.com/minio/operator/blob/master/examples/kes-secret.yaml")
88-
f.BoolVarP(&c.output, "output", "o", false, "dry run this command and generate requisite yaml")
85+
f.StringVarP(&c.tenantOpts.Image, "image", "i", helpers.DefaultTenantImage, "custom MinIO image for this tenant")
86+
f.BoolVar(&c.tenantOpts.DisableAntiAffinity, "enable-host-sharing", false, "[TESTING-ONLY] disable anti-affinity to allow pods to be co-located on a single node (unsupported in production environment)")
87+
f.StringVar(&c.tenantOpts.KmsSecret, "kes-config", "", "name of secret for KES KMS setup, refer https://github.com/minio/operator/blob/master/examples/kes-secret.yaml")
88+
f.BoolVarP(&c.output, "output", "o", false, "generate tenant yaml for 'kubectl apply -f tenant.yaml'")
8989

9090
cmd.MarkFlagRequired("servers")
9191
cmd.MarkFlagRequired("volumes")
9292
cmd.MarkFlagRequired("capacity")
93+
cmd.MarkFlagRequired("namespace")
9394
return cmd
9495
}
9596

kubectl-minio/cmd/tenant-delete.go

+15-17
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,19 @@ func newTenantDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
4545
c := &tenantDeleteCmd{out: out, errOut: errOut}
4646

4747
cmd := &cobra.Command{
48-
Use: "delete",
48+
Use: "delete <TENANTNAME> --namespace <TENANTNS>",
4949
Short: "Delete a MinIO tenant",
5050
Long: deleteDesc,
5151
Example: deleteExample,
52-
PreRunE: func(cmd *cobra.Command, args []string) error {
53-
if err := c.validate(args); err != nil {
54-
return err
55-
}
52+
Args: func(cmd *cobra.Command, args []string) error {
53+
return c.validate(args)
54+
},
55+
RunE: func(cmd *cobra.Command, args []string) error {
5656
if !c.force {
57-
if !helpers.Ask(fmt.Sprintf("This will delete the Tenant %s and ALL its data. Do you want to proceed?", args[0])) {
58-
return fmt.Errorf(Bold("Aborting Tenant deletion\n"))
57+
if !helpers.Ask(fmt.Sprintf("This will delete the Tenant %s and ALL its data. Do you want to proceed", args[0])) {
58+
return fmt.Errorf(Bold("Aborting Tenant deletion"))
5959
}
6060
}
61-
return nil
62-
},
63-
RunE: func(cmd *cobra.Command, args []string) error {
6461
klog.Info("delete tenant command started")
6562
err := c.run(args)
6663
if err != nil {
@@ -72,8 +69,9 @@ func newTenantDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
7269
}
7370
cmd = helpers.DisableHelp(cmd)
7471
f := cmd.Flags()
75-
f.StringVarP(&c.ns, "namespace", "n", helpers.DefaultNamespace, "namespace scope for this request")
72+
f.StringVarP(&c.ns, "namespace", "n", "", "namespace scope for this request")
7673
f.BoolVarP(&c.force, "force", "f", false, "force delete the tenant")
74+
cmd.MarkFlagRequired("namespace")
7775

7876
return cmd
7977
}
@@ -83,10 +81,10 @@ func (d *tenantDeleteCmd) validate(args []string) error {
8381
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant delete tenant1'")
8482
}
8583
if len(args) != 1 {
86-
return errors.New("delete command requires specifying the tenant name as an argument, e.g. 'kubectl minio tenant delete tenant1'")
84+
return errors.New("delete command requires specifying the tenant name as an argument, e.g. 'kubectl minio tenant delete tenant1 --namespace tenant1-ns'")
8785
}
8886
if args[0] == "" {
89-
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant delete tenant1'")
87+
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant delete tenant1 --namespace tenant1-ns'")
9088
}
9189
// Tenant name should have DNS token restrictions
9290
return helpers.CheckValidTenantName(args[0])
@@ -121,24 +119,24 @@ func deleteTenant(client *operatorv1.Clientset, kclient *kubernetes.Clientset, d
121119
return err
122120
}
123121

124-
fmt.Printf("Deleting MinIO Tenant: %s\n", name)
122+
fmt.Println("Deleting MinIO Tenant: ", name)
125123

126124
// Delete credentials secret, ignore any errors.
127125
kclient.CoreV1().Secrets(d.ns).Delete(context.Background(), tenant.Spec.CredsSecret.Name,
128126
metav1.DeleteOptions{})
129127

130-
fmt.Printf("Deleting MinIO Tenant Credentials Secret: %s\n", tenant.Spec.CredsSecret.Name)
128+
fmt.Println("Deleting MinIO Tenant Credentials Secret: ", tenant.Spec.CredsSecret.Name)
131129

132130
if tenant.HasConfigurationSecret() {
133131
kclient.CoreV1().Secrets(d.ns).Delete(context.Background(), tenant.Spec.Configuration.Name,
134132
metav1.DeleteOptions{})
135-
fmt.Printf("Deleting MinIO Tenant Configuration Secret: %s\n", tenant.Spec.Configuration.Name)
133+
fmt.Println("Deleting MinIO Tenant Configuration Secret: ", tenant.Spec.Configuration.Name)
136134
}
137135

138136
// Delete all users, ignore any errors.
139137
for _, user := range tenant.Spec.Users {
140138
kclient.CoreV1().Secrets(d.ns).Delete(context.Background(), user.Name, metav1.DeleteOptions{})
141-
fmt.Printf("Deleting MinIO Tenant user: %s\n", user.Name)
139+
fmt.Println("Deleting MinIO Tenant user: ", user.Name)
142140
}
143141

144142
return nil

kubectl-minio/cmd/tenant-expand.go

+8-14
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import (
4040
const (
4141
expandDesc = `
4242
'expand' command adds storage capacity to a MinIO tenant`
43-
expandExample = ` kubectl minio tenant expand tenant1 --servers 4 --volumes 32 --capacity 32Ti --namespace tenant1-ns`
43+
expandExample = ` kubectl minio tenant expand tenant1 --servers 4 --volumes 32 --capacity 32Ti`
4444
)
4545

4646
type expandCmd struct {
@@ -54,14 +54,14 @@ func newTenantExpandCmd(out io.Writer, errOut io.Writer) *cobra.Command {
5454
v := &expandCmd{out: out, errOut: errOut}
5555

5656
cmd := &cobra.Command{
57-
Use: "expand <string> --servers <int> --volumes <int> --capacity <str> --namespace <str>",
57+
Use: "expand <TENANTNAME> --servers <NSERVERS> --volumes <NVOLUMES> --capacity <SIZE>",
5858
Short: "Add capacity to existing tenant",
5959
Long: expandDesc,
6060
Example: expandExample,
61+
Args: func(cmd *cobra.Command, args []string) error {
62+
return v.validate(args)
63+
},
6164
RunE: func(cmd *cobra.Command, args []string) error {
62-
if err := v.validate(args); err != nil {
63-
return err
64-
}
6565
klog.Info("expand tenant command started")
6666
err := v.run()
6767
if err != nil {
@@ -76,9 +76,8 @@ func newTenantExpandCmd(out io.Writer, errOut io.Writer) *cobra.Command {
7676
f.Int32Var(&v.tenantOpts.Servers, "servers", 0, "total number of pods to add to tenant")
7777
f.Int32Var(&v.tenantOpts.Volumes, "volumes", 0, "total number of volumes to add to tenant")
7878
f.StringVar(&v.tenantOpts.Capacity, "capacity", "", "total raw capacity to add to tenant, e.g. 16Ti")
79-
f.StringVarP(&v.tenantOpts.NS, "namespace", "n", helpers.DefaultNamespace, "namespace scope for this request")
80-
f.StringVarP(&v.tenantOpts.StorageClass, "storage-class", "s", helpers.DefaultStorageclass, "storage class for this MinIO tenant")
81-
f.BoolVarP(&v.output, "output", "o", false, "dry run this command and generate requisite yaml")
79+
f.StringVarP(&v.tenantOpts.StorageClass, "storage-class", "s", helpers.DefaultStorageclass, "storage class for the expanded MinIO tenant pool (can be different than original pool)")
80+
f.BoolVarP(&v.output, "output", "o", false, "generate MinIO tenant yaml with expansion details")
8281

8382
cmd.MarkFlagRequired("servers")
8483
cmd.MarkFlagRequired("volumes")
@@ -114,15 +113,10 @@ func (v *expandCmd) run() error {
114113
}
115114

116115
if v.tenantOpts.NS == "" || v.tenantOpts.NS == helpers.DefaultNamespace {
117-
tenants, err := client.MinioV2().Tenants("").List(context.Background(), metav1.ListOptions{})
116+
v.tenantOpts.NS, err = getTenantNamespace(client, v.tenantOpts.Name)
118117
if err != nil {
119118
return err
120119
}
121-
for _, tenant := range tenants.Items {
122-
if tenant.Name == v.tenantOpts.Name {
123-
v.tenantOpts.NS = tenant.ObjectMeta.Namespace
124-
}
125-
}
126120
}
127121

128122
t, err := client.MinioV2().Tenants(v.tenantOpts.NS).Get(context.Background(), v.tenantOpts.Name, metav1.GetOptions{})

kubectl-minio/cmd/tenant-info.go

+9-13
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,14 @@ func newTenantInfoCmd(out io.Writer, errOut io.Writer) *cobra.Command {
4949
c := &infoCmd{out: out, errOut: errOut}
5050

5151
cmd := &cobra.Command{
52-
Use: "info",
53-
Short: "List all volumes in existing tenant",
54-
Long: infoDesc,
52+
Use: "info <TENANTNAME>",
53+
Short: "List all volumes in existing tenant",
54+
Long: infoDesc,
55+
Example: ` kubectl minio info tenant1`,
56+
Args: func(cmd *cobra.Command, args []string) error {
57+
return c.validate(args)
58+
},
5559
RunE: func(cmd *cobra.Command, args []string) error {
56-
if err := c.validate(args); err != nil {
57-
return err
58-
}
5960
klog.Info("info tenant command started")
6061
err := c.run(args)
6162
if err != nil {
@@ -67,7 +68,7 @@ func newTenantInfoCmd(out io.Writer, errOut io.Writer) *cobra.Command {
6768
}
6869
cmd = helpers.DisableHelp(cmd)
6970
f := cmd.Flags()
70-
f.StringVarP(&c.ns, "namespace", "n", helpers.DefaultNamespace, "namespace scope for this request")
71+
f.StringVarP(&c.ns, "namespace", "n", "", "namespace scope for this request")
7172
return cmd
7273
}
7374

@@ -93,15 +94,10 @@ func (d *infoCmd) run(args []string) error {
9394
}
9495

9596
if d.ns == "" || d.ns == helpers.DefaultNamespace {
96-
tenants, err := oclient.MinioV2().Tenants("").List(context.Background(), metav1.ListOptions{})
97+
d.ns, err = getTenantNamespace(oclient, args[0])
9798
if err != nil {
9899
return err
99100
}
100-
for _, tenant := range tenants.Items {
101-
if tenant.Name == args[0] {
102-
d.ns = tenant.ObjectMeta.Namespace
103-
}
104-
}
105101
}
106102

107103
tenant, err := oclient.MinioV2().Tenants(d.ns).Get(context.Background(), args[0], metav1.GetOptions{})

0 commit comments

Comments
 (0)