Add liens resource. (#1484)

This commit is contained in:
The Magician 2018-05-17 16:33:30 -07:00 committed by Nathan McKinley
parent 6ae7dc6f72
commit 56481d8316
17 changed files with 633 additions and 17 deletions

View File

@ -95,6 +95,7 @@ func Provider() terraform.ResourceProvider {
ResourcesMap: mergeResourceMaps(
GeneratedComputeResourcesMap,
GeneratedResourceManagerResourcesMap,
map[string]*schema.Resource{
"google_bigquery_dataset": resourceBigQueryDataset(),
"google_bigquery_table": resourceBigQueryTable(),

View File

@ -0,0 +1,21 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------
package google
import "github.com/hashicorp/terraform/helper/schema"
var GeneratedResourceManagerResourcesMap = map[string]*schema.Resource{
"google_resource_manager_lien": resourceResourceManagerLien(),
}

View File

@ -143,6 +143,8 @@ func resourceComputeBackendBucketCreate(d *schema.ResourceData, meta interface{}
return fmt.Errorf("Error waiting to create BackendBucket: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating BackendBucket %q: %#v", d.Id(), res)
return resourceComputeBackendBucketRead(d, meta)
}
@ -163,6 +165,7 @@ func resourceComputeBackendBucketRead(d *schema.ResourceData, meta interface{})
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeBackendBucket %q", d.Id()))
}
if err := d.Set("bucket_name", flattenComputeBackendBucketBucketName(res["bucketName"])); err != nil {
return fmt.Errorf("Error reading BackendBucket: %s", err)
}
@ -282,6 +285,7 @@ func resourceComputeBackendBucketDelete(d *schema.ResourceData, meta interface{}
return err
}
log.Printf("[DEBUG] Finished deleting BackendBucket %q: %#v", d.Id(), res)
return nil
}

View File

@ -139,6 +139,8 @@ func resourceComputeGlobalAddressCreate(d *schema.ResourceData, meta interface{}
return fmt.Errorf("Error waiting to create GlobalAddress: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating GlobalAddress %q: %#v", d.Id(), res)
return resourceComputeGlobalAddressRead(d, meta)
}
@ -159,6 +161,7 @@ func resourceComputeGlobalAddressRead(d *schema.ResourceData, meta interface{})
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeGlobalAddress %q", d.Id()))
}
if err := d.Set("address", flattenComputeGlobalAddressAddress(res["address"])); err != nil {
return fmt.Errorf("Error reading GlobalAddress: %s", err)
}
@ -217,6 +220,7 @@ func resourceComputeGlobalAddressDelete(d *schema.ResourceData, meta interface{}
return err
}
log.Printf("[DEBUG] Finished deleting GlobalAddress %q: %#v", d.Id(), res)
return nil
}

View File

@ -194,6 +194,8 @@ func resourceComputeHttpHealthCheckCreate(d *schema.ResourceData, meta interface
return fmt.Errorf("Error waiting to create HttpHealthCheck: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating HttpHealthCheck %q: %#v", d.Id(), res)
return resourceComputeHttpHealthCheckRead(d, meta)
}
@ -214,6 +216,7 @@ func resourceComputeHttpHealthCheckRead(d *schema.ResourceData, meta interface{}
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeHttpHealthCheck %q", d.Id()))
}
if err := d.Set("check_interval_sec", flattenComputeHttpHealthCheckCheckIntervalSec(res["checkIntervalSec"])); err != nil {
return fmt.Errorf("Error reading HttpHealthCheck: %s", err)
}
@ -373,6 +376,7 @@ func resourceComputeHttpHealthCheckDelete(d *schema.ResourceData, meta interface
return err
}
log.Printf("[DEBUG] Finished deleting HttpHealthCheck %q: %#v", d.Id(), res)
return nil
}

View File

@ -194,6 +194,8 @@ func resourceComputeHttpsHealthCheckCreate(d *schema.ResourceData, meta interfac
return fmt.Errorf("Error waiting to create HttpsHealthCheck: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating HttpsHealthCheck %q: %#v", d.Id(), res)
return resourceComputeHttpsHealthCheckRead(d, meta)
}
@ -214,6 +216,7 @@ func resourceComputeHttpsHealthCheckRead(d *schema.ResourceData, meta interface{
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeHttpsHealthCheck %q", d.Id()))
}
if err := d.Set("check_interval_sec", flattenComputeHttpsHealthCheckCheckIntervalSec(res["checkIntervalSec"])); err != nil {
return fmt.Errorf("Error reading HttpsHealthCheck: %s", err)
}
@ -373,6 +376,7 @@ func resourceComputeHttpsHealthCheckDelete(d *schema.ResourceData, meta interfac
return err
}
log.Printf("[DEBUG] Finished deleting HttpsHealthCheck %q: %#v", d.Id(), res)
return nil
}

View File

@ -195,6 +195,8 @@ func resourceComputeSslPolicyCreate(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("Error waiting to create SslPolicy: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating SslPolicy %q: %#v", d.Id(), res)
return resourceComputeSslPolicyRead(d, meta)
}
@ -215,6 +217,7 @@ func resourceComputeSslPolicyRead(d *schema.ResourceData, meta interface{}) erro
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeSslPolicy %q", d.Id()))
}
if err := d.Set("creation_timestamp", flattenComputeSslPolicyCreationTimestamp(res["creationTimestamp"])); err != nil {
return fmt.Errorf("Error reading SslPolicy: %s", err)
}
@ -349,6 +352,7 @@ func resourceComputeSslPolicyDelete(d *schema.ResourceData, meta interface{}) er
return err
}
log.Printf("[DEBUG] Finished deleting SslPolicy %q: %#v", d.Id(), res)
return nil
}

View File

@ -140,6 +140,8 @@ func resourceComputeTargetHttpProxyCreate(d *schema.ResourceData, meta interface
return fmt.Errorf("Error waiting to create TargetHttpProxy: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating TargetHttpProxy %q: %#v", d.Id(), res)
return resourceComputeTargetHttpProxyRead(d, meta)
}
@ -160,6 +162,7 @@ func resourceComputeTargetHttpProxyRead(d *schema.ResourceData, meta interface{}
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeTargetHttpProxy %q", d.Id()))
}
if err := d.Set("creation_timestamp", flattenComputeTargetHttpProxyCreationTimestamp(res["creationTimestamp"])); err != nil {
return fmt.Errorf("Error reading TargetHttpProxy: %s", err)
}
@ -272,6 +275,7 @@ func resourceComputeTargetHttpProxyDelete(d *schema.ResourceData, meta interface
return err
}
log.Printf("[DEBUG] Finished deleting TargetHttpProxy %q: %#v", d.Id(), res)
return nil
}

View File

@ -163,6 +163,8 @@ func resourceComputeTargetHttpsProxyCreate(d *schema.ResourceData, meta interfac
return fmt.Errorf("Error waiting to create TargetHttpsProxy: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating TargetHttpsProxy %q: %#v", d.Id(), res)
return resourceComputeTargetHttpsProxyRead(d, meta)
}
@ -183,6 +185,7 @@ func resourceComputeTargetHttpsProxyRead(d *schema.ResourceData, meta interface{
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeTargetHttpsProxy %q", d.Id()))
}
if err := d.Set("creation_timestamp", flattenComputeTargetHttpsProxyCreationTimestamp(res["creationTimestamp"])); err != nil {
return fmt.Errorf("Error reading TargetHttpsProxy: %s", err)
}
@ -367,6 +370,7 @@ func resourceComputeTargetHttpsProxyDelete(d *schema.ResourceData, meta interfac
return err
}
log.Printf("[DEBUG] Finished deleting TargetHttpsProxy %q: %#v", d.Id(), res)
return nil
}

View File

@ -166,6 +166,8 @@ func resourceComputeTargetSslProxyCreate(d *schema.ResourceData, meta interface{
return fmt.Errorf("Error waiting to create TargetSslProxy: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating TargetSslProxy %q: %#v", d.Id(), res)
return resourceComputeTargetSslProxyRead(d, meta)
}
@ -186,6 +188,7 @@ func resourceComputeTargetSslProxyRead(d *schema.ResourceData, meta interface{})
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeTargetSslProxy %q", d.Id()))
}
if err := d.Set("creation_timestamp", flattenComputeTargetSslProxyCreationTimestamp(res["creationTimestamp"])); err != nil {
return fmt.Errorf("Error reading TargetSslProxy: %s", err)
}
@ -370,6 +373,7 @@ func resourceComputeTargetSslProxyDelete(d *schema.ResourceData, meta interface{
return err
}
log.Printf("[DEBUG] Finished deleting TargetSslProxy %q: %#v", d.Id(), res)
return nil
}

View File

@ -152,6 +152,8 @@ func resourceComputeTargetTcpProxyCreate(d *schema.ResourceData, meta interface{
return fmt.Errorf("Error waiting to create TargetTcpProxy: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating TargetTcpProxy %q: %#v", d.Id(), res)
return resourceComputeTargetTcpProxyRead(d, meta)
}
@ -172,6 +174,7 @@ func resourceComputeTargetTcpProxyRead(d *schema.ResourceData, meta interface{})
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeTargetTcpProxy %q", d.Id()))
}
if err := d.Set("creation_timestamp", flattenComputeTargetTcpProxyCreationTimestamp(res["creationTimestamp"])); err != nil {
return fmt.Errorf("Error reading TargetTcpProxy: %s", err)
}
@ -320,6 +323,7 @@ func resourceComputeTargetTcpProxyDelete(d *schema.ResourceData, meta interface{
return err
}
log.Printf("[DEBUG] Finished deleting TargetTcpProxy %q: %#v", d.Id(), res)
return nil
}

View File

@ -146,6 +146,8 @@ func resourceComputeVpnGatewayCreate(d *schema.ResourceData, meta interface{}) e
return fmt.Errorf("Error waiting to create VpnGateway: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating VpnGateway %q: %#v", d.Id(), res)
return resourceComputeVpnGatewayRead(d, meta)
}
@ -166,6 +168,7 @@ func resourceComputeVpnGatewayRead(d *schema.ResourceData, meta interface{}) err
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeVpnGateway %q", d.Id()))
}
if err := d.Set("creation_timestamp", flattenComputeVpnGatewayCreationTimestamp(res["creationTimestamp"])); err != nil {
return fmt.Errorf("Error reading VpnGateway: %s", err)
}
@ -224,6 +227,7 @@ func resourceComputeVpnGatewayDelete(d *schema.ResourceData, meta interface{}) e
return err
}
log.Printf("[DEBUG] Finished deleting VpnGateway %q: %#v", d.Id(), res)
return nil
}

View File

@ -0,0 +1,336 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------
package google
import (
"fmt"
"log"
"reflect"
"strconv"
"strings"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceResourceManagerLien() *schema.Resource {
return &schema.Resource{
Create: resourceResourceManagerLienCreate,
Read: resourceResourceManagerLienRead,
Delete: resourceResourceManagerLienDelete,
Importer: &schema.ResourceImporter{
State: resourceResourceManagerLienImport,
},
Schema: map[string]*schema.Schema{
"origin": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"parent": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"reason": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"restrictions": {
Type: schema.TypeList,
Required: true,
ForceNew: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"create_time": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceResourceManagerLienCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
reasonProp, err := expandResourceManagerLienReason(d.Get("reason"), d, config)
if err != nil {
return err
}
originProp, err := expandResourceManagerLienOrigin(d.Get("origin"), d, config)
if err != nil {
return err
}
parentProp, err := expandResourceManagerLienParent(d.Get("parent"), d, config)
if err != nil {
return err
}
restrictionsProp, err := expandResourceManagerLienRestrictions(d.Get("restrictions"), d, config)
if err != nil {
return err
}
obj := map[string]interface{}{
"reason": reasonProp,
"origin": originProp,
"parent": parentProp,
"restrictions": restrictionsProp,
}
url, err := replaceVars(d, config, "https://cloudresourcemanager.googleapis.com/v1/liens")
if err != nil {
return err
}
log.Printf("[DEBUG] Creating new Lien: %#v", obj)
res, err := Post(config, url, obj)
if err != nil {
return fmt.Errorf("Error creating Lien: %s", err)
}
// Store the ID now
id, err := replaceVars(d, config, "{{name}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
log.Printf("[DEBUG] Finished creating Lien %q: %#v", d.Id(), res)
// This resource is unusual - instead of returning an Operation from
// Create, it returns the created object itself. We don't parse
// any of the values there, preferring to centralize that logic in
// Read(). In this resource, Read is also unusual - it requires
// us to know the server-side generated name of the object we're
// trying to fetch, and the only way to know that is to capture
// it here. The following two lines do that.
d.SetId(flattenResourceManagerLienName(res["name"]).(string))
d.Set("name", flattenResourceManagerLienName(res["name"]))
return resourceResourceManagerLienRead(d, meta)
}
func resourceResourceManagerLienRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
url, err := replaceVars(d, config, "https://cloudresourcemanager.googleapis.com/v1/liens?parent={{parent}}")
if err != nil {
return err
}
res, err := Get(config, url)
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ResourceManagerLien %q", d.Id()))
}
// Extract the object we're interested in from the list response.
itemsList_ := res["liens"]
var itemsList []interface{}
if itemsList_ != nil {
itemsList = itemsList_.([]interface{})
}
listObj := make([]map[string]interface{}, len(itemsList))
for i, item := range itemsList {
listObj[i] = item.(map[string]interface{})
}
res = nil
for _, item := range listObj {
thisName := d.Get("name")
thatName := flattenResourceManagerLienName(item["name"])
log.Printf("[DEBUG] Checking equality of %#v, %#v", thatName, thisName)
if !reflect.DeepEqual(thatName, thisName) {
continue
}
res = item
break
}
if res == nil {
// Object isn't there any more - remove it from the state.
log.Printf("[DEBUG] Removing ResourceManagerLien because it couldn't be matched.")
d.SetId("")
return nil
}
res, err = resourceResourceManagerLienDecoder(d, meta, res)
if err != nil {
return err
}
if err := d.Set("name", flattenResourceManagerLienName(res["name"])); err != nil {
return fmt.Errorf("Error reading Lien: %s", err)
}
if err := d.Set("reason", flattenResourceManagerLienReason(res["reason"])); err != nil {
return fmt.Errorf("Error reading Lien: %s", err)
}
if err := d.Set("origin", flattenResourceManagerLienOrigin(res["origin"])); err != nil {
return fmt.Errorf("Error reading Lien: %s", err)
}
if err := d.Set("create_time", flattenResourceManagerLienCreateTime(res["createTime"])); err != nil {
return fmt.Errorf("Error reading Lien: %s", err)
}
if err := d.Set("parent", flattenResourceManagerLienParent(res["parent"])); err != nil {
return fmt.Errorf("Error reading Lien: %s", err)
}
if err := d.Set("restrictions", flattenResourceManagerLienRestrictions(res["restrictions"])); err != nil {
return fmt.Errorf("Error reading Lien: %s", err)
}
return nil
}
func resourceResourceManagerLienDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
url, err := replaceVars(d, config, "https://cloudresourcemanager.googleapis.com/v1/liens?parent={{parent}}")
if err != nil {
return err
}
url, err = replaceVars(d, config, "https://cloudresourcemanager.googleapis.com/v1/liens/{{name}}")
if err != nil {
return err
}
log.Printf("[DEBUG] Deleting Lien %q", d.Id())
res, err := Delete(config, url)
if err != nil {
return fmt.Errorf("Error deleting Lien %q: %s", d.Id(), err)
}
log.Printf("[DEBUG] Finished deleting Lien %q: %#v", d.Id(), res)
return nil
}
func resourceResourceManagerLienImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*Config)
parseImportId([]string{"(?P<parent>[^/]+)/(?P<name>[^/]+)"}, d, config)
// Replace import id for the resource id
id, err := replaceVars(d, config, "{{name}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
parent, err := replaceVars(d, config, "projects/{{parent}}")
if err != nil {
return nil, err
}
d.Set("parent", parent)
return []*schema.ResourceData{d}, nil
}
func flattenResourceManagerLienName(v interface{}) interface{} {
return NameFromSelfLinkStateFunc(v)
}
func flattenResourceManagerLienReason(v interface{}) interface{} {
return v
}
func flattenResourceManagerLienOrigin(v interface{}) interface{} {
return v
}
func flattenResourceManagerLienCreateTime(v interface{}) interface{} {
return v
}
func flattenResourceManagerLienParent(v interface{}) interface{} {
return v
}
func flattenResourceManagerLienRestrictions(v interface{}) interface{} {
return v
}
func expandResourceManagerLienReason(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandResourceManagerLienOrigin(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandResourceManagerLienParent(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandResourceManagerLienRestrictions(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func resourceResourceManagerLienDecoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) {
// The problem we're trying to solve here is that this property is a Project,
// and there are a lot of ways to specify a Project, including the ID vs
// Number, which is something that we can't address in a diffsuppress.
// Since we can't enforce a particular method of entering the project,
// we're just going to have to use whatever the user entered, whether
// it's project/projectName, project/12345, projectName, or 12345.
// The normal behavior of this method would be 'return res' - and that's
// what we'll fall back to if any of our conditions aren't met. Those
// conditions are:
// 1) if the new or old values contain '/', the prefix of that is 'projects'.
// 2) if either is non-numeric, a project with that ID exists.
// 3) the project IDs represented by both the new and old values are the same.
config := meta.(*Config)
new := res["parent"].(string)
old := d.Get("parent").(string)
if strings.HasPrefix(new, "projects/") {
new = strings.Split(new, "/")[1]
}
if strings.HasPrefix(old, "projects/") {
old = strings.Split(old, "/")[1]
}
log.Printf("[DEBUG] Trying to figure out whether to use %s or %s", old, new)
// If there's still a '/' in there, the value must not be a project ID.
if strings.Contains(old, "/") || strings.Contains(new, "/") {
return res, nil
}
// If 'old' isn't entirely numeric, let's assume it's a project ID.
// If it's a project ID
var oldProjId int64
var newProjId int64
if oldVal, err := strconv.ParseInt(old, 10, 64); err == nil {
log.Printf("[DEBUG] The old value was a real number: %d", oldVal)
oldProjId = oldVal
} else {
pOld, err := config.clientResourceManager.Projects.Get(old).Do()
if err != nil {
return res, nil
}
oldProjId = pOld.ProjectNumber
}
if newVal, err := strconv.ParseInt(new, 10, 64); err == nil {
log.Printf("[DEBUG] The new value was a real number: %d", newVal)
newProjId = newVal
} else {
pNew, err := config.clientResourceManager.Projects.Get(new).Do()
if err != nil {
return res, nil
}
newProjId = pNew.ProjectNumber
}
if newProjId == oldProjId {
res["parent"] = d.Get("parent")
}
return res, nil
}

View File

@ -0,0 +1,108 @@
package google
import (
"fmt"
"strings"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
resourceManager "google.golang.org/api/cloudresourcemanager/v1"
)
func TestAccResourceManagerLien_basic(t *testing.T) {
t.Parallel()
projectName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
org := getTestOrgFromEnv(t)
var lien resourceManager.Lien
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckResourceManagerLienDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccResourceManagerLien_basic(projectName, org),
Check: resource.ComposeTestCheckFunc(
testAccCheckResourceManagerLienExists(
"google_resource_manager_lien.lien", projectName, &lien),
),
},
resource.TestStep{
ResourceName: "google_resource_manager_lien.lien",
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: func(_ *terraform.State) (string, error) {
// This has to be a function to close over lien.Name, which is necessary
// because Name is a Computed attribute.
return fmt.Sprintf("%s/%s",
projectName,
strings.Split(lien.Name, "/")[1]), nil
},
},
},
})
}
func testAccCheckResourceManagerLienExists(n, projectName string, lien *resourceManager.Lien) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}
config := testAccProvider.Meta().(*Config)
found, err := config.clientResourceManager.Liens.List().Parent(fmt.Sprintf("projects/%s", projectName)).Do()
if err != nil {
return err
}
if len(found.Liens) != 1 {
return fmt.Errorf("Lien %s not found", rs.Primary.ID)
}
*lien = *found.Liens[0]
return nil
}
}
func testAccCheckResourceManagerLienDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
for _, rs := range s.RootModule().Resources {
if rs.Type != "google_resource_manager_lien" {
continue
}
_, err := config.clientResourceManager.Liens.List().Parent(fmt.Sprintf("projects/%s", rs.Primary.Attributes["parent"])).Do()
if err == nil {
return fmt.Errorf("Lien %s still exists", rs.Primary.ID)
}
}
return nil
}
func testAccResourceManagerLien_basic(projectName, org string) string {
return fmt.Sprintf(`
resource "google_project" "project" {
project_id = "%s"
name = "some test project"
org_id = "%s"
}
resource "google_resource_manager_lien" "lien" {
parent = "projects/${google_project.project.project_id}"
restrictions = ["resourcemanager.projects.delete"]
origin = "something"
reason = "something else"
}
`, projectName, org)
}

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"net/http"
"net/url"
"reflect"
"regexp"
"strings"
@ -75,23 +76,23 @@ func isEmptyValue(v reflect.Value) bool {
return false
}
func Post(config *Config, url string, body map[string]interface{}) (map[string]interface{}, error) {
return sendRequest(config, "POST", url, body)
func Post(config *Config, rawurl string, body map[string]interface{}) (map[string]interface{}, error) {
return sendRequest(config, "POST", rawurl, body)
}
func Get(config *Config, url string) (map[string]interface{}, error) {
return sendRequest(config, "GET", url, nil)
func Get(config *Config, rawurl string) (map[string]interface{}, error) {
return sendRequest(config, "GET", rawurl, nil)
}
func Put(config *Config, url string, body map[string]interface{}) (map[string]interface{}, error) {
return sendRequest(config, "PUT", url, body)
func Put(config *Config, rawurl string, body map[string]interface{}) (map[string]interface{}, error) {
return sendRequest(config, "PUT", rawurl, body)
}
func Delete(config *Config, url string) (map[string]interface{}, error) {
return sendRequest(config, "DELETE", url, nil)
func Delete(config *Config, rawurl string) (map[string]interface{}, error) {
return sendRequest(config, "DELETE", rawurl, nil)
}
func sendRequest(config *Config, method, url string, body map[string]interface{}) (map[string]interface{}, error) {
func sendRequest(config *Config, method, rawurl string, body map[string]interface{}) (map[string]interface{}, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("User-Agent", config.userAgent)
reqHeaders.Set("Content-Type", "application/json")
@ -105,7 +106,15 @@ func sendRequest(config *Config, method, url string, body map[string]interface{}
}
}
req, err := http.NewRequest(method, url+"?alt=json", &buf)
u, err := url.Parse(rawurl)
if err != nil {
return nil, err
}
q := u.Query()
q.Set("alt", "json")
u.RawQuery = q.Encode()
req, err := http.NewRequest(method, u.String(), &buf)
if err != nil {
return nil, err
}

View File

@ -298,15 +298,13 @@ func mergeSchemas(a, b map[string]*schema.Schema) map[string]*schema.Schema {
return merged
}
func mergeResourceMaps(a, b map[string]*schema.Resource) map[string]*schema.Resource {
func mergeResourceMaps(ms ...map[string]*schema.Resource) map[string]*schema.Resource {
merged := make(map[string]*schema.Resource)
for k, v := range a {
merged[k] = v
}
for k, v := range b {
merged[k] = v
for _, m := range ms {
for k, v := range m {
merged[k] = v
}
}
return merged

View File

@ -0,0 +1,103 @@
---
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in
# .github/CONTRIBUTING.md.
#
# ----------------------------------------------------------------------------
layout: "google"
page_title: "Google: google_resourcemanager_lien"
sidebar_current: "docs-google-resourcemanager-lien"
description: |-
A Lien represents an encumbrance on the actions that can be performed on a resource.
---
# google\_resourcemanager\_lien
A Lien represents an encumbrance on the actions that can be performed on a resource.
## Example Usage
```hcl
resource "random_id" "r" {
byte_length = 8
}
resource "google_project" "project" {
project_id = "project-${random_id.r.hex}"
name = "A very important project!"
}
resource "google_resourcemanager_lien" "lien" {
parent = "projects/${google_project.project.number}"
restrictions = ["resourcemanager.projects.delete"]
origin = "machine-readable-explanation"
reason = "This project is very important to me!"
}
```
## Argument Reference
The following arguments are supported:
* `reason` -
(Required)
Concise user-visible strings indicating why an action cannot be performed
on a resource. Maximum length of 200 characters.
* `origin` -
(Required)
A stable, user-visible/meaningful string identifying the origin
of the Lien, intended to be inspected programmatically. Maximum length of
200 characters.
* `parent` -
(Required)
A reference to the resource this Lien is attached to.
The server will validate the parent against those for which Liens are supported.
Since a variety of objects can have Liens against them, you must provide the type
prefix (e.g. "projects/my-project-name").
* `restrictions` -
(Required)
The types of operations which should be blocked as a result of this Lien.
Each value should correspond to an IAM permission. The server will validate
the permissions against those for which Liens are supported. An empty
list is meaningless and will be rejected.
e.g. ['resourcemanager.projects.delete']
- - -
## Attributes Reference
In addition to the arguments listed above, the following computed attributes are exported:
* `name` -
A system-generated unique identifier for this Lien.
* `create_time` -
Time of creation
## Timeouts
This resource provides the following
[Timeouts](/docs/configuration/resources.html#timeouts) configuration options:
- `create` - Default is 4 minutes.
- `delete` - Default is 4 minutes.
## Import
Lien can be imported using any of these accepted formats:
```
$ terraform import google_resourcemanager_lien.default {{parent}}/{{name}}
```