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 Active Directory to Cloud SQL #5988

Merged
merged 39 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f683562
Add SQL Active Directory Config sub-block to settings
priyam1011 Apr 26, 2022
d4375f3
Add active directory fixes & add audit config
priyam1011 Apr 27, 2022
5be201f
Remove unwanted fields and update markdown
priyam1011 Apr 27, 2022
fe287be
Make upload and retention interval optional
priyam1011 Apr 27, 2022
8c6b42b
Update go.sum and minor test fix
priyam1011 Apr 27, 2022
56bc765
Fix google api dependency update issue
priyam1011 Apr 28, 2022
a5f22b5
Fix typo in testGoogleSqlDatabaseInstance_ActiveDirectoryConfig
priyam1011 Apr 28, 2022
7d09f1a
Fix for retentionalInterval casing and for required fields
priyam1011 Apr 28, 2022
0b94d21
Fix AtLeastOneOf and Required related errors
priyam1011 Apr 28, 2022
e2167d8
Fix active directory test - 1
priyam1011 Apr 29, 2022
4968075
Fix spacing & active directory test
priyam1011 Apr 29, 2022
aaddb6f
Fix active directory test - 2
priyam1011 Apr 29, 2022
f0209f6
Debug private ip failure
priyam1011 Apr 29, 2022
58b5083
Fix active directory test - 3
priyam1011 Apr 30, 2022
7308e3d
Fix activeDirectory test & remove audit changes
priyam1011 Apr 30, 2022
43d7a58
Fix test - Add missing fields in tf resource
priyam1011 May 1, 2022
09549f9
Fix spacing & rerun test
priyam1011 May 2, 2022
8e39cdd
Test network peering error
priyam1011 May 2, 2022
2901458
Test AD with default network & update markdown
priyam1011 May 3, 2022
4c502b0
Fix lint errors
priyam1011 May 3, 2022
ad4e87c
Add AD domain resource creation in test & revert to tf created network
priyam1011 May 3, 2022
96af952
Fix lint error
priyam1011 May 3, 2022
888aab3
Remove unused variables
priyam1011 May 3, 2022
1d6c085
Fix reserved_ip_range field error
priyam1011 May 3, 2022
03246ec
Add authorized network to AD domain
priyam1011 May 4, 2022
b7eb04b
Revert go.sum & go.mod.erb changes as they are not needed for active …
priyam1011 May 4, 2022
88e707b
Fix authorized_networks field in AD domain
priyam1011 May 4, 2022
cce507f
Test run with existing AD ad.domain.com
priyam1011 May 6, 2022
be9bb85
Fix addressRangeName field
priyam1011 May 6, 2022
89f4be7
Add AD bootstrap logic & use separate network
priyam1011 May 6, 2022
75e9499
Add newline to rerun failing generate-diff step
priyam1011 May 6, 2022
79c1980
Revert "Add newline to rerun failing generate-diff step"
priyam1011 May 6, 2022
4131783
Revert "Add AD bootstrap logic & use separate network"
priyam1011 May 6, 2022
9e35cde
Reapply AD bootstrap & test changes
priyam1011 May 6, 2022
30c7d69
AD bootstrap - Comment 60 min wait & rerun to test using existing AD …
priyam1011 May 6, 2022
90b69b2
Fix test ResourceName
priyam1011 May 9, 2022
c9b1146
Fixed formatting
priyam1011 May 10, 2022
d1f4e2c
Update mmv1/third_party/terraform/resources/resource_sql_database_ins…
c2thorn May 10, 2022
e93449c
Add missing comma in active directory block
priyam1011 May 10, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,20 @@ func resourceSqlDatabaseInstance() *schema.Resource {
Default: "ALWAYS",
Description: `This specifies when the instance should be active. Can be either ALWAYS, NEVER or ON_DEMAND.`,
},
"active_directory_config": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain": {
Type: schema.TypeString,
Required: true,
Description: `Domain name of the Active Directory for SQL Server (e.g., mydomain.com).`,
},
},
},
},
"availability_type": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -969,6 +983,7 @@ func expandSqlDatabaseInstanceSettings(configured []interface{}) *sqladmin.Setti
Tier: _settings["tier"].(string),
ForceSendFields: []string{"StorageAutoResize"},
ActivationPolicy: _settings["activation_policy"].(string),
ActiveDirectoryConfig: expandActiveDirectoryConfig(_settings["active_directory_config"].([]interface{})),
AvailabilityType: _settings["availability_type"].(string),
Collation: _settings["collation"].(string),
DataDiskSizeGb: int64(_settings["disk_size"].(int)),
Expand Down Expand Up @@ -1131,6 +1146,18 @@ func expandBackupRetentionSettings(configured interface{}) *sqladmin.BackupReten
}
}

func expandActiveDirectoryConfig(configured interface{}) *sqladmin.SqlActiveDirectoryConfig {
l := configured.([]interface{})
if len(l) == 0 {
return nil
}

config := l[0].(map[string]interface{})
return &sqladmin.SqlActiveDirectoryConfig{
Domain: config["domain"].(string),
}
}

func expandInsightsConfig(configured []interface{}) *sqladmin.InsightsConfig {
if len(configured) == 0 || configured[0] == nil {
return nil
Expand Down Expand Up @@ -1374,6 +1401,10 @@ func flattenSettings(settings *sqladmin.Settings) []map[string]interface{} {
"user_labels": settings.UserLabels,
}

if settings.ActiveDirectoryConfig != nil {
data["active_directory_config"] = flattenActiveDirectoryConfig(settings.ActiveDirectoryConfig)
}

if settings.BackupConfiguration != nil {
data["backup_configuration"] = flattenBackupConfiguration(settings.BackupConfiguration)
}
Expand Down Expand Up @@ -1434,6 +1465,16 @@ func flattenBackupRetentionSettings(b *sqladmin.BackupRetentionSettings) []map[s
}
}

func flattenActiveDirectoryConfig(sqlActiveDirectoryConfig *sqladmin.SqlActiveDirectoryConfig) []map[string]interface{} {
if sqlActiveDirectoryConfig == nil {
return nil
}
return []map[string]interface{}{
{
"domain": sqlActiveDirectoryConfig.Domain,
},
}
}

func flattenDatabaseFlags(databaseFlags []*sqladmin.DatabaseFlags) []map[string]interface{} {
flags := make([]map[string]interface{}, 0, len(databaseFlags))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,32 @@ func TestAccSqlDatabaseInstance_encryptionKey(t *testing.T) {
}
<% end -%>

func TestAccSqlDatabaseInstance_ActiveDirectory(t *testing.T) {
t.Parallel()
databaseName := "tf-test-" + randString(t, 10)
networkName := BootstrapSharedTestNetwork(t, "sql-instance-private-test-ad")
addressName := "tf-test-" + randString(t, 10)
rootPassword := randString(t, 15)
adDomainName := BootstrapSharedTestADDomain(t, "test-domain", networkName)

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testGoogleSqlDatabaseInstance_ActiveDirectoryConfig(databaseName, networkName, addressName, rootPassword, adDomainName),
},
{
ResourceName: "google_sql_database_instance.instance-with-ad",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"root_password", "deletion_protection"},
},
},
})
}

var testGoogleSqlDatabaseInstance_basic2 = `
resource "google_sql_database_instance" "instance" {
region = "us-central1"
Expand Down Expand Up @@ -1099,6 +1125,47 @@ resource "google_sql_database_instance" "instance" {
}
`

func testGoogleSqlDatabaseInstance_ActiveDirectoryConfig(databaseName, networkName, addressRangeName, rootPassword, adDomainName string) string {
return fmt.Sprintf(`
data "google_compute_network" "servicenet" {
name = "%s"
}

resource "google_compute_global_address" "foobar" {
name = "%s"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = data.google_compute_network.servicenet.self_link
}

resource "google_service_networking_connection" "foobar" {
network = data.google_compute_network.servicenet.self_link
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.foobar.name]
}

resource "google_sql_database_instance" "instance-with-ad" {
depends_on = [google_service_networking_connection.foobar]
name = "%s"
region = "us-central1"
database_version = "SQLSERVER_2017_STANDARD"
root_password = "%s"
deletion_protection = false
settings {
tier = "db-custom-2-7680"
ip_configuration {
ipv4_enabled = "false"
private_network = data.google_compute_network.servicenet.self_link
}

active_directory_config {
domain = "%s"
}
}
}`, networkName, addressRangeName, databaseName, rootPassword, adDomainName)
}

func testGoogleSqlDatabaseInstanceConfig_withoutReplica(instanceName string) string {
return fmt.Sprintf(`
resource "google_sql_database_instance" "instance" {
Expand Down
41 changes: 41 additions & 0 deletions mmv1/third_party/terraform/utils/bootstrap_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,47 @@ func BootstrapServiceAccount(t *testing.T, project, testRunner string) string {
return sa.Email
}

const SharedTestADDomainPrefix = "tf-bootstrap-ad"

func BootstrapSharedTestADDomain(t *testing.T, testId string, networkName string) string {
project := getTestProjectFromEnv()
sharedADDomain := fmt.Sprintf("%s.%s.com", SharedTestADDomainPrefix, testId)
adDomainName := fmt.Sprintf("projects/%s/locations/global/domains/%s", project, sharedADDomain)

config := BootstrapConfig(t)
if config == nil {
return ""
}

log.Printf("[DEBUG] Getting shared test active directory domain %q", adDomainName)
getURL := fmt.Sprintf("%s%s", config.ActiveDirectoryBasePath, adDomainName)
_, err := sendRequestWithTimeout(config, "GET", project, getURL, config.userAgent, nil, 4*time.Minute)
if err != nil && isGoogleApiErrorWithCode(err, 404) {
log.Printf("[DEBUG] AD domain %q not found, bootstrapping", sharedADDomain)
postURL := fmt.Sprintf("%sprojects/%s/locations/global/domains?domainName=%s", config.ActiveDirectoryBasePath, project, sharedADDomain)
domainObj := map[string]interface{}{
"locations": []string{"us-central1"},
"reservedIpRange": "10.0.1.0/24",
"authorizedNetworks": []string{fmt.Sprintf("projects/%s/global/networks/%s", project, networkName)},
}

_, err := sendRequestWithTimeout(config, "POST", project, postURL, config.userAgent, domainObj, 60*time.Minute)
if err != nil {
t.Fatalf("Error bootstrapping shared active directory domain %q: %s", adDomainName, err)
}

log.Printf("[DEBUG] Waiting for active directory domain creation to finish")
}

_, err = sendRequestWithTimeout(config, "GET", project, getURL, config.userAgent, nil, 4*time.Minute)

if err != nil {
t.Fatalf("Error getting shared active directory domain %q: %s", adDomainName, err)
}

return sharedADDomain
}

const SharedTestNetworkPrefix = "tf-bootstrap-net-"

// BootstrapSharedTestNetwork will return a shared compute network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ The optional `settings.database_flags` sublist supports:

* `value` - (Required) Value of the flag.

The optional `settings.active_directory_config` subblock supports:

* `domain` - (Required) The domain name for the active directory (e.g., mydomain.com).
Can only be used with SQL Server.

The optional `settings.backup_configuration` subblock supports:

* `binary_log_enabled` - (Optional) True if binary logging is enabled.
Expand Down