Skip to content

Commit

Permalink
Add Status sub command and small refactor (#1196)
Browse files Browse the repository at this point in the history
  • Loading branch information
reivaj05 committed Jul 6, 2022
1 parent 4938596 commit 8291884
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 47 deletions.
13 changes: 1 addition & 12 deletions kubectl-minio/cmd/tenant-delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package cmd

import (
"context"
"errors"
"fmt"
"io"

Expand Down Expand Up @@ -73,17 +72,7 @@ func newTenantDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}

func (d *tenantDeleteCmd) validate(args []string) error {
if args == nil {
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 --namespace tenant1-ns'")
}
if args[0] == "" {
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])
return validateTenantArgs("delete", args)
}

// run initializes local config and installs MinIO Operator to Kubernetes cluster.
Expand Down
12 changes: 1 addition & 11 deletions kubectl-minio/cmd/tenant-info.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package cmd

import (
"context"
"errors"
"fmt"
"io"
"strconv"
Expand Down Expand Up @@ -69,16 +68,7 @@ func newTenantInfoCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}

func (d *infoCmd) validate(args []string) error {
if args == nil {
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant info tenant1'")
}
if len(args) != 1 {
return errors.New("info command supports a single argument, e.g. 'kubectl minio tenant info tenant1'")
}
if args[0] == "" {
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant info tenant1'")
}
return nil
return validateTenantArgs("info", args)
}

// run initializes local config and installs MinIO Operator to Kubernetes cluster.
Expand Down
13 changes: 1 addition & 12 deletions kubectl-minio/cmd/tenant-report.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"archive/zip"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -70,17 +69,7 @@ func newTenantReportCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}

func (d *reportCmd) validate(args []string) error {
if args == nil {
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant report tenant1'")
}
if len(args) != 1 {
return errors.New("report command supports a single argument, e.g. 'kubectl minio tenant report tenant1'")
}
if args[0] == "" {
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant report tenant1'")
}
// Tenant name should have DNS token restrictions
return helpers.CheckValidTenantName(args[0])
return validateTenantArgs("report", args)
}

// run initializes local config and installs MinIO Operator to Kubernetes cluster.
Expand Down
158 changes: 158 additions & 0 deletions kubectl-minio/cmd/tenant-status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// This file is part of MinIO Operator
// Copyright (C) 2022, MinIO, Inc.
//
// This code is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License, version 3,
// along with this program. If not, see <http://www.gnu.org/licenses/>

package cmd

import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"strings"

"github.com/dustin/go-humanize"
"github.com/minio/kubectl-minio/cmd/helpers"
v2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"sigs.k8s.io/yaml"
)

const (
statusDesc = `'status' command displays tenant status information`
)

type statusCmd struct {
out io.Writer
errOut io.Writer
ns string
yamlOutput bool
jsonOutput bool
}

func newTenantStatusCmd(out io.Writer, errOut io.Writer) *cobra.Command {
c := &statusCmd{out: out, errOut: errOut}

cmd := &cobra.Command{
Use: "status <TENANTNAME>",
Short: "Display tenant status",
Long: statusDesc,
Example: ` kubectl minio status tenant1`,
Args: func(cmd *cobra.Command, args []string) error {
return c.validate(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
err := c.run(args)
if err != nil {
klog.Warning(err)
return err
}
return nil
},
}
cmd = helpers.DisableHelp(cmd)
f := cmd.Flags()
f.StringVarP(&c.ns, "namespace", "n", "", "namespace scope for this request")
f.BoolVarP(&c.yamlOutput, "yaml", "y", false, "yaml output")
f.BoolVarP(&c.jsonOutput, "json", "j", false, "json output")
return cmd
}

func (d *statusCmd) validate(args []string) error {
return validateTenantArgs("status", args)
}

func validateTenantArgs(cmd string, args []string) error {
if args == nil {
return errors.New(fmt.Sprintf("provide the name of the tenant, e.g. 'kubectl minio tenant %s tenant1'", cmd))
}
if len(args) != 1 {
return errors.New(fmt.Sprintf("%s command supports a single argument, e.g. 'kubectl minio %s tenant1'", cmd, cmd))
}
if args[0] == "" {
return errors.New(fmt.Sprintf("provide the name of the tenant, e.g. 'kubectl minio tenant %s tenant1'", cmd))
}
return helpers.CheckValidTenantName(args[0])

}

func (d *statusCmd) run(args []string) error {
oclient, err := helpers.GetKubeOperatorClient()
if err != nil {
return err
}
if d.ns == "" || d.ns == helpers.DefaultNamespace {
d.ns, err = getTenantNamespace(oclient, args[0])
if err != nil {
return err
}
}
tenant, err := oclient.MinioV2().Tenants(d.ns).Get(context.Background(), args[0], metav1.GetOptions{})
if err != nil {
return err
}
return d.printTenantStatus(tenant)
}

func (d *statusCmd) printTenantStatus(tenant *v2.Tenant) error {
if !d.jsonOutput && !d.yamlOutput {
d.printRawTenantStatus(tenant)
return nil
}
if d.jsonOutput && d.yamlOutput {
return fmt.Errorf("Only one output can be used to display status")
}
if d.jsonOutput {
return d.printJSONTenantStatus(tenant)
}
if d.yamlOutput {
return d.printYAMLTenantStatus(tenant)
}
return nil
}

func (d *statusCmd) printRawTenantStatus(tenant *v2.Tenant) {
var s strings.Builder
s.WriteString(Blue("Current status: %s \n", tenant.Status.CurrentState))
s.WriteString(Blue("Available replicas: %d \n", tenant.Status.AvailableReplicas))
s.WriteString(Blue("Pools: %d \n", len(tenant.Status.Pools)))
s.WriteString(Blue("Revision: %d \n", tenant.Status.Revision))
s.WriteString(Blue("Sync version: %s \n", tenant.Status.SyncVersion))
s.WriteString(Blue("Provisioned users: %t \n", tenant.Status.ProvisionedUsers))
s.WriteString(Blue("Write quorum: %d \n", tenant.Status.WriteQuorum))
s.WriteString(Blue("Drives online: %d \n", tenant.Status.DrivesOnline))
s.WriteString(Blue("Drives offline: %d \n", tenant.Status.DrivesOffline))
s.WriteString(Blue("Drives healing: %d \n", tenant.Status.DrivesHealing))
s.WriteString(Blue("Health status: %s \n", tenant.Status.HealthStatus))
s.WriteString(Blue("Usable capacity: %s \n", humanize.IBytes(uint64(tenant.Status.Usage.Capacity))))
fmt.Fprintln(d.out, s.String())
}

func (d *statusCmd) printJSONTenantStatus(tenant *v2.Tenant) error {
enc := json.NewEncoder(d.out)
enc.SetIndent("", " ")
return enc.Encode(tenant.Status)
}

func (d *statusCmd) printYAMLTenantStatus(tenant *v2.Tenant) error {
statusYAML, err := yaml.Marshal(tenant.Status)
if err != nil {
return err
}
fmt.Fprintln(d.out, string(statusYAML))
return nil
}
13 changes: 1 addition & 12 deletions kubectl-minio/cmd/tenant-upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package cmd

import (
"context"
"errors"
"fmt"
"io"
"strings"
Expand Down Expand Up @@ -74,20 +73,10 @@ func newTenantUpgradeCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}

func (u *upgradeCmd) validate(args []string) error {
if args == nil {
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant upgrade tenant1'")
}
if len(args) != 1 {
return errors.New("upgrade command requires a single argument, e.g. 'kubectl minio tenant upgrade tenant1'")
}
if args[0] == "" {
return errors.New("provide the name of the tenant, e.g. 'kubectl minio tenant upgrade tenant1'")
}
if u.tenantOpts.Image == "" {
return fmt.Errorf("provide the --image flag, e.g. 'kubectl minio tenant upgrade tenant1 --image %s'", helpers.DefaultTenantImage)
}
// Tenant name should have DNS token restrictions
return helpers.CheckValidTenantName(args[0])
return validateTenantArgs("upgrade", args)
}

// run initializes local config and installs MinIO Operator to Kubernetes cluster.
Expand Down
1 change: 1 addition & 0 deletions kubectl-minio/cmd/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func newTenantCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd.AddCommand(newTenantUpgradeCmd(cmd.OutOrStdout(), cmd.ErrOrStderr()))
cmd.AddCommand(newTenantDeleteCmd(cmd.OutOrStdout(), cmd.ErrOrStderr()))
cmd.AddCommand(newTenantReportCmd(cmd.OutOrStdout(), cmd.ErrOrStderr()))
cmd.AddCommand(newTenantStatusCmd(cmd.OutOrStdout(), cmd.ErrOrStderr()))

return cmd
}

0 comments on commit 8291884

Please sign in to comment.