Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add secretmanager resources and secret_version data source #1708

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/3007.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
secretmanager: added `secret` and `secret_version` resources and `secret_version` datasource
```
3 changes: 3 additions & 0 deletions google-beta/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ type Config struct {
RedisBasePath string
ResourceManagerBasePath string
RuntimeConfigBasePath string
SecretManagerBasePath string
SecurityCenterBasePath string
SecurityScannerBasePath string
SourceRepoBasePath string
Expand Down Expand Up @@ -248,6 +249,7 @@ var PubsubDefaultBasePath = "https://pubsub.googleapis.com/v1/"
var RedisDefaultBasePath = "https://redis.googleapis.com/v1beta1/"
var ResourceManagerDefaultBasePath = "https://cloudresourcemanager.googleapis.com/v1/"
var RuntimeConfigDefaultBasePath = "https://runtimeconfig.googleapis.com/v1beta1/"
var SecretManagerDefaultBasePath = "https://secretmanager.googleapis.com/v1beta1/"
var SecurityCenterDefaultBasePath = "https://securitycenter.googleapis.com/v1/"
var SecurityScannerDefaultBasePath = "https://websecurityscanner.googleapis.com/v1beta/"
var SourceRepoDefaultBasePath = "https://sourcerepo.googleapis.com/v1/"
Expand Down Expand Up @@ -748,6 +750,7 @@ func ConfigureBasePaths(c *Config) {
c.RedisBasePath = RedisDefaultBasePath
c.ResourceManagerBasePath = ResourceManagerDefaultBasePath
c.RuntimeConfigBasePath = RuntimeConfigDefaultBasePath
c.SecretManagerBasePath = SecretManagerDefaultBasePath
c.SecurityCenterBasePath = SecurityCenterDefaultBasePath
c.SecurityScannerBasePath = SecurityScannerDefaultBasePath
c.SourceRepoBasePath = SourceRepoDefaultBasePath
Expand Down
2 changes: 1 addition & 1 deletion google-beta/data_source_monitoring_notification_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func dataSourceMonitoringNotificationChannelRead(d *schema.ResourceData, meta in
}
res := channels[0].(map[string]interface{})

name := flattenMonitoringNotificationChannelName(res["name"], d).(string)
name := flattenMonitoringNotificationChannelName(res["name"], d, config).(string)
d.Set("name", name)
d.SetId(name)

Expand Down
121 changes: 121 additions & 0 deletions google-beta/data_source_secret_manager_secret_version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package google

import (
"fmt"
"log"
"regexp"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func dataSourceSecretManagerSecretVersion() *schema.Resource {
return &schema.Resource{
Read: dataSourceSecretManagerSecretVersionRead,
Schema: map[string]*schema.Schema{
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"secret": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
},
"version": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"create_time": {
Type: schema.TypeString,
Computed: true,
},
"destroy_time": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"secret_data": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
},
}
}

func dataSourceSecretManagerSecretVersionRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

fv, err := parseProjectFieldValue("secrets", d.Get("secret").(string), "project", d, config, false)
if err != nil {
return err
}
if d.Get("project").(string) != "" && d.Get("project").(string) != fv.Project {
return fmt.Errorf("The project set on this secret version (%s) is not equal to the project where this secret exists (%s).", d.Get("project").(string), fv.Project)
}
project := fv.Project
d.Set("project", project)
d.Set("secret", fv.Name)

var url string
versionNum := d.Get("version")

if versionNum != "" {
url, err = replaceVars(d, config, "{{SecretManagerBasePath}}projects/{{project}}/secrets/{{secret}}/versions/{{version}}")
if err != nil {
return err
}
} else {
url, err = replaceVars(d, config, "{{SecretManagerBasePath}}projects/{{project}}/secrets/{{secret}}/versions/latest")
if err != nil {
return err
}
}

var version map[string]interface{}
version, err = sendRequest(config, "GET", project, url, nil)
if err != nil {
return fmt.Errorf("Error retrieving available secret manager secret versions: %s", err.Error())
}

secretVersionRegex := regexp.MustCompile("projects/(.+)/secrets/(.+)/versions/(.+)$")

parts := secretVersionRegex.FindStringSubmatch(version["name"].(string))
// should return [full string, project number, secret name, version number]
if len(parts) != 4 {
panic(fmt.Sprintf("secret name, %s, does not match format, projects/{{project}}/secrets/{{secret}}/versions/{{version}}", version["name"].(string)))
}

log.Printf("[DEBUG] Received Google SecretManager Version: %q", version)

d.Set("version", parts[3])

url = fmt.Sprintf("%s:access", url)
resp, err := sendRequest(config, "GET", project, url, nil)
if err != nil {
return fmt.Errorf("Error retrieving available secret manager secret version access: %s", err.Error())
}

d.Set("create_time", version["createTime"].(string))
if version["destroyTime"] != nil {
d.Set("destroy_time", version["destroyTime"].(string))
}
d.Set("name", version["name"].(string))
d.Set("enabled", true)

data := resp["payload"].(map[string]interface{})
d.Set("secret_data", data["data"].(string))

d.SetId(time.Now().UTC().String())
return nil
}
135 changes: 135 additions & 0 deletions google-beta/data_source_secret_manager_secret_version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package google

import (
"errors"
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

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

randomString := acctest.RandString(10)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProvidersOiCS,
CheckDestroy: testAccCheckSecretManagerSecretVersionDestroy,
Steps: []resource.TestStep{
{
Config: testAccDatasourceSecretManagerSecretVersion_basic(randomString),
Check: resource.ComposeTestCheckFunc(
testAccCheckDatasourceSecretManagerSecretVersion("data.google_secret_manager_secret_version.basic", "1"),
),
},
},
})
}

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

randomString := acctest.RandString(10)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProvidersOiCS,
CheckDestroy: testAccCheckSecretManagerSecretVersionDestroy,
Steps: []resource.TestStep{
{
Config: testAccDatasourceSecretManagerSecretVersion_latest(randomString),
Check: resource.ComposeTestCheckFunc(
testAccCheckDatasourceSecretManagerSecretVersion("data.google_secret_manager_secret_version.latest", "2"),
),
},
},
})
}

func testAccCheckDatasourceSecretManagerSecretVersion(n, expected string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find Secret Version data source: %s", n)
}

if rs.Primary.ID == "" {
return errors.New("data source ID not set.")
}

version, ok := rs.Primary.Attributes["version"]
if !ok {
return errors.New("can't find 'version' attribute")
}

if version != expected {
return fmt.Errorf("expected %s, got %s, version not found", expected, version)
}
return nil
}
}

func testAccDatasourceSecretManagerSecretVersion_latest(randomString string) string {
return fmt.Sprintf(`
resource "google_secret_manager_secret" "secret-basic" {
provider = google-beta
secret_id = "tf-test-secret-version-%s"
labels = {
label = "my-label"
}
replication {
automatic = true
}
}

resource "google_secret_manager_secret_version" "secret-version-basic-1" {
provider = google-beta
secret = google_secret_manager_secret.secret-basic.name
secret_data = "my-tf-test-secret-first"
}

resource "google_secret_manager_secret_version" "secret-version-basic-2" {
provider = google-beta
secret = google_secret_manager_secret.secret-basic.name
secret_data = "my-tf-test-secret-second"

depends_on = [google_secret_manager_secret_version.secret-version-basic-1]
}

data "google_secret_manager_secret_version" "latest" {
provider = google-beta
secret = google_secret_manager_secret_version.secret-version-basic-2.secret
}
`, randomString)
}

func testAccDatasourceSecretManagerSecretVersion_basic(randomString string) string {
return fmt.Sprintf(`
resource "google_secret_manager_secret" "secret-basic" {
provider = google-beta
secret_id = "tf-test-secret-version-%s"
labels = {
label = "my-label"
}
replication {
automatic = true
}
}

resource "google_secret_manager_secret_version" "secret-version-basic" {
provider = google-beta
secret = google_secret_manager_secret.secret-basic.name
secret_data = "my-tf-test-secret-%s"
}

data "google_secret_manager_secret_version" "basic" {
provider = google-beta
secret = google_secret_manager_secret_version.secret-version-basic.secret
version = 1
}
`, randomString, randomString)
}
24 changes: 12 additions & 12 deletions google-beta/iam_binary_authorization_attestor_generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ resource "google_container_analysis_note" "note" {
}

resource "google_binary_authorization_attestor_iam_member" "foo" {
project = "${google_binary_authorization_attestor.attestor.project}"
attestor = "${google_binary_authorization_attestor.attestor.name}"
project = google_binary_authorization_attestor.attestor.project
attestor = google_binary_authorization_attestor.attestor.name
role = "%{role}"
member = "user:admin@hashicorptest.com"
}
Expand Down Expand Up @@ -210,9 +210,9 @@ data "google_iam_policy" "foo" {
}

resource "google_binary_authorization_attestor_iam_policy" "foo" {
project = "${google_binary_authorization_attestor.attestor.project}"
attestor = "${google_binary_authorization_attestor.attestor.name}"
policy_data = "${data.google_iam_policy.foo.policy_data}"
project = google_binary_authorization_attestor.attestor.project
attestor = google_binary_authorization_attestor.attestor.name
policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
}
Expand Down Expand Up @@ -259,9 +259,9 @@ data "google_iam_policy" "foo" {
}

resource "google_binary_authorization_attestor_iam_policy" "foo" {
project = "${google_binary_authorization_attestor.attestor.project}"
attestor = "${google_binary_authorization_attestor.attestor.name}"
policy_data = "${data.google_iam_policy.foo.policy_data}"
project = google_binary_authorization_attestor.attestor.project
attestor = google_binary_authorization_attestor.attestor.name
policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
}
Expand Down Expand Up @@ -305,8 +305,8 @@ resource "google_container_analysis_note" "note" {
}

resource "google_binary_authorization_attestor_iam_binding" "foo" {
project = "${google_binary_authorization_attestor.attestor.project}"
attestor = "${google_binary_authorization_attestor.attestor.name}"
project = google_binary_authorization_attestor.attestor.project
attestor = google_binary_authorization_attestor.attestor.name
role = "%{role}"
members = ["user:admin@hashicorptest.com"]
}
Expand Down Expand Up @@ -352,8 +352,8 @@ resource "google_container_analysis_note" "note" {
}

resource "google_binary_authorization_attestor_iam_binding" "foo" {
project = "${google_binary_authorization_attestor.attestor.project}"
attestor = "${google_binary_authorization_attestor.attestor.name}"
project = google_binary_authorization_attestor.attestor.project
attestor = google_binary_authorization_attestor.attestor.name
role = "%{role}"
members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"]
}
Expand Down
Loading