Skip to content

Commit

Permalink
new resource for azurerm_synapse_firewall_rule (#7904)
Browse files Browse the repository at this point in the history
another resource for #7406
  • Loading branch information
njuCZ authored Aug 11, 2020
1 parent 46d0eeb commit 76d63e1
Show file tree
Hide file tree
Showing 12 changed files with 687 additions and 4 deletions.
5 changes: 5 additions & 0 deletions azurerm/internal/services/synapse/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@ import (
)

type Client struct {
FirewallRulesClient *synapse.IPFirewallRulesClient
WorkspaceClient *synapse.WorkspacesClient
WorkspaceAadAdminsClient *synapse.WorkspaceAadAdminsClient
}

func NewClient(o *common.ClientOptions) *Client {
firewallRuleClient := synapse.NewIPFirewallRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&firewallRuleClient.Client, o.ResourceManagerAuthorizer)

workspaceClient := synapse.NewWorkspacesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&workspaceClient.Client, o.ResourceManagerAuthorizer)

workspaceAadAdminsClient := synapse.NewWorkspaceAadAdminsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&workspaceAadAdminsClient.Client, o.ResourceManagerAuthorizer)

return &Client{
FirewallRulesClient: &firewallRuleClient,
WorkspaceClient: &workspaceClient,
WorkspaceAadAdminsClient: &workspaceAadAdminsClient,
}
Expand Down
37 changes: 37 additions & 0 deletions azurerm/internal/services/synapse/parse/synapse_firewall_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package parse

import (
"fmt"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
)

type SynapseFirewallRuleId struct {
Workspace *SynapseWorkspaceId
Name string
}

func SynapseFirewallRuleID(input string) (*SynapseFirewallRuleId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, fmt.Errorf("parsing synapseWorkspace ID %q: %+v", input, err)
}

FirewallRuleId := SynapseFirewallRuleId{
Workspace: &SynapseWorkspaceId{
SubscriptionID: id.SubscriptionID,
ResourceGroup: id.ResourceGroup,
},
}
if FirewallRuleId.Workspace.Name, err = id.PopSegment("workspaces"); err != nil {
return nil, err
}
if FirewallRuleId.Name, err = id.PopSegment("firewallRules"); err != nil {
return nil, err
}
if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &FirewallRuleId, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package parse

import (
"testing"
)

func TestSynapseFirewallRuleID(t *testing.T) {
testData := []struct {
Name string
Input string
Expected *SynapseFirewallRuleId
}{
{
Name: "Empty",
Input: "",
Expected: nil,
},
{
Name: "No Resource Groups Segment",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000",
Expected: nil,
},
{
Name: "No Resource Groups Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/",
Expected: nil,
},
{
Name: "Resource Group ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/",
Expected: nil,
},
{
Name: "Missing Firewall Rule Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.Synapse/workspaces/workspace1/firewallRules",
Expected: nil,
},
{
Name: "synapse Firewall Rule ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.Synapse/workspaces/workspace1/firewallRules/rule1",
Expected: &SynapseFirewallRuleId{
Workspace: &SynapseWorkspaceId{
ResourceGroup: "resourceGroup1",
Name: "workspace1",
},
Name: "rule1",
},
},
{
Name: "Wrong Casing",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.Synapse/workspaces/workspace1/FirewallRules/rule1",
Expected: nil,
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q..", v.Name)

actual, err := SynapseFirewallRuleID(v.Input)
if err != nil {
if v.Expected == nil {
continue
}
t.Fatalf("Expected a value but got an error: %s", err)
}

if actual.Workspace.ResourceGroup != v.Expected.Workspace.ResourceGroup {
t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.Workspace.ResourceGroup, actual.Workspace.ResourceGroup)
}

if actual.Workspace.Name != v.Expected.Workspace.Name {
t.Fatalf("Expected %q but got %q for WorkspaceName", v.Expected.Workspace.Name, actual.Workspace.Name)
}

if actual.Name != v.Expected.Name {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}
}
}
12 changes: 9 additions & 3 deletions azurerm/internal/services/synapse/parse/synapse_workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import (
)

type SynapseWorkspaceId struct {
ResourceGroup string
Name string
SubscriptionID string
ResourceGroup string
Name string
}

func SynapseWorkspaceID(input string) (*SynapseWorkspaceId, error) {
Expand All @@ -18,7 +19,8 @@ func SynapseWorkspaceID(input string) (*SynapseWorkspaceId, error) {
}

synapseWorkspace := SynapseWorkspaceId{
ResourceGroup: id.ResourceGroup,
ResourceGroup: id.ResourceGroup,
SubscriptionID: id.SubscriptionID,
}
if synapseWorkspace.Name, err = id.PopSegment("workspaces"); err != nil {
return nil, err
Expand All @@ -29,3 +31,7 @@ func SynapseWorkspaceID(input string) (*SynapseWorkspaceId, error) {

return &synapseWorkspace, nil
}

func (id *SynapseWorkspaceId) String() string {
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Synapse/workspaces/%s", id.SubscriptionID, id.ResourceGroup, id.Name)
}
3 changes: 2 additions & 1 deletion azurerm/internal/services/synapse/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
// SupportedResources returns the supported Resources supported by this Service
func (r Registration) SupportedResources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_synapse_workspace": resourceArmSynapseWorkspace(),
"azurerm_synapse_firewall_rule": resourceArmSynapseFirewallRule(),
"azurerm_synapse_workspace": resourceArmSynapseWorkspace(),
}
}
166 changes: 166 additions & 0 deletions azurerm/internal/services/synapse/synapse_firewall_rule_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package synapse

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/synapse/mgmt/2019-06-01-preview/synapse"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/synapse/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/synapse/validate"
azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmSynapseFirewallRule() *schema.Resource {
return &schema.Resource{
Create: resourceArmSynapseFirewallRuleCreateUpdate,
Read: resourceArmSynapseFirewallRuleRead,
Update: resourceArmSynapseFirewallRuleCreateUpdate,
Delete: resourceArmSynapseFirewallRuleDelete,

Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error {
_, err := parse.SynapseFirewallRuleID(id)
return err
}),

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Read: schema.DefaultTimeout(5 * time.Minute),
Update: schema.DefaultTimeout(30 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.SynapseFirewallRuleName,
},

"synapse_workspace_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.SynapseWorkspaceID,
},

"start_ip_address": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.IsIPv4Address,
},

"end_ip_address": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.IsIPv4Address,
},
},
}
}

func resourceArmSynapseFirewallRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Synapse.FirewallRulesClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

name := d.Get("name").(string)
workspaceId, _ := parse.SynapseWorkspaceID(d.Get("synapse_workspace_id").(string))

if d.IsNewResource() {
existing, err := client.Get(ctx, workspaceId.ResourceGroup, workspaceId.Name, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for presence of existing Synapse Firewall Rule %q (Resource Group %q / Workspace %q): %+v", name, workspaceId.ResourceGroup, workspaceId.Name, err)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_synapse_firewall_rule", *existing.ID)
}
}

parameters := synapse.IPFirewallRuleInfo{
IPFirewallRuleProperties: &synapse.IPFirewallRuleProperties{
StartIPAddress: utils.String(d.Get("start_ip_address").(string)),
EndIPAddress: utils.String(d.Get("end_ip_address").(string)),
},
}

future, err := client.CreateOrUpdate(ctx, workspaceId.ResourceGroup, workspaceId.Name, name, parameters)
if err != nil {
return fmt.Errorf("creating/updating Synapse Firewall Rule %q (Resource Group %q / Workspace %q): %+v", name, workspaceId.ResourceGroup, workspaceId.Name, err)
}
if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("waiting on creation/updation for Synapse Firewall Rule %q (Resource Group %q / Workspace %q): %+v", name, workspaceId.ResourceGroup, workspaceId.Name, err)
}

resp, err := client.Get(ctx, workspaceId.ResourceGroup, workspaceId.Name, name)
if err != nil {
return fmt.Errorf("retrieving Synapse Firewall Rule %q (Resource Group %q / Workspace %q): %+v", name, workspaceId.ResourceGroup, workspaceId.Name, err)
}

d.SetId(*resp.ID)

return resourceArmSynapseFirewallRuleRead(d, meta)
}

func resourceArmSynapseFirewallRuleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Synapse.FirewallRulesClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.SynapseFirewallRuleID(d.Id())
if err != nil {
return err
}

resp, err := client.Get(ctx, id.Workspace.ResourceGroup, id.Workspace.Name, id.Name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[INFO] Error reading Synapse Firewall Rule %q - removing from state", d.Id())
d.SetId("")
return nil
}

return fmt.Errorf("reading Synapse Firewall Rule %q (Resource Group %q / Workspace %q): %+v", id.Name, id.Workspace.ResourceGroup, id.Workspace.Name, err)
}

d.Set("name", id.Name)
d.Set("synapse_workspace_id", id.Workspace.String())
if resp.IPFirewallRuleProperties != nil {
d.Set("start_ip_address", resp.IPFirewallRuleProperties.StartIPAddress)
d.Set("end_ip_address", resp.IPFirewallRuleProperties.EndIPAddress)
}

return nil
}

func resourceArmSynapseFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Synapse.FirewallRulesClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.SynapseFirewallRuleID(d.Id())
if err != nil {
return err
}

future, err := client.Delete(ctx, id.Workspace.ResourceGroup, id.Workspace.Name, id.Name)
if err != nil {
return fmt.Errorf("deleting Synapse Firewall Rule %q (Resource Group %q / Workspace %q): %+v", id.Name, id.Workspace.ResourceGroup, id.Workspace.Name, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("waiting for deleting Synapse Firewall Rule %q (Resource Group %q / Workspace %q): %+v", id.Name, id.Workspace.ResourceGroup, id.Workspace.Name, err)
}

return nil
}
Loading

0 comments on commit 76d63e1

Please sign in to comment.