Merge pull request #1123 in YUNIONIO/onecloud from ~LIZEXI/onecloud:feature/lzx-cluster-api to release/2.7.0

* commit 'b6fe9b80592be6a080c981c8af32a7ae293c5b84':
  k8s multi cluster api
This commit is contained in:
李泽玺
2019-02-28 16:20:28 +08:00
11 changed files with 420 additions and 12 deletions
+7 -2
View File
@@ -135,8 +135,13 @@ func init() {
return doK8sEventList(s, &nargs)
})
R(&TypeEventListOptions{}, "kube-node-event", "Show operation event logs of kubernetes node", func(s *mcclient.ClientSession, args *TypeEventListOptions) error {
nargs := EventListOptions{BaseEventListOptions: args.BaseEventListOptions, Id: args.ID, Type: []string{"kube_node"}}
R(&TypeEventListOptions{}, "kubecluster-event", "Show operation event logs of kubernetes cluster", func(s *mcclient.ClientSession, args *TypeEventListOptions) error {
nargs := EventListOptions{BaseEventListOptions: args.BaseEventListOptions, Id: args.ID, Type: []string{"kubecluster"}}
return doK8sEventList(s, &nargs)
})
R(&TypeEventListOptions{}, "kubemachine-event", "Show operation event logs of kubernetes machine", func(s *mcclient.ClientSession, args *TypeEventListOptions) error {
nargs := EventListOptions{BaseEventListOptions: args.BaseEventListOptions, Id: args.ID, Type: []string{"kubemachine"}}
return doK8sEventList(s, &nargs)
})
}
+2
View File
@@ -15,6 +15,8 @@ import (
func init() {
// cluster resources
initCluster()
initKubeCluster()
initKubeMachine()
initNode()
// helm resources
+159
View File
@@ -0,0 +1,159 @@
package k8s
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
)
func initKubeCluster() {
cmdN := func(action string) string {
return fmt.Sprintf("kubecluster-%s", action)
}
R(&o.ClusterListOptions{}, cmdN("list"), "List k8s clusters", func(s *mcclient.ClientSession, args *o.ClusterListOptions) error {
result, err := k8s.KubeClusters.List(s, args.Params())
if err != nil {
return err
}
printList(result, k8s.KubeClusters.GetColumns(s))
return nil
})
R(&o.IdentOptions{}, cmdN("show"), "Show details of a cluster", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
result, err := k8s.KubeClusters.Get(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&o.KubeClusterCreateOptions{}, cmdN("create"), "Create k8s cluster", func(s *mcclient.ClientSession, args *o.KubeClusterCreateOptions) error {
params, err := args.Params()
if err != nil {
return err
}
cluster, err := k8s.KubeClusters.Create(s, params)
if err != nil {
return err
}
printObject(cluster)
return nil
})
R(&o.ClusterDeleteOptions{}, cmdN("delete"), "Delete cluster", func(s *mcclient.ClientSession, args *o.ClusterDeleteOptions) error {
ret := k8s.KubeClusters.BatchDeleteWithParam(s, args.ID, nil, nil)
printBatchResults(ret, k8s.Clusters.GetColumns(s))
return nil
})
R(&o.KubeClusterAddMachinesOptions{}, cmdN("add-machines"), "Add machines to cluster", func(s *mcclient.ClientSession, args *o.KubeClusterAddMachinesOptions) error {
params, err := args.Params()
if err != nil {
return err
}
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "add-machines", params)
if err != nil {
return err
}
printObject(ret)
return nil
})
R(&o.KubeClusterDeleteMachinesOptions{}, cmdN("delete-machines"), "Delete machines in cluster", func(s *mcclient.ClientSession, args *o.KubeClusterDeleteMachinesOptions) error {
params, err := args.Params()
if err != nil {
return err
}
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "delete-machines", params)
if err != nil {
return err
}
printObject(ret)
return nil
})
R(&o.IdentOptions{}, cmdN("terminate"), "Terminate cluster", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "terminate", nil)
if err != nil {
return err
}
printObject(ret)
return nil
})
R(&o.IdentOptions{}, cmdN("kubeconfig"), "Generate kubeconfig of a cluster", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
ret, err := k8s.KubeClusters.GetSpecific(s, args.ID, "kubeconfig", nil)
if err != nil {
return err
}
conf, err := ret.GetString("kubeconfig")
if err != nil {
return err
}
fmt.Println(conf)
return nil
})
R(&o.ClusterK8sVersions{}, cmdN("k8s-versions"), "Get kubernetes deployable versions", func(s *mcclient.ClientSession, args *o.ClusterK8sVersions) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.PROVIDER), "provider")
ret, err := k8s.KubeClusters.Get(s, "k8s-versions", params)
if err != nil {
return err
}
fmt.Println(ret.String())
return nil
})
R(&o.ClusterK8sVersions{}, cmdN("usable-instances"), "Get deploy usable instance", func(s *mcclient.ClientSession, args *o.ClusterK8sVersions) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.PROVIDER), "provider")
ret, err := k8s.KubeClusters.Get(s, "usable-instances", params)
if err != nil {
return err
}
fmt.Println(ret.String())
return nil
})
R(&o.IdentOptions{}, cmdN("apply-addons"), "Apply base requirements addons", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "apply-addons", nil)
if err != nil {
return err
}
printObject(ret)
return nil
})
R(&o.IdentOptions{}, cmdN("syncstatus"), "Sync cluster status", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "syncstatus", nil)
if err != nil {
return err
}
printObject(ret)
return nil
})
R(&o.IdentOptions{}, cmdN("public"), "Make cluster public", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "public", nil)
if err != nil {
return err
}
printObject(ret)
return nil
})
R(&o.IdentOptions{}, cmdN("private"), "Make cluster private", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "private", nil)
if err != nil {
return err
}
printObject(ret)
return nil
})
}
+70
View File
@@ -0,0 +1,70 @@
package k8s
import (
"fmt"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
)
func initKubeMachine() {
cmdN := func(action string) string {
return fmt.Sprintf("kubemachine-%s", action)
}
R(&o.NodeListOptions{}, cmdN("list"), "List k8s node machines", func(s *mcclient.ClientSession, args *o.NodeListOptions) error {
params, err := args.Params()
if err != nil {
return err
}
result, err := k8s.KubeMachines.List(s, params)
if err != nil {
return err
}
printList(result, k8s.KubeMachines.GetColumns(s))
return nil
})
R(&o.MachineCreateOptions{}, cmdN("create"), "Create k8s machine", func(s *mcclient.ClientSession, args *o.MachineCreateOptions) error {
params := args.Params()
node, err := k8s.KubeMachines.Create(s, params)
if err != nil {
return err
}
printObject(node)
return nil
})
R(&o.IdentOptions{}, cmdN("show"), "Show details of a machine", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
result, err := k8s.KubeMachines.Get(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&o.IdentsOptions{}, cmdN("delete"), "Delete machine", func(s *mcclient.ClientSession, args *o.IdentsOptions) error {
ret := k8s.KubeMachines.BatchDelete(s, args.ID, nil)
printBatchResults(ret, k8s.KubeMachines.GetColumns(s))
return nil
})
R(&o.IdentOptions{}, cmdN("recreate"), "Re-Create machine when create fail", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
ret, err := k8s.KubeMachines.PerformAction(s, args.ID, "recreate", nil)
if err != nil {
return err
}
printObject(ret)
return nil
})
R(&o.IdentOptions{}, cmdN("terminate"), "Terminate a machine", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
ret, err := k8s.KubeMachines.PerformAction(s, args.ID, "terminate", nil)
if err != nil {
return err
}
printObject(ret)
return nil
})
}
+6 -1
View File
@@ -5,12 +5,17 @@ import (
)
var (
Clusters *ResourceManager
Clusters *ResourceManager
KubeClusters *ResourceManager
)
func init() {
Clusters = NewResourceManager("kube_cluster", "kube_clusters",
NewResourceCols("mode", "k8s_version", "status", "api_endpoint"),
NewColumns("is_public"))
KubeClusters = NewResourceManager("kubecluster", "kubeclusters",
NewResourceCols("cluster_type", "cloud_type", "version", "status", "mode", "provider", "machines"),
NewColumns())
modules.Register(Clusters)
modules.Register(KubeClusters)
}
+1 -6
View File
@@ -1,16 +1,11 @@
package k8s
import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var (
Logs *ResourceManager
)
func init() {
Logs = NewResourceManager("kube_event", "kube_events",
Logs = NewResourceManager("event", "events",
NewColumns("id", "ops_time", "obj_id", "obj_type", "obj_name", "user", "user_id", "tenant", "tenant_id", "owner_tenant_id", "action", "notes"),
NewColumns())
modules.Register(Logs)
}
+16
View File
@@ -0,0 +1,16 @@
package k8s
import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var (
KubeMachines *ResourceManager
)
func init() {
KubeMachines = NewResourceManager("kubemachine", "kubemachines",
NewResourceCols("role", "first_node", "cluster", "provider", "resource_type", "status", "address"),
NewColumns())
modules.Register(KubeMachines)
}
+1 -1
View File
@@ -5,7 +5,7 @@ import (
)
type ClusterBaseOptions struct {
Cluster string `default:"$K8S_CLUSTER|default" help:"Kubernetes cluster name"`
Cluster string `default:"$K8S_CLUSTER" help:"Kubernetes cluster name"`
}
func (o ClusterBaseOptions) Params() *jsonutils.JSONDict {
+126
View File
@@ -58,6 +58,94 @@ func (o ClusterCreateOptions) Params() *jsonutils.JSONDict {
return params
}
type KubeClusterCreateOptions struct {
NAME string `help:"Name of cluster"`
ClusterType string `help:"Cluster cluster type" choices:"default|serverless"`
CloudType string `help:"Cluster cloud type" choices:"private|public|hybrid"`
Mode string `help:"Cluster mode type" choices:"customize|managed"`
Provider string `help:"Cluster provider" choices:"onecloud|aws|aliyun|azure|qcloud"`
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"`
Machine []string `help:"Machine create desc, e.g. host01:baremetal:controlplane"`
}
func parseMachineDesc(desc string) (*MachineCreateOptions, error) {
matchType := func(p string) bool {
switch p {
case "baremetal", "vm":
return true
default:
return false
}
}
matchRole := func(p string) bool {
switch p {
case "controlplane", "node":
return true
default:
return false
}
}
mo := new(MachineCreateOptions)
for _, part := range strings.Split(desc, ":") {
switch {
case matchType(part):
mo.Type = part
case matchRole(part):
mo.ROLE = part
default:
mo.Instance = part
}
}
if mo.ROLE == "" {
return nil, fmt.Errorf("Machine role is empty")
}
if mo.Type == "" {
return nil, fmt.Errorf("Machine type is empty")
}
return mo, nil
}
func (o KubeClusterCreateOptions) Params() (*jsonutils.JSONDict, error) {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(o.NAME), "name")
if o.ClusterType != "" {
params.Add(jsonutils.NewString(o.ClusterType), "cluster_type")
}
if o.CloudType != "" {
params.Add(jsonutils.NewString(o.CloudType), "cloud_type")
}
if o.Mode != "" {
params.Add(jsonutils.NewString(o.Mode), "mode")
}
if o.Provider != "" {
params.Add(jsonutils.NewString(o.Provider), "provider")
}
if o.ServiceCidr != "" {
params.Add(jsonutils.NewString(o.ServiceCidr), "service_cidr")
}
if o.ServiceDomain != "" {
params.Add(jsonutils.NewString(o.ServiceDomain), "service_domain")
}
if o.Vip != "" {
params.Add(jsonutils.NewString(o.Vip), "vip")
}
if len(o.Machine) != 0 {
machineObjs := jsonutils.NewArray()
for _, m := range o.Machine {
machine, err := parseMachineDesc(m)
if err != nil {
return nil, err
}
machineObjs.Add(machine.Params())
}
params.Add(machineObjs, "machines")
}
return params, nil
}
type ClusterImportOptions struct {
NAME string `help:"Name of cluster to import"`
KUBECONFIG string `help:"Kubernetes auth config"`
@@ -90,6 +178,10 @@ type IdentOptions struct {
ID string `help:"ID or name of the model"`
}
type ClusterK8sVersions struct {
PROVIDER string `help:"cluster provider" choices:"system|onecloud"`
}
type IdentsOptions struct {
ID []string `help:"ID of models to operate"`
}
@@ -124,6 +216,25 @@ func (o ClusterKubeconfigOptions) Params() *jsonutils.JSONDict {
return params
}
type KubeClusterAddMachinesOptions struct {
IdentOptions
Machine []string `help:"Node spec, 'host:[role]' e.g: --machine host01:controlplane:baremetal --node-config host02:node:baremetal"`
}
func (o KubeClusterAddMachinesOptions) Params() (*jsonutils.JSONDict, error) {
params := jsonutils.NewDict()
machinesArray := jsonutils.NewArray()
for _, config := range o.Machine {
opt, err := parseMachineDesc(config)
if err != nil {
return nil, err
}
machinesArray.Add(jsonutils.Marshal(opt))
}
params.Add(machinesArray, "machines")
return params, nil
}
type ClusterAddNodesOptions struct {
IdentOptions
NodeConfig []string `help:"Node spec, 'host:[roles]' e.g: --node-config host01:controlplane,etcd,worker --node-config host02:worker"`
@@ -195,6 +306,21 @@ func (o ClusterDeleteNodesOptions) Params() (*jsonutils.JSONDict, error) {
return params, nil
}
type KubeClusterDeleteMachinesOptions struct {
IdentOptions
Machines []string `help:"Machine id or name"`
}
func (o KubeClusterDeleteMachinesOptions) Params() (*jsonutils.JSONDict, error) {
params := jsonutils.NewDict()
machinesArray := jsonutils.NewArray()
for _, m := range o.Machines {
machinesArray.Add(jsonutils.NewString(m))
}
params.Add(machinesArray, "machines")
return params, nil
}
type ClusterRestartAgentsOptions struct {
ClusterDeleteNodesOptions
All bool `help:"Restart all nodes agent"`
+31
View File
@@ -0,0 +1,31 @@
package k8s
import (
"yunion.io/x/jsonutils"
)
type MachineCreateOptions struct {
CLUSTER string `help:"Cluster id"`
ROLE string `help:"Machine role" choices:"node|controlplane"`
Type string `help:"Resource type" choices:"vm|baremetal" json:"resource_type"`
Instance string `help:"VM or host instance id" json:"resource_id"`
Name string `help:"Name of node"`
}
func (o MachineCreateOptions) Params() *jsonutils.JSONDict {
params := jsonutils.NewDict()
if o.Name != "" {
params.Add(jsonutils.NewString(o.Name), "name")
}
params.Add(jsonutils.NewString(o.CLUSTER), "cluster")
if o.ROLE != "" {
params.Add(jsonutils.NewString(o.ROLE), "role")
}
if o.Instance != "" {
params.Add(jsonutils.NewString(o.Instance), "resource_id")
}
if o.Type != "" {
params.Add(jsonutils.NewString(o.Type), "resource_type")
}
return params
}
+1 -2
View File
@@ -62,8 +62,7 @@ func fetchK8sEnv(ctx context.Context, w http.ResponseWriter, r *http.Request) (*
}
data := jsonutils.NewDict()
data.Add(jsonutils.JSONTrue, "directly")
ret, err := k8s.Clusters.PerformAction(adminSession, cluster, "generate-kubeconfig", data)
ret, err := k8s.KubeClusters.GetSpecific(adminSession, cluster, "kubeconfig", data)
if err != nil {
return nil, err
}