Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List() signature change, accept credential and client option from caller #2

Merged
merged 4 commits into from
Jan 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions azlist/azlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strings"

"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/resourcemanager/resourcegraph/armresourcegraph"
"github.com/magodo/armid"
"github.com/magodo/workerpool"
Expand All @@ -36,6 +37,12 @@ type ARMSchemaEntry struct {
}

type Option struct {
// Required
SubscriptionId string
Cred azcore.TokenCredential
ClientOpt arm.ClientOptions

// Optional
Parallelism int
Recursive bool
IncludeManaged bool
Expand All @@ -62,20 +69,27 @@ type ListResult struct {
Errors []ListError
}

func List(ctx context.Context, subscriptionId, predicate string, opt *Option) (*ListResult, error) {
if opt == nil {
opt = defaultOption()
func List(ctx context.Context, predicate string, opt Option) (*ListResult, error) {
if opt.Cred == nil {
return nil, fmt.Errorf("token credential is empty")
}
if opt.SubscriptionId == "" {
return nil, fmt.Errorf("subscription id is empty")
}
if opt.Parallelism == 0 {
opt.Parallelism = runtime.NumCPU()
}

log.Printf("[INFO] List for subscription %s via predicate %s, with option %#v", subscriptionId, predicate, opt)
log.Printf("[INFO] List for subscription %s via predicate %s (parallelism: %d | recursive %t | include managed %t)", opt.SubscriptionId, predicate, opt.Parallelism, opt.Recursive, opt.IncludeManaged)

client, err := NewClient(subscriptionId)
log.Printf("[INFO] New Client")
client, err := NewClient(opt.SubscriptionId, opt.Cred, opt.ClientOpt)
if err != nil {
return nil, fmt.Errorf("new client: %v", err)
}

log.Printf("[INFO] Listing tracked resources")
rl, err := ListTrackedResources(ctx, client, subscriptionId, predicate)
rl, err := ListTrackedResources(ctx, client, opt.SubscriptionId, predicate)
if err != nil {
return nil, err
}
Expand Down
68 changes: 4 additions & 64 deletions azlist/client.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package azlist

import (
"fmt"
"os"
"strings"

"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/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph"
"github.com/magodo/azlist/armresources"
)
Expand All @@ -18,67 +12,13 @@ type Client struct {
resourceGraph *armresourcegraph.Client
}

func NewClient(subscriptionId string) (*Client, error) {
env := "public"
if v := os.Getenv("ARM_ENVIRONMENT"); v != "" {
env = v
}

var cloudCfg cloud.Configuration
switch strings.ToLower(env) {
case "public":
cloudCfg = cloud.AzurePublic
case "usgovernment":
cloudCfg = cloud.AzureGovernment
case "china":
cloudCfg = cloud.AzureChina
default:
return nil, fmt.Errorf("unknown environment specified: %q", env)
}

// Maps the auth related environment variables used in the provider to what azidentity honors.
if v, ok := os.LookupEnv("ARM_TENANT_ID"); ok {
os.Setenv("AZURE_TENANT_ID", v)
}
if v, ok := os.LookupEnv("ARM_CLIENT_ID"); ok {
os.Setenv("AZURE_CLIENT_ID", v)
}
if v, ok := os.LookupEnv("ARM_CLIENT_SECRET"); ok {
os.Setenv("AZURE_CLIENT_SECRET", v)
}
if v, ok := os.LookupEnv("ARM_CLIENT_CERTIFICATE_PATH"); ok {
os.Setenv("AZURE_CLIENT_CERTIFICATE_PATH", v)
}

cred, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{
ClientOptions: policy.ClientOptions{
Cloud: cloudCfg,
},
TenantID: os.Getenv("ARM_TENANT_ID"),
})
if err != nil {
return nil, fmt.Errorf("failed to obtain a credential: %v", err)
}

opt := &arm.ClientOptions{
ClientOptions: policy.ClientOptions{
Cloud: cloudCfg,
Telemetry: policy.TelemetryOptions{
ApplicationID: "azlist",
Disabled: false,
},
Logging: policy.LogOptions{
IncludeBody: true,
},
},
}

resClient, err := armresources.NewClient(subscriptionId, cred, opt)
func NewClient(subscriptionId string, cred azcore.TokenCredential, clientOpt arm.ClientOptions) (*Client, error) {
resClient, err := armresources.NewClient(subscriptionId, cred, &clientOpt)
if err != nil {
return nil, err
}

argClient, err := armresourcegraph.NewClient(cred, opt)
argClient, err := armresourcegraph.NewClient(cred, &clientOpt)
if err != nil {
return nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/magodo/azlist
go 1.19

require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.3
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.6.0
github.com/hashicorp/go-hclog v1.3.1
github.com/magodo/armid v0.0.0-20220915030809-9ed860f93894
Expand All @@ -14,12 +14,12 @@ require (
)

require (
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
github.com/google/uuid v1.1.1 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
Expand Down
23 changes: 10 additions & 13 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.3 h1:8LoU8N2lIUzkmstvwXvVfniMZlFbesfT2AmA1aqvRr8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.3/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 h1:jp0dGvZ7ZK0mgqnTSClMxa5xuRL7NZgHameVYF6BurY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.0 h1:VuHAcMq8pU1IWNT/m5yRaGqbK0BiQKHT8X4DTp9CHdI=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.0/go.mod h1:tZoQYdDZNOiIjdSn0dVWVfl0NEPGOJqVLzSrcFk4Is0=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.1 h1:T8quHYlUGyb/oqtSTwqlCr1ilJHrDv+ZtpSfo+hm1BU=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.1/go.mod h1:gLa1CL2RNE4s7M3yopJ/p0iq5DdY6Yv5ZUt9MTRZOQM=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.6.0 h1:ofIfA+/dTgrqhykfrz+GbFtPAtE697LAOCSw/8AQbwI=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.6.0/go.mod h1:KKrvyReEXgIA2D4ez2Jq5dRynJW4bOjRDkONdze2qjs=
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 h1:BWe8a+f/t+7KY7zH2mqygeUD0t8hNFXe08p1Pb3/jKE=
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4=
github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1 h1:oPdPEZFSbl7oSPEAIPMPBMUmiL+mqgzBJwM/9qYcwNg=
github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1/go.mod h1:4qFor3D/HDsvBME35Xy9rwW9DecL+M2sNw1ybjPtwA0=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -16,9 +16,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
Expand All @@ -39,7 +38,6 @@ github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI=
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -62,7 +60,6 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR3
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
70 changes: 66 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import (
"encoding/json"
"fmt"
"os"
"strings"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/hashicorp/go-hclog"
"github.com/magodo/azlist/azlist"

Expand All @@ -14,6 +19,7 @@ import (

func main() {
var (
flagEnvironment string
flagSubscriptionId string
flagRecursive bool
flagWithBody bool
Expand All @@ -30,8 +36,14 @@ func main() {
UsageText: "azlist [option] <ARG where predicate>",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "subscription-id",
// Honor the "ARM_SUBSCRIPTION_ID" as is used by the AzureRM provider, for easier use.
Name: "env",
EnvVars: []string{"AZLIST_ENV"},
Usage: `The environment. Can be one of "public", "china", "usgovernment".`,
Destination: &flagEnvironment,
Value: "public",
},
&cli.StringFlag{
Name: "subscription-id",
EnvVars: []string{"AZLIST_SUBSCRIPTION_ID", "ARM_SUBSCRIPTION_ID"},
Aliases: []string{"s"},
Required: true,
Expand Down Expand Up @@ -104,13 +116,63 @@ func main() {
})
}

opt := &azlist.Option{
cloudCfg := cloud.AzurePublic
switch strings.ToLower(flagEnvironment) {
case "public":
cloudCfg = cloud.AzurePublic
case "usgovernment":
cloudCfg = cloud.AzureGovernment
case "china":
cloudCfg = cloud.AzureChina
default:
return fmt.Errorf("unknown environment specified: %q", flagEnvironment)
}

if v, ok := os.LookupEnv("ARM_TENANT_ID"); ok {
os.Setenv("AZURE_TENANT_ID", v)
}
if v, ok := os.LookupEnv("ARM_CLIENT_ID"); ok {
os.Setenv("AZURE_CLIENT_ID", v)
}
if v, ok := os.LookupEnv("ARM_CLIENT_SECRET"); ok {
os.Setenv("AZURE_CLIENT_SECRET", v)
}
if v, ok := os.LookupEnv("ARM_CLIENT_CERTIFICATE_PATH"); ok {
os.Setenv("AZURE_CLIENT_CERTIFICATE_PATH", v)
}

clientOpt := arm.ClientOptions{
ClientOptions: policy.ClientOptions{
Cloud: cloudCfg,
Telemetry: policy.TelemetryOptions{
ApplicationID: "azlist",
Disabled: false,
},
Logging: policy.LogOptions{
IncludeBody: true,
},
},
}

cred, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{
ClientOptions: clientOpt.ClientOptions,
TenantID: os.Getenv("ARM_TENANT_ID"),
})
if err != nil {
return fmt.Errorf("failed to obtain a credential: %v", err)
}

opt := azlist.Option{
SubscriptionId: flagSubscriptionId,
Cred: cred,
ClientOpt: clientOpt,

Parallelism: flagParallelism,
Recursive: flagRecursive,
IncludeManaged: flagIncludeManaged,
}

result, err := azlist.List(ctx.Context, flagSubscriptionId, ctx.Args().First(), opt)
result, err := azlist.List(ctx.Context, ctx.Args().First(), opt)
if err != nil {
return err
}
Expand Down