github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/google/resource_compute_region_backend_service.go (about) 1 package google 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "regexp" 8 9 "github.com/hashicorp/terraform/helper/hashcode" 10 "github.com/hashicorp/terraform/helper/schema" 11 "google.golang.org/api/compute/v1" 12 "google.golang.org/api/googleapi" 13 ) 14 15 func resourceComputeRegionBackendService() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceComputeRegionBackendServiceCreate, 18 Read: resourceComputeRegionBackendServiceRead, 19 Update: resourceComputeRegionBackendServiceUpdate, 20 Delete: resourceComputeRegionBackendServiceDelete, 21 22 Schema: map[string]*schema.Schema{ 23 "name": &schema.Schema{ 24 Type: schema.TypeString, 25 Required: true, 26 ForceNew: true, 27 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 28 value := v.(string) 29 re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$` 30 if !regexp.MustCompile(re).MatchString(value) { 31 errors = append(errors, fmt.Errorf( 32 "%q (%q) doesn't match regexp %q", k, value, re)) 33 } 34 return 35 }, 36 }, 37 38 "health_checks": &schema.Schema{ 39 Type: schema.TypeSet, 40 Elem: &schema.Schema{Type: schema.TypeString}, 41 Required: true, 42 Set: schema.HashString, 43 }, 44 45 "backend": &schema.Schema{ 46 Type: schema.TypeSet, 47 Elem: &schema.Resource{ 48 Schema: map[string]*schema.Schema{ 49 "group": &schema.Schema{ 50 Type: schema.TypeString, 51 Optional: true, 52 }, 53 "description": &schema.Schema{ 54 Type: schema.TypeString, 55 Optional: true, 56 }, 57 }, 58 }, 59 Optional: true, 60 Set: resourceGoogleComputeRegionBackendServiceBackendHash, 61 }, 62 63 "description": &schema.Schema{ 64 Type: schema.TypeString, 65 Optional: true, 66 }, 67 68 "fingerprint": &schema.Schema{ 69 Type: schema.TypeString, 70 Computed: true, 71 }, 72 73 "project": &schema.Schema{ 74 Type: schema.TypeString, 75 Optional: true, 76 ForceNew: true, 77 }, 78 79 "protocol": &schema.Schema{ 80 Type: schema.TypeString, 81 Optional: true, 82 Computed: true, 83 }, 84 85 "session_affinity": &schema.Schema{ 86 Type: schema.TypeString, 87 Optional: true, 88 Computed: true, 89 }, 90 91 "region": &schema.Schema{ 92 Type: schema.TypeString, 93 Optional: true, 94 ForceNew: true, 95 }, 96 97 "self_link": &schema.Schema{ 98 Type: schema.TypeString, 99 Computed: true, 100 }, 101 102 "timeout_sec": &schema.Schema{ 103 Type: schema.TypeInt, 104 Optional: true, 105 Computed: true, 106 }, 107 }, 108 } 109 } 110 111 func resourceComputeRegionBackendServiceCreate(d *schema.ResourceData, meta interface{}) error { 112 config := meta.(*Config) 113 114 hc := d.Get("health_checks").(*schema.Set).List() 115 healthChecks := make([]string, 0, len(hc)) 116 for _, v := range hc { 117 healthChecks = append(healthChecks, v.(string)) 118 } 119 120 service := compute.BackendService{ 121 Name: d.Get("name").(string), 122 HealthChecks: healthChecks, 123 LoadBalancingScheme: "INTERNAL", 124 } 125 126 if v, ok := d.GetOk("backend"); ok { 127 service.Backends = expandBackends(v.(*schema.Set).List()) 128 } 129 130 if v, ok := d.GetOk("description"); ok { 131 service.Description = v.(string) 132 } 133 134 if v, ok := d.GetOk("protocol"); ok { 135 service.Protocol = v.(string) 136 } 137 138 if v, ok := d.GetOk("session_affinity"); ok { 139 service.SessionAffinity = v.(string) 140 } 141 142 if v, ok := d.GetOk("timeout_sec"); ok { 143 service.TimeoutSec = int64(v.(int)) 144 } 145 146 project, err := getProject(d, config) 147 if err != nil { 148 return err 149 } 150 151 region, err := getRegion(d, config) 152 if err != nil { 153 return err 154 } 155 156 log.Printf("[DEBUG] Creating new Region Backend Service: %#v", service) 157 158 op, err := config.clientCompute.RegionBackendServices.Insert( 159 project, region, &service).Do() 160 if err != nil { 161 return fmt.Errorf("Error creating backend service: %s", err) 162 } 163 164 log.Printf("[DEBUG] Waiting for new backend service, operation: %#v", op) 165 166 d.SetId(service.Name) 167 168 err = computeOperationWaitRegion(config, op, project, region, "Creating Region Backend Service") 169 if err != nil { 170 return err 171 } 172 173 return resourceComputeRegionBackendServiceRead(d, meta) 174 } 175 176 func resourceComputeRegionBackendServiceRead(d *schema.ResourceData, meta interface{}) error { 177 config := meta.(*Config) 178 179 project, err := getProject(d, config) 180 if err != nil { 181 return err 182 } 183 184 region, err := getRegion(d, config) 185 if err != nil { 186 return err 187 } 188 189 service, err := config.clientCompute.RegionBackendServices.Get( 190 project, region, d.Id()).Do() 191 if err != nil { 192 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 193 // The resource doesn't exist anymore 194 log.Printf("[WARN] Removing Backend Service %q because it's gone", d.Get("name").(string)) 195 d.SetId("") 196 197 return nil 198 } 199 200 return fmt.Errorf("Error reading service: %s", err) 201 } 202 203 d.Set("description", service.Description) 204 d.Set("protocol", service.Protocol) 205 d.Set("session_affinity", service.SessionAffinity) 206 d.Set("timeout_sec", service.TimeoutSec) 207 d.Set("fingerprint", service.Fingerprint) 208 d.Set("self_link", service.SelfLink) 209 210 d.Set("backend", flattenBackends(service.Backends)) 211 d.Set("health_checks", service.HealthChecks) 212 213 return nil 214 } 215 216 func resourceComputeRegionBackendServiceUpdate(d *schema.ResourceData, meta interface{}) error { 217 config := meta.(*Config) 218 219 project, err := getProject(d, config) 220 if err != nil { 221 return err 222 } 223 224 region, err := getRegion(d, config) 225 if err != nil { 226 return err 227 } 228 229 hc := d.Get("health_checks").(*schema.Set).List() 230 healthChecks := make([]string, 0, len(hc)) 231 for _, v := range hc { 232 healthChecks = append(healthChecks, v.(string)) 233 } 234 235 service := compute.BackendService{ 236 Name: d.Get("name").(string), 237 Fingerprint: d.Get("fingerprint").(string), 238 HealthChecks: healthChecks, 239 LoadBalancingScheme: "INTERNAL", 240 } 241 242 // Optional things 243 if v, ok := d.GetOk("backend"); ok { 244 service.Backends = expandBackends(v.(*schema.Set).List()) 245 } 246 if v, ok := d.GetOk("description"); ok { 247 service.Description = v.(string) 248 } 249 if v, ok := d.GetOk("protocol"); ok { 250 service.Protocol = v.(string) 251 } 252 if v, ok := d.GetOk("session_affinity"); ok { 253 service.SessionAffinity = v.(string) 254 } 255 if v, ok := d.GetOk("timeout_sec"); ok { 256 service.TimeoutSec = int64(v.(int)) 257 } 258 259 log.Printf("[DEBUG] Updating existing Backend Service %q: %#v", d.Id(), service) 260 op, err := config.clientCompute.RegionBackendServices.Update( 261 project, region, d.Id(), &service).Do() 262 if err != nil { 263 return fmt.Errorf("Error updating backend service: %s", err) 264 } 265 266 d.SetId(service.Name) 267 268 err = computeOperationWaitRegion(config, op, project, region, "Updating Backend Service") 269 if err != nil { 270 return err 271 } 272 273 return resourceComputeRegionBackendServiceRead(d, meta) 274 } 275 276 func resourceComputeRegionBackendServiceDelete(d *schema.ResourceData, meta interface{}) error { 277 config := meta.(*Config) 278 279 project, err := getProject(d, config) 280 if err != nil { 281 return err 282 } 283 284 region, err := getRegion(d, config) 285 if err != nil { 286 return err 287 } 288 289 log.Printf("[DEBUG] Deleting backend service %s", d.Id()) 290 op, err := config.clientCompute.RegionBackendServices.Delete( 291 project, region, d.Id()).Do() 292 if err != nil { 293 return fmt.Errorf("Error deleting backend service: %s", err) 294 } 295 296 err = computeOperationWaitRegion(config, op, project, region, "Deleting Backend Service") 297 if err != nil { 298 return err 299 } 300 301 d.SetId("") 302 return nil 303 } 304 305 func resourceGoogleComputeRegionBackendServiceBackendHash(v interface{}) int { 306 if v == nil { 307 return 0 308 } 309 310 var buf bytes.Buffer 311 m := v.(map[string]interface{}) 312 313 buf.WriteString(fmt.Sprintf("%s-", m["group"].(string))) 314 315 if v, ok := m["description"]; ok { 316 buf.WriteString(fmt.Sprintf("%s-", v.(string))) 317 } 318 319 return hashcode.String(buf.String()) 320 }