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 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 TestInvalidNextPageURLs(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprintf(w, `{"floatingips": [{}], "floatingips_links": {}}`) }) floatingips.List(fake.ServiceClient(), floatingips.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { floatingips.ExtractFloatingIPs(page) return true, nil }) }
func TestLayer3FloatingIPsList(t *testing.T) { client, err := clients.NewNetworkV2Client() if err != nil { t.Fatalf("Unable to create a compute client: %v", err) } listOpts := floatingips.ListOpts{} allPages, err := floatingips.List(client, listOpts).AllPages() if err != nil { t.Fatalf("Unable to list floating IPs: %v", err) } allFIPs, err := floatingips.ExtractFloatingIPs(allPages) if err != nil { t.Fatalf("Unable to extract floating IPs: %v", err) } for _, fip := range allFIPs { PrintFloatingIP(t, &fip) } }
func (os *OpenStack) getFloatingIPByPort(portID string) (*floatingips.FloatingIP, error) { var result *floatingips.FloatingIP opts := floatingips.ListOpts{ PortID: portID, } 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 { result = &floatingipList[0] } return true, err }) return result, err }
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) }
func TestList(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/v2.0/floatingips", 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, ` { "floatingips": [ { "floating_network_id": "6d67c30a-ddb4-49a1-bec3-a65b286b4170", "router_id": null, "fixed_ip_address": null, "floating_ip_address": "192.0.0.4", "tenant_id": "017d8de156df4177889f31a9bd6edc00", "status": "DOWN", "port_id": null, "id": "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e" }, { "floating_network_id": "90f742b1-6d17-487b-ba95-71881dbc0b64", "router_id": "0a24cb83-faf5-4d7f-b723-3144ed8a2167", "fixed_ip_address": "192.0.0.2", "floating_ip_address": "10.0.0.3", "tenant_id": "017d8de156df4177889f31a9bd6edc00", "status": "DOWN", "port_id": "74a342ce-8e07-4e91-880c-9f834b68fa25", "id": "ada25a95-f321-4f59-b0e0-f3a970dd3d63" } ] } `) }) count := 0 floatingips.List(fake.ServiceClient(), floatingips.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { count++ actual, err := floatingips.ExtractFloatingIPs(page) if err != nil { t.Errorf("Failed to extract floating IPs: %v", err) return false, err } expected := []floatingips.FloatingIP{ { FloatingNetworkID: "6d67c30a-ddb4-49a1-bec3-a65b286b4170", FixedIP: "", FloatingIP: "192.0.0.4", TenantID: "017d8de156df4177889f31a9bd6edc00", Status: "DOWN", PortID: "", ID: "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e", }, { FloatingNetworkID: "90f742b1-6d17-487b-ba95-71881dbc0b64", FixedIP: "192.0.0.2", FloatingIP: "10.0.0.3", TenantID: "017d8de156df4177889f31a9bd6edc00", Status: "DOWN", PortID: "74a342ce-8e07-4e91-880c-9f834b68fa25", ID: "ada25a95-f321-4f59-b0e0-f3a970dd3d63", }, } th.CheckDeepEquals(t, expected, actual) return true, nil }) if count != 1 { t.Errorf("Expected 1 page, got %d", count) } }