func waitForRouterDelete(networkingClient *gophercloud.ServiceClient, routerId string) resource.StateRefreshFunc { return func() (interface{}, string, error) { log.Printf("[DEBUG] Attempting to delete OpenStack Router %s.\n", routerId) r, err := routers.Get(networkingClient, routerId).Extract() if err != nil { errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError) if !ok { return r, "ACTIVE", err } if errCode.Actual == 404 { log.Printf("[DEBUG] Successfully deleted OpenStack Router %s", routerId) return r, "DELETED", nil } } err = routers.Delete(networkingClient, routerId).ExtractErr() if err != nil { errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError) if !ok { return r, "ACTIVE", err } if errCode.Actual == 404 { log.Printf("[DEBUG] Successfully deleted OpenStack Router %s", routerId) return r, "DELETED", nil } } log.Printf("[DEBUG] OpenStack Router %s still active.\n", routerId) return r, "ACTIVE", nil } }
func resourceNetworkingRouterV2Read(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) } n, err := routers.Get(networkingClient, d.Id()).Extract() if err != nil { httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError) if !ok { return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) } if httpError.Actual == 404 { d.SetId("") return nil } return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) } log.Printf("[DEBUG] Retreived Router %s: %+v", d.Id(), n) d.Set("name", n.Name) d.Set("admin_state_up", n.AdminStateUp) d.Set("distributed", n.Distributed) d.Set("tenant_id", n.TenantID) d.Set("external_gateway", n.GatewayInfo.NetworkID) return nil }
func testAccCheckNetworkingV2RouterExists(t *testing.T, n string, router *routers.Router) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { return fmt.Errorf("Not found: %s", n) } if rs.Primary.ID == "" { return fmt.Errorf("No ID is set") } config := testAccProvider.Meta().(*Config) networkingClient, err := config.networkingV2Client(OS_REGION_NAME) if err != nil { return fmt.Errorf("(testAccCheckNetworkingV2RouterExists) Error creating OpenStack networking client: %s", err) } found, err := routers.Get(networkingClient, rs.Primary.ID).Extract() if err != nil { return err } if found.ID != rs.Primary.ID { return fmt.Errorf("Router not found") } *router = *found return nil } }
func getRouter(t *testing.T, routerID string) { r, err := routers.Get(base.Client, routerID).Extract() th.AssertNoErr(t, err) t.Logf("Getting router: ID [%s] Name [%s] Status [%s]", r.ID, r.Name, r.Status) }
func testAccCheckNetworkingV2RouterRouteEmpty(t *testing.T, n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { return fmt.Errorf("Not found: %s", n) } if rs.Primary.ID == "" { return fmt.Errorf("No ID is set") } config := testAccProvider.Meta().(*Config) networkingClient, err := config.networkingV2Client(OS_REGION_NAME) if err != nil { return fmt.Errorf("(testAccCheckNetworkingV2RouterRouteExists) Error creating OpenStack networking client: %s", err) } router, err := routers.Get(networkingClient, rs.Primary.ID).Extract() if err != nil { return err } if router.ID != rs.Primary.ID { return fmt.Errorf("Router not found") } if len(router.Routes) != 0 { return fmt.Errorf("Invalid number of route entries: %d", len(router.Routes)) } return nil } }
func resourceNetworkingRouterRouteV2Delete(d *schema.ResourceData, meta interface{}) error { routerId := d.Get("router_id").(string) osMutexKV.Lock(routerId) defer osMutexKV.Unlock(routerId) config := meta.(*Config) networkingClient, err := config.networkingV2Client(d.Get("region").(string)) if err != nil { return fmt.Errorf("Error creating OpenStack networking client: %s", err) } n, err := routers.Get(networkingClient, routerId).Extract() if err != nil { httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError) if !ok { return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) } if httpError.Actual == 404 { return nil } return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) } var updateOpts routers.UpdateOpts var destCidr string = d.Get("destination_cidr").(string) var nextHop string = d.Get("next_hop").(string) var oldRts []routers.Route = n.Routes var newRts []routers.Route for _, r := range oldRts { if r.DestinationCIDR != destCidr || r.NextHop != nextHop { newRts = append(newRts, r) } } if len(oldRts) != len(newRts) { r := routers.Route{DestinationCIDR: destCidr, NextHop: nextHop} log.Printf( "[INFO] Deleting route %s", r) updateOpts.Routes = newRts log.Printf("[DEBUG] Updating Router %s with options: %+v", routerId, updateOpts) _, err = routers.Update(networkingClient, routerId, updateOpts).Extract() if err != nil { return fmt.Errorf("Error updating OpenStack Neutron Router: %s", err) } } else { return fmt.Errorf("Route did not exist already") } return nil }
func waitForRouterActive(networkingClient *gophercloud.ServiceClient, routerId string) resource.StateRefreshFunc { return func() (interface{}, string, error) { r, err := routers.Get(networkingClient, routerId).Extract() if err != nil { return nil, r.Status, err } log.Printf("[DEBUG] OpenStack Neutron Router: %+v", r) return r, r.Status, nil } }
func (r *Routes) ListRoutes(clusterName string) ([]*cloudprovider.Route, error) { glog.V(4).Infof("ListRoutes(%v)", clusterName) nodeNamesByAddr := make(map[string]types.NodeName) err := foreachServer(r.compute, servers.ListOpts{Status: "ACTIVE"}, func(srv *servers.Server) (bool, error) { addrs, err := nodeAddresses(srv) if err != nil { return false, err } name := mapServerToNodeName(srv) for _, addr := range addrs { nodeNamesByAddr[addr.Address] = name } return true, nil }) if err != nil { return nil, err } router, err := routers.Get(r.network, r.opts.RouterId).Extract() if err != nil { return nil, err } var routes []*cloudprovider.Route for _, item := range router.Routes { nodeName, ok := nodeNamesByAddr[item.NextHop] if !ok { // Not one of our routes? glog.V(4).Infof("Skipping route with unknown nexthop %v", item.NextHop) continue } route := cloudprovider.Route{ Name: item.DestinationCIDR, TargetNode: nodeName, DestinationCIDR: item.DestinationCIDR, } routes = append(routes, &route) } return routes, nil }
func resourceNetworkingRouterRouteV2Read(d *schema.ResourceData, meta interface{}) error { routerId := d.Get("router_id").(string) config := meta.(*Config) networkingClient, err := config.networkingV2Client(d.Get("region").(string)) if err != nil { return fmt.Errorf("Error creating OpenStack networking client: %s", err) } n, err := routers.Get(networkingClient, routerId).Extract() if err != nil { httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError) if !ok { return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) } if httpError.Actual == 404 { d.SetId("") return nil } return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) } log.Printf("[DEBUG] Retrieved Router %s: %+v", routerId, n) var destCidr string = d.Get("destination_cidr").(string) var nextHop string = d.Get("next_hop").(string) d.Set("next_hop", "") d.Set("destination_cidr", "") for _, r := range n.Routes { if r.DestinationCIDR == destCidr && r.NextHop == nextHop { d.Set("destination_cidr", destCidr) d.Set("next_hop", nextHop) break } } return nil }
func testAccCheckNetworkingV2RouterDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) networkingClient, err := config.networkingV2Client(OS_REGION_NAME) if err != nil { return fmt.Errorf("(testAccCheckNetworkingV2RouterDestroy) Error creating OpenStack networking client: %s", err) } for _, rs := range s.RootModule().Resources { if rs.Type != "openstack_networking_router_v2" { continue } _, err := routers.Get(networkingClient, rs.Primary.ID).Extract() if err == nil { return fmt.Errorf("Router still exists") } } return nil }
func testAccCheckNetworkingV2RouterRouteExists(t *testing.T, n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { return fmt.Errorf("Not found: %s", n) } if rs.Primary.ID == "" { return fmt.Errorf("No ID is set") } config := testAccProvider.Meta().(*Config) networkingClient, err := config.networkingV2Client(OS_REGION_NAME) if err != nil { return fmt.Errorf("(testAccCheckNetworkingV2RouterRouteExists) Error creating OpenStack networking client: %s", err) } router, err := routers.Get(networkingClient, rs.Primary.Attributes["router_id"]).Extract() if err != nil { return err } if router.ID != rs.Primary.Attributes["router_id"] { return fmt.Errorf("Router for route not found") } var found bool = false for _, r := range router.Routes { if r.DestinationCIDR == rs.Primary.Attributes["destination_cidr"] && r.NextHop == rs.Primary.Attributes["next_hop"] { found = true } } if !found { return fmt.Errorf("Could not find route for destination CIDR: %s, next hop: %s", rs.Primary.Attributes["destination_cidr"], rs.Primary.Attributes["next_hop"]) } return nil } }
func (r *Routes) DeleteRoute(clusterName string, route *cloudprovider.Route) error { glog.V(4).Infof("DeleteRoute(%v, %v)", clusterName, route) onFailure := NewCaller() addr, err := getAddressByName(r.compute, route.TargetNode) if err != nil { return err } router, err := routers.Get(r.network, r.opts.RouterId).Extract() if err != nil { return err } routes := router.Routes index := -1 for i, item := range routes { if item.DestinationCIDR == route.DestinationCIDR && item.NextHop == addr { index = i break } } if index == -1 { glog.V(4).Infof("Skipping non-existent route: %v", route) return nil } // Delete element `index` routes[index] = routes[len(routes)-1] routes = routes[:len(routes)-1] unwind, err := updateRoutes(r.network, router, routes) if err != nil { return err } defer onFailure.Call(unwind) port, err := getPortByIP(r.network, addr) if err != nil { return err } addr_pairs := port.AllowedAddressPairs index = -1 for i, item := range addr_pairs { if item.IPAddress == route.DestinationCIDR { index = i break } } if index != -1 { // Delete element `index` addr_pairs[index] = addr_pairs[len(routes)-1] addr_pairs = addr_pairs[:len(routes)-1] unwind, err := updateAllowedAddressPairs(r.network, &port, addr_pairs) if err != nil { return err } defer onFailure.Call(unwind) } glog.V(4).Infof("Route deleted: %v", route) onFailure.Disarm() return nil }
func (r *Routes) CreateRoute(clusterName string, nameHint string, route *cloudprovider.Route) error { glog.V(4).Infof("CreateRoute(%v, %v, %v)", clusterName, nameHint, route) onFailure := NewCaller() addr, err := getAddressByName(r.compute, route.TargetNode) if err != nil { return err } glog.V(4).Infof("Using nexthop %v for node %v", addr, route.TargetNode) router, err := routers.Get(r.network, r.opts.RouterId).Extract() if err != nil { return err } routes := router.Routes for _, item := range routes { if item.DestinationCIDR == route.DestinationCIDR && item.NextHop == addr { glog.V(4).Infof("Skipping existing route: %v", route) return nil } } routes = append(routes, routers.Route{ DestinationCIDR: route.DestinationCIDR, NextHop: addr, }) unwind, err := updateRoutes(r.network, router, routes) if err != nil { return err } defer onFailure.Call(unwind) port, err := getPortByIP(r.network, addr) if err != nil { return err } found := false for _, item := range port.AllowedAddressPairs { if item.IPAddress == route.DestinationCIDR { glog.V(4).Info("Found existing allowed-address-pair: ", item) found = true break } } if !found { newPairs := append(port.AllowedAddressPairs, neutronports.AddressPair{ IPAddress: route.DestinationCIDR, }) unwind, err := updateAllowedAddressPairs(r.network, &port, newPairs) if err != nil { return err } defer onFailure.Call(unwind) } glog.V(4).Infof("Route created: %v", route) onFailure.Disarm() return nil }
func resourceNetworkingRouterRouteV2Create(d *schema.ResourceData, meta interface{}) error { routerId := d.Get("router_id").(string) osMutexKV.Lock(routerId) defer osMutexKV.Unlock(routerId) var destCidr string = d.Get("destination_cidr").(string) var nextHop string = d.Get("next_hop").(string) config := meta.(*Config) networkingClient, err := config.networkingV2Client(d.Get("region").(string)) if err != nil { return fmt.Errorf("Error creating OpenStack networking client: %s", err) } n, err := routers.Get(networkingClient, routerId).Extract() if err != nil { httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError) if !ok { return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) } if httpError.Actual == 404 { d.SetId("") return nil } return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) } var updateOpts routers.UpdateOpts var routeExists bool = false var rts []routers.Route = n.Routes for _, r := range rts { if r.DestinationCIDR == destCidr && r.NextHop == nextHop { routeExists = true break } } if !routeExists { if destCidr != "" && nextHop != "" { r := routers.Route{DestinationCIDR: destCidr, NextHop: nextHop} log.Printf( "[INFO] Adding route %s", r) rts = append(rts, r) } updateOpts.Routes = rts log.Printf("[DEBUG] Updating Router %s with options: %+v", routerId, updateOpts) _, err = routers.Update(networkingClient, routerId, updateOpts).Extract() if err != nil { return fmt.Errorf("Error updating OpenStack Neutron Router: %s", err) } d.SetId(fmt.Sprintf("%s-route-%s-%s", routerId, destCidr, nextHop)) } else { log.Printf("[DEBUG] Router %s has route already", routerId) } return resourceNetworkingRouterRouteV2Read(d, meta) }