From 347d9ad1ca63a91ed6915845d1c86addb2a2c8d4 Mon Sep 17 00:00:00 2001 From: Zexi Li Date: Sat, 21 Nov 2020 17:58:44 +0800 Subject: [PATCH] feat(climc): k8s cluster addon add enable native ip alloc option --- cmd/climc/shell/k8s/clusters.go | 76 ++++++++++++++++++++++++- cmd/climc/shell/k8s/machines.go | 2 + pkg/mcclient/modules/k8s/cluster.go | 2 +- pkg/mcclient/modules/k8s/machine.go | 2 +- pkg/mcclient/options/k8s/cluster.go | 88 +++++++++++++++++++++++------ pkg/mcclient/options/k8s/machine.go | 19 +++++++ 6 files changed, 168 insertions(+), 21 deletions(-) diff --git a/cmd/climc/shell/k8s/clusters.go b/cmd/climc/shell/k8s/clusters.go index 818b1409c5..b6cf032555 100644 --- a/cmd/climc/shell/k8s/clusters.go +++ b/cmd/climc/shell/k8s/clusters.go @@ -16,6 +16,9 @@ package k8s import ( "fmt" + "io/ioutil" + "os" + "path/filepath" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -36,9 +39,10 @@ func initKubeCluster() { cmd.ShowEvent() cmd.List(new(o.ClusterListOptions)) cmd.Show(new(o.IdentOptions)) - cmd.Create(new(o.KubeClusterCreateOptions)) + cmd.Create(new(o.K8SClusterCreateOptions)) cmd.Perform("sync", new(o.ClusterSyncOptions)) cmd.Perform("syncstatus", new(o.IdentOptions)) + cmd.Perform("deploy", new(o.IdentOptions)) cmd.Get("components-status", new(o.IdentOptions)) cmd.Get("api-resources", new(o.IdentOptions)) cmd.Get("cluster-users", new(o.IdentOptions)) @@ -80,8 +84,12 @@ func initKubeCluster() { return nil }) - R(&o.IdentOptions{}, cmdN("addons"), "Get addon manifest of a cluster", func(s *mcclient.ClientSession, args *o.IdentOptions) error { - ret, err := k8s.KubeClusters.GetSpecific(s, args.ID, "addons", nil) + R(&o.ClusterGetAddonsOpt{}, cmdN("addons"), "Get addon manifest of a cluster", func(s *mcclient.ClientSession, args *o.ClusterGetAddonsOpt) error { + params, err := args.Params() + if err != nil { + return err + } + ret, err := k8s.KubeClusters.GetSpecific(s, args.ID, "addons", params) if err != nil { return err } @@ -280,4 +288,66 @@ func initKubeCluster() { printObject(ret) return nil }) + + type GetKubesprayConfigOpt struct { + o.IdentOptions + OUTPUT string `help:"Output directory to store config files"` + } + + R(&GetKubesprayConfigOpt{}, cmdN("kubespray-config"), "Get cluster kubespray config", func(s *mcclient.ClientSession, args *GetKubesprayConfigOpt) error { + conf, err := k8s.KubeClusters.GetSpecific(s, args.ID, "kubespray-config", nil) + if err != nil { + return err + } + + inventoryContent, err := conf.GetString("inventory_content") + if err != nil { + return errors.Wrap(err, "get inventory content") + } + + vars, err := conf.Get("vars") + if err != nil { + return errors.Wrap(err, "get variables") + } + + privateKey, err := conf.GetString("private_key") + if err != nil { + return errors.Wrap(err, "get private key") + } + + if err := os.MkdirAll(args.OUTPUT, 0755); err != nil { + return errors.Wrap(err, "mkdir") + } + + writeFile := func(name, content string) error { + fp := filepath.Join(args.OUTPUT, name) + log.Infof("Write file: %s", fp) + if err := ioutil.WriteFile(fp, []byte(content), 0644); err != nil { + return errors.Wrap(err, "write file") + } + if err := os.Chmod(fp, 0600); err != nil { + return errors.Wrap(err, "chmod") + } + return nil + } + + iPath := filepath.Join(args.OUTPUT, "hosts.ini") + vPath := filepath.Join(args.OUTPUT, "vars.json") + kPath := filepath.Join(args.OUTPUT, "private_key") + + for fPath, content := range map[string]string{ + iPath: inventoryContent, + vPath: vars.PrettyString(), + kPath: privateKey, + } { + name := filepath.Base(fPath) + if err := writeFile(name, content); err != nil { + return errors.Wrapf(err, "write file %s", name) + } + } + + fmt.Printf("try cmd:\nansible-playbook -i %s cluster.yml -b -v --private-key %s --extra-vars @%s\n", iPath, kPath, vPath) + + return nil + }) } diff --git a/cmd/climc/shell/k8s/machines.go b/cmd/climc/shell/k8s/machines.go index abe3c02162..ff5a235ccc 100644 --- a/cmd/climc/shell/k8s/machines.go +++ b/cmd/climc/shell/k8s/machines.go @@ -29,4 +29,6 @@ func initKubeMachine() { cmd.BatchDelete(new(o.IdentsOptions)) cmd.Perform("recreate", new(o.IdentOptions)) cmd.Perform("terminate", new(o.IdentOptions)) + cmd.Get("networkaddress", new(o.MachineListNetworkAddressOptions)) + cmd.Perform("attach-networkaddress", new(o.MachineAttachNetworkAddressOptions)) } diff --git a/pkg/mcclient/modules/k8s/cluster.go b/pkg/mcclient/modules/k8s/cluster.go index 7009b5adf4..5c2a7bb855 100644 --- a/pkg/mcclient/modules/k8s/cluster.go +++ b/pkg/mcclient/modules/k8s/cluster.go @@ -24,7 +24,7 @@ var ( func init() { KubeClusters = NewResourceManager("kubecluster", "kubeclusters", - NewResourceCols("Cluster_Type", "Resource_Type", "Cloud_Type", "Version", "Status", "Mode", "Provider", "Machines"), + NewResourceCols("Cluster_Type", "Cloudregion_Id", "Vpc_Id", "Resource_Type", "Cloud_Type", "Version", "Status", "Mode", "Provider", "Machines"), NewColumns("Sync_Status", "Sync_Message")) modules.Register(KubeClusters) } diff --git a/pkg/mcclient/modules/k8s/machine.go b/pkg/mcclient/modules/k8s/machine.go index 5ea86ba670..ab910d095d 100644 --- a/pkg/mcclient/modules/k8s/machine.go +++ b/pkg/mcclient/modules/k8s/machine.go @@ -24,7 +24,7 @@ var ( func init() { KubeMachines = NewResourceManager("kubemachine", "kubemachines", - NewResourceCols("role", "first_node", "cluster", "provider", "resource_type", "resource_id", "status", "address", "hypervisor"), + NewResourceCols("Role", "First_Node", "Cluster", "Provider", "Resource_Type", "Resource_Id", "Status", "Address", "Hypervisor", "Zone_Id", "Network_Id"), NewColumns()) modules.Register(KubeMachines) } diff --git a/pkg/mcclient/options/k8s/cluster.go b/pkg/mcclient/options/k8s/cluster.go index ca72569206..2fe01b5d5d 100644 --- a/pkg/mcclient/options/k8s/cluster.go +++ b/pkg/mcclient/options/k8s/cluster.go @@ -54,27 +54,40 @@ type AddMachineOptions struct { MachineDisk string `help:"Machine root disk size, e.g. 100G"` MachineCpu int `help:"Machine cpu count"` MachineMemory string `help:"Machine memory size, e.g. 1G"` + MachineSku string `help:"Machine sku, e.g. 'ecs.c6.large'"` MachineHypervisor string `help:"Machine hypervisor, e.g. kvm, openstack"` } -type KubeClusterCreateOptions struct { - NAME string `help:"Name of cluster"` - ClusterType string `help:"Cluster cluster type" choices:"default|serverless"` - ResourceType string `help:"Cluster cluster type" choices:"host|guest"` - CloudType string `help:"Cluster cloud type" choices:"private|public|hybrid"` - Mode string `help:"Cluster mode type" choices:"customize|managed|import"` - Provider string `help:"Cluster provider" choices:"onecloud|aws|aliyun|azure|qcloud|system"` +type K8SClusterCreateOptions struct { + NAME string `help:"Name of cluster"` + // ClusterType string `help:"Cluster cluster type" choices:"default|serverless"` + ResourceType string `help:"Cluster cluster type" choices:"host|guest"` + // CloudType string `help:"Cluster cloud type" choices:"private|public|hybrid"` + Mode string `help:"Cluster mode type" choices:"customize|import"` + Provider string `help:"Cluster provider" choices:"onecloud|system"` ServiceCidr string `help:"Cluster service CIDR, e.g. 10.43.0.0/16"` ServiceDomain string `help:"Cluster service domain, e.g. cluster.local"` Vip string `help:"Cluster api server static loadbalancer vip"` Version string `help:"Cluster kubernetes version"` ImageRepo string `help:"Image repository, e.g. registry-1.docker.io/yunion"` ImageRepoInsecure bool `help:"Image repostiory is insecure"` + Vpc string `help:"Cluster nodes network vpc"` + // AddMachineOptions include create machine options AddMachineOptions + // Addons options + EnableNativeIPAlloc bool `help:"Calico CNI plugin enable native ip allocation"` } -func parseMachineDesc(desc string, disk string, netConf string, ncpu int, memorySize string, hypervisor string) (*MachineCreateOptions, error) { +func parseMachineDesc( + desc string, + disk string, + netConf string, + ncpu int, + memorySize string, + sku string, + hypervisor string, +) (*MachineCreateOptions, error) { matchType := func(p string) bool { switch p { case "baremetal", "vm": @@ -111,23 +124,45 @@ func parseMachineDesc(desc string, disk string, netConf string, ncpu int, memory mo.Disk = disk mo.Cpu = ncpu mo.Memory = memorySize + mo.Sku = sku mo.Net = netConf mo.Hypervisor = hypervisor return mo, nil } -func (o KubeClusterCreateOptions) Params() (jsonutils.JSONObject, error) { +type K8SClusterAddonNetworkConfig struct { + EnableNativeIPAlloc bool `json:"enable_native_ip_alloc"` +} + +type K8SClusterAddonConfig struct { + Network K8SClusterAddonNetworkConfig `json:"network"` +} + +func (o K8SClusterCreateOptions) getAddonsConfig() (jsonutils.JSONObject, error) { + conf := &K8SClusterAddonConfig{ + Network: K8SClusterAddonNetworkConfig{ + EnableNativeIPAlloc: o.EnableNativeIPAlloc, + }, + } + return jsonutils.Marshal(conf), nil +} + +func (o K8SClusterCreateOptions) Params() (jsonutils.JSONObject, error) { params := jsonutils.NewDict() params.Add(jsonutils.NewString(o.NAME), "name") - if o.ClusterType != "" { - params.Add(jsonutils.NewString(o.ClusterType), "cluster_type") - } + /* + * if o.ClusterType != "" { + * params.Add(jsonutils.NewString(o.ClusterType), "cluster_type") + * } + */ if o.ResourceType != "" { params.Add(jsonutils.NewString(o.ResourceType), "resource_type") } - if o.CloudType != "" { - params.Add(jsonutils.NewString(o.CloudType), "cloud_type") - } + /* + * if o.CloudType != "" { + * params.Add(jsonutils.NewString(o.CloudType), "cloud_type") + * } + */ if o.Mode != "" { params.Add(jsonutils.NewString(o.Mode), "mode") } @@ -143,6 +178,9 @@ func (o KubeClusterCreateOptions) Params() (jsonutils.JSONObject, error) { if o.Vip != "" { params.Add(jsonutils.NewString(o.Vip), "vip") } + if o.Vpc != "" { + params.Add(jsonutils.NewString(o.Vpc), "vpc_id") + } imageRepo := jsonutils.NewDict() if o.ImageRepo != "" { imageRepo.Add(jsonutils.NewString(o.ImageRepo), "url") @@ -156,6 +194,12 @@ func (o KubeClusterCreateOptions) Params() (jsonutils.JSONObject, error) { } params.Add(machineObjs, "machines") params.Add(imageRepo, "image_repository") + + addonsConf, err := o.getAddonsConfig() + if err != nil { + return nil, errors.Wrap(err, "get addons config") + } + params.Add(addonsConf, "addons_config") return params, nil } @@ -264,7 +308,7 @@ func (o AddMachineOptions) Params() (jsonutils.JSONObject, error) { return machineObjs, nil } for _, m := range o.Machine { - machine, err := parseMachineDesc(m, o.MachineDisk, o.MachineNet, o.MachineCpu, o.MachineMemory, o.MachineHypervisor) + machine, err := parseMachineDesc(m, o.MachineDisk, o.MachineNet, o.MachineCpu, o.MachineMemory, o.MachineSku, o.MachineHypervisor) if err != nil { return nil, err } @@ -668,3 +712,15 @@ func (o ClusterEnableComponentThanosOpt) Params() (jsonutils.JSONObject, error) params.Add(setting, "thanos") return params, nil } + +type ClusterGetAddonsOpt struct { + IdentOptions + EnableNativeIPAlloc bool `json:"enable_native_ip_alloc"` +} + +func (o ClusterGetAddonsOpt) Params() (jsonutils.JSONObject, error) { + params := jsonutils.NewDict() + params.Add(jsonutils.NewBool(o.EnableNativeIPAlloc), "enable_native_ip_alloc") + + return params, nil +} diff --git a/pkg/mcclient/options/k8s/machine.go b/pkg/mcclient/options/k8s/machine.go index 0762134f9b..4da885ccb8 100644 --- a/pkg/mcclient/options/k8s/machine.go +++ b/pkg/mcclient/options/k8s/machine.go @@ -44,6 +44,7 @@ type MachineCreateOptions struct { Cpu int `help:"VM cpu count"` Memory string `help:"VM memory size, e.g. 1G"` Hypervisor string `help:"VM hypervisor"` + Sku string `help:"VM sku (instance type), e.g. 'ecs.c6.large'"` } func (o MachineCreateOptions) Params() (jsonutils.JSONObject, error) { @@ -90,6 +91,24 @@ func (o MachineCreateOptions) Params() (jsonutils.JSONObject, error) { vmConfig.Add(jsonutils.NewInt(int64(o.Cpu)), "vcpu_count") } vmConfig.Add(jsonutils.NewString(o.Hypervisor), "hypervisor") + vmConfig.Add(jsonutils.NewString(o.Sku), "instance_type") params.Add(vmConfig, "config", "vm") return params, nil } + +type MachineListNetworkAddressOptions struct { + IdentOptions +} + +type MachineAttachNetworkAddressOptions struct { + IdentOptions + IPAddr string `help:"preferred ip address"` +} + +func (o MachineAttachNetworkAddressOptions) Params() (jsonutils.JSONObject, error) { + params := jsonutils.NewDict() + if o.IPAddr != "" { + params.Add(jsonutils.NewString(o.IPAddr), "ip_addr") + } + return params, nil +}