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 disable_dependent_services to google_project_service resource. #2938

Merged
merged 1 commit into from
Jan 28, 2019
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
4 changes: 2 additions & 2 deletions google/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import (
redis "google.golang.org/api/redis/v1beta1"
runtimeconfig "google.golang.org/api/runtimeconfig/v1beta1"
"google.golang.org/api/servicemanagement/v1"
serviceusage "google.golang.org/api/serviceusage/v1beta1"
"google.golang.org/api/serviceusage/v1"
"google.golang.org/api/sourcerepo/v1"
"google.golang.org/api/spanner/v1"
sqladmin "google.golang.org/api/sqladmin/v1beta4"
Expand Down Expand Up @@ -86,7 +86,7 @@ type Config struct {
clientSqlAdmin *sqladmin.Service
clientIAM *iam.Service
clientServiceMan *servicemanagement.APIService
clientServiceUsage *serviceusage.APIService
clientServiceUsage *serviceusage.Service
clientBigQuery *bigquery.Service
clientCloudFunctions *cloudfunctions.Service
clientCloudIoT *cloudiot.Service
Expand Down
8 changes: 7 additions & 1 deletion google/resource_google_project_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ func resourceGoogleProjectService() *schema.Resource {
Computed: true,
ForceNew: true,
},

"disable_dependent_services": {
Type: schema.TypeBool,
Optional: true,
},

"disable_on_destroy": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -120,7 +126,7 @@ func resourceGoogleProjectServiceDelete(d *schema.ResourceData, meta interface{}
return nil
}

if err = disableService(id.service, id.project, config); err != nil {
if err = disableService(id.service, id.project, config, d.Get("disable_dependent_services").(bool)); err != nil {
return fmt.Errorf("Error disabling service: %s", err)
}

Expand Down
77 changes: 77 additions & 0 deletions google/resource_google_project_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package google

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
Expand Down Expand Up @@ -63,6 +64,46 @@ func TestAccProjectService_basic(t *testing.T) {
})
}

func TestAccProjectService_disableDependentServices(t *testing.T) {
t.Parallel()

org := getTestOrgFromEnv(t)
pid := "terraform-" + acctest.RandString(10)
services := []string{"cloudbuild.googleapis.com", "containerregistry.googleapis.com"}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccProjectService_disableDependentServices(services, pid, pname, org, "false"),
},
{
ResourceName: "google_project_service.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"disable_on_destroy"},
},
{
Config: testAccProjectService_dependencyRemoved(services, pid, pname, org),
ExpectError: regexp.MustCompile("Please specify disable_dependent_services=true if you want to proceed with disabling all services."),
},
{
Config: testAccProjectService_disableDependentServices(services, pid, pname, org, "true"),
},
{
ResourceName: "google_project_service.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"disable_on_destroy"},
},
{
Config: testAccProjectService_dependencyRemoved(services, pid, pname, org),
ExpectNonEmptyPlan: true,
},
},
})
}

func TestAccProjectService_handleNotFound(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -136,6 +177,42 @@ resource "google_project_service" "test2" {
`, pid, name, org, services[0], services[1])
}

func testAccProjectService_disableDependentServices(services []string, pid, name, org, disableDependentServices string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
project_id = "%s"
name = "%s"
org_id = "%s"
}

resource "google_project_service" "test" {
project = "${google_project.acceptance.project_id}"
service = "%s"
}

resource "google_project_service" "test2" {
project = "${google_project.acceptance.project_id}"
service = "%s"
disable_dependent_services = %s
}
`, pid, name, org, services[0], services[1], disableDependentServices)
}

func testAccProjectService_dependencyRemoved(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_service" "test" {
project = "${google_project.acceptance.project_id}"
service = "%s"
}
`, pid, name, org, services[0])
}

func testAccProjectService_noDisable(services []string, pid, name, org string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
Expand Down
25 changes: 16 additions & 9 deletions google/resource_google_project_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import (
"context"
"fmt"
"log"
"sort"
"strings"

"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/googleapi"
"google.golang.org/api/serviceusage/v1beta1"
"google.golang.org/api/serviceusage/v1"
)

func resourceGoogleProjectServices() *schema.Resource {
Expand Down Expand Up @@ -129,7 +130,7 @@ func resourceGoogleProjectServicesDelete(d *schema.ResourceData, meta interface{
config := meta.(*Config)
services := resourceServices(d)
for _, s := range services {
disableService(s, d.Id(), config)
disableService(s, d.Id(), config, true)
}
d.SetId("")
return nil
Expand All @@ -148,19 +149,21 @@ func reconcileServices(cfgServices, apiServices []string, config *Config, pid st
return sm
}

sort.Strings(cfgServices)
cfgMap := m(cfgServices)
log.Printf("[DEBUG]: Saw the following services in config: %v", cfgServices)
apiMap := m(apiServices)
log.Printf("[DEBUG]: Saw the following services enabled: %v", apiServices)

for k := range apiMap {
if _, ok := cfgMap[k]; !ok {
// The service in the API is not in the config; disable it.
err := disableService(k, pid, config)
log.Printf("[DEBUG]: Disabling %s as it's enabled upstream but not in config", k)
err := disableService(k, pid, config, true)
if err != nil {
return err
}
} else {
// The service exists in the config and the API, so we don't need
// to re-enable it
log.Printf("[DEBUG]: Skipping %s as it's enabled in both config and upstream", k)
delete(cfgMap, k)
}
}
Expand All @@ -169,6 +172,8 @@ func reconcileServices(cfgServices, apiServices []string, config *Config, pid st
for k := range cfgMap {
keys = append(keys, k)
}
sort.Strings(keys)
log.Printf("[DEBUG]: Enabling the following services: %v", keys)
err := enableServices(keys, pid, config)
if err != nil {
return err
Expand Down Expand Up @@ -233,7 +238,7 @@ func enableServices(s []string, pid string, config *Config) error {
// It's not permitted to enable more than 20 services in one API call (even
// for batch).
//
// https://godoc.org/google.golang.org/api/serviceusage/v1beta1#BatchEnableServicesRequest
// https://godoc.org/google.golang.org/api/serviceusage/v1#BatchEnableServicesRequest
batchSize := 20

for i := 0; i < len(s); i += batchSize {
Expand Down Expand Up @@ -334,10 +339,12 @@ func diffStringSlice(wanted, actual []string) []string {
return missing
}

func disableService(s, pid string, config *Config) error {
func disableService(s, pid string, config *Config, disableDependentServices bool) error {
err := retryTime(func() error {
name := fmt.Sprintf("projects/%s/services/%s", pid, s)
sop, err := config.clientServiceUsage.Services.Disable(name, &serviceusage.DisableServiceRequest{}).Do()
sop, err := config.clientServiceUsage.Services.Disable(name, &serviceusage.DisableServiceRequest{
DisableDependentServices: disableDependentServices,
}).Do()
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions google/serviceusage_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package google
import (
"fmt"

serviceusage "google.golang.org/api/serviceusage/v1beta1"
"google.golang.org/api/serviceusage/v1"
)

type ServiceUsageOperationWaiter struct {
Service *serviceusage.APIService
Service *serviceusage.Service
CommonOperationWaiter
}

Expand Down
Loading