Skip to content

Commit

Permalink
Binary Authorization: globalPolicyEvaluationMode
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
drebes authored and modular-magician committed Aug 6, 2019
1 parent 202d226 commit 9f3a6b2
Show file tree
Hide file tree
Showing 3 changed files with 310 additions and 2 deletions.
29 changes: 29 additions & 0 deletions google/resource_binary_authorization_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ func resourceBinaryAuthorizationPolicy() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"global_policy_evaluation_mode": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"ENABLE", "DISABLE", ""}, false),
},
"project": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -178,6 +184,12 @@ func resourceBinaryAuthorizationPolicyCreate(d *schema.ResourceData, meta interf
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
obj["description"] = descriptionProp
}
globalPolicyEvaluationModeProp, err := expandBinaryAuthorizationPolicyGlobalPolicyEvaluationMode(d.Get("global_policy_evaluation_mode"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("global_policy_evaluation_mode"); !isEmptyValue(reflect.ValueOf(globalPolicyEvaluationModeProp)) && (ok || !reflect.DeepEqual(v, globalPolicyEvaluationModeProp)) {
obj["globalPolicyEvaluationMode"] = globalPolicyEvaluationModeProp
}
admissionWhitelistPatternsProp, err := expandBinaryAuthorizationPolicyAdmissionWhitelistPatterns(d.Get("admission_whitelist_patterns"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -244,6 +256,9 @@ func resourceBinaryAuthorizationPolicyRead(d *schema.ResourceData, meta interfac
if err := d.Set("description", flattenBinaryAuthorizationPolicyDescription(res["description"], d)); err != nil {
return fmt.Errorf("Error reading Policy: %s", err)
}
if err := d.Set("global_policy_evaluation_mode", flattenBinaryAuthorizationPolicyGlobalPolicyEvaluationMode(res["globalPolicyEvaluationMode"], d)); err != nil {
return fmt.Errorf("Error reading Policy: %s", err)
}
if err := d.Set("admission_whitelist_patterns", flattenBinaryAuthorizationPolicyAdmissionWhitelistPatterns(res["admissionWhitelistPatterns"], d)); err != nil {
return fmt.Errorf("Error reading Policy: %s", err)
}
Expand All @@ -267,6 +282,12 @@ func resourceBinaryAuthorizationPolicyUpdate(d *schema.ResourceData, meta interf
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
obj["description"] = descriptionProp
}
globalPolicyEvaluationModeProp, err := expandBinaryAuthorizationPolicyGlobalPolicyEvaluationMode(d.Get("global_policy_evaluation_mode"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("global_policy_evaluation_mode"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, globalPolicyEvaluationModeProp)) {
obj["globalPolicyEvaluationMode"] = globalPolicyEvaluationModeProp
}
admissionWhitelistPatternsProp, err := expandBinaryAuthorizationPolicyAdmissionWhitelistPatterns(d.Get("admission_whitelist_patterns"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -344,6 +365,10 @@ func flattenBinaryAuthorizationPolicyDescription(v interface{}, d *schema.Resour
return v
}

func flattenBinaryAuthorizationPolicyGlobalPolicyEvaluationMode(v interface{}, d *schema.ResourceData) interface{} {
return v
}

func flattenBinaryAuthorizationPolicyAdmissionWhitelistPatterns(v interface{}, d *schema.ResourceData) interface{} {
if v == nil {
return v
Expand Down Expand Up @@ -434,6 +459,10 @@ func expandBinaryAuthorizationPolicyDescription(v interface{}, d TerraformResour
return v, nil
}

func expandBinaryAuthorizationPolicyGlobalPolicyEvaluationMode(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandBinaryAuthorizationPolicyAdmissionWhitelistPatterns(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
Expand Down
245 changes: 243 additions & 2 deletions google/resource_binaryauthorization_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,123 @@ func TestAccBinaryAuthorizationPolicy_basic(t *testing.T) {
})
}

// Because Container Analysis is still in beta, we can't run any of the tests that call that
// resource without vendoring in the full beta provider.
func TestAccBinaryAuthorizationPolicy_full(t *testing.T) {
t.Parallel()

org := getTestOrgFromEnv(t)
pid := "tf-test-" + acctest.RandString(10)
billingId := getTestBillingAccountFromEnv(t)
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, billingId, note, attestor, "DISABLE"),
},
{
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, billingId),
Check: testAccCheckBinaryAuthorizationPolicyDefault(pid),
},
},
})
}

// Use an attestor created in the default CI project
func TestAccBinaryAuthorizationPolicy_separateProject(t *testing.T) {
t.Parallel()

org := getTestOrgFromEnv(t)
pid := "tf-test-" + acctest.RandString(10)
billingId := getTestBillingAccountFromEnv(t)
note := acctest.RandString(10)
attestor := acctest.RandString(10)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccBinaryAuthorizationPolicy_separateProject(pid, pname, org, billingId, 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, billingId),
Check: testAccCheckBinaryAuthorizationPolicyDefault(pid),
},
},
})
}

func TestAccBinaryAuthorizationPolicy_update(t *testing.T) {
t.Parallel()

org := getTestOrgFromEnv(t)
pid := "tf-test-" + acctest.RandString(10)
billingId := getTestBillingAccountFromEnv(t)
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, billingId),
},
{
ResourceName: "google_binary_authorization_policy.policy",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccBinaryAuthorizationPolicyFull(pid, pname, org, billingId, note, attestor, "DISABLE"),
},
{
ResourceName: "google_binary_authorization_policy.policy",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccBinaryAuthorizationPolicyFull(pid, pname, org, billingId, note, attestor, "ENABLE"),
},
{
ResourceName: "google_binary_authorization_policy.policy",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccBinaryAuthorizationPolicyBasic(pid, pname, org, billingId),
},
{
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, billingId),
Check: testAccCheckBinaryAuthorizationPolicyDefault(pid),
},
},
})
}

func testAccCheckBinaryAuthorizationPolicyDefault(pid string) resource.TestCheckFunc {
return func(s *terraform.State) error {
Expand Down Expand Up @@ -95,3 +210,129 @@ resource "google_binary_authorization_policy" "policy" {
}
`, pid, pname, org, billing)
}

func testAccBinaryAuthorizationPolicyFull(pid, pname, org, billing, note, attestor, gpmode 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"
billing_account = "%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}"]
}
global_policy_evaluation mode = "%s"
}
`, pid, pname, org, billing, note, attestor, gpmode)
}

func testAccBinaryAuthorizationPolicy_separateProject(pid, pname, org, billing, 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"
billing_account = "%s"
}
data "google_client_config" "current" {}
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" {
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 = ["projects/${data.google_client_config.current.project}/attestors/${google_binary_authorization_attestor.attestor.name}"]
}
}
`, pid, pname, org, billing, note, attestor)
}
38 changes: 38 additions & 0 deletions website/docs/r/binary_authorization_policy.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,38 @@ resource "google_container_analysis_note" "note" {
}
}
resource "google_binary_authorization_attestor" "attestor" {
name = "test-attestor"
attestation_authority_note {
note_reference = "${google_container_analysis_note.note.name}"
}
}
```
## Example Usage - Binary Authorization Policy Global Evaluation


```hcl
resource "google_binary_authorization_policy" "policy" {
default_admission_rule {
evaluation_mode = "REQUIRE_ATTESTATION"
enforcement_mode = "ENFORCED_BLOCK_AND_AUDIT_LOG"
require_attestations_by = ["${google_binary_authorization_attestor.attestor.name}"]
}
global_policy_evaluation_mode = "ENABLE"
}
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 {
Expand Down Expand Up @@ -108,6 +140,12 @@ The `default_admission_rule` block supports:
(Optional)
A descriptive comment.

* `global_policy_evaluation_mode` -
(Optional)
Controls the evaluation of a Google-maintained global admission policy
for common system-level images. Images not covered by the global
policy will be subject to the project admission policy.

* `admission_whitelist_patterns` -
(Optional)
A whitelist of image patterns to exclude from admission rules. If an
Expand Down

0 comments on commit 9f3a6b2

Please sign in to comment.