forked from TrueCloudLab/lego
874e3ea023
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
126 lines
3.1 KiB
Go
126 lines
3.1 KiB
Go
package azuredns
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
|
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
|
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph"
|
|
)
|
|
|
|
type ServiceDiscoveryZone struct {
|
|
Name string
|
|
SubscriptionID string
|
|
ResourceGroup string
|
|
}
|
|
|
|
const (
|
|
ResourceGraphTypePublicDNSZone = "microsoft.network/dnszones"
|
|
ResourceGraphTypePrivateDNSZone = "microsoft.network/privatednszones"
|
|
)
|
|
|
|
const ResourceGraphQueryOptionsTop int32 = 1000
|
|
|
|
// discoverDNSZones finds all visible Azure DNS zones based on optional subscriptionID, resourceGroup and serviceDiscovery filter using Kusto query.
|
|
func discoverDNSZones(ctx context.Context, config *Config, credentials azcore.TokenCredential) (map[string]ServiceDiscoveryZone, error) {
|
|
options := &arm.ClientOptions{
|
|
ClientOptions: azcore.ClientOptions{
|
|
Cloud: config.Environment,
|
|
},
|
|
}
|
|
|
|
client, err := armresourcegraph.NewClient(credentials, options)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Set options
|
|
requestOptions := &armresourcegraph.QueryRequestOptions{
|
|
ResultFormat: to.Ptr(armresourcegraph.ResultFormatObjectArray),
|
|
Top: to.Ptr(ResourceGraphQueryOptionsTop),
|
|
Skip: to.Ptr[int32](0),
|
|
}
|
|
|
|
zones := map[string]ServiceDiscoveryZone{}
|
|
for {
|
|
// create the query request
|
|
request := armresourcegraph.QueryRequest{
|
|
Query: to.Ptr(createGraphQuery(config)),
|
|
Options: requestOptions,
|
|
}
|
|
|
|
result, err := client.Resources(ctx, request, nil)
|
|
if err != nil {
|
|
return zones, err
|
|
}
|
|
|
|
resultList, ok := result.Data.([]any)
|
|
if !ok {
|
|
// got invalid or empty data, skipping
|
|
break
|
|
}
|
|
|
|
for _, row := range resultList {
|
|
rowData, ok := row.(map[string]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
zoneName, ok := rowData["name"].(string)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
if _, exists := zones[zoneName]; exists {
|
|
return zones, fmt.Errorf(`found duplicate dns zone "%s"`, zoneName)
|
|
}
|
|
|
|
zones[zoneName] = ServiceDiscoveryZone{
|
|
Name: zoneName,
|
|
ResourceGroup: rowData["resourceGroup"].(string),
|
|
SubscriptionID: rowData["subscriptionId"].(string),
|
|
}
|
|
}
|
|
|
|
*requestOptions.Skip += ResourceGraphQueryOptionsTop
|
|
|
|
if result.TotalRecords != nil {
|
|
if int64(deref(requestOptions.Skip)) >= deref(result.TotalRecords) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return zones, nil
|
|
}
|
|
|
|
func createGraphQuery(config *Config) string {
|
|
buf := new(bytes.Buffer)
|
|
buf.WriteString("\nresources\n")
|
|
|
|
resourceType := ResourceGraphTypePublicDNSZone
|
|
if config.PrivateZone {
|
|
resourceType = ResourceGraphTypePrivateDNSZone
|
|
}
|
|
|
|
_, _ = fmt.Fprintf(buf, "| where type =~ %q\n", resourceType)
|
|
|
|
if config.SubscriptionID != "" {
|
|
_, _ = fmt.Fprintf(buf, "| where subscriptionId =~ %q\n", config.SubscriptionID)
|
|
}
|
|
|
|
if config.ResourceGroup != "" {
|
|
_, _ = fmt.Fprintf(buf, "| where resourceGroup =~ %q\n", config.ResourceGroup)
|
|
}
|
|
|
|
if config.ServiceDiscoveryFilter != "" {
|
|
_, _ = fmt.Fprintf(buf, "| %s\n", config.ServiceDiscoveryFilter)
|
|
}
|
|
|
|
buf.WriteString("| project subscriptionId, resourceGroup, name")
|
|
|
|
return buf.String()
|
|
}
|