diff --git a/cmd/climc/shell/k8s/clusters.go b/cmd/climc/shell/k8s/clusters.go index 634c15c656..818b1409c5 100644 --- a/cmd/climc/shell/k8s/clusters.go +++ b/cmd/climc/shell/k8s/clusters.go @@ -18,10 +18,13 @@ import ( "fmt" "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules/k8s" o "yunion.io/x/onecloud/pkg/mcclient/options/k8s" + "yunion.io/x/onecloud/pkg/util/shellutils" ) func initKubeCluster() { @@ -130,14 +133,24 @@ func initKubeCluster() { return nil }) - R(&o.ClusterComponentTypeOptions{}, cmdN("component-setting"), "Get cluster component setting", func(s *mcclient.ClientSession, args *o.ClusterComponentTypeOptions) error { + getComponentSetting := func(s *mcclient.ClientSession, args *o.ClusterComponentType, asHelmValues bool) (jsonutils.JSONObject, error) { q := jsonutils.NewDict() q.Add(jsonutils.NewString(args.TYPE), "type") - ret, err := k8s.KubeClusters.GetSpecific(s, args.ID, "component-setting", q) + q.Add(jsonutils.JSONTrue, "system") + q.Add(jsonutils.NewBool(asHelmValues), "as_helm_values") + return k8s.KubeClusters.GetSpecific(s, args.ID, "component-setting", q) + } + + R(&o.ClusterComponentTypeOptions{}, cmdN("component-setting"), "Get cluster component setting", func(s *mcclient.ClientSession, args *o.ClusterComponentTypeOptions) error { + ret, err := getComponentSetting(s, &args.ClusterComponentType, args.AsHelmValues) if err != nil { return err } - printObject(ret) + if args.AsHelmValues { + printObjectYAML(ret) + } else { + printObject(ret) + } return nil }) @@ -180,6 +193,32 @@ func initKubeCluster() { return nil }) + R(&o.ClusterEnableComponentMinioOpt{}, cmdN("component-enable-minio"), "Enable cluster minio component", func(s *mcclient.ClientSession, args *o.ClusterEnableComponentMinioOpt) 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.ClusterEnableComponentThanosOpt{}, cmdN("component-enable-thanos"), "Enable cluster thanos component", func(s *mcclient.ClientSession, args *o.ClusterEnableComponentThanosOpt) 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) @@ -200,7 +239,7 @@ func initKubeCluster() { return nil }) - R(&o.ClusterUpdateComponentCephCSIOpt{}, cmdN("component-update-ceph-csi"), "Update cluster component", func(s *mcclient.ClientSession, args *o.ClusterUpdateComponentCephCSIOpt) error { + R(&o.ClusterUpdateComponentCephCSIOpt{}, cmdN("component-update-ceph-csi"), "Update cluster component ceph csi", func(s *mcclient.ClientSession, args *o.ClusterUpdateComponentCephCSIOpt) error { params, err := args.Params() if err != nil { return err @@ -212,4 +251,33 @@ func initKubeCluster() { printObject(ret) return nil }) + + R(&o.ClusterComponentType{}, cmdN("component-update"), "Update cluster component", func(s *mcclient.ClientSession, args *o.ClusterComponentType) error { + // 1. get current setting + setting, err := getComponentSetting(s, args, false) + if err != nil { + return errors.Wrap(err, "get component setting") + } + + // 2. edit yaml + yaml, err := shellutils.Edit(setting.YAMLString()) + if len(yaml) == 0 { + log.Infof("Nothing to update") + return nil + } + nowSetting, err := jsonutils.ParseYAML(yaml) + if err != nil { + return err + } + params := args.Params(args.TYPE) + params.Update(nowSetting) + + // 3. call update api + ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "update-component", params) + if err != nil { + return err + } + printObject(ret) + return nil + }) } diff --git a/pkg/mcclient/options/k8s/cluster.go b/pkg/mcclient/options/k8s/cluster.go index 4b3c38871c..ca72569206 100644 --- a/pkg/mcclient/options/k8s/cluster.go +++ b/pkg/mcclient/options/k8s/cluster.go @@ -312,9 +312,14 @@ func (o ClusterComponentOptions) Params(typ string) *jsonutils.JSONDict { return params } +type ClusterComponentType struct { + ClusterComponentOptions + TYPE string `help:"Component type"` +} + type ClusterComponentTypeOptions struct { - IdentOptions - TYPE string `help:"component type"` + ClusterComponentType + AsHelmValues bool `help:"As helm values config" json:"as_helm_values"` } type ClusterEnableComponentCephCSIOpt struct { @@ -340,7 +345,7 @@ func (o ClusterEnableComponentCephCSIOpt) Params() (*jsonutils.JSONDict, error) return params, nil } -type ClusterComponentMonitorStorage struct { +type ClusterComponentStorage struct { Enabled bool `help:"Enable this storage" json:"enabled"` SizeMB int `help:"Persistent storage size MB" json:"sizeMB"` ClassName string `help:"Storage class name" json:"storageClassName"` @@ -352,20 +357,36 @@ type ClusterComponentMonitorGrafanaTlsOpt struct { } type ClusterComponentMonitorGrafana struct { - AdminUser string `help:"Grafana admin user" default:"admin" json:"adminUser"` - AdminPassword string `help:"Grafana admin user password" json:"adminPassword"` - Storage ClusterComponentMonitorStorage `help:"Storage setting"` - PublicAddress string `help:"Grafana expose public IP address or domain hostname" json:"publicAddress"` - Host string `help:"Grafana ingress host domain name" json:"host"` - Tls ClusterComponentMonitorGrafanaTlsOpt `help:"TLS setting"` + AdminUser string `help:"Grafana admin user" default:"admin" json:"adminUser"` + AdminPassword string `help:"Grafana admin user password" json:"adminPassword"` + Storage ClusterComponentStorage `help:"Storage setting"` + PublicAddress string `help:"Grafana expose public IP address or domain hostname" json:"publicAddress"` + Host string `help:"Grafana ingress host domain name" json:"host"` + Tls ClusterComponentMonitorGrafanaTlsOpt `help:"TLS setting"` + DisableSubpath bool `help:"Disable grafana subpath" json:"disableSubpath"` + EnableThanosQuery bool `help:"Enable thanos query datasource" json:"enableThanosQueryDataSource"` +} + +type ObjectStoreConfig struct { + Bucket string `json:"bucket"` + Endpoint string `json:"endpoint"` + AccessKey string `json:"access_key"` + SecretKey string `json:"secret_key"` + Insecure bool `json:"insecure"` } type ClusterComponentMonitorLoki struct { - Storage ClusterComponentMonitorStorage `help:"Storage setting"` + Storage ClusterComponentStorage `help:"Storage setting" json:"storage"` + ObjectStoreConfig ObjectStoreConfig `json:"objectStoreConfig"` +} + +type MonitorPrometheusThanosSidecar struct { + ObjectStoreConfig ObjectStoreConfig `json:"objectStoreConfig"` } type ClusterComponentMonitorPrometheus struct { - Storage ClusterComponentMonitorStorage `help:"Storage setting"` + Storage ClusterComponentStorage `help:"Storage setting" json:"storage"` + Thanos MonitorPrometheusThanosSidecar `json:"thanosSidecar"` } type ClusterComponentMonitorPromtail struct { @@ -587,3 +608,63 @@ func (o ClusterUpdateComponentCephCSIOpt) Params() (*jsonutils.JSONDict, error) params.Add(conf, "cephCSI") return params, nil } + +type ClusterComponentMinioSetting struct { + Mode string `help:"MinIO mode" choices:"standalone|distributed" json:"mode"` + Replicas int `help:"MinIO replicas" default:"1" json:"replicas"` + DrivesPerNode int `help:"MinIO drives per node" default:"1" json:"drivesPerNode"` + AccessKey string `help:"MinIO admin access key" json:"accessKey"` + SecretKey string `help:"MinIO admin secret key" json:"secretKey"` + MountPath string `help:"MinIO export mount path" json:"mountPath"` + Storage ClusterComponentStorage `help:"Storage setting" json:"storage"` +} + +type ClusterEnableComponentMinioOpt struct { + ClusterComponentOptions + ClusterComponentMinioSetting +} + +func (o ClusterEnableComponentMinioOpt) Params() (jsonutils.JSONObject, error) { + params := o.ClusterComponentOptions.Params("minio") + setting := jsonutils.Marshal(o.ClusterComponentMinioSetting) + params.Add(setting, "minio") + return params, nil +} + +type ComponentThanosDnsDiscovery struct { + SidecarsService string `help:"Sidecars service name to discover them using DNS discovery" default:"prometheus-operated" json:"sidecarsService"` + SidecarsNamespace string `help:"Sidecars namespace to discover them using DNS discovery" default:"onecloud-monitoring" json:"sidecarsNamespace"` +} + +type ComponentThanosQuery struct { + DnsDiscovery ComponentThanosDnsDiscovery `json:"dnsDiscovery"` + Stores []string `help:"Statically configure store APIs to connect with Thanos" json:"stores"` +} + +type ComponentThanosCompactor struct { + Storage ClusterComponentStorage `json:"storage"` +} + +type ComponentThanosStoregateway struct { + Storage ClusterComponentStorage `json:"storage"` +} + +type ClusterComponentThanosSetting struct { + ClusterDomain string `json:"clusterDomain"` + ObjectStoreConfig ObjectStoreConfig `json:"objectStoreConfig"` + Query ComponentThanosQuery `json:"query"` + Store ComponentThanosStoregateway `json:"store"` + Compactor ComponentThanosCompactor `json:"compactor"` +} + +type ClusterEnableComponentThanosOpt struct { + ClusterComponentOptions + ClusterComponentThanosSetting +} + +func (o ClusterEnableComponentThanosOpt) Params() (jsonutils.JSONObject, error) { + params := o.ClusterComponentOptions.Params("thanos") + setting := jsonutils.Marshal(o.ClusterComponentThanosSetting) + params.Add(setting, "thanos") + return params, nil +}