github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/google/resource_compute_router.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 resourceComputeRouter() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceComputeRouterCreate, 17 Read: resourceComputeRouterRead, 18 Delete: resourceComputeRouterDelete, 19 Importer: &schema.ResourceImporter{ 20 State: resourceComputeRouterImportState, 21 }, 22 23 Schema: map[string]*schema.Schema{ 24 "name": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 }, 29 30 "network": &schema.Schema{ 31 Type: schema.TypeString, 32 Required: true, 33 ForceNew: true, 34 DiffSuppressFunc: linkDiffSuppress, 35 }, 36 37 "description": &schema.Schema{ 38 Type: schema.TypeString, 39 Optional: true, 40 ForceNew: true, 41 }, 42 43 "project": &schema.Schema{ 44 Type: schema.TypeString, 45 Optional: true, 46 Computed: true, 47 ForceNew: true, 48 }, 49 50 "region": &schema.Schema{ 51 Type: schema.TypeString, 52 Optional: true, 53 Computed: true, 54 ForceNew: true, 55 }, 56 57 "bgp": &schema.Schema{ 58 Type: schema.TypeList, 59 MaxItems: 1, 60 Required: true, 61 ForceNew: true, 62 Elem: &schema.Resource{ 63 Schema: map[string]*schema.Schema{ 64 65 "asn": &schema.Schema{ 66 Type: schema.TypeInt, 67 Required: true, 68 ForceNew: true, 69 }, 70 }, 71 }, 72 }, 73 74 "self_link": &schema.Schema{ 75 Type: schema.TypeString, 76 Computed: true, 77 }, 78 }, 79 } 80 } 81 82 func resourceComputeRouterCreate(d *schema.ResourceData, meta interface{}) error { 83 84 config := meta.(*Config) 85 86 region, err := getRegion(d, config) 87 if err != nil { 88 return err 89 } 90 91 project, err := getProject(d, config) 92 if err != nil { 93 return err 94 } 95 96 name := d.Get("name").(string) 97 98 routerLock := getRouterLockName(region, name) 99 mutexKV.Lock(routerLock) 100 defer mutexKV.Unlock(routerLock) 101 102 network, err := getNetworkLink(d, config, "network") 103 if err != nil { 104 return err 105 } 106 routersService := config.clientCompute.Routers 107 108 router := &compute.Router{ 109 Name: name, 110 Network: network, 111 } 112 113 if v, ok := d.GetOk("description"); ok { 114 router.Description = v.(string) 115 } 116 117 if _, ok := d.GetOk("bgp"); ok { 118 prefix := "bgp.0" 119 if v, ok := d.GetOk(prefix + ".asn"); ok { 120 asn := v.(int) 121 bgp := &compute.RouterBgp{ 122 Asn: int64(asn), 123 } 124 router.Bgp = bgp 125 } 126 } 127 128 op, err := routersService.Insert(project, region, router).Do() 129 if err != nil { 130 return fmt.Errorf("Error Inserting Router %s into network %s: %s", name, network, err) 131 } 132 d.SetId(fmt.Sprintf("%s/%s", region, name)) 133 err = computeOperationWaitRegion(config, op, project, region, "Inserting Router") 134 if err != nil { 135 d.SetId("") 136 return fmt.Errorf("Error Waiting to Insert Router %s into network %s: %s", name, network, err) 137 } 138 139 return resourceComputeRouterRead(d, meta) 140 } 141 142 func resourceComputeRouterRead(d *schema.ResourceData, meta interface{}) error { 143 144 config := meta.(*Config) 145 146 region, err := getRegion(d, config) 147 if err != nil { 148 return err 149 } 150 151 project, err := getProject(d, config) 152 if err != nil { 153 return err 154 } 155 156 name := d.Get("name").(string) 157 routersService := config.clientCompute.Routers 158 router, err := routersService.Get(project, region, name).Do() 159 160 if err != nil { 161 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 162 log.Printf("[WARN] Removing router %s/%s because it is gone", region, name) 163 d.SetId("") 164 165 return nil 166 } 167 168 return fmt.Errorf("Error Reading Router %s: %s", name, err) 169 } 170 171 d.Set("self_link", router.SelfLink) 172 d.Set("network", router.Network) 173 174 d.Set("name", router.Name) 175 d.Set("description", router.Description) 176 d.Set("region", region) 177 d.Set("project", project) 178 d.Set("bgp", flattenAsn(router.Bgp.Asn)) 179 d.SetId(fmt.Sprintf("%s/%s", region, name)) 180 181 return nil 182 } 183 184 func resourceComputeRouterDelete(d *schema.ResourceData, meta interface{}) error { 185 186 config := meta.(*Config) 187 188 region, err := getRegion(d, config) 189 if err != nil { 190 return err 191 } 192 193 project, err := getProject(d, config) 194 if err != nil { 195 return err 196 } 197 198 name := d.Get("name").(string) 199 200 routerLock := getRouterLockName(region, name) 201 mutexKV.Lock(routerLock) 202 defer mutexKV.Unlock(routerLock) 203 204 routersService := config.clientCompute.Routers 205 206 op, err := routersService.Delete(project, region, name).Do() 207 if err != nil { 208 return fmt.Errorf("Error Reading Router %s: %s", name, err) 209 } 210 211 err = computeOperationWaitRegion(config, op, project, region, "Deleting Router") 212 if err != nil { 213 return fmt.Errorf("Error Waiting to Delete Router %s: %s", name, err) 214 } 215 216 d.SetId("") 217 return nil 218 } 219 220 func resourceComputeRouterImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { 221 parts := strings.Split(d.Id(), "/") 222 if len(parts) != 2 { 223 return nil, fmt.Errorf("Invalid router specifier. Expecting {region}/{name}") 224 } 225 226 d.Set("region", parts[0]) 227 d.Set("name", parts[1]) 228 229 return []*schema.ResourceData{d}, nil 230 } 231 232 func getRouterLink(config *Config, project string, region string, router string) (string, error) { 233 234 if !strings.HasPrefix(router, "https://www.googleapis.com/compute/") { 235 // Router value provided is just the name, lookup the router SelfLink 236 routerData, err := config.clientCompute.Routers.Get( 237 project, region, router).Do() 238 if err != nil { 239 return "", fmt.Errorf("Error reading router: %s", err) 240 } 241 router = routerData.SelfLink 242 } 243 244 return router, nil 245 246 } 247 248 func flattenAsn(asn int64) []map[string]interface{} { 249 result := make([]map[string]interface{}, 0, 1) 250 r := make(map[string]interface{}) 251 r["asn"] = asn 252 result = append(result, r) 253 return result 254 }