yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/openstack/loadbalancerlistener.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package openstack 16 17 import ( 18 "context" 19 "fmt" 20 "net/url" 21 "strconv" 22 "time" 23 24 "github.com/coredns/coredns/plugin/pkg/log" 25 26 "yunion.io/x/jsonutils" 27 "yunion.io/x/pkg/errors" 28 29 api "yunion.io/x/cloudmux/pkg/apis/compute" 30 "yunion.io/x/cloudmux/pkg/cloudprovider" 31 "yunion.io/x/cloudmux/pkg/multicloud" 32 ) 33 34 type SLoadbalancerListenerCreateParams struct { 35 Protocol string `json:"protocol,omitempty"` 36 Description string `json:"description,omitempty"` 37 AdminStateUp bool `json:"admin_state_up,omitempty"` 38 ConnectionLimit *int `json:"connection_limit,omitempty"` 39 ProtocolPort string `json:"protocol_port,omitempty"` 40 LoadbalancerID string `json:"loadbalancer_id,omitempty"` 41 DefaultPoolId string `json:"default_pool_id,omitempty"` 42 Name string `json:"name,omitempty"` 43 InsertHeaders SInsertHeaders `json:"insert_headers,omitempty"` 44 DefaultTLSContainerRef string `json:"default_tls_container_ref,omitempty"` 45 SniContainerRefs []string `json:"sni_container_refs,omitempty"` 46 TimeoutClientData *int `json:"timeout_client_data,omitempty"` 47 TimeoutMemberConnect *int `json:"timeout_member_connect,omitempty"` 48 TimeoutMemberData *int `json:"timeout_member_data,omitempty"` 49 TimeoutTCPInspect *int `json:"timeout_tcp_inspect,omitempty"` 50 Tags []string `json:"tags,omitempty"` 51 ClientCaTLSContainerRef string `json:"client_ca_tls_container_ref,omitempty"` 52 ClientAuthentication string `json:"client_authentication,omitempty"` 53 ClientCrlContainerRef string `json:"client_crl_container_ref,omitempty"` 54 AllowedCidrs []string `json:"allowed_cidrs,omitempty"` 55 TLSCiphers string `json:"tls_ciphers,omitempty"` 56 TLSVersions []string `json:"tls_versions,omitempty"` 57 } 58 59 type SLoadbalancerListenerUpdateParams struct { 60 Description string `json:"description,omitempty"` 61 AdminStateUp bool `json:"admin_state_up,omitempty"` 62 ConnectionLimit *int `json:"connection_limit,omitempty"` 63 DefaultPoolId string `json:"default_pool_id,omitempty"` 64 Name string `json:"name,omitempty"` 65 InsertHeaders SInsertHeaders `json:"insert_headers,omitempty"` 66 DefaultTLSContainerRef string `json:"default_tls_container_ref,omitempty"` 67 SniContainerRefs []string `json:"sni_container_refs,omitempty"` 68 TimeoutClientData *int `json:"timeout_client_data,omitempty"` 69 TimeoutMemberConnect *int `json:"timeout_member_connect,omitempty"` 70 TimeoutMemberData *int `json:"timeout_member_data,omitempty"` 71 TimeoutTCPInspect *int `json:"timeout_tcp_inspect,omitempty"` 72 Tags []string `json:"tags,omitempty"` 73 ClientCaTLSContainerRef string `json:"client_ca_tls_container_ref,omitempty"` 74 ClientAuthentication string `json:"client_authentication,omitempty"` 75 ClientCrlContainerRef string `json:"client_crl_container_ref,omitempty"` 76 AllowedCidrs []string `json:"allowed_cidrs,omitempty"` 77 TLSCiphers string `json:"tls_ciphers,omitempty"` 78 TLSVersions []string `json:"tls_versions,omitempty"` 79 } 80 81 type SInsertHeaders struct { 82 XForwardedPort string `json:"X-Forwarded-Port"` 83 XForwardedFor string `json:"X-Forwarded-For"` 84 } 85 86 type SLoadbalancerListener struct { 87 multicloud.SResourceBase 88 multicloud.SLoadbalancerRedirectBase 89 OpenStackTags 90 region *SRegion 91 l7policies []SLoadbalancerL7Policy 92 pools []SLoadbalancerPool 93 Description string `json:"description"` 94 AdminStateUp bool `json:"admin_state_up"` 95 ProjectID string `json:"project_id"` 96 Protocol string `json:"protocol"` 97 ProtocolPort int `json:"protocol_port"` 98 ProvisioningStatus string `json:"provisioning_status"` 99 DefaultTLSContainerRef string `json:"default_tls_container_ref"` 100 LoadbalancerIds []SLoadbalancerID `json:"loadbalancers"` 101 InsertHeaders SInsertHeaders `json:"insert_headers"` 102 CreatedAt string `json:"created_at"` 103 UpdatedAt string `json:"updated_at"` 104 ID string `json:"id"` 105 OperatingStatus string `json:"operating_status"` 106 DefaultPoolID string `json:"default_pool_id"` 107 SniContainerRefs []string `json:"sni_container_refs"` 108 L7PolicieIds []SL7PolicieID `json:"l7policies"` 109 Name string `json:"name"` 110 TimeoutClientData int `json:"timeout_client_data"` 111 TimeoutMemberConnect int `json:"timeout_member_connect"` 112 TimeoutMemberData int `json:"timeout_member_data"` 113 TimeoutTCPInspect int `json:"timeout_tcp_inspect"` 114 Tags []string `json:"tags"` 115 ClientCaTLSContainerRef string `json:"client_ca_tls_container_ref"` 116 ClientAuthentication string `json:"client_authentication"` 117 ClientCrlContainerRef string `json:"client_crl_container_ref"` 118 AllowedCidrs []string `json:"allowed_cidrs"` 119 TLSCiphers string `json:"tls_ciphers"` 120 TLSVersions []string `json:"tls_versions"` 121 } 122 123 func (listener *SLoadbalancerListener) GetName() string { 124 if len(listener.Name) == 0 { 125 listener.Refresh() 126 } 127 if len(listener.Name) > 0 { 128 return listener.Name 129 } 130 return fmt.Sprintf("HTTP:%d", listener.ProtocolPort) 131 } 132 133 func (listener *SLoadbalancerListener) GetId() string { 134 return listener.ID 135 } 136 137 func (listener *SLoadbalancerListener) GetGlobalId() string { 138 return listener.GetId() 139 } 140 141 func (listener *SLoadbalancerListener) GetStatus() string { 142 switch listener.ProvisioningStatus { 143 case "ACTIVE": 144 return api.LB_STATUS_ENABLED 145 case "PENDING_CREATE": 146 return api.LB_CREATING 147 case "PENDING_UPDATE": 148 return api.LB_SYNC_CONF 149 case "PENDING_DELETE": 150 return api.LB_STATUS_DELETING 151 case "DELETED": 152 return api.LB_STATUS_DELETED 153 default: 154 return api.LB_STATUS_UNKNOWN 155 } 156 } 157 158 func (listener *SLoadbalancerListener) IsEmulated() bool { 159 return false 160 } 161 162 func (listener *SLoadbalancerListener) GetEgressMbps() int { 163 164 return 0 165 } 166 167 func (region *SRegion) GetLoadbalancerListeners() ([]SLoadbalancerListener, error) { 168 listeners := []SLoadbalancerListener{} 169 resource := "/v2/lbaas/listeners" 170 query := url.Values{} 171 for { 172 resp, err := region.lbList(resource, query) 173 if err != nil { 174 return nil, errors.Wrap(err, "lbList") 175 } 176 part := struct { 177 Listeners []SLoadbalancerListener 178 ListenersLinks SNextLinks 179 }{} 180 err = resp.Unmarshal(&part) 181 if err != nil { 182 return nil, errors.Wrap(err, "resp.Unmarshal") 183 } 184 listeners = append(listeners, part.Listeners...) 185 marker := part.ListenersLinks.GetNextMark() 186 if len(marker) == 0 { 187 break 188 } 189 query.Set("marker", marker) 190 } 191 192 for i := 0; i < len(listeners); i++ { 193 listeners[i].region = region 194 } 195 for i := 0; i < len(listeners); i++ { 196 err := listeners[i].fetchLoadbalancerListenerL7Policies() 197 if err != nil { 198 return nil, errors.Wrap(err, "listener.fetchLoadbalancerListenerL7Policies()") 199 } 200 } 201 202 for i := 0; i < len(listeners); i++ { 203 err := listeners[i].fetchLoadbalancerPools() 204 if err != nil { 205 return nil, errors.Wrap(err, "listeners[i].fetchLoadbalancerPools()") 206 } 207 } 208 209 return listeners, nil 210 } 211 212 func (region *SRegion) GetLoadbalancerListenerbyId(listenerId string) (*SLoadbalancerListener, error) { 213 resp, err := region.lbGet(fmt.Sprintf("/v2/lbaas/listeners/%s", listenerId)) 214 if err != nil { 215 return nil, errors.Wrapf(err, "region.Get(/v2/lbaas/listeners/%s)", listenerId) 216 } 217 listener := SLoadbalancerListener{} 218 err = resp.Unmarshal(&listener, "listener") 219 if err != nil { 220 return nil, errors.Wrap(err, "resp.Unmarshal(&listener, listener)") 221 } 222 listener.region = region 223 err = listener.fetchLoadbalancerListenerL7Policies() 224 if err != nil { 225 return nil, errors.Wrap(err, "listener.fetchLoadbalancerListenerL7Policies()") 226 } 227 228 err = listener.fetchLoadbalancerPools() 229 if err != nil { 230 return nil, errors.Wrap(err, "listeners[i].fetchLoadbalancerPools()") 231 232 } 233 return &listener, nil 234 } 235 236 func (region *SRegion) CreateLoadbalancerListener(loadbalancerId string, listenerParams *cloudprovider.SLoadbalancerListener) (*SLoadbalancerListener, error) { 237 type CreateParams struct { 238 Listener SLoadbalancerListenerCreateParams `json:"listener"` 239 } 240 params := CreateParams{} 241 params.Listener.AdminStateUp = true 242 params.Listener.LoadbalancerID = loadbalancerId 243 params.Listener.DefaultPoolId = listenerParams.BackendGroupID 244 params.Listener.Protocol = LB_PROTOCOL_MAP[listenerParams.ListenerType] 245 params.Listener.ProtocolPort = strconv.Itoa(listenerParams.ListenerPort) 246 if listenerParams.ClientIdleTimeout != 0 { 247 // 毫秒单位 248 msClientIdleTimeout := listenerParams.ClientIdleTimeout * 1000 249 params.Listener.TimeoutClientData = &msClientIdleTimeout 250 } 251 if listenerParams.BackendConnectTimeout != 0 { 252 msBackendConnectTimeout := listenerParams.BackendConnectTimeout * 1000 253 params.Listener.TimeoutMemberConnect = &msBackendConnectTimeout 254 } 255 if listenerParams.BackendIdleTimeout != 0 { 256 msBackendIdleTimeout := listenerParams.BackendIdleTimeout * 1000 257 params.Listener.TimeoutMemberData = &msBackendIdleTimeout 258 } 259 260 params.Listener.Name = listenerParams.Name 261 if listenerParams.XForwardedFor { 262 params.Listener.InsertHeaders.XForwardedFor = "true" 263 } 264 body, err := region.lbPost("/v2/lbaas/listeners", jsonutils.Marshal(params)) 265 if err != nil { 266 return nil, errors.Wrap(err, "region.Post(/v2/lbaas/listeners)") 267 } 268 slistener := SLoadbalancerListener{} 269 slistener.region = region 270 return &slistener, body.Unmarshal(&slistener, "listener") 271 } 272 273 func (listener *SLoadbalancerListener) Refresh() error { 274 newlistener, err := listener.region.GetLoadbalancerListenerbyId(listener.ID) 275 if err != nil { 276 return errors.Wrapf(err, "listener.region.GetLoadbalancerListenerbyId(%s)", listener.ID) 277 } 278 return jsonutils.Update(listener, newlistener) 279 } 280 281 func (listener *SLoadbalancerListener) GetListenerType() string { 282 switch listener.Protocol { 283 case "HTTP": 284 return api.LB_LISTENER_TYPE_HTTP 285 case "HTTPS": 286 return api.LB_LISTENER_TYPE_HTTPS 287 case "TERMINATED_HTTPS": 288 return api.LB_LISTENER_TYPE_TERMINATED_HTTPS 289 case "TCP": 290 return api.LB_LISTENER_TYPE_TCP 291 case "UDP": 292 return api.LB_LISTENER_TYPE_UDP 293 default: 294 return "" 295 } 296 } 297 298 func (listener *SLoadbalancerListener) GetListenerPort() int { 299 return listener.ProtocolPort 300 } 301 302 func (listener *SLoadbalancerListener) GetBackendGroupId() string { 303 return listener.DefaultPoolID 304 } 305 306 func (listener *SLoadbalancerListener) GetBackendServerPort() int { 307 return listener.ProtocolPort 308 } 309 310 func (listener *SLoadbalancerListener) GetScheduler() string { 311 pool, err := listener.fetchFeaturePool() 312 if err != nil { 313 log.Errorf("GetScheduler():listener.fetchFeaturePool():%s", err) 314 return "" 315 } 316 switch pool.LbAlgorithm { 317 case "ROUND_ROBIN": 318 return api.LB_SCHEDULER_WRR 319 case "LEAST_CONNECTIONS": 320 return api.LB_SCHEDULER_WLC 321 case "SOURCE_IP": 322 return api.LB_SCHEDULER_SCH 323 case "SOURCE_IP_PORT": 324 return api.LB_SCHEDULER_TCH 325 default: 326 return "" 327 } 328 } 329 330 func (listener *SLoadbalancerListener) GetAclStatus() string { 331 if len(listener.AllowedCidrs) > 0 { 332 return api.LB_BOOL_ON 333 } 334 return api.LB_BOOL_OFF 335 } 336 337 func (listener *SLoadbalancerListener) GetAclType() string { 338 return api.LB_ACL_TYPE_WHITE 339 } 340 341 func (listener *SLoadbalancerListener) GetAclId() string { 342 return "" 343 } 344 345 func (listener *SLoadbalancerListener) GetHealthCheck() string { 346 pool, err := listener.fetchFeaturePool() 347 if err != nil { 348 log.Errorf("GetHealthCheck():listener.fetchFeaturePool():%s", err) 349 return "" 350 } 351 if pool.healthmonitor != nil { 352 return api.LB_BOOL_ON 353 } 354 return api.LB_BOOL_OFF 355 356 } 357 358 func (listener *SLoadbalancerListener) GetHealthCheckType() string { 359 pool, err := listener.fetchFeaturePool() 360 if err != nil { 361 log.Errorf("GetHealthCheckType():listener.fetchFeaturePool():%s", err) 362 return "" 363 } 364 if pool.healthmonitor == nil { 365 return "" 366 } 367 switch pool.healthmonitor.Type { 368 case "HTTP": 369 return api.LB_HEALTH_CHECK_HTTP 370 case "HTTPS": 371 return api.LB_HEALTH_CHECK_HTTPS 372 case "TCP": 373 return api.LB_HEALTH_CHECK_TCP 374 case "UDP-CONNECT": 375 return api.LB_HEALTH_CHECK_UDP 376 default: 377 return "" 378 } 379 } 380 381 func (listener *SLoadbalancerListener) GetHealthCheckDomain() string { 382 pool, err := listener.fetchFeaturePool() 383 if err != nil { 384 log.Errorf("GetHealthCheckDomain():listener.fetchFeaturePool():%s", err) 385 return "" 386 } 387 if pool.healthmonitor == nil { 388 return "" 389 } 390 return pool.healthmonitor.DomainName 391 } 392 393 func (listener *SLoadbalancerListener) GetHealthCheckURI() string { 394 pool, err := listener.fetchFeaturePool() 395 if err != nil { 396 log.Errorf("GetHealthCheckURI():listener.fetchFeaturePool():%s", err) 397 return "" 398 } 399 if pool.healthmonitor == nil { 400 return "" 401 } 402 return pool.healthmonitor.URLPath 403 } 404 405 func (listener *SLoadbalancerListener) GetHealthCheckCode() string { 406 pool, err := listener.fetchFeaturePool() 407 if err != nil { 408 log.Errorf("GetHealthCheckCode():listener.fetchFeaturePool():%s", err) 409 return "" 410 } 411 if pool.healthmonitor == nil { 412 return "" 413 } 414 return pool.healthmonitor.ExpectedCodes 415 } 416 417 func (listener *SLoadbalancerListener) GetHealthCheckRise() int { 418 pool, err := listener.fetchFeaturePool() 419 if err != nil { 420 log.Errorf("GetHealthCheckRise():listener.fetchFeaturePool():%s", err) 421 return 0 422 } 423 if pool.healthmonitor == nil { 424 return 0 425 } 426 return pool.healthmonitor.MaxRetries 427 } 428 429 func (listener *SLoadbalancerListener) GetHealthCheckFail() int { 430 pool, err := listener.fetchFeaturePool() 431 if err != nil { 432 log.Errorf("GetHealthCheckFail():listener.fetchFeaturePool():%s", err) 433 return 0 434 } 435 if pool.healthmonitor == nil { 436 return 0 437 } 438 return pool.healthmonitor.MaxRetriesDown 439 } 440 441 func (listener *SLoadbalancerListener) GetHealthCheckTimeout() int { 442 pool, err := listener.fetchFeaturePool() 443 if err != nil { 444 log.Errorf("GetHealthCheckTimeout():listener.fetchFeaturePool():%s", err) 445 return 0 446 } 447 if pool.healthmonitor == nil { 448 return 0 449 } 450 return pool.healthmonitor.Timeout 451 } 452 453 func (listener *SLoadbalancerListener) GetHealthCheckInterval() int { 454 pool, err := listener.fetchFeaturePool() 455 if err != nil { 456 log.Errorf("GetHealthCheckInterval():listener.fetchFeaturePool():%s", err) 457 return 0 458 } 459 if pool.healthmonitor == nil { 460 return 0 461 } 462 return pool.healthmonitor.Delay 463 } 464 465 func (listener *SLoadbalancerListener) GetHealthCheckReq() string { 466 return "" 467 } 468 469 func (listener *SLoadbalancerListener) GetHealthCheckExp() string { 470 return "" 471 } 472 473 func (listener *SLoadbalancerListener) GetStickySession() string { 474 pool, err := listener.fetchFeaturePool() 475 if err != nil { 476 log.Errorf("GetStickySession():listener.fetchFeaturePool():%s", err) 477 return api.LB_BOOL_OFF 478 } 479 stickySession, err := pool.GetStickySession() 480 if err != nil { 481 log.Errorf("GetStickySession():listener.fetchFeaturePool():%s", err) 482 return api.LB_BOOL_OFF 483 } 484 if stickySession == nil { 485 return "" 486 } 487 return stickySession.StickySession 488 } 489 490 func (listener *SLoadbalancerListener) GetStickySessionType() string { 491 pool, err := listener.fetchFeaturePool() 492 if err != nil { 493 log.Errorf("GetStickySession():listener.fetchFeaturePool():%s", err) 494 return "" 495 } 496 stickySession, err := pool.GetStickySession() 497 if err != nil { 498 log.Errorf("GetStickySession():listener.fetchFeaturePool():%s", err) 499 return "" 500 } 501 if stickySession == nil { 502 return "" 503 } 504 return stickySession.StickySessionType 505 } 506 507 func (listener *SLoadbalancerListener) GetStickySessionCookie() string { 508 pool, err := listener.fetchFeaturePool() 509 if err != nil { 510 log.Errorf("GetStickySession():listener.fetchFeaturePool():%s", err) 511 return "" 512 } 513 stickySession, err := pool.GetStickySession() 514 if err != nil { 515 log.Errorf("GetStickySession():listener.fetchFeaturePool():%s", err) 516 return "" 517 } 518 if stickySession == nil { 519 return "" 520 } 521 return stickySession.StickySessionCookie 522 } 523 524 func (listener *SLoadbalancerListener) GetStickySessionCookieTimeout() int { 525 pool, err := listener.fetchFeaturePool() 526 if err != nil { 527 log.Errorf("GetStickySession():listener.fetchFeaturePool():%s", err) 528 return 0 529 } 530 stickySession, err := pool.GetStickySession() 531 if err != nil { 532 log.Errorf("GetStickySession():listener.fetchFeaturePool():%s", err) 533 return 0 534 } 535 if stickySession == nil { 536 return 0 537 } 538 return stickySession.StickySessionCookieTimeout 539 } 540 541 func (listener *SLoadbalancerListener) XForwardedForEnabled() bool { 542 if listener.InsertHeaders.XForwardedFor == "true" { 543 return true 544 } 545 return false 546 } 547 548 func (listener *SLoadbalancerListener) GzipEnabled() bool { 549 return false 550 } 551 552 func (listener *SLoadbalancerListener) GetCertificateId() string { 553 return "" 554 } 555 556 func (listener *SLoadbalancerListener) GetTLSCipherPolicy() string { 557 return listener.TLSCiphers 558 } 559 560 func (listener *SLoadbalancerListener) HTTP2Enabled() bool { 561 return false 562 } 563 564 func (listener *SLoadbalancerListener) fetchLoadbalancerListenerL7Policies() error { 565 l7policies := []SLoadbalancerL7Policy{} 566 for i := 0; i < len(listener.L7PolicieIds); i++ { 567 l7policy, err := listener.region.GetLoadbalancerL7PolicybyId(listener.L7PolicieIds[i].ID) 568 if err != nil { 569 return errors.Wrapf(err, "listener.region.GetLoadbalancerL7PolicybyId(%s)", listener.L7PolicieIds[i].ID) 570 } 571 l7policies = append(l7policies, *l7policy) 572 } 573 listener.l7policies = l7policies 574 return nil 575 } 576 577 func (listener *SLoadbalancerListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) { 578 iRules := []cloudprovider.ICloudLoadbalancerListenerRule{} 579 for i := 0; i < len(listener.l7policies); i++ { 580 for j := 0; j < len(listener.l7policies[i].l7rules); j++ { 581 iRules = append(iRules, &listener.l7policies[i].l7rules[j]) 582 } 583 } 584 return iRules, nil 585 } 586 587 func (region *SRegion) DeleteLoadbalancerListener(listenerId string) error { 588 _, err := region.lbDelete(fmt.Sprintf("/v2/lbaas/listeners/%s", listenerId)) 589 if err != nil { 590 return errors.Wrapf(err, `region.lbDelete("/v2/lbaas/listeners/%s")`, listenerId) 591 } 592 return nil 593 } 594 595 func (listener *SLoadbalancerListener) Delete(ctx context.Context) error { 596 waitLbResStatus(listener, 10*time.Second, 1*time.Minute) 597 return listener.region.DeleteLoadbalancerListener(listener.ID) 598 } 599 600 func (listener *SLoadbalancerListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) { 601 l7policy, err := listener.region.CreateLoadbalancerL7Policy(listener.ID, rule) 602 if err != nil { 603 return nil, errors.Wrapf(err, `listener.region.CreateLoadbalancerL7Policy(%s, rule)`, listener.ID) 604 } 605 // async wait 606 err = waitLbResStatus(l7policy, 10*time.Second, 8*time.Minute) 607 if err != nil { 608 return nil, errors.Wrap(err, `waitLbResStatus(l7policy, 10*time.Second, 8*time.Minute)`) 609 } 610 611 l7rule, err := listener.region.CreateLoadbalancerL7Rule(l7policy.ID, rule) 612 if err != nil { 613 return nil, errors.Wrapf(err, `listener.region.CreateLoadbalancerL7Rule(%s, rule)`, l7policy.ID) 614 } 615 l7rule.policy = l7policy 616 // async wait 617 err = waitLbResStatus(l7rule, 10*time.Second, 8*time.Minute) 618 if err != nil { 619 return nil, errors.Wrap(err, `waitLbResStatus(l7rule, 10*time.Second, 8*time.Minute)`) 620 } 621 return l7rule, nil 622 } 623 624 func (listener *SLoadbalancerListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) { 625 for i := 0; i < len(listener.l7policies); i++ { 626 for j := 0; j < len(listener.l7policies[i].l7rules); j++ { 627 if listener.l7policies[i].l7rules[j].GetId() == ruleId { 628 return &listener.l7policies[i].l7rules[j], nil 629 } 630 } 631 } 632 return nil, nil 633 } 634 635 func (listener *SLoadbalancerListener) fetchLoadbalancerPools() error { 636 pools := []SLoadbalancerPool{} 637 if len(listener.DefaultPoolID) > 0 { 638 defaultPool, err := listener.region.GetLoadbalancerPoolById(listener.DefaultPoolID) 639 if err != nil { 640 return errors.Wrapf(err, "listener.region.GetLoadbalancerPoolById(%s)", listener.DefaultPoolID) 641 } 642 pools = append(pools, *defaultPool) 643 } 644 for i := 0; i < len(listener.l7policies); i++ { 645 if len(listener.l7policies[i].RedirectPoolID) > 0 { 646 policyPool, err := listener.region.GetLoadbalancerPoolById(listener.l7policies[i].RedirectPoolID) 647 if err != nil { 648 return errors.Wrapf(err, "listener.region.GetLoadbalancerPoolById(%s)", listener.l7policies[i].RedirectPoolID) 649 } 650 pools = append(pools, *policyPool) 651 } 652 } 653 listener.pools = pools 654 return nil 655 } 656 657 func (listener *SLoadbalancerListener) fetchFeaturePool() (*SLoadbalancerPool, error) { 658 if len(listener.pools) < 1 { 659 return nil, fmt.Errorf("can't find pool with healthmonitor") 660 } 661 for i := 0; i < len(listener.pools); i++ { 662 if listener.pools[i].healthmonitor != nil { 663 return &listener.pools[i], nil 664 } 665 } 666 return &listener.pools[0], nil 667 } 668 669 func (region *SRegion) UpdateLoadBalancerListenerAdminStateUp(AdminStateUp bool, loadbalancerListenerId string) error { 670 params := jsonutils.NewDict() 671 poolParam := jsonutils.NewDict() 672 poolParam.Add(jsonutils.NewBool(AdminStateUp), "admin_state_up") 673 params.Add(poolParam, "listener") 674 _, err := region.lbUpdate(fmt.Sprintf("/v2/lbaas/listeners/%s", loadbalancerListenerId), params) 675 if err != nil { 676 return errors.Wrapf(err, `region.lbUpdate(/v2/lbaas/listeners/%s, params)`, loadbalancerListenerId) 677 } 678 return nil 679 } 680 681 func (region *SRegion) UpdateLoadBalancerListener(loadbalancerListenerId string, lblis *cloudprovider.SLoadbalancerListener) error { 682 type UpdateParams struct { 683 Listener SLoadbalancerListenerUpdateParams `json:"listener"` 684 } 685 params := UpdateParams{} 686 params.Listener.AdminStateUp = true 687 params.Listener.DefaultPoolId = lblis.BackendGroupID 688 689 if lblis.ClientIdleTimeout != 0 { 690 // 毫秒单位 691 msClientIdleTimeout := lblis.ClientIdleTimeout * 1000 692 params.Listener.TimeoutClientData = &msClientIdleTimeout 693 } 694 if lblis.BackendConnectTimeout != 0 { 695 msBackendConnectTimeout := lblis.BackendConnectTimeout * 1000 696 params.Listener.TimeoutMemberConnect = &msBackendConnectTimeout 697 } 698 if lblis.BackendIdleTimeout != 0 { 699 msBackendIdleTimeout := lblis.BackendIdleTimeout * 1000 700 params.Listener.TimeoutMemberData = &msBackendIdleTimeout 701 } 702 params.Listener.Name = lblis.Name 703 if lblis.XForwardedFor { 704 params.Listener.InsertHeaders.XForwardedFor = "true" 705 } 706 _, err := region.lbUpdate(fmt.Sprintf("/v2/lbaas/listeners/%s", loadbalancerListenerId), jsonutils.Marshal(params)) 707 if err != nil { 708 return errors.Wrapf(err, `region.lbUpdate(/v2/lbaas/listeners/%s, jsonutils.Marshal(params))`, loadbalancerListenerId) 709 } 710 return nil 711 } 712 713 func (listener *SLoadbalancerListener) Start() error { 714 // ensure listener status 715 err := waitLbResStatus(listener, 10*time.Second, 8*time.Minute) 716 if err != nil { 717 return errors.Wrap(err, ` waitLbResStatus(listener, 10*time.Second, 8*time.Minute)`) 718 } 719 err = listener.region.UpdateLoadBalancerListenerAdminStateUp(true, listener.ID) 720 if err != nil { 721 return errors.Wrapf(err, `listener.region.UpdateLoadBalancerListenerAdminStateUp(true, %s)`, listener.ID) 722 } 723 err = waitLbResStatus(listener, 10*time.Second, 8*time.Minute) 724 if err != nil { 725 return errors.Wrap(err, `waitLbResStatus(listener, 10*time.Second, 8*time.Minute)`) 726 } 727 return nil 728 } 729 730 func (listener *SLoadbalancerListener) Stop() error { 731 // ensure listener status 732 err := waitLbResStatus(listener, 10*time.Second, 8*time.Minute) 733 if err != nil { 734 return errors.Wrap(err, ` waitLbResStatus(listener, 10*time.Second, 8*time.Minute)`) 735 } 736 err = listener.region.UpdateLoadBalancerListenerAdminStateUp(false, listener.ID) 737 if err != nil { 738 return errors.Wrapf(err, `listener.region.UpdateLoadBalancerListenerAdminStateUp(false,%s)`, listener.ID) 739 } 740 err = waitLbResStatus(listener, 10*time.Second, 8*time.Minute) 741 if err != nil { 742 return errors.Wrap(err, `waitLbResStatus(listener, 10*time.Second, 8*time.Minute)`) 743 } 744 return nil 745 } 746 747 func (listener *SLoadbalancerListener) Sync(ctx context.Context, lblis *cloudprovider.SLoadbalancerListener) error { 748 // ensure listener status 749 err := waitLbResStatus(listener, 10*time.Second, 8*time.Minute) 750 if err != nil { 751 return errors.Wrap(err, ` waitLbResStatus(listener, 10*time.Second, 8*time.Minute)`) 752 } 753 err = listener.region.UpdateLoadBalancerListener(listener.ID, lblis) 754 if err != nil { 755 return errors.Wrapf(err, `listener.region.UpdateLoadBalancerListener(%s, lblis)`, listener.ID) 756 } 757 err = waitLbResStatus(listener, 10*time.Second, 8*time.Minute) 758 if err != nil { 759 return errors.Wrap(err, `waitLbResStatus(listener, 10*time.Second, 8*time.Minute)`) 760 } 761 return nil 762 } 763 764 func (listener *SLoadbalancerListener) GetProjectId() string { 765 return listener.ProjectID 766 } 767 768 func (listener *SLoadbalancerListener) GetClientIdleTimeout() int { 769 return 0 770 } 771 772 func (listener *SLoadbalancerListener) GetBackendConnectTimeout() int { 773 return 0 774 }