github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/google/resource_google_project_services_test.go (about)

     1  package google
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"os"
     8  	"reflect"
     9  	"sort"
    10  	"testing"
    11  
    12  	"github.com/hashicorp/terraform/helper/acctest"
    13  	"github.com/hashicorp/terraform/helper/resource"
    14  	"github.com/hashicorp/terraform/terraform"
    15  	"google.golang.org/api/servicemanagement/v1"
    16  )
    17  
    18  // Test that services can be enabled and disabled on a project
    19  func TestAccGoogleProjectServices_basic(t *testing.T) {
    20  	pid := "terraform-" + acctest.RandString(10)
    21  	services1 := []string{"iam.googleapis.com", "cloudresourcemanager.googleapis.com"}
    22  	services2 := []string{"cloudresourcemanager.googleapis.com"}
    23  	oobService := "iam.googleapis.com"
    24  	resource.Test(t, resource.TestCase{
    25  		PreCheck:  func() { testAccPreCheck(t) },
    26  		Providers: testAccProviders,
    27  		Steps: []resource.TestStep{
    28  			// Create a new project with some services
    29  			resource.TestStep{
    30  				Config: testAccGoogleProjectAssociateServicesBasic(services1, pid, pname, org),
    31  				Check: resource.ComposeTestCheckFunc(
    32  					testProjectServicesMatch(services1, pid),
    33  				),
    34  			},
    35  			// Update services to remove one
    36  			resource.TestStep{
    37  				Config: testAccGoogleProjectAssociateServicesBasic(services2, pid, pname, org),
    38  				Check: resource.ComposeTestCheckFunc(
    39  					testProjectServicesMatch(services2, pid),
    40  				),
    41  			},
    42  			// Add a service out-of-band and ensure it is removed
    43  			resource.TestStep{
    44  				PreConfig: func() {
    45  					config := testAccProvider.Meta().(*Config)
    46  					enableService(oobService, pid, config)
    47  				},
    48  				Config: testAccGoogleProjectAssociateServicesBasic(services2, pid, pname, org),
    49  				Check: resource.ComposeTestCheckFunc(
    50  					testProjectServicesMatch(services2, pid),
    51  				),
    52  			},
    53  		},
    54  	})
    55  }
    56  
    57  // Test that services are authoritative when a project has existing
    58  // sevices not represented in config
    59  func TestAccGoogleProjectServices_authoritative(t *testing.T) {
    60  	pid := "terraform-" + acctest.RandString(10)
    61  	services := []string{"cloudresourcemanager.googleapis.com"}
    62  	oobService := "iam.googleapis.com"
    63  	resource.Test(t, resource.TestCase{
    64  		PreCheck:  func() { testAccPreCheck(t) },
    65  		Providers: testAccProviders,
    66  		Steps: []resource.TestStep{
    67  			// Create a new project with no services
    68  			resource.TestStep{
    69  				Config: testAccGoogleProject_create(pid, pname, org),
    70  				Check: resource.ComposeTestCheckFunc(
    71  					testAccCheckGoogleProjectExists("google_project.acceptance", pid),
    72  				),
    73  			},
    74  			// Add a service out-of-band, then apply a config that creates a service.
    75  			// It should remove the out-of-band service.
    76  			resource.TestStep{
    77  				PreConfig: func() {
    78  					config := testAccProvider.Meta().(*Config)
    79  					enableService(oobService, pid, config)
    80  				},
    81  				Config: testAccGoogleProjectAssociateServicesBasic(services, pid, pname, org),
    82  				Check: resource.ComposeTestCheckFunc(
    83  					testProjectServicesMatch(services, pid),
    84  				),
    85  			},
    86  		},
    87  	})
    88  }
    89  
    90  // Test that services are authoritative when a project has existing
    91  // sevices, some which are represented in the config and others
    92  // that are not
    93  func TestAccGoogleProjectServices_authoritative2(t *testing.T) {
    94  	pid := "terraform-" + acctest.RandString(10)
    95  	oobServices := []string{"iam.googleapis.com", "cloudresourcemanager.googleapis.com"}
    96  	services := []string{"iam.googleapis.com"}
    97  
    98  	resource.Test(t, resource.TestCase{
    99  		PreCheck:  func() { testAccPreCheck(t) },
   100  		Providers: testAccProviders,
   101  		Steps: []resource.TestStep{
   102  			// Create a new project with no services
   103  			resource.TestStep{
   104  				Config: testAccGoogleProject_create(pid, pname, org),
   105  				Check: resource.ComposeTestCheckFunc(
   106  					testAccCheckGoogleProjectExists("google_project.acceptance", pid),
   107  				),
   108  			},
   109  			// Add a service out-of-band, then apply a config that creates a service.
   110  			// It should remove the out-of-band service.
   111  			resource.TestStep{
   112  				PreConfig: func() {
   113  					config := testAccProvider.Meta().(*Config)
   114  					for _, s := range oobServices {
   115  						enableService(s, pid, config)
   116  					}
   117  				},
   118  				Config: testAccGoogleProjectAssociateServicesBasic(services, pid, pname, org),
   119  				Check: resource.ComposeTestCheckFunc(
   120  					testProjectServicesMatch(services, pid),
   121  				),
   122  			},
   123  		},
   124  	})
   125  }
   126  
   127  // Test that services that can't be enabled on their own (such as dataproc-control.googleapis.com)
   128  // don't end up causing diffs when they are enabled as a side-effect of a different service's
   129  // enablement.
   130  func TestAccGoogleProjectServices_ignoreUnenablableServices(t *testing.T) {
   131  	skipIfEnvNotSet(t,
   132  		[]string{
   133  			"GOOGLE_ORG",
   134  			"GOOGLE_BILLING_ACCOUNT",
   135  		}...,
   136  	)
   137  
   138  	billingId := os.Getenv("GOOGLE_BILLING_ACCOUNT")
   139  	pid := "terraform-" + acctest.RandString(10)
   140  	services := []string{
   141  		"dataproc.googleapis.com",
   142  		// The following services are enabled as a side-effect of dataproc's enablement
   143  		"storage-component.googleapis.com",
   144  		"deploymentmanager.googleapis.com",
   145  		"replicapool.googleapis.com",
   146  		"replicapoolupdater.googleapis.com",
   147  		"resourceviews.googleapis.com",
   148  		"compute-component.googleapis.com",
   149  		"container.googleapis.com",
   150  		"containerregistry.googleapis.com",
   151  		"storage-api.googleapis.com",
   152  		"pubsub.googleapis.com",
   153  	}
   154  
   155  	resource.Test(t, resource.TestCase{
   156  		PreCheck:  func() { testAccPreCheck(t) },
   157  		Providers: testAccProviders,
   158  		Steps: []resource.TestStep{
   159  			resource.TestStep{
   160  				Config: testAccGoogleProjectAssociateServicesBasic_withBilling(services, pid, pname, org, billingId),
   161  				Check: resource.ComposeTestCheckFunc(
   162  					testProjectServicesMatch(services, pid),
   163  				),
   164  			},
   165  		},
   166  	})
   167  }
   168  
   169  func TestAccGoogleProjectServices_manyServices(t *testing.T) {
   170  	skipIfEnvNotSet(t,
   171  		[]string{
   172  			"GOOGLE_ORG",
   173  			"GOOGLE_BILLING_ACCOUNT",
   174  		}...,
   175  	)
   176  
   177  	billingId := os.Getenv("GOOGLE_BILLING_ACCOUNT")
   178  	pid := "terraform-" + acctest.RandString(10)
   179  	services := []string{
   180  		"bigquery-json.googleapis.com",
   181  		"cloudbuild.googleapis.com",
   182  		"cloudfunctions.googleapis.com",
   183  		"cloudresourcemanager.googleapis.com",
   184  		"cloudtrace.googleapis.com",
   185  		"compute-component.googleapis.com",
   186  		"container.googleapis.com",
   187  		"containerregistry.googleapis.com",
   188  		"dataflow.googleapis.com",
   189  		"dataproc.googleapis.com",
   190  		"deploymentmanager.googleapis.com",
   191  		"dns.googleapis.com",
   192  		"endpoints.googleapis.com",
   193  		"iam.googleapis.com",
   194  		"logging.googleapis.com",
   195  		"ml.googleapis.com",
   196  		"monitoring.googleapis.com",
   197  		"pubsub.googleapis.com",
   198  		"replicapool.googleapis.com",
   199  		"replicapoolupdater.googleapis.com",
   200  		"resourceviews.googleapis.com",
   201  		"runtimeconfig.googleapis.com",
   202  		"servicecontrol.googleapis.com",
   203  		"servicemanagement.googleapis.com",
   204  		"sourcerepo.googleapis.com",
   205  		"spanner.googleapis.com",
   206  		"storage-api.googleapis.com",
   207  		"storage-component.googleapis.com",
   208  	}
   209  
   210  	resource.Test(t, resource.TestCase{
   211  		PreCheck:  func() { testAccPreCheck(t) },
   212  		Providers: testAccProviders,
   213  		Steps: []resource.TestStep{
   214  			resource.TestStep{
   215  				Config: testAccGoogleProjectAssociateServicesBasic_withBilling(services, pid, pname, org, billingId),
   216  				Check: resource.ComposeTestCheckFunc(
   217  					testProjectServicesMatch(services, pid),
   218  				),
   219  			},
   220  		},
   221  	})
   222  }
   223  
   224  func testAccGoogleProjectAssociateServicesBasic(services []string, pid, name, org string) string {
   225  	return fmt.Sprintf(`
   226  resource "google_project" "acceptance" {
   227    project_id = "%s"
   228    name = "%s"
   229    org_id = "%s"
   230  }
   231  resource "google_project_services" "acceptance" {
   232    project = "${google_project.acceptance.project_id}"
   233    services = [%s]
   234  }
   235  `, pid, name, org, testStringsToString(services))
   236  }
   237  
   238  func testAccGoogleProjectAssociateServicesBasic_withBilling(services []string, pid, name, org, billing string) string {
   239  	return fmt.Sprintf(`
   240  resource "google_project" "acceptance" {
   241    project_id = "%s"
   242    name = "%s"
   243    org_id = "%s"
   244    billing_account = "%s"
   245  }
   246  resource "google_project_services" "acceptance" {
   247    project = "${google_project.acceptance.project_id}"
   248    services = [%s]
   249  }
   250  `, pid, name, org, billing, testStringsToString(services))
   251  }
   252  
   253  func testProjectServicesMatch(services []string, pid string) resource.TestCheckFunc {
   254  	return func(s *terraform.State) error {
   255  		config := testAccProvider.Meta().(*Config)
   256  
   257  		apiServices, err := getApiServices(pid, config)
   258  		if err != nil {
   259  			return fmt.Errorf("Error listing services for project %q: %v", pid, err)
   260  		}
   261  
   262  		sort.Strings(services)
   263  		sort.Strings(apiServices)
   264  		if !reflect.DeepEqual(services, apiServices) {
   265  			return fmt.Errorf("Services in config (%v) do not exactly match services returned by API (%v)", services, apiServices)
   266  		}
   267  
   268  		return nil
   269  	}
   270  }
   271  
   272  func testStringsToString(s []string) string {
   273  	var b bytes.Buffer
   274  	for i, v := range s {
   275  		b.WriteString(fmt.Sprintf("\"%s\"", v))
   276  		if i < len(s)-1 {
   277  			b.WriteString(",")
   278  		}
   279  	}
   280  	r := b.String()
   281  	log.Printf("[DEBUG]: Converted list of strings to %s", r)
   282  	return b.String()
   283  }
   284  
   285  func testManagedServicesToString(svcs []*servicemanagement.ManagedService) string {
   286  	var b bytes.Buffer
   287  	for _, s := range svcs {
   288  		b.WriteString(s.ServiceName)
   289  	}
   290  	return b.String()
   291  }