github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/builtin/providers/openstack/resource_openstack_networking_router_route_v2.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/hashicorp/terraform/helper/schema" 8 9 "github.com/rackspace/gophercloud" 10 "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers" 11 ) 12 13 func resourceNetworkingRouterRouteV2() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceNetworkingRouterRouteV2Create, 16 Read: resourceNetworkingRouterRouteV2Read, 17 Delete: resourceNetworkingRouterRouteV2Delete, 18 19 Schema: map[string]*schema.Schema{ 20 "region": &schema.Schema{ 21 Type: schema.TypeString, 22 Required: true, 23 ForceNew: true, 24 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 25 }, 26 "router_id": &schema.Schema{ 27 Type: schema.TypeString, 28 Required: true, 29 ForceNew: true, 30 }, 31 "destination_cidr": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 }, 36 "next_hop": &schema.Schema{ 37 Type: schema.TypeString, 38 Required: true, 39 ForceNew: true, 40 }, 41 }, 42 } 43 } 44 45 func resourceNetworkingRouterRouteV2Create(d *schema.ResourceData, meta interface{}) error { 46 47 routerId := d.Get("router_id").(string) 48 osMutexKV.Lock(routerId) 49 defer osMutexKV.Unlock(routerId) 50 51 var destCidr string = d.Get("destination_cidr").(string) 52 var nextHop string = d.Get("next_hop").(string) 53 54 config := meta.(*Config) 55 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 56 if err != nil { 57 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 58 } 59 60 n, err := routers.Get(networkingClient, routerId).Extract() 61 if err != nil { 62 httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError) 63 if !ok { 64 return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) 65 } 66 67 if httpError.Actual == 404 { 68 d.SetId("") 69 return nil 70 } 71 return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) 72 } 73 74 var updateOpts routers.UpdateOpts 75 var routeExists bool = false 76 77 var rts []routers.Route = n.Routes 78 for _, r := range rts { 79 80 if r.DestinationCIDR == destCidr && r.NextHop == nextHop { 81 routeExists = true 82 break 83 } 84 } 85 86 if !routeExists { 87 88 if destCidr != "" && nextHop != "" { 89 r := routers.Route{DestinationCIDR: destCidr, NextHop: nextHop} 90 log.Printf( 91 "[INFO] Adding route %s", r) 92 rts = append(rts, r) 93 } 94 95 updateOpts.Routes = rts 96 97 log.Printf("[DEBUG] Updating Router %s with options: %+v", routerId, updateOpts) 98 99 _, err = routers.Update(networkingClient, routerId, updateOpts).Extract() 100 if err != nil { 101 return fmt.Errorf("Error updating OpenStack Neutron Router: %s", err) 102 } 103 d.SetId(fmt.Sprintf("%s-route-%s-%s", routerId, destCidr, nextHop)) 104 105 } else { 106 log.Printf("[DEBUG] Router %s has route already", routerId) 107 } 108 109 return resourceNetworkingRouterRouteV2Read(d, meta) 110 } 111 112 func resourceNetworkingRouterRouteV2Read(d *schema.ResourceData, meta interface{}) error { 113 114 routerId := d.Get("router_id").(string) 115 116 config := meta.(*Config) 117 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 118 if err != nil { 119 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 120 } 121 122 n, err := routers.Get(networkingClient, routerId).Extract() 123 if err != nil { 124 httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError) 125 if !ok { 126 return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) 127 } 128 129 if httpError.Actual == 404 { 130 d.SetId("") 131 return nil 132 } 133 return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) 134 } 135 136 log.Printf("[DEBUG] Retrieved Router %s: %+v", routerId, n) 137 138 var destCidr string = d.Get("destination_cidr").(string) 139 var nextHop string = d.Get("next_hop").(string) 140 141 d.Set("next_hop", "") 142 d.Set("destination_cidr", "") 143 144 for _, r := range n.Routes { 145 146 if r.DestinationCIDR == destCidr && r.NextHop == nextHop { 147 d.Set("destination_cidr", destCidr) 148 d.Set("next_hop", nextHop) 149 break 150 } 151 } 152 153 return nil 154 } 155 156 func resourceNetworkingRouterRouteV2Delete(d *schema.ResourceData, meta interface{}) error { 157 158 routerId := d.Get("router_id").(string) 159 osMutexKV.Lock(routerId) 160 defer osMutexKV.Unlock(routerId) 161 162 config := meta.(*Config) 163 164 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 165 if err != nil { 166 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 167 } 168 169 n, err := routers.Get(networkingClient, routerId).Extract() 170 if err != nil { 171 httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError) 172 if !ok { 173 return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) 174 } 175 176 if httpError.Actual == 404 { 177 return nil 178 } 179 return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err) 180 } 181 182 var updateOpts routers.UpdateOpts 183 184 var destCidr string = d.Get("destination_cidr").(string) 185 var nextHop string = d.Get("next_hop").(string) 186 187 var oldRts []routers.Route = n.Routes 188 var newRts []routers.Route 189 190 for _, r := range oldRts { 191 192 if r.DestinationCIDR != destCidr || r.NextHop != nextHop { 193 newRts = append(newRts, r) 194 } 195 } 196 197 if len(oldRts) != len(newRts) { 198 r := routers.Route{DestinationCIDR: destCidr, NextHop: nextHop} 199 log.Printf( 200 "[INFO] Deleting route %s", r) 201 updateOpts.Routes = newRts 202 203 log.Printf("[DEBUG] Updating Router %s with options: %+v", routerId, updateOpts) 204 205 _, err = routers.Update(networkingClient, routerId, updateOpts).Extract() 206 if err != nil { 207 return fmt.Errorf("Error updating OpenStack Neutron Router: %s", err) 208 } 209 } else { 210 return fmt.Errorf("Route did not exist already") 211 } 212 213 return nil 214 }