blob: b7824bab7d6fc96df4e92f29c2612b315ac3b26e [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package pubsub_test
import (
"fmt"
"reflect"
"sort"
"testing"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/services/pubsub"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
)
func TestAccPubsubTopicIamBinding(t *testing.T) {
t.Parallel()
topic := "tf-test-topic-iam-" + acctest.RandString(t, 10)
account := "tf-test-topic-iam-" + acctest.RandString(t, 10)
acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
// Test IAM Binding creation
Config: testAccPubsubTopicIamBinding_basic(topic, account),
Check: testAccCheckPubsubTopicIam(t, topic, "roles/pubsub.publisher", []string{
fmt.Sprintf("serviceAccount:%s-1@%s.iam.gserviceaccount.com", account, envvar.GetTestProjectFromEnv()),
}),
},
{
ResourceName: "google_pubsub_topic_iam_binding.foo",
ImportStateId: fmt.Sprintf("%s roles/pubsub.publisher", pubsub.GetComputedTopicName(envvar.GetTestProjectFromEnv(), topic)),
ImportState: true,
ImportStateVerify: true,
},
{
// Test IAM Binding update
Config: testAccPubsubTopicIamBinding_update(topic, account),
Check: testAccCheckPubsubTopicIam(t, topic, "roles/pubsub.publisher", []string{
fmt.Sprintf("serviceAccount:%s-1@%s.iam.gserviceaccount.com", account, envvar.GetTestProjectFromEnv()),
fmt.Sprintf("serviceAccount:%s-2@%s.iam.gserviceaccount.com", account, envvar.GetTestProjectFromEnv()),
}),
},
{
ResourceName: "google_pubsub_topic_iam_binding.foo",
ImportStateId: fmt.Sprintf("%s roles/pubsub.publisher", pubsub.GetComputedTopicName(envvar.GetTestProjectFromEnv(), topic)),
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccPubsubTopicIamBinding_topicName(t *testing.T) {
t.Parallel()
topic := "tf-test-topic-iam-" + acctest.RandString(t, 10)
account := "tf-test-topic-iam-" + acctest.RandString(t, 10)
acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
// Test IAM Binding creation
Config: testAccPubsubTopicIamBinding_topicName(topic, account),
Check: testAccCheckPubsubTopicIam(t, topic, "roles/pubsub.publisher", []string{
fmt.Sprintf("serviceAccount:%s-1@%s.iam.gserviceaccount.com", account, envvar.GetTestProjectFromEnv()),
}),
},
// No import step- imports want the resource to be defined using the full id as the topic
},
})
}
func TestAccPubsubTopicIamMember(t *testing.T) {
t.Parallel()
topic := "tf-test-topic-iam-" + acctest.RandString(t, 10)
account := "tf-test-topic-iam-" + acctest.RandString(t, 10)
accountEmail := fmt.Sprintf("%s@%s.iam.gserviceaccount.com", account, envvar.GetTestProjectFromEnv())
acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
// Test Iam Member creation (no update for member, no need to test)
Config: testAccPubsubTopicIamMember_basic(topic, account),
Check: testAccCheckPubsubTopicIam(t, topic, "roles/pubsub.publisher", []string{
fmt.Sprintf("serviceAccount:%s", accountEmail),
}),
},
{
ResourceName: "google_pubsub_topic_iam_member.foo",
ImportStateId: fmt.Sprintf("%s roles/pubsub.publisher serviceAccount:%s", pubsub.GetComputedTopicName(envvar.GetTestProjectFromEnv(), topic), accountEmail),
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccPubsubTopicIamPolicy(t *testing.T) {
t.Parallel()
topic := "tf-test-topic-iam-" + acctest.RandString(t, 10)
account := "tf-test-topic-iam-" + acctest.RandString(t, 10)
acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccPubsubTopicIamPolicy_basic(topic, account, "roles/pubsub.publisher"),
Check: testAccCheckPubsubTopicIam(t, topic, "roles/pubsub.publisher", []string{
fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, envvar.GetTestProjectFromEnv()),
}),
},
{
Config: testAccPubsubTopicIamPolicy_basic(topic, account, "roles/pubsub.subscriber"),
Check: testAccCheckPubsubTopicIam(t, topic, "roles/pubsub.subscriber", []string{
fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, envvar.GetTestProjectFromEnv()),
}),
},
{
ResourceName: "google_pubsub_topic_iam_policy.foo",
ImportStateId: pubsub.GetComputedTopicName(envvar.GetTestProjectFromEnv(), topic),
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccCheckPubsubTopicIam(t *testing.T, topic, role string, members []string) resource.TestCheckFunc {
return func(s *terraform.State) error {
config := acctest.GoogleProviderConfig(t)
p, err := config.NewPubsubClient(config.UserAgent).Projects.Topics.GetIamPolicy(pubsub.GetComputedTopicName(envvar.GetTestProjectFromEnv(), topic)).Do()
if err != nil {
return err
}
for _, binding := range p.Bindings {
if binding.Role == role {
sort.Strings(members)
sort.Strings(binding.Members)
if reflect.DeepEqual(members, binding.Members) {
return nil
}
return fmt.Errorf("Binding found but expected members is %v, got %v", members, binding.Members)
}
}
return fmt.Errorf("No binding for role %q", role)
}
}
func testAccPubsubTopicIamBinding_topicName(topic, account string) string {
return fmt.Sprintf(`
resource "google_pubsub_topic" "topic" {
name = "%s"
}
resource "google_service_account" "test-account-1" {
account_id = "%s-1"
display_name = "Iam Testing Account"
}
resource "google_pubsub_topic_iam_binding" "foo" {
project = "%s"
topic = google_pubsub_topic.topic.name
role = "roles/pubsub.publisher"
members = [
"serviceAccount:${google_service_account.test-account-1.email}",
]
}
`, topic, account, envvar.GetTestProjectFromEnv())
}
func testAccPubsubTopicIamBinding_basic(topic, account string) string {
return fmt.Sprintf(`
resource "google_pubsub_topic" "topic" {
name = "%s"
}
resource "google_service_account" "test-account-1" {
account_id = "%s-1"
display_name = "Iam Testing Account"
}
resource "google_pubsub_topic_iam_binding" "foo" {
# use the id instead of the name because it's more compatible with import
topic = google_pubsub_topic.topic.id
role = "roles/pubsub.publisher"
members = [
"serviceAccount:${google_service_account.test-account-1.email}",
]
}
`, topic, account)
}
func testAccPubsubTopicIamBinding_update(topic, account string) string {
return fmt.Sprintf(`
resource "google_pubsub_topic" "topic" {
name = "%s"
}
resource "google_service_account" "test-account-1" {
account_id = "%s-1"
display_name = "Iam Testing Account"
}
resource "google_service_account" "test-account-2" {
account_id = "%s-2"
display_name = "Iam Testing Account"
}
resource "google_pubsub_topic_iam_binding" "foo" {
# use the id instead of the name because it's more compatible with import
topic = google_pubsub_topic.topic.id
role = "roles/pubsub.publisher"
members = [
"serviceAccount:${google_service_account.test-account-1.email}",
"serviceAccount:${google_service_account.test-account-2.email}",
]
}
`, topic, account, account)
}
func testAccPubsubTopicIamMember_basic(topic, account string) string {
return fmt.Sprintf(`
resource "google_pubsub_topic" "topic" {
name = "%s"
}
resource "google_service_account" "test-account" {
account_id = "%s"
display_name = "Iam Testing Account"
}
resource "google_pubsub_topic_iam_member" "foo" {
topic = google_pubsub_topic.topic.id
role = "roles/pubsub.publisher"
member = "serviceAccount:${google_service_account.test-account.email}"
}
`, topic, account)
}
func testAccPubsubTopicIamPolicy_basic(topic, account, role string) string {
return fmt.Sprintf(`
resource "google_pubsub_topic" "topic" {
name = "%s"
}
resource "google_service_account" "test-account" {
account_id = "%s"
display_name = "Iam Testing Account"
}
data "google_iam_policy" "foo" {
binding {
role = "%s"
members = ["serviceAccount:${google_service_account.test-account.email}"]
}
}
resource "google_pubsub_topic_iam_policy" "foo" {
topic = google_pubsub_topic.topic.id
policy_data = data.google_iam_policy.foo.policy_data
}
`, topic, account, role)
}