Skip to content

Commit

Permalink
Merge pull request #2 from magodo/auth
Browse files Browse the repository at this point in the history
`List()` signature change, accept credential and client option from caller
  • Loading branch information
magodo authored Jan 29, 2023
2 parents 39d50eb + 66c856a commit 8624647
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 92 deletions.
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

0 comments on commit 8624647

Please sign in to comment.