github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/google/resource_compute_router_peer.go (about) 1 package google 2 3 import ( 4 "fmt" 5 "log" 6 7 "strings" 8 9 "github.com/hashicorp/terraform/helper/schema" 10 "google.golang.org/api/compute/v1" 11 "google.golang.org/api/googleapi" 12 ) 13 14 func resourceComputeRouterPeer() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceComputeRouterPeerCreate, 17 Read: resourceComputeRouterPeerRead, 18 Delete: resourceComputeRouterPeerDelete, 19 Importer: &schema.ResourceImporter{ 20 State: resourceComputeRouterPeerImportState, 21 }, 22 23 Schema: map[string]*schema.Schema{ 24 "name": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 }, 29 "router": &schema.Schema{ 30 Type: schema.TypeString, 31 Required: true, 32 ForceNew: true, 33 }, 34 "interface": &schema.Schema{ 35 Type: schema.TypeString, 36 Required: true, 37 ForceNew: true, 38 }, 39 40 "peer_ip_address": &schema.Schema{ 41 Type: schema.TypeString, 42 Optional: true, 43 ForceNew: true, 44 }, 45 46 "peer_asn": &schema.Schema{ 47 Type: schema.TypeInt, 48 Required: true, 49 ForceNew: true, 50 }, 51 52 "advertised_route_priority": &schema.Schema{ 53 Type: schema.TypeInt, 54 Optional: true, 55 ForceNew: true, 56 }, 57 58 "ip_address": &schema.Schema{ 59 Type: schema.TypeString, 60 Computed: true, 61 }, 62 63 "project": &schema.Schema{ 64 Type: schema.TypeString, 65 Optional: true, 66 Computed: true, 67 ForceNew: true, 68 }, 69 70 "region": &schema.Schema{ 71 Type: schema.TypeString, 72 Optional: true, 73 Computed: true, 74 ForceNew: true, 75 }, 76 }, 77 } 78 } 79 80 func resourceComputeRouterPeerCreate(d *schema.ResourceData, meta interface{}) error { 81 82 config := meta.(*Config) 83 84 region, err := getRegion(d, config) 85 if err != nil { 86 return err 87 } 88 89 project, err := getProject(d, config) 90 if err != nil { 91 return err 92 } 93 94 routerName := d.Get("router").(string) 95 peerName := d.Get("name").(string) 96 97 routerLock := getRouterLockName(region, routerName) 98 mutexKV.Lock(routerLock) 99 defer mutexKV.Unlock(routerLock) 100 101 routersService := config.clientCompute.Routers 102 router, err := routersService.Get(project, region, routerName).Do() 103 if err != nil { 104 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 105 log.Printf("[WARN] Removing router peer %s because its router %s/%s is gone", peerName, region, routerName) 106 d.SetId("") 107 108 return nil 109 } 110 111 return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) 112 } 113 114 peers := router.BgpPeers 115 for _, peer := range peers { 116 if peer.Name == peerName { 117 d.SetId("") 118 return fmt.Errorf("Router %s has peer %s already", routerName, peerName) 119 } 120 } 121 122 ifaceName := d.Get("interface").(string) 123 124 peer := &compute.RouterBgpPeer{Name: peerName, 125 InterfaceName: ifaceName} 126 127 if v, ok := d.GetOk("peer_ip_address"); ok { 128 peer.PeerIpAddress = v.(string) 129 } 130 131 if v, ok := d.GetOk("peer_asn"); ok { 132 peer.PeerAsn = int64(v.(int)) 133 } 134 135 if v, ok := d.GetOk("advertised_route_priority"); ok { 136 peer.AdvertisedRoutePriority = int64(v.(int)) 137 } 138 139 log.Printf("[INFO] Adding peer %s", peerName) 140 peers = append(peers, peer) 141 patchRouter := &compute.Router{ 142 BgpPeers: peers, 143 } 144 145 log.Printf("[DEBUG] Updating router %s/%s with peers: %+v", region, routerName, peers) 146 op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() 147 if err != nil { 148 return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) 149 } 150 d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, peerName)) 151 err = computeOperationWaitRegion(config, op, project, region, "Patching router") 152 if err != nil { 153 d.SetId("") 154 return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) 155 } 156 157 return resourceComputeRouterPeerRead(d, meta) 158 } 159 160 func resourceComputeRouterPeerRead(d *schema.ResourceData, meta interface{}) error { 161 162 config := meta.(*Config) 163 164 region, err := getRegion(d, config) 165 if err != nil { 166 return err 167 } 168 169 project, err := getProject(d, config) 170 if err != nil { 171 return err 172 } 173 174 routerName := d.Get("router").(string) 175 peerName := d.Get("name").(string) 176 177 routersService := config.clientCompute.Routers 178 router, err := routersService.Get(project, region, routerName).Do() 179 if err != nil { 180 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 181 log.Printf("[WARN] Removing router peer %s because its router %s/%s is gone", peerName, region, routerName) 182 d.SetId("") 183 184 return nil 185 } 186 187 return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) 188 } 189 190 for _, peer := range router.BgpPeers { 191 192 if peer.Name == peerName { 193 d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, peerName)) 194 d.Set("interface", peer.InterfaceName) 195 d.Set("peer_ip_address", peer.PeerIpAddress) 196 d.Set("peer_asn", peer.PeerAsn) 197 d.Set("advertised_route_priority", peer.AdvertisedRoutePriority) 198 d.Set("ip_address", peer.IpAddress) 199 d.Set("region", region) 200 d.Set("project", project) 201 return nil 202 } 203 } 204 205 log.Printf("[WARN] Removing router peer %s/%s/%s because it is gone", region, routerName, peerName) 206 d.SetId("") 207 return nil 208 } 209 210 func resourceComputeRouterPeerDelete(d *schema.ResourceData, meta interface{}) error { 211 212 config := meta.(*Config) 213 214 region, err := getRegion(d, config) 215 if err != nil { 216 return err 217 } 218 219 project, err := getProject(d, config) 220 if err != nil { 221 return err 222 } 223 224 routerName := d.Get("router").(string) 225 peerName := d.Get("name").(string) 226 227 routerLock := getRouterLockName(region, routerName) 228 mutexKV.Lock(routerLock) 229 defer mutexKV.Unlock(routerLock) 230 231 routersService := config.clientCompute.Routers 232 router, err := routersService.Get(project, region, routerName).Do() 233 if err != nil { 234 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 235 log.Printf("[WARN] Removing router peer %s because its router %s/%s is gone", peerName, region, routerName) 236 237 return nil 238 } 239 240 return fmt.Errorf("Error Reading Router %s: %s", routerName, err) 241 } 242 243 var newPeers []*compute.RouterBgpPeer = make([]*compute.RouterBgpPeer, 0, len(router.BgpPeers)) 244 for _, peer := range router.BgpPeers { 245 if peer.Name == peerName { 246 continue 247 } else { 248 newPeers = append(newPeers, peer) 249 } 250 } 251 252 if len(newPeers) == len(router.BgpPeers) { 253 log.Printf("[DEBUG] Router %s/%s had no peer %s already", region, routerName, peerName) 254 d.SetId("") 255 return nil 256 } 257 258 log.Printf( 259 "[INFO] Removing peer %s from router %s/%s", peerName, region, routerName) 260 patchRouter := &compute.Router{ 261 BgpPeers: newPeers, 262 } 263 264 log.Printf("[DEBUG] Updating router %s/%s with peers: %+v", region, routerName, newPeers) 265 op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() 266 if err != nil { 267 return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) 268 } 269 270 err = computeOperationWaitRegion(config, op, project, region, "Patching router") 271 if err != nil { 272 return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) 273 } 274 275 d.SetId("") 276 return nil 277 } 278 279 func resourceComputeRouterPeerImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { 280 parts := strings.Split(d.Id(), "/") 281 if len(parts) != 3 { 282 return nil, fmt.Errorf("Invalid router peer specifier. Expecting {region}/{router}/{peer}") 283 } 284 285 d.Set("region", parts[0]) 286 d.Set("router", parts[1]) 287 d.Set("name", parts[2]) 288 289 return []*schema.ResourceData{d}, nil 290 }