diff --git a/cmd/climc/shell/k8s/clusters.go b/cmd/climc/shell/k8s/clusters.go index 6ae9d42437..23dfecbadc 100644 --- a/cmd/climc/shell/k8s/clusters.go +++ b/cmd/climc/shell/k8s/clusters.go @@ -205,4 +205,70 @@ func initKubeCluster() { printObject(ret) return nil }) + + R(&o.IdentOptions{}, cmdN("components-status"), "Get cluster component status", func(s *mcclient.ClientSession, args *o.IdentOptions) error { + ret, err := k8s.KubeClusters.GetSpecific(s, args.ID, "components-status", nil) + if err != nil { + return err + } + printObject(ret) + return nil + }) + + R(&o.ClusterComponentTypeOptions{}, cmdN("component-setting"), "Get cluster component setting", func(s *mcclient.ClientSession, args *o.ClusterComponentTypeOptions) error { + q := jsonutils.NewDict() + q.Add(jsonutils.NewString(args.TYPE), "type") + ret, err := k8s.KubeClusters.GetSpecific(s, args.ID, "component-setting", q) + if err != nil { + return err + } + printObject(ret) + return nil + }) + + R(&o.ClusterEnableComponentCephCSIOpt{}, cmdN("component-enable-ceph-csi"), "Enable cluster component", func(s *mcclient.ClientSession, args *o.ClusterEnableComponentCephCSIOpt) error { + params, err := args.Params() + if err != nil { + return err + } + ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "enable-component", params) + if err != nil { + return err + } + printObject(ret) + return nil + }) + + R(&o.ClusterDisableComponent{}, cmdN("component-disable"), "Enable cluster component", func(s *mcclient.ClientSession, args *o.ClusterDisableComponent) error { + params := args.Params() + ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "disable-component", params) + if err != nil { + return err + } + printObject(ret) + return nil + }) + + R(&o.ClusterDisableComponent{}, cmdN("component-delete"), "Delete cluster component", func(s *mcclient.ClientSession, args *o.ClusterDisableComponent) error { + params := args.Params() + ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "delete-component", params) + if err != nil { + return err + } + printObject(ret) + return nil + }) + + R(&o.ClusterUpdateComponentCephCSIOpt{}, cmdN("component-update-ceph-csi"), "Update cluster component", func(s *mcclient.ClientSession, args *o.ClusterUpdateComponentCephCSIOpt) error { + params, err := args.Params() + if err != nil { + return err + } + ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "update-component", params) + if err != nil { + return err + } + printObject(ret) + return nil + }) } diff --git a/cmd/climc/shell/k8s/secret.go b/cmd/climc/shell/k8s/secret.go index c56f67375d..a0d95e31fe 100644 --- a/cmd/climc/shell/k8s/secret.go +++ b/cmd/climc/shell/k8s/secret.go @@ -58,4 +58,23 @@ func initSecret() { return nil }) registryCmd.AddR(createCmd) + + cephCSICmd := NewCmdNameFactory("secret-ceph-csi") + cephCSICreateCmd := NewCommand( + &o.CephCSISecretCreateOptions{}, + cephCSICmd.Do("create"), + "Create ceph csi user secret", + func(s *mcclient.ClientSession, args *o.CephCSISecretCreateOptions) error { + params, err := args.Params() + if err != nil { + return err + } + ret, err := k8s.Secrets.Create(s, params) + if err != nil { + return err + } + printObject(ret) + return nil + }) + secretCmd.AddR(cephCSICreateCmd) } diff --git a/cmd/climc/shell/k8s/storageclass.go b/cmd/climc/shell/k8s/storageclass.go index 2c418806b1..e8c65b90e6 100644 --- a/cmd/climc/shell/k8s/storageclass.go +++ b/cmd/climc/shell/k8s/storageclass.go @@ -15,9 +15,70 @@ package k8s import ( + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules/k8s" + o "yunion.io/x/onecloud/pkg/mcclient/options/k8s" ) func initStorageClass() { - initK8sClusterResource("storageclass", k8s.Storageclass) + cmdN := NewCmdNameFactory("storageclass") + scCmd := initK8sClusterResource("storageclass", k8s.Storageclass) + + setDefaultCmd := NewCommand( + &o.ClusterResourceBaseOptions{}, + cmdN.Do("set-default"), + "Set storageclass as default", + func(s *mcclient.ClientSession, args *o.ClusterResourceBaseOptions) error { + ret, err := k8s.Storageclass.PerformAction(s, args.NAME, "set-default", args.Params()) + if err != nil { + return err + } + printObject(ret) + return nil + }, + ) + + scCmd.AddR(setDefaultCmd) + + addStorageClassCephCSI(scCmd) +} + +func addStorageClassCephCSI(cmd *ShellCommands) { + rbdN := NewCmdNameFactory("storageclass-ceph-csi-rbd") + rbdCreateCmd := NewCommand( + &o.StorageClassCephCSIRBDCreateOptions{}, + rbdN.Do("create"), + "Create ceph csi rbd", + func(s *mcclient.ClientSession, args *o.StorageClassCephCSIRBDCreateOptions) error { + params, err := args.Params() + if err != nil { + return err + } + ret, err := k8s.Storageclass.Create(s, params) + if err != nil { + return err + } + printObject(ret) + return nil + }, + ) + testConnCmd := NewCommand( + &o.StorageClassCephCSIRBDTestOptions{}, + rbdN.Do("connection-test"), + "Test storageclass connection", + func(s *mcclient.ClientSession, args *o.StorageClassCephCSIRBDTestOptions) error { + params, err := args.Params() + if err != nil { + return err + } + ret, err := k8s.Storageclass.PerformClassAction(s, "connection-test", params) + if err != nil { + return err + } + printObject(ret) + return nil + }, + ) + + cmd.AddR(rbdCreateCmd, testConnCmd) } diff --git a/pkg/mcclient/modules/k8s/storageclass.go b/pkg/mcclient/modules/k8s/storageclass.go index cecaf976b2..b2ed8b7831 100644 --- a/pkg/mcclient/modules/k8s/storageclass.go +++ b/pkg/mcclient/modules/k8s/storageclass.go @@ -28,7 +28,7 @@ type StorageclassManager struct { func init() { Storageclass = &StorageclassManager{ - MetaResourceManager: NewMetaResourceManager("storageclass", "storageclasses", NewColumns("Provisioner"), NewColumns()), + MetaResourceManager: NewMetaResourceManager("storageclass", "storageclasses", NewColumns("Provisioner", "IsDefault"), NewColumns()), } modules.Register(Storageclass) @@ -38,3 +38,8 @@ func (m StorageclassManager) GetProvisioner(obj jsonutils.JSONObject) interface{ provisioner, _ := obj.GetString("provisioner") return provisioner } + +func (m StorageclassManager) GetIsDefault(obj jsonutils.JSONObject) interface{} { + isDefault, _ := obj.Bool("isDefault") + return isDefault +} diff --git a/pkg/mcclient/options/k8s/base.go b/pkg/mcclient/options/k8s/base.go index 4b7cde4576..079fb20ea2 100644 --- a/pkg/mcclient/options/k8s/base.go +++ b/pkg/mcclient/options/k8s/base.go @@ -28,6 +28,21 @@ func (o ClusterBaseOptions) Params() *jsonutils.JSONDict { return ret } +type ClusterResourceBaseOptions struct { + ClusterBaseOptions + NAME string `help:"Name of resource"` +} + +type ClusterResourceCreateOptions struct { + ClusterResourceBaseOptions +} + +func (o ClusterResourceCreateOptions) Params() *jsonutils.JSONDict { + params := o.ClusterBaseOptions.Params() + params.Add(jsonutils.NewString(o.NAME), "name") + return params +} + type BaseListOptions struct { Limit int `default:"20" help:"Page limit"` Offset int `default:"0" help:"Page offset"` diff --git a/pkg/mcclient/options/k8s/cluster.go b/pkg/mcclient/options/k8s/cluster.go index fef26570e6..bd9bc2d920 100644 --- a/pkg/mcclient/options/k8s/cluster.go +++ b/pkg/mcclient/options/k8s/cluster.go @@ -235,3 +235,78 @@ func (o KubeClusterDeleteMachinesOptions) Params() (*jsonutils.JSONDict, error) params.Add(machinesArray, "machines") return params, nil } + +type ClusterComponentOptions struct { + IdentOptions +} + +func (o ClusterComponentOptions) Params(typ string) *jsonutils.JSONDict { + params := jsonutils.NewDict() + params.Add(jsonutils.NewString(typ), "type") + return params +} + +type ClusterComponentTypeOptions struct { + IdentOptions + TYPE string `help:"component type"` +} + +type ClusterEnableComponentCephCSIOpt struct { + ClusterComponentOptions + ClusterId string `help:"Ceph cluster id"` + Monitor []string `help:"Ceph monitor, format is 'ip:port'"` +} + +func (o ClusterEnableComponentCephCSIOpt) Params() (*jsonutils.JSONDict, error) { + params := o.ClusterComponentOptions.Params("cephCSI") + conf := jsonutils.NewDict() + clusterConfs := jsonutils.NewArray() + clusterConf := jsonutils.NewDict() + clusterConf.Add(jsonutils.NewString(o.ClusterId), "clusterId") + mons := jsonutils.NewArray() + for _, m := range o.Monitor { + mons.Add(jsonutils.NewString(m)) + } + clusterConf.Add(mons, "monitors") + clusterConfs.Add(clusterConf) + conf.Add(clusterConfs, "config") + params.Add(conf, "cephCSI") + return params, nil +} + +type ClusterDisableComponent struct { + ClusterComponentOptions + TYPE string `help:"component type"` +} + +func (o ClusterDisableComponent) Params() *jsonutils.JSONDict { + p := o.ClusterComponentOptions.Params(o.TYPE) + return p +} + +type ClusterUpdateComponentCephCSIOpt struct { + ClusterComponentOptions + ClusterId string `help:"Ceph cluster id"` + Monitor []string `help:"Ceph monitor, format is 'ip:port'"` +} + +func (o ClusterUpdateComponentCephCSIOpt) Params() (*jsonutils.JSONDict, error) { + params := o.ClusterComponentOptions.Params("cephCSI") + conf := jsonutils.NewDict() + clusterConfs := jsonutils.NewArray() + clusterConf := jsonutils.NewDict() + if o.ClusterId != "" { + clusterConf.Add(jsonutils.NewString(o.ClusterId), "clusterId") + } + mons := jsonutils.NewArray() + for _, m := range o.Monitor { + mons.Add(jsonutils.NewString(m)) + } + if mons.Length() != 0 { + clusterConf.Add(mons, "monitors") + } + clusterConfs.Add(clusterConf) + conf.Add(clusterConfs, "config") + params.Add(conf, "cephCSI") + return params, nil +} diff --git a/pkg/mcclient/options/k8s/secret.go b/pkg/mcclient/options/k8s/secret.go index 0a84d41777..378a834c28 100644 --- a/pkg/mcclient/options/k8s/secret.go +++ b/pkg/mcclient/options/k8s/secret.go @@ -51,3 +51,33 @@ func (o RegistrySecretCreateOptions) Params() (*jsonutils.JSONDict, error) { } return params, nil } + +type SecretCreateOptions struct { + NamespaceWithClusterOptions + NAME string `help:"Name of secret"` +} + +func (o SecretCreateOptions) Params(typ string) (*jsonutils.JSONDict, error) { + params := o.NamespaceWithClusterOptions.Params() + params.Add(jsonutils.NewString(o.NAME), "name") + params.Add(jsonutils.NewString(typ), "type") + return params, nil +} + +type CephCSISecretCreateOptions struct { + SecretCreateOptions + USERID string `help:"User id"` + USERKEY string `help:"User key"` +} + +func (o CephCSISecretCreateOptions) Params() (*jsonutils.JSONDict, error) { + params, err := o.SecretCreateOptions.Params("yunion.io/ceph-csi") + if err != nil { + return nil, err + } + conf := jsonutils.NewDict() + conf.Add(jsonutils.NewString(o.USERID), "userId") + conf.Add(jsonutils.NewString(o.USERKEY), "userKey") + params.Add(conf, "cephCSI") + return params, nil +} diff --git a/pkg/mcclient/options/k8s/storageclass.go b/pkg/mcclient/options/k8s/storageclass.go new file mode 100644 index 0000000000..6ea9415e87 --- /dev/null +++ b/pkg/mcclient/options/k8s/storageclass.go @@ -0,0 +1,85 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package k8s + +import "yunion.io/x/jsonutils" + +type StorageClassCreateOptions struct { + ClusterResourceCreateOptions + // Provisioner string `help:"StorageClass provisioner"` +} + +func (o *StorageClassCreateOptions) Params(provisioner string) *jsonutils.JSONDict { + params := o.ClusterBaseOptions.Params() + params.Add(jsonutils.NewString(o.NAME), "name") + params.Add(jsonutils.NewString(provisioner), "provisioner") + return params +} + +type StorageClassCephCSIRBDTestOptions struct { + StorageClassCreateOptions + CLUSTERID string `help:"Ceph cluster id"` + SecretName string `help:"Ceph credentials with required access to the pool"` + SecretNamespace string `help:"Ceph credentials secret namespace"` +} + +func (o *StorageClassCephCSIRBDTestOptions) Params() (*jsonutils.JSONDict, error) { + params := o.StorageClassCreateOptions.Params("rbd.csi.ceph.com") + input, err := o.getInput() + if err != nil { + return nil, err + } + params.Add(input, "cephCSIRBD") + return params, nil +} + +func (o *StorageClassCephCSIRBDTestOptions) getInput() (*jsonutils.JSONDict, error) { + params := jsonutils.NewDict() + params.Add(jsonutils.NewString(o.CLUSTERID), "clusterId") + params.Add(jsonutils.NewString(o.SecretName), "secretName") + params.Add(jsonutils.NewString(o.SecretNamespace), "secretNamespace") + return params, nil +} + +type StorageClassCephCSIRBDCreateOptions struct { + StorageClassCephCSIRBDTestOptions + POOL string `help:"Ceph RBD pool"` + ImageFeatures string `help:"RBD image features" default:"layering"` + FsType string `help:"CSI default volume filesystem type" default:"ext4"` +} + +func (o *StorageClassCephCSIRBDCreateOptions) Params() (*jsonutils.JSONDict, error) { + params, err := o.StorageClassCephCSIRBDTestOptions.Params() + if err != nil { + return nil, err + } + input, err := o.getInput() + if err != nil { + return nil, err + } + params.Add(input, "cephCSIRBD") + return params, nil +} + +func (o *StorageClassCephCSIRBDCreateOptions) getInput() (*jsonutils.JSONDict, error) { + params := jsonutils.NewDict() + params.Add(jsonutils.NewString(o.POOL), "pool") + params.Add(jsonutils.NewString(o.CLUSTERID), "clusterId") + params.Add(jsonutils.NewString(o.FsType), "csiFsType") + params.Add(jsonutils.NewString(o.ImageFeatures), "imageFeatures") + params.Add(jsonutils.NewString(o.SecretName), "secretName") + params.Add(jsonutils.NewString(o.SecretNamespace), "secretNamespace") + return params, nil +}