From 7ff540a66e1e5422a9ca013b30c3f278eab74bc9 Mon Sep 17 00:00:00 2001 From: Jim Minter Date: Mon, 2 Dec 2019 19:23:58 -0600 Subject: [PATCH] get tenantID from MSI --- pkg/env/dev/dev.go | 2 +- pkg/env/prod/prod.go | 50 ++++++++++++++++++++++++++++++++++++---- pkg/env/shared/shared.go | 6 +++-- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/pkg/env/dev/dev.go b/pkg/env/dev/dev.go index c8ad48c0d..ca20ad327 100644 --- a/pkg/env/dev/dev.go +++ b/pkg/env/dev/dev.go @@ -30,7 +30,7 @@ func New(ctx context.Context, log *logrus.Entry) (*dev, error) { d := &dev{} var err error - d.Shared, err = shared.NewShared(ctx, log, os.Getenv("AZURE_SUBSCRIPTION_ID"), os.Getenv("RESOURCEGROUP")) + d.Shared, err = shared.NewShared(ctx, log, os.Getenv("AZURE_TENANT_ID"), os.Getenv("AZURE_SUBSCRIPTION_ID"), os.Getenv("RESOURCEGROUP")) if err != nil { return nil, err } diff --git a/pkg/env/prod/prod.go b/pkg/env/prod/prod.go index 3e66cfc0d..5a8a487c2 100644 --- a/pkg/env/prod/prod.go +++ b/pkg/env/prod/prod.go @@ -9,6 +9,9 @@ import ( "net/http" "strings" + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/dgrijalva/jwt-go" "github.com/sirupsen/logrus" "github.com/jim-minter/rp/pkg/api" @@ -22,8 +25,21 @@ type prod struct { resourceGroup string } +type azureClaim struct { + TenantID string `json:"tid,omitempty"` +} + +func (*azureClaim) Valid() error { + return fmt.Errorf("unimplemented") +} + func New(ctx context.Context, log *logrus.Entry) (*prod, error) { - location, subscriptionID, resourceGroup, err := getMetadata() + tenantID, err := getTenantID() + if err != nil { + return nil, err + } + + subscriptionID, location, resourceGroup, err := getInstanceMetadata() if err != nil { return nil, err } @@ -34,7 +50,7 @@ func New(ctx context.Context, log *logrus.Entry) (*prod, error) { resourceGroup: resourceGroup, } - p.Shared, err = shared.NewShared(ctx, log, subscriptionID, resourceGroup) + p.Shared, err = shared.NewShared(ctx, log, tenantID, subscriptionID, resourceGroup) if err != nil { return nil, err } @@ -87,7 +103,33 @@ func (p *prod) ResourceGroup() string { return p.resourceGroup } -func getMetadata() (string, string, string, error) { +func getTenantID() (string, error) { + msiEndpoint, err := adal.GetMSIVMEndpoint() + if err != nil { + return "", err + } + + token, err := adal.NewServicePrincipalTokenFromMSI(msiEndpoint, azure.PublicCloud.ResourceManagerEndpoint) + if err != nil { + return "", err + } + + err = token.EnsureFresh() + if err != nil { + return "", err + } + + p := &jwt.Parser{} + c := &azureClaim{} + _, _, err = p.ParseUnverified(token.OAuthToken(), c) + if err != nil { + return "", err + } + + return c.TenantID, nil +} + +func getInstanceMetadata() (string, string, string, error) { req, err := http.NewRequest(http.MethodGet, "http://169.254.169.254/metadata/instance/compute?api-version=2019-03-11", nil) if err != nil { return "", "", "", err @@ -119,5 +161,5 @@ func getMetadata() (string, string, string, error) { return "", "", "", err } - return m.Location, m.SubscriptionID, m.ResourceGroupName, nil + return m.SubscriptionID, m.Location, m.ResourceGroupName, nil } diff --git a/pkg/env/shared/shared.go b/pkg/env/shared/shared.go index 563da71c2..7d8f36efd 100644 --- a/pkg/env/shared/shared.go +++ b/pkg/env/shared/shared.go @@ -28,11 +28,12 @@ type Shared struct { dns dns.Manager + tenantID string resourceGroup string vaultURI string } -func NewShared(ctx context.Context, log *logrus.Entry, subscriptionID, resourceGroup string) (*Shared, error) { +func NewShared(ctx context.Context, log *logrus.Entry, tenantID, subscriptionID, resourceGroup string) (*Shared, error) { rpAuthorizer, err := auth.NewAuthorizerFromEnvironment() if err != nil { return nil, err @@ -44,6 +45,7 @@ func NewShared(ctx context.Context, log *logrus.Entry, subscriptionID, resourceG } s := &Shared{ + tenantID: tenantID, resourceGroup: resourceGroup, } @@ -141,7 +143,7 @@ func (s *Shared) FPAuthorizer(ctx context.Context) (autorest.Authorizer, error) return nil, err } - oauthConfig, err := adal.NewOAuthConfig(azure.PublicCloud.ActiveDirectoryEndpoint, os.Getenv("AZURE_TENANT_ID")) + oauthConfig, err := adal.NewOAuthConfig(azure.PublicCloud.ActiveDirectoryEndpoint, s.tenantID) if err != nil { return nil, err }