2016-11-23 06:55:40 +00:00
|
|
|
package google
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"reflect"
|
|
|
|
"sort"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/helper/acctest"
|
|
|
|
"github.com/hashicorp/terraform/helper/resource"
|
|
|
|
"github.com/hashicorp/terraform/terraform"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Test that services can be enabled and disabled on a project
|
2018-02-23 23:14:24 +00:00
|
|
|
func TestAccProjectServices_basic(t *testing.T) {
|
2017-10-12 22:07:29 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-11-20 23:45:51 +00:00
|
|
|
org := getTestOrgFromEnv(t)
|
2016-11-23 06:55:40 +00:00
|
|
|
pid := "terraform-" + acctest.RandString(10)
|
2018-12-14 01:51:11 +00:00
|
|
|
services1 := []string{"iam.googleapis.com", "cloudresourcemanager.googleapis.com"}
|
2016-11-23 06:55:40 +00:00
|
|
|
services2 := []string{"cloudresourcemanager.googleapis.com"}
|
2018-12-14 01:51:11 +00:00
|
|
|
oobService := "iam.googleapis.com"
|
2016-11-23 06:55:40 +00:00
|
|
|
resource.Test(t, resource.TestCase{
|
|
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
|
|
Providers: testAccProviders,
|
|
|
|
Steps: []resource.TestStep{
|
|
|
|
// Create a new project with some services
|
|
|
|
resource.TestStep{
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProjectAssociateServicesBasic(services1, pid, pname, org),
|
2016-11-23 06:55:40 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testProjectServicesMatch(services1, pid),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
// Update services to remove one
|
|
|
|
resource.TestStep{
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProjectAssociateServicesBasic(services2, pid, pname, org),
|
2016-11-23 06:55:40 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testProjectServicesMatch(services2, pid),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
// Add a service out-of-band and ensure it is removed
|
|
|
|
resource.TestStep{
|
|
|
|
PreConfig: func() {
|
|
|
|
config := testAccProvider.Meta().(*Config)
|
|
|
|
enableService(oobService, pid, config)
|
|
|
|
},
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProjectAssociateServicesBasic(services2, pid, pname, org),
|
2016-11-23 06:55:40 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testProjectServicesMatch(services2, pid),
|
|
|
|
),
|
|
|
|
},
|
2018-04-05 20:32:26 +00:00
|
|
|
resource.TestStep{
|
|
|
|
ResourceName: "google_project_services.acceptance",
|
|
|
|
ImportState: true,
|
|
|
|
ImportStateId: pid,
|
|
|
|
ImportStateVerify: true,
|
|
|
|
ImportStateVerifyIgnore: []string{"disable_on_destroy"},
|
|
|
|
},
|
2016-11-23 06:55:40 +00:00
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that services are authoritative when a project has existing
|
|
|
|
// sevices not represented in config
|
2018-02-23 23:14:24 +00:00
|
|
|
func TestAccProjectServices_authoritative(t *testing.T) {
|
2017-10-12 22:07:29 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-11-20 23:45:51 +00:00
|
|
|
org := getTestOrgFromEnv(t)
|
2016-11-23 06:55:40 +00:00
|
|
|
pid := "terraform-" + acctest.RandString(10)
|
|
|
|
services := []string{"cloudresourcemanager.googleapis.com"}
|
2018-12-14 01:51:11 +00:00
|
|
|
oobService := "iam.googleapis.com"
|
2016-11-23 06:55:40 +00:00
|
|
|
resource.Test(t, resource.TestCase{
|
|
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
|
|
Providers: testAccProviders,
|
|
|
|
Steps: []resource.TestStep{
|
|
|
|
// Create a new project with no services
|
|
|
|
resource.TestStep{
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProject_create(pid, pname, org),
|
2016-11-23 06:55:40 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testAccCheckGoogleProjectExists("google_project.acceptance", pid),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
// Add a service out-of-band, then apply a config that creates a service.
|
|
|
|
// It should remove the out-of-band service.
|
|
|
|
resource.TestStep{
|
|
|
|
PreConfig: func() {
|
|
|
|
config := testAccProvider.Meta().(*Config)
|
|
|
|
enableService(oobService, pid, config)
|
|
|
|
},
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProjectAssociateServicesBasic(services, pid, pname, org),
|
2016-11-23 06:55:40 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testProjectServicesMatch(services, pid),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that services are authoritative when a project has existing
|
|
|
|
// sevices, some which are represented in the config and others
|
|
|
|
// that are not
|
2018-02-23 23:14:24 +00:00
|
|
|
func TestAccProjectServices_authoritative2(t *testing.T) {
|
2017-10-12 22:07:29 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-11-20 23:45:51 +00:00
|
|
|
org := getTestOrgFromEnv(t)
|
2016-11-23 06:55:40 +00:00
|
|
|
pid := "terraform-" + acctest.RandString(10)
|
2018-12-14 01:51:11 +00:00
|
|
|
oobServices := []string{"iam.googleapis.com", "cloudresourcemanager.googleapis.com"}
|
|
|
|
services := []string{"iam.googleapis.com"}
|
2016-11-23 06:55:40 +00:00
|
|
|
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
|
|
Providers: testAccProviders,
|
|
|
|
Steps: []resource.TestStep{
|
|
|
|
// Create a new project with no services
|
|
|
|
resource.TestStep{
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProject_create(pid, pname, org),
|
2016-11-23 06:55:40 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testAccCheckGoogleProjectExists("google_project.acceptance", pid),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
// Add a service out-of-band, then apply a config that creates a service.
|
|
|
|
// It should remove the out-of-band service.
|
|
|
|
resource.TestStep{
|
|
|
|
PreConfig: func() {
|
|
|
|
config := testAccProvider.Meta().(*Config)
|
|
|
|
for _, s := range oobServices {
|
|
|
|
enableService(s, pid, config)
|
|
|
|
}
|
|
|
|
},
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProjectAssociateServicesBasic(services, pid, pname, org),
|
2016-11-23 06:55:40 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testProjectServicesMatch(services, pid),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-04-27 20:00:54 +00:00
|
|
|
// Test that services that can't be enabled on their own (such as dataproc-control.googleapis.com)
|
|
|
|
// don't end up causing diffs when they are enabled as a side-effect of a different service's
|
|
|
|
// enablement.
|
2018-02-23 23:14:24 +00:00
|
|
|
func TestAccProjectServices_ignoreUnenablableServices(t *testing.T) {
|
2017-10-12 22:07:29 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-11-20 23:45:51 +00:00
|
|
|
org := getTestOrgFromEnv(t)
|
|
|
|
billingId := getTestBillingAccountFromEnv(t)
|
2017-04-27 20:00:54 +00:00
|
|
|
pid := "terraform-" + acctest.RandString(10)
|
|
|
|
services := []string{
|
|
|
|
"dataproc.googleapis.com",
|
|
|
|
// The following services are enabled as a side-effect of dataproc's enablement
|
|
|
|
"storage-component.googleapis.com",
|
|
|
|
"deploymentmanager.googleapis.com",
|
|
|
|
"replicapool.googleapis.com",
|
|
|
|
"replicapoolupdater.googleapis.com",
|
|
|
|
"resourceviews.googleapis.com",
|
2017-08-03 17:58:58 +00:00
|
|
|
"compute.googleapis.com",
|
2017-04-27 20:00:54 +00:00
|
|
|
"container.googleapis.com",
|
2017-05-03 21:29:48 +00:00
|
|
|
"containerregistry.googleapis.com",
|
2017-04-27 20:00:54 +00:00
|
|
|
"storage-api.googleapis.com",
|
2017-05-03 21:29:48 +00:00
|
|
|
"pubsub.googleapis.com",
|
2018-05-10 17:02:31 +00:00
|
|
|
"oslogin.googleapis.com",
|
2018-05-23 00:45:22 +00:00
|
|
|
"bigquery-json.googleapis.com",
|
2017-04-27 20:00:54 +00:00
|
|
|
}
|
|
|
|
|
2017-05-01 23:33:51 +00:00
|
|
|
resource.Test(t, resource.TestCase{
|
|
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
|
|
Providers: testAccProviders,
|
|
|
|
Steps: []resource.TestStep{
|
|
|
|
resource.TestStep{
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProjectAssociateServicesBasic_withBilling(services, pid, pname, org, billingId),
|
2017-05-01 23:33:51 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testProjectServicesMatch(services, pid),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-07-12 17:26:48 +00:00
|
|
|
func TestAccProjectServices_pagination(t *testing.T) {
|
2017-10-12 22:07:29 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-11-20 23:45:51 +00:00
|
|
|
org := getTestOrgFromEnv(t)
|
|
|
|
billingId := getTestBillingAccountFromEnv(t)
|
2017-05-01 23:33:51 +00:00
|
|
|
pid := "terraform-" + acctest.RandString(10)
|
2018-07-12 17:26:48 +00:00
|
|
|
|
|
|
|
// we need at least 50 services (doesn't matter what they are) to exercise the
|
|
|
|
// pagination handling code.
|
2017-05-01 23:33:51 +00:00
|
|
|
services := []string{
|
2018-07-12 13:04:09 +00:00
|
|
|
"actions.googleapis.com",
|
|
|
|
"appengine.googleapis.com",
|
|
|
|
"appengineflex.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"bigquery-json.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"bigquerydatatransfer.googleapis.com",
|
|
|
|
"bigtableadmin.googleapis.com",
|
|
|
|
"bigtabletableadmin.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"cloudbuild.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"clouderrorreporting.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"cloudfunctions.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"cloudiot.googleapis.com",
|
|
|
|
"cloudkms.googleapis.com",
|
|
|
|
"cloudmonitoring.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"cloudresourcemanager.googleapis.com",
|
|
|
|
"cloudtrace.googleapis.com",
|
2017-08-03 17:58:58 +00:00
|
|
|
"compute.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"container.googleapis.com",
|
|
|
|
"containerregistry.googleapis.com",
|
|
|
|
"dataflow.googleapis.com",
|
|
|
|
"dataproc.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"datastore.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"deploymentmanager.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"dialogflow.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"dns.googleapis.com",
|
|
|
|
"endpoints.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"firebaserules.googleapis.com",
|
|
|
|
"firestore.googleapis.com",
|
|
|
|
"genomics.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"iam.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"language.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"logging.googleapis.com",
|
|
|
|
"ml.googleapis.com",
|
|
|
|
"monitoring.googleapis.com",
|
2018-05-10 17:02:31 +00:00
|
|
|
"oslogin.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"pubsub.googleapis.com",
|
|
|
|
"replicapool.googleapis.com",
|
|
|
|
"replicapoolupdater.googleapis.com",
|
|
|
|
"resourceviews.googleapis.com",
|
|
|
|
"runtimeconfig.googleapis.com",
|
|
|
|
"servicecontrol.googleapis.com",
|
|
|
|
"servicemanagement.googleapis.com",
|
|
|
|
"sourcerepo.googleapis.com",
|
|
|
|
"spanner.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"speech.googleapis.com",
|
|
|
|
"sql-component.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
"storage-api.googleapis.com",
|
|
|
|
"storage-component.googleapis.com",
|
2018-07-12 13:04:09 +00:00
|
|
|
"storagetransfer.googleapis.com",
|
|
|
|
"testing.googleapis.com",
|
|
|
|
"toolresults.googleapis.com",
|
|
|
|
"translate.googleapis.com",
|
|
|
|
"videointelligence.googleapis.com",
|
|
|
|
"vision.googleapis.com",
|
|
|
|
"zync.googleapis.com",
|
2017-05-01 23:33:51 +00:00
|
|
|
}
|
|
|
|
|
2017-04-27 20:00:54 +00:00
|
|
|
resource.Test(t, resource.TestCase{
|
|
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
|
|
Providers: testAccProviders,
|
|
|
|
Steps: []resource.TestStep{
|
|
|
|
resource.TestStep{
|
2018-02-23 23:14:24 +00:00
|
|
|
Config: testAccProjectAssociateServicesBasic_withBilling(services, pid, pname, org, billingId),
|
2017-04-27 20:00:54 +00:00
|
|
|
Check: resource.ComposeTestCheckFunc(
|
|
|
|
testProjectServicesMatch(services, pid),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-02-23 23:14:24 +00:00
|
|
|
func testAccProjectAssociateServicesBasic(services []string, pid, name, org string) string {
|
2016-11-23 06:55:40 +00:00
|
|
|
return fmt.Sprintf(`
|
|
|
|
resource "google_project" "acceptance" {
|
|
|
|
project_id = "%s"
|
2018-04-04 23:20:13 +00:00
|
|
|
name = "%s"
|
|
|
|
org_id = "%s"
|
2016-11-23 06:55:40 +00:00
|
|
|
}
|
|
|
|
resource "google_project_services" "acceptance" {
|
2018-04-05 20:32:26 +00:00
|
|
|
project = "${google_project.acceptance.project_id}"
|
|
|
|
services = [%s]
|
|
|
|
disable_on_destroy = true
|
2016-11-23 06:55:40 +00:00
|
|
|
}
|
|
|
|
`, pid, name, org, testStringsToString(services))
|
|
|
|
}
|
|
|
|
|
2018-02-23 23:14:24 +00:00
|
|
|
func testAccProjectAssociateServicesBasic_withBilling(services []string, pid, name, org, billing string) string {
|
2017-04-27 20:00:54 +00:00
|
|
|
return fmt.Sprintf(`
|
|
|
|
resource "google_project" "acceptance" {
|
2018-04-04 23:20:13 +00:00
|
|
|
project_id = "%s"
|
|
|
|
name = "%s"
|
|
|
|
org_id = "%s"
|
2017-04-27 20:00:54 +00:00
|
|
|
billing_account = "%s"
|
|
|
|
}
|
|
|
|
resource "google_project_services" "acceptance" {
|
2018-04-04 23:20:13 +00:00
|
|
|
project = "${google_project.acceptance.project_id}"
|
|
|
|
services = [%s]
|
|
|
|
disable_on_destroy = false
|
2017-04-27 20:00:54 +00:00
|
|
|
}
|
|
|
|
`, pid, name, org, billing, testStringsToString(services))
|
|
|
|
}
|
|
|
|
|
2016-11-23 06:55:40 +00:00
|
|
|
func testProjectServicesMatch(services []string, pid string) resource.TestCheckFunc {
|
|
|
|
return func(s *terraform.State) error {
|
|
|
|
config := testAccProvider.Meta().(*Config)
|
|
|
|
|
2017-11-07 23:19:57 +00:00
|
|
|
apiServices, err := getApiServices(pid, config, ignoreProjectServices)
|
2016-11-23 06:55:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error listing services for project %q: %v", pid, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sort.Strings(services)
|
|
|
|
sort.Strings(apiServices)
|
|
|
|
if !reflect.DeepEqual(services, apiServices) {
|
|
|
|
return fmt.Errorf("Services in config (%v) do not exactly match services returned by API (%v)", services, apiServices)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testStringsToString(s []string) string {
|
|
|
|
var b bytes.Buffer
|
|
|
|
for i, v := range s {
|
|
|
|
b.WriteString(fmt.Sprintf("\"%s\"", v))
|
|
|
|
if i < len(s)-1 {
|
|
|
|
b.WriteString(",")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
r := b.String()
|
|
|
|
log.Printf("[DEBUG]: Converted list of strings to %s", r)
|
|
|
|
return b.String()
|
|
|
|
}
|