Add support for Google RuntimeConfig (#315)

* Vendor runtimeconfig

* Add support for RuntimeConfig config and variable resources

This allows users to create/manage Google RuntimeConfig resources and
variables. More information here:
https://cloud.google.com/deployment-manager/runtime-configurator/

Closes #236

* Remove typo

* Use top-level declaration rather than init()

* Cleanup testing-related code by using ConflictsWith

Also adds better comments around how update works
This commit is contained in:
Joe Selman 2017-08-14 14:16:11 -07:00 committed by GitHub
parent 09fb183e40
commit bcaa151cfa
12 changed files with 6555 additions and 0 deletions

View File

@ -25,6 +25,7 @@ import (
"google.golang.org/api/dns/v1"
"google.golang.org/api/iam/v1"
"google.golang.org/api/pubsub/v1"
"google.golang.org/api/runtimeconfig/v1beta1"
"google.golang.org/api/servicemanagement/v1"
"google.golang.org/api/sourcerepo/v1"
"google.golang.org/api/spanner/v1"
@ -46,6 +47,7 @@ type Config struct {
clientDns *dns.Service
clientPubsub *pubsub.Service
clientResourceManager *cloudresourcemanager.Service
clientRuntimeconfig *runtimeconfig.Service
clientSpanner *spanner.Service
clientSourceRepo *sourcerepo.Service
clientStorage *storage.Service
@ -177,6 +179,13 @@ func (c *Config) loadAndValidate() error {
}
c.clientResourceManager.UserAgent = userAgent
log.Printf("[INFO] Instantiating Google Cloud Runtimeconfig Client...")
c.clientRuntimeconfig, err = runtimeconfig.New(client)
if err != nil {
return err
}
c.clientRuntimeconfig.UserAgent = userAgent
log.Printf("[INFO] Instantiating Google Cloud IAM Client...")
c.clientIAM, err = iam.New(client)
if err != nil {

View File

@ -123,6 +123,8 @@ func Provider() terraform.ResourceProvider {
"google_project_services": resourceGoogleProjectServices(),
"google_pubsub_topic": resourcePubsubTopic(),
"google_pubsub_subscription": resourcePubsubSubscription(),
"google_runtimeconfig_config": resourceRuntimeconfigConfig(),
"google_runtimeconfig_variable": resourceRuntimeconfigVariable(),
"google_service_account": resourceGoogleServiceAccount(),
"google_storage_bucket": resourceStorageBucket(),
"google_storage_bucket_acl": resourceStorageBucketAcl(),

View File

@ -0,0 +1,146 @@
package google
import (
"fmt"
"regexp"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/runtimeconfig/v1beta1"
)
var runtimeConfigFullName *regexp.Regexp = regexp.MustCompile("^projects/([^/]+)/configs/(.+)$")
func resourceRuntimeconfigConfig() *schema.Resource {
return &schema.Resource{
Create: resourceRuntimeconfigConfigCreate,
Read: resourceRuntimeconfigConfigRead,
Update: resourceRuntimeconfigConfigUpdate,
Delete: resourceRuntimeconfigConfigDelete,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateGCPName,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"project": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
}
}
func resourceRuntimeconfigConfigCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
name := d.Get("name").(string)
fullName := resourceRuntimeconfigFullName(project, name)
runtimeConfig := runtimeconfig.RuntimeConfig{
Name: fullName,
}
if val, ok := d.GetOk("description"); ok {
runtimeConfig.Description = val.(string)
}
_, err = config.clientRuntimeconfig.Projects.Configs.Create("projects/"+project, &runtimeConfig).Do()
if err != nil {
return err
}
d.SetId(fullName)
return nil
}
func resourceRuntimeconfigConfigRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
fullName := d.Id()
runConfig, err := config.clientRuntimeconfig.Projects.Configs.Get(fullName).Do()
if err != nil {
return err
}
project, name, err := resourceRuntimeconfigParseFullName(runConfig.Name)
if err != nil {
return err
}
// Check to see if project matches our current defined value - if it doesn't, we'll explicitly set it
curProject, err := getProject(d, config)
if err != nil {
return err
}
if project != curProject {
d.Set("project", project)
}
d.Set("name", name)
d.Set("description", runConfig.Description)
return nil
}
func resourceRuntimeconfigConfigUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
// Update works more like an 'overwrite' method - we build a new runtimeconfig.RuntimeConfig struct and it becomes
// the new config. This means our Update logic looks an awful lot like Create (and hence, doesn't use
// schema.ResourceData.hasChange()).
fullName := d.Id()
runtimeConfig := runtimeconfig.RuntimeConfig{
Name: fullName,
}
if v, ok := d.GetOk("description"); ok {
runtimeConfig.Description = v.(string)
}
_, err := config.clientRuntimeconfig.Projects.Configs.Update(fullName, &runtimeConfig).Do()
if err != nil {
return err
}
return nil
}
func resourceRuntimeconfigConfigDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
fullName := d.Id()
_, err := config.clientRuntimeconfig.Projects.Configs.Delete(fullName).Do()
if err != nil {
return err
}
d.SetId("")
return nil
}
// resourceRuntimeconfigFullName turns a given project and a 'short name' for a runtime config into a full name
// (e.g. projects/my-project/configs/my-config).
func resourceRuntimeconfigFullName(project, name string) string {
return fmt.Sprintf("projects/%s/configs/%s", project, name)
}
// resourceRuntimeconfigParseFullName parses a full name (e.g. projects/my-project/configs/my-config) by parsing out the
// project and the short name. Returns "", "", nil upon error.
func resourceRuntimeconfigParseFullName(fullName string) (project, name string, err error) {
matches := runtimeConfigFullName.FindStringSubmatch(fullName)
if matches == nil {
return "", "", fmt.Errorf("Given full name doesn't match expected regexp; fullname = '%s'", fullName)
}
return matches[1], matches[2], nil
}

View File

@ -0,0 +1,159 @@
package google
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/runtimeconfig/v1beta1"
)
func TestAccRuntimeconfigConfig_basic(t *testing.T) {
var runtimeConfig runtimeconfig.RuntimeConfig
configName := fmt.Sprintf("runtimeconfig-test-%s", acctest.RandString(10))
description := "my test description"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRuntimeconfigConfigDestroy,
Steps: []resource.TestStep{
{
Config: testAccRuntimeconfigConfig_basicDescription(configName, description),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeConfigExists(
"google_runtimeconfig_config.foobar", &runtimeConfig),
testAccCheckRuntimeConfigDescription(&runtimeConfig, description),
),
},
},
})
}
func TestAccRuntimeconfig_update(t *testing.T) {
var runtimeConfig runtimeconfig.RuntimeConfig
configName := fmt.Sprintf("runtimeconfig-test-%s", acctest.RandString(10))
firstDescription := "my test description"
secondDescription := "my updated test description"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRuntimeconfigConfigDestroy,
Steps: []resource.TestStep{
{
Config: testAccRuntimeconfigConfig_basicDescription(configName, firstDescription),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeConfigExists(
"google_runtimeconfig_config.foobar", &runtimeConfig),
testAccCheckRuntimeConfigDescription(&runtimeConfig, firstDescription),
),
}, {
Config: testAccRuntimeconfigConfig_basicDescription(configName, secondDescription),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeConfigExists(
"google_runtimeconfig_config.foobar", &runtimeConfig),
testAccCheckRuntimeConfigDescription(&runtimeConfig, secondDescription),
),
},
},
})
}
func TestAccRuntimeconfig_updateEmptyDescription(t *testing.T) {
var runtimeConfig runtimeconfig.RuntimeConfig
configName := fmt.Sprintf("runtimeconfig-test-%s", acctest.RandString(10))
description := "my test description"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRuntimeconfigConfigDestroy,
Steps: []resource.TestStep{
{
Config: testAccRuntimeconfigConfig_basicDescription(configName, description),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeConfigExists(
"google_runtimeconfig_config.foobar", &runtimeConfig),
testAccCheckRuntimeConfigDescription(&runtimeConfig, description),
),
}, {
Config: testAccRuntimeconfigConfig_emptyDescription(configName),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeConfigExists(
"google_runtimeconfig_config.foobar", &runtimeConfig),
testAccCheckRuntimeConfigDescription(&runtimeConfig, ""),
),
},
},
})
}
func testAccCheckRuntimeConfigDescription(runtimeConfig *runtimeconfig.RuntimeConfig, description string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if runtimeConfig.Description != description {
return fmt.Errorf("On runtime config '%s', expected description '%s', but found '%s'",
runtimeConfig.Name, description, runtimeConfig.Description)
}
return nil
}
}
func testAccCheckRuntimeConfigExists(resourceName string, runtimeConfig *runtimeconfig.RuntimeConfig) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("Not found: %s", resourceName)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}
config := testAccProvider.Meta().(*Config)
found, err := config.clientRuntimeconfig.Projects.Configs.Get(rs.Primary.ID).Do()
if err != nil {
return err
}
*runtimeConfig = *found
return nil
}
}
func testAccCheckRuntimeconfigConfigDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
for _, rs := range s.RootModule().Resources {
if rs.Type != "google_runtimeconfig_config" {
continue
}
_, err := config.clientRuntimeconfig.Projects.Configs.Get(rs.Primary.ID).Do()
if err == nil {
return fmt.Errorf("Runtimeconfig still exists")
}
}
return nil
}
func testAccRuntimeconfigConfig_basicDescription(name, description string) string {
return fmt.Sprintf(`
resource "google_runtimeconfig_config" "foobar" {
name = "%s"
description = "%s"
}`, name, description)
}
func testAccRuntimeconfigConfig_emptyDescription(name string) string {
return fmt.Sprintf(`
resource "google_runtimeconfig_config" "foobar" {
name = "%s"
}`, name)
}

View File

@ -0,0 +1,196 @@
package google
import (
"fmt"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/runtimeconfig/v1beta1"
"regexp"
)
func resourceRuntimeconfigVariable() *schema.Resource {
return &schema.Resource{
Create: resourceRuntimeconfigVariableCreate,
Read: resourceRuntimeconfigVariableRead,
Update: resourceRuntimeconfigVariableUpdate,
Delete: resourceRuntimeconfigVariableDelete,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"parent": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"project": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"value": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"text"},
},
"text": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"value"},
},
"update_time": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceRuntimeconfigVariableCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
variable, parent, err := newRuntimeconfigVariableFromResourceData(d, project)
if err != nil {
return err
}
createdVariable, err := config.clientRuntimeconfig.Projects.Configs.Variables.Create(resourceRuntimeconfigFullName(project, parent), variable).Do()
if err != nil {
return err
}
d.SetId(createdVariable.Name)
return setRuntimeConfigVariableToResourceData(d, project, *createdVariable)
}
func resourceRuntimeconfigVariableRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
fullName := d.Id()
createdVariable, err := config.clientRuntimeconfig.Projects.Configs.Variables.Get(fullName).Do()
if err != nil {
return err
}
return setRuntimeConfigVariableToResourceData(d, project, *createdVariable)
}
func resourceRuntimeconfigVariableUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
// Update works more like an 'overwrite' method - we build a new runtimeconfig.Variable struct and it becomes the
// new config. This means our Update logic looks an awful lot like Create (and hence, doesn't use
// schema.ResourceData.hasChange()).
variable, _, err := newRuntimeconfigVariableFromResourceData(d, project)
if err != nil {
return err
}
createdVariable, err := config.clientRuntimeconfig.Projects.Configs.Variables.Update(variable.Name, variable).Do()
if err != nil {
return err
}
return setRuntimeConfigVariableToResourceData(d, project, *createdVariable)
}
func resourceRuntimeconfigVariableDelete(d *schema.ResourceData, meta interface{}) error {
fullName := d.Id()
config := meta.(*Config)
_, err := config.clientRuntimeconfig.Projects.Configs.Variables.Delete(fullName).Do()
if err != nil {
return err
}
d.SetId("")
return nil
}
// resourceRuntimeconfigVariableFullName turns a given project, runtime config name, and a 'short name' for a runtime
// config variable into a full name (e.g. projects/my-project/configs/my-config/variables/my-variable).
func resourceRuntimeconfigVariableFullName(project, config, name string) string {
return fmt.Sprintf("projects/%s/configs/%s/variables/%s", project, config, name)
}
// resourceRuntimeconfigVariableParseFullName parses a full name
// (e.g. projects/my-project/configs/my-config/variables/my-variable) by parsing out the
// project, runtime config name, and the short name. Returns "", "", "", err upon error.
func resourceRuntimeconfigVariableParseFullName(fullName string) (project, config, name string, err error) {
re := regexp.MustCompile("^projects/([^/]+)/configs/([^/]+)/variables/(.+)$")
matches := re.FindStringSubmatch(fullName)
if matches == nil {
return "", "", "", fmt.Errorf("Given full name doesn't match expected regexp; fullname = '%s'", fullName)
}
return matches[1], matches[2], matches[3], nil
}
// newRuntimeconfigVariableFromResourceData builds a new runtimeconfig.Variable struct from the data stored in a
// schema.ResourceData. Also returns the full name of the parent. Returns nil, "", err upon error.
func newRuntimeconfigVariableFromResourceData(d *schema.ResourceData, project string) (variable *runtimeconfig.Variable, parent string, err error) {
// Validate that both text and value are not set
text, textSet := d.GetOk("text")
value, valueSet := d.GetOk("value")
if !textSet && !valueSet {
return nil, "", fmt.Errorf("You must specify one of value or text.")
}
// TODO(selmanj) here we assume it's a simple name, not a full name. Should probably support full name as well
parent = d.Get("parent").(string)
name := d.Get("name").(string)
fullName := resourceRuntimeconfigVariableFullName(project, parent, name)
variable = &runtimeconfig.Variable{
Name: fullName,
}
if textSet {
variable.Text = text.(string)
} else {
variable.Value = value.(string)
}
return variable, parent, nil
}
// setRuntimeConfigVariableToResourceData stores a provided runtimeconfig.Variable struct inside a schema.ResourceData.
func setRuntimeConfigVariableToResourceData(d *schema.ResourceData, project string, variable runtimeconfig.Variable) error {
varProject, parent, name, err := resourceRuntimeconfigVariableParseFullName(variable.Name)
if err != nil {
return err
}
d.Set("name", name)
d.Set("parent", parent)
if varProject != project {
d.Set("project", varProject)
}
d.Set("value", variable.Value)
d.Set("text", variable.Text)
d.Set("update_time", variable.UpdateTime)
return nil
}

View File

@ -0,0 +1,270 @@
package google
import (
"fmt"
"regexp"
"testing"
"time"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/runtimeconfig/v1beta1"
)
func TestAccRuntimeconfigVariable_basic(t *testing.T) {
var variable runtimeconfig.Variable
varName := fmt.Sprintf("variable-test-%s", acctest.RandString(10))
varText := "this is my test value"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRuntimeconfigVariableDestroy,
Steps: []resource.TestStep{
{
Config: testAccRuntimeconfigVariable_basicText(varName, varText),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeconfigVariableExists(
"google_runtimeconfig_variable.foobar", &variable),
testAccCheckRuntimeconfigVariableText(&variable, varText),
testAccCheckRuntimeconfigVariableUpdateTime("google_runtimeconfig_variable.foobar"),
),
},
},
})
}
func TestAccRuntimeconfigVariable_basicUpdate(t *testing.T) {
var variable runtimeconfig.Variable
configName := fmt.Sprintf("some-name-%s", acctest.RandString(10))
varName := fmt.Sprintf("variable-test-%s", acctest.RandString(10))
varText := "this is my test value"
varText2 := "this is my updated value"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRuntimeconfigVariableDestroy,
Steps: []resource.TestStep{
{
Config: testAccRuntimeconfigVariable_basicTextUpdate(configName, varName, varText),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeconfigVariableExists(
"google_runtimeconfig_variable.foobar", &variable),
testAccCheckRuntimeconfigVariableText(&variable, varText),
),
}, {
Config: testAccRuntimeconfigVariable_basicTextUpdate(configName, varName, varText2),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeconfigVariableExists(
"google_runtimeconfig_variable.foobar", &variable),
testAccCheckRuntimeconfigVariableText(&variable, varText2),
),
},
},
})
}
func TestAccRuntimeconfigVariable_basicValue(t *testing.T) {
var variable runtimeconfig.Variable
varName := fmt.Sprintf("variable-test-%s", acctest.RandString(10))
varValue := "Zm9vYmFyCg=="
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRuntimeconfigVariableDestroy,
Steps: []resource.TestStep{
{
Config: testAccRuntimeconfigVariable_basicValue(varName, varValue),
Check: resource.ComposeTestCheckFunc(
testAccCheckRuntimeconfigVariableExists(
"google_runtimeconfig_variable.foobar", &variable),
testAccCheckRuntimeconfigVariableValue(&variable, varValue),
testAccCheckRuntimeconfigVariableUpdateTime("google_runtimeconfig_variable.foobar"),
),
},
},
})
}
func TestAccRuntimeconfigVariable_errorsOnBothValueAndText(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccRuntimeconfigVariable_invalidBothTextValue(),
ExpectError: regexp.MustCompile("conflicts with"),
},
},
})
}
func TestAccRuntimeconfigVariable_errorsOnMissingValueAndText(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccRuntimeconfigVariable_invalidMissingTextValue(),
ExpectError: regexp.MustCompile("You must specify one of value or text"),
},
},
})
}
func testAccCheckRuntimeconfigVariableExists(resourceName string, variable *runtimeconfig.Variable) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("Not found: %s", resourceName)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}
config := testAccProvider.Meta().(*Config)
found, err := config.clientRuntimeconfig.Projects.Configs.Variables.Get(rs.Primary.ID).Do()
if err != nil {
return err
}
*variable = *found
return nil
}
}
func testAccCheckRuntimeconfigVariableUpdateTime(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("Not found: %s", resourceName)
}
updateTime := rs.Primary.Attributes["update_time"]
if updateTime == "" {
return fmt.Errorf("No update time set for resource %s", resourceName)
}
// Make sure it's a valid rfc 3339 date
_, err := time.Parse(time.RFC3339, updateTime)
if err != nil {
return fmt.Errorf("Error while parsing update time for resource %s: %s", resourceName, err.Error())
}
return nil
}
}
func testAccCheckRuntimeconfigVariableText(variable *runtimeconfig.Variable, text string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if variable.Text != text {
return fmt.Errorf("Variable %s had incorrect text: expected '%s' but found '%s'", variable.Name,
text, variable.Text)
}
return nil
}
}
func testAccCheckRuntimeconfigVariableValue(variable *runtimeconfig.Variable, value string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if variable.Value != value {
return fmt.Errorf("Variable %s had incorrect value: expected '%s' but found '%s'", variable.Name,
value, variable.Value)
}
return nil
}
}
func testAccCheckRuntimeconfigVariableDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
for _, rs := range s.RootModule().Resources {
if rs.Type != "google_runtimeconfig_variable" {
continue
}
_, err := config.clientRuntimeconfig.Projects.Configs.Variables.Get(rs.Primary.ID).Do()
if err == nil {
return fmt.Errorf("Runtimeconfig variable still exists")
}
}
return nil
}
func testAccRuntimeconfigVariable_basicText(name, text string) string {
return fmt.Sprintf(`
resource "google_runtimeconfig_config" "foobar" {
name = "some-config-%s"
}
resource "google_runtimeconfig_variable" "foobar" {
parent = "${google_runtimeconfig_config.foobar.name}"
name = "%s"
text = "%s"
}`, acctest.RandString(10), name, text)
}
func testAccRuntimeconfigVariable_basicTextUpdate(configName, name, text string) string {
return fmt.Sprintf(`
resource "google_runtimeconfig_config" "foobar" {
name = "%s"
}
resource "google_runtimeconfig_variable" "foobar" {
parent = "${google_runtimeconfig_config.foobar.name}"
name = "%s"
text = "%s"
}`, configName, name, text)
}
func testAccRuntimeconfigVariable_basicValue(name, value string) string {
return fmt.Sprintf(`
resource "google_runtimeconfig_config" "foobar" {
name = "some-config-%s"
}
resource "google_runtimeconfig_variable" "foobar" {
parent = "${google_runtimeconfig_config.foobar.name}"
name = "%s"
value = "%s"
}`, acctest.RandString(10), name, value)
}
func testAccRuntimeconfigVariable_invalidBothTextValue() string {
return fmt.Sprintf(`
resource "google_runtimeconfig_config" "foobar" {
name = "some-config-%s"
}
resource "google_runtimeconfig_variable" "foobar" {
parent = "${google_runtimeconfig_config.foobar.name}"
name = "%s"
text = "here's my value"
value = "Zm9vYmFyCg=="
}`, acctest.RandString(10), acctest.RandString(10))
}
func testAccRuntimeconfigVariable_invalidMissingTextValue() string {
return fmt.Sprintf(`
resource "google_runtimeconfig_config" "foobar" {
name = "some-config-%s"
}
resource "google_runtimeconfig_variable" "foobar" {
parent = "${google_runtimeconfig_config.foobar.name}"
name = "my-variable-namespace/%s"
}`, acctest.RandString(10), acctest.RandString(10))
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6
vendor/vendor.json vendored
View File

@ -953,6 +953,12 @@
"revision": "3cc2e591b550923a2c5f0ab5a803feda924d5823",
"revisionTime": "2016-11-27T23:54:21Z"
},
{
"checksumSHA1": "I++0sh1HstuolRimPvyw9gNohXg=",
"path": "google.golang.org/api/runtimeconfig/v1beta1",
"revision": "5c4ffd5985e22d25e9cadc37183b88c3a31497c2",
"revisionTime": "2017-08-07T18:53:53Z"
},
{
"checksumSHA1": "4xiJmsULiSTn2iO4zUYtMgJqJSQ=",
"path": "google.golang.org/api/servicemanagement/v1",

View File

@ -0,0 +1,39 @@
---
layout: "google"
page_title: "Google: google_runtimeconfig_config"
sidebar_current: "docs-google-runtimeconfig-config"
description: |-
Manages a RuntimeConfig resource in Google Cloud.
---
# google\_runtimeconfig\_config
Manages a RuntimeConfig resource in Google Cloud. For more information, see the
[official documentation](https://cloud.google.com/deployment-manager/runtime-configurator/),
or the
[JSON API](https://cloud.google.com/deployment-manager/runtime-configurator/reference/rest/).
## Example Usage
Example creating a RuntimeConfig resource.
```hcl
resource "google_runtimeconfig_config" "my-runtime-config" {
name = "my-service-runtime-config"
description = "Runtime configuration values for my service"
}
```
## Argument Reference
The following arguments are supported:
* `name` - (Required) The name of the runtime config.
- - -
* `project` - (Optional) The project in which the resource belongs. If it
is not provided, the provider project is used.
* `description` - (Optional) The description to associate with the runtime
config.

View File

@ -0,0 +1,78 @@
---
layout: "google"
page_title: "Google: google_runtimeconfig_variable"
sidebar_current: "docs-google-runtimeconfig-variable"
description: |-
Manages a RuntimeConfig variable in Google Cloud.
---
# google\_runtimeconfig\_variable
Manages a RuntimeConfig variable in Google Cloud. For more information, see the
[official documentation](https://cloud.google.com/deployment-manager/runtime-configurator/),
or the
[JSON API](https://cloud.google.com/deployment-manager/runtime-configurator/reference/rest/).
## Example Usage
Example creating a RuntimeConfig variable.
```hcl
resource "google_runtimeconfig_config" "my-runtime-config" {
name = "my-service-runtime-config"
description = "Runtime configuration values for my service"
}
resource "google_runtimeconfig_variable" "environment" {
parent = "${google_runtimeconfig_config.my-runtime-config.name}"
name = "prod-variables/hostname"
text = "example.com"
}
```
You can also encode binary content using the `value` argument instead. The
value must be base64 encoded.
Example of using the `value` argument.
```hcl
resource "google_runtimeconfig_config" "my-runtime-config" {
name = "my-service-runtime-config"
description = "Runtime configuration values for my service"
}
resource "google_runtimeconfig_variable" "my-secret" {
parent = "${google_runtimeconfig_config.my-runtime-config.name}"
name = "secret"
value = "${base64encode(file("my-encrypted-secret.dat"))}"
}
```
## Argument Reference
The following arguments are supported:
* `name` - (Required) The name of the variable to manage. Note that variable
names can be hierarchical using slashes (e.g. "prod-variables/hostname").
* `parent` - (Required) The name of the RuntimeConfig resource containing this
variable.
* `text` or `value` - (Required) The content to associate with the variable.
Exactly one of `text` or `variable` must be specified. If `text` is specified,
it must be a valid UTF-8 string and less than 4096 bytes in length. If `value`
is specified, it must be base64 encoded and less than 4096 bytes in length.
- - -
* `project` - (Optional) The project in which the resource belongs. If it
is not provided, the provider project is used.
## Attributes Reference
In addition to the arguments listed above, the following computed attributes are
exported:
* `update_time` - (Computed) The timestamp in RFC3339 UTC "Zulu" format,
accurate to nanoseconds, representing when the variable was last updated.
Example: "2016-10-09T12:33:37.578138407Z".

View File

@ -270,6 +270,19 @@
</ul>
</li>
<li<%= sidebar_current("docs-google-runtimeconfig") %>>
<a href="#">Google RuntimeConfig Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-google-runtimeconfig-config") %>>
<a href="/docs/providers/google/r/runtimeconfig_config.html">google_runtimeconfig_config</a>
</li>
<li<%= sidebar_current("docs-google-runtimeconfig-variable") %>>
<a href="/docs/providers/google/r/runtimeconfig_variable.html">google_runtimeconfig_variable</a>
</li>
</ul>
</li>
<li<%= sidebar_current("docs-google-sourcerepo") %>>
<a href="#">Google Source Repositories Resources</a>
<ul class="nav nav-visible">