Beispiel #1
0
// Get load balancer by name
func (os *OpenStack) GetLoadBalancer(name string) (*provider.LoadBalancer, error) {
	pool, err := os.getPoolByName(name)
	if err != nil {
		return nil, err
	}

	vip, err := os.getVipByID(pool.VIPID)
	if err != nil {
		return nil, err
	}

	var lb provider.LoadBalancer
	lb.Uid = pool.ID
	lb.Name = pool.Name
	lb.Status = pool.Status
	lb.LoadBalanceType = "TCP"
	lb.Vip = vip.Address
	lb.Subnets = []*provider.Subnet{{Uid: vip.SubnetID}}
	lb.Hosts = make([]*provider.HostPort, 0, 1)

	pager := members.List(os.network, members.ListOpts{PoolID: pool.ID})
	err = pager.EachPage(func(page pagination.Page) (bool, error) {
		memList, err := members.ExtractMembers(page)
		if err != nil {
			return false, err
		}

		for _, member := range memList {
			host := provider.HostPort{
				Ipaddress:   member.Address,
				TargetPort:  int32(member.ProtocolPort),
				ServicePort: int32(vip.ProtocolPort),
			}
			lb.Hosts = append(lb.Hosts, &host)
		}

		return true, nil
	})
	if err != nil {
		return nil, err
	}

	return &lb, nil
}
func TestMembersList(t *testing.T) {
	client, err := clients.NewNetworkV2Client()
	if err != nil {
		t.Fatalf("Unable to create a network client: %v", err)
	}

	allPages, err := members.List(client, members.ListOpts{}).AllPages()
	if err != nil {
		t.Fatalf("Unable to list members: %v", err)
	}

	allMembers, err := members.ExtractMembers(allPages)
	if err != nil {
		t.Fatalf("Unable to extract members: %v", err)
	}

	for _, member := range allMembers {
		PrintMember(t, &member)
	}
}
func resourceLBPoolV1Update(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	var updateOpts pools.UpdateOpts
	// If either option changed, update both.
	// Gophercloud complains if one is empty.
	if d.HasChange("name") || d.HasChange("lb_method") {
		updateOpts.Name = d.Get("name").(string)

		lbMethod := resourceLBPoolV1DetermineLBMethod(d.Get("lb_method").(string))
		updateOpts.LBMethod = lbMethod
	}

	log.Printf("[DEBUG] Updating OpenStack LB Pool %s with options: %+v", d.Id(), updateOpts)

	_, err = pools.Update(networkingClient, d.Id(), updateOpts).Extract()
	if err != nil {
		return fmt.Errorf("Error updating OpenStack LB Pool: %s", err)
	}

	if d.HasChange("monitor_ids") {
		oldMIDsRaw, newMIDsRaw := d.GetChange("security_groups")
		oldMIDsSet, newMIDsSet := oldMIDsRaw.(*schema.Set), newMIDsRaw.(*schema.Set)
		monitorsToAdd := newMIDsSet.Difference(oldMIDsSet)
		monitorsToRemove := oldMIDsSet.Difference(newMIDsSet)

		log.Printf("[DEBUG] Monitors to add: %v", monitorsToAdd)

		log.Printf("[DEBUG] Monitors to remove: %v", monitorsToRemove)

		for _, m := range monitorsToAdd.List() {
			_, err := pools.AssociateMonitor(networkingClient, d.Id(), m.(string)).Extract()
			if err != nil {
				return fmt.Errorf("Error associating monitor (%s) with OpenStack server (%s): %s", m.(string), d.Id(), err)
			}
			log.Printf("[DEBUG] Associated monitor (%s) with pool (%s)", m.(string), d.Id())
		}

		for _, m := range monitorsToRemove.List() {
			_, err := pools.DisassociateMonitor(networkingClient, d.Id(), m.(string)).Extract()
			if err != nil {
				return fmt.Errorf("Error disassociating monitor (%s) from OpenStack server (%s): %s", m.(string), d.Id(), err)
			}
			log.Printf("[DEBUG] Disassociated monitor (%s) from pool (%s)", m.(string), d.Id())
		}
	}

	if d.HasChange("member") {
		oldMembersRaw, newMembersRaw := d.GetChange("member")
		oldMembersSet, newMembersSet := oldMembersRaw.(*schema.Set), newMembersRaw.(*schema.Set)
		membersToAdd := newMembersSet.Difference(oldMembersSet)
		membersToRemove := oldMembersSet.Difference(newMembersSet)

		log.Printf("[DEBUG] Members to add: %v", membersToAdd)

		log.Printf("[DEBUG] Members to remove: %v", membersToRemove)

		for _, m := range membersToRemove.List() {
			oldMember := resourcePoolMemberV1(d, m)
			listOpts := members.ListOpts{
				PoolID:       d.Id(),
				Address:      oldMember.Address,
				ProtocolPort: oldMember.ProtocolPort,
			}
			err = members.List(networkingClient, listOpts).EachPage(func(page pagination.Page) (bool, error) {
				extractedMembers, err := members.ExtractMembers(page)
				if err != nil {
					return false, err
				}
				for _, member := range extractedMembers {
					err := members.Delete(networkingClient, member.ID).ExtractErr()
					if err != nil {
						return false, fmt.Errorf("Error deleting member (%s) from OpenStack LB pool (%s): %s", member.ID, d.Id(), err)
					}
					log.Printf("[DEBUG] Deleted member (%s) from pool (%s)", member.ID, d.Id())
				}
				return true, nil
			})
		}

		for _, m := range membersToAdd.List() {
			createOpts := resourcePoolMemberV1(d, m)
			newMember, err := members.Create(networkingClient, createOpts).Extract()
			if err != nil {
				return fmt.Errorf("Error creating LB member: %s", err)
			}
			log.Printf("[DEBUG] Created member (%s) in OpenStack LB pool (%s)", newMember.ID, d.Id())
		}
	}

	return resourceLBPoolV1Read(d, meta)
}
func TestList(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	th.Mux.HandleFunc("/v2.0/lb/members", func(w http.ResponseWriter, r *http.Request) {
		th.TestMethod(t, r, "GET")
		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)

		w.Header().Add("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)

		fmt.Fprintf(w, `
{
   "members":[
      {
         "status":"ACTIVE",
         "weight":1,
         "admin_state_up":true,
         "tenant_id":"83657cfcdfe44cd5920adaf26c48ceea",
         "pool_id":"72741b06-df4d-4715-b142-276b6bce75ab",
         "address":"10.0.0.4",
         "protocol_port":80,
         "id":"701b531b-111a-4f21-ad85-4795b7b12af6"
      },
      {
         "status":"ACTIVE",
         "weight":1,
         "admin_state_up":true,
         "tenant_id":"83657cfcdfe44cd5920adaf26c48ceea",
         "pool_id":"72741b06-df4d-4715-b142-276b6bce75ab",
         "address":"10.0.0.3",
         "protocol_port":80,
         "id":"beb53b4d-230b-4abd-8118-575b8fa006ef"
      }
   ]
}
      `)
	})

	count := 0

	members.List(fake.ServiceClient(), members.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
		count++
		actual, err := members.ExtractMembers(page)
		if err != nil {
			t.Errorf("Failed to extract members: %v", err)
			return false, err
		}

		expected := []members.Member{
			{
				Status:       "ACTIVE",
				Weight:       1,
				AdminStateUp: true,
				TenantID:     "83657cfcdfe44cd5920adaf26c48ceea",
				PoolID:       "72741b06-df4d-4715-b142-276b6bce75ab",
				Address:      "10.0.0.4",
				ProtocolPort: 80,
				ID:           "701b531b-111a-4f21-ad85-4795b7b12af6",
			},
			{
				Status:       "ACTIVE",
				Weight:       1,
				AdminStateUp: true,
				TenantID:     "83657cfcdfe44cd5920adaf26c48ceea",
				PoolID:       "72741b06-df4d-4715-b142-276b6bce75ab",
				Address:      "10.0.0.3",
				ProtocolPort: 80,
				ID:           "beb53b4d-230b-4abd-8118-575b8fa006ef",
			},
		}

		th.CheckDeepEquals(t, expected, actual)

		return true, nil
	})

	if count != 1 {
		t.Errorf("Expected 1 page, got %d", count)
	}
}
Beispiel #5
0
// Update load balancer
func (os *OpenStack) UpdateLoadBalancer(name string, hosts []*provider.HostPort, externalIPs []string) (string, error) {
	if len(externalIPs) > 1 {
		return "", fmt.Errorf("multiple floatingips are not yet supported by openstack")
	}

	vip, err := os.getVipByName(name)
	if err != nil {
		return "", err
	}

	lb, err := os.GetLoadBalancer(name)
	if err != nil {
		return "", err
	}

	// Set of member (addresses) that _should_ exist
	addrs := make(map[string]*provider.HostPort)
	for _, host := range hosts {
		addrs[host.Ipaddress] = host
	}

	// Iterate over members that _do_ exist
	pager := members.List(os.network, members.ListOpts{PoolID: vip.PoolID})
	err = pager.EachPage(func(page pagination.Page) (bool, error) {
		memList, err := members.ExtractMembers(page)
		if err != nil {
			return false, err
		}

		for _, member := range memList {
			if _, found := addrs[member.Address]; found {
				// Member already exists
				delete(addrs, member.Address)
			} else {
				// Member needs to be deleted
				err = members.Delete(os.network, member.ID).ExtractErr()
				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
	for _, addr := range addrs {
		_, err := members.Create(os.network, members.CreateOpts{
			TenantID:     lb.TenantID,
			PoolID:       vip.PoolID,
			Address:      addr.Ipaddress,
			ProtocolPort: int(addr.TargetPort),
		}).Extract()
		if err != nil {
			return "", err
		}
	}

	// bind to external ip
	if len(externalIPs) > 0 {
		err := os.BindPortToFloatingip(vip.PortID, externalIPs[0], vip.TenantID)
		if err != nil {
			return "", err
		}
	}

	return lb.Vip, nil
}