fix(region): support aliyun k8s op

This commit is contained in:
ioito
2023-06-02 10:23:00 +08:00
parent 46e6394da5
commit 84ebd491a0
10 changed files with 209 additions and 17 deletions
+1 -1
View File
@@ -83,7 +83,7 @@ require (
k8s.io/client-go v0.19.3
k8s.io/cluster-bootstrap v0.19.3
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230531121637-7453981269de
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230602022139-e5d6a679e169
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656
yunion.io/x/jsonutils v1.0.1-0.20230428104347-7c2fdff8e8e7
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361
+2 -2
View File
@@ -1175,8 +1175,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230531121637-7453981269de h1:s+y+9cCe6+J+APiqyLQQq/myixihzO3GeSc0nBB2iyY=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230531121637-7453981269de/go.mod h1:crMeQeaNaZefTXfXbQkoj5SStggqkSNVABHtYBFjM3Y=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230602022139-e5d6a679e169 h1:qWpki3zZrZMqI0/e4Z+EeHNbW1sgdwlWNF+h8Qj9S5A=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230602022139-e5d6a679e169/go.mod h1:crMeQeaNaZefTXfXbQkoj5SStggqkSNVABHtYBFjM3Y=
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 h1:0zlZD5uhZoIHgLVAWCz2aHaYk2ZrNsACCYD7R6EIBII=
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
+3 -1
View File
@@ -38,6 +38,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/sshkeys"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/logclient"
@@ -3174,6 +3175,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateKubeCluster(ctx con
opts.RoleName, _ = params.GetString("role_name")
opts.PrivateAccess, _ = params.Bool("private_access")
opts.PublicAccess, _ = params.Bool("public_access")
_, opts.PublicKey, _ = sshkeys.GetSshAdminKeypair(ctx)
iregion, err := cluster.GetIRegion(ctx)
if err != nil {
@@ -3247,7 +3249,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateKubeNodePool(ctx co
}
err = cloudprovider.WaitStatus(ipool, api.KUBE_CLUSTER_STATUS_RUNNING, time.Second*30, time.Hour*1)
if err != nil {
return nil, errors.Wrapf(err, "wait cluster status timeout, current status: %s", icluster.GetStatus())
return nil, errors.Wrapf(err, "wait node pool status timeout, current status: %s", icluster.GetStatus())
}
return nil, pool.SetStatus(userCred, api.KUBE_CLUSTER_STATUS_RUNNING, "")
})
+1 -1
View File
@@ -1440,7 +1440,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230531121637-7453981269de
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230602022139-e5d6a679e169
## explicit; go 1.18
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
+2
View File
@@ -34,6 +34,8 @@ type KubeClusterCreateOptions struct {
PrivateAccess bool
PublicAccess bool
RoleName string
PublicKey string
}
type KubeNodePoolCreateOptions struct {
+7 -1
View File
@@ -32,6 +32,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/httputils"
v "yunion.io/x/pkg/util/version"
"yunion.io/x/pkg/utils"
@@ -161,7 +162,11 @@ func jsonRequest(client *sdk.Client, domain, apiVersion, apiName string, params
func doRequest(client *sdk.Client, domain, apiVersion, apiName string, params map[string]string, body interface{}, debug bool) (jsonutils.JSONObject, error) {
if debug {
log.Debugf("request %s %s %s %s", domain, apiVersion, apiName, params)
if !gotypes.IsNil(body) {
log.Debugf("request %s %s %s %s", domain, apiVersion, apiName, jsonutils.Marshal(body))
} else {
log.Debugf("request %s %s %s %s", domain, apiVersion, apiName, params)
}
}
var resp jsonutils.JSONObject
var err error
@@ -171,6 +176,7 @@ func doRequest(client *sdk.Client, domain, apiVersion, apiName string, params ma
if err != nil {
for _, code := range []string{
"ErrorClusterNotFound",
"ErrorNodePoolNotFound",
} {
if strings.Contains(err.Error(), code) {
return nil, errors.Wrap(cloudprovider.ErrNotFound, err.Error())
+152 -5
View File
@@ -174,7 +174,7 @@ func (self *SRegion) GetKubeConfig(clusterId string, private bool, minutes int)
if minutes >= 15 && minutes <= 4320 {
params["TemporaryDurationMinutes"] = fmt.Sprintf("%d", minutes)
}
resp, err := self.k8sRequest("DescribeClusterUserKubeconfig", params)
resp, err := self.k8sRequest("DescribeClusterUserKubeconfig", params, nil)
if err != nil {
return nil, errors.Wrapf(err, "DescribeClusterUserKubeconfig")
}
@@ -198,7 +198,7 @@ func (self *SRegion) GetKubeClusters(pageSize, pageNumber int) ([]SKubeCluster,
"page_number": fmt.Sprintf("%d", pageNumber),
"PathPattern": "/api/v1/clusters",
}
resp, err := self.k8sRequest("DescribeClustersV1", params)
resp, err := self.k8sRequest("DescribeClustersV1", params, nil)
if err != nil {
return nil, 0, errors.Wrapf(err, "DescribeClustersV1")
}
@@ -248,7 +248,7 @@ func (self *SRegion) GetKubeCluster(id string) (*SKubeCluster, error) {
params := map[string]string{
"PathPattern": fmt.Sprintf("/clusters/%s", id),
}
resp, err := self.k8sRequest("DescribeClusterDetail", params)
resp, err := self.k8sRequest("DescribeClusterDetail", params, nil)
if err != nil {
return nil, errors.Wrapf(err, "DescribeClusterDetail")
}
@@ -268,10 +268,157 @@ func (self *SRegion) DeleteKubeCluster(id string, isRetain bool) error {
params["retain_all_resources"] = "true"
params["keep_slb"] = "true"
}
_, err := self.k8sRequest("DeleteCluster", params)
_, err := self.k8sRequest("DeleteCluster", params, nil)
return errors.Wrapf(err, "DeleteCluster")
}
func (self *SKubeCluster) CreateIKubeNodePool(opts *cloudprovider.KubeNodePoolCreateOptions) (cloudprovider.ICloudKubeNodePool, error) {
return nil, cloudprovider.ErrNotImplemented
pool, err := self.region.CreateKubeNodePool(self.ClusterId, opts)
if err != nil {
return nil, errors.Wrapf(err, "CreateKubeNodePool")
}
pool.cluster = self
return pool, nil
}
func (self *SRegion) CreateKubeNodePool(clusterId string, opts *cloudprovider.KubeNodePoolCreateOptions) (*SKubeNodePool, error) {
keyName, err := self.syncKeypair(opts.PublicKey)
if err != nil {
return nil, errors.Wrapf(err, "syncKeypair")
}
params := map[string]interface{}{
"kubernetes_config": map[string]interface{}{
"cms_enabled": true,
},
"nodepool_info": map[string]interface{}{
"name": opts.NAME,
},
"auto_scaling": map[string]interface{}{
"enable": false,
},
"scaling_group": map[string]interface{}{
"instance_types": opts.InstanceTypes,
"key_pair": keyName,
"system_disk_category": "cloud_efficiency",
"system_disk_size": opts.RootDiskSizeGb,
"vswitch_ids": opts.NetworkIds,
"desired_size": opts.DesiredInstanceCount,
},
}
path := fmt.Sprintf("/clusters/%s/nodepools", clusterId)
resp, err := self.k8sRequest("CreateClusterNodePool", map[string]string{"PathPattern": path}, params)
if err != nil {
return nil, err
}
poolId, err := resp.GetString("nodepool_id")
if err != nil {
return nil, errors.Wrapf(err, "get nodepool_id")
}
return self.GetKubeNodePool(clusterId, poolId)
}
func (self *SRegion) CreateIKubeCluster(opts *cloudprovider.KubeClusterCreateOptions) (cloudprovider.ICloudKubeCluster, error) {
cluster, err := self.CreateKubeCluster(opts)
if err != nil {
return nil, err
}
return cluster, nil
}
func (self *SRegion) CreateKubeCluster(opts *cloudprovider.KubeClusterCreateOptions) (*SKubeCluster, error) {
tags := []struct {
Key string
Value string
}{}
for k, v := range opts.Tags {
tags = append(tags, struct {
Key string
Value string
}{
Key: k,
Value: v,
})
}
if len(opts.ServiceCIDR) == 0 {
opts.ServiceCIDR = "192.168.0.0/16"
}
addons := []struct {
Name string
Config string
Disabled bool
}{
{
Name: "terway-eniip",
Config: `{"IPVlan":"false","NetworkPolicy":"false","ENITrunking":"false"}`,
},
{
Name: "csi-plugin",
},
{
Name: "csi-provisioner",
},
{
Name: "storage-operator",
Config: `{"CnfsOssEnable":"false","CnfsNasEnable":"false"}`,
},
{
Name: "nginx-ingress-controller",
Disabled: true,
},
}
if len(opts.PublicKey) == 0 {
return nil, fmt.Errorf("missing public_key")
}
keyName, err := self.syncKeypair(opts.PublicKey)
if err != nil {
return nil, errors.Wrapf(err, "syncKeypair")
}
params := map[string]interface{}{
"name": opts.NAME,
"region_id": self.RegionId,
"disable_rollback": true,
"cluster_type": "ManagedKubernetes",
"cluster_spec": "ack.pro.small",
"deletion_protection": false,
"proxy_mode": "ipvs",
"cis_enable_risk_check": false,
"os_type": "Linux",
"platform": "AliyunLinux",
"image_type": "AliyunLinux",
"timezone": "Asia/Shanghai",
"pod_vswitch_ids": opts.NetworkIds,
"vswitch_ids": opts.NetworkIds,
"charge_type": "PostPaid",
"vpcid": opts.VpcId,
"service_cidr": opts.ServiceCIDR,
"api_audiences": "https://kubernetes.default.svc",
"service_account_issuer": "https://kubernetes.default.svc",
"key_pair": keyName,
"snat_entry": false,
"ssh_flags": true,
"tags": tags,
"cloud_monitor_flags": true,
"is_enterprise_security_group": true,
"num_of_nodes": 0,
"nodepools": []interface{}{},
"addons": addons,
}
if opts.PublicAccess {
params["endpoint_public_access"] = true
}
if len(opts.Version) > 0 {
params["kubernetes_version"] = opts.Version
}
resp, err := self.k8sRequest("CreateCluster", map[string]string{"PathPattern": "/clusters"}, params)
if err != nil {
return nil, errors.Wrapf(err, "CreateCluster")
}
ret := &SKubeCluster{region: self}
return ret, resp.Unmarshal(ret)
}
+1 -1
View File
@@ -80,7 +80,7 @@ func (self *SRegion) GetKubeNodes(clusterId string, pageSize, pageNumber int) ([
"page_number": fmt.Sprintf("%d", pageNumber),
"PathPattern": fmt.Sprintf("/clusters/%s/nodes", clusterId),
}
resp, err := self.k8sRequest("DescribeClusterNodes", params)
resp, err := self.k8sRequest("DescribeClusterNodes", params, nil)
if err != nil {
return nil, 0, errors.Wrapf(err, "DescribeClusterNodes")
}
+38 -3
View File
@@ -17,8 +17,10 @@ package aliyun
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
@@ -84,6 +86,7 @@ type SKubeNodePool struct {
VswitchIds []string `json:"vswitch_ids"`
LoginPassword string `json:"login_password"`
KeyPair string `json:"key_pair"`
DesiredSize int `json:"desired_size"`
} `json:"scaling_group"`
Status struct {
FailedNodes string `json:"failed_nodes"`
@@ -122,7 +125,19 @@ func (self *SKubeNodePool) GetGlobalId() string {
return self.NodepoolInfo.NodepoolId
}
func (self *SKubeNodePool) Refresh() error {
pool, err := self.cluster.region.GetKubeNodePool(self.cluster.ClusterId, self.NodepoolInfo.NodepoolId)
if err != nil {
return err
}
return jsonutils.Update(self, pool)
}
func (self *SKubeNodePool) GetStatus() string {
switch self.Status.State {
case "active":
return api.KUBE_CLUSTER_STATUS_RUNNING
}
return self.Status.State
}
@@ -135,7 +150,7 @@ func (self *SKubeNodePool) GetMaxInstanceCount() int {
}
func (self *SKubeNodePool) GetDesiredInstanceCount() int {
return 0
return self.ScalingGroup.DesiredSize
}
func (self *SKubeNodePool) GetRootDiskSizeGb() int {
@@ -143,7 +158,7 @@ func (self *SKubeNodePool) GetRootDiskSizeGb() int {
}
func (self *SKubeNodePool) Delete() error {
return cloudprovider.ErrNotImplemented
return self.cluster.region.DeleteKubeNodePool(self.cluster.ClusterId, self.NodepoolInfo.NodepoolId)
}
func (self *SKubeNodePool) GetInstanceTypes() []string {
@@ -154,6 +169,26 @@ func (self *SKubeNodePool) GetNetworkIds() []string {
return self.ScalingGroup.VswitchIds
}
func (self *SRegion) DeleteKubeNodePool(clusterId, id string) error {
params := map[string]string{
"PathPattern": fmt.Sprintf("/clusters/%s/nodepools/%s", clusterId, id),
}
_, err := self.k8sRequest("DeleteClusterNodepool", params, map[string]string{})
return errors.Wrapf(err, "DeleteCluster")
}
func (self *SRegion) GetKubeNodePool(clusterId, id string) (*SKubeNodePool, error) {
params := map[string]string{
"PathPattern": fmt.Sprintf("/clusters/%s/nodepools/%s", clusterId, id),
}
resp, err := self.k8sRequest("DescribeClusterNodePoolDetail", params, map[string]string{})
if err != nil {
return nil, err
}
ret := &SKubeNodePool{}
return ret, resp.Unmarshal(ret)
}
func (self *SKubeCluster) GetIKubeNodePools() ([]cloudprovider.ICloudKubeNodePool, error) {
pools, err := self.region.GetKubeNodePools(self.ClusterId)
if err != nil {
@@ -171,7 +206,7 @@ func (self *SRegion) GetKubeNodePools(clusterId string) ([]SKubeNodePool, error)
params := map[string]string{
"PathPattern": fmt.Sprintf("/clusters/%s/nodepools", clusterId),
}
resp, err := self.k8sRequest("DescribeClusterNodePools", params)
resp, err := self.k8sRequest("DescribeClusterNodePools", params, nil)
if err != nil {
return nil, errors.Wrapf(err, "DescribeClusterNodePools")
}
+2 -2
View File
@@ -180,13 +180,13 @@ func (self *SRegion) rdsRequest(apiName string, params map[string]string) (jsonu
return jsonRequest(client, "rds.aliyuncs.com", ALIYUN_RDS_API_VERSION, apiName, params, self.client.debug)
}
func (self *SRegion) k8sRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
func (self *SRegion) k8sRequest(apiName string, params map[string]string, body interface{}) (jsonutils.JSONObject, error) {
client, err := self.getSdkClient()
if err != nil {
return nil, err
}
params = self.client.SetResourceGropuId(params)
return jsonRequest(client, fmt.Sprintf("cs.%s.aliyuncs.com", self.RegionId), ALIYUN_K8S_API_VERSION, apiName, params, self.client.debug)
return doRequest(client, fmt.Sprintf("cs.%s.aliyuncs.com", self.RegionId), ALIYUN_K8S_API_VERSION, apiName, params, body, self.client.debug)
}
func (self *SRegion) mongodbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {