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 }
// 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) } }
// 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) }