From 505431e2636ef816c57c9b9a2ee21abcba5d0a3a Mon Sep 17 00:00:00 2001
From: Lalit Bhardwaj <37527306+LalitTurbot@users.noreply.github.com>
Date: Thu, 20 Jan 2022 03:06:01 +0530
Subject: [PATCH] Fix auth session token not being cached properly. Fixes #441
(#442)
This commit also fixes some incorrect plugin name references in the index doc
---
azure/service.go | 54 +++++++++++++++++++++++++++++++-----------------
docs/index.md | 4 ++--
2 files changed, 37 insertions(+), 21 deletions(-)
diff --git a/azure/service.go b/azure/service.go
index edd5e5fc..ce46096d 100644
--- a/azure/service.go
+++ b/azure/service.go
@@ -16,6 +16,7 @@ import (
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/azure/auth"
"github.com/Azure/go-autorest/autorest/azure/cli"
+ "github.com/turbot/go-kit/types"
"github.com/turbot/steampipe-plugin-sdk/plugin"
)
@@ -40,6 +41,7 @@ type Session struct {
*/
func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience string) (session *Session, err error) {
logger := plugin.Logger(ctx)
+
cacheKey := "GetNewSession"
if cachedData, ok := d.ConnectionManager.Cache.Get(cacheKey); ok {
session = cachedData.(*Session)
@@ -50,6 +52,8 @@ func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience strin
}
}
+ logger.Debug("Auth session not found in cache, creating new session")
+
var subscriptionID, tenantID string
settings := auth.EnvironmentSettings{
Values: map[string]string{},
@@ -113,7 +117,7 @@ func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience strin
if azureConfig.Environment != nil {
env, err := azure.EnvironmentFromName(*azureConfig.Environment)
if err != nil {
- logger.Debug("GetNewSession_", "Error getting environment from name with config environment", err)
+ logger.Error("GetNewSession", "Error getting environment from name with config environment", err)
return nil, err
}
settings.Environment = env
@@ -124,7 +128,7 @@ func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience strin
if ok {
env, err = azure.EnvironmentFromName(envName)
if err != nil {
- logger.Debug("GetNewSession_", "Error getting environment from name with no config environment", err)
+ logger.Error("GetNewSession", "Error getting environment from name with no config environment", err)
return nil, err
}
settings.Values[auth.EnvironmentName] = envName
@@ -134,28 +138,30 @@ func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience strin
authMethod, resource, err := getApplicableAuthorizationDetails(ctx, settings, tokenAudience)
if err != nil {
- logger.Debug("GetNewSession__", "getApplicableAuthorizationDetails error", err)
+ logger.Error("GetNewSession", "getApplicableAuthorizationDetails error", err)
return nil, err
}
settings.Values[auth.Resource] = resource
var authorizer autorest.Authorizer
- var expiresOn time.Time
+ var expiresOn *time.Time
// so if it was not in cache - create session
switch authMethod {
case "Environment":
+ logger.Trace("Creating new session authorizer from environment")
authorizer, err = settings.GetAuthorizer()
if err != nil {
- logger.Debug("GetNewSession__", "NewAuthorizerFromEnvironmentWithResource error", err)
+ logger.Error("GetNewSession", "NewAuthorizerFromEnvironmentWithResource error", err)
return nil, err
}
// Get the subscription ID and tenant ID for "GRAPH" token audience
case "CLI":
+ logger.Trace("Creating new session authorizer from Azure CLI")
authorizer, err = auth.NewAuthorizerFromCLIWithResource(resource)
if err != nil {
- logger.Debug("GetNewSession__", "NewAuthorizerFromCLIWithResource error", err)
+ logger.Error("GetNewSession", "NewAuthorizerFromCLIWithResource error", err)
// Check if the password was changed and the session token is stored in
// the system, or if the CLI is outdated
@@ -165,16 +171,17 @@ func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience strin
return nil, err
}
default:
+ logger.Trace("Getting token for authorizer from Azure CLI")
token, err := cli.GetTokenFromCLI(resource)
if err != nil {
return nil, err
}
adalToken, err := token.ToADALToken()
- expiresOn = adalToken.Expires()
+ expiresOn = types.Time(adalToken.Expires())
if err != nil {
- logger.Debug("GetNewSession__", "NewAuthorizerFromCLIWithResource error", err)
+ logger.Error("GetNewSession", "Get token from Azure CLI error", err)
// Check if the password was changed and the session token is stored in
// the system, or if the CLI is outdated
@@ -186,24 +193,29 @@ func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience strin
authorizer = autorest.NewBearerAuthorizer(&adalToken)
}
- if authMethod == "CLI" {
+ // Get the subscription ID and tenant ID from CLI if not set in connection
+ // config or environment variables
+ if authMethod == "CLI" && (settings.Values[auth.SubscriptionID] == "" || settings.Values[auth.TenantID] == "") {
+ logger.Trace("Getting subscription ID and/or tenant ID from from Azure CLI")
subscription, err := getSubscriptionFromCLI(resource)
if err != nil {
- logger.Debug("GetNewSession__", "getSubscriptionFromCLI error", err)
+ logger.Error("GetNewSession", "getSubscriptionFromCLI error", err)
return nil, err
}
tenantID = subscription.TenantID
- // If "AZURE_SUBSCRIPTION_ID" is set then it will take precedence over the subscription set in the CLI
+ // Subscription ID set in config file or environment variable takes
+ // precedence over the subscription ID set in the CLI
if subscriptionID == "" {
subscriptionID = subscription.SubscriptionID
+ logger.Trace("Setting subscription ID from Azure CLI", "subscription_id", subscriptionID)
}
}
sess := &Session{
Authorizer: authorizer,
CloudEnvironment: settings.Environment.Name,
- Expires: &expiresOn,
+ Expires: expiresOn,
GraphEndpoint: settings.Environment.GraphEndpoint,
ResourceManagerEndpoint: settings.Environment.ResourceManagerEndpoint,
StorageEndpointSuffix: settings.Environment.StorageEndpointSuffix,
@@ -211,13 +223,17 @@ func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience strin
TenantID: tenantID,
}
- if sess.Expires != nil {
- d.ConnectionManager.Cache.SetWithTTL(cacheKey, sess, time.Until(*sess.Expires))
+ var expireMins time.Duration
+ if expiresOn != nil {
+ expireMins = time.Until(*sess.Expires)
} else {
// Cache for 55 minutes to avoid expiry issue
- d.ConnectionManager.Cache.SetWithTTL(cacheKey, sess, time.Minute*55)
+ expireMins = time.Minute * 55
}
+ logger.Debug("Session saved in cache", "expiration_time", expireMins)
+ d.ConnectionManager.Cache.SetWithTTL(cacheKey, sess, expireMins)
+
return sess, err
}
@@ -238,7 +254,7 @@ func getApplicableAuthorizationDetails(ctx context.Context, settings auth.Enviro
authMethod = "Environment"
}
- logger.Trace("getApplicableAuthorizationDetails_", "Auth Method: ", authMethod)
+ logger.Debug("getApplicableAuthorizationDetails", "auth_method", authMethod)
var environment azure.Environment
// Get the environment endpoint to be used for authorization
@@ -247,13 +263,13 @@ func getApplicableAuthorizationDetails(ctx context.Context, settings auth.Enviro
} else {
environment, err = azure.EnvironmentFromName(environmentName)
if err != nil {
- logger.Error("Unable to get azure environment", "ERROR", err)
+ logger.Error("getApplicableAuthorizationDetails", "get_environment_name_error", err)
return
}
settings.Environment = environment
}
- logger.Trace("getApplicableAuthorizationDetails_", "tokenAudience: ", tokenAudience)
+ logger.Debug("getApplicableAuthorizationDetails", "token_audience", tokenAudience)
switch tokenAudience {
case "GRAPH":
@@ -266,7 +282,7 @@ func getApplicableAuthorizationDetails(ctx context.Context, settings auth.Enviro
resource = settings.Environment.ResourceManagerEndpoint
}
- logger.Trace("getApplicableAuthorizationDetails_", "resource: ", resource)
+ logger.Debug("getApplicableAuthorizationDetails", "resource", resource)
return
}
diff --git a/docs/index.md b/docs/index.md
index 67692c67..ae7eefd8 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -61,7 +61,7 @@ steampipe plugin install azure
| Credentials | Use the `az login` command to setup your [Azure Default Connection](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli). |
| Permissions | Grant the `Global Reader` permission to your user. |
| Radius | Each connection represents a single Azure Subscription. |
-| Resolution | 1. Credentials explicitly set in a steampipe config file (`~/.steampipe/config/azuread.spc`).
2. Credentials specified in [environment variables](#credentials-from-environment-variables), e.g., `AZURE_SUBSCRIPTION_ID`. |
+| Resolution | 1. Credentials explicitly set in a steampipe config file (`~/.steampipe/config/azure.spc`).
2. Credentials specified in [environment variables](#credentials-from-environment-variables), e.g., `AZURE_SUBSCRIPTION_ID`. |
### Configuration
@@ -197,7 +197,7 @@ Steampipe works with managed identities (formerly known as Managed Service Ident
```hcl
connection "azure_msi" {
- plugin = "azuread"
+ plugin = "azure"
tenant_id = "00000000-0000-0000-0000-000000000000"
client_id = "00000000-0000-0000-0000-000000000000"
subscription_id = "00000000-0000-0000-0000-000000000000"