feat(az): parse pwsh context from module output

this fixes an issue where using multiple powershell sessions with a
different Azure context would display the same context everywhere when
using Set-AzContext to switch between them

BREAKING CHANGE: this requires adding `$env:POSH_AZURE_ENABLED = $true`
to your PowerShell profile if you want to get the correct context
displayed in your prompt for Azure powershell
This commit is contained in:
Jan De Dobbeleer 2022-09-26 08:10:33 +02:00 committed by Jan De Dobbeleer
parent a16f18f9ec
commit 56ae9e6fda
6 changed files with 152 additions and 144 deletions

View file

@ -23,6 +23,7 @@ const (
pwsh = "pwsh"
cli = "cli"
firstMatch = "first_match"
azureEnv = "POSH_AZURE_SUBSCRIPTION"
)
type AzureConfig struct {
@ -47,47 +48,25 @@ type AzureUser struct {
Type string `json:"type"`
}
type AzurePowerShellConfig struct {
DefaultContextKey string `json:"DefaultContextKey"`
Contexts map[string]*AzurePowerShellSubscription `json:"Contexts"`
}
type AzurePowerShellSubscription struct {
Name string `json:"Name"`
Account struct {
ID string `json:"Id"`
Credential interface{} `json:"Credential"`
Type string `json:"Type"`
TenantMap struct {
} `json:"TenantMap"`
ExtendedProperties struct {
Subscriptions string `json:"Subscriptions"`
Tenants string `json:"Tenants"`
HomeAccountID string `json:"HomeAccountId"`
} `json:"ExtendedProperties"`
Type string `json:"Type"`
} `json:"Account"`
Tenant struct {
ID string `json:"Id"`
Directory interface{} `json:"Directory"`
IsHome bool `json:"IsHome"`
ExtendedProperties struct {
} `json:"ExtendedProperties"`
} `json:"Tenant"`
Environment struct {
Name string `json:"Name"`
} `json:"Environment"`
Subscription struct {
ID string `json:"Id"`
Name string `json:"Name"`
State string `json:"State"`
ExtendedProperties struct {
HomeTenant string `json:"HomeTenant"`
AuthorizationSource string `json:"AuthorizationSource"`
SubscriptionPolices string `json:"SubscriptionPolices"`
Tenants string `json:"Tenants"`
Account string `json:"Account"`
Environment string `json:"Environment"`
Account string `json:"Account"`
} `json:"ExtendedProperties"`
} `json:"Subscription"`
Environment struct {
Name string `json:"Name"`
} `json:"Environment"`
Tenant struct {
ID string `json:"Id"`
} `json:"Tenant"`
}
func (a *Az) Template() string {
@ -142,31 +121,23 @@ func (a *Az) getCLISubscription() bool {
}
func (a *Az) getModuleSubscription() bool {
cfg, err := a.findConfig("AzureRmContext.json")
if err != nil {
envSubscription := a.env.Getenv(azureEnv)
if len(envSubscription) == 0 {
return false
}
content := a.FileContentWithoutBom(cfg)
if len(content) == 0 {
return false
}
var config AzurePowerShellConfig
if err := json.Unmarshal([]byte(content), &config); err != nil {
return false
}
defaultContext := config.Contexts[config.DefaultContextKey]
if defaultContext == nil {
var config AzurePowerShellSubscription
if err := json.Unmarshal([]byte(envSubscription), &config); err != nil {
return false
}
a.IsDefault = true
a.EnvironmentName = defaultContext.Environment.Name
a.TenantID = defaultContext.Tenant.ID
a.ID = defaultContext.Subscription.ID
a.Name = defaultContext.Subscription.Name
a.State = defaultContext.Subscription.State
a.EnvironmentName = config.Environment.Name
a.TenantID = config.Tenant.ID
a.ID = config.Subscription.ID
a.Name = config.Subscription.Name
a.State = config.Subscription.State
a.User = &AzureUser{
Name: defaultContext.Subscription.ExtendedProperties.Account,
Type: defaultContext.Account.Type,
Name: config.Subscription.ExtendedProperties.Account,
Type: config.Account.Type,
}
a.Origin = "PWSH"
return true

View file

@ -124,21 +124,14 @@ func TestAzSegment(t *testing.T) {
env.On("GOOS").Return(environment.LINUX)
env.On("FileContent", filepath.Join(home, ".azure", "azureProfile.json")).Return(azureProfile)
env.On("FileContent", filepath.Join(home, ".azure", "AzureRmContext.json")).Return(azureRmContext)
env.On("Getenv", "POSH_AZURE_SUBSCRIPTION").Return(azureRmContext)
env.On("Getenv", "AZURE_CONFIG_DIR").Return("")
if tc.HasCLI {
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.azure"), "azureProfile.json").Return(true)
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.azure"), "AzureRmContext.json").Return(false)
} else if tc.HasPowerShell {
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.azure"), "azureProfile.json").Return(false)
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.Azure"), "azureProfile.json").Return(false)
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.azure"), "AzureRmContext.json").Return(true)
} else {
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.azure"), "azureProfile.json").Return(false)
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.Azure"), "azureProfile.json").Return(false)
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.azure"), "AzureRmContext.json").Return(false)
env.On("HasFilesInDir", filepath.Clean("/Users/posh/.Azure"), "AzureRmContext.json").Return(false)
}
if tc.Source == "" {

View file

@ -25,10 +25,25 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
if ((::CONFIG:: -ne '') -and (Test-Path ::CONFIG::)) {
$env:POSH_THEME = (Resolve-Path -Path ::CONFIG::).ProviderPath
}
# specific module support (disabled by default)
if (($null -eq $env:POSH_GIT_ENABLED) -or ($null -eq (Get-Module 'posh-git'))) {
$env:POSH_GIT_ENABLED = $false
}
if (($null -eq $env:POSH_AZURE_ENABLED) -or ($null -eq (Get-Module 'az'))) {
$env:POSH_AZURE_ENABLED = $false
}
function Initialize-ModuleSupport {
if ($env:POSH_GIT_ENABLED -eq $true) {
# We need to set the status so posh-git can facilitate autocomplete
$global:GitStatus = Get-GitStatus
$env:POSH_GIT_STATUS = $global:GitStatus | ConvertTo-Json
}
if ($env:POSH_AZURE_ENABLED -eq $true) {
$env:POSH_AZURE_SUBSCRIPTION = Get-AzContext | ConvertTo-Json
}
}
function Start-Utf8Process {
param(
@ -93,14 +108,6 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
return $cleanPWD, $cleanPSWD
}
function Initialize-ModuleSupport {
if ($env:POSH_GIT_ENABLED -eq $true) {
# We need to set the status so posh-git can facilitate autocomplete
$global:GitStatus = Get-GitStatus
$env:POSH_GIT_STATUS = $global:GitStatus | ConvertTo-Json
}
}
if (("::TOOLTIPS::" -eq "true") -and ($ExecutionContext.SessionState.LanguageMode -ne "ConstrainedLanguage")) {
Set-PSReadLineKeyHandler -Key Spacebar -BriefDescription 'OhMyPoshSpaceKeyHandler' -ScriptBlock {
[Microsoft.PowerShell.PSConsoleReadLine]::Insert(' ')

View file

@ -1,81 +1,112 @@
{
"DefaultContextKey": "My Azure Subscription (subscription_id) - tenant_id - user_name",
"EnvironmentTable": {},
"Contexts": {
"My Azure Subscription (subscription_id) - tenant_id - user_name": {
"Account": {
"Id": "232-232-232-232",
"Type": "user",
"TenantMap": {},
"ExtendedProperties": {
"Subscriptions": "subscription_ids",
"Tenants": "tenants_ids",
"HomeAccountId": "tenants_ids"
}
},
"Tenant": {
"Id": "4777-4777-4777-4777",
"Directory": null,
"IsHome": true,
"ExtendedProperties": {}
},
"Subscription": {
"Id": "97hkk-97hkk-97hkk-97hkk",
"Name": "AzurePosh",
"State": "Poshfull",
"ExtendedProperties": {
"HomeTenant": "688ab8f8-d8d8-4c8b-b8b8-b8b8b8b8b8b8",
"AuthorizationSource": "Legacy",
"SubscriptionPolices": "{\"locationPlacementId\":\"Public_2014-09-01\",\"quotaId\":\"MSDN_2014-09-01\",\"spendingLimit\":\"On\"}",
"Tenants": "4777-4777-4777-4777",
"Account": "Bill",
"Environment": "AzurePoshCloud"
}
},
"Environment": {
"Name": "AzurePoshCloud",
"Type": "Built-in",
"OnPremise": false,
"ServiceManagementUrl": "https://management.core.windows.net/",
"ResourceManagerUrl": "https://management.azure.com/",
"ManagementPortalUrl": "https://portal.azure.com/",
"PublishSettingsFileUrl": "https://go.microsoft.com/fwlink/?LinkID=301775",
"ActiveDirectoryAuthority": "https://login.microsoftonline.com/",
"GalleryUrl": "https://gallery.azure.com/",
"GraphUrl": "https://graph.windows.net/",
"ActiveDirectoryServiceEndpointResourceId": "https://management.core.windows.net/",
"StorageEndpointSuffix": "core.windows.net",
"SqlDatabaseDnsSuffix": ".database.windows.net",
"TrafficManagerDnsSuffix": "trafficmanager.net",
"AzureKeyVaultDnsSuffix": "vault.azure.net",
"AzureKeyVaultServiceEndpointResourceId": "https://vault.azure.net",
"GraphEndpointResourceId": "https://graph.windows.net/",
"DataLakeEndpointResourceId": "https://datalake.azure.net/",
"BatchEndpointResourceId": "https://batch.core.windows.net/",
"AzureDataLakeAnalyticsCatalogAndJobEndpointSuffix": "azuredatalakeanalytics.net",
"AzureDataLakeStoreFileSystemEndpointSuffix": "azuredatalakestore.net",
"AdTenant": "Common",
"ContainerRegistryEndpointSuffix": "azurecr.io",
"VersionProfiles": [],
"ExtendedProperties": {
"OperationalInsightsEndpoint": "https://api.loganalytics.io/v1",
"OperationalInsightsEndpointResourceId": "https://api.loganalytics.io",
"AzureAnalysisServicesEndpointSuffix": "asazure.windows.net",
"AnalysisServicesEndpointResourceId": "https://region.asazure.windows.net",
"AzureAttestationServiceEndpointSuffix": "attest.azure.net",
"AzureAttestationServiceEndpointResourceId": "https://attest.azure.net",
"AzureSynapseAnalyticsEndpointSuffix": "dev.azuresynapse.net",
"AzureSynapseAnalyticsEndpointResourceId": "https://dev.azuresynapse.net",
"ManagedHsmServiceEndpointResourceId": "https://managedhsm.azure.net",
"ManagedHsmServiceEndpointSuffix": "managedhsm.azure.net",
"MicrosoftGraphEndpointResourceId": "https://graph.microsoft.com/",
"MicrosoftGraphUrl": "https://graph.microsoft.com"
}
},
"VersionProfile": null,
"TokenCache": { "CacheData": null },
"ExtendedProperties": {}
"Name": "MVP (c2733c30-f2c9-45bd-9f1f-528d7c6191b8) - be96dc2e-13ce-4ee1-9cad-13b52b893716 - jan@ohmyposh.dev",
"Account": {
"Id": "jan@ohmyposh.dev",
"Type": "User",
"Tenants": [
"be96dc2e-13ce-4ee1-9cad-13b52b893716"
],
"AccessToken": null,
"Credential": null,
"TenantMap": {},
"CertificateThumbprint": null,
"ExtendedProperties": {
"Tenants": "be96dc2e-13ce-4ee1-9cad-13b52b893716",
"HomeAccountId": "360a9158-bf5d-45a7-8539-88e7f6f1d90b.161de531-8316-49b4-88fb-1a669ecc3b5c",
"Subscriptions": "c2733c30-f2c9-45bd-9f1f-528d7c6191b8"
}
},
"Environment": {
"Name": "AzurePoshCloud",
"Type": "Built-in",
"EnableAdfsAuthentication": false,
"OnPremise": false,
"ActiveDirectoryServiceEndpointResourceId": "https://management.core.windows.net/",
"AdTenant": "Common",
"GalleryUrl": "https://gallery.azure.com/",
"ManagementPortalUrl": "https://portal.azure.com/",
"ServiceManagementUrl": "https://management.core.windows.net/",
"PublishSettingsFileUrl": "https://go.microsoft.com/fwlink/?LinkID=301775",
"ResourceManagerUrl": "https://management.azure.com/",
"SqlDatabaseDnsSuffix": ".database.windows.net",
"StorageEndpointSuffix": "core.windows.net",
"ActiveDirectoryAuthority": "https://login.microsoftonline.com/",
"GraphUrl": "https://graph.windows.net/",
"GraphEndpointResourceId": "https://graph.windows.net/",
"TrafficManagerDnsSuffix": "trafficmanager.net",
"AzureKeyVaultDnsSuffix": "vault.azure.net",
"DataLakeEndpointResourceId": "https://datalake.azure.net/",
"AzureDataLakeStoreFileSystemEndpointSuffix": "azuredatalakestore.net",
"AzureDataLakeAnalyticsCatalogAndJobEndpointSuffix": "azuredatalakeanalytics.net",
"AzureKeyVaultServiceEndpointResourceId": "https://vault.azure.net",
"ContainerRegistryEndpointSuffix": "azurecr.io",
"AzureOperationalInsightsEndpointResourceId": "https://api.loganalytics.io",
"AzureOperationalInsightsEndpoint": "https://api.loganalytics.io/v1",
"AzureAnalysisServicesEndpointSuffix": "asazure.windows.net",
"AnalysisServicesEndpointResourceId": "https://region.asazure.windows.net",
"AzureAttestationServiceEndpointSuffix": "attest.azure.net",
"AzureAttestationServiceEndpointResourceId": "https://attest.azure.net",
"AzureSynapseAnalyticsEndpointSuffix": "dev.azuresynapse.net",
"AzureSynapseAnalyticsEndpointResourceId": "https://dev.azuresynapse.net",
"VersionProfiles": [],
"ExtendedProperties": {
"OperationalInsightsEndpoint": "https://api.loganalytics.io/v1",
"OperationalInsightsEndpointResourceId": "https://api.loganalytics.io",
"AzureAnalysisServicesEndpointSuffix": "asazure.windows.net",
"AnalysisServicesEndpointResourceId": "https://region.asazure.windows.net",
"AzureAttestationServiceEndpointSuffix": "attest.azure.net",
"AzureAttestationServiceEndpointResourceId": "https://attest.azure.net",
"AzureSynapseAnalyticsEndpointSuffix": "dev.azuresynapse.net",
"AzureSynapseAnalyticsEndpointResourceId": "https://dev.azuresynapse.net",
"ManagedHsmServiceEndpointResourceId": "https://managedhsm.azure.net",
"ManagedHsmServiceEndpointSuffix": "managedhsm.azure.net",
"MicrosoftGraphEndpointResourceId": "https://graph.microsoft.com/",
"MicrosoftGraphUrl": "https://graph.microsoft.com",
"AzurePurviewEndpointSuffix": "purview.azure.net",
"AzurePurviewEndpointResourceId": "https://purview.azure.net"
},
"BatchEndpointResourceId": "https://batch.core.windows.net/"
},
"Subscription": {
"Id": "c2733c30-f2c9-45bd-9f1f-528d7c6191b8",
"Name": "MVP",
"State": "Enabled",
"SubscriptionId": "c2733c30-f2c9-45bd-9f1f-528d7c6191b8",
"TenantId": "be96dc2e-13ce-4ee1-9cad-13b52b893716",
"HomeTenantId": "be96dc2e-13ce-4ee1-9cad-13b52b893716",
"ManagedByTenantIds": [],
"CurrentStorageAccountName": null,
"SubscriptionPolicies": {
"LocationPlacementId": "Public_2014-09-01",
"QuotaId": "MSDN_2014-09-01",
"SpendingLimit": "On"
},
"ExtendedProperties": {
"Account": "jan.de.dobbeleer@gmail.com",
"Tenants": "be96dc2e-13ce-4ee1-9cad-13b52b893716",
"AuthorizationSource": "Legacy",
"SubscriptionPolices": "{\"locationPlacementId\":\"Public_2014-09-01\",\"quotaId\":\"MSDN_2014-09-01\",\"spendingLimit\":\"On\"}",
"HomeTenant": "be96dc2e-13ce-4ee1-9cad-13b52b893716",
"Environment": "AzureCloud"
},
"CurrentStorageAccount": null,
"AuthorizationSource": "Legacy",
"Tags": null
},
"Tenant": {
"Id": "be96dc2e-13ce-4ee1-9cad-13b52b893716",
"TenantId": "be96dc2e-13ce-4ee1-9cad-13b52b893716",
"ExtendedProperties": {},
"TenantCategory": null,
"Country": null,
"CountryCode": null,
"Name": null,
"Domains": [],
"DefaultDomain": null,
"TenantType": null,
"TenantBrandingLogoUrl": null
},
"TokenCache": null,
"VersionProfile": null,
"ExtendedProperties": {}
}

View file

@ -8,6 +8,12 @@ sidebar_label: Azure
Display the currently active Azure subscription information.
:::tip
PowerShell offers support for the [az][az] module, but it is disabled by default.
To enable this, set `$env:POSH_AZURE_ENABLED = $true` in your `$PROFILE` after
initializing Oh My Posh.
:::
## Sample Configuration
```json

View file

@ -11,8 +11,8 @@ make sure your `git` executable is up-to-date (when branch or status information
:::tip
PowerShell offers support for the [posh-git][poshgit] module for autocompletion, but it is disabled by default.
To enable this, set `$env:POSH_GIT_ENABLED = $true` in your `$PROFILE`. This will also make use of the
[posh-git][poshgit] output rather than do additional work to get the git status.
To enable this, set `$env:POSH_GIT_ENABLED = $true` in your `$PROFILE` after initializing Oh My Posh.
This will also make use of the [posh-git][poshgit] output rather than do additional work to get the git status.
If you want to display the default [posh-git][poshgit] output, **do not** set the above environment variable
and add the following snippet after initializing Oh My Posh in your `$PROFILE`: