Skip to content

Commit

Permalink
Merge pull request #8065 from ArcturusZhang/support-identity-eventhub
Browse files Browse the repository at this point in the history
Update `azurerm_eventhub_namespace` - Support `identity`
  • Loading branch information
tombuildsstuff authored Aug 10, 2020
2 parents 7c1880e + de00d8f commit 6232799
Show file tree
Hide file tree
Showing 6 changed files with 371 additions and 23 deletions.
110 changes: 88 additions & 22 deletions azurerm/internal/services/eventhub/eventhub_namespace_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
"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/features"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/eventhub/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/eventhub/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
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"
)
Expand All @@ -34,9 +35,11 @@ func resourceArmEventHubNamespace() *schema.Resource {
Read: resourceArmEventHubNamespaceRead,
Update: resourceArmEventHubNamespaceCreateUpdate,
Delete: resourceArmEventHubNamespaceDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

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

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Expand Down Expand Up @@ -94,6 +97,33 @@ func resourceArmEventHubNamespace() *schema.Resource {
ValidateFunc: validate.ValidateEventHubDedicatedClusterID,
},

"identity": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(eventhub.SystemAssigned),
}, false),
},

"principal_id": {
Type: schema.TypeString,
Computed: true,
},

"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"maximum_throughput_units": {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -223,7 +253,7 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter
name := d.Get("name").(string)
resGroup := d.Get("resource_group_name").(string)

if features.ShouldResourcesBeImported() && d.IsNewResource() {
if d.IsNewResource() {
existing, err := client.Get(ctx, resGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
Expand All @@ -250,6 +280,7 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter
Tier: eventhub.SkuTier(sku),
Capacity: &capacity,
},
Identity: expandEventHubIdentity(d.Get("identity").([]interface{})),
EHNamespaceProperties: &eventhub.EHNamespaceProperties{
IsAutoInflateEnabled: utils.Bool(autoInflateEnabled),
ZoneRedundant: utils.Bool(zoneRedundant),
Expand Down Expand Up @@ -314,24 +345,22 @@ func resourceArmEventHubNamespaceRead(d *schema.ResourceData, meta interface{})
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := azure.ParseAzureResourceID(d.Id())
id, err := parse.NamespaceID(d.Id())
if err != nil {
return err
}
resGroup := id.ResourceGroup
name := id.Path["namespaces"]

resp, err := client.Get(ctx, resGroup, name)
resp, err := client.Get(ctx, id.ResourceGroup, id.Name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}
return fmt.Errorf("Error making Read request on EventHub Namespace %q: %+v", name, err)
return fmt.Errorf("Error making Read request on EventHub Namespace %q: %+v", id.Name, err)
}

d.Set("name", resp.Name)
d.Set("resource_group_name", resGroup)
d.Set("resource_group_name", id.ResourceGroup)
if location := resp.Location; location != nil {
d.Set("location", azure.NormalizeLocation(*location))
}
Expand All @@ -341,25 +370,29 @@ func resourceArmEventHubNamespaceRead(d *schema.ResourceData, meta interface{})
d.Set("capacity", sku.Capacity)
}

if err := d.Set("identity", flattenEventHubIdentity(resp.Identity)); err != nil {
return fmt.Errorf("Error setting `identity`: %+v", err)
}

if props := resp.EHNamespaceProperties; props != nil {
d.Set("auto_inflate_enabled", props.IsAutoInflateEnabled)
d.Set("maximum_throughput_units", int(*props.MaximumThroughputUnits))
d.Set("zone_redundant", props.ZoneRedundant)
d.Set("dedicated_cluster_id", props.ClusterArmID)
}

ruleset, err := client.GetNetworkRuleSet(ctx, resGroup, name)
ruleset, err := client.GetNetworkRuleSet(ctx, id.ResourceGroup, id.Name)
if err != nil {
return fmt.Errorf("Error making Read request on EventHub Namespace %q Network Ruleset: %+v", name, err)
return fmt.Errorf("Error making Read request on EventHub Namespace %q Network Ruleset: %+v", id.Name, err)
}

if err := d.Set("network_rulesets", flattenEventHubNamespaceNetworkRuleset(ruleset)); err != nil {
return fmt.Errorf("Error setting `network_ruleset` for Evenhub Namespace %s: %v", name, err)
return fmt.Errorf("Error setting `network_ruleset` for Evenhub Namespace %s: %v", id.Name, err)
}

keys, err := client.ListKeys(ctx, resGroup, name, eventHubNamespaceDefaultAuthorizationRule)
keys, err := client.ListKeys(ctx, id.ResourceGroup, id.Name, eventHubNamespaceDefaultAuthorizationRule)
if err != nil {
log.Printf("[WARN] Unable to List default keys for EventHub Namespace %q: %+v", name, err)
log.Printf("[WARN] Unable to List default keys for EventHub Namespace %q: %+v", id.Name, err)
} else {
d.Set("default_primary_connection_string_alias", keys.AliasPrimaryConnectionString)
d.Set("default_secondary_connection_string_alias", keys.AliasSecondaryConnectionString)
Expand All @@ -377,22 +410,20 @@ func resourceArmEventHubNamespaceDelete(d *schema.ResourceData, meta interface{}
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := azure.ParseAzureResourceID(d.Id())
id, err := parse.NamespaceID(d.Id())
if err != nil {
return err
}
resGroup := id.ResourceGroup
name := id.Path["namespaces"]

future, err := client.Delete(ctx, resGroup, name)
future, err := client.Delete(ctx, id.ResourceGroup, id.Name)
if err != nil {
if response.WasNotFound(future.Response()) {
return nil
}
return fmt.Errorf("Error issuing delete request of EventHub Namespace %q (Resource Group %q): %+v", name, resGroup, err)
return fmt.Errorf("Error issuing delete request of EventHub Namespace %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
}

return waitForEventHubNamespaceToBeDeleted(ctx, client, resGroup, name, d)
return waitForEventHubNamespaceToBeDeleted(ctx, client, id.ResourceGroup, id.Name, d)
}

func waitForEventHubNamespaceToBeDeleted(ctx context.Context, client *eventhub.NamespacesClient, resourceGroup, name string, d *schema.ResourceData) error {
Expand Down Expand Up @@ -519,3 +550,38 @@ func flattenEventHubNamespaceNetworkRuleset(ruleset eventhub.NetworkRuleSet) []i
"ip_rule": ipBlocks,
}}
}

func expandEventHubIdentity(input []interface{}) *eventhub.Identity {
if len(input) == 0 {
return nil
}

v := input[0].(map[string]interface{})
return &eventhub.Identity{
Type: eventhub.IdentityType(v["type"].(string)),
}
}

func flattenEventHubIdentity(input *eventhub.Identity) []interface{} {
if input == nil {
return []interface{}{}
}

principalID := ""
if input.PrincipalID != nil {
principalID = *input.PrincipalID
}

tenantID := ""
if input.TenantID != nil {
tenantID = *input.TenantID
}

return []interface{}{
map[string]interface{}{
"type": string(input.Type),
"principal_id": principalID,
"tenant_id": tenantID,
},
}
}
29 changes: 29 additions & 0 deletions azurerm/internal/services/eventhub/parse/namespace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package parse

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

type NamespaceId struct {
Name string
ResourceGroup string
}

func NamespaceID(input string) (*NamespaceId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

rule := NamespaceId{
ResourceGroup: id.ResourceGroup,
}

if rule.Name, err = id.PopSegment("namespaces"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &rule, nil
}
72 changes: 72 additions & 0 deletions azurerm/internal/services/eventhub/parse/namespace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package parse

import "testing"

func TestNamespaceID(t *testing.T) {
testData := []struct {
Name string
Input string
Error bool
Expect *NamespaceId
}{
{
Name: "Empty",
Input: "",
Error: true,
},
{
Name: "No Resource Groups Segment",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000",
Error: true,
},
{
Name: "No Resource Groups Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/",
Error: true,
},
{
Name: "Resource Group ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/",
Error: true,
},
{
Name: "Missing Namespaces Key",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.EventHub/namespaces/",
Error: true,
},
{
Name: "Namespaces Value ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.EventHub/namespaces/namespace1",
Expect: &NamespaceId{
Name: "namespace1",
ResourceGroup: "group1",
},
},
{
Name: "Wrong Casing",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.EventHub/Namespaces/namespace1",
Error: true,
},
}

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

actual, err := NamespaceID(v.Input)
if err != nil {
if v.Error {
continue
}

t.Fatalf("Expected a value but got an error: %s", err)
}

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

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

0 comments on commit 6232799

Please sign in to comment.