Skip to content

Commit

Permalink
Add azure_private_dns_zone table (#583)
Browse files Browse the repository at this point in the history
  • Loading branch information
pdecat authored Mar 24, 2023
1 parent 02c846c commit 818c843
Show file tree
Hide file tree
Showing 14 changed files with 368 additions and 9 deletions.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"id": "{{ output.resource_id.value }}",
"name": "{{resourceName}}.local",
"region": "global",
"type": "Microsoft.Network/privateDnsZones"
}
]
6 changes: 6 additions & 0 deletions azure-test/tests/azure_private_dns_zone/test-get-query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
select name,
id,
region,
type
from azure.azure_private_dns_zone
where name = '{{resourceName}}.local'
13 changes: 13 additions & 0 deletions azure-test/tests/azure_private_dns_zone/test-hydrate-expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"akas": [
"{{ output.resource_aka.value }}",
"azure:///subscriptions/{{ output.subscription_id.value }}/resourcegroups/{{resourceName}}/providers/microsoft.network/privatednszones/{{resourceName}}.local"
],
"name": "{{resourceName}}.local",
"tags": {
"name": "{{resourceName}}.local"
},
"title": "{{resourceName}}.local"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
select name,
akas,
tags,
title
from azure.azure_private_dns_zone
where name = '{{resourceName}}.local'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"id": "{{ output.resource_id.value }}",
"name": "{{resourceName}}.local"
}
]
4 changes: 4 additions & 0 deletions azure-test/tests/azure_private_dns_zone/test-list-query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
select id,
name
from azure.azure_private_dns_zone
where id = '{{ output.resource_id.value }}'
1 change: 1 addition & 0 deletions azure-test/tests/azure_private_dns_zone/variables.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
68 changes: 68 additions & 0 deletions azure-test/tests/azure_private_dns_zone/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

variable "resource_name" {
type = string
default = "turbot-test-20230313-create-update"
description = "Name of the resource used throughout the test."
}

variable "azure_environment" {
type = string
default = "public"
description = "Azure environment used for the test."
}

variable "azure_subscription" {
type = string
default = "3510ae4d-530b-497d-8f30-53b9616fc6c1"
description = "Azure subscription used for the test."
}

provider "azurerm" {
# Cannot be passed as a variable
environment = var.azure_environment
subscription_id = var.azure_subscription
features {}
}

data "azurerm_client_config" "current" {}

data "null_data_source" "resource" {
inputs = {
scope = "azure:///subscriptions/${data.azurerm_client_config.current.subscription_id}"
}
}

resource "azurerm_resource_group" "named_test_resource" {
name = var.resource_name
location = "East US"
tags = {
name = var.resource_name
}
}

resource "azurerm_private_dns_zone" "named_test_resource" {
name = "${var.resource_name}.local"
resource_group_name = azurerm_resource_group.named_test_resource.name

tags = {
name = "${var.resource_name}.local"
}
}

output "resource_aka" {
# Azure always puts privateDnsZones with lowercase d and z
value = replace("azure://${azurerm_private_dns_zone.named_test_resource.id}", "Microsoft.Network/PrivateDnsZones", "Microsoft.Network/privatednszones")
}

output "resource_name" {
value = var.resource_name
}

output "resource_id" {
# Azure always puts dnsZones with with lowercase d and z
value = replace(azurerm_private_dns_zone.named_test_resource.id, "Microsoft.Network/PrivateDnsZones", "Microsoft.Network/privatednszones")
}

output "subscription_id" {
value = var.azure_subscription
}
1 change: 1 addition & 0 deletions azure/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"azure_policy_assignment": tableAzurePolicyAssignment(ctx),
"azure_policy_definition": tableAzurePolicyDefinition(ctx),
"azure_postgresql_server": tableAzurePostgreSqlServer(ctx),
"azure_private_dns_zone": tableAzurePrivateDNSZone(ctx),
"azure_provider": tableAzureProvider(ctx),
"azure_public_ip": tableAzurePublicIP(ctx),
"azure_recovery_services_vault": tableAzureRecoveryServicesVault(ctx),
Expand Down
2 changes: 1 addition & 1 deletion azure/table_azure_dns_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func tableAzureDNSZone(_ context.Context) *plugin.Table {
},
{
Name: "zone_type",
Description: "The type of this DNS zone (Public or Private).",
Description: "The type of this DNS zone (always `Public`, see `azure_private_dns_zone` table for private DNS zones).",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ZoneProperties.ZoneType"),
},
Expand Down
207 changes: 207 additions & 0 deletions azure/table_azure_private_dns_zone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
package azure

import (
"context"

"github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns"
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"

"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
)

//// TABLE DEFINITION

func tableAzurePrivateDNSZone(_ context.Context) *plugin.Table {
return &plugin.Table{
Name: "azure_private_dns_zone",
Description: "Azure Private DNS Zone",
Get: &plugin.GetConfig{
KeyColumns: plugin.AllColumns([]string{"name", "resource_group"}),
Hydrate: getPrivateDNSZone,
IgnoreConfig: &plugin.IgnoreConfig{
ShouldIgnoreErrorFunc: isNotFoundError([]string{"ResourceNotFound", "ResourceGroupNotFound", "404"}),
},
},
List: &plugin.ListConfig{
Hydrate: listPrivateDNSZones,
},
Columns: azureColumns([]*plugin.Column{
{
Name: "name",
Type: proto.ColumnType_STRING,
Description: "The friendly name that identifies the Private DNS zone.",
},
{
Name: "id",
Description: "Contains ID to identify a Private DNS zone uniquely.",
Type: proto.ColumnType_STRING,
Transform: transform.FromGo(),
},
{
Name: "etag",
Description: "An unique read-only string that changes whenever the resource is updated.",
Type: proto.ColumnType_STRING,
},
{
Name: "type",
Description: "The resource type of the Private DNS zone.",
Type: proto.ColumnType_STRING,
},
{
Name: "max_number_of_record_sets",
Description: "The maximum number of record sets that can be created in this Private DNS zone.",
Type: proto.ColumnType_INT,
Transform: transform.FromField("PrivateZoneProperties.MaxNumberOfRecordSets"),
},
{
Name: "number_of_record_sets",
Description: "The current number of record sets in this Private DNS zone.",
Type: proto.ColumnType_INT,
Transform: transform.FromField("PrivateZoneProperties.NumberOfRecordSets").Transform(transform.ToString),
},
{
Name: "max_number_of_virtual_network_links",
Description: "The maximum number of virtual networks that can be linked to this Private DNS zone.",
Type: proto.ColumnType_INT,
Transform: transform.FromField("PrivateZoneProperties.MaxNumberOfVirtualNetworkLinks"),
},
{
Name: "number_of_virtual_network_links",
Description: "The current number of virtual networks that are linked to this Private DNS zone.",
Type: proto.ColumnType_INT,
Transform: transform.FromField("PrivateZoneProperties.NumberOfVirtualNetworkLinks"),
},
{
Name: "max_number_of_virtual_network_links_with_registration",
Description: "The maximum number of virtual networks that can be linked to this Private DNS zone with registration enabled.",
Type: proto.ColumnType_INT,
Transform: transform.FromField("PrivateZoneProperties.MaxNumberOfVirtualNetworkLinksWithRegistration"),
},
{
Name: "number_of_virtual_network_links_with_registration",
Description: "The current number of virtual networks that are linked to this Private DNS zone with registration enabled.",
Type: proto.ColumnType_INT,
Transform: transform.FromField("PrivateZoneProperties.NumberOfVirtualNetworkLinksWithRegistration"),
},
{
Name: "provisioning_state",
Description: "The provisioning state of the resource. Possible values include: `Creating`, `Updating`, `Deleting`, `Succeeded`, `Failed`, `Canceled`.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("PrivateZoneProperties.ProvisioningState"),
},

// Steampipe standard columns
{
Name: "title",
Description: ColumnDescriptionTitle,
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Name"),
},
{
Name: "tags",
Description: ColumnDescriptionTags,
Type: proto.ColumnType_JSON,
},
{
Name: "akas",
Description: ColumnDescriptionAkas,
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ID").Transform(idToAkas),
},

// Azure standard columns
{
Name: "region",
Description: ColumnDescriptionRegion,
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Location").Transform(toLower),
},
{
Name: "resource_group",
Description: ColumnDescriptionResourceGroup,
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ID").Transform(extractResourceGroupFromID),
},
}),
}
}

//// FETCH FUNCTIONS ////

func listPrivateDNSZones(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
session, err := GetNewSession(ctx, d, "MANAGEMENT")
if err != nil {
plugin.Logger(ctx).Error("azure_private_dns_zone.listPrivateDNSZones", "client_error", err)
return nil, err
}
subscriptionID := session.SubscriptionID

dnsClient := privatedns.NewPrivateZonesClientWithBaseURI(session.ResourceManagerEndpoint, subscriptionID)
dnsClient.Authorizer = session.Authorizer

result, err := dnsClient.List(ctx, nil)
if err != nil {
plugin.Logger(ctx).Error("azure_private_dns_zone.listPrivateDNSZones", "query_error", err)
return nil, err
}
for _, dnsZone := range result.Values() {
d.StreamListItem(ctx, dnsZone)
// Check if context has been cancelled or if the limit has been hit (if specified)
// if there is a limit, it will return the number of rows required to reach this limit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}

for result.NotDone() {
err = result.NextWithContext(ctx)
if err != nil {
return nil, err
}

for _, dnsZone := range result.Values() {
d.StreamListItem(ctx, dnsZone)
// Check if context has been cancelled or if the limit has been hit (if specified)
// if there is a limit, it will return the number of rows required to reach this limit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}
}
return nil, err
}

//// HYDRATE FUNCTIONS ////

func getPrivateDNSZone(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
plugin.Logger(ctx).Trace("getPrivateDNSZone")

name := d.EqualsQuals["name"].GetStringValue()
resourceGroup := d.EqualsQuals["resource_group"].GetStringValue()

session, err := GetNewSession(ctx, d, "MANAGEMENT")
if err != nil {
plugin.Logger(ctx).Error("azure_private_dns_zone.getPrivateDNSZone", "client_error", err)
return nil, err
}
subscriptionID := session.SubscriptionID

dnsClient := dns.NewZonesClientWithBaseURI(session.ResourceManagerEndpoint, subscriptionID)
dnsClient.Authorizer = session.Authorizer

op, err := dnsClient.Get(ctx, resourceGroup, name)
if err != nil {
plugin.Logger(ctx).Error("azure_private_dns_zone.getPrivateDNSZone", "query_error", err)
return nil, err
}

// In some cases resource does not give any notFound error
// instead of notFound error, it returns empty data
if op.ID != nil {
return op, nil
}

return nil, nil
}
15 changes: 7 additions & 8 deletions docs/tables/azure_dns_zone.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Table: azure_dns_zone

Azure DNS zone is used to host the DNS records for a particular domain.
Azure DNS zone is used to host the DNS records for a particular domain. Please note that this table only retrieves public DNS zones, use the `azure_private_dns_zone` table for private DNS zones.

## Examples

Expand All @@ -9,31 +9,30 @@ Azure DNS zone is used to host the DNS records for a particular domain.
```sql
select
name,
id,
zone_type
resource_group,
tags
from
azure_dns_zone;
```

### List private DNS zones
### List public DNS zones with record sets

```sql
select
name,
id,
tags
resource_group
from
azure_dns_zone
where
zone_type = 'Private';
number_of_record_sets > 1;
```

### List public DNS zones with delegated name servers

```sql
select
name,
id,
resource_group,
ns
from
azure_dns_zone, jsonb_array_elements_text(name_servers) as ns
Expand Down
Loading

0 comments on commit 818c843

Please sign in to comment.