mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-20 11:48:24 -06:00
Add support for creating, updating, and deleting projects, as well as their enabled services and their IAM policies. Various concessions were made for backwards compatibility, and will be removed in 0.9 or 0.10.
179 lines
5.4 KiB
Go
179 lines
5.4 KiB
Go
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"
|
|
"google.golang.org/api/servicemanagement/v1"
|
|
)
|
|
|
|
// Test that services can be enabled and disabled on a project
|
|
func TestAccGoogleProjectServices_basic(t *testing.T) {
|
|
pid := "terraform-" + acctest.RandString(10)
|
|
services1 := []string{"iam.googleapis.com", "cloudresourcemanager.googleapis.com"}
|
|
services2 := []string{"cloudresourcemanager.googleapis.com"}
|
|
oobService := "iam.googleapis.com"
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
Providers: testAccProviders,
|
|
Steps: []resource.TestStep{
|
|
// Create a new project with some services
|
|
resource.TestStep{
|
|
Config: testAccGoogleProjectAssociateServicesBasic(services1, pid, pname, org),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testProjectServicesMatch(services1, pid),
|
|
),
|
|
},
|
|
// Update services to remove one
|
|
resource.TestStep{
|
|
Config: testAccGoogleProjectAssociateServicesBasic(services2, pid, pname, org),
|
|
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)
|
|
},
|
|
Config: testAccGoogleProjectAssociateServicesBasic(services2, pid, pname, org),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testProjectServicesMatch(services2, pid),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
// Test that services are authoritative when a project has existing
|
|
// sevices not represented in config
|
|
func TestAccGoogleProjectServices_authoritative(t *testing.T) {
|
|
pid := "terraform-" + acctest.RandString(10)
|
|
services := []string{"cloudresourcemanager.googleapis.com"}
|
|
oobService := "iam.googleapis.com"
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
Providers: testAccProviders,
|
|
Steps: []resource.TestStep{
|
|
// Create a new project with no services
|
|
resource.TestStep{
|
|
Config: testAccGoogleProject_create(pid, pname, org),
|
|
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)
|
|
},
|
|
Config: testAccGoogleProjectAssociateServicesBasic(services, pid, pname, org),
|
|
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
|
|
func TestAccGoogleProjectServices_authoritative2(t *testing.T) {
|
|
pid := "terraform-" + acctest.RandString(10)
|
|
oobServices := []string{"iam.googleapis.com", "cloudresourcemanager.googleapis.com"}
|
|
services := []string{"iam.googleapis.com"}
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
Providers: testAccProviders,
|
|
Steps: []resource.TestStep{
|
|
// Create a new project with no services
|
|
resource.TestStep{
|
|
Config: testAccGoogleProject_create(pid, pname, org),
|
|
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)
|
|
}
|
|
},
|
|
Config: testAccGoogleProjectAssociateServicesBasic(services, pid, pname, org),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testProjectServicesMatch(services, pid),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func testAccGoogleProjectAssociateServicesBasic(services []string, pid, name, org string) string {
|
|
return fmt.Sprintf(`
|
|
resource "google_project" "acceptance" {
|
|
project_id = "%s"
|
|
name = "%s"
|
|
org_id = "%s"
|
|
}
|
|
resource "google_project_services" "acceptance" {
|
|
project = "${google_project.acceptance.project_id}"
|
|
services = [%s]
|
|
}
|
|
`, pid, name, org, testStringsToString(services))
|
|
}
|
|
|
|
func testProjectServicesMatch(services []string, pid string) resource.TestCheckFunc {
|
|
return func(s *terraform.State) error {
|
|
config := testAccProvider.Meta().(*Config)
|
|
|
|
apiServices, err := getApiServices(pid, config)
|
|
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()
|
|
}
|
|
|
|
func testManagedServicesToString(svcs []*servicemanagement.ManagedService) string {
|
|
var b bytes.Buffer
|
|
for _, s := range svcs {
|
|
b.WriteString(s.ServiceName)
|
|
}
|
|
return b.String()
|
|
}
|