Skip to content

Commit

Permalink
cleanup kubectl-minio plugin (#923)
Browse files Browse the repository at this point in the history
  • Loading branch information
harshavardhana authored Dec 8, 2021
1 parent d5fadfe commit 883fd73
Show file tree
Hide file tree
Showing 29 changed files with 205 additions and 681 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ clean:
@rm -rf dist/

regen-crd:
@GO111MODULE=on go install github.com/minio/controller-tools/cmd/controller-gen@v0.4.7
@go install -v github.com/minio/controller-tools/cmd/controller-gen@v0.4.7
@echo "WARNING: installing our fork github.com/minio/controller-tools/cmd/controller-gen@v0.4.7"
@echo "Any other controller-gen will cause the generated CRD to lose the volumeClaimTemplate metadata to be lost"
@controller-gen crd:maxDescLen=0,generateEmbeddedObjectMeta=true paths="./..." output:crd:artifacts:config=$(KUSTOMIZE_CRDS)
Expand Down
14 changes: 4 additions & 10 deletions kubectl-minio/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package cmd

import (
"bufio"
"errors"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -56,18 +55,13 @@ func newDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {

cmd := &cobra.Command{
Use: "delete",
Short: "Delete MinIO Operator",
Short: "Delete MinIO Operator and all MinIO tenants",
Long: deleteDesc,
Example: deleteExample,
PreRunE: func(cmd *cobra.Command, args []string) error {
if !helpers.Ask("Are you sure you want to delete ALL the MinIO Tenants and MinIO Operator?") {
return fmt.Errorf(Bold("Aborting Operator deletion\n"))
}
return nil
},
Args: cobra.MaximumNArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return errors.New("delete command does not accept arguments")
if !helpers.Ask("Are you sure you want to delete ALL the MinIO Tenants and MinIO Operator, this is not a reversible operation") {
return fmt.Errorf(Bold("Aborting Operator deletion"))
}
klog.Info("delete command started")
err := o.run(out)
Expand Down
26 changes: 5 additions & 21 deletions kubectl-minio/cmd/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package helpers
import (
"bytes"
"context"
"fmt"
"io"
"os"
"os/exec"
Expand Down Expand Up @@ -226,26 +225,11 @@ func DisableHelp(cmd *cobra.Command) *cobra.Command {

// Ask user for Y/N input. Return true if response is "y"
func Ask(label string) bool {
validate := func(input string) error {
s := strings.Trim(input, "\n\r")
s = strings.ToLower(s)
if strings.Compare(s, "n") != 0 && strings.Compare(s, "y") != 0 {
return errors.New("Please enter y/n")
}
return nil
}

prompt := promptui.Prompt{
Label: label,
Validate: validate,
}
fmt.Println()
result, err := prompt.Run()
if err != nil {
return false
}
if strings.Compare(result, "n") == 0 {
return false
Label: label,
IsConfirm: true,
Default: "n",
}
return true
_, err := prompt.Run()
return err == nil
}
5 changes: 1 addition & 4 deletions kubectl-minio/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package cmd
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -66,10 +65,8 @@ func newInitCmd(out io.Writer, errOut io.Writer) *cobra.Command {
Short: "Initialize MinIO Operator",
Long: operatorInitDesc,
Example: operatorInitExample,
Args: cobra.MaximumNArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return errors.New("this command does not accept arguments")
}
klog.Info("init command started")
err := o.run(out)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions kubectl-minio/cmd/kubectl-minio.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
)

const (
minioDesc = `Deploy and manage the multi tenant, S3 API compatible object storage on Kubernetes`
minioDesc = `Manage and deploy MinIO object storage tenants on k8s`
kubeconfig = "kubeconfig"
)

Expand All @@ -50,14 +50,14 @@ func init() {

}

// NewCmdMinIO creates a new root command for kubectl-minio
func NewCmdMinIO(streams genericclioptions.IOStreams) *cobra.Command {
// New creates a new root command for kubectl-minio
func New(streams genericclioptions.IOStreams) *cobra.Command {
rootCmd = helpers.DisableHelp(rootCmd)
cobra.EnableCommandSorting = false
rootCmd.AddCommand(newInitCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
rootCmd.AddCommand(newProxyCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
rootCmd.AddCommand(newTenantCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
rootCmd.AddCommand(newDeleteCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
rootCmd.AddCommand(newProxyCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
rootCmd.AddCommand(newVersionCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
return rootCmd
}
4 changes: 1 addition & 3 deletions kubectl-minio/cmd/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ func newProxyCmd(out io.Writer, errOut io.Writer) *cobra.Command {
Short: "Open a port-forward to Console UI",
Long: operatorProxyDesc,
Example: operatorProxyExample,
Args: cobra.MaximumNArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return errors.New("this command does not accept arguments")
}
klog.Info("proxy command started")
err := o.run()
if err != nil {
Expand Down
19 changes: 10 additions & 9 deletions kubectl-minio/cmd/tenant-create.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ func newTenantCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command {
c := &createCmd{out: out, errOut: errOut}

cmd := &cobra.Command{
Use: "create <string> --servers <int> --volumes <int> --capacity <str> --namespace <str>",
Use: "create <TENANTNAME> --servers <NSERVERS> --volumes <NVOLUMES> --capacity <SIZE> --namespace <TENANTNS>",
Short: "Create a MinIO tenant",
Long: createDesc,
Example: createExample,
Args: func(cmd *cobra.Command, args []string) error {
return c.validate(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := c.validate(args); err != nil {
return err
}
klog.Info("create tenant command started")
err := c.run(args)
if err != nil {
Expand All @@ -80,16 +80,17 @@ func newTenantCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command {
f.Int32Var(&c.tenantOpts.Servers, "servers", 0, "total number of pods in MinIO tenant")
f.Int32Var(&c.tenantOpts.Volumes, "volumes", 0, "total number of volumes in the MinIO tenant")
f.StringVar(&c.tenantOpts.Capacity, "capacity", "", "total raw capacity of MinIO tenant in this pool, e.g. 16Ti")
f.StringVarP(&c.tenantOpts.NS, "namespace", "n", helpers.DefaultNamespace, "namespace scope for this request")
f.StringVarP(&c.tenantOpts.NS, "namespace", "n", "", "k8s namespace for this MinIO tenant")
f.StringVarP(&c.tenantOpts.StorageClass, "storage-class", "s", helpers.DefaultStorageclass, "storage class for this MinIO tenant")
f.StringVarP(&c.tenantOpts.Image, "image", "i", helpers.DefaultTenantImage, "MinIO image for this tenant")
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.")
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")
f.BoolVarP(&c.output, "output", "o", false, "dry run this command and generate requisite yaml")
f.StringVarP(&c.tenantOpts.Image, "image", "i", helpers.DefaultTenantImage, "custom MinIO image for this tenant")
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)")
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")
f.BoolVarP(&c.output, "output", "o", false, "generate tenant yaml for 'kubectl apply -f tenant.yaml'")

cmd.MarkFlagRequired("servers")
cmd.MarkFlagRequired("volumes")
cmd.MarkFlagRequired("capacity")
cmd.MarkFlagRequired("namespace")
return cmd
}

Expand Down
32 changes: 15 additions & 17 deletions kubectl-minio/cmd/tenant-delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,19 @@ func newTenantDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
c := &tenantDeleteCmd{out: out, errOut: errOut}

cmd := &cobra.Command{
Use: "delete",
Use: "delete <TENANTNAME> --namespace <TENANTNS>",
Short: "Delete a MinIO tenant",
Long: deleteDesc,
Example: deleteExample,
PreRunE: func(cmd *cobra.Command, args []string) error {
if err := c.validate(args); err != nil {
return err
}
Args: func(cmd *cobra.Command, args []string) error {
return c.validate(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
if !c.force {
if !helpers.Ask(fmt.Sprintf("This will delete the Tenant %s and ALL its data. Do you want to proceed?", args[0])) {
return fmt.Errorf(Bold("Aborting Tenant deletion\n"))
if !helpers.Ask(fmt.Sprintf("This will delete the Tenant %s and ALL its data. Do you want to proceed", args[0])) {
return fmt.Errorf(Bold("Aborting Tenant deletion"))
}
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
klog.Info("delete tenant command started")
err := c.run(args)
if err != nil {
Expand All @@ -72,8 +69,9 @@ func newTenantDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
cmd = helpers.DisableHelp(cmd)
f := cmd.Flags()
f.StringVarP(&c.ns, "namespace", "n", helpers.DefaultNamespace, "namespace scope for this request")
f.StringVarP(&c.ns, "namespace", "n", "", "namespace scope for this request")
f.BoolVarP(&c.force, "force", "f", false, "force delete the tenant")
cmd.MarkFlagRequired("namespace")

return cmd
}
Expand All @@ -83,10 +81,10 @@ func (d *tenantDeleteCmd) validate(args []string) error {
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant delete tenant1'")
}
if len(args) != 1 {
return errors.New("delete command requires specifying the tenant name as an argument, e.g. 'kubectl minio tenant delete tenant1'")
return errors.New("delete command requires specifying the tenant name as an argument, e.g. 'kubectl minio tenant delete tenant1 --namespace tenant1-ns'")
}
if args[0] == "" {
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant delete tenant1'")
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant delete tenant1 --namespace tenant1-ns'")
}
// Tenant name should have DNS token restrictions
return helpers.CheckValidTenantName(args[0])
Expand Down Expand Up @@ -121,24 +119,24 @@ func deleteTenant(client *operatorv1.Clientset, kclient *kubernetes.Clientset, d
return err
}

fmt.Printf("Deleting MinIO Tenant: %s\n", name)
fmt.Println("Deleting MinIO Tenant: ", name)

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

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

if tenant.HasConfigurationSecret() {
kclient.CoreV1().Secrets(d.ns).Delete(context.Background(), tenant.Spec.Configuration.Name,
metav1.DeleteOptions{})
fmt.Printf("Deleting MinIO Tenant Configuration Secret: %s\n", tenant.Spec.Configuration.Name)
fmt.Println("Deleting MinIO Tenant Configuration Secret: ", tenant.Spec.Configuration.Name)
}

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

return nil
Expand Down
22 changes: 8 additions & 14 deletions kubectl-minio/cmd/tenant-expand.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import (
const (
expandDesc = `
'expand' command adds storage capacity to a MinIO tenant`
expandExample = ` kubectl minio tenant expand tenant1 --servers 4 --volumes 32 --capacity 32Ti --namespace tenant1-ns`
expandExample = ` kubectl minio tenant expand tenant1 --servers 4 --volumes 32 --capacity 32Ti`
)

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

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

cmd.MarkFlagRequired("servers")
cmd.MarkFlagRequired("volumes")
Expand Down Expand Up @@ -114,15 +113,10 @@ func (v *expandCmd) run() error {
}

if v.tenantOpts.NS == "" || v.tenantOpts.NS == helpers.DefaultNamespace {
tenants, err := client.MinioV2().Tenants("").List(context.Background(), metav1.ListOptions{})
v.tenantOpts.NS, err = getTenantNamespace(client, v.tenantOpts.Name)
if err != nil {
return err
}
for _, tenant := range tenants.Items {
if tenant.Name == v.tenantOpts.Name {
v.tenantOpts.NS = tenant.ObjectMeta.Namespace
}
}
}

t, err := client.MinioV2().Tenants(v.tenantOpts.NS).Get(context.Background(), v.tenantOpts.Name, metav1.GetOptions{})
Expand Down
22 changes: 9 additions & 13 deletions kubectl-minio/cmd/tenant-info.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ func newTenantInfoCmd(out io.Writer, errOut io.Writer) *cobra.Command {
c := &infoCmd{out: out, errOut: errOut}

cmd := &cobra.Command{
Use: "info",
Short: "List all volumes in existing tenant",
Long: infoDesc,
Use: "info <TENANTNAME>",
Short: "List all volumes in existing tenant",
Long: infoDesc,
Example: ` kubectl minio info tenant1`,
Args: func(cmd *cobra.Command, args []string) error {
return c.validate(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := c.validate(args); err != nil {
return err
}
klog.Info("info tenant command started")
err := c.run(args)
if err != nil {
Expand All @@ -67,7 +68,7 @@ func newTenantInfoCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
cmd = helpers.DisableHelp(cmd)
f := cmd.Flags()
f.StringVarP(&c.ns, "namespace", "n", helpers.DefaultNamespace, "namespace scope for this request")
f.StringVarP(&c.ns, "namespace", "n", "", "namespace scope for this request")
return cmd
}

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

if d.ns == "" || d.ns == helpers.DefaultNamespace {
tenants, err := oclient.MinioV2().Tenants("").List(context.Background(), metav1.ListOptions{})
d.ns, err = getTenantNamespace(oclient, args[0])
if err != nil {
return err
}
for _, tenant := range tenants.Items {
if tenant.Name == args[0] {
d.ns = tenant.ObjectMeta.Namespace
}
}
}

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

0 comments on commit 883fd73

Please sign in to comment.