Merge pull request #7852 from gaker/google-provider-backend-cdn

google_compute_backend_service "enable_cdn"
This commit is contained in:
Evan Brown 2016-08-03 20:11:54 -07:00 committed by GitHub
commit 89df636163
12 changed files with 6008 additions and 2525 deletions

View File

@ -88,6 +88,12 @@ func resourceComputeBackendService() *schema.Resource {
Optional: true,
},
"enable_cdn": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"fingerprint": &schema.Schema{
Type: schema.TypeString,
Computed: true,
@ -165,6 +171,10 @@ func resourceComputeBackendServiceCreate(d *schema.ResourceData, meta interface{
service.TimeoutSec = int64(v.(int))
}
if v, ok := d.GetOk("enable_cdn"); ok {
service.EnableCDN = v.(bool)
}
project, err := getProject(d, config)
if err != nil {
return err
@ -212,6 +222,7 @@ func resourceComputeBackendServiceRead(d *schema.ResourceData, meta interface{})
}
d.Set("description", service.Description)
d.Set("enable_cdn", service.EnableCDN)
d.Set("port_name", service.PortName)
d.Set("protocol", service.Protocol)
d.Set("timeout_sec", service.TimeoutSec)
@ -260,6 +271,10 @@ func resourceComputeBackendServiceUpdate(d *schema.ResourceData, meta interface{
service.TimeoutSec = int64(d.Get("timeout_sec").(int))
}
if d.HasChange("enable_cdn") {
service.EnableCDN = d.Get("enable_cdn").(bool)
}
log.Printf("[DEBUG] Updating existing Backend Service %q: %#v", d.Id(), service)
op, err := config.clientCompute.BackendServices.Update(
project, d.Id(), &service).Do()

View File

@ -121,6 +121,32 @@ func testAccCheckComputeBackendServiceExists(n string, svc *compute.BackendServi
}
}
func TestAccComputeBackendService_withCDNEnabled(t *testing.T) {
serviceName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
checkName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
var svc compute.BackendService
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeBackendServiceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeBackendService_withCDNEnabled(
serviceName, checkName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeBackendServiceExists(
"google_compute_backend_service.foobar", &svc),
),
},
},
})
if svc.EnableCDN != true {
t.Errorf("Expected EnableCDN == true, got %t", svc.EnableCDN)
}
}
func testAccComputeBackendService_basic(serviceName, checkName string) string {
return fmt.Sprintf(`
resource "google_compute_backend_service" "foobar" {
@ -137,6 +163,23 @@ resource "google_compute_http_health_check" "zero" {
`, serviceName, checkName)
}
func testAccComputeBackendService_withCDNEnabled(serviceName, checkName string) string {
return fmt.Sprintf(`
resource "google_compute_backend_service" "foobar" {
name = "%s"
health_checks = ["${google_compute_http_health_check.zero.self_link}"]
enable_cdn = true
}
resource "google_compute_http_health_check" "zero" {
name = "%s"
request_path = "/"
check_interval_sec = 1
timeout_sec = 1
}
`, serviceName, checkName)
}
func testAccComputeBackendService_basicModified(serviceName, checkOne, checkTwo string) string {
return fmt.Sprintf(`
resource "google_compute_backend_service" "foobar" {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,8 @@ import (
"google.golang.org/api/googleapi"
)
// ResumableBuffer buffers data from an io.Reader to support uploading media in retryable chunks.
type ResumableBuffer struct {
// MediaBuffer buffers data from an io.Reader to support uploading media in retryable chunks.
type MediaBuffer struct {
media io.Reader
chunk []byte // The current chunk which is pending upload. The capacity is the chunk size.
@ -22,42 +22,42 @@ type ResumableBuffer struct {
off int64
}
func NewResumableBuffer(media io.Reader, chunkSize int) *ResumableBuffer {
return &ResumableBuffer{media: media, chunk: make([]byte, 0, chunkSize)}
func NewMediaBuffer(media io.Reader, chunkSize int) *MediaBuffer {
return &MediaBuffer{media: media, chunk: make([]byte, 0, chunkSize)}
}
// Chunk returns the current buffered chunk, the offset in the underlying media
// from which the chunk is drawn, and the size of the chunk.
// Successive calls to Chunk return the same chunk between calls to Next.
func (rb *ResumableBuffer) Chunk() (chunk io.Reader, off int64, size int, err error) {
func (mb *MediaBuffer) Chunk() (chunk io.Reader, off int64, size int, err error) {
// There may already be data in chunk if Next has not been called since the previous call to Chunk.
if rb.err == nil && len(rb.chunk) == 0 {
rb.err = rb.loadChunk()
if mb.err == nil && len(mb.chunk) == 0 {
mb.err = mb.loadChunk()
}
return bytes.NewReader(rb.chunk), rb.off, len(rb.chunk), rb.err
return bytes.NewReader(mb.chunk), mb.off, len(mb.chunk), mb.err
}
// loadChunk will read from media into chunk, up to the capacity of chunk.
func (rb *ResumableBuffer) loadChunk() error {
bufSize := cap(rb.chunk)
rb.chunk = rb.chunk[:bufSize]
func (mb *MediaBuffer) loadChunk() error {
bufSize := cap(mb.chunk)
mb.chunk = mb.chunk[:bufSize]
read := 0
var err error
for err == nil && read < bufSize {
var n int
n, err = rb.media.Read(rb.chunk[read:])
n, err = mb.media.Read(mb.chunk[read:])
read += n
}
rb.chunk = rb.chunk[:read]
mb.chunk = mb.chunk[:read]
return err
}
// Next advances to the next chunk, which will be returned by the next call to Chunk.
// Calls to Next without a corresponding prior call to Chunk will have no effect.
func (rb *ResumableBuffer) Next() {
rb.off += int64(len(rb.chunk))
rb.chunk = rb.chunk[0:0]
func (mb *MediaBuffer) Next() {
mb.off += int64(len(mb.chunk))
mb.chunk = mb.chunk[0:0]
}
type readerTyper struct {

View File

@ -176,25 +176,24 @@ func typeHeader(contentType string) textproto.MIMEHeader {
// chunkSize is the size of the chunk that media should be split into.
// If chunkSize is non-zero and the contents of media do not fit in a single
// chunk (or there is an error reading media), then media will be returned as a
// ResumableBuffer. Otherwise, media will be returned as a Reader.
// MediaBuffer. Otherwise, media will be returned as a Reader.
//
// After PrepareUpload has been called, media should no longer be used: the
// media content should be accessed via one of the return values.
func PrepareUpload(media io.Reader, chunkSize int) (io.Reader,
*ResumableBuffer) {
func PrepareUpload(media io.Reader, chunkSize int) (io.Reader, *MediaBuffer) {
if chunkSize == 0 { // do not chunk
return media, nil
}
rb := NewResumableBuffer(media, chunkSize)
rdr, _, _, err := rb.Chunk()
mb := NewMediaBuffer(media, chunkSize)
rdr, _, _, err := mb.Chunk()
if err == io.EOF { // we can upload this in a single request
return rdr, nil
}
// err might be a non-EOF error. If it is, the next call to rb.Chunk will
// return the same error. Returning a ResumableBuffer ensures that this error
// err might be a non-EOF error. If it is, the next call to mb.Chunk will
// return the same error. Returning a MediaBuffer ensures that this error
// will be handled at some point.
return nil, rb
return nil, mb
}

View File

@ -35,7 +35,7 @@ type ResumableUpload struct {
URI string
UserAgent string // User-Agent for header of the request
// Media is the object being uploaded.
Media *ResumableBuffer
Media *MediaBuffer
// MediaType defines the media type, e.g. "image/jpeg".
MediaType string
@ -80,7 +80,10 @@ func (rx *ResumableUpload) doUploadRequest(ctx context.Context, data io.Reader,
req.Header.Set("Content-Range", contentRange)
req.Header.Set("Content-Type", rx.MediaType)
req.Header.Set("User-Agent", rx.UserAgent)
return ctxhttp.Do(ctx, rx.Client, req)
fn := Hook(ctx, req)
resp, err := ctxhttp.Do(ctx, rx.Client, req)
fn(resp)
return resp, err
}
@ -135,6 +138,8 @@ func contextDone(ctx context.Context) bool {
// It retries using the provided back off strategy until cancelled or the
// strategy indicates to stop retrying.
// It is called from the auto-generated API code and is not visible to the user.
// Before sending an HTTP request, Upload calls Hook to obtain a function which
// it subsequently calls with the HTTP response.
// rx is private to the auto-generated API code.
// Exactly one of resp or err will be nil. If resp is non-nil, the caller must call resp.Body.Close.
func (rx *ResumableUpload) Upload(ctx context.Context) (resp *http.Response, err error) {

35
vendor/google.golang.org/api/gensupport/send.go generated vendored Normal file
View File

@ -0,0 +1,35 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gensupport
import (
"net/http"
"golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp"
)
// Hook is a function that is called once before each HTTP request that is sent
// by a generated API. It returns a function that is called after the request
// returns.
// Hook is never called if the context is nil.
var Hook func(ctx context.Context, req *http.Request) func(resp *http.Response) = defaultHook
func defaultHook(ctx context.Context, req *http.Request) func(resp *http.Response) {
return func(resp *http.Response) {}
}
// SendRequest sends a single HTTP request using the given client.
// If ctx is non-nil, uses ctxhttp.Do, and calls Hook beforehand. The function
// returned by Hook is called after the request returns.
func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
if ctx != nil {
fn := Hook(ctx, req)
resp, err := ctxhttp.Do(ctx, client, req)
fn(resp)
return resp, err
}
return client.Do(req)
}

View File

@ -1,11 +1,11 @@
{
"kind": "discovery#restDescription",
"etag": "\"bRFOOrZKfO9LweMbPqu0kcu6De8/KVPQfwGxQTBtH0g1kuij0C9i4uc\"",
"etag": "\"C5oy1hgQsABtYOYIOXWcR3BgYqU/cPnwg2U9hg8m8Y6wHWcvqIF8qSM\"",
"discoveryVersion": "v1",
"id": "storage:v1",
"name": "storage",
"version": "v1",
"revision": "20160304",
"revision": "20160609",
"title": "Cloud Storage JSON API",
"description": "Stores and retrieves potentially large, immutable data objects.",
"ownerDomain": "google.com",
@ -294,15 +294,15 @@
},
"website": {
"type": "object",
"description": "The bucket's website configuration.",
"description": "The bucket's website configuration, controlling how the service behaves when accessing bucket contents as a web site. See the Static Website Examples for more information.",
"properties": {
"mainPageSuffix": {
"type": "string",
"description": "Behaves as the bucket's directory index where missing objects are treated as potential directories."
"description": "If the requested object path is missing, the service will ensure the path has a trailing '/', append this suffix, and attempt to retrieve the resulting object. This allows the creation of index.html objects to represent directory pages."
},
"notFoundPage": {
"type": "string",
"description": "The custom object to return when a requested resource is not found."
"description": "If the requested object path is missing, and any mainPageSuffix object is missing, if applicable, the service will return the named object from this bucket as the content for a 404 Not Found result."
}
}
}
@ -574,7 +574,7 @@
},
"contentType": {
"type": "string",
"description": "Content-Type of the object data."
"description": "Content-Type of the object data. If contentType is not specified, object downloads will be served as application/octet-stream."
},
"crc32c": {
"type": "string",
@ -1088,7 +1088,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit acl and defaultObjectAcl properties."
"Omit owner, acl and defaultObjectAcl properties."
],
"location": "query"
}
@ -1168,7 +1168,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit acl and defaultObjectAcl properties."
"Omit owner, acl and defaultObjectAcl properties."
],
"location": "query"
}
@ -1226,7 +1226,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit acl and defaultObjectAcl properties."
"Omit owner, acl and defaultObjectAcl properties."
],
"location": "query"
}
@ -1318,7 +1318,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit acl and defaultObjectAcl properties."
"Omit owner, acl and defaultObjectAcl properties."
],
"location": "query"
}
@ -1334,8 +1334,7 @@
},
"scopes": [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/devstorage.full_control",
"https://www.googleapis.com/auth/devstorage.read_write"
"https://www.googleapis.com/auth/devstorage.full_control"
]
},
"update": {
@ -1411,7 +1410,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit acl and defaultObjectAcl properties."
"Omit owner, acl and defaultObjectAcl properties."
],
"location": "query"
}
@ -1427,8 +1426,7 @@
},
"scopes": [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/devstorage.full_control",
"https://www.googleapis.com/auth/devstorage.read_write"
"https://www.googleapis.com/auth/devstorage.full_control"
]
}
}
@ -2076,7 +2074,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit the acl property."
"Omit the owner, acl property."
],
"location": "query"
},
@ -2235,7 +2233,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit the acl property."
"Omit the owner, acl property."
],
"location": "query"
}
@ -2333,7 +2331,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit the acl property."
"Omit the owner, acl property."
],
"location": "query"
}
@ -2414,7 +2412,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit the acl property."
"Omit the owner, acl property."
],
"location": "query"
},
@ -2517,7 +2515,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit the acl property."
"Omit the owner, acl property."
],
"location": "query"
}
@ -2534,8 +2532,7 @@
},
"scopes": [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/devstorage.full_control",
"https://www.googleapis.com/auth/devstorage.read_write"
"https://www.googleapis.com/auth/devstorage.full_control"
]
},
"rewrite": {
@ -2640,7 +2637,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit the acl property."
"Omit the owner, acl property."
],
"location": "query"
},
@ -2764,7 +2761,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit the acl property."
"Omit the owner, acl property."
],
"location": "query"
}
@ -2781,8 +2778,7 @@
},
"scopes": [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/devstorage.full_control",
"https://www.googleapis.com/auth/devstorage.read_write"
"https://www.googleapis.com/auth/devstorage.full_control"
],
"supportsMediaDownload": true,
"useMediaDownloadService": true
@ -2830,7 +2826,7 @@
],
"enumDescriptions": [
"Include all properties.",
"Omit the acl property."
"Omit the owner, acl property."
],
"location": "query"
},

File diff suppressed because it is too large Load Diff

12
vendor/vendor.json vendored
View File

@ -1927,8 +1927,10 @@
"revision": "5eaf0df67e70d6997a9fe0ed24383fa1b01638d3"
},
{
"checksumSHA1": "SjcL6w27LsP7xLQe9V068FO3qWI=",
"path": "google.golang.org/api/compute/v1",
"revision": "43c645d4bcf9251ced36c823a93b6d198764aae4"
"revision": "fa0566afd4c8fdae644725fdf9b57b5851a20742",
"revisionTime": "2016-07-18T05:58:24Z"
},
{
"path": "google.golang.org/api/container/v1",
@ -1939,8 +1941,10 @@
"revision": "43c645d4bcf9251ced36c823a93b6d198764aae4"
},
{
"checksumSHA1": "SLzHstPylt3EcBt9yEBJV+JqGp4=",
"path": "google.golang.org/api/gensupport",
"revision": "43c645d4bcf9251ced36c823a93b6d198764aae4"
"revision": "fa0566afd4c8fdae644725fdf9b57b5851a20742",
"revisionTime": "2016-07-18T05:58:24Z"
},
{
"path": "google.golang.org/api/googleapi",
@ -1959,8 +1963,10 @@
"revision": "43c645d4bcf9251ced36c823a93b6d198764aae4"
},
{
"checksumSHA1": "xIEDa8ZDicVplvLtQUHc9eVZays=",
"path": "google.golang.org/api/storage/v1",
"revision": "43c645d4bcf9251ced36c823a93b6d198764aae4"
"revision": "fa0566afd4c8fdae644725fdf9b57b5851a20742",
"revisionTime": "2016-07-18T05:58:24Z"
},
{
"path": "google.golang.org/appengine",

View File

@ -19,6 +19,7 @@ resource "google_compute_backend_service" "foobar" {
port_name = "http"
protocol = "HTTP"
timeout_sec = 10
enable_cdn = false
backend {
group = "${google_compute_instance_group_manager.foo.instance_group}"
@ -74,6 +75,8 @@ The following arguments are supported:
* `description` - (Optional) The textual description for the backend service.
* `enable_cdn` - (Optional) Whether or not to enable the Cloud CDN on the backend service.
* `port_name` - (Optional) The name of a service that has been added to an
instance group in this backend. See [related docs](https://cloud.google.com/compute/docs/instance-groups/#specifying_service_endpoints) for details. Defaults to http.