Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0=
github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ=
github.com/lestrrat-go/jwx v1.2.27 h1:cvnTnda/YzdyFuWdEAMkI6BsLtItSrASEVCI3C/IUEQ=
github.com/lestrrat-go/jwx v1.2.27/go.mod h1:Stob9LjSqR3lOmNdxF0/TvZo60V3hUGv8Fr7Bwzla3k=
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
Expand Down Expand Up @@ -442,7 +438,6 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
Expand Down
6 changes: 5 additions & 1 deletion kubectl-minio/cmd/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,11 @@ func CapacityPerVolume(capacity string, volumes int32) (*resource.Quantity, erro
if err != nil {
return nil, err
}
return resource.NewQuantity(totalQuantity.Value()/int64(volumes), totalQuantity.Format), nil
quantity := resource.NewQuantity(totalQuantity.Value()/int64(volumes), totalQuantity.Format)
if quantity.Sign() <= 0 {
return nil, errors.New("capacity per volume needs to be greater than zero")
}
return quantity, nil
}

// TotalCapacity returns total capacity of a given tenant
Expand Down
33 changes: 26 additions & 7 deletions kubectl-minio/cmd/resources/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package resources

import (
"errors"

"github.com/minio/kubectl-minio/cmd/helpers"
operator "github.com/minio/operator/pkg/apis/minio.min.io"
miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
Expand All @@ -33,6 +32,7 @@ type TenantOptions struct {
ConfigurationSecretName string
Servers int32
Volumes int32
VolumesPerServer int32
Capacity string
NS string
Image string
Expand All @@ -55,22 +55,35 @@ func (t TenantOptions) Validate() error {
if t.Servers <= 0 {
return errors.New("--servers is required. Specify a value greater than or equal to 1")
}
if t.Volumes <= 0 {
return errors.New("--volumes is required. Specify a positive value")
if t.Volumes <= 0 && t.VolumesPerServer <= 0 {
return errors.New("--volumes or --volumes-per-server is required. Specify either with a value greater than or equal to 1")
}
if t.Volumes > 0 && t.VolumesPerServer > 0 {
return errors.New("only either --volumes or --volumes-per-server may be specified")
}
if t.VolumesPerServer > 0 {
t.Volumes = t.VolumesPerServer * t.Servers
}
if t.Capacity == "" {
return errors.New("--capacity flag is required")
}
_, err := resource.ParseQuantity(t.Capacity)
capacity, err := resource.ParseQuantity(t.Capacity)
if err != nil {
if err == resource.ErrFormatWrong {
return errors.New("--capacity flag is incorrectly formatted. Please use suffix like 'T' or 'Ti' only")
return errors.New("--capacity flag is incorrectly formatted. Use a suffix like 'T' or 'Ti' only")
}
return err
}
if capacity.Sign() <= 0 {
return errors.New("--capacity needs to be greater than zero")
}
if t.Volumes%t.Servers != 0 {
return errors.New("--volumes should be a multiple of --servers")
}
_, err = helpers.CapacityPerVolume(t.Capacity, t.Volumes)
if err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -104,7 +117,13 @@ func storageClass(sc string) *string {
// NewTenant will return a new Tenant for a MinIO Operator
func NewTenant(opts *TenantOptions, userSecret *v1.Secret) (*miniov2.Tenant, error) {
autoCert := !opts.DisableTLS
volumesPerServer := helpers.VolumesPerServer(opts.Volumes, opts.Servers)
// Derive Volumes or VolumesPerServer in the absence of the other
// Exclusively either variable is guaranteed to exist
if opts.Volumes == 0 {
opts.Volumes = opts.VolumesPerServer * opts.Servers
} else {
opts.VolumesPerServer = helpers.VolumesPerServer(opts.Volumes, opts.Servers)
}
capacityPerVolume, err := helpers.CapacityPerVolume(opts.Capacity, opts.Volumes)
if err != nil {
return nil, err
Expand All @@ -128,7 +147,7 @@ func NewTenant(opts *TenantOptions, userSecret *v1.Secret) (*miniov2.Tenant, err
Console: opts.ExposeConsoleService,
MinIO: opts.ExposeMinioService,
},
Pools: []miniov2.Pool{Pool(opts, volumesPerServer, *capacityPerVolume)},
Pools: []miniov2.Pool{Pool(opts, opts.VolumesPerServer, *capacityPerVolume)},
RequestAutoCert: &autoCert,
Mountpath: helpers.MinIOMountPath,
KES: tenantKESConfig(opts.Name, opts.KmsSecret, opts.KesImage),
Expand Down
23 changes: 19 additions & 4 deletions kubectl-minio/cmd/tenant-create.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ func newTenantCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command {
c := &createCmd{out: out, errOut: errOut}

cmd := &cobra.Command{
Use: "create <TENANTNAME> --pool <POOLNAME> --servers <NSERVERS> --volumes <NVOLUMES> --capacity <SIZE> --namespace <TENANTNS>",
Use: "create <TENANTNAME> --pool <POOLNAME> --servers <NSERVERS> ( --volumes <NVOLUMES> | --volumes-per-server <NVOLUMESPERSERVER> ) --capacity <SIZE> --namespace <TENANTNS>",
Short: "Create a MinIO tenant",
Long: createDesc,
Example: createExample,
Args: func(cmd *cobra.Command, args []string) error {
// The disable-tls parameter default value is false, we cannot rely on the default value binded to the tenantOpts.DisableTLS variable
// The disable-tls parameter default value is false, we cannot rely on the default value bound to the tenantOpts.DisableTLS variable
// to identify if the parameter --disable-tls was actually set on the command line.
// regardless of which value is being set to the flag, if the flag and ONLY if the flag is present, then we disable TLS
c.tenantOpts.DisableTLS = cmd.Flags().Lookup("disable-tls").Changed
Expand All @@ -80,6 +80,7 @@ func newTenantCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command {
f.StringVarP(&c.tenantOpts.PoolName, "pool", "p", "", "name for this pool")
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.Int32Var(&c.tenantOpts.VolumesPerServer, "volumes-per-server", 0, "number of volumes in each server 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", "", "k8s namespace for this MinIO tenant")
f.StringVarP(&c.tenantOpts.StorageClass, "storage-class", "s", helpers.DefaultStorageclass, "storage class for this MinIO tenant")
Expand Down Expand Up @@ -182,7 +183,11 @@ func (c *createCmd) populateInteractiveTenant() error {
c.tenantOpts.Name = helpers.AskQuestion("Tenant name", helpers.CheckValidTenantName)
c.tenantOpts.ConfigurationSecretName = fmt.Sprintf("%s-env-configuration", c.tenantOpts.Name)
c.tenantOpts.Servers = int32(helpers.AskNumber("Total of servers", greaterThanZero))
c.tenantOpts.Volumes = int32(helpers.AskNumber("Total of volumes", greaterThanZero))
if helpers.Ask("Define 'Total of volumes'") {
c.tenantOpts.Volumes = int32(helpers.AskNumber("Total of volumes", greaterThanZero))
} else {
c.tenantOpts.VolumesPerServer = int32(helpers.AskNumber("Volumes per server", greaterThanZero))
}
c.tenantOpts.NS = helpers.AskQuestion("Namespace", validateEmptyInput)
c.tenantOpts.Capacity = helpers.AskQuestion("Capacity", validateCapacity)
if err := c.tenantOpts.Validate(); err != nil {
Expand All @@ -192,6 +197,7 @@ func (c *createCmd) populateInteractiveTenant() error {
c.tenantOpts.ExposeMinioService = helpers.Ask("Expose Minio Service")
c.tenantOpts.ExposeConsoleService = helpers.Ask("Expose Console Service")
c.tenantOpts.EnableSFTP = helpers.Ask("Enable SFTP")
c.tenantOpts.DisableAntiAffinity = helpers.Ask("Disable Anti-Affinity (unsupported in production environment)")
return nil
}

Expand All @@ -206,7 +212,16 @@ func validateCapacity(value string) error {
if err := validateEmptyInput(value); err != nil {
return err
}
_, err := resource.ParseQuantity(value)
capacity, err := resource.ParseQuantity(value)
if err != nil {
if err == resource.ErrFormatWrong {
return errors.New("capacity flag is incorrectly formatted. Use a suffix like 'T' or 'Ti' only")
}
return err
}
if capacity.Sign() <= 0 {
return errors.New("capacity needs to be greater than zero")
}
return err
}

Expand Down
18 changes: 12 additions & 6 deletions kubectl-minio/cmd/tenant-expand.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ import (
"encoding/json"
"errors"
"fmt"
"io"

"github.com/minio/kubectl-minio/cmd/helpers"
"github.com/minio/kubectl-minio/cmd/resources"
"io"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -51,7 +50,7 @@ func newTenantExpandCmd(out io.Writer, errOut io.Writer) *cobra.Command {
v := &expandCmd{out: out, errOut: errOut}

cmd := &cobra.Command{
Use: "expand <TENANTNAME> --pool <POOLNAME> --servers <NSERVERS> --volumes <NVOLUMES> --capacity <SIZE> --namespace <TENANTNS>",
Use: "expand <TENANTNAME> --pool <POOLNAME> --servers <NSERVERS> ( --volumes <NVOLUMES> | --volumes-per-server <NVOLUMESPERSERVER> ) --capacity <SIZE> --namespace <TENANTNS>",
Short: "Add capacity to existing tenant",
Long: expandDesc,
Example: expandExample,
Expand All @@ -73,12 +72,13 @@ func newTenantExpandCmd(out io.Writer, errOut io.Writer) *cobra.Command {
f.StringVarP(&v.tenantOpts.PoolName, "pool", "p", "", "name for this pool expansion")
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.Int32Var(&v.tenantOpts.VolumesPerServer, "volumes-per-server", 0, "number of volumes in each server in the MinIO tenant")
f.StringVar(&v.tenantOpts.Capacity, "capacity", "", "total raw capacity to add to tenant, e.g. 16Ti")
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.BoolVar(&v.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.BoolVarP(&v.output, "output", "o", false, "generate MinIO tenant yaml with expansion details")

cmd.MarkFlagRequired("servers")
cmd.MarkFlagRequired("volumes")
cmd.MarkFlagRequired("capacity")
return cmd
}
Expand Down Expand Up @@ -123,7 +123,13 @@ func (v *expandCmd) run() error {
return err
}
currentCapacity := helpers.TotalCapacity(*t)
volumesPerServer := helpers.VolumesPerServer(v.tenantOpts.Volumes, v.tenantOpts.Servers)
// Derive Volumes or VolumesPerServer in the absence of the other
// Exclusively either variable is guaranteed to exist
if v.tenantOpts.Volumes == 0 {
v.tenantOpts.Volumes = v.tenantOpts.VolumesPerServer * v.tenantOpts.Servers
} else {
v.tenantOpts.VolumesPerServer = helpers.VolumesPerServer(v.tenantOpts.Volumes, v.tenantOpts.Servers)
}
capacityPerVolume, err := helpers.CapacityPerVolume(v.tenantOpts.Capacity, v.tenantOpts.Volumes)
if err != nil {
return err
Expand All @@ -134,7 +140,7 @@ func (v *expandCmd) run() error {
v.tenantOpts.PoolName = resources.GeneratePoolName(len(t.Spec.Pools))
}

t.Spec.Pools = append(t.Spec.Pools, resources.Pool(&v.tenantOpts, volumesPerServer, *capacityPerVolume))
t.Spec.Pools = append(t.Spec.Pools, resources.Pool(&v.tenantOpts, v.tenantOpts.VolumesPerServer, *capacityPerVolume))
expandedCapacity := helpers.TotalCapacity(*t)
if !v.output {
fmt.Printf(Bold(fmt.Sprintf("\nExpanding Tenant '%s/%s' from %s to %s\n\n", t.ObjectMeta.Name, t.ObjectMeta.Namespace, currentCapacity, expandedCapacity)))
Expand Down
4 changes: 3 additions & 1 deletion kubectl-minio/cmd/tenant-info.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,15 @@ func printTenantInfo(tenant miniov2.Tenant) {
}

t := helpers.GetTable()
t.SetHeader([]string{"Pool", "Servers", "Volumes(server)", "Capacity(volume)"})
t.SetHeader([]string{"Pool", "Servers", "Volumes per server", "Volumes", "Capacity per volume", "Capacity"})
for i, z := range tenant.Spec.Pools {
t.Append([]string{
strconv.Itoa(i),
strconv.Itoa(int(z.Servers)),
strconv.Itoa(int(z.VolumesPerServer)),
strconv.Itoa(int(z.VolumesPerServer) * int(z.Servers)),
humanize.IBytes(uint64(z.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value())),
humanize.IBytes(uint64(z.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value()) * uint64(z.VolumesPerServer) * uint64(z.Servers)),
})
}
t.Render()
Expand Down
3 changes: 0 additions & 3 deletions kubectl-minio/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ require (
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
Expand All @@ -55,8 +54,6 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/lestrrat-go/jwx v1.2.27 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect
github.com/mailru/easyjson v0.7.7 // indirect
Expand Down
Loading