Skip to content

Commit ec41ae1

Browse files
optimize repeatedly specifying EIP use case (#239)
1 parent 6240c80 commit ec41ae1

File tree

5 files changed

+373
-0
lines changed

5 files changed

+373
-0
lines changed

pkg/cloudprovider/huaweicloud/sharedloadbalancer.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,17 +240,48 @@ func (l *SharedLoadBalancer) EnsureLoadBalancer(ctx context.Context, clusterName
240240

241241
func (l *SharedLoadBalancer) createOrAssociateEIP(loadbalancer *elbmodel.LoadbalancerResp, service *v1.Service) (string, error) {
242242
var err error
243+
specifiedEip := true
244+
instance, err := l.sharedELBClient.Show(loadbalancer.Id)
245+
if err != nil {
246+
return "", status.Errorf(codes.Internal, "rollback:failed to query detail of ELB instance, error: %s", err)
247+
}
248+
243249
eipID := getStringFromSvsAnnotation(service, ElbEipID, "")
244250
if eipID == "" {
251+
opts, err := parseEIPAutoCreateOptions(service)
252+
if err != nil || opts == nil {
253+
return "", err
254+
}
255+
256+
if len(instance.PublicIPs) > 0 {
257+
klog.Infof("the ELB has bound EIP: %s / %s, skip creating EIP", instance.PublicIPs[0].Address, instance.PublicIPs[0].ID)
258+
return instance.PublicIPs[0].Address, nil
259+
}
260+
245261
eipID, err = l.createEIP(service)
246262
if err != nil {
247263
return "", status.Errorf(codes.Internal, "rollback:failed to create EIP, delete ELB instance, error: %s", err)
248264
}
265+
specifiedEip = false
249266
}
250267
if eipID == "" {
251268
return "", nil
252269
}
253270

271+
if specifiedEip && len(instance.PublicIPs) > 0 {
272+
if instance.PublicIPs[0].ID == eipID {
273+
klog.Infof("the ELB has been bound to the specified EIP %s", eipID)
274+
return instance.PublicIPs[0].Address, nil
275+
}
276+
277+
// remove bound EIP
278+
klog.Infof("remove the bound EIP %s and the specified will be used: %s", instance.PublicIPs[0].ID, eipID)
279+
err = l.eipClient.Unbind(instance.PublicIPs[0].ID)
280+
if err != nil {
281+
return "", status.Errorf(codes.Internal, "rollback:failed to unbind EIP from ELB instance, error: %s", err)
282+
}
283+
}
284+
254285
eip, err := l.eipClient.Get(eipID)
255286
if err != nil {
256287
return "", status.Errorf(codes.Internal, "rollback:failed to get EIP, delete ELB instance, error: %s", err)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package model
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/def"
7+
)
8+
9+
func GenReqDefForShowLoadbalancer() *def.HttpRequestDef {
10+
reqDefBuilder := def.NewHttpRequestDefBuilder().
11+
WithMethod(http.MethodGet).
12+
WithPath("/v2/{project_id}/elb/loadbalancers/{loadbalancer_id}").
13+
WithResponse(new(ShowLoadbalancerResponse)).
14+
WithContentType("application/json")
15+
16+
reqDefBuilder.WithRequestField(def.NewFieldDef().
17+
WithName("LoadbalancerId").
18+
WithJsonTag("loadbalancer_id").
19+
WithLocationType(def.Path))
20+
21+
requestDef := reqDefBuilder.Build()
22+
return requestDef
23+
}
24+
25+
func GenReqDefForListLoadbalancers() *def.HttpRequestDef {
26+
reqDefBuilder := def.NewHttpRequestDefBuilder().
27+
WithMethod(http.MethodGet).
28+
WithPath("/v2/{project_id}/elb/loadbalancers").
29+
WithResponse(new(ListLoadbalancersRsp)).
30+
WithContentType("application/json")
31+
32+
reqDefBuilder.WithRequestField(def.NewFieldDef().
33+
WithName("Limit").
34+
WithJsonTag("limit").
35+
WithLocationType(def.Query))
36+
reqDefBuilder.WithRequestField(def.NewFieldDef().
37+
WithName("Marker").
38+
WithJsonTag("marker").
39+
WithLocationType(def.Query))
40+
reqDefBuilder.WithRequestField(def.NewFieldDef().
41+
WithName("PageReverse").
42+
WithJsonTag("page_reverse").
43+
WithLocationType(def.Query))
44+
reqDefBuilder.WithRequestField(def.NewFieldDef().
45+
WithName("Id").
46+
WithJsonTag("id").
47+
WithLocationType(def.Query))
48+
reqDefBuilder.WithRequestField(def.NewFieldDef().
49+
WithName("Description").
50+
WithJsonTag("description").
51+
WithLocationType(def.Query))
52+
reqDefBuilder.WithRequestField(def.NewFieldDef().
53+
WithName("Name").
54+
WithJsonTag("name").
55+
WithLocationType(def.Query))
56+
reqDefBuilder.WithRequestField(def.NewFieldDef().
57+
WithName("OperatingStatus").
58+
WithJsonTag("operating_status").
59+
WithLocationType(def.Query))
60+
reqDefBuilder.WithRequestField(def.NewFieldDef().
61+
WithName("ProvisioningStatus").
62+
WithJsonTag("provisioning_status").
63+
WithLocationType(def.Query))
64+
reqDefBuilder.WithRequestField(def.NewFieldDef().
65+
WithName("VipAddress").
66+
WithJsonTag("vip_address").
67+
WithLocationType(def.Query))
68+
reqDefBuilder.WithRequestField(def.NewFieldDef().
69+
WithName("VipPortId").
70+
WithJsonTag("vip_port_id").
71+
WithLocationType(def.Query))
72+
reqDefBuilder.WithRequestField(def.NewFieldDef().
73+
WithName("VipSubnetId").
74+
WithJsonTag("vip_subnet_id").
75+
WithLocationType(def.Query))
76+
reqDefBuilder.WithRequestField(def.NewFieldDef().
77+
WithName("VpcId").
78+
WithJsonTag("vpc_id").
79+
WithLocationType(def.Query))
80+
reqDefBuilder.WithRequestField(def.NewFieldDef().
81+
WithName("EnterpriseProjectId").
82+
WithJsonTag("enterprise_project_id").
83+
WithLocationType(def.Query))
84+
reqDefBuilder.WithRequestField(def.NewFieldDef().
85+
WithName("AdminStateUp").
86+
WithJsonTag("admin_state_up").
87+
WithLocationType(def.Query))
88+
reqDefBuilder.WithRequestField(def.NewFieldDef().
89+
WithName("MemberAddress").
90+
WithJsonTag("member_address").
91+
WithLocationType(def.Query))
92+
reqDefBuilder.WithRequestField(def.NewFieldDef().
93+
WithName("MemberDeviceId").
94+
WithJsonTag("member_device_id").
95+
WithLocationType(def.Query))
96+
97+
requestDef := reqDefBuilder.Build()
98+
return requestDef
99+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// nolint: golint
2+
package model
3+
4+
import (
5+
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/utils"
6+
7+
"strings"
8+
)
9+
10+
// Response Object
11+
type ListLoadbalancersRsp struct {
12+
13+
// 负载均衡器对象列表
14+
Loadbalancers *[]Loadbalancer `json:"loadbalancers,omitempty"`
15+
HttpStatusCode int `json:"-"`
16+
}
17+
18+
func (o ListLoadbalancersRsp) String() string {
19+
data, err := utils.Marshal(o)
20+
if err != nil {
21+
return "ListLoadbalancersResponse struct{}"
22+
}
23+
24+
return strings.Join([]string{"ListLoadbalancersResponse", string(data)}, " ")
25+
}
26+
27+
type ShowLoadbalancerResponse struct {
28+
Loadbalancer *Loadbalancer `json:"loadbalancer,omitempty"`
29+
HttpStatusCode int `json:"-"`
30+
}
31+
32+
func (o ShowLoadbalancerResponse) String() string {
33+
data, err := utils.Marshal(o)
34+
if err != nil {
35+
return "ShowLoadbalancerResponse struct{}"
36+
}
37+
38+
return strings.Join([]string{"ShowLoadbalancerResponse", string(data)}, " ")
39+
}
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// nolint: golint
2+
package model
3+
4+
import (
5+
"errors"
6+
"strings"
7+
8+
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/utils"
9+
10+
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/converter"
11+
"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v2/model"
12+
)
13+
14+
// 负载均衡器响应体
15+
type Loadbalancer struct {
16+
17+
// 负载均衡器ID
18+
Id string `json:"id"`
19+
20+
// 负载均衡器所在的项目ID。
21+
TenantId string `json:"tenant_id"`
22+
23+
// 负载均衡器名称。
24+
Name string `json:"name"`
25+
26+
// 负载均衡器的描述信息
27+
Description string `json:"description"`
28+
29+
// 负载均衡器所在的子网的IPv4网络ID。仅支持内网类型。
30+
VipSubnetId string `json:"vip_subnet_id"`
31+
32+
// 负载均衡器虚拟IP对应的端口ID
33+
VipPortId string `json:"vip_port_id"`
34+
35+
// 负载均衡器的虚拟IP。
36+
VipAddress string `json:"vip_address"`
37+
38+
// 负载均衡器关联的监听器ID的列表
39+
Listeners []model.ResourceList `json:"listeners"`
40+
41+
// 负载均衡器关联的后端云服务器组ID的列表。
42+
Pools []model.ResourceList `json:"pools"`
43+
44+
// 负载均衡器的供应者名称。只支持vlb
45+
Provider string `json:"provider"`
46+
47+
// 负载均衡器的操作状态
48+
OperatingStatus LoadbalancerOperatingStatus `json:"operating_status"`
49+
50+
// 负载均衡器的配置状态
51+
ProvisioningStatus LoadbalancerProvisioningStatus `json:"provisioning_status"`
52+
53+
// 负载均衡器的管理状态。只支持设定为true,该字段的值无实际意义。
54+
AdminStateUp bool `json:"admin_state_up"`
55+
56+
// 负载均衡器的创建时间
57+
CreatedAt string `json:"created_at"`
58+
59+
// 负载均衡器的更新时间
60+
UpdatedAt string `json:"updated_at"`
61+
62+
// 负载均衡器的企业项目ID。
63+
EnterpriseProjectId string `json:"enterprise_project_id"`
64+
65+
// 负载均衡器所在的项目ID。
66+
ProjectId string `json:"project_id"`
67+
68+
// 负载均衡器的标签列表
69+
Tags []string `json:"tags"`
70+
71+
PublicIPs []PublicIP `json:"publicips"`
72+
}
73+
74+
func (o Loadbalancer) String() string {
75+
data, err := utils.Marshal(o)
76+
if err != nil {
77+
return "Loadbalancer struct{}"
78+
}
79+
80+
return strings.Join([]string{"Loadbalancer", string(data)}, " ")
81+
}
82+
83+
type LoadbalancerOperatingStatus struct {
84+
value string
85+
}
86+
87+
type LoadbalancerOperatingStatusEnum struct {
88+
ONLINE LoadbalancerOperatingStatus
89+
OFFLINE LoadbalancerOperatingStatus
90+
DEGRADED LoadbalancerOperatingStatus
91+
DISABLED LoadbalancerOperatingStatus
92+
NO_MONITOR LoadbalancerOperatingStatus
93+
}
94+
95+
func GetLoadbalancerOperatingStatusEnum() LoadbalancerOperatingStatusEnum {
96+
return LoadbalancerOperatingStatusEnum{
97+
ONLINE: LoadbalancerOperatingStatus{
98+
value: "ONLINE",
99+
},
100+
OFFLINE: LoadbalancerOperatingStatus{
101+
value: "OFFLINE",
102+
},
103+
DEGRADED: LoadbalancerOperatingStatus{
104+
value: "DEGRADED",
105+
},
106+
DISABLED: LoadbalancerOperatingStatus{
107+
value: "DISABLED",
108+
},
109+
NO_MONITOR: LoadbalancerOperatingStatus{
110+
value: "NO_MONITOR",
111+
},
112+
}
113+
}
114+
115+
func (c LoadbalancerOperatingStatus) Value() string {
116+
return c.value
117+
}
118+
119+
func (c LoadbalancerOperatingStatus) MarshalJSON() ([]byte, error) {
120+
return utils.Marshal(c.value)
121+
}
122+
123+
func (c *LoadbalancerOperatingStatus) UnmarshalJSON(b []byte) error {
124+
myConverter := converter.StringConverterFactory("string")
125+
if myConverter != nil {
126+
val, err := myConverter.CovertStringToInterface(strings.Trim(string(b[:]), "\""))
127+
if err == nil {
128+
c.value = val.(string)
129+
return nil
130+
}
131+
return err
132+
} else {
133+
return errors.New("convert enum data to string error")
134+
}
135+
}
136+
137+
type LoadbalancerProvisioningStatus struct {
138+
value string
139+
}
140+
141+
type LoadbalancerProvisioningStatusEnum struct {
142+
ACTIVE LoadbalancerProvisioningStatus
143+
PENDING_CREATE LoadbalancerProvisioningStatus
144+
ERROR LoadbalancerProvisioningStatus
145+
}
146+
147+
func GetLoadbalancerProvisioningStatusEnum() LoadbalancerProvisioningStatusEnum {
148+
return LoadbalancerProvisioningStatusEnum{
149+
ACTIVE: LoadbalancerProvisioningStatus{
150+
value: "ACTIVE",
151+
},
152+
PENDING_CREATE: LoadbalancerProvisioningStatus{
153+
value: "PENDING_CREATE",
154+
},
155+
ERROR: LoadbalancerProvisioningStatus{
156+
value: "ERROR",
157+
},
158+
}
159+
}
160+
161+
func (c LoadbalancerProvisioningStatus) Value() string {
162+
return c.value
163+
}
164+
165+
func (c LoadbalancerProvisioningStatus) MarshalJSON() ([]byte, error) {
166+
return utils.Marshal(c.value)
167+
}
168+
169+
func (c *LoadbalancerProvisioningStatus) UnmarshalJSON(b []byte) error {
170+
myConverter := converter.StringConverterFactory("string")
171+
if myConverter != nil {
172+
val, err := myConverter.CovertStringToInterface(strings.Trim(string(b[:]), "\""))
173+
if err == nil {
174+
c.value = val.(string)
175+
return nil
176+
}
177+
return err
178+
} else {
179+
return errors.New("convert enum data to string error")
180+
}
181+
}
182+
183+
type PublicIP struct {
184+
ID string `json:"publicip_id"`
185+
Address string `json:"publicip_address"`
186+
IPVersion int `json:"ip_version"`
187+
}

0 commit comments

Comments
 (0)