github.com/atsaki/terraform@v0.4.3-0.20150919165407-25bba5967654/builtin/providers/google/resource_compute_route.go (about) 1 package google 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/hashicorp/terraform/helper/hashcode" 9 "github.com/hashicorp/terraform/helper/schema" 10 "google.golang.org/api/compute/v1" 11 "google.golang.org/api/googleapi" 12 ) 13 14 func resourceComputeRoute() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceComputeRouteCreate, 17 Read: resourceComputeRouteRead, 18 Delete: resourceComputeRouteDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "name": &schema.Schema{ 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 27 "dest_range": &schema.Schema{ 28 Type: schema.TypeString, 29 Required: true, 30 ForceNew: true, 31 }, 32 33 "network": &schema.Schema{ 34 Type: schema.TypeString, 35 Required: true, 36 ForceNew: true, 37 }, 38 39 "next_hop_ip": &schema.Schema{ 40 Type: schema.TypeString, 41 Optional: true, 42 ForceNew: true, 43 }, 44 45 "next_hop_instance": &schema.Schema{ 46 Type: schema.TypeString, 47 Optional: true, 48 ForceNew: true, 49 }, 50 51 "next_hop_instance_zone": &schema.Schema{ 52 Type: schema.TypeString, 53 Optional: true, 54 ForceNew: true, 55 }, 56 57 "next_hop_gateway": &schema.Schema{ 58 Type: schema.TypeString, 59 Optional: true, 60 ForceNew: true, 61 }, 62 63 "next_hop_network": &schema.Schema{ 64 Type: schema.TypeString, 65 Optional: true, 66 ForceNew: true, 67 }, 68 69 "next_hop_vpn_tunnel": &schema.Schema{ 70 Type: schema.TypeString, 71 Optional: true, 72 ForceNew: true, 73 }, 74 75 "priority": &schema.Schema{ 76 Type: schema.TypeInt, 77 Required: true, 78 ForceNew: true, 79 }, 80 81 "tags": &schema.Schema{ 82 Type: schema.TypeSet, 83 Optional: true, 84 ForceNew: true, 85 Elem: &schema.Schema{Type: schema.TypeString}, 86 Set: func(v interface{}) int { 87 return hashcode.String(v.(string)) 88 }, 89 }, 90 91 "self_link": &schema.Schema{ 92 Type: schema.TypeString, 93 Computed: true, 94 }, 95 }, 96 } 97 } 98 99 func resourceComputeRouteCreate(d *schema.ResourceData, meta interface{}) error { 100 config := meta.(*Config) 101 102 // Look up the network to attach the route to 103 network, err := config.clientCompute.Networks.Get( 104 config.Project, d.Get("network").(string)).Do() 105 if err != nil { 106 return fmt.Errorf("Error reading network: %s", err) 107 } 108 109 // Next hop data 110 var nextHopInstance, nextHopIp, nextHopNetwork, nextHopGateway, 111 nextHopVpnTunnel string 112 if v, ok := d.GetOk("next_hop_ip"); ok { 113 nextHopIp = v.(string) 114 } 115 if v, ok := d.GetOk("next_hop_gateway"); ok { 116 nextHopGateway = v.(string) 117 } 118 if v, ok := d.GetOk("next_hop_vpn_tunnel"); ok { 119 nextHopVpnTunnel = v.(string) 120 } 121 if v, ok := d.GetOk("next_hop_instance"); ok { 122 nextInstance, err := config.clientCompute.Instances.Get( 123 config.Project, 124 d.Get("next_hop_instance_zone").(string), 125 v.(string)).Do() 126 if err != nil { 127 return fmt.Errorf("Error reading instance: %s", err) 128 } 129 130 nextHopInstance = nextInstance.SelfLink 131 } 132 if v, ok := d.GetOk("next_hop_network"); ok { 133 nextNetwork, err := config.clientCompute.Networks.Get( 134 config.Project, v.(string)).Do() 135 if err != nil { 136 return fmt.Errorf("Error reading network: %s", err) 137 } 138 139 nextHopNetwork = nextNetwork.SelfLink 140 } 141 142 // Tags 143 var tags []string 144 if v := d.Get("tags").(*schema.Set); v.Len() > 0 { 145 tags = make([]string, v.Len()) 146 for i, v := range v.List() { 147 tags[i] = v.(string) 148 } 149 } 150 151 // Build the route parameter 152 route := &compute.Route{ 153 Name: d.Get("name").(string), 154 DestRange: d.Get("dest_range").(string), 155 Network: network.SelfLink, 156 NextHopInstance: nextHopInstance, 157 NextHopVpnTunnel: nextHopVpnTunnel, 158 NextHopIp: nextHopIp, 159 NextHopNetwork: nextHopNetwork, 160 NextHopGateway: nextHopGateway, 161 Priority: int64(d.Get("priority").(int)), 162 Tags: tags, 163 } 164 log.Printf("[DEBUG] Route insert request: %#v", route) 165 op, err := config.clientCompute.Routes.Insert( 166 config.Project, route).Do() 167 if err != nil { 168 return fmt.Errorf("Error creating route: %s", err) 169 } 170 171 // It probably maybe worked, so store the ID now 172 d.SetId(route.Name) 173 174 // Wait for the operation to complete 175 w := &OperationWaiter{ 176 Service: config.clientCompute, 177 Op: op, 178 Project: config.Project, 179 Type: OperationWaitGlobal, 180 } 181 state := w.Conf() 182 state.Timeout = 2 * time.Minute 183 state.MinTimeout = 1 * time.Second 184 opRaw, err := state.WaitForState() 185 if err != nil { 186 return fmt.Errorf("Error waiting for route to create: %s", err) 187 } 188 op = opRaw.(*compute.Operation) 189 if op.Error != nil { 190 // The resource didn't actually create 191 d.SetId("") 192 193 // Return the error 194 return OperationError(*op.Error) 195 } 196 197 return resourceComputeRouteRead(d, meta) 198 } 199 200 func resourceComputeRouteRead(d *schema.ResourceData, meta interface{}) error { 201 config := meta.(*Config) 202 203 route, err := config.clientCompute.Routes.Get( 204 config.Project, d.Id()).Do() 205 if err != nil { 206 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 207 // The resource doesn't exist anymore 208 d.SetId("") 209 210 return nil 211 } 212 213 return fmt.Errorf("Error reading route: %#v", err) 214 } 215 216 d.Set("self_link", route.SelfLink) 217 218 return nil 219 } 220 221 func resourceComputeRouteDelete(d *schema.ResourceData, meta interface{}) error { 222 config := meta.(*Config) 223 224 // Delete the route 225 op, err := config.clientCompute.Routes.Delete( 226 config.Project, d.Id()).Do() 227 if err != nil { 228 return fmt.Errorf("Error deleting route: %s", err) 229 } 230 231 // Wait for the operation to complete 232 w := &OperationWaiter{ 233 Service: config.clientCompute, 234 Op: op, 235 Project: config.Project, 236 Type: OperationWaitGlobal, 237 } 238 state := w.Conf() 239 state.Timeout = 2 * time.Minute 240 state.MinTimeout = 1 * time.Second 241 opRaw, err := state.WaitForState() 242 if err != nil { 243 return fmt.Errorf("Error waiting for route to delete: %s", err) 244 } 245 op = opRaw.(*compute.Operation) 246 if op.Error != nil { 247 // Return the error 248 return OperationError(*op.Error) 249 } 250 251 d.SetId("") 252 return nil 253 }