Skip to content

Commit

Permalink
Add l7policies (#82)
Browse files Browse the repository at this point in the history
  • Loading branch information
niuzhenguo authored Feb 2, 2019
1 parent 99ef5e3 commit 0948a40
Show file tree
Hide file tree
Showing 904 changed files with 349,636 additions and 7 deletions.
238 changes: 238 additions & 0 deletions huaweicloud/lb_v2_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,22 @@ import (
"github.com/hashicorp/terraform/helper/schema"

"github.com/huaweicloud/golangsdk"
"github.com/huaweicloud/golangsdk/openstack/networking/v2/extensions/lbaas_v2/l7policies"
"github.com/huaweicloud/golangsdk/openstack/networking/v2/extensions/lbaas_v2/listeners"
"github.com/huaweicloud/golangsdk/openstack/networking/v2/extensions/lbaas_v2/loadbalancers"
"github.com/huaweicloud/golangsdk/openstack/networking/v2/extensions/lbaas_v2/monitors"
"github.com/huaweicloud/golangsdk/openstack/networking/v2/extensions/lbaas_v2/pools"
)

// lbPendingStatuses are the valid statuses a LoadBalancer will be in while
// it's updating.
var lbPendingStatuses = []string{"PENDING_CREATE", "PENDING_UPDATE"}

// lbPendingDeleteStatuses are the valid statuses a LoadBalancer will be before delete
var lbPendingDeleteStatuses = []string{"ERROR", "PENDING_UPDATE", "PENDING_DELETE", "ACTIVE"}

var lbSkipLBStatuses = []string{"ERROR", "ACTIVE"}

func waitForLBV2Listener(networkingClient *golangsdk.ServiceClient, id string, target string, pending []string, timeout time.Duration) error {
log.Printf("[DEBUG] Waiting for listener %s to become %s.", id, target)

Expand Down Expand Up @@ -249,3 +259,231 @@ func chooseLBV2Client(d *schema.ResourceData, config *Config) (*golangsdk.Servic
}
return config.networkingV2Client(GetRegion(d, config))
}

func resourceLBV2LoadBalancerStatusRefreshFuncNeutron(lbClient *golangsdk.ServiceClient, lbID, resourceType, resourceID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
statuses, err := loadbalancers.GetStatuses(lbClient, lbID).Extract()
if err != nil {
return nil, "", fmt.Errorf("Unable to get statuses from the Load Balancer %s statuses tree: %s", lbID, err)
}

if !strSliceContains(lbSkipLBStatuses, statuses.Loadbalancer.ProvisioningStatus) {
return statuses.Loadbalancer, statuses.Loadbalancer.ProvisioningStatus, nil
}

switch resourceType {
case "listener":
for _, listener := range statuses.Loadbalancer.Listeners {
if listener.ID == resourceID {
if listener.ProvisioningStatus != "" {
return listener, listener.ProvisioningStatus, nil
}
}
}
listener, err := listeners.Get(lbClient, resourceID).Extract()
return listener, "ACTIVE", err

case "pool":
for _, pool := range statuses.Loadbalancer.Pools {
if pool.ID == resourceID {
if pool.ProvisioningStatus != "" {
return pool, pool.ProvisioningStatus, nil
}
}
}
pool, err := pools.Get(lbClient, resourceID).Extract()
return pool, "ACTIVE", err

case "monitor":
for _, pool := range statuses.Loadbalancer.Pools {
if pool.Monitor.ID == resourceID {
if pool.Monitor.ProvisioningStatus != "" {
return pool.Monitor, pool.Monitor.ProvisioningStatus, nil
}
}
}
monitor, err := monitors.Get(lbClient, resourceID).Extract()
return monitor, "ACTIVE", err

case "member":
for _, pool := range statuses.Loadbalancer.Pools {
for _, member := range pool.Members {
if member.ID == resourceID {
if member.ProvisioningStatus != "" {
return member, member.ProvisioningStatus, nil
}
}
}
}
return "", "DELETED", nil

case "l7policy":
for _, listener := range statuses.Loadbalancer.Listeners {
for _, l7policy := range listener.L7Policies {
if l7policy.ID == resourceID {
if l7policy.ProvisioningStatus != "" {
return l7policy, l7policy.ProvisioningStatus, nil
}
}
}
}
l7policy, err := l7policies.Get(lbClient, resourceID).Extract()
return l7policy, "ACTIVE", err

case "l7rule":
for _, listener := range statuses.Loadbalancer.Listeners {
for _, l7policy := range listener.L7Policies {
for _, l7rule := range l7policy.Rules {
if l7rule.ID == resourceID {
if l7rule.ProvisioningStatus != "" {
return l7rule, l7rule.ProvisioningStatus, nil
}
}
}
}
}
return "", "DELETED", nil
}

return nil, "", fmt.Errorf("An unexpected error occurred querying the status of %s %s by loadbalancer %s", resourceType, resourceID, lbID)
}
}

func resourceLBV2L7PolicyRefreshFunc(lbClient *golangsdk.ServiceClient, lbID string, l7policy *l7policies.L7Policy) resource.StateRefreshFunc {
if l7policy.ProvisioningStatus != "" {
return func() (interface{}, string, error) {
lb, status, err := resourceLBV2LoadBalancerRefreshFunc(lbClient, lbID)()
if err != nil {
return lb, status, err
}
if !strSliceContains(lbSkipLBStatuses, status) {
return lb, status, nil
}

l7policy, err := l7policies.Get(lbClient, l7policy.ID).Extract()
if err != nil {
return nil, "", err
}

return l7policy, l7policy.ProvisioningStatus, nil
}
}

return resourceLBV2LoadBalancerStatusRefreshFuncNeutron(lbClient, lbID, "l7policy", l7policy.ID)
}

func waitForLBV2L7Policy(lbClient *golangsdk.ServiceClient, parentListener *listeners.Listener, l7policy *l7policies.L7Policy, target string, pending []string, timeout time.Duration) error {
log.Printf("[DEBUG] Waiting for l7policy %s to become %s.", l7policy.ID, target)

if len(parentListener.Loadbalancers) == 0 {
return fmt.Errorf("Unable to determine loadbalancer ID from listener %s", parentListener.ID)
}

lbID := parentListener.Loadbalancers[0].ID

stateConf := &resource.StateChangeConf{
Target: []string{target},
Pending: pending,
Refresh: resourceLBV2L7PolicyRefreshFunc(lbClient, lbID, l7policy),
Timeout: timeout,
Delay: 1 * time.Second,
MinTimeout: 1 * time.Second,
}

_, err := stateConf.WaitForState()
if err != nil {
if _, ok := err.(golangsdk.ErrDefault404); ok {
if target == "DELETED" {
return nil
}
}

return fmt.Errorf("Error waiting for l7policy %s to become %s: %s", l7policy.ID, target, err)
}

return nil
}

func getListenerIDForL7Policy(lbClient *golangsdk.ServiceClient, id string) (string, error) {
log.Printf("[DEBUG] Trying to get Listener ID associated with the %s L7 Policy ID", id)
lbsPages, err := loadbalancers.List(lbClient, loadbalancers.ListOpts{}).AllPages()
if err != nil {
return "", fmt.Errorf("No Load Balancers were found: %s", err)
}

lbs, err := loadbalancers.ExtractLoadBalancers(lbsPages)
if err != nil {
return "", fmt.Errorf("Unable to extract Load Balancers list: %s", err)
}

for _, lb := range lbs {
statuses, err := loadbalancers.GetStatuses(lbClient, lb.ID).Extract()
if err != nil {
return "", fmt.Errorf("Failed to get Load Balancer statuses: %s", err)
}
for _, listener := range statuses.Loadbalancer.Listeners {
for _, l7policy := range listener.L7Policies {
if l7policy.ID == id {
return listener.ID, nil
}
}
}
}

return "", fmt.Errorf("Unable to find Listener ID associated with the %s L7 Policy ID", id)
}

func resourceLBV2L7RuleRefreshFunc(lbClient *golangsdk.ServiceClient, lbID string, l7policyID string, l7rule *l7policies.Rule) resource.StateRefreshFunc {
if l7rule.ProvisioningStatus != "" {
return func() (interface{}, string, error) {
lb, status, err := resourceLBV2LoadBalancerRefreshFunc(lbClient, lbID)()
if err != nil {
return lb, status, err
}
if !strSliceContains(lbSkipLBStatuses, status) {
return lb, status, nil
}

l7rule, err := l7policies.GetRule(lbClient, l7policyID, l7rule.ID).Extract()
if err != nil {
return nil, "", err
}

return l7rule, l7rule.ProvisioningStatus, nil
}
}

return resourceLBV2LoadBalancerStatusRefreshFuncNeutron(lbClient, lbID, "l7rule", l7rule.ID)
}

func waitForLBV2L7Rule(lbClient *golangsdk.ServiceClient, parentListener *listeners.Listener, parentL7policy *l7policies.L7Policy, l7rule *l7policies.Rule, target string, pending []string, timeout time.Duration) error {
log.Printf("[DEBUG] Waiting for l7rule %s to become %s.", l7rule.ID, target)

if len(parentListener.Loadbalancers) == 0 {
return fmt.Errorf("Unable to determine loadbalancer ID from listener %s", parentListener.ID)
}

lbID := parentListener.Loadbalancers[0].ID

stateConf := &resource.StateChangeConf{
Target: []string{target},
Pending: pending,
Refresh: resourceLBV2L7RuleRefreshFunc(lbClient, lbID, parentL7policy.ID, l7rule),
Timeout: timeout,
Delay: 1 * time.Second,
MinTimeout: 1 * time.Second,
}

_, err := stateConf.WaitForState()
if err != nil {
if _, ok := err.(golangsdk.ErrDefault404); ok {
if target == "DELETED" {
return nil
}
}

return fmt.Errorf("Error waiting for l7rule %s to become %s: %s", l7rule.ID, target, err)
}

return nil
}
2 changes: 2 additions & 0 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ func Provider() terraform.ResourceProvider {
"huaweicloud_lb_pool_v2": resourcePoolV2(),
"huaweicloud_lb_member_v2": resourceMemberV2(),
"huaweicloud_lb_monitor_v2": resourceMonitorV2(),
"huaweicloud_lb_l7policy_v2": resourceL7PolicyV2(),
"huaweicloud_lb_l7rule_v2": resourceL7RuleV2(),
"huaweicloud_mrs_cluster_v1": resourceMRSClusterV1(),
"huaweicloud_mrs_job_v1": resourceMRSJobV1(),
"huaweicloud_networking_network_v2": resourceNetworkingNetworkV2(),
Expand Down
Loading

0 comments on commit 0948a40

Please sign in to comment.