Skip to content
This repository has been archived by the owner on Jul 6, 2022. It is now read-only.

Add VNET rules to PostgreSQL #676

Merged
merged 2 commits into from
Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions docs/modules/postgresql.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ name.
| `firewallRules[n].name` | `string` | Specifies the name of the generated firewall rule |Y | |
| `firewallRules[n].startIPAddress` | `string` | Specifies the start of the IP range allowed by this firewall rule | Y | |
| `firewallRules[n].endIPAddress` | `string` | Specifies the end of the IP range allowed by this firewall rule | Y | |
| `virtualNetworkRules` | `array` | Specifies the firewall rules to apply to the server. Definition follows. | N | `[]` Left unspecified, Firewall will default to only Azure IPs. If rules are provided, they must have valid values. |
| `virtualNetworkRules[n].name` | `string` | Specifies the name of the generated virtual network rule |Y | |
| `virtualNetworkRules[n].subnetId` | `string` | The full resource ID of a subnet in a virtual network to allow access from. Example format: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vn}/subnets/{sn} | Y | |
| `tags` | `map[string]string` | Tags to be applied to new resources, specified as key/value pairs. | N | Tags (even if none are specified) are automatically supplemented with `heritage: open-service-broker-azure`. |
| `extensions` | `string[]` | Specifies a list of PostgreSQL extensions to install | N | |

Expand Down
15 changes: 15 additions & 0 deletions pkg/services/postgresql/all_in_one_arm_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ var allInOneARMTemplateBytes = []byte(`
}
},
{{end}}
{{range .virtualNetworkRules}}
{
"type": "virtualNetworkRules",
"apiVersion": "[variables('DBforPostgreSQLapiVersion')]",
"dependsOn": [
"Microsoft.DBforPostgreSQL/servers/{{ $.serverName }}"
],
"location": "{{$root.location}}",
"name": "{{.name}}",
"properties": {
"ignoreMissingVnetServiceEndpoint": true,
"virtualNetworkSubnetId": "{{.subnetId}}"
}
},
{{end}}
{
"apiVersion": "[variables('DBforPostgreSQLapiVersion')]",
"name": "{{ .databaseName }}",
Expand Down
8 changes: 8 additions & 0 deletions pkg/services/postgresql/common_provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,13 @@ func buildGoTemplateParameters(
}
p["firewallRules"] = firewallRules

virtualNetworkRulesParams := pp.GetObjectArray("virtualNetworkRules")
virtualNetworkRules := make([]map[string]interface{},
len(virtualNetworkRulesParams))
for i, virtualNetworkRulesParams := range virtualNetworkRulesParams {
virtualNetworkRules[i] = virtualNetworkRulesParams.Data
}
p["virtualNetworkRules"] = virtualNetworkRules

return p, nil
}
20 changes: 18 additions & 2 deletions pkg/services/postgresql/dbms_arm_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ var dbmsARMTemplateBytes = []byte(`
"tags": "[parameters('tags')]",
"resources": [
{{ $root := . }}
{{$count := sub (len .firewallRules) 1}}
{{$firewallRulesCount := sub (len .firewallRules) 1}}
{{$virtualNetworkRulesCount := sub (len .virtualNetworkRules) 1 }}
{{range $i, $rule := .firewallRules}}
{
"type": "firewallrules",
Expand All @@ -57,7 +58,22 @@ var dbmsARMTemplateBytes = []byte(`
"startIpAddress": "{{$rule.startIPAddress}}",
"endIpAddress": "{{$rule.endIPAddress}}"
}
}{{if lt $i $count}},{{end}}
}{{ if or (lt $i $firewallRulesCount) (gt $virtualNetworkRulesCount -1) }},{{end}}
{{end}}
{{range $i, $rule := .virtualNetworkRules}}
{
"type": "virtualNetworkRules",
"apiVersion": "[variables('DBforPostgreSQLapiVersion')]",
"dependsOn": [
"Microsoft.DBforPostgreSQL/servers/{{ $.serverName }}"
],
"location": "{{$root.location}}",
"name": "{{$rule.name}}",
"properties": {
"ignoreMissingVnetServiceEndpoint": true,
"virtualNetworkSubnetId": "{{$rule.subnetId}}"
timja marked this conversation as resolved.
Show resolved Hide resolved
}
}{{if lt $i $virtualNetworkRulesCount}},{{end}}
{{end}}
]
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/services/postgresql/plan_schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,28 @@ func generateUpdatingParamsSchema(
},
},
},
"virtualNetworkRules": &service.ArrayPropertySchema{
Title: "Virtual network rules",
Description: "Virtual network rules to apply to instance. ",
ItemsSchema: &service.ObjectPropertySchema{
Title: "Virtual network rule",
Description: "Individual virtual network rules",
timja marked this conversation as resolved.
Show resolved Hide resolved
RequiredProperties: []string{
"name",
"subnetId",
},
PropertySchemas: map[string]service.PropertySchema{
"name": &service.StringPropertySchema{
Title: "Name",
Description: "Name of virtual network rule",
},
"subnetId": &service.StringPropertySchema{
Title: "Subnet ID",
Description: "Subnet ID to add",
},
},
},
},
},
}
}
Expand Down
84 changes: 83 additions & 1 deletion tests/lifecycle/postgresql_cases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
package lifecycle

import (
"context"
"database/sql"
"fmt"

networkSDK "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network" // nolint: lll
"github.com/Azure/go-autorest/autorest/to"
"github.com/Azure/open-service-broker-azure/pkg/service"
_ "github.com/lib/pq" // Postgres SQL driver
uuid "github.com/satori/go.uuid"
)
Expand Down Expand Up @@ -107,6 +111,9 @@ var postgresqlTestCases = []serviceLifecycleTestCase{
},
"backupRedundancy": "geo",
},
preProvisionFns: []preProvisionFn{
createVirtualNetworkForPostgres,
},
updatingParameters: map[string]interface{}{
"cores": 2,
"storage": 25,
Expand All @@ -117,7 +124,7 @@ var postgresqlTestCases = []serviceLifecycleTestCase{
group: "postgresql",
name: "dbms-only-v10",
serviceID: "cabd3125-5a13-46ea-afad-a69582af9578",
planID: "5cc758d2-b530-479e-8af7-e66f2906463a",
planID: "f5218659-72ba-4fd3-9567-afd52d871fee",
provisioningParameters: map[string]interface{}{
"location": "southcentralus",
"alias": postgresqlV10DBMSAlias,
Expand All @@ -129,6 +136,9 @@ var postgresqlTestCases = []serviceLifecycleTestCase{
},
},
},
preProvisionFns: []preProvisionFn{
createVirtualNetworkForPostgres,
},
childTestCases: []*serviceLifecycleTestCase{
{ // database only scenario
group: "postgresql",
Expand Down Expand Up @@ -190,3 +200,75 @@ func testPostgreSQLCreds(credentials map[string]interface{}) error {
}
return nil
}

// nolint: lll
func createVirtualNetworkForPostgres(
ctx context.Context,
resourceGroup string,
parent *service.Instance,
pp *map[string]interface{},
) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
azureConfig, err := getAzureConfig()
if err != nil {
return fmt.Errorf("error getting azure config %s", err)
}
authorizer, err := getBearerTokenAuthorizer(azureConfig)
if err != nil {
return fmt.Errorf("error getting authorizer %s", err)
}
virtualNetworksClient := networkSDK.NewVirtualNetworksClientWithBaseURI(
azureConfig.Environment.ResourceManagerEndpoint,
azureConfig.SubscriptionID,
)
virtualNetworksClient.Authorizer = authorizer
virtualNetworkName := uuid.NewV4().String()
subnetName := "default"
vnResult, err := virtualNetworksClient.CreateOrUpdate(
ctx,
resourceGroup,
virtualNetworkName,
networkSDK.VirtualNetwork{
Location: to.StringPtr("southcentralus"),
VirtualNetworkPropertiesFormat: &networkSDK.VirtualNetworkPropertiesFormat{
AddressSpace: &networkSDK.AddressSpace{
AddressPrefixes: &[]string{"172.19.0.0/16"},
},
Subnets: &[]networkSDK.Subnet{
{
Name: &subnetName,
SubnetPropertiesFormat: &networkSDK.SubnetPropertiesFormat{
AddressPrefix: to.StringPtr("172.19.0.0/24"),
},
},
},
},
},
)
if err != nil {
return fmt.Errorf("error creating virtual network %s", err)
}
if err = vnResult.WaitForCompletion(
ctx,
virtualNetworksClient.Client,
); err != nil {
return fmt.Errorf("error waiting for virtual network creation complete %s", err)
}
subnetID := fmt.Sprintf(
"/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s",
azureConfig.SubscriptionID,
resourceGroup,
virtualNetworkName,
subnetName,
)

(*pp)["virtualNetworkRules"] = []interface{}{
map[string]interface{}{
"name": "test-subnet",
"subnetId": subnetID,
},
}

return nil
}