Merge pull request #7852 from gaker/google-provider-backend-cdn
google_compute_backend_service "enable_cdn"
This commit is contained in:
commit
89df636163
|
@ -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()
|
||||
|
|
|
@ -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
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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
|
@ -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",
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue