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 more import paths for Terraform google_service_account #566

Merged
merged 4 commits into from
Oct 16, 2018
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
2 changes: 1 addition & 1 deletion build/terraform
8 changes: 4 additions & 4 deletions provider/terraform/common~copy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,26 @@
-%>
# Handwritten acceptance tests for autogenerated resources.
# Adding them here allows updating the tests as part of a MM pull request.
<% Dir["provider/terraform/tests/*#{api.prefix[1..-1]}*"].each do |file_path|
<% Dir["provider/terraform/tests/*.go"].each do |file_path|
fname = file_path.split('/')[-1]
-%>
'<%= dir -%>/<%= fname -%>': 'provider/terraform/tests/<%= fname -%>'
<% end -%>
# Copy all of the terraform resources that are still hand written
<%
Dir["provider/terraform/resources/*#{api.prefix[1..-1]}*"].each do |file_path|
Dir["provider/terraform/resources/*.go"].each do |file_path|
fname = file_path.split('/')[-1]
-%>
'<%= dir -%>/<%= fname -%>': 'provider/terraform/resources/<%= fname -%>'
<% end -%>
<%
Dir["provider/terraform/data_sources/*#{api.prefix[1..-1]}*"].each do |file_path|
Dir["provider/terraform/data_sources/*.go"].each do |file_path|
fname = file_path.split('/')[-1]
-%>
'<%= dir -%>/<%= fname -%>': 'provider/terraform/data_sources/<%= fname -%>'
<% end -%>
<%
Dir["provider/terraform/utils/*"].each do |file_path|
Dir["provider/terraform/utils/*.go"].each do |file_path|
fname = file_path.split('/')[-1]
-%>
'<%= dir -%>/<%= fname -%>': 'provider/terraform/utils/<%= fname -%>'
Expand Down
19 changes: 18 additions & 1 deletion provider/terraform/resources/resource_google_service_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func resourceGoogleServiceAccount() *schema.Resource {
Delete: resourceGoogleServiceAccountDelete,
Update: resourceGoogleServiceAccountUpdate,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
State: resourceGoogleServiceAccountImport,
},
Schema: map[string]*schema.Schema{
"email": &schema.Schema{
Expand Down Expand Up @@ -194,3 +194,20 @@ func saMergeBindings(bindings []*iam.Binding) []*iam.Binding {

return rb
}

func resourceGoogleServiceAccountImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*Config)
parseImportId([]string{
"projects/(?P<project>[^/]+)/serviceAccounts/(?P<email>[^/]+)",
"(?P<project>[^/]+)/(?P<email>[^/]+)",
"(?P<email>[^/]+)"}, d, config)

// Replace import id for the resource id
id, err := replaceVars(d, config, "projects/{{project}}/serviceAccounts/{{email}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

return []*schema.ResourceData{d}, nil
}
128 changes: 128 additions & 0 deletions provider/terraform/tests/resource_google_service_account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package google

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

// Test that a service account resource can be created, updated, and destroyed
func TestAccServiceAccount_basic(t *testing.T) {
t.Parallel()

accountId := "a" + acctest.RandString(10)
uniqueId := ""
displayName := "Terraform Test"
displayName2 := "Terraform Test Update"
project := getTestProjectFromEnv()
expectedEmail := fmt.Sprintf("%s@%s.iam.gserviceaccount.com", accountId, project)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
// The first step creates a basic service account
resource.TestStep{
Config: testAccServiceAccountBasic(accountId, displayName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
),
},
resource.TestStep{
ResourceName: "google_service_account.acceptance",
ImportStateId: fmt.Sprintf("projects/%s/serviceAccounts/%s", project, expectedEmail),
ImportState: true,
ImportStateVerify: true,
},
resource.TestStep{
ResourceName: "google_service_account.acceptance",
ImportStateId: fmt.Sprintf("%s/%s", project, expectedEmail),
ImportState: true,
ImportStateVerify: true,
},
resource.TestStep{
ResourceName: "google_service_account.acceptance",
ImportStateId: expectedEmail,
ImportState: true,
ImportStateVerify: true,
},
// The second step updates the service account
resource.TestStep{
Config: testAccServiceAccountBasic(accountId, displayName2),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
testAccStoreServiceAccountUniqueId(&uniqueId),
),
},
resource.TestStep{
ResourceName: "google_service_account.acceptance",
ImportState: true,
ImportStateVerify: true,
},
// The third step explicitely adds the same default project to the service account configuration
// and ensure the service account is not recreated by comparing the value of its unique_id with the one from the previous step
resource.TestStep{
Config: testAccServiceAccountWithProject(project, accountId, displayName2),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
resource.TestCheckResourceAttrPtr(
"google_service_account.acceptance", "unique_id", &uniqueId),
),
},
resource.TestStep{
ResourceName: "google_service_account.acceptance",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccStoreServiceAccountUniqueId(uniqueId *string) resource.TestCheckFunc {
return func(s *terraform.State) error {
*uniqueId = s.RootModule().Resources["google_service_account.acceptance"].Primary.Attributes["unique_id"]
return nil
}
}

func testAccServiceAccountBasic(account, name string) string {
return fmt.Sprintf(`
resource "google_service_account" "acceptance" {
account_id = "%v"
display_name = "%v"
}
`, account, name)
}

func testAccServiceAccountWithProject(project, account, name string) string {
return fmt.Sprintf(`
resource "google_service_account" "acceptance" {
project = "%v"
account_id = "%v"
display_name = "%v"
}
`, project, account, name)
}

func testAccServiceAccountPolicy(account, project string) string {
return fmt.Sprintf(`
resource "google_service_account" "acceptance" {
account_id = "%v"
display_name = "%v"
}

data "google_iam_policy" "service_account" {
binding {
role = "roles/iam.serviceAccountActor"
members = [
"serviceAccount:%v@%v.iam.gserviceaccount.com",
]
}
}
`, account, account, account, project)
}