Skip to content

Commit d46df66

Browse files
authored
Merge pull request kubernetes#3621 from RainbowMango/pr_implement_asg
CA huaweicloud: implements node group by AS
2 parents 0e8e609 + 3a0f7af commit d46df66

File tree

6 files changed

+396
-273
lines changed

6 files changed

+396
-273
lines changed

cluster-autoscaler/cloudprovider/huaweicloud/examples/cluster-autoscaler-secret.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ stringData:
99
cloud-config: |-
1010
[Global]
1111
identity-endpoint=https://{Identity Endpoint}/v3.0
12+
ecs-endpoint=https://{ECS endpoint}
13+
as-endpoint=https://{AS endpoint}
1214
project-id={Project ID}
1315
access-key={Access Key}
1416
secret-key={Secret Key}

cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud_auto_scaling_group.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,33 @@ import (
2121

2222
apiv1 "k8s.io/api/core/v1"
2323
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
24+
huaweicloudsdkasmodel "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/services/as/v1/model"
2425
"k8s.io/klog/v2"
2526
schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
2627
)
2728

2829
// AutoScalingGroup represents a HuaweiCloud's 'Auto Scaling Group' which also can be treated as a node group.
2930
type AutoScalingGroup struct {
3031
cloudServiceManager CloudServiceManager
31-
32-
groupID string
33-
minInstanceNumber int
34-
maxInstanceNumber int
32+
groupName string
33+
groupID string
34+
minInstanceNumber int
35+
maxInstanceNumber int
3536
}
3637

3738
// Check if our AutoScalingGroup implements necessary interface.
3839
var _ cloudprovider.NodeGroup = &AutoScalingGroup{}
3940

41+
func newAutoScalingGroup(csm CloudServiceManager, sg huaweicloudsdkasmodel.ScalingGroups) AutoScalingGroup {
42+
return AutoScalingGroup{
43+
cloudServiceManager: csm,
44+
groupName: *sg.ScalingGroupName,
45+
groupID: *sg.ScalingGroupId,
46+
minInstanceNumber: int(*sg.MinInstanceNumber),
47+
maxInstanceNumber: int(*sg.MaxInstanceNumber),
48+
}
49+
}
50+
4051
// MaxSize returns maximum size of the node group.
4152
func (asg *AutoScalingGroup) MaxSize() int {
4253
return asg.maxInstanceNumber
@@ -92,7 +103,7 @@ func (asg *AutoScalingGroup) DeleteNodes(nodes []*apiv1.Node) error {
92103

93104
servers := make([]string, 0, len(instances))
94105
for _, instance := range instances {
95-
servers = append(servers, *instance.InstanceId)
106+
servers = append(servers, instance.Id)
96107
}
97108

98109
err = asg.cloudServiceManager.DeleteServers(servers)
@@ -101,6 +112,8 @@ func (asg *AutoScalingGroup) DeleteNodes(nodes []*apiv1.Node) error {
101112
return err
102113
}
103114

115+
// TODO(RainbowMango): Wait for node group size updated.
116+
104117
return nil
105118
}
106119

@@ -134,21 +147,8 @@ func (asg *AutoScalingGroup) Nodes() ([]cloudprovider.Instance, error) {
134147
klog.Warningf("failed to get nodes from group: %s, error: %v", asg.groupID, err)
135148
return nil, err
136149
}
137-
if len(instances) == 0 {
138-
return nil, nil
139-
}
140150

141-
// TODO(RainbowMango) Convert AS instances to cloud provider instances. Especially convert status.
142-
providerInstances := make([]cloudprovider.Instance, 0, len(instances))
143-
for i := range instances {
144-
pInstances := cloudprovider.Instance{
145-
Id: *instances[i].InstanceId,
146-
Status: nil,
147-
}
148-
149-
providerInstances = append(providerInstances, pInstances)
150-
}
151-
return nil, nil
151+
return instances, nil
152152
}
153153

154154
// TemplateNodeInfo returns a schedulerframework.NodeInfo structure of an empty

cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud_cloud_config.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,25 @@ limitations under the License.
1717
package huaweicloud
1818

1919
import (
20+
"fmt"
21+
"io"
22+
"os"
23+
24+
"gopkg.in/gcfg.v1"
25+
huaweicloudsdkbasic "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
26+
huaweicloudsdkconfig "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/core/config"
27+
huaweicloudsdkas "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/services/as/v1"
28+
huaweicloudsdkecs "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/services/ecs/v2"
29+
2030
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk"
2131
)
2232

2333
// CloudConfig is the cloud config file for huaweicloud.
2434
type CloudConfig struct {
2535
Global struct {
2636
IdentityEndpoint string `gcfg:"identity-endpoint"` // example: "https://iam.cn-north-4.myhuaweicloud.com/v3.0"
37+
ECSEndpoint string `gcfg:"ecs-endpoint"`
38+
ASEndpoint string `gcfg:"as-endpoint"`
2739
ProjectID string `gcfg:"project-id"`
2840
AccessKey string `gcfg:"access-key"`
2941
SecretKey string `gcfg:"secret-key"`
@@ -33,6 +45,69 @@ type CloudConfig struct {
3345
}
3446
}
3547

48+
func (c *CloudConfig) getECSClient() *huaweicloudsdkecs.EcsClient {
49+
// There are two types of services provided by HUAWEI CLOUD according to scope:
50+
// - Regional services: most of services belong to this classification, such as ECS.
51+
// - Global services: such as IAM, TMS, EPS.
52+
// For Regional services' authentication, projectId is required.
53+
// For global services' authentication, domainId is required.
54+
// More details please refer to:
55+
// https://github.com/huaweicloud/huaweicloud-sdk-go-v3/blob/0281b9734f0f95ed5565729e54d96e9820262426/README.md#use-go-sdk
56+
credentials := huaweicloudsdkbasic.NewCredentialsBuilder().
57+
WithAk(c.Global.AccessKey).
58+
WithSk(c.Global.SecretKey).
59+
WithProjectId(c.Global.ProjectID).
60+
Build()
61+
62+
client := huaweicloudsdkecs.EcsClientBuilder().
63+
WithEndpoint(c.Global.ECSEndpoint).
64+
WithCredential(credentials).
65+
WithHttpConfig(huaweicloudsdkconfig.DefaultHttpConfig()).
66+
Build()
67+
68+
return huaweicloudsdkecs.NewEcsClient(client)
69+
}
70+
71+
func (c *CloudConfig) getASClient() *huaweicloudsdkas.AsClient {
72+
credentials := huaweicloudsdkbasic.NewCredentialsBuilder().
73+
WithAk(c.Global.AccessKey).
74+
WithSk(c.Global.SecretKey).
75+
WithProjectId(c.Global.ProjectID).
76+
Build()
77+
78+
client := huaweicloudsdkas.AsClientBuilder().
79+
WithEndpoint(c.Global.ASEndpoint).
80+
WithCredential(credentials).
81+
WithHttpConfig(huaweicloudsdkconfig.DefaultHttpConfig()).
82+
Build()
83+
84+
return huaweicloudsdkas.NewAsClient(client)
85+
}
86+
87+
func (c *CloudConfig) validate() error {
88+
if len(c.Global.ECSEndpoint) == 0 {
89+
return fmt.Errorf("ECS endpoint missing from cloud configuration")
90+
}
91+
92+
if len(c.Global.ASEndpoint) == 0 {
93+
return fmt.Errorf("AS endpoint missing from cloud configuration")
94+
}
95+
96+
if len(c.Global.AccessKey) == 0 {
97+
return fmt.Errorf("access key missing from cloud coniguration")
98+
}
99+
100+
if len(c.Global.SecretKey) == 0 {
101+
return fmt.Errorf("secret key missing from cloud configuration")
102+
}
103+
104+
if len(c.Global.ProjectID) == 0 {
105+
return fmt.Errorf("project id missing from cloud configuration")
106+
}
107+
108+
return nil
109+
}
110+
36111
// toAKSKOptions creates and returns a new instance of type aksk.AKSKOptions
37112
func toAKSKOptions(cfg CloudConfig) aksk.AKSKOptions {
38113
opts := aksk.AKSKOptions{
@@ -46,3 +121,19 @@ func toAKSKOptions(cfg CloudConfig) aksk.AKSKOptions {
46121
}
47122
return opts
48123
}
124+
125+
func readConf(confFile string) (*CloudConfig, error) {
126+
var conf io.ReadCloser
127+
conf, err := os.Open(confFile)
128+
if err != nil {
129+
return nil, fmt.Errorf("failed to open configuration file: %s, error: %v", confFile, err)
130+
}
131+
defer conf.Close()
132+
133+
var cloudConfig CloudConfig
134+
if err := gcfg.ReadInto(&cloudConfig, conf); err != nil {
135+
return nil, fmt.Errorf("failed to read configuration file: %s, error: %v", confFile, err)
136+
}
137+
138+
return &cloudConfig, nil
139+
}

0 commit comments

Comments
 (0)