func lbVipV1AssignFloatingIP(floatingIP, portID string, networkingClient *gophercloud.ServiceClient) error {
	log.Printf("[DEBUG] Assigning floating IP %s to VIP %s", floatingIP, portID)

	listOpts := floatingips.ListOpts{
		FloatingIP: floatingIP,
	}
	page, err := floatingips.List(networkingClient, listOpts).AllPages()
	if err != nil {
		return err
	}

	fips, err := floatingips.ExtractFloatingIPs(page)
	if err != nil {
		return err
	}
	if len(fips) != 1 {
		return fmt.Errorf("Unable to retrieve floating IP '%s'", floatingIP)
	}

	updateOpts := floatingips.UpdateOpts{
		PortID: &portID,
	}
	if err = floatingips.Update(networkingClient, fips[0].ID, updateOpts).Err; err != nil {
		return err
	}

	return nil
}
Exemple #2
0
// Bind an port to external network, return floatingip binded
func (os *OpenStack) BindPortToExternal(portName, tenantID string) (string, error) {
	port, err := os.GetPort(portName)
	if err != nil {
		glog.Errorf("Get openstack port failed: %v", err)
		return "", err
	}

	opts := floatingips.CreateOpts{
		FloatingNetworkID: os.ExtNetID,
		TenantID:          tenantID,
	}
	ip, err := floatingips.Create(os.network, opts).Extract()
	if err != nil {
		glog.Errorf("Create openstack flaotingip failed: %v", err)
		return "", err
	}

	floatOpts := floatingips.UpdateOpts{PortID: port.ID}
	_, err = floatingips.Update(os.network, ip.ID, floatOpts).Extract()
	if err != nil {
		glog.Errorf("Associate floatingip failed: %v", err)
		e := floatingips.Delete(os.network, ip.ID).ExtractErr()
		if e != nil {
			glog.Errorf("Delete floatingip error: %v", e)
		}
		return "", err
	}

	return ip.FloatingIP, nil
}
func TestLayer3FloatingIPsCreateDelete(t *testing.T) {
	client, err := clients.NewNetworkV2Client()
	if err != nil {
		t.Fatalf("Unable to create a compute client: %v", err)
	}

	choices, err := clients.AcceptanceTestChoicesFromEnv()
	if err != nil {
		t.Fatalf("Unable to get choices: %v", err)
	}

	subnet, err := networking.CreateSubnet(t, client, choices.ExternalNetworkID)
	if err != nil {
		t.Fatalf("Unable to create subnet: %v", err)
	}
	defer networking.DeleteSubnet(t, client, subnet.ID)

	router, err := CreateExternalRouter(t, client)
	if err != nil {
		t.Fatalf("Unable to create router: %v", err)
	}
	defer DeleteRouter(t, client, router.ID)

	port, err := networking.CreatePort(t, client, choices.ExternalNetworkID, subnet.ID)
	if err != nil {
		t.Fatalf("Unable to create port: %v", err)
	}

	_, err = CreateRouterInterface(t, client, port.ID, router.ID)
	if err != nil {
		t.Fatalf("Unable to create router interface: %v", err)
	}
	defer DeleteRouterInterface(t, client, port.ID, router.ID)

	fip, err := CreateFloatingIP(t, client, choices.ExternalNetworkID, port.ID)
	if err != nil {
		t.Fatalf("Unable to create floating IP: %v", err)
	}
	defer DeleteFloatingIP(t, client, fip.ID)

	newFip, err := floatingips.Get(client, fip.ID).Extract()
	if err != nil {
		t.Fatalf("Unable to get floating ip: %v", err)
	}

	PrintFloatingIP(t, newFip)

	// Disassociate the floating IP
	updateOpts := floatingips.UpdateOpts{
		PortID: nil,
	}

	newFip, err = floatingips.Update(client, fip.ID, updateOpts).Extract()
	if err != nil {
		t.Fatalf("Unable to disassociate floating IP: %v", err)
	}
}
Exemple #4
0
// Bind an port to external network, return error
func (os *OpenStack) BindPortToFloatingip(portID, floatingIPAddress, tenantID string) error {
	var fip *floatingips.FloatingIP
	opts := floatingips.ListOpts{
		FloatingIP: floatingIPAddress,
	}
	pager := floatingips.List(os.network, opts)
	err := pager.EachPage(func(page pagination.Page) (bool, error) {
		floatingipList, err := floatingips.ExtractFloatingIPs(page)
		if err != nil {
			glog.Errorf("Get openstack floatingips error: %v", err)
			return false, err
		}

		if len(floatingipList) > 0 {
			fip = &floatingipList[0]
		}

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

	if fip != nil {
		// fip has already been used
		if fip.PortID != "" {
			return fmt.Errorf("FloatingIP %v is already been binded to %v", floatingIPAddress, fip.PortID)
		}

		// Update floatingip
		floatOpts := floatingips.UpdateOpts{PortID: portID}
		_, err = floatingips.Update(os.network, fip.ID, floatOpts).Extract()
		if err != nil {
			glog.Errorf("Bind floatingip %v to %v failed: %v", floatingIPAddress, portID, err)
			return err
		}
	} else {
		// Create floatingip
		opts := floatingips.CreateOpts{
			FloatingNetworkID: os.ExtNetID,
			TenantID:          tenantID,
			FloatingIP:        floatingIPAddress,
			PortID:            portID,
		}
		_, err := floatingips.Create(os.network, opts).Extract()
		if err != nil {
			glog.Errorf("Create openstack flaotingip failed: %v", err)
			return err
		}
	}

	return nil
}
func TestDisassociate(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) {
		th.TestMethod(t, r, "PUT")
		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
		th.TestHeader(t, r, "Content-Type", "application/json")
		th.TestHeader(t, r, "Accept", "application/json")
		th.TestJSONRequest(t, r, `
{
    "floatingip": {
      "port_id": null
    }
}
      `)

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

		fmt.Fprintf(w, `
{
    "floatingip": {
        "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f",
        "tenant_id": "4969c491a3c74ee4af974e6d800c62de",
        "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57",
        "fixed_ip_address": null,
        "floating_ip_address": "172.24.4.228",
        "port_id": null,
        "id": "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
    }
}
    `)
	})

	ip, err := floatingips.Update(fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", floatingips.UpdateOpts{PortID: nil}).Extract()
	th.AssertNoErr(t, err)

	th.AssertDeepEquals(t, "", ip.FixedIP)
	th.AssertDeepEquals(t, "", ip.PortID)
}
func resourceNetworkFloatingIPV2Update(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(GetRegion(d))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack network client: %s", err)
	}

	var updateOpts floatingips.UpdateOpts

	if d.HasChange("port_id") {
		portID := d.Get("port_id").(string)
		updateOpts.PortID = &portID
	}

	log.Printf("[DEBUG] Update Options: %#v", updateOpts)

	_, err = floatingips.Update(networkingClient, d.Id(), updateOpts).Extract()
	if err != nil {
		return fmt.Errorf("Error updating floating IP: %s", err)
	}

	return resourceNetworkFloatingIPV2Read(d, meta)
}
func resourceLBVipV1Update(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(GetRegion(d))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	var updateOpts vips.UpdateOpts
	if d.HasChange("name") {
		v := d.Get("name").(string)
		updateOpts.Name = &v
	}

	if d.HasChange("pool_id") {
		v := d.Get("pool_id").(string)
		updateOpts.PoolID = &v
	}

	if d.HasChange("description") {
		v := d.Get("description").(string)
		updateOpts.Description = &v
	}

	if d.HasChange("conn_limit") {
		updateOpts.ConnLimit = gophercloud.MaybeInt(d.Get("conn_limit").(int))
	}

	if d.HasChange("floating_ip") {
		portID := d.Get("port_id").(string)

		// Searching for a floating IP assigned to the VIP
		listOpts := floatingips.ListOpts{
			PortID: portID,
		}
		page, err := floatingips.List(networkingClient, listOpts).AllPages()
		if err != nil {
			return err
		}

		fips, err := floatingips.ExtractFloatingIPs(page)
		if err != nil {
			return err
		}

		// If a floating IP is found we unassign it
		if len(fips) == 1 {
			portID := ""
			updateOpts := floatingips.UpdateOpts{
				PortID: &portID,
			}
			if err = floatingips.Update(networkingClient, fips[0].ID, updateOpts).Err; err != nil {
				return err
			}
		}

		// Assign the updated floating IP
		floatingIP := d.Get("floating_ip").(string)
		if floatingIP != "" {
			lbVipV1AssignFloatingIP(floatingIP, portID, networkingClient)
		}
	}

	if d.HasChange("admin_state_up") {
		asu := d.Get("admin_state_up").(bool)
		updateOpts.AdminStateUp = &asu
	}

	// Persistence has to be included, even if it hasn't changed.
	updateOpts.Persistence = resourceVipPersistenceV1(d)

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

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

	return resourceLBVipV1Read(d, meta)
}