mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
Add Policy, Attestor, and Note resources for Binary Authorization (#1885)
<!-- This change is generated by MagicModules. --> /cc @danawillow
This commit is contained in:
parent
fb66cd88c5
commit
3ff7ccca7c
@ -99,7 +99,9 @@ func Provider() terraform.ResourceProvider {
|
||||
},
|
||||
|
||||
ResourcesMap: mergeResourceMaps(
|
||||
GeneratedBinaryAuthorizationResourcesMap,
|
||||
GeneratedComputeResourcesMap,
|
||||
GeneratedContainerAnalysisResourcesMap,
|
||||
GeneratedRedisResourcesMap,
|
||||
GeneratedResourceManagerResourcesMap,
|
||||
map[string]*schema.Resource{
|
||||
|
22
google/provider_binaryauthorization_gen.go
Normal file
22
google/provider_binaryauthorization_gen.go
Normal file
@ -0,0 +1,22 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// *** 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 GeneratedBinaryAuthorizationResourcesMap = map[string]*schema.Resource{
|
||||
"google_binary_authorization_attestor": resourceBinaryAuthorizationAttestor(),
|
||||
"google_binary_authorization_policy": resourceBinaryAuthorizationPolicy(),
|
||||
}
|
21
google/provider_containeranalysis_gen.go
Normal file
21
google/provider_containeranalysis_gen.go
Normal 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 GeneratedContainerAnalysisResourcesMap = map[string]*schema.Resource{
|
||||
"google_container_analysis_note": resourceContainerAnalysisNote(),
|
||||
}
|
397
google/resource_binaryauthorization_attestor.go
Normal file
397
google/resource_binaryauthorization_attestor.go
Normal file
@ -0,0 +1,397 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// *** 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"
|
||||
"regexp"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceBinaryAuthorizationAttestor() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceBinaryAuthorizationAttestorCreate,
|
||||
Read: resourceBinaryAuthorizationAttestorRead,
|
||||
Update: resourceBinaryAuthorizationAttestorUpdate,
|
||||
Delete: resourceBinaryAuthorizationAttestorDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: resourceBinaryAuthorizationAttestorImport,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"attestation_authority_note": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"note_reference": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
DiffSuppressFunc: compareSelfLinkOrResourceName,
|
||||
},
|
||||
"public_keys": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"ascii_armored_pgp_public_key": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"comment": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"delegation_service_account_email": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"project": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationAttestorCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
obj := make(map[string]interface{})
|
||||
nameProp, err := expandBinaryAuthorizationAttestorName(d.Get("name"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
|
||||
obj["name"] = nameProp
|
||||
}
|
||||
descriptionProp, err := expandBinaryAuthorizationAttestorDescription(d.Get("description"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
|
||||
obj["description"] = descriptionProp
|
||||
}
|
||||
userOwnedDrydockNoteProp, err := expandBinaryAuthorizationAttestorAttestationAuthorityNote(d.Get("attestation_authority_note"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("attestation_authority_note"); !isEmptyValue(reflect.ValueOf(userOwnedDrydockNoteProp)) && (ok || !reflect.DeepEqual(v, userOwnedDrydockNoteProp)) {
|
||||
obj["userOwnedDrydockNote"] = userOwnedDrydockNoteProp
|
||||
}
|
||||
|
||||
url, err := replaceVars(d, config, "https://binaryauthorization.googleapis.com/v1beta1/projects/{{project}}/attestors?attestorId={{name}}")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Creating new Attestor: %#v", obj)
|
||||
res, err := sendRequest(config, "POST", url, obj)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Attestor: %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 Attestor %q: %#v", d.Id(), res)
|
||||
|
||||
return resourceBinaryAuthorizationAttestorRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationAttestorRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
url, err := replaceVars(d, config, "https://binaryauthorization.googleapis.com/v1beta1/projects/{{project}}/attestors/{{name}}")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := sendRequest(config, "GET", url, nil)
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, fmt.Sprintf("BinaryAuthorizationAttestor %q", d.Id()))
|
||||
}
|
||||
|
||||
if err := d.Set("name", flattenBinaryAuthorizationAttestorName(res["name"])); err != nil {
|
||||
return fmt.Errorf("Error reading Attestor: %s", err)
|
||||
}
|
||||
if err := d.Set("description", flattenBinaryAuthorizationAttestorDescription(res["description"])); err != nil {
|
||||
return fmt.Errorf("Error reading Attestor: %s", err)
|
||||
}
|
||||
if err := d.Set("attestation_authority_note", flattenBinaryAuthorizationAttestorAttestationAuthorityNote(res["userOwnedDrydockNote"])); err != nil {
|
||||
return fmt.Errorf("Error reading Attestor: %s", err)
|
||||
}
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set("project", project); err != nil {
|
||||
return fmt.Errorf("Error reading Attestor: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationAttestorUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
obj := make(map[string]interface{})
|
||||
nameProp, err := expandBinaryAuthorizationAttestorName(d.Get("name"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nameProp)) {
|
||||
obj["name"] = nameProp
|
||||
}
|
||||
descriptionProp, err := expandBinaryAuthorizationAttestorDescription(d.Get("description"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
|
||||
obj["description"] = descriptionProp
|
||||
}
|
||||
userOwnedDrydockNoteProp, err := expandBinaryAuthorizationAttestorAttestationAuthorityNote(d.Get("attestation_authority_note"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("attestation_authority_note"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, userOwnedDrydockNoteProp)) {
|
||||
obj["userOwnedDrydockNote"] = userOwnedDrydockNoteProp
|
||||
}
|
||||
|
||||
url, err := replaceVars(d, config, "https://binaryauthorization.googleapis.com/v1beta1/projects/{{project}}/attestors/{{name}}")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Updating Attestor %q: %#v", d.Id(), obj)
|
||||
_, err = sendRequest(config, "PUT", url, obj)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error updating Attestor %q: %s", d.Id(), err)
|
||||
}
|
||||
|
||||
return resourceBinaryAuthorizationAttestorRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationAttestorDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
url, err := replaceVars(d, config, "https://binaryauthorization.googleapis.com/v1beta1/projects/{{project}}/attestors/{{name}}")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var obj map[string]interface{}
|
||||
log.Printf("[DEBUG] Deleting Attestor %q", d.Id())
|
||||
res, err := sendRequest(config, "DELETE", url, obj)
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, "Attestor")
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Finished deleting Attestor %q: %#v", d.Id(), res)
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationAttestorImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||
config := meta.(*Config)
|
||||
parseImportId([]string{"projects/(?P<project>[^/]+)/attestors/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<name>[^/]+)", "(?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)
|
||||
|
||||
return []*schema.ResourceData{d}, nil
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationAttestorName(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return v
|
||||
}
|
||||
return NameFromSelfLinkStateFunc(v)
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationAttestorDescription(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationAttestorAttestationAuthorityNote(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
original := v.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
transformed["note_reference"] =
|
||||
flattenBinaryAuthorizationAttestorAttestationAuthorityNoteNoteReference(original["noteReference"])
|
||||
transformed["public_keys"] =
|
||||
flattenBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeys(original["publicKeys"])
|
||||
transformed["delegation_service_account_email"] =
|
||||
flattenBinaryAuthorizationAttestorAttestationAuthorityNoteDelegationServiceAccountEmail(original["delegationServiceAccountEmail"])
|
||||
return []interface{}{transformed}
|
||||
}
|
||||
func flattenBinaryAuthorizationAttestorAttestationAuthorityNoteNoteReference(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeys(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return v
|
||||
}
|
||||
l := v.([]interface{})
|
||||
transformed := make([]interface{}, 0, len(l))
|
||||
for _, raw := range l {
|
||||
original := raw.(map[string]interface{})
|
||||
transformed = append(transformed, map[string]interface{}{
|
||||
"comment": flattenBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysComment(original["comment"]),
|
||||
"id": flattenBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysId(original["id"]),
|
||||
"ascii_armored_pgp_public_key": flattenBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysAsciiArmoredPgpPublicKey(original["asciiArmoredPgpPublicKey"]),
|
||||
})
|
||||
}
|
||||
return transformed
|
||||
}
|
||||
func flattenBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysComment(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysId(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysAsciiArmoredPgpPublicKey(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationAttestorAttestationAuthorityNoteDelegationServiceAccountEmail(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorDescription(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorAttestationAuthorityNote(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
l := v.([]interface{})
|
||||
if len(l) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
raw := l[0]
|
||||
original := raw.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
|
||||
transformedNoteReference, err := expandBinaryAuthorizationAttestorAttestationAuthorityNoteNoteReference(original["note_reference"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["noteReference"] = transformedNoteReference
|
||||
transformedPublicKeys, err := expandBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeys(original["public_keys"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["publicKeys"] = transformedPublicKeys
|
||||
transformedDelegationServiceAccountEmail, err := expandBinaryAuthorizationAttestorAttestationAuthorityNoteDelegationServiceAccountEmail(original["delegation_service_account_email"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["delegationServiceAccountEmail"] = transformedDelegationServiceAccountEmail
|
||||
return transformed, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorAttestationAuthorityNoteNoteReference(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
r := regexp.MustCompile("projects/(.+)/notes/(.+)")
|
||||
if r.MatchString(v.(string)) {
|
||||
return v.(string), nil
|
||||
}
|
||||
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("projects/%s/notes/%s", project, v.(string)), nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeys(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
l := v.([]interface{})
|
||||
req := make([]interface{}, 0, len(l))
|
||||
for _, raw := range l {
|
||||
original := raw.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
|
||||
transformedComment, err := expandBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysComment(original["comment"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["comment"] = transformedComment
|
||||
transformedId, err := expandBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysId(original["id"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["id"] = transformedId
|
||||
transformedAsciiArmoredPgpPublicKey, err := expandBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysAsciiArmoredPgpPublicKey(original["ascii_armored_pgp_public_key"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["asciiArmoredPgpPublicKey"] = transformedAsciiArmoredPgpPublicKey
|
||||
req = append(req, transformed)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysComment(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysId(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorAttestationAuthorityNotePublicKeysAsciiArmoredPgpPublicKey(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationAttestorAttestationAuthorityNoteDelegationServiceAccountEmail(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
182
google/resource_binaryauthorization_attestor_test.go
Normal file
182
google/resource_binaryauthorization_attestor_test.go
Normal file
@ -0,0 +1,182 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccBinaryAuthorizationAttestor_basic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
name := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckBinaryAuthorizationAttestorDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccBinaryAuthorizationAttestorBasic(name),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_attestor.attestor",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccBinaryAuthorizationAttestor_full(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
name := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckBinaryAuthorizationAttestorDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccBinaryAuthorizationAttestorFull(name),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_attestor.attestor",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccBinaryAuthorizationAttestor_update(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
name := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckBinaryAuthorizationAttestorDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccBinaryAuthorizationAttestorBasic(name),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_attestor.attestor",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
{
|
||||
Config: testAccBinaryAuthorizationAttestorFull(name),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_attestor.attestor",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
{
|
||||
Config: testAccBinaryAuthorizationAttestorBasic(name),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_attestor.attestor",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckBinaryAuthorizationAttestorDestroy(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "google_binary_authorization_attestor" {
|
||||
continue
|
||||
}
|
||||
|
||||
project, err := getTestProject(rs.Primary, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := rs.Primary.Attributes["name"]
|
||||
|
||||
url := fmt.Sprintf("https://binaryauthorization.googleapis.com/v1beta1/projects/%s/attestors/%s", project, name)
|
||||
_, err = sendRequest(config, "GET", url, nil)
|
||||
|
||||
if err == nil {
|
||||
return fmt.Errorf("Error, attestor %s still exists", name)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccBinaryAuthorizationAttestorBasic(name string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_container_analysis_note" "note" {
|
||||
name = "tf-test-%s"
|
||||
attestation_authority {
|
||||
hint {
|
||||
human_readable_name = "My Attestor"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_binary_authorization_attestor" "attestor" {
|
||||
name = "tf-test-%s"
|
||||
attestation_authority_note {
|
||||
note_reference = "${google_container_analysis_note.note.name}"
|
||||
}
|
||||
}
|
||||
`, name, name)
|
||||
}
|
||||
|
||||
func testAccBinaryAuthorizationAttestorFull(name string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_container_analysis_note" "note" {
|
||||
name = "tf-test-%s"
|
||||
attestation_authority {
|
||||
hint {
|
||||
human_readable_name = "My Attestor"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_binary_authorization_attestor" "attestor" {
|
||||
name = "tf-test-%s"
|
||||
description = "my description"
|
||||
attestation_authority_note {
|
||||
note_reference = "${google_container_analysis_note.note.name}"
|
||||
public_keys {
|
||||
ascii_armored_pgp_public_key = <<EOF
|
||||
%s
|
||||
EOF
|
||||
comment = "this key has a comment"
|
||||
}
|
||||
}
|
||||
}
|
||||
`, name, name, armoredPubKey)
|
||||
}
|
||||
|
||||
// Generated key using instructions from
|
||||
// https://cloud.google.com/binary-authorization/docs/creating-attestors#generate_pgp_key_pairs.
|
||||
// This key has no real meaning and was generated in order to have a valid key
|
||||
// for testing.
|
||||
const armoredPubKey = `mQENBFtP0doBCADF+joTiXWKVuP8kJt3fgpBSjT9h8ezMfKA4aXZctYLx5wslWQl
|
||||
bB7Iu2ezkECNzoEeU7WxUe8a61pMCh9cisS9H5mB2K2uM4Jnf8tgFeXn3akJDVo0
|
||||
oR1IC+Dp9mXbRSK3MAvKkOwWlG99sx3uEdvmeBRHBOO+grchLx24EThXFOyP9Fk6
|
||||
V39j6xMjw4aggLD15B4V0v9JqBDdJiIYFzszZDL6pJwZrzcP0z8JO4rTZd+f64bD
|
||||
Mpj52j/pQfA8lZHOaAgb1OrthLdMrBAjoDjArV4Ek7vSbrcgYWcI6BhsQrFoxKdX
|
||||
83TZKai55ZCfCLIskwUIzA1NLVwyzCS+fSN/ABEBAAG0KCJUZXN0IEF0dGVzdG9y
|
||||
IiA8ZGFuYWhvZmZtYW5AZ29vZ2xlLmNvbT6JAU4EEwEIADgWIQRfWkqHt6hpTA1L
|
||||
uY060eeM4dc66AUCW0/R2gIbLwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRA6
|
||||
0eeM4dc66HdpCAC4ot3b0OyxPb0Ip+WT2U0PbpTBPJklesuwpIrM4Lh0N+1nVRLC
|
||||
51WSmVbM8BiAFhLbN9LpdHhds1kUrHF7+wWAjdR8sqAj9otc6HGRM/3qfa2qgh+U
|
||||
WTEk/3us/rYSi7T7TkMuutRMIa1IkR13uKiW56csEMnbOQpn9rDqwIr5R8nlZP5h
|
||||
MAU9vdm1DIv567meMqTaVZgR3w7bck2P49AO8lO5ERFpVkErtu/98y+rUy9d789l
|
||||
+OPuS1NGnxI1YKsNaWJF4uJVuvQuZ1twrhCbGNtVorO2U12+cEq+YtUxj7kmdOC1
|
||||
qoIRW6y0+UlAc+MbqfL0ziHDOAmcqz1GnROg
|
||||
=6Bvm`
|
556
google/resource_binaryauthorization_policy.go
Normal file
556
google/resource_binaryauthorization_policy.go
Normal file
@ -0,0 +1,556 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// *** 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 (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/hashicorp/terraform/helper/validation"
|
||||
)
|
||||
|
||||
func defaultBinaryAuthorizationPolicy(project string) map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"name": fmt.Sprintf("projects/%s/policy", project),
|
||||
"admissionWhitelistPatterns": []interface{}{
|
||||
map[string]interface{}{
|
||||
"namePattern": "gcr.io/google_containers/*",
|
||||
},
|
||||
},
|
||||
"defaultAdmissionRule": map[string]interface{}{
|
||||
"evaluationMode": "ALWAYS_ALLOW",
|
||||
"enforcementMode": "ENFORCED_BLOCK_AND_AUDIT_LOG",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationPolicy() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceBinaryAuthorizationPolicyCreate,
|
||||
Read: resourceBinaryAuthorizationPolicyRead,
|
||||
Update: resourceBinaryAuthorizationPolicyUpdate,
|
||||
Delete: resourceBinaryAuthorizationPolicyDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: resourceBinaryAuthorizationPolicyImport,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"default_admission_rule": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"enforcement_mode": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"ENFORCED_BLOCK_AND_AUDIT_LOG", "DRYRUN_AUDIT_LOG_ONLY"}, false),
|
||||
},
|
||||
"evaluation_mode": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"ALWAYS_ALLOW", "REQUIRE_ATTESTATION", "ALWAYS_DENY"}, false),
|
||||
},
|
||||
"require_attestations_by": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
DiffSuppressFunc: compareSelfLinkOrResourceName,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Set: selfLinkNameHash,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"admission_whitelist_patterns": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name_pattern": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"cluster_admission_rules": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cluster": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"evaluation_mode": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"ALWAYS_ALLOW", "REQUIRE_ATTESTATION", "ALWAYS_DENY", ""}, false),
|
||||
},
|
||||
"require_attestations_by": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
DiffSuppressFunc: compareSelfLinkOrResourceName,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Set: selfLinkNameHash,
|
||||
},
|
||||
"enforcement_mode": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"ENFORCED_BLOCK_AND_AUDIT_LOG", "DRYRUN_AUDIT_LOG_ONLY", ""}, false),
|
||||
},
|
||||
},
|
||||
},
|
||||
Set: func(v interface{}) int {
|
||||
// require_attestations_by is a set of strings that can have the format
|
||||
// projects/{project}/attestors/{attestor} or {attestor}. We diffsuppress
|
||||
// and hash that set on the name, but now we need to make sure that the
|
||||
// overall hash here respects that so changing the attestor format doesn't
|
||||
// change the hash code of cluster_admission_rules.
|
||||
raw := v.(map[string]interface{})
|
||||
at := raw["require_attestations_by"].(*schema.Set)
|
||||
if at != nil {
|
||||
t := convertAndMapStringArr(at.List(), GetResourceNameFromSelfLink)
|
||||
raw["require_attestations_by"] = schema.NewSet(selfLinkNameHash, convertStringArrToInterface(t))
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
schema.SerializeResourceForHash(&buf, raw, resourceBinaryAuthorizationPolicy().Schema["cluster_admission_rules"].Elem.(*schema.Resource))
|
||||
return hashcode.String(buf.String())
|
||||
},
|
||||
},
|
||||
"project": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationPolicyCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
obj := make(map[string]interface{})
|
||||
descriptionProp, err := expandBinaryAuthorizationPolicyDescription(d.Get("description"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
|
||||
obj["description"] = descriptionProp
|
||||
}
|
||||
admissionWhitelistPatternsProp, err := expandBinaryAuthorizationPolicyAdmissionWhitelistPatterns(d.Get("admission_whitelist_patterns"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("admission_whitelist_patterns"); !isEmptyValue(reflect.ValueOf(admissionWhitelistPatternsProp)) && (ok || !reflect.DeepEqual(v, admissionWhitelistPatternsProp)) {
|
||||
obj["admissionWhitelistPatterns"] = admissionWhitelistPatternsProp
|
||||
}
|
||||
clusterAdmissionRulesProp, err := expandBinaryAuthorizationPolicyClusterAdmissionRules(d.Get("cluster_admission_rules"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("cluster_admission_rules"); !isEmptyValue(reflect.ValueOf(clusterAdmissionRulesProp)) && (ok || !reflect.DeepEqual(v, clusterAdmissionRulesProp)) {
|
||||
obj["clusterAdmissionRules"] = clusterAdmissionRulesProp
|
||||
}
|
||||
defaultAdmissionRuleProp, err := expandBinaryAuthorizationPolicyDefaultAdmissionRule(d.Get("default_admission_rule"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("default_admission_rule"); !isEmptyValue(reflect.ValueOf(defaultAdmissionRuleProp)) && (ok || !reflect.DeepEqual(v, defaultAdmissionRuleProp)) {
|
||||
obj["defaultAdmissionRule"] = defaultAdmissionRuleProp
|
||||
}
|
||||
|
||||
url, err := replaceVars(d, config, "https://binaryauthorization.googleapis.com/v1beta1/projects/{{project}}/policy")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Creating new Policy: %#v", obj)
|
||||
res, err := sendRequest(config, "PUT", url, obj)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Policy: %s", err)
|
||||
}
|
||||
|
||||
// Store the ID now
|
||||
id, err := replaceVars(d, config, "{{project}}")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error constructing id: %s", err)
|
||||
}
|
||||
d.SetId(id)
|
||||
|
||||
log.Printf("[DEBUG] Finished creating Policy %q: %#v", d.Id(), res)
|
||||
|
||||
return resourceBinaryAuthorizationPolicyRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationPolicyRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
url, err := replaceVars(d, config, "https://binaryauthorization.googleapis.com/v1beta1/projects/{{project}}/policy")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := sendRequest(config, "GET", url, nil)
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, fmt.Sprintf("BinaryAuthorizationPolicy %q", d.Id()))
|
||||
}
|
||||
|
||||
if err := d.Set("description", flattenBinaryAuthorizationPolicyDescription(res["description"])); err != nil {
|
||||
return fmt.Errorf("Error reading Policy: %s", err)
|
||||
}
|
||||
if err := d.Set("admission_whitelist_patterns", flattenBinaryAuthorizationPolicyAdmissionWhitelistPatterns(res["admissionWhitelistPatterns"])); err != nil {
|
||||
return fmt.Errorf("Error reading Policy: %s", err)
|
||||
}
|
||||
if err := d.Set("cluster_admission_rules", flattenBinaryAuthorizationPolicyClusterAdmissionRules(res["clusterAdmissionRules"])); err != nil {
|
||||
return fmt.Errorf("Error reading Policy: %s", err)
|
||||
}
|
||||
if err := d.Set("default_admission_rule", flattenBinaryAuthorizationPolicyDefaultAdmissionRule(res["defaultAdmissionRule"])); err != nil {
|
||||
return fmt.Errorf("Error reading Policy: %s", err)
|
||||
}
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set("project", project); err != nil {
|
||||
return fmt.Errorf("Error reading Policy: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
obj := make(map[string]interface{})
|
||||
descriptionProp, err := expandBinaryAuthorizationPolicyDescription(d.Get("description"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
|
||||
obj["description"] = descriptionProp
|
||||
}
|
||||
admissionWhitelistPatternsProp, err := expandBinaryAuthorizationPolicyAdmissionWhitelistPatterns(d.Get("admission_whitelist_patterns"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("admission_whitelist_patterns"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, admissionWhitelistPatternsProp)) {
|
||||
obj["admissionWhitelistPatterns"] = admissionWhitelistPatternsProp
|
||||
}
|
||||
clusterAdmissionRulesProp, err := expandBinaryAuthorizationPolicyClusterAdmissionRules(d.Get("cluster_admission_rules"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("cluster_admission_rules"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clusterAdmissionRulesProp)) {
|
||||
obj["clusterAdmissionRules"] = clusterAdmissionRulesProp
|
||||
}
|
||||
defaultAdmissionRuleProp, err := expandBinaryAuthorizationPolicyDefaultAdmissionRule(d.Get("default_admission_rule"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("default_admission_rule"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, defaultAdmissionRuleProp)) {
|
||||
obj["defaultAdmissionRule"] = defaultAdmissionRuleProp
|
||||
}
|
||||
|
||||
url, err := replaceVars(d, config, "https://binaryauthorization.googleapis.com/v1beta1/projects/{{project}}/policy")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Updating Policy %q: %#v", d.Id(), obj)
|
||||
_, err = sendRequest(config, "PUT", url, obj)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error updating Policy %q: %s", d.Id(), err)
|
||||
}
|
||||
|
||||
return resourceBinaryAuthorizationPolicyRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationPolicyDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
url, err := replaceVars(d, config, "https://binaryauthorization.googleapis.com/v1beta1/projects/{{project}}/policy")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var obj map[string]interface{}
|
||||
obj = defaultBinaryAuthorizationPolicy(d.Get("project").(string))
|
||||
log.Printf("[DEBUG] Deleting Policy %q", d.Id())
|
||||
res, err := sendRequest(config, "PUT", url, obj)
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, "Policy")
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Finished deleting Policy %q: %#v", d.Id(), res)
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceBinaryAuthorizationPolicyImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||
config := meta.(*Config)
|
||||
parseImportId([]string{"projects/(?P<project>[^/]+)", "(?P<project>[^/]+)"}, d, config)
|
||||
|
||||
// Replace import id for the resource id
|
||||
id, err := replaceVars(d, config, "{{project}}")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error constructing id: %s", err)
|
||||
}
|
||||
d.SetId(id)
|
||||
|
||||
return []*schema.ResourceData{d}, nil
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationPolicyDescription(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationPolicyAdmissionWhitelistPatterns(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return v
|
||||
}
|
||||
l := v.([]interface{})
|
||||
transformed := make([]interface{}, 0, len(l))
|
||||
for _, raw := range l {
|
||||
original := raw.(map[string]interface{})
|
||||
transformed = append(transformed, map[string]interface{}{
|
||||
"name_pattern": flattenBinaryAuthorizationPolicyAdmissionWhitelistPatternsNamePattern(original["namePattern"]),
|
||||
})
|
||||
}
|
||||
return transformed
|
||||
}
|
||||
func flattenBinaryAuthorizationPolicyAdmissionWhitelistPatternsNamePattern(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationPolicyClusterAdmissionRules(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return v
|
||||
}
|
||||
l := v.(map[string]interface{})
|
||||
transformed := make([]interface{}, 0, len(l))
|
||||
for k, raw := range l {
|
||||
original := raw.(map[string]interface{})
|
||||
transformed = append(transformed, map[string]interface{}{
|
||||
"cluster": k,
|
||||
"evaluation_mode": flattenBinaryAuthorizationPolicyClusterAdmissionRulesEvaluationMode(original["evaluationMode"]),
|
||||
"require_attestations_by": flattenBinaryAuthorizationPolicyClusterAdmissionRulesRequireAttestationsBy(original["requireAttestationsBy"]),
|
||||
"enforcement_mode": flattenBinaryAuthorizationPolicyClusterAdmissionRulesEnforcementMode(original["enforcementMode"]),
|
||||
})
|
||||
}
|
||||
return transformed
|
||||
}
|
||||
func flattenBinaryAuthorizationPolicyClusterAdmissionRulesEvaluationMode(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationPolicyClusterAdmissionRulesRequireAttestationsBy(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return v
|
||||
}
|
||||
return schema.NewSet(selfLinkNameHash, v.([]interface{}))
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationPolicyClusterAdmissionRulesEnforcementMode(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationPolicyDefaultAdmissionRule(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
original := v.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
transformed["evaluation_mode"] =
|
||||
flattenBinaryAuthorizationPolicyDefaultAdmissionRuleEvaluationMode(original["evaluationMode"])
|
||||
transformed["require_attestations_by"] =
|
||||
flattenBinaryAuthorizationPolicyDefaultAdmissionRuleRequireAttestationsBy(original["requireAttestationsBy"])
|
||||
transformed["enforcement_mode"] =
|
||||
flattenBinaryAuthorizationPolicyDefaultAdmissionRuleEnforcementMode(original["enforcementMode"])
|
||||
return []interface{}{transformed}
|
||||
}
|
||||
func flattenBinaryAuthorizationPolicyDefaultAdmissionRuleEvaluationMode(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationPolicyDefaultAdmissionRuleRequireAttestationsBy(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return v
|
||||
}
|
||||
return schema.NewSet(selfLinkNameHash, v.([]interface{}))
|
||||
}
|
||||
|
||||
func flattenBinaryAuthorizationPolicyDefaultAdmissionRuleEnforcementMode(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyDescription(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyAdmissionWhitelistPatterns(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
l := v.([]interface{})
|
||||
req := make([]interface{}, 0, len(l))
|
||||
for _, raw := range l {
|
||||
original := raw.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
|
||||
transformedNamePattern, err := expandBinaryAuthorizationPolicyAdmissionWhitelistPatternsNamePattern(original["name_pattern"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["namePattern"] = transformedNamePattern
|
||||
req = append(req, transformed)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyAdmissionWhitelistPatternsNamePattern(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyClusterAdmissionRules(v interface{}, d *schema.ResourceData, config *Config) (map[string]interface{}, error) {
|
||||
if v == nil {
|
||||
return map[string]interface{}{}, nil
|
||||
}
|
||||
m := make(map[string]interface{})
|
||||
for _, raw := range v.(*schema.Set).List() {
|
||||
original := raw.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
|
||||
transformedEvaluationMode, err := expandBinaryAuthorizationPolicyClusterAdmissionRulesEvaluationMode(original["evaluation_mode"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["evaluationMode"] = transformedEvaluationMode
|
||||
transformedRequireAttestationsBy, err := expandBinaryAuthorizationPolicyClusterAdmissionRulesRequireAttestationsBy(original["require_attestations_by"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["requireAttestationsBy"] = transformedRequireAttestationsBy
|
||||
transformedEnforcementMode, err := expandBinaryAuthorizationPolicyClusterAdmissionRulesEnforcementMode(original["enforcement_mode"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["enforcementMode"] = transformedEnforcementMode
|
||||
|
||||
m[original["cluster"].(string)] = transformed
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyClusterAdmissionRulesEvaluationMode(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyClusterAdmissionRulesRequireAttestationsBy(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
r := regexp.MustCompile("projects/(.+)/attestors/(.+)")
|
||||
|
||||
// It's possible that all entries in the list will specify a project, in
|
||||
// which case the user wouldn't necessarily have to specify a provider
|
||||
// project.
|
||||
var project string
|
||||
var err error
|
||||
for _, s := range v.(*schema.Set).List() {
|
||||
if !r.MatchString(s.(string)) {
|
||||
project, err = getProject(d, config)
|
||||
if err != nil {
|
||||
return []interface{}{}, err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return convertAndMapStringArr(v.(*schema.Set).List(), func(s string) string {
|
||||
if r.MatchString(s) {
|
||||
return s
|
||||
}
|
||||
|
||||
return fmt.Sprintf("projects/%s/attestors/%s", project, s)
|
||||
}), nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyClusterAdmissionRulesEnforcementMode(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyDefaultAdmissionRule(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
l := v.([]interface{})
|
||||
if len(l) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
raw := l[0]
|
||||
original := raw.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
|
||||
transformedEvaluationMode, err := expandBinaryAuthorizationPolicyDefaultAdmissionRuleEvaluationMode(original["evaluation_mode"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["evaluationMode"] = transformedEvaluationMode
|
||||
transformedRequireAttestationsBy, err := expandBinaryAuthorizationPolicyDefaultAdmissionRuleRequireAttestationsBy(original["require_attestations_by"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["requireAttestationsBy"] = transformedRequireAttestationsBy
|
||||
transformedEnforcementMode, err := expandBinaryAuthorizationPolicyDefaultAdmissionRuleEnforcementMode(original["enforcement_mode"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["enforcementMode"] = transformedEnforcementMode
|
||||
return transformed, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyDefaultAdmissionRuleEvaluationMode(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyDefaultAdmissionRuleRequireAttestationsBy(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
r := regexp.MustCompile("projects/(.+)/attestors/(.+)")
|
||||
|
||||
// It's possible that all entries in the list will specify a project, in
|
||||
// which case the user wouldn't necessarily have to specify a provider
|
||||
// project.
|
||||
var project string
|
||||
var err error
|
||||
for _, s := range v.(*schema.Set).List() {
|
||||
if !r.MatchString(s.(string)) {
|
||||
project, err = getProject(d, config)
|
||||
if err != nil {
|
||||
return []interface{}{}, err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return convertAndMapStringArr(v.(*schema.Set).List(), func(s string) string {
|
||||
if r.MatchString(s) {
|
||||
return s
|
||||
}
|
||||
|
||||
return fmt.Sprintf("projects/%s/attestors/%s", project, s)
|
||||
}), nil
|
||||
}
|
||||
|
||||
func expandBinaryAuthorizationPolicyDefaultAdmissionRuleEnforcementMode(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
226
google/resource_binaryauthorization_policy_test.go
Normal file
226
google/resource_binaryauthorization_policy_test.go
Normal file
@ -0,0 +1,226 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccBinaryAuthorizationPolicy_basic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
pid := "tf-test-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccBinaryAuthorizationPolicyBasic(pid, pname, org),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_policy.policy",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
// Destroy the policy without destroying the project so we can check
|
||||
// that it was restored to the default.
|
||||
{
|
||||
Config: testAccBinaryAuthorizationPolicyDefault(pid, pname, org),
|
||||
Check: testAccCheckBinaryAuthorizationPolicyDefault(pid),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccBinaryAuthorizationPolicy_full(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
pid := "tf-test-" + acctest.RandString(10)
|
||||
note := acctest.RandString(10)
|
||||
attestor := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccBinaryAuthorizationPolicyFull(pid, pname, org, note, attestor),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_policy.policy",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
// Destroy the policy without destroying the project so we can check
|
||||
// that it was restored to the default.
|
||||
{
|
||||
Config: testAccBinaryAuthorizationPolicyDefault(pid, pname, org),
|
||||
Check: testAccCheckBinaryAuthorizationPolicyDefault(pid),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccBinaryAuthorizationPolicy_update(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
pid := "tf-test-" + acctest.RandString(10)
|
||||
note := acctest.RandString(10)
|
||||
attestor := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccBinaryAuthorizationPolicyBasic(pid, pname, org),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_policy.policy",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
{
|
||||
Config: testAccBinaryAuthorizationPolicyFull(pid, pname, org, note, attestor),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_policy.policy",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
{
|
||||
Config: testAccBinaryAuthorizationPolicyBasic(pid, pname, org),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_binary_authorization_policy.policy",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
// Destroy the policy without destroying the project so we can check
|
||||
// that it was restored to the default.
|
||||
{
|
||||
Config: testAccBinaryAuthorizationPolicyDefault(pid, pname, org),
|
||||
Check: testAccCheckBinaryAuthorizationPolicyDefault(pid),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckBinaryAuthorizationPolicyDefault(pid string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
url := fmt.Sprintf("https://binaryauthorization.googleapis.com/v1beta1/projects/%s/policy", pid)
|
||||
pol, err := sendRequest(config, "GET", url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(pol, "updateTime")
|
||||
|
||||
defaultPol := defaultBinaryAuthorizationPolicy(pid)
|
||||
if !reflect.DeepEqual(pol, defaultPol) {
|
||||
return fmt.Errorf("Policy for project %s was %v, expected default policy %v", pid, pol, defaultPol)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccBinaryAuthorizationPolicyDefault(pid, pname, org string) string {
|
||||
return fmt.Sprintf(`
|
||||
// Use a separate project since each project can only have one policy
|
||||
resource "google_project" "project" {
|
||||
project_id = "%s"
|
||||
name = "%s"
|
||||
org_id = "%s"
|
||||
}
|
||||
`, pid, pname, org)
|
||||
}
|
||||
|
||||
func testAccBinaryAuthorizationPolicyBasic(pid, pname, org string) string {
|
||||
return fmt.Sprintf(`
|
||||
// Use a separate project since each project can only have one policy
|
||||
resource "google_project" "project" {
|
||||
project_id = "%s"
|
||||
name = "%s"
|
||||
org_id = "%s"
|
||||
}
|
||||
|
||||
resource "google_binary_authorization_policy" "policy" {
|
||||
project = "${google_project.project.project_id}"
|
||||
|
||||
admission_whitelist_patterns {
|
||||
name_pattern= "gcr.io/google_containers/*"
|
||||
}
|
||||
|
||||
default_admission_rule {
|
||||
evaluation_mode = "ALWAYS_DENY"
|
||||
enforcement_mode = "ENFORCED_BLOCK_AND_AUDIT_LOG"
|
||||
}
|
||||
}
|
||||
`, pid, pname, org)
|
||||
}
|
||||
|
||||
func testAccBinaryAuthorizationPolicyFull(pid, pname, org, note, attestor string) string {
|
||||
return fmt.Sprintf(`
|
||||
// Use a separate project since each project can only have one policy
|
||||
resource "google_project" "project" {
|
||||
project_id = "%s"
|
||||
name = "%s"
|
||||
org_id = "%s"
|
||||
}
|
||||
|
||||
resource "google_project_service" "binauthz" {
|
||||
project = "${google_project.project.project_id}"
|
||||
service = "binaryauthorization.googleapis.com"
|
||||
}
|
||||
|
||||
resource "google_container_analysis_note" "note" {
|
||||
project = "${google_project.project.project_id}"
|
||||
|
||||
name = "tf-test-%s"
|
||||
attestation_authority {
|
||||
hint {
|
||||
human_readable_name = "My attestor"
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = ["google_project_service.binauthz"]
|
||||
}
|
||||
|
||||
resource "google_binary_authorization_attestor" "attestor" {
|
||||
project = "${google_project.project.project_id}"
|
||||
|
||||
name = "tf-test-%s"
|
||||
description = "my description"
|
||||
attestation_authority_note {
|
||||
note_reference = "${google_container_analysis_note.note.name}"
|
||||
}
|
||||
|
||||
depends_on = ["google_project_service.binauthz"]
|
||||
}
|
||||
|
||||
resource "google_binary_authorization_policy" "policy" {
|
||||
project = "${google_project.project.project_id}"
|
||||
|
||||
admission_whitelist_patterns {
|
||||
name_pattern= "gcr.io/google_containers/*"
|
||||
}
|
||||
|
||||
default_admission_rule {
|
||||
evaluation_mode = "ALWAYS_ALLOW"
|
||||
enforcement_mode = "ENFORCED_BLOCK_AND_AUDIT_LOG"
|
||||
}
|
||||
|
||||
cluster_admission_rules {
|
||||
cluster = "us-central1-a.prod-cluster"
|
||||
evaluation_mode = "REQUIRE_ATTESTATION"
|
||||
enforcement_mode = "ENFORCED_BLOCK_AND_AUDIT_LOG"
|
||||
require_attestations_by = ["${google_binary_authorization_attestor.attestor.name}"]
|
||||
}
|
||||
}
|
||||
`, pid, pname, org, note, attestor)
|
||||
}
|
291
google/resource_containeranalysis_note.go
Normal file
291
google/resource_containeranalysis_note.go
Normal file
@ -0,0 +1,291 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// *** 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"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceContainerAnalysisNote() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceContainerAnalysisNoteCreate,
|
||||
Read: resourceContainerAnalysisNoteRead,
|
||||
Update: resourceContainerAnalysisNoteUpdate,
|
||||
Delete: resourceContainerAnalysisNoteDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: resourceContainerAnalysisNoteImport,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"attestation_authority": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"hint": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"human_readable_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"project": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceContainerAnalysisNoteCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
obj := make(map[string]interface{})
|
||||
nameProp, err := expandContainerAnalysisNoteName(d.Get("name"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
|
||||
obj["name"] = nameProp
|
||||
}
|
||||
attestationAuthorityProp, err := expandContainerAnalysisNoteAttestationAuthority(d.Get("attestation_authority"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("attestation_authority"); !isEmptyValue(reflect.ValueOf(attestationAuthorityProp)) && (ok || !reflect.DeepEqual(v, attestationAuthorityProp)) {
|
||||
obj["attestationAuthority"] = attestationAuthorityProp
|
||||
}
|
||||
|
||||
url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1alpha1/projects/{{project}}/notes?noteId={{name}}")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Creating new Note: %#v", obj)
|
||||
res, err := sendRequest(config, "POST", url, obj)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Note: %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 Note %q: %#v", d.Id(), res)
|
||||
|
||||
return resourceContainerAnalysisNoteRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceContainerAnalysisNoteRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1alpha1/projects/{{project}}/notes/{{name}}")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := sendRequest(config, "GET", url, nil)
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, fmt.Sprintf("ContainerAnalysisNote %q", d.Id()))
|
||||
}
|
||||
|
||||
if err := d.Set("name", flattenContainerAnalysisNoteName(res["name"])); err != nil {
|
||||
return fmt.Errorf("Error reading Note: %s", err)
|
||||
}
|
||||
if err := d.Set("attestation_authority", flattenContainerAnalysisNoteAttestationAuthority(res["attestationAuthority"])); err != nil {
|
||||
return fmt.Errorf("Error reading Note: %s", err)
|
||||
}
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set("project", project); err != nil {
|
||||
return fmt.Errorf("Error reading Note: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceContainerAnalysisNoteUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
obj := make(map[string]interface{})
|
||||
nameProp, err := expandContainerAnalysisNoteName(d.Get("name"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nameProp)) {
|
||||
obj["name"] = nameProp
|
||||
}
|
||||
attestationAuthorityProp, err := expandContainerAnalysisNoteAttestationAuthority(d.Get("attestation_authority"), d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if v, ok := d.GetOkExists("attestation_authority"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, attestationAuthorityProp)) {
|
||||
obj["attestationAuthority"] = attestationAuthorityProp
|
||||
}
|
||||
|
||||
url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1alpha1/projects/{{project}}/notes/{{name}}")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Updating Note %q: %#v", d.Id(), obj)
|
||||
updateMask := []string{}
|
||||
if d.HasChange("attestation_authority.0.hint.0.human_readable_name") {
|
||||
updateMask = append(updateMask, "attestationAuthority.hint.humanReadableName")
|
||||
}
|
||||
// updateMask is a URL parameter but not present in the schema, so replaceVars
|
||||
// won't set it
|
||||
url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = sendRequest(config, "PATCH", url, obj)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error updating Note %q: %s", d.Id(), err)
|
||||
}
|
||||
|
||||
return resourceContainerAnalysisNoteRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceContainerAnalysisNoteDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1alpha1/projects/{{project}}/notes/{{name}}")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var obj map[string]interface{}
|
||||
log.Printf("[DEBUG] Deleting Note %q", d.Id())
|
||||
res, err := sendRequest(config, "DELETE", url, obj)
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, "Note")
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Finished deleting Note %q: %#v", d.Id(), res)
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceContainerAnalysisNoteImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||
config := meta.(*Config)
|
||||
parseImportId([]string{"projects/(?P<project>[^/]+)/notes/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<name>[^/]+)", "(?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)
|
||||
|
||||
return []*schema.ResourceData{d}, nil
|
||||
}
|
||||
|
||||
func flattenContainerAnalysisNoteName(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return v
|
||||
}
|
||||
return NameFromSelfLinkStateFunc(v)
|
||||
}
|
||||
|
||||
func flattenContainerAnalysisNoteAttestationAuthority(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
original := v.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
transformed["hint"] =
|
||||
flattenContainerAnalysisNoteAttestationAuthorityHint(original["hint"])
|
||||
return []interface{}{transformed}
|
||||
}
|
||||
func flattenContainerAnalysisNoteAttestationAuthorityHint(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
original := v.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
transformed["human_readable_name"] =
|
||||
flattenContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(original["humanReadableName"])
|
||||
return []interface{}{transformed}
|
||||
}
|
||||
func flattenContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func expandContainerAnalysisNoteName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func expandContainerAnalysisNoteAttestationAuthority(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
l := v.([]interface{})
|
||||
if len(l) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
raw := l[0]
|
||||
original := raw.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
|
||||
transformedHint, err := expandContainerAnalysisNoteAttestationAuthorityHint(original["hint"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["hint"] = transformedHint
|
||||
return transformed, nil
|
||||
}
|
||||
|
||||
func expandContainerAnalysisNoteAttestationAuthorityHint(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
l := v.([]interface{})
|
||||
if len(l) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
raw := l[0]
|
||||
original := raw.(map[string]interface{})
|
||||
transformed := make(map[string]interface{})
|
||||
|
||||
transformedHumanReadableName, err := expandContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(original["human_readable_name"], d, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformed["humanReadableName"] = transformedHumanReadableName
|
||||
return transformed, nil
|
||||
}
|
||||
|
||||
func expandContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
102
google/resource_containeranalysis_note_test.go
Normal file
102
google/resource_containeranalysis_note_test.go
Normal file
@ -0,0 +1,102 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccContainerAnalysisNote_basic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
name := acctest.RandString(10)
|
||||
readableName := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckContainerAnalysisNoteDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccContainerAnalysisNoteBasic(name, readableName),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_container_analysis_note.note",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccContainerAnalysisNote_update(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
name := acctest.RandString(10)
|
||||
readableName := acctest.RandString(10)
|
||||
readableName2 := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckContainerAnalysisNoteDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccContainerAnalysisNoteBasic(name, readableName),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_container_analysis_note.note",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
{
|
||||
Config: testAccContainerAnalysisNoteBasic(name, readableName2),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_container_analysis_note.note",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckContainerAnalysisNoteDestroy(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "google_container_analysis_note" {
|
||||
continue
|
||||
}
|
||||
|
||||
project, err := getTestProject(rs.Primary, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := rs.Primary.Attributes["name"]
|
||||
|
||||
url := fmt.Sprintf("https://containeranalysis.googleapis.com/v1alpha1/projects/%s/notes/%s", project, name)
|
||||
_, err = sendRequest(config, "GET", url, nil)
|
||||
|
||||
if err == nil {
|
||||
return fmt.Errorf("Error, container analysis note %s still exists", name)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccContainerAnalysisNoteBasic(name, readableName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_container_analysis_note" "note" {
|
||||
name = "tf-test-%s"
|
||||
attestation_authority {
|
||||
hint {
|
||||
human_readable_name = "My Attestor %s"
|
||||
}
|
||||
}
|
||||
}
|
||||
`, name, readableName)
|
||||
}
|
158
website/docs/r/binaryauthorization_attestor.html.markdown
Normal file
158
website/docs/r/binaryauthorization_attestor.html.markdown
Normal file
@ -0,0 +1,158 @@
|
||||
---
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# *** 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_binary_authorization_attestor"
|
||||
sidebar_current: "docs-google-binary-authorization-attestor"
|
||||
description: |-
|
||||
An attestor that attests to container image artifacts.
|
||||
---
|
||||
|
||||
# google\_binary\_authorization\_attestor
|
||||
|
||||
An attestor that attests to container image artifacts.
|
||||
|
||||
To get more information about Attestor, see:
|
||||
|
||||
* [API documentation](https://cloud.google.com/binary-authorization/docs/reference/rest/)
|
||||
* How-to Guides
|
||||
* [Official Documentation](https://cloud.google.com/binary-authorization/)
|
||||
|
||||
## Example Usage
|
||||
|
||||
```hcl
|
||||
resource "google_container_analysis_note" "note" {
|
||||
name = "test-attestor-note"
|
||||
attestation_authority {
|
||||
hint {
|
||||
human_readable_name = "Attestor Note"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_binary_authorization_attestor" "attestor" {
|
||||
name = "test-attestor"
|
||||
attestation_authority_note {
|
||||
note_reference = "${google_container_analysis_note.note.name}"
|
||||
public_keys {
|
||||
ascii_armored_pgp_public_key = <<EOF
|
||||
mQENBFtP0doBCADF+joTiXWKVuP8kJt3fgpBSjT9h8ezMfKA4aXZctYLx5wslWQl
|
||||
bB7Iu2ezkECNzoEeU7WxUe8a61pMCh9cisS9H5mB2K2uM4Jnf8tgFeXn3akJDVo0
|
||||
oR1IC+Dp9mXbRSK3MAvKkOwWlG99sx3uEdvmeBRHBOO+grchLx24EThXFOyP9Fk6
|
||||
V39j6xMjw4aggLD15B4V0v9JqBDdJiIYFzszZDL6pJwZrzcP0z8JO4rTZd+f64bD
|
||||
Mpj52j/pQfA8lZHOaAgb1OrthLdMrBAjoDjArV4Ek7vSbrcgYWcI6BhsQrFoxKdX
|
||||
83TZKai55ZCfCLIskwUIzA1NLVwyzCS+fSN/ABEBAAG0KCJUZXN0IEF0dGVzdG9y
|
||||
IiA8ZGFuYWhvZmZtYW5AZ29vZ2xlLmNvbT6JAU4EEwEIADgWIQRfWkqHt6hpTA1L
|
||||
uY060eeM4dc66AUCW0/R2gIbLwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRA6
|
||||
0eeM4dc66HdpCAC4ot3b0OyxPb0Ip+WT2U0PbpTBPJklesuwpIrM4Lh0N+1nVRLC
|
||||
51WSmVbM8BiAFhLbN9LpdHhds1kUrHF7+wWAjdR8sqAj9otc6HGRM/3qfa2qgh+U
|
||||
WTEk/3us/rYSi7T7TkMuutRMIa1IkR13uKiW56csEMnbOQpn9rDqwIr5R8nlZP5h
|
||||
MAU9vdm1DIv567meMqTaVZgR3w7bck2P49AO8lO5ERFpVkErtu/98y+rUy9d789l
|
||||
+OPuS1NGnxI1YKsNaWJF4uJVuvQuZ1twrhCbGNtVorO2U12+cEq+YtUxj7kmdOC1
|
||||
qoIRW6y0+UlAc+MbqfL0ziHDOAmcqz1GnROg
|
||||
=6Bvm
|
||||
EOF
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
|
||||
* `name` -
|
||||
(Required)
|
||||
The resource name.
|
||||
|
||||
* `attestation_authority_note` -
|
||||
(Required)
|
||||
A Container Analysis ATTESTATION_AUTHORITY Note, created by the user. Structure is documented below.
|
||||
|
||||
|
||||
The `attestation_authority_note` block supports:
|
||||
|
||||
* `note_reference` -
|
||||
(Required)
|
||||
The resource name of a ATTESTATION_AUTHORITY Note, created by the
|
||||
user. If the Note is in a different project from the Attestor, it
|
||||
should be specified in the format `projects/*/notes/*` (or the legacy
|
||||
`providers/*/notes/*`). This field may not be updated.
|
||||
An attestation by this attestor is stored as a Container Analysis
|
||||
ATTESTATION_AUTHORITY Occurrence that names a container image
|
||||
and that links to this Note.
|
||||
|
||||
* `public_keys` -
|
||||
(Optional)
|
||||
Public keys that verify attestations signed by this attestor. This
|
||||
field may be updated.
|
||||
If this field is non-empty, one of the specified public keys must
|
||||
verify that an attestation was signed by this attestor for the
|
||||
image specified in the admission request.
|
||||
If this field is empty, this attestor always returns that no valid
|
||||
attestations exist. Structure is documented below.
|
||||
|
||||
* `delegation_service_account_email` -
|
||||
This field will contain the service account email address that
|
||||
this Attestor will use as the principal when querying Container
|
||||
Analysis. Attestor administrators must grant this service account
|
||||
the IAM role needed to read attestations from the noteReference in
|
||||
Container Analysis (containeranalysis.notes.occurrences.viewer).
|
||||
This email address is fixed for the lifetime of the Attestor, but
|
||||
callers should not make any other assumptions about the service
|
||||
account email; future versions may use an email based on a
|
||||
different naming pattern.
|
||||
|
||||
|
||||
The `public_keys` block supports:
|
||||
|
||||
* `comment` -
|
||||
(Optional)
|
||||
A descriptive comment. This field may be updated.
|
||||
|
||||
* `id` -
|
||||
This field will be overwritten with key ID information, for
|
||||
example, an identifier extracted from a PGP public key. This
|
||||
field may not be updated.
|
||||
|
||||
* `ascii_armored_pgp_public_key` -
|
||||
(Required)
|
||||
ASCII-armored representation of a PGP public key, as the
|
||||
entire output by the command
|
||||
`gpg --export --armor foo@example.com` (either LF or CRLF
|
||||
line endings).
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
* `description` -
|
||||
(Optional)
|
||||
A descriptive comment. This field may be updated. The field may be
|
||||
displayed in chooser dialogs.
|
||||
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||
If it is not provided, the provider project is used.
|
||||
|
||||
|
||||
|
||||
|
||||
## Import
|
||||
|
||||
Attestor can be imported using any of these accepted formats:
|
||||
|
||||
```
|
||||
$ terraform import google_binary_authorization_attestor.default projects/{{project}}/attestors/{{name}}
|
||||
$ terraform import google_binary_authorization_attestor.default {{project}}/{{name}}
|
||||
$ terraform import google_binary_authorization_attestor.default {{name}}
|
||||
```
|
165
website/docs/r/binaryauthorization_policy.html.markdown
Normal file
165
website/docs/r/binaryauthorization_policy.html.markdown
Normal file
@ -0,0 +1,165 @@
|
||||
---
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# *** 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_binary_authorization_policy"
|
||||
sidebar_current: "docs-google-binary-authorization-policy"
|
||||
description: |-
|
||||
A policy for container image binary authorization.
|
||||
---
|
||||
|
||||
# google\_binary\_authorization\_policy
|
||||
|
||||
A policy for container image binary authorization.
|
||||
|
||||
To get more information about Policy, see:
|
||||
|
||||
* [API documentation](https://cloud.google.com/binary-authorization/docs/reference/rest/)
|
||||
* How-to Guides
|
||||
* [Official Documentation](https://cloud.google.com/binary-authorization/)
|
||||
|
||||
## Example Usage
|
||||
|
||||
```hcl
|
||||
resource "google_container_analysis_note" "note" {
|
||||
name = "test-attestor-note"
|
||||
attestation_authority {
|
||||
hint {
|
||||
human_readable_name = "My attestor"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_binary_authorization_attestor" "attestor" {
|
||||
name = "test-attestor"
|
||||
attestation_authority_note {
|
||||
note_reference = "${google_container_analysis_note.note.name}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_binary_authorization_policy" "policy" {
|
||||
admission_whitelist_patterns {
|
||||
name_pattern= "gcr.io/google_containers/*"
|
||||
}
|
||||
|
||||
default_admission_rule {
|
||||
evaluation_mode = "ALWAYS_ALLOW"
|
||||
enforcement_mode = "ENFORCED_BLOCK_AND_AUDIT_LOG"
|
||||
}
|
||||
|
||||
cluster_admission_rules {
|
||||
cluster = "us-central1-a.prod-cluster"
|
||||
evaluation_mode = "REQUIRE_ATTESTATION"
|
||||
enforcement_mode = "ENFORCED_BLOCK_AND_AUDIT_LOG"
|
||||
require_attestations_by = ["${google_binary_authorization_attestor.attestor.name}"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
|
||||
* `default_admission_rule` -
|
||||
(Required)
|
||||
Default admission rule for a cluster without a per-cluster admission
|
||||
rule. Structure is documented below.
|
||||
|
||||
|
||||
The `default_admission_rule` block supports:
|
||||
|
||||
* `evaluation_mode` -
|
||||
(Required)
|
||||
How this admission rule will be evaluated.
|
||||
|
||||
* `require_attestations_by` -
|
||||
(Optional)
|
||||
The resource names of the attestors that must attest to a
|
||||
container image. If the attestor is in a different project from the
|
||||
policy, it should be specified in the format `projects/*/attestors/*`.
|
||||
Each attestor must exist before a policy can reference it. To add an
|
||||
attestor to a policy the principal issuing the policy change
|
||||
request must be able to read the attestor resource.
|
||||
Note: this field must be non-empty when the evaluation_mode field
|
||||
specifies REQUIRE_ATTESTATION, otherwise it must be empty.
|
||||
|
||||
* `enforcement_mode` -
|
||||
(Required)
|
||||
The action when a pod creation is denied by the admission rule.
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
* `description` -
|
||||
(Optional)
|
||||
A descriptive comment.
|
||||
|
||||
* `admission_whitelist_patterns` -
|
||||
(Optional)
|
||||
Admission policy whitelisting. A matching admission request will
|
||||
always be permitted. This feature is typically used to exclude Google
|
||||
or third-party infrastructure images from Binary Authorization
|
||||
policies. Structure is documented below.
|
||||
|
||||
* `cluster_admission_rules` -
|
||||
(Optional)
|
||||
Admission policy whitelisting. A matching admission request will
|
||||
always be permitted. This feature is typically used to exclude Google
|
||||
or third-party infrastructure images from Binary Authorization
|
||||
policies.
|
||||
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||
If it is not provided, the provider project is used.
|
||||
|
||||
|
||||
The `admission_whitelist_patterns` block supports:
|
||||
|
||||
* `name_pattern` -
|
||||
(Optional)
|
||||
An image name pattern to whitelist, in the form
|
||||
`registry/path/to/image`. This supports a trailing * as a
|
||||
wildcard, but this is allowed only in text after the registry/
|
||||
part.
|
||||
|
||||
The `cluster_admission_rules` block supports:
|
||||
|
||||
* `evaluation_mode` -
|
||||
(Optional)
|
||||
How this admission rule will be evaluated.
|
||||
|
||||
* `require_attestations_by` -
|
||||
(Optional)
|
||||
The resource names of the attestors that must attest to a
|
||||
container image. If the attestor is in a different project from the
|
||||
policy, it should be specified in the format `projects/*/attestors/*`.
|
||||
Each attestor must exist before a policy can reference it. To add an
|
||||
attestor to a policy the principal issuing the policy change
|
||||
request must be able to read the attestor resource.
|
||||
Note: this field must be non-empty when the evaluation_mode field
|
||||
specifies REQUIRE_ATTESTATION, otherwise it must be empty.
|
||||
|
||||
* `enforcement_mode` -
|
||||
(Optional)
|
||||
The action when a pod creation is denied by the admission rule.
|
||||
|
||||
|
||||
|
||||
## Import
|
||||
|
||||
Policy can be imported using any of these accepted formats:
|
||||
|
||||
```
|
||||
$ terraform import google_binary_authorization_policy.default projects/{{project}}
|
||||
$ terraform import google_binary_authorization_policy.default {{project}}
|
||||
```
|
@ -84,6 +84,7 @@ The following arguments are supported:
|
||||
following characters must be a dash, lowercase letter, or digit,
|
||||
except the last character, which cannot be a dash.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -114,6 +114,8 @@ The following arguments are supported:
|
||||
* `target` -
|
||||
(Required)
|
||||
URL of the managed instance group that this autoscaler will scale.
|
||||
|
||||
|
||||
The `autoscaling_policy` block supports:
|
||||
|
||||
* `min_replicas` -
|
||||
@ -157,7 +159,9 @@ The `autoscaling_policy` block supports:
|
||||
* `load_balancing_utilization` -
|
||||
(Optional)
|
||||
Configuration parameters of autoscaling based on a load balancer. Structure is documented below.
|
||||
The `cpu_utilization` block supports:
|
||||
|
||||
|
||||
The `cpu_utilization` block supports:
|
||||
|
||||
* `target` -
|
||||
(Required)
|
||||
@ -172,8 +176,8 @@ The `autoscaling_policy` block supports:
|
||||
scales up until it reaches the maximum number of instances you
|
||||
specified or until the average utilization reaches the target
|
||||
utilization.
|
||||
|
||||
The `metric` block supports:
|
||||
|
||||
The `metric` block supports:
|
||||
|
||||
* `name` -
|
||||
(Required)
|
||||
@ -197,15 +201,14 @@ The `autoscaling_policy` block supports:
|
||||
Defines how target utilization value is expressed for a
|
||||
Stackdriver Monitoring metric. Either GAUGE, DELTA_PER_SECOND,
|
||||
or DELTA_PER_MINUTE.
|
||||
|
||||
The `load_balancing_utilization` block supports:
|
||||
|
||||
The `load_balancing_utilization` block supports:
|
||||
|
||||
* `target` -
|
||||
(Required)
|
||||
Fraction of backend capacity utilization (set in HTTP(s) load
|
||||
balancing configuration) that autoscaler should maintain. Must
|
||||
be a positive float value. If not defined, the default is 0.8.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
@ -71,6 +71,7 @@ The following arguments are supported:
|
||||
characters must be a dash, lowercase letter, or digit, except the
|
||||
last character, which cannot be a dash.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -77,6 +77,7 @@ The following arguments are supported:
|
||||
characters must be a dash, lowercase letter, or digit, except the last
|
||||
character, which cannot be a dash.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
@ -155,6 +156,7 @@ The following arguments are supported:
|
||||
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||
If it is not provided, the provider project is used.
|
||||
|
||||
|
||||
The `source_image_encryption_key` block supports:
|
||||
|
||||
* `raw_key` -
|
||||
@ -165,7 +167,7 @@ The `source_image_encryption_key` block supports:
|
||||
* `sha256` -
|
||||
The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied
|
||||
encryption key that protects this resource.
|
||||
|
||||
|
||||
The `disk_encryption_key` block supports:
|
||||
|
||||
* `raw_key` -
|
||||
@ -176,7 +178,7 @@ The `disk_encryption_key` block supports:
|
||||
* `sha256` -
|
||||
The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied
|
||||
encryption key that protects this resource.
|
||||
|
||||
|
||||
The `source_snapshot_encryption_key` block supports:
|
||||
|
||||
* `raw_key` -
|
||||
@ -187,7 +189,6 @@ The `source_snapshot_encryption_key` block supports:
|
||||
* `sha256` -
|
||||
The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied
|
||||
encryption key that protects this resource.
|
||||
|
||||
|
||||
* (Deprecated) `disk_encryption_key_raw`: This is an alias for
|
||||
`disk_encryption_key.raw_key`. It is deprecated to enhance
|
||||
|
@ -56,6 +56,7 @@ The following arguments are supported:
|
||||
characters must be a dash, lowercase letter, or digit, except the last
|
||||
character, which cannot be a dash.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -53,6 +53,7 @@ The following arguments are supported:
|
||||
characters must be a dash, lowercase letter, or digit, except the last
|
||||
character, which cannot be a dash.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -64,6 +64,7 @@ The following arguments are supported:
|
||||
characters must be a dash, lowercase letter, or digit, except the
|
||||
last character, which cannot be a dash.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -64,6 +64,7 @@ The following arguments are supported:
|
||||
characters must be a dash, lowercase letter, or digit, except the
|
||||
last character, which cannot be a dash.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -114,6 +114,8 @@ The following arguments are supported:
|
||||
* `target` -
|
||||
(Required)
|
||||
URL of the managed instance group that this autoscaler will scale.
|
||||
|
||||
|
||||
The `autoscaling_policy` block supports:
|
||||
|
||||
* `min_replicas` -
|
||||
@ -157,7 +159,9 @@ The `autoscaling_policy` block supports:
|
||||
* `load_balancing_utilization` -
|
||||
(Optional)
|
||||
Configuration parameters of autoscaling based on a load balancer. Structure is documented below.
|
||||
The `cpu_utilization` block supports:
|
||||
|
||||
|
||||
The `cpu_utilization` block supports:
|
||||
|
||||
* `target` -
|
||||
(Required)
|
||||
@ -172,8 +176,8 @@ The `autoscaling_policy` block supports:
|
||||
scales up until it reaches the maximum number of instances you
|
||||
specified or until the average utilization reaches the target
|
||||
utilization.
|
||||
|
||||
The `metric` block supports:
|
||||
|
||||
The `metric` block supports:
|
||||
|
||||
* `name` -
|
||||
(Required)
|
||||
@ -197,15 +201,14 @@ The `autoscaling_policy` block supports:
|
||||
Defines how target utilization value is expressed for a
|
||||
Stackdriver Monitoring metric. Either GAUGE, DELTA_PER_SECOND,
|
||||
or DELTA_PER_MINUTE.
|
||||
|
||||
The `load_balancing_utilization` block supports:
|
||||
|
||||
The `load_balancing_utilization` block supports:
|
||||
|
||||
* `target` -
|
||||
(Required)
|
||||
Fraction of backend capacity utilization (set in HTTP(s) load
|
||||
balancing configuration) that autoscaler should maintain. Must
|
||||
be a positive float value. If not defined, the default is 0.8.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
@ -94,6 +94,7 @@ The following arguments are supported:
|
||||
(Required)
|
||||
URLs of the zones where the disk should be replicated to.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
@ -155,6 +156,7 @@ The following arguments are supported:
|
||||
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||
If it is not provided, the provider project is used.
|
||||
|
||||
|
||||
The `disk_encryption_key` block supports:
|
||||
|
||||
* `raw_key` -
|
||||
@ -165,7 +167,7 @@ The `disk_encryption_key` block supports:
|
||||
* `sha256` -
|
||||
The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied
|
||||
encryption key that protects this resource.
|
||||
|
||||
|
||||
The `source_snapshot_encryption_key` block supports:
|
||||
|
||||
* `raw_key` -
|
||||
@ -176,7 +178,6 @@ The `source_snapshot_encryption_key` block supports:
|
||||
* `sha256` -
|
||||
The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied
|
||||
encryption key that protects this resource.
|
||||
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
|
@ -96,6 +96,7 @@ The following arguments are supported:
|
||||
(Required)
|
||||
The network that this route applies to.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -72,6 +72,7 @@ The following arguments are supported:
|
||||
(Required)
|
||||
A reference to the network to which this router belongs.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
@ -89,6 +90,7 @@ The following arguments are supported:
|
||||
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||
If it is not provided, the provider project is used.
|
||||
|
||||
|
||||
The `bgp` block supports:
|
||||
|
||||
* `asn` -
|
||||
@ -119,7 +121,9 @@ The `bgp` block supports:
|
||||
is CUSTOM and is advertised to all peers of the router. These IP
|
||||
ranges will be advertised in addition to any specified groups.
|
||||
Leave this field blank to advertise no custom IP ranges. Structure is documented below.
|
||||
The `advertised_ip_ranges` block supports:
|
||||
|
||||
|
||||
The `advertised_ip_ranges` block supports:
|
||||
|
||||
* `range` -
|
||||
(Optional)
|
||||
@ -129,7 +133,6 @@ The `bgp` block supports:
|
||||
* `description` -
|
||||
(Optional)
|
||||
User-specified description for the IP range.
|
||||
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
|
@ -67,6 +67,7 @@ The following arguments are supported:
|
||||
characters must be a dash, lowercase letter, or digit, except the last
|
||||
character, which cannot be a dash.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -99,6 +99,7 @@ The following arguments are supported:
|
||||
The network this subnet belongs to.
|
||||
Only networks that are in the distributed mode can have subnetworks.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
@ -130,6 +131,7 @@ The following arguments are supported:
|
||||
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||
If it is not provided, the provider project is used.
|
||||
|
||||
|
||||
The `secondary_ip_range` block supports:
|
||||
|
||||
* `range_name` -
|
||||
@ -145,7 +147,6 @@ The `secondary_ip_range` block supports:
|
||||
range. Provide this property when you create the subnetwork.
|
||||
Ranges must be unique and non-overlapping with all primary and
|
||||
secondary IP ranges within a network. Only IPv4 is supported.
|
||||
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
|
@ -99,6 +99,7 @@ The following arguments are supported:
|
||||
A reference to the UrlMap resource that defines the mapping from URL
|
||||
to the BackendService.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -113,6 +113,7 @@ The following arguments are supported:
|
||||
A reference to the UrlMap resource that defines the mapping from URL
|
||||
to the BackendService.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -89,6 +89,7 @@ The following arguments are supported:
|
||||
connections between users and the load balancer. Currently, exactly
|
||||
one SSL certificate must be specified.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -80,6 +80,7 @@ The following arguments are supported:
|
||||
(Required)
|
||||
A reference to the BackendService resource.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -117,6 +117,7 @@ The following arguments are supported:
|
||||
(Required)
|
||||
The network this VPN gateway is accepting traffic for.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -138,6 +138,7 @@ The following arguments are supported:
|
||||
Shared secret used to set the secure session between the Cloud VPN
|
||||
gateway and the peer VPN gateway.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
104
website/docs/r/containeranalysis_note.html.markdown
Normal file
104
website/docs/r/containeranalysis_note.html.markdown
Normal file
@ -0,0 +1,104 @@
|
||||
---
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# *** 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_container_analysis_note"
|
||||
sidebar_current: "docs-google-container-analysis-note"
|
||||
description: |-
|
||||
Provides a detailed description of a Note.
|
||||
---
|
||||
|
||||
# google\_container\_analysis\_note
|
||||
|
||||
Provides a detailed description of a Note.
|
||||
|
||||
To get more information about Note, see:
|
||||
|
||||
* [API documentation](https://cloud.google.com/container-analysis/api/reference/rest/)
|
||||
* How-to Guides
|
||||
* [Official Documentation](https://cloud.google.com/container-analysis/)
|
||||
|
||||
## Example Usage
|
||||
|
||||
```hcl
|
||||
resource "google_container_analysis_note" "note" {
|
||||
name = "test-attestor-note"
|
||||
attestation_authority {
|
||||
hint {
|
||||
human_readable_name = "Attestor Note"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
|
||||
* `name` -
|
||||
(Required)
|
||||
The name of the note.
|
||||
|
||||
* `attestation_authority` -
|
||||
(Required)
|
||||
Note kind that represents a logical attestation "role" or "authority".
|
||||
For example, an organization might have one AttestationAuthority for
|
||||
"QA" and one for "build". This Note is intended to act strictly as a
|
||||
grouping mechanism for the attached Occurrences (Attestations). This
|
||||
grouping mechanism also provides a security boundary, since IAM ACLs
|
||||
gate the ability for a principle to attach an Occurrence to a given
|
||||
Note. It also provides a single point of lookup to find all attached
|
||||
Attestation Occurrences, even if they don't all live in the same
|
||||
project. Structure is documented below.
|
||||
|
||||
|
||||
The `attestation_authority` block supports:
|
||||
|
||||
* `hint` -
|
||||
(Required)
|
||||
This submessage provides human-readable hints about the purpose of
|
||||
the AttestationAuthority. Because the name of a Note acts as its
|
||||
resource reference, it is important to disambiguate the canonical
|
||||
name of the Note (which might be a UUID for security purposes)
|
||||
from "readable" names more suitable for debug output. Note that
|
||||
these hints should NOT be used to look up AttestationAuthorities
|
||||
in security sensitive contexts, such as when looking up
|
||||
Attestations to verify. Structure is documented below.
|
||||
|
||||
|
||||
The `hint` block supports:
|
||||
|
||||
* `human_readable_name` -
|
||||
(Required)
|
||||
The human readable name of this Attestation Authority, for
|
||||
example "qa".
|
||||
|
||||
- - -
|
||||
|
||||
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||
If it is not provided, the provider project is used.
|
||||
|
||||
|
||||
|
||||
|
||||
## Import
|
||||
|
||||
Note can be imported using any of these accepted formats:
|
||||
|
||||
```
|
||||
$ terraform import google_container_analysis_note.default projects/{{project}}/notes/{{name}}
|
||||
$ terraform import google_container_analysis_note.default {{project}}/{{name}}
|
||||
$ terraform import google_container_analysis_note.default {{name}}
|
||||
```
|
@ -80,6 +80,7 @@ The following arguments are supported:
|
||||
(Required)
|
||||
Redis memory size in GiB.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
|
@ -13,13 +13,13 @@
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
layout: "google"
|
||||
page_title: "Google: google_resourcemanager_lien"
|
||||
sidebar_current: "docs-google-resourcemanager-lien"
|
||||
page_title: "Google: google_resource_manager_lien"
|
||||
sidebar_current: "docs-google-resource-manager-lien"
|
||||
description: |-
|
||||
A Lien represents an encumbrance on the actions that can be performed on a resource.
|
||||
---
|
||||
|
||||
# google\_resourcemanager\_lien
|
||||
# google\_resource\_manager\_lien
|
||||
|
||||
A Lien represents an encumbrance on the actions that can be performed on a resource.
|
||||
|
||||
@ -75,6 +75,7 @@ The following arguments are supported:
|
||||
list is meaningless and will be rejected.
|
||||
e.g. ['resourcemanager.projects.delete']
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
@ -97,5 +98,5 @@ In addition to the arguments listed above, the following computed attributes are
|
||||
Lien can be imported using any of these accepted formats:
|
||||
|
||||
```
|
||||
$ terraform import google_resourcemanager_lien.default {{parent}}/{{name}}
|
||||
$ terraform import google_resource_manager_lien.default {{parent}}/{{name}}
|
||||
```
|
||||
|
@ -143,6 +143,17 @@
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-google-binary-authorization") %>>
|
||||
<a href="#">Google Binary Authorization Resources</a>
|
||||
<ul class="nav nav-visible">
|
||||
<li<%= sidebar_current("docs-google-binary-authorization-attestor") %>>
|
||||
<a href="/docs/providers/google/r/binaryauthorization_attestor.html">google_binary_authorization_attestor</a>
|
||||
<li<%= sidebar_current("docs-google-binary-authorization-policy") %>>
|
||||
<a href="/docs/providers/google/r/binaryauthorization_policy.html">google_binary_authorization_policy</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-google-cloudbuild") %>>
|
||||
<a href="#">Google Cloud Build Resources</a>
|
||||
<ul class="nav nav-visible">
|
||||
@ -221,8 +232,8 @@
|
||||
<li<%= sidebar_current("docs-google-project-usage-export-bucket") %>>
|
||||
<a href="/docs/providers/google/r/usage_export_bucket.html">google_project_usage_export_bucket</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-google-resourcemanager-lien") %>>
|
||||
<a href="/docs/providers/google/r/resourcemanager_lien.html">google_resourcemanager_lien</a>
|
||||
<li<%= sidebar_current("docs-google-resource-manager-lien") %>>
|
||||
<a href="/docs/providers/google/r/resourcemanager_lien.html">google_resource_manager_lien</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-google-service-account-x") %>>
|
||||
<a href="/docs/providers/google/r/google_service_account.html">google_service_account</a>
|
||||
@ -440,6 +451,15 @@
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-google-container-analysis") %>>
|
||||
<a href="#">Google Container Analysis Resources</a>
|
||||
<ul class="nav nav-visible">
|
||||
<li<%= sidebar_current("docs-google-container-analysis-note") %>>
|
||||
<a href="/docs/providers/google/r/containeranalysis_note.html">google_container_analysis_note</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-google-container") %>>
|
||||
<a href="#">Google Kubernetes (Container) Engine Resources</a>
|
||||
<ul class="nav nav-visible">
|
||||
|
Loading…
Reference in New Issue
Block a user