Skip to content

Commit

Permalink
Organization Source iam (GoogleCloudPlatform#10881)
Browse files Browse the repository at this point in the history
  • Loading branch information
thokalavinod authored and BBBmau committed Aug 21, 2024
1 parent f2c9393 commit eec3ede
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 0 deletions.
83 changes: 83 additions & 0 deletions mmv1/products/securitycenterv2/OrganizationSource.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Api::Resource
name: 'OrganizationSource'
base_url: organizations/{{organization}}/sources
self_link: '{{name}}'
update_verb: :PATCH
update_mask: true
description: |
A Cloud Security Command Center's (Cloud SCC) finding source. A finding
source is an entity or a mechanism that can produce a finding. A source is
like a container of findings that come from the same scanner, logger,
monitor, etc.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/security-command-center/docs'
api: 'https://cloud.google.com/security-command-center/docs/reference/rest/v2/organizations.sources'
iam_policy: !ruby/object:Api::Resource::IamPolicy
method_name_separator: ':'
fetch_iam_policy_verb: :POST
parent_resource_attribute: 'source'
base_url: organizations/{{organization}}/sources/{{source}}
import_format:
['organizations/{{organization}}/sources/{{source}}', '{{source}}']
skip_delete: true
examples:
- !ruby/object:Provider::Terraform::Examples
name:
'scc_source_basic'
# resource can't be destroyed, so checkdestroy fails unnecessarily
skip_test: true
primary_resource_id: 'custom_source'
vars:
source_display_name: 'My Source'
test_env_vars:
org_id: :ORG_ID
custom_code: !ruby/object:Provider::Terraform::CustomCode
custom_import: templates/terraform/custom_import/scc_source_self_link_as_name_set_organization.go.erb
post_create: templates/terraform/post_create/set_computed_name.erb
parameters:
- !ruby/object:Api::Type::String
name: organization
required: true
immutable: true
url_param_only: true
description: |
The organization whose Cloud Security Command Center the Source
lives in.
properties:
- !ruby/object:Api::Type::String
name: name
output: true
description: |
The resource name of this source, in the format
`organizations/{{organization}}/sources/{{source}}`.
- !ruby/object:Api::Type::String
name: description
description: |
The description of the source (max of 1024 characters).
validation: !ruby/object:Provider::Terraform::Validation
function: 'validation.StringLenBetween(0, 1024)'
- !ruby/object:Api::Type::String
name: displayName
required: true
description: |
The source’s display name. A source’s display name must be unique
amongst its siblings, for example, two sources with the same parent
can't share the same display name. The display name must start and end
with a letter or digit, may contain letters, digits, spaces, hyphens,
and underscores, and can be no longer than 32 characters.
validation: !ruby/object:Provider::Terraform::Validation
regex: '[\p{L}\p{N}]({\p{L}\p{N}_- ]{0,30}[\p{L}\p{N}])?'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "google_scc_v2_organization_source" "<%= ctx[:primary_resource_id] %>" {
display_name = "<%= ctx[:vars]['source_display_name'] %>"
organization = "<%= ctx[:test_env_vars]['org_id'] %>"
description = "My custom Cloud Security Command Center Finding Source"
}
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,11 @@ var ServicesListBeta = mapOf(
"displayName" to "Securitycenter",
"path" to "./google-beta/services/securitycenter"
),
"securitycenterv2" to mapOf(
"name" to "securitycenterv2",
"displayName" to "securitycenterv2",
"path" to "./google-beta/services/securitycenterv2"
),
"securitycentermanagement" to mapOf(
"name" to "securitycentermanagement",
"displayName" to "Securitycentermanagement",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,11 @@ var ServicesListGa = mapOf(
"displayName" to "Securitycenter",
"path" to "./google/services/securitycenter"
),
"securitycenterv2" to mapOf(
"name" to "securitycenterv2",
"displayName" to "securitycenterv2",
"path" to "./google-beta/services/securitycenterv2"
),
"securitycentermanagement" to mapOf(
"name" to "securitycentermanagement",
"displayName" to "Securitycentermanagement",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
package securitycenterv2_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
)

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

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
"role": "roles/securitycenter.sourcesViewer",
"org_id": envvar.GetTestOrgFromEnv(t),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccSecurityCenterSourceIamBinding_basic(context),
},
{
ResourceName: "google_scc_v2_organization_source_iam_binding.foo",
ImportStateIdFunc: func(state *terraform.State) (string, error) {
id := state.RootModule().Resources["google_scc_v2_organization_source.custom_source"].Primary.Attributes["id"]
return fmt.Sprintf("%s %s",
id,
context["role"],
), nil
},
ImportState: true,
ImportStateVerify: true,
},
{
// Test Iam Binding update
Config: testAccSecurityCenterSourceIamBinding_update(context),
},
{
ResourceName: "google_scc_v2_organization_source_iam_binding.foo",
ImportStateIdFunc: func(state *terraform.State) (string, error) {
id := state.RootModule().Resources["google_scc_v2_organization_source.custom_source"].Primary.Attributes["id"]
return fmt.Sprintf("%s %s",
id,
context["role"],
), nil
},
ImportState: true,
ImportStateVerify: true,
},
},
})
}

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

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
"role": "roles/securitycenter.sourcesViewer",
"org_id": envvar.GetTestOrgFromEnv(t),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccSecurityCenterSourceIamMember_basic(context),
},
{
ResourceName: "google_scc_v2_organization_source_iam_member.foo",
ImportStateIdFunc: func(state *terraform.State) (string, error) {
id := state.RootModule().Resources["google_scc_v2_organization_source.custom_source"].Primary.Attributes["id"]
return fmt.Sprintf("%s %s user:[email protected]",
id,
context["role"],
), nil
},
ImportState: true,
ImportStateVerify: true,
},
},
})
}

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

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
"role": "roles/securitycenter.sourcesViewer",
"org_id": envvar.GetTestOrgFromEnv(t),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccSecurityCenterSourceIamPolicy_basic(context),
},
{
ResourceName: "google_scc_v2_organization_source_iam_policy.foo",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccSecurityCenterSourceIamPolicy_emptyBinding(context),
},
{
ResourceName: "google_scc_v2_organization_source_iam_policy.foo",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccSecurityCenterSourceIamMember_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_scc_v2_organization_source" "custom_source" {
display_name = "tf-test-source%{random_suffix}"
organization = "%{org_id}"
description = "My custom Cloud Security Command Center Finding Source"
}
resource "google_scc_v2_organization_source_iam_member" "foo" {
source = google_scc_v2_organization_source.custom_source.id
organization = "%{org_id}"
role = "%{role}"
member = "user:[email protected]"
}
`, context)
}

func testAccSecurityCenterSourceIamPolicy_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_scc_v2_organization_source" "custom_source" {
display_name = "tf-test-source%{random_suffix}"
organization = "%{org_id}"
description = "My custom Cloud Security Command Center Finding Source"
}
data "google_iam_policy" "foo" {
binding {
role = "%{role}"
members = ["user:[email protected]"]
}
}
resource "google_scc_v2_organization_source_iam_policy" "foo" {
source = google_scc_v2_organization_source.custom_source.id
organization = "%{org_id}"
policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
}

func testAccSecurityCenterSourceIamPolicy_emptyBinding(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_scc_v2_organization_source" "custom_source" {
display_name = "tf-test-source%{random_suffix}"
organization = "%{org_id}"
description = "My custom Cloud Security Command Center Finding Source"
}
data "google_iam_policy" "foo" {
}
resource "google_scc_v2_organization_source_iam_policy" "foo" {
source = google_scc_v2_organization_source.custom_source.id
organization = "%{org_id}"
policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
}

func testAccSecurityCenterSourceIamBinding_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_scc_v2_organization_source" "custom_source" {
display_name = "tf-test-source%{random_suffix}"
organization = "%{org_id}"
description = "My custom Cloud Security Command Center Finding Source"
}
resource "google_scc_v2_organization_source_iam_binding" "foo" {
source = google_scc_v2_organization_source.custom_source.id
organization = "%{org_id}"
role = "%{role}"
members = ["user:[email protected]"]
}
`, context)
}

func testAccSecurityCenterSourceIamBinding_update(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_scc_v2_organization_source" "custom_source" {
display_name = "tf-test-source%{random_suffix}"
organization = "%{org_id}"
description = "My custom Cloud Security Command Center Finding Source"
}
resource "google_scc_v2_organization_source_iam_binding" "foo" {
source = google_scc_v2_organization_source.custom_source.id
organization = "%{org_id}"
role = "%{role}"
members = ["user:[email protected]", "user:[email protected]"]
}
`, context)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package securitycenterv2_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
)

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

orgId := envvar.GetTestOrgFromEnv(t)
suffix := acctest.RandString(t, 10)

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccSecurityCenterSource_sccSourceBasicExample(orgId, suffix, "My description"),
},
{
ResourceName: "google_scc_v2_organization_source.custom_source",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccSecurityCenterSource_sccSourceBasicExample(orgId, suffix, ""),
},
{
ResourceName: "google_scc_v2_organization_source.custom_source",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccSecurityCenterSource_sccSourceBasicExample(orgId, suffix, description string) string {
return fmt.Sprintf(`
resource "google_scc_v2_organization_source" "custom_source" {
display_name = "TFSrc %s"
organization = "%s"
description = "%s"
}
`, suffix, orgId, description)
}

0 comments on commit eec3ede

Please sign in to comment.