Skip to content

Commit

Permalink
Add azure_dns_zone table
Browse files Browse the repository at this point in the history
  • Loading branch information
pdecat committed Mar 13, 2023
1 parent d8c666c commit f6ca012
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 0 deletions.
1 change: 1 addition & 0 deletions azure/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"azure_data_lake_store": tableAzureDataLakeStore(ctx),
"azure_databox_edge_device": tableAzureDataBoxEdgeDevice(ctx),
"azure_diagnostic_setting": tableAzureDiagnosticSetting(ctx),
"azure_dns_zone": tableAzureDNSZone(ctx),
"azure_eventgrid_domain": tableAzureEventGridDomain(ctx),
"azure_eventgrid_topic": tableAzureEventGridTopic(ctx),
"azure_eventhub_namespace": tableAzureEventHubNamespace(ctx),
Expand Down
203 changes: 203 additions & 0 deletions azure/table_azure_dns_zone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
package azure

import (
"context"

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

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

//// TABLE DEFINITION

func tableAzureDNSZone(_ context.Context) *plugin.Table {
return &plugin.Table{
Name: "azure_dns_zone",
Description: "Azure DNS zone",
Get: &plugin.GetConfig{
KeyColumns: plugin.AllColumns([]string{"name", "resource_group"}),
Hydrate: getDNSZone,
IgnoreConfig: &plugin.IgnoreConfig{
ShouldIgnoreErrorFunc: isNotFoundError([]string{"ResourceNotFound", "ResourceGroupNotFound", "404"}),
},
},
List: &plugin.ListConfig{
Hydrate: listDNSZones,
},
Columns: azureColumns([]*plugin.Column{
{
Name: "name",
Type: proto.ColumnType_STRING,
Description: "The friendly name that identifies the DNS zone",
},
{
Name: "id",
Description: "Contains ID to identify a 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 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 DNS zone",
Type: proto.ColumnType_INT,
Transform: transform.FromField("ZoneProperties.MaxNumberOfRecordSets"),
},
{
Name: "max_number_of_records_per_record_set",
Description: "The maximum number of records per record set that can be created in this DNS zone",
Type: proto.ColumnType_INT,
Transform: transform.FromField("ZoneProperties.MaxNumberOfRecordsPerRecordSet"),
},
{
Name: "number_of_record_sets",
Description: "The current number of record sets in this DNS zone",
Type: proto.ColumnType_INT,
Transform: transform.FromField("ZoneProperties.NumberOfRecordSets").Transform(transform.ToString),
},
{
Name: "name_servers",
Description: "The name servers for this DNS zone",
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ZoneProperties.NameServers"),
},
{
Name: "zone_type",
Description: "The type of this DNS zone (Public or Private)",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ZoneProperties.ZoneType"),
},
{
Name: "registration_virtual_networks",
Description: "A list of references to virtual networks that register hostnames in this DNS zone",
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ZoneProperties.RegistrationVirtualNetworks"),
},
{
Name: "resolution_virtual_networks",
Description: "A list of references to virtual networks that resolve records in this DNS zone",
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ZoneProperties.ResolutionVirtualNetworks"),
},

// 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 listDNSZones(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
session, err := GetNewSession(ctx, d, "MANAGEMENT")
if err != nil {
return nil, err
}
subscriptionID := session.SubscriptionID

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

result, err := dnsClient.List(ctx, nil)
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.QueryStatus.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.QueryStatus.RowsRemaining(ctx) == 0 {
return nil, nil
}
}
}
return nil, err
}

//// HYDRATE FUNCTIONS ////

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

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

session, err := GetNewSession(ctx, d, "MANAGEMENT")
if err != nil {
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 {
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
}
43 changes: 43 additions & 0 deletions docs/tables/azure_dns_zone.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Table: azure_dns_zone

Azure DNS zone is used to host the DNS records for a particular domain.

## Examples

### Basic info

```sql
select
name,
id,
zone_type
from
azure_dns_zone;
```

### List private DNS zones

```sql
select
name,
id,
tags
from
azure_dns_zone
where
zone_type = 'Private';
```

### List public DNS zones with delegated name servers

```sql
select
name,
id,
ns
from
azure_dns_zone, jsonb_array_elements_text(name_servers) as ns
where
zone_type = 'Public'
and ns not like '%.azure-dns.%.';
```

0 comments on commit f6ca012

Please sign in to comment.