func getMembersByPoolID(client *gophercloud.ServiceClient, id string) ([]v2pools.Member, error) { var members []v2pools.Member err := v2pools.ListAssociateMembers(client, id, v2pools.MemberListOpts{}).EachPage(func(page pagination.Page) (bool, error) { membersList, err := v2pools.ExtractMembers(page) if err != nil { return false, err } members = append(members, membersList...) return true, nil }) if err != nil { return nil, err } return members, nil }
func listMembers(t *testing.T, poolID string) { err := pools.ListAssociateMembers(base.Client, poolID, pools.MemberListOpts{}).EachPage(func(page pagination.Page) (bool, error) { membersList, err := pools.ExtractMembers(page) if err != nil { t.Errorf("Failed to extract Members: %v", err) return false, err } for _, member := range membersList { t.Logf("Listing Member: ID [%s] Name [%s] Pool ID [%s] Weight [%s]", member.ID, member.Name, member.PoolID, member.Weight) } return true, nil }) th.AssertNoErr(t, err) }
func (lbaas *LbaasV2) UpdateLoadBalancer(clusterName string, service *v1.Service, nodeNames []string) error { loadBalancerName := cloudprovider.GetLoadBalancerName(service) glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v)", clusterName, loadBalancerName, nodeNames) ports := service.Spec.Ports if len(ports) == 0 { return fmt.Errorf("no ports provided to openstack load balancer") } loadbalancer, err := getLoadbalancerByName(lbaas.network, loadBalancerName) if err != nil { return err } if loadbalancer == nil { return fmt.Errorf("Loadbalancer %s does not exist", loadBalancerName) } // Get all listeners for this loadbalancer, by "port key". type portKey struct { Protocol string Port int } lbListeners := make(map[portKey]listeners.Listener) err = listeners.List(lbaas.network, listeners.ListOpts{LoadbalancerID: loadbalancer.ID}).EachPage(func(page pagination.Page) (bool, error) { listenersList, err := listeners.ExtractListeners(page) if err != nil { return false, err } for _, l := range listenersList { for _, lb := range l.Loadbalancers { // Double check this Listener belongs to the LB we're updating. Neutron's API filtering // can't be counted on in older releases (i.e Liberty). if loadbalancer.ID == lb.ID { key := portKey{Protocol: l.Protocol, Port: l.ProtocolPort} lbListeners[key] = l break } } } return true, nil }) if err != nil { return err } // Get all pools for this loadbalancer, by listener ID. lbPools := make(map[string]v2pools.Pool) err = v2pools.List(lbaas.network, v2pools.ListOpts{LoadbalancerID: loadbalancer.ID}).EachPage(func(page pagination.Page) (bool, error) { poolsList, err := v2pools.ExtractPools(page) if err != nil { return false, err } for _, p := range poolsList { for _, l := range p.Listeners { // Double check this Pool belongs to the LB we're deleting. Neutron's API filtering // can't be counted on in older releases (i.e Liberty). for _, val := range lbListeners { if val.ID == l.ID { lbPools[l.ID] = p break } } } } return true, nil }) if err != nil { return err } // Compose Set of member (addresses) that _should_ exist addrs := map[string]empty{} for _, nodeName := range nodeNames { addr, err := getAddressByName(lbaas.compute, types.NodeName(nodeName)) if err != nil { return err } addrs[addr] = empty{} } // Check for adding/removing members associated with each port for _, port := range ports { // Get listener associated with this port listener, ok := lbListeners[portKey{ Protocol: string(port.Protocol), Port: int(port.Port), }] if !ok { return fmt.Errorf("Loadbalancer %s does not contain required listener for port %d and protocol %s", loadBalancerName, port.Port, port.Protocol) } // Get pool associated with this listener pool, ok := lbPools[listener.ID] if !ok { return fmt.Errorf("Loadbalancer %s does not contain required pool for listener %s", loadBalancerName, listener.ID) } // Find existing pool members (by address) for this port members := make(map[string]v2pools.Member) err := v2pools.ListAssociateMembers(lbaas.network, pool.ID, v2pools.MemberListOpts{}).EachPage(func(page pagination.Page) (bool, error) { membersList, err := v2pools.ExtractMembers(page) if err != nil { return false, err } for _, member := range membersList { members[member.Address] = member } return true, nil }) if err != nil { return err } // Add any new members for this port for addr := range addrs { if _, ok := members[addr]; ok && members[addr].ProtocolPort == int(port.NodePort) { // Already exists, do not create member continue } _, err := v2pools.CreateAssociateMember(lbaas.network, pool.ID, v2pools.MemberCreateOpts{ Address: addr, ProtocolPort: int(port.NodePort), SubnetID: lbaas.opts.SubnetId, }).Extract() if err != nil { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // Remove any old members for this port for _, member := range members { if _, ok := addrs[member.Address]; ok && member.ProtocolPort == int(port.NodePort) { // Still present, do not delete member continue } err = v2pools.DeleteMember(lbaas.network, pool.ID, member.ID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } } return nil }
func (lbaas *LbaasV2) EnsureLoadBalancerDeleted(clusterName string, service *v1.Service) error { loadBalancerName := cloudprovider.GetLoadBalancerName(service) glog.V(4).Infof("EnsureLoadBalancerDeleted(%v, %v)", clusterName, loadBalancerName) loadbalancer, err := getLoadbalancerByName(lbaas.network, loadBalancerName) if err != nil && err != ErrNotFound { return err } if loadbalancer == nil { return nil } if lbaas.opts.FloatingNetworkId != "" && loadbalancer != nil { portID, err := getPortIDByIP(lbaas.network, loadbalancer.VipAddress) if err != nil { return err } floatingIP, err := getFloatingIPByPortID(lbaas.network, portID) if err != nil && err != ErrNotFound { return err } if floatingIP != nil { err = floatingips.Delete(lbaas.network, floatingIP.ID).ExtractErr() if err != nil && !isNotFound(err) { return err } } } // get all listeners associated with this loadbalancer var listenerIDs []string err = listeners.List(lbaas.network, listeners.ListOpts{LoadbalancerID: loadbalancer.ID}).EachPage(func(page pagination.Page) (bool, error) { listenerList, err := listeners.ExtractListeners(page) if err != nil { return false, err } for _, listener := range listenerList { listenerIDs = append(listenerIDs, listener.ID) } return true, nil }) if err != nil { return err } // get all pools (and health monitors) associated with this loadbalancer var poolIDs []string var monitorIDs []string err = v2pools.List(lbaas.network, v2pools.ListOpts{LoadbalancerID: loadbalancer.ID}).EachPage(func(page pagination.Page) (bool, error) { poolsList, err := v2pools.ExtractPools(page) if err != nil { return false, err } for _, pool := range poolsList { poolIDs = append(poolIDs, pool.ID) monitorIDs = append(monitorIDs, pool.MonitorID) } return true, nil }) if err != nil { return err } // get all members associated with each poolIDs var memberIDs []string for _, poolID := range poolIDs { err := v2pools.ListAssociateMembers(lbaas.network, poolID, v2pools.MemberListOpts{}).EachPage(func(page pagination.Page) (bool, error) { membersList, err := v2pools.ExtractMembers(page) if err != nil { return false, err } for _, member := range membersList { memberIDs = append(memberIDs, member.ID) } return true, nil }) if err != nil { return err } } // delete all monitors for _, monitorID := range monitorIDs { err := v2monitors.Delete(lbaas.network, monitorID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // delete all members and pools for _, poolID := range poolIDs { // delete all members for this pool for _, memberID := range memberIDs { err := v2pools.DeleteMember(lbaas.network, poolID, memberID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // delete pool err := v2pools.Delete(lbaas.network, poolID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // delete all listeners for _, listenerID := range listenerIDs { err := listeners.Delete(lbaas.network, listenerID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // delete loadbalancer err = loadbalancers.Delete(lbaas.network, loadbalancer.ID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerDeleted(lbaas.network, loadbalancer.ID) // Delete the Security Group if lbaas.opts.ManageSecurityGroups { // Generate Name lbSecGroupName := getSecurityGroupName(clusterName, service) lbSecGroupID, err := groups.IDFromName(lbaas.network, lbSecGroupName) if err != nil { glog.V(1).Infof("Error occurred finding security group: %s: %v", lbSecGroupName, err) return nil } lbSecGroup := groups.Delete(lbaas.network, lbSecGroupID) if lbSecGroup.Err != nil && !isNotFound(lbSecGroup.Err) { return lbSecGroup.Err } // Delete the rules in the Node Security Group opts := rules.ListOpts{ SecGroupID: lbaas.opts.NodeSecurityGroupID, RemoteGroupID: lbSecGroupID, } secGroupRules, err := getSecurityGroupRules(lbaas.network, opts) if err != nil && !isNotFound(err) { glog.Errorf("Error finding rules for remote group id %s in security group id %s", lbSecGroupID, lbaas.opts.NodeSecurityGroupID) return err } for _, rule := range secGroupRules { res := rules.Delete(lbaas.network, rule.ID) if res.Err != nil && !isNotFound(res.Err) { glog.V(1).Infof("Error occurred deleting security group rule: %s: %v", rule.ID, res.Err) } } } return nil }
func (lbaas *LbaasV2) EnsureLoadBalancerDeleted(service *api.Service) error { loadBalancerName := cloudprovider.GetLoadBalancerName(service) glog.V(4).Infof("EnsureLoadBalancerDeleted(%v)", loadBalancerName) loadbalancer, err := getLoadbalancerByName(lbaas.network, loadBalancerName) if err != nil && err != ErrNotFound { return err } if loadbalancer == nil { return nil } if lbaas.opts.FloatingNetworkId != "" && loadbalancer != nil { portID, err := getPortIDByIP(lbaas.network, loadbalancer.VipAddress) if err != nil { return err } floatingIP, err := getFloatingIPByPortID(lbaas.network, portID) if err != nil && err != ErrNotFound { return err } if floatingIP != nil { err = floatingips.Delete(lbaas.network, floatingIP.ID).ExtractErr() if err != nil && !isNotFound(err) { return err } } } // get all listeners associated with this loadbalancer var listenerIDs []string err = listeners.List(lbaas.network, listeners.ListOpts{LoadbalancerID: loadbalancer.ID}).EachPage(func(page pagination.Page) (bool, error) { listenerList, err := listeners.ExtractListeners(page) if err != nil { return false, err } for _, listener := range listenerList { listenerIDs = append(listenerIDs, listener.ID) } return true, nil }) if err != nil { return err } // get all pools associated with this loadbalancer var poolIDs []string err = v2_pools.List(lbaas.network, v2_pools.ListOpts{LoadbalancerID: loadbalancer.ID}).EachPage(func(page pagination.Page) (bool, error) { poolsList, err := v2_pools.ExtractPools(page) if err != nil { return false, err } for _, pool := range poolsList { poolIDs = append(poolIDs, pool.ID) } return true, nil }) if err != nil { return err } // get all members associated with each poolIDs var memberIDs []string for _, poolID := range poolIDs { err := v2_pools.ListAssociateMembers(lbaas.network, poolID, v2_pools.MemberListOpts{}).EachPage(func(page pagination.Page) (bool, error) { membersList, err := v2_pools.ExtractMembers(page) if err != nil { return false, err } for _, member := range membersList { memberIDs = append(memberIDs, member.ID) } return true, nil }) if err != nil { return err } } // get all monitors associated with each poolIDs var monitorIDs []string for _, poolID := range poolIDs { err = v2_monitors.List(lbaas.network, v2_monitors.ListOpts{PoolID: poolID}).EachPage(func(page pagination.Page) (bool, error) { monitorsList, err := v2_monitors.ExtractMonitors(page) if err != nil { return false, err } for _, monitor := range monitorsList { monitorIDs = append(monitorIDs, monitor.ID) } return true, nil }) if err != nil { return err } } // delete all monitors for _, monitorID := range monitorIDs { err := v2_monitors.Delete(lbaas.network, monitorID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // delete all members and pools for _, poolID := range poolIDs { // delete all members for this pool for _, memberID := range memberIDs { err := v2_pools.DeleteMember(lbaas.network, poolID, memberID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // delete pool err := v2_pools.Delete(lbaas.network, poolID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // delete all listeners for _, listenerID := range listenerIDs { err := listeners.Delete(lbaas.network, listenerID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } // delete loadbalancer err = loadbalancers.Delete(lbaas.network, loadbalancer.ID).ExtractErr() if err != nil && !isNotFound(err) { return err } waitLoadbalancerDeleted(lbaas.network, loadbalancer.ID) return nil }
func (lbaas *LbaasV2) UpdateLoadBalancer(service *api.Service, hosts []string) error { loadBalancerName := cloudprovider.GetLoadBalancerName(service) glog.V(4).Infof("UpdateLoadBalancer(%v, %v)", loadBalancerName, hosts) ports := service.Spec.Ports if len(ports) > 1 { return fmt.Errorf("multiple ports are not yet supported in openstack load balancers") } else if len(ports) == 0 { return fmt.Errorf("no ports provided to openstack load balancer") } loadbalancer, err := getLoadbalancerByName(lbaas.network, loadBalancerName) if err != nil { return err } if loadbalancer == nil { return fmt.Errorf("Loadbalancer %s does not exist", loadBalancerName) } // Set of member (addresses) that _should_ exist addrs := map[string]bool{} for _, host := range hosts { addr, err := getAddressByName(lbaas.compute, host) if err != nil { return err } addrs[addr] = true } // Iterate over members in each pool that _do_ exist var poolID string err = v2_pools.List(lbaas.network, v2_pools.ListOpts{LoadbalancerID: loadbalancer.ID}).EachPage(func(page pagination.Page) (bool, error) { poolsList, err := v2_pools.ExtractPools(page) if err != nil { return false, err } for _, pool := range poolsList { poolID = pool.ID err := v2_pools.ListAssociateMembers(lbaas.network, poolID, v2_pools.MemberListOpts{}).EachPage(func(page pagination.Page) (bool, error) { membersList, err := v2_pools.ExtractMembers(page) if err != nil { return false, err } for _, member := range membersList { if _, found := addrs[member.Address]; found { // Member already exists, remove from update list delete(addrs, member.Address) } else { // Member needs to be deleted err = v2_pools.DeleteMember(lbaas.network, poolID, member.ID).ExtractErr() if err != nil { return false, err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } } return true, nil }) if err != nil { return false, err } } return true, nil }) if err != nil { return err } // Anything left in addrs is a new member that needs to be added to a pool for addr := range addrs { _, err := v2_pools.CreateAssociateMember(lbaas.network, poolID, v2_pools.MemberCreateOpts{ Address: addr, ProtocolPort: int(ports[0].NodePort), SubnetID: lbaas.opts.SubnetId, }).Extract() if err != nil { return err } waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) } return nil }