-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
219 changes: 219 additions & 0 deletions
219
builtin/providers/openstack/resource_openstack_networking_router_table_v2.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
package openstack | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"log" | ||
|
||
"github.com/hashicorp/terraform/helper/hashcode" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
|
||
"github.com/rackspace/gophercloud" | ||
"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers" | ||
) | ||
|
||
func resourceNetworkingRouterTableV2() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceNetworkingRouterTableV2Create, | ||
Read: resourceNetworkingRouterTableV2Read, | ||
Update: resourceNetworkingRouterTableV2Update, | ||
Delete: resourceNetworkingRouterTableV2Delete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"region": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), | ||
}, | ||
"router_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"route": &schema.Schema{ | ||
Type: schema.TypeSet, | ||
Required: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"next_hop": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
|
||
"destination_cidr": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
}, | ||
}, | ||
Set: resourceOpenstackRoutesHash, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceOpenstackRoutesHash(v interface{}) int { | ||
var buf bytes.Buffer | ||
m := v.(map[string]interface{}) | ||
|
||
if v, ok := m["next_hop"]; ok { | ||
buf.WriteString(fmt.Sprintf("%s", v.(string))) | ||
} | ||
|
||
if v, ok := m["destination_cidr"]; ok { | ||
buf.WriteString(fmt.Sprintf("%s", v.(string))) | ||
} | ||
|
||
return hashcode.String(buf.String()) | ||
} | ||
|
||
func resourceNetworkingRouterTableV2Create(d *schema.ResourceData, meta interface{}) error { | ||
|
||
d.SetId(fmt.Sprintf("%s-routes", 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) | ||
} | ||
|
||
var updateOpts routers.UpdateOpts | ||
|
||
n := d.Get("route") | ||
nrs := n.(*schema.Set) | ||
var rts []routers.Route | ||
|
||
// Loop through all the routes converting them | ||
for _, route := range nrs.List() { | ||
m := route.(map[string]interface{}) | ||
if m["destination_cidr"].(string) != "" && m["next_hop"].(string) != "" { | ||
r := routers.Route{DestinationCIDR: m["destination_cidr"].(string), NextHop: m["next_hop"].(string)} | ||
log.Printf( | ||
"[INFO] Adding route %s", r) | ||
rts = append(rts, r) | ||
} | ||
|
||
} | ||
updateOpts.Routes = rts | ||
|
||
log.Printf("[DEBUG] Updating Router %s with options: %+v", d.Get("router_id").(string), updateOpts) | ||
|
||
_, err = routers.Update(networkingClient, d.Get("router_id").(string), updateOpts).Extract() | ||
if err != nil { | ||
return fmt.Errorf("Error updating OpenStack Neutron Router: %s", err) | ||
} | ||
|
||
return resourceNetworkingRouterTableV2Read(d, meta) | ||
} | ||
|
||
func resourceNetworkingRouterTableV2Read(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.Get("router_id").(string)).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", d.Get("router_id").(string), n) | ||
|
||
// Create an empty schema.Set to hold all routes | ||
route := &schema.Set{F: resourceOpenstackRoutesHash} | ||
|
||
// Loop through the routes and add them to the set | ||
for _, r := range n.Routes { | ||
|
||
m := make(map[string]interface{}) | ||
|
||
if r.NextHop != "" { | ||
m["next_hop"] = r.NextHop | ||
} | ||
if r.DestinationCIDR != "" { | ||
m["destination_cidr"] = r.DestinationCIDR | ||
} | ||
|
||
route.Add(m) | ||
} | ||
|
||
d.Set("route", route) | ||
|
||
return nil | ||
} | ||
|
||
func resourceNetworkingRouterTableV2Update(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 routers.UpdateOpts | ||
|
||
// Check if the route set as a whole has changed | ||
if d.HasChange("route") { | ||
n := d.Get("route") | ||
nrs := n.(*schema.Set) | ||
var rts []routers.Route | ||
|
||
// Loop through all the routes converting them | ||
for _, route := range nrs.List() { | ||
m := route.(map[string]interface{}) | ||
if m["destination_cidr"].(string) != "" && m["next_hop"].(string) != "" { | ||
r := routers.Route{DestinationCIDR: m["destination_cidr"].(string), NextHop: m["next_hop"].(string)} | ||
log.Printf( | ||
"[INFO] Adding route %s", r) | ||
rts = append(rts, r) | ||
} | ||
|
||
} | ||
|
||
updateOpts.Routes = rts | ||
|
||
log.Printf("[DEBUG] Updating Router %s with options: %+v", d.Get("router_id").(string), updateOpts) | ||
|
||
_, err = routers.Update(networkingClient, d.Get("router_id").(string), updateOpts).Extract() | ||
if err != nil { | ||
return fmt.Errorf("Error updating OpenStack Neutron Router: %s", err) | ||
} | ||
} | ||
|
||
return resourceNetworkingRouterTableV2Read(d, meta) | ||
} | ||
|
||
func resourceNetworkingRouterTableV2Delete(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 routers.UpdateOpts | ||
|
||
var rts []routers.Route | ||
|
||
updateOpts.Routes = rts | ||
|
||
log.Printf("[DEBUG] Updating Router %s with options: %+v", d.Get("router_id").(string), updateOpts) | ||
|
||
_, err = routers.Update(networkingClient, d.Get("router_id").(string), updateOpts).Extract() | ||
if err != nil { | ||
return fmt.Errorf("Error updating OpenStack Neutron Router: %s", err) | ||
} | ||
|
||
d.SetId("") | ||
return nil | ||
} |