diff --git a/bce/config.go b/bce/config.go index 9f7a1fbc..b6919ff4 100644 --- a/bce/config.go +++ b/bce/config.go @@ -26,7 +26,7 @@ import ( // Constants and default values for the package bce const ( - SDK_VERSION = "0.9.19" + SDK_VERSION = "0.9.20" URI_PREFIX = "/" // now support uri without prefix "v1" so just set root path DEFAULT_DOMAIN = "baidubce.com" DEFAULT_PROTOCOL = "http" diff --git a/doc/CCEv2.md b/doc/CCEv2.md index 6e2179d5..1e2c290c 100644 --- a/doc/CCEv2.md +++ b/doc/CCEv2.md @@ -455,6 +455,21 @@ s, _ := json.MarshalIndent(resp, "", "\t") fmt.Println("Response:"+ string(s)) ``` +## 获取节点组的节点列表 +使用以下代码可以获取节点组的节点列表 +```go +args := &ListInstanceByInstanceGroupIDArgs{ + ClusterID: "your-cluster-id", + InstanceGroupID: "your-instance-group-id", + PageSize: 0, + {ageNo: 0, +} +resp, err := ccev2Client.ListInstancesByInstanceGroupID(args) + +s, _ := json.MarshalIndent(resp, "", "\t") +fmt.Println("Response:" + string(s)) +``` + ## 删除节点(集群缩容) 使用以下代码可以删除集群内的一个节点 ```go @@ -593,6 +608,127 @@ s, _ := json.MarshalIndent(resp, "", "\t") fmt.Println("Response:"+ string(s)) ``` +## 创建节点组 +使用以下代码可以创建节点组 +```go +args := &CreateInstanceGroupArgs{ + ClusterID: CCE_CLUSTER_ID, + Request: &CreateInstanceGroupRequest{ + types.InstanceGroupSpec{ + InstanceGroupName: "your-instance-group-name", + CleanPolicy: types.DeleteCleanPolicy, + Replicas: 3, + InstanceTemplate: types.InstanceTemplate{ + InstanceSpec: types.InstanceSpec{ + ClusterRole: types.ClusterRoleNode, + Existed: false, + MachineType: types.MachineTypeBCC, + InstanceType: bccapi.InstanceTypeN3, + VPCConfig: types.VPCConfig{ + VPCID: "your-vpc-id", + VPCSubnetID: "your-vpc-subnet-id", + SecurityGroupID: "your-secuirity-group-id", + AvailableZone: types.AvailableZoneA, + }, + DeployCustomConfig: types.DeployCustomConfig{ + PreUserScript: "your-script", + PostUserScript:"your-script", + }, + InstanceResource: types.InstanceResource{ + CPU: 1, + MEM: 4, + RootDiskSize: 40, + LocalDiskSize: 0, + }, + ImageID: IMAGE_TEST_ID, + InstanceOS: types.InstanceOS{ + ImageType: bccapi.ImageTypeSystem, + }, + NeedEIP: false, + AdminPassword: "your-admin-password", + SSHKeyID: "your-ssh-key-id", + InstanceChargingType: bccapi.PaymentTimingPostPaid, + RuntimeType: types.RuntimeTypeDocker, + }, + }, + }, + }, +} +resp, err := ccev2Client.CreateInstanceGroup(args) + +s, _ = json.MarshalIndent(resp, "", "\t") +fmt.Println("Response:" + string(s)) +``` + + +## 获取节点组列表 +使用以下代码可以获取节点组列表 +```go +args := &ListInstanceGroupsArgs{ + ClusterID: "your-cluster-id", + ListOption: &InstanceGroupListOption{ + PageNo: 0, + PageSize: 0, + }, +} +resp, err := ccev2Client.ListInstanceGroups(args) + +s, _ := json.MarshalIndent(resp, "", "\t") +fmt.Println("Response:" + string(s)) +``` + + +## 查询节点组详情 +使用以下代码可以查询节点组详情 +```go +args := &GetInstanceGroupArgs{ + ClusterID: "your-cluster-id", + InstanceGroupID: "your-instance-group-id", +} +resp, err := ccev2Client.GetInstanceGroup(args) + +s, _ := json.MarshalIndent(resp, "", "\t") +fmt.Println("Response:" + string(s)) +``` + + +## 修改节点组内节点副本数 +使用以下代码可以修改节点组内节点副本数 +```go +args := &UpdateInstanceGroupReplicasArgs{ + ClusterID: "your-cluster-id", + InstanceGroupID: "your-instance-group-id", + Request: &UpdateInstanceGroupReplicasRequest{ + Replicas: 1, + DeleteInstance: true, + DeleteOption: &types.DeleteOption{ + MoveOut: false, + DeleteCDSSnapshot: true, + DeleteResource: true, + }, + }, +} +resp, err := ccev2Client.UpdateInstanceGroupReplicas(args) + +s, _ := json.MarshalIndent(resp, "", "\t") +fmt.Println("Response:" + string(s)) +``` + + +## 删除节点组 +使用以下代码可以删除节点组 +```go +args := &DeleteInstanceGroupArgs{ + ClusterID: "your-cluster-id", + InstanceGroupID: "your-instance-group-id", + DeleteInstances: true, +} +resp, err := ccev2Client.DeleteInstanceGroup(args) + +s, _ := json.MarshalIndent(resp, "", "\t") +fmt.Println("Response:" + string(s)) +``` + # 错误处理 GO语言以error类型标识错误,CCE支持两种错误见下表: @@ -687,4 +823,11 @@ myLogger.Info("this is my own logger from the CCE go sdk") - 支持创建集群、获取集群列表、获取集群详情、删除集群。 - 支持创建节点(集群扩容)、获取集群的节点列表、获取节点详情、删除节点(集群缩容) - 支持检查集群网络网段、检查容器网络网段、推荐集群网络网段、推荐容器网络网段 - - 支持查询集群配额、集群节点配额 \ No newline at end of file + - 支持查询集群配额、集群节点配额 + + + ## v1.1.0 [2020-08-20] + + 增加节点组相关接口: + - 支持节点组创建、获取节点组列表、查询节点组详情、修改节点组内节点副本数、删除节点组 + - 获取节点组的节点列表 \ No newline at end of file diff --git a/services/cce/v2/ccev2.go b/services/cce/v2/ccev2.go index ddeceee1..83218ced 100644 --- a/services/cce/v2/ccev2.go +++ b/services/cce/v2/ccev2.go @@ -1,6 +1,7 @@ package v2 import ( + "encoding/json" "fmt" "strconv" @@ -10,12 +11,27 @@ import ( // 创建集群 func (c *Client) CreateCluster(args *CreateClusterArgs) (*CreateClusterResponse, error) { - if args == nil { + if args == nil || args.CreateClusterRequest == nil { return nil, fmt.Errorf("args is nil") } + //给其中可能存在的user script用base64编码 + err := encodeUserScriptInInstanceSet(args.CreateClusterRequest.MasterSpecs) + if err != nil{ + return nil ,err + } + + err = encodeUserScriptInInstanceSet(args.CreateClusterRequest.NodeSpecs) + if err != nil{ + return nil ,err + } + + + s, _ := json.MarshalIndent(args, "", "\t") + fmt.Println("Args:" + string(s)) + result := &CreateClusterResponse{} - err := bce.NewRequestBuilder(c). + err = bce.NewRequestBuilder(c). WithMethod(http.POST). WithURL(getClusterURI()). WithBody(args.CreateClusterRequest). @@ -90,8 +106,17 @@ func (c *Client) CreateInstances(args *CreateInstancesArgs) (*CreateInstancesRes return nil, fmt.Errorf("args is nil") } + //给其中可能存在的user script用base64编码 + err := encodeUserScriptInInstanceSet(args.Instances) + if err != nil{ + return nil ,err + } + + s, _ := json.MarshalIndent(args, "", "\t") + fmt.Println("Args:" + string(s)) + result := &CreateInstancesResponse{} - err := bce.NewRequestBuilder(c). + err = bce.NewRequestBuilder(c). WithMethod(http.POST). WithURL(getClusterInstanceListURI(args.ClusterID)). WithBody(args.Instances). @@ -250,4 +275,107 @@ func (c *Client) GetClusterNodeQuota(clusterID string) (*GetQuotaResponse, error Do() return result, err -} \ No newline at end of file +} + +//创建节点组 +func (c *Client) CreateInstanceGroup(args *CreateInstanceGroupArgs) (*CreateInstanceGroupResponse, error) { + if args == nil { + return nil, fmt.Errorf("args is nil") + } + + encodeUserScript(&args.Request.InstanceTemplate.InstanceSpec) + + result := &CreateInstanceGroupResponse{} + err := bce.NewRequestBuilder(c). + WithMethod(http.POST). + WithURL(getInstanceGroupURI(args.ClusterID)). + WithBody(args.Request). + WithResult(result). + Do() + + return result, err +} + +//获取节点组列表 +func (c *Client) ListInstanceGroups(args *ListInstanceGroupsArgs) (*ListInstanceGroupResponse, error) { + if args == nil { + return nil, fmt.Errorf("args is nil") + } + + result := &ListInstanceGroupResponse{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithQueryParamFilter("pageNo", strconv.Itoa(args.ListOption.PageNo)). + WithQueryParamFilter("pageSize", strconv.Itoa(args.ListOption.PageSize)). + WithURL(getInstanceGroupListURI(args.ClusterID)). + WithResult(result). + Do() + + return result, err +} + +func (c *Client) ListInstancesByInstanceGroupID(args *ListInstanceByInstanceGroupIDArgs) (*ListInstancesByInstanceGroupIDResponse, error) { + if args == nil { + return nil, fmt.Errorf("args is nil") + } + + result := &ListInstancesByInstanceGroupIDResponse{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithQueryParamFilter("pageNo", strconv.Itoa(args.PageNo)). + WithQueryParamFilter("pageSize", strconv.Itoa(args.PageSize)). + WithURL(getClusterInstanceListWithInstanceGroupIDURI(args.ClusterID, args.InstanceGroupID)). + WithResult(result). + Do() + + return result, err +} + +//获取节点组详情 +func (c *Client) GetInstanceGroup(args *GetInstanceGroupArgs) (*GetInstanceGroupResponse, error) { + if args == nil { + return nil, fmt.Errorf("args is nil") + } + + result := &GetInstanceGroupResponse{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithURL(getInstanceGroupWithIDURI(args.ClusterID, args.InstanceGroupID)). + WithResult(result). + Do() + + return result, err +} + +//更新节点组副本数 +func (c *Client) UpdateInstanceGroupReplicas(args *UpdateInstanceGroupReplicasArgs) (*UpdateInstanceGroupReplicasResponse, error) { + if args == nil { + return nil, fmt.Errorf("args is nil") + } + + result := &UpdateInstanceGroupReplicasResponse{} + err := bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getInstanceGroupReplicasURI(args.ClusterID, args.InstanceGroupID)). + WithBody(args.Request). + WithResult(result). + Do() + + return result, err +} + +//删除节点组 +func (c *Client) DeleteInstanceGroup(args *DeleteInstanceGroupArgs) (*DeleteInstanceGroupResponse, error) { + if args == nil { + return nil, fmt.Errorf("args is nil") + } + + result := &DeleteInstanceGroupResponse{} + err := bce.NewRequestBuilder(c). + WithMethod(http.DELETE). + WithURL(getInstanceGroupWithIDURI(args.ClusterID, args.InstanceGroupID)). + WithResult(result). + Do() + + return result, err +} diff --git a/services/cce/v2/client.go b/services/cce/v2/client.go index 49b67a45..e3f38b9c 100644 --- a/services/cce/v2/client.go +++ b/services/cce/v2/client.go @@ -10,11 +10,14 @@ modification history package v2 import ( + "encoding/base64" + "github.com/baidubce/bce-sdk-go/bce" + "github.com/baidubce/bce-sdk-go/services/cce/v2/types" ) const ( - URI_PREFIX = bce.URI_PREFIX + "/api/cce/service/v2" + URI_PREFIX = bce.URI_PREFIX + "api/cce/service/v2" DEFAULT_ENDPOINT = "cce." + bce.DEFAULT_REGION + ".baidubce.com" @@ -38,10 +41,6 @@ const ( REQUEST_NODE_URL = "/node" - REQUEST_KUBECONFIG_URL = "/kubeconfig" - - REQUEST_KUBECONFIG_ADMIN_URL = "/admin" - REQUEST_NET_URL = "/net" REQUEST_NET_CHECK_CONTAINER_NETWORK_CIDR_URL = "/check_container_network_cidr" @@ -139,6 +138,27 @@ func getQuotaNodeURI(clusterID string) string { return URI_PREFIX + REQUEST_QUOTA_URL + REQUEST_CLUSTER_URL + "/" + clusterID + REQUEST_NODE_URL } -func getAdminKubeConfigURI(clusterID, kubeconfigType string) string { - return URI_PREFIX + REQUEST_KUBECONFIG_URL + "/" + clusterID + REQUEST_KUBECONFIG_ADMIN_URL + "/" + kubeconfigType + +func encodeUserScriptInInstanceSet(instancesSets []*InstanceSet) error { + if instancesSets == nil { + return nil + } + for _, instanceSet := range instancesSets { + encodeUserScript(&instanceSet.InstanceSpec) + } + return nil +} + +func encodeUserScript(instanceSpec *types.InstanceSpec) { + if instanceSpec == nil{ + return + } + if instanceSpec.DeployCustomConfig.PreUserScript != "" { + base64Str := base64.StdEncoding.EncodeToString([]byte(instanceSpec.DeployCustomConfig.PreUserScript)) + instanceSpec.DeployCustomConfig.PreUserScript = base64Str + } + if instanceSpec.DeployCustomConfig.PostUserScript != "" { + base64Str := base64.StdEncoding.EncodeToString([]byte(instanceSpec.DeployCustomConfig.PostUserScript)) + instanceSpec.DeployCustomConfig.PostUserScript = base64Str + } } diff --git a/services/cce/v2/client_test.go b/services/cce/v2/client_test.go index 25ff53a0..8fdd7dd3 100644 --- a/services/cce/v2/client_test.go +++ b/services/cce/v2/client_test.go @@ -18,6 +18,7 @@ import ( var ( CCE_CLIENT *Client CCE_CLUSTER_ID string + CCE_INSTANCE_GROUP_ID string CCE_INSTANCE_ID string VPC_TEST_ID = "vpc-mwbgygrjb72w" IMAGE_TEST_ID = "m-gTpZ1k6n" @@ -176,12 +177,61 @@ func TestClient_CreateCluster(t *testing.T) { ClusterPodCIDR: "172.28.0.0/16", ClusterIPServiceCIDR: "172.31.0.0/16", }, + K8SCustomConfig: types.K8SCustomConfig{ + KubeAPIQPS: 1000, + KubeAPIBurst: 2000, + }, }, - NodeSpecs: []*InstanceSet{ - { - Count: 1, + }, + } + resp, err := CCE_CLIENT.CreateCluster(args) + + ExpectEqual(t.Errorf, nil, err) + CCE_CLUSTER_ID = resp.ClusterID + + s, _ := json.MarshalIndent(resp, "", "\t") + fmt.Println("Response:" + string(s)) + + //等集群创建完成 + time.Sleep(time.Duration(180) * time.Second) +} + +func TestClient_GetCluster(t *testing.T) { + resp, err := CCE_CLIENT.GetCluster(CCE_CLUSTER_ID) + + ExpectEqual(t.Errorf, nil, err) + + s, _ := json.MarshalIndent(resp, "", "\t") + fmt.Println("Response:" + string(s)) +} + +func TestClient_ListClusters(t *testing.T) { + args := &ListClustersArgs{ + KeywordType: "clusterName", + Keyword: "", + OrderBy: "clusterID", + Order: OrderASC, + PageSize: 10, + PageNum: 1, + } + resp, err := CCE_CLIENT.ListClusters(args) + + ExpectEqual(t.Errorf, nil, err) + + s, _ := json.MarshalIndent(resp, "", "\t") + fmt.Println("Response:" + string(s)) +} + +func TestClient_CreateInstanceGroup(t *testing.T) { + args := &CreateInstanceGroupArgs{ + ClusterID: CCE_CLUSTER_ID, + Request: &CreateInstanceGroupRequest{ + types.InstanceGroupSpec{ + InstanceGroupName: "jichao-sdk-testcase", + CleanPolicy: types.DeleteCleanPolicy, + Replicas: 3, + InstanceTemplate: types.InstanceTemplate{ InstanceSpec: types.InstanceSpec{ - InstanceName: "", ClusterRole: types.ClusterRoleNode, Existed: false, MachineType: types.MachineTypeBCC, @@ -192,12 +242,15 @@ func TestClient_CreateCluster(t *testing.T) { SecurityGroupID: SECURITY_GROUP_TESI_ID, AvailableZone: types.AvailableZoneA, }, + DeployCustomConfig: types.DeployCustomConfig{ + PreUserScript: "ls", + PostUserScript: "time", + }, InstanceResource: types.InstanceResource{ - CPU: 4, - MEM: 8, + CPU: 1, + MEM: 4, RootDiskSize: 40, LocalDiskSize: 0, - CDSList: []types.CDSConfig{}, }, ImageID: IMAGE_TEST_ID, InstanceOS: types.InstanceOS{ @@ -205,7 +258,7 @@ func TestClient_CreateCluster(t *testing.T) { }, NeedEIP: false, AdminPassword: ADMIN_PASSWORD_TEST, - SSHKeyID: "", + SSHKeyID: SSH_KEY_TEST_ID, InstanceChargingType: bccapi.PaymentTimingPostPaid, RuntimeType: types.RuntimeTypeDocker, }, @@ -213,20 +266,44 @@ func TestClient_CreateCluster(t *testing.T) { }, }, } - resp, err := CCE_CLIENT.CreateCluster(args) + + resp, err := CCE_CLIENT.CreateInstanceGroup(args) + ExpectEqual(t.Errorf, nil, err) - CCE_CLUSTER_ID = resp.ClusterID + CCE_INSTANCE_GROUP_ID = resp.InstanceGroupID s, _ := json.MarshalIndent(resp, "", "\t") fmt.Println("Response:" + string(s)) - //等集群创建完成 - time.Sleep(time.Duration(240) * time.Second) + time.Sleep(time.Duration(180) * time.Second) } -func TestClient_GetCluster(t *testing.T) { - resp, err := CCE_CLIENT.GetCluster(CCE_CLUSTER_ID) +func TestClient_ListInstanceGroups(t *testing.T) { + args := &ListInstanceGroupsArgs{ + ClusterID: CCE_CLUSTER_ID, + ListOption: &InstanceGroupListOption{ + PageNo: 0, + PageSize: 0, + }, + } + resp, err := CCE_CLIENT.ListInstanceGroups(args) + + s, _ := json.MarshalIndent(resp, "", "\t") + fmt.Println("Response:" + string(s)) + + ExpectEqual(t.Errorf, nil, err) +} + +func TestClient_ListInstancesByInstanceGroupID(t *testing.T) { + args := &ListInstanceByInstanceGroupIDArgs{ + ClusterID: CCE_CLUSTER_ID, + InstanceGroupID: CCE_INSTANCE_GROUP_ID, + PageSize: 0, + PageNo: 0, + } + + resp, err := CCE_CLIENT.ListInstancesByInstanceGroupID(args) ExpectEqual(t.Errorf, nil, err) @@ -234,21 +311,60 @@ func TestClient_GetCluster(t *testing.T) { fmt.Println("Response:" + string(s)) } -func TestClient_ListClusters(t *testing.T) { - args := &ListClustersArgs{ - KeywordType: "clusterName", - Keyword: "", - OrderBy: "clusterID", - Order: OrderASC, - PageSize: 10, - PageNum: 1, +func TestClient_GetInstanceGroup(t *testing.T) { + args := &GetInstanceGroupArgs{ + ClusterID: CCE_CLUSTER_ID, + InstanceGroupID: CCE_INSTANCE_GROUP_ID, } - resp, err := CCE_CLIENT.ListClusters(args) + + resp, err := CCE_CLIENT.GetInstanceGroup(args) + + ExpectEqual(t.Errorf, nil, err) + + s, _ := json.MarshalIndent(resp, "", "\t") + fmt.Println("Response:" + string(s)) +} + +func TestClient_UpdateInstanceGroupReplicas(t *testing.T) { + args := &UpdateInstanceGroupReplicasArgs{ + ClusterID: CCE_CLUSTER_ID, + InstanceGroupID: CCE_INSTANCE_GROUP_ID, + Request: &UpdateInstanceGroupReplicasRequest{ + Replicas: 1, + DeleteInstance: true, + DeleteOption: &types.DeleteOption{ + MoveOut: false, + DeleteCDSSnapshot: true, + DeleteResource: true, + }, + }, + } + + resp, err := CCE_CLIENT.UpdateInstanceGroupReplicas(args) ExpectEqual(t.Errorf, nil, err) s, _ := json.MarshalIndent(resp, "", "\t") fmt.Println("Response:" + string(s)) + + time.Sleep(time.Duration(120) * time.Second) +} + +func TestClient_DeleteInstanceGroup(t *testing.T) { + args := &DeleteInstanceGroupArgs{ + ClusterID: CCE_CLUSTER_ID, + InstanceGroupID: CCE_INSTANCE_GROUP_ID, + DeleteInstances: true, + } + + resp, err := CCE_CLIENT.DeleteInstanceGroup(args) + + ExpectEqual(t.Errorf, nil, err) + + s, _ := json.MarshalIndent(resp, "", "\t") + fmt.Println("Response:" + string(s)) + + time.Sleep(time.Duration(180) * time.Second) } func TestClient_CreateInstances(t *testing.T) { @@ -268,6 +384,10 @@ func TestClient_CreateInstances(t *testing.T) { SecurityGroupID: SECURITY_GROUP_TESI_ID, AvailableZone: types.AvailableZoneA, }, + DeployCustomConfig: types.DeployCustomConfig{ + PreUserScript: "ls", + PostUserScript: "time", + }, InstanceResource: types.InstanceResource{ CPU: 1, MEM: 4, @@ -294,6 +414,8 @@ func TestClient_CreateInstances(t *testing.T) { s, _ := json.MarshalIndent(resp, "", "\t") fmt.Println("Response:" + string(s)) + + time.Sleep(time.Duration(180) * time.Second) } func TestClient_ListInstancesByPage(t *testing.T) { diff --git a/services/cce/v2/model.go b/services/cce/v2/model.go index 32dcefd4..844375a3 100644 --- a/services/cce/v2/model.go +++ b/services/cce/v2/model.go @@ -569,3 +569,193 @@ type InstanceTemplate struct { type CommonResponse struct { RequestID string `json:"requestID"` } + +type InstanceGroup struct { + Spec *InstanceGroupSpec `json:"spec"` + Status *InstanceGroupStatus `json:"status"` + CreatedAt time.Time `json:"createdAt"` +} + +type InstanceGroupSpec struct { + CCEInstanceGroupID string `json:"cceInstanceGroupID,omitempty"` + InstanceGroupName string `json:"instanceGroupName"` + + ClusterID string `json:"clusterID,omitempty"` + ClusterRole types.ClusterRole `json:"clusterRole,omitempty"` + ShrinkPolicy ShrinkPolicy `json:"shrinkPolicy,omitempty"` + UpdatePolicy UpdatePolicy `json:"updatePolicy,omitempty"` + CleanPolicy CleanPolicy `json:"cleanPolicy,omitempty"` + + InstanceTemplate InstanceTemplate `json:"instanceTemplate"` + Replicas int `json:"replicas"` + + ClusterAutoscalerSpec *ClusterAutoscalerSpec `json:"clusterAutoscalerSpec,omitempty"` +} + +type ShrinkPolicy string +type UpdatePolicy string +type CleanPolicy string + +type ClusterAutoscalerSpec struct { + Enabled bool `json:"enabled"` + MinReplicas int `json:"minReplicas"` + MaxReplicas int `json:"maxReplicas"` + ScalingGroupPriority int `json:"scalingGroupPriority"` +} + +// InstanceGroupStatus - +type InstanceGroupStatus struct { + ReadyReplicas int `json:"readyReplicas"` + Pause *PauseDetail `json:"pause,omitempty"` +} + +type PauseDetail struct { + Paused bool `json:"paused"` + Reason string `json:"reason"` +} + +// CreateInstanceGroupRequest - 创建InstanceGroup request +type CreateInstanceGroupRequest struct { + types.InstanceGroupSpec +} + +// CreateInstanceGroupResponse - 创建InstanceGroup response +type CreateInstanceGroupResponse struct { + CommonResponse + InstanceGroupID string `json:"instanceGroupID"` +} + +type ListInstanceGroupResponse struct { + CommonResponse + Page ListInstanceGroupPage `json:"page"` +} + +type ListInstanceGroupPage struct { + PageNo int `json:"pageNo"` + PageSize int `json:"pageSize"` + TotalCount int `json:"totalCount"` + List []*InstanceGroup `json:"list"` +} + +type GetInstanceGroupResponse struct { + CommonResponse + InstanceGroup *InstanceGroup `json:"instanceGroup"` +} + +type UpdateInstanceGroupReplicasRequest struct { + Replicas int `json:"replicas"` + InstanceIDs []string `json:"instanceIDs"` + DeleteInstance bool `json:"deleteInstance"` + DeleteOption *types.DeleteOption `json:"deleteOption,omitempty"` +} + +type UpdateInstanceGroupReplicasResponse struct { + CommonResponse +} + +type UpdateInstanceGroupClusterAutoscalerSpecResponse struct { + CommonResponse +} + +type DeleteInstanceGroupResponse struct { + CommonResponse +} + +type ListInstancesByInstanceGroupIDPage struct { + PageNo int `json:"pageNo"` + PageSize int `json:"pageSize"` + TotalCount int `json:"totalCount"` + List []*Instance `json:"list"` +} + +type ListInstancesByInstanceGroupIDResponse struct { + CommonResponse + Page ListInstancesByInstanceGroupIDPage `json:"page"` +} + +type GetAutoscalerResponse struct { + Autoscaler *Autoscaler `json:"autoscaler"` + RequestID string `json:"requestID"` +} + +type Autoscaler struct { + ClusterID string `json:"clusterID"` + ClusterName string `json:"clusterName"` + CAConfig ClusterAutoscalerConfig `json:"caConfig,omitempty"` +} + +type ClusterAutoscalerConfig struct { + KubeVersion string `json:"kubeVersion,omitempty"` + ReplicaCount int `json:"replicaCount"` + InstanceGroups []ClusterAutoscalerInstanceGroup `json:"instanceGroups,omitempty"` + // default: false + ScaleDownEnabled bool `json:"scaleDownEnabled"` + // 可选,缩容阈值百分比,范围(0, 100) + ScaleDownUtilizationThreshold *int `json:"scaleDownUtilizationThreshold,omitempty"` + // 可选,GPU缩容阈值百分比,范围(0, 100) + ScaleDownGPUUtilizationThreshold *int `json:"scaleDownGPUUtilizationThreshold,omitempty"` + // 可选,缩容触发时延,单位:m + ScaleDownUnneededTime *int `json:"scaleDownUnneededTime,omitempty"` + // 可选,扩容后缩容启动时延,单位:m + ScaleDownDelayAfterAdd *int `json:"scaleDownDelayAfterAdd,omitempty"` + // 可选,最大并发缩容数 + MaxEmptyBulkDelete *int `json:"maxEmptyBulkDelete,omitempty"` + // 可选, + SkipNodesWithLocalStorage *bool `json:"skipNodesWithLocalStorage,omitempty"` + // 可选, + SkipNodesWithSystemPods *bool `json:"skipNodesWithSystemPods,omitempty"` + // supported: random, most-pods, least-waste, priority; default: random + Expander string `json:"expander"` +} + +type ClusterAutoscalerInstanceGroup struct { + InstanceGroupID string + MinReplicas int + MaxReplicas int + Priority int +} + +type InstanceGroupListOption struct { + PageNo int + PageSize int +} + +type CreateInstanceGroupArgs struct { + ClusterID string + Request *CreateInstanceGroupRequest +} + +type ListInstanceGroupsArgs struct { + ClusterID string + ListOption *InstanceGroupListOption +} + +type ListInstanceByInstanceGroupIDArgs struct { + ClusterID string + InstanceGroupID string + PageNo int + PageSize int +} + +type GetInstanceGroupArgs struct { + ClusterID string + InstanceGroupID string +} + +type UpdateInstanceGroupClusterAutoscalerSpecArgs struct { + ClusterID string + InstanceGroupID string + Request *ClusterAutoscalerSpec +} + +type UpdateInstanceGroupReplicasArgs struct { + ClusterID string + InstanceGroupID string + Request *UpdateInstanceGroupReplicasRequest +} + +type DeleteInstanceGroupArgs struct { + ClusterID string + InstanceGroupID string + DeleteInstances bool +} \ No newline at end of file diff --git a/services/cce/v2/types/cluster.go b/services/cce/v2/types/cluster.go index 3e164100..334bdae8 100644 --- a/services/cce/v2/types/cluster.go +++ b/services/cce/v2/types/cluster.go @@ -58,6 +58,21 @@ type ClusterSpec struct { MasterConfig MasterConfig `json:"masterConfig,omitempty" valid:"Required"` ContainerNetworkConfig ContainerNetworkConfig `json:"containerNetworkConfig,omitempty" valid:"Required"` + // K8S 自定义配置 + K8SCustomConfig K8SCustomConfig `json:"k8sCustomConfig,omitempty"` +} + +// K8SCustomConfig - K8S 自定义配置 +type K8SCustomConfig struct { + MasterFeatureGates map[string]bool `json:"masterFeatureGates,omitempty"` // 自定义 FeatureGates + NodeFeatureGates map[string]bool `json:"nodeFeatureGates,omitempty"` // 自定义 FeatureGates + AdmissionPlugins []string `json:"admissionPlugins,omitempty"` // 自定义 AdmissionPlugins + PauseImage string `json:"pauseImage,omitempty"` // 自定义 PauseImage + KubeAPIQPS int `json:"kubeAPIQPS,omitempty"` // 自定义 KubeAPIQPS + KubeAPIBurst int `json:"kubeAPIBurst,omitempty"` // 自定义 KubeAPIBurst + SchedulerPredicates []string `json:"schedulerPredicates,omitempty"` // 自定义 SchedulerPredicates + SchedulerPriorities map[string]int `json:"schedulerPriorities,omitempty"` // 自定义 SchedulerPriorities + ETCDDataPath string `json:"etcdDataPath,omitempty"` // 自定义 etcd数据目录 } // ClusterType usually used to init Provider diff --git a/services/cce/v2/types/instance.go b/services/cce/v2/types/instance.go index 34c53a73..83bb9145 100644 --- a/services/cce/v2/types/instance.go +++ b/services/cce/v2/types/instance.go @@ -188,8 +188,13 @@ type DeployCustomConfig struct { // key:value: cpu: 100m, memory: 1000Mi KubeReserved map[string]string `json:"kubeReserved,omitempty"` - // 用户自定义脚本, 前端 base64编码后传参 - UserScript string `json:"userScript,omitempty"` + // 是否封锁节点 + EnableCordon bool `json:"enableCordon,omitempty"` + + // 部署前执行脚本, 前端 base64编码后传参 + PreUserScript string `json:"preUserScript,omitempty"` + // 部署后执行脚本, 前端 base64编码后传参 + PostUserScript string `json:"postUserScript,omitempty"` } diff --git a/services/cce/v2/types/instance_group.go b/services/cce/v2/types/instance_group.go new file mode 100644 index 00000000..69637557 --- /dev/null +++ b/services/cce/v2/types/instance_group.go @@ -0,0 +1,93 @@ +package types + +const ( + DefaultShrinkPolicy = PriorityShrinkPolicy + PriorityShrinkPolicy ShrinkPolicy = "Priority" + RandomShrinkPolicy ShrinkPolicy = "Random" + + DefaultUpdatePolicy = ConcurrencyUpdatePolicy + RollingUpdatePolicy UpdatePolicy = "Rolling" + ConcurrencyUpdatePolicy UpdatePolicy = "Concurrency" + + DefaultCleanPolicy = RemainCleanPolicy + RemainCleanPolicy CleanPolicy = "Remain" + DeleteCleanPolicy CleanPolicy = "Delete" +) + +type InstanceGroupSpec struct { + + CCEInstanceGroupID string `json:"cceInstanceGroupID,omitempty" ` + InstanceGroupName string `json:"instanceGroupName" ` + + ClusterID string `json:"clusterID,omitempty" ` + ClusterRole ClusterRole `json:"clusterRole,omitempty" ` + + Selector *InstanceSelector `json:"selector" ` + + ShrinkPolicy ShrinkPolicy `json:"shrinkPolicy,omitempty" ` + + UpdatePolicy UpdatePolicy `json:"updatePolicy,omitempty" ` + + CleanPolicy CleanPolicy `json:"cleanPolicy,omitempty" ` + + InstanceTemplate InstanceTemplate `json:"instanceTemplate" ` + Replicas int `json:"replicas" ` + + ClusterAutoscalerSpec *ClusterAutoscalerSpec `json:"clusterAutoscalerSpec,omitempty" ` +} + +type InstanceTemplate struct { + InstanceSpec `json:",inline"` +} + +type InstanceSelector struct { + LabelSelector `json:",inline"` +} + +type ShrinkPolicy string +type UpdatePolicy string +type CleanPolicy string + +type ClusterAutoscalerSpec struct { + Enabled bool `json:"enabled" ` + MinReplicas int `json:"minReplicas" ` + MaxReplicas int `json:"maxReplicas" ` + ScalingGroupPriority int `json:"scalingGroupPriority" ` +} + + +type InstanceGroupStatus struct { + ReadyReplicas int `json:"readyReplicas" ` + UndeliveredMachines UndeliveredMachines `json:"undeliveredMachines,omitempty" ` + Pause *PauseDetail `json:"pause,omitempty" ` +} + +type UndeliveredMachines struct { + FailedMachines []string `json:"failedMachines,omitempty"` + PendingMachines []string `json:"pendingMachines,omitempty"` +} + +type PauseDetail struct { + Paused bool `json:"paused"` + Reason string `json:"reason"` +} + +type LabelSelector struct { + MatchLabels map[string]string `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels"` + MatchExpressions []LabelSelectorRequirement `json:"matchExpressions,omitempty" protobuf:"bytes,2,rep,name=matchExpressions"` +} + +type LabelSelectorRequirement struct { + Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"` + Operator LabelSelectorOperator `json:"operator" protobuf:"bytes,2,opt,name=operator,casttype=LabelSelectorOperator"` + Values []string `json:"values,omitempty" protobuf:"bytes,3,rep,name=values"` +} + +type LabelSelectorOperator string + +const ( + LabelSelectorOpIn LabelSelectorOperator = "In" + LabelSelectorOpNotIn LabelSelectorOperator = "NotIn" + LabelSelectorOpExists LabelSelectorOperator = "Exists" + LabelSelectorOpDoesNotExist LabelSelectorOperator = "DoesNotExist" +) \ No newline at end of file