mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-11-11 00:05:27 -05:00
bootstrapper: make Azure auth method configurable on cluster init (#1346)
* bootstrapper: make Azure auth method configurable on cluster init * azure: convert uami resource ID to clientID Co-authored-by: 3u13r <lc@edgeless.systems>
This commit is contained in:
parent
5cb1899c27
commit
d15968bed7
14 changed files with 307 additions and 209 deletions
|
|
@ -125,19 +125,30 @@ func (c *Cloud) GetCCMConfig(ctx context.Context, providerID string, cloudServic
|
|||
return nil, fmt.Errorf("could not dereference load balancer name")
|
||||
}
|
||||
|
||||
var uamiClientID string
|
||||
useManagedIdentityExtension := creds.PreferredAuthMethod == azureshared.AuthMethodUserAssignedIdentity
|
||||
if useManagedIdentityExtension {
|
||||
uamiClientID, err = c.getUAMIClientIDFromURI(ctx, providerID, creds.UamiResourceID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("retrieving user-assigned managed identity client ID: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
config := cloudConfig{
|
||||
Cloud: "AzurePublicCloud",
|
||||
TenantID: creds.TenantID,
|
||||
SubscriptionID: subscriptionID,
|
||||
ResourceGroup: resourceGroup,
|
||||
LoadBalancerSku: "standard",
|
||||
SecurityGroupName: securityGroupName,
|
||||
LoadBalancerName: *loadBalancer.Name,
|
||||
UseInstanceMetadata: true,
|
||||
VMType: "vmss",
|
||||
Location: creds.Location,
|
||||
AADClientID: creds.AppClientID,
|
||||
AADClientSecret: creds.ClientSecretValue,
|
||||
Cloud: "AzurePublicCloud",
|
||||
TenantID: creds.TenantID,
|
||||
SubscriptionID: subscriptionID,
|
||||
ResourceGroup: resourceGroup,
|
||||
LoadBalancerSku: "standard",
|
||||
SecurityGroupName: securityGroupName,
|
||||
LoadBalancerName: *loadBalancer.Name,
|
||||
UseInstanceMetadata: true,
|
||||
VMType: "vmss",
|
||||
Location: creds.Location,
|
||||
UseManagedIdentityExtension: useManagedIdentityExtension,
|
||||
UserAssignedIdentityID: uamiClientID,
|
||||
AADClientID: creds.AppClientID,
|
||||
AADClientSecret: creds.ClientSecretValue,
|
||||
}
|
||||
|
||||
return json.Marshal(config)
|
||||
|
|
@ -304,6 +315,24 @@ func (c *Cloud) getInstance(ctx context.Context, providerID string) (metadata.In
|
|||
return instance, nil
|
||||
}
|
||||
|
||||
func (c *Cloud) getUAMIClientIDFromURI(ctx context.Context, providerID, resourceID string) (string, error) {
|
||||
// userAssignedIdentityURI := "/subscriptions/{subscription-id}/resourcegroups/{resource-group}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity-name}"
|
||||
_, resourceGroup, scaleSet, instanceID, err := azureshared.ScaleSetInformationFromProviderID(providerID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid provider ID: %w", err)
|
||||
}
|
||||
vmResp, err := c.scaleSetsVMAPI.Get(ctx, resourceGroup, scaleSet, instanceID, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("retrieving instance: %w", err)
|
||||
}
|
||||
for rID, v := range vmResp.Identity.UserAssignedIdentities {
|
||||
if rID == resourceID {
|
||||
return *v.ClientID, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no user assinged identity found for resource ID %s", resourceID)
|
||||
}
|
||||
|
||||
// getNetworkSecurityGroupName returns the security group name of the resource group.
|
||||
func (c *Cloud) getNetworkSecurityGroupName(ctx context.Context, resourceGroup, uid string) (string, error) {
|
||||
pager := c.secGroupAPI.NewListPager(resourceGroup, nil)
|
||||
|
|
@ -383,23 +412,25 @@ func (c *Cloud) getVMInterfaces(ctx context.Context, vm armcompute.VirtualMachin
|
|||
}
|
||||
|
||||
type cloudConfig struct {
|
||||
Cloud string `json:"cloud,omitempty"`
|
||||
TenantID string `json:"tenantId,omitempty"`
|
||||
SubscriptionID string `json:"subscriptionId,omitempty"`
|
||||
ResourceGroup string `json:"resourceGroup,omitempty"`
|
||||
Location string `json:"location,omitempty"`
|
||||
SubnetName string `json:"subnetName,omitempty"`
|
||||
SecurityGroupName string `json:"securityGroupName,omitempty"`
|
||||
SecurityGroupResourceGroup string `json:"securityGroupResourceGroup,omitempty"`
|
||||
LoadBalancerName string `json:"loadBalancerName,omitempty"`
|
||||
LoadBalancerSku string `json:"loadBalancerSku,omitempty"`
|
||||
VNetName string `json:"vnetName,omitempty"`
|
||||
VNetResourceGroup string `json:"vnetResourceGroup,omitempty"`
|
||||
CloudProviderBackoff bool `json:"cloudProviderBackoff,omitempty"`
|
||||
UseInstanceMetadata bool `json:"useInstanceMetadata,omitempty"`
|
||||
VMType string `json:"vmType,omitempty"`
|
||||
AADClientID string `json:"aadClientId,omitempty"`
|
||||
AADClientSecret string `json:"aadClientSecret,omitempty"`
|
||||
Cloud string `json:"cloud,omitempty"`
|
||||
TenantID string `json:"tenantId,omitempty"`
|
||||
SubscriptionID string `json:"subscriptionId,omitempty"`
|
||||
ResourceGroup string `json:"resourceGroup,omitempty"`
|
||||
Location string `json:"location,omitempty"`
|
||||
SubnetName string `json:"subnetName,omitempty"`
|
||||
SecurityGroupName string `json:"securityGroupName,omitempty"`
|
||||
SecurityGroupResourceGroup string `json:"securityGroupResourceGroup,omitempty"`
|
||||
LoadBalancerName string `json:"loadBalancerName,omitempty"`
|
||||
LoadBalancerSku string `json:"loadBalancerSku,omitempty"`
|
||||
VNetName string `json:"vnetName,omitempty"`
|
||||
VNetResourceGroup string `json:"vnetResourceGroup,omitempty"`
|
||||
CloudProviderBackoff bool `json:"cloudProviderBackoff,omitempty"`
|
||||
UseInstanceMetadata bool `json:"useInstanceMetadata,omitempty"`
|
||||
VMType string `json:"vmType,omitempty"`
|
||||
UseManagedIdentityExtension bool `json:"useManagedIdentityExtension,omitempty"`
|
||||
UserAssignedIdentityID string `json:"userAssignedIdentityID,omitempty"`
|
||||
AADClientID string `json:"aadClientId,omitempty"`
|
||||
AADClientSecret string `json:"aadClientSecret,omitempty"`
|
||||
}
|
||||
|
||||
// convertToInstanceMetadata converts a armcomputev2.VirtualMachineScaleSetVM to a metadata.InstanceMetadata.
|
||||
|
|
|
|||
|
|
@ -52,10 +52,13 @@ func TestGetCCMConfig(t *testing.T) {
|
|||
Name: to.Ptr("security-group"),
|
||||
}
|
||||
|
||||
uamiClientID := "uami-client-id"
|
||||
|
||||
testCases := map[string]struct {
|
||||
imdsAPI imdsAPI
|
||||
loadBalancerAPI loadBalancerAPI
|
||||
secGroupAPI securityGroupsAPI
|
||||
scaleSetsVMAPI virtualMachineScaleSetVMsAPI
|
||||
providerID string
|
||||
cloudServiceAccountURI string
|
||||
wantErr bool
|
||||
|
|
@ -75,8 +78,50 @@ func TestGetCCMConfig(t *testing.T) {
|
|||
list: []armnetwork.SecurityGroup{goodSecurityGroup},
|
||||
},
|
||||
},
|
||||
scaleSetsVMAPI: &stubVirtualMachineScaleSetVMsAPI{
|
||||
getVM: armcompute.VirtualMachineScaleSetVM{
|
||||
Identity: &armcompute.VirtualMachineIdentity{
|
||||
UserAssignedIdentities: map[string]*armcompute.UserAssignedIdentitiesValue{
|
||||
"subscriptions/9b352db0-82af-408c-a02c-36fbffbf7015/resourceGroups/resourceGroupName/providers/Microsoft.ManagedIdentity/userAssignedIdentities/UAMIName": {ClientID: &uamiClientID},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
providerID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set/virtualMachines/0",
|
||||
cloudServiceAccountURI: "serviceaccount://azure?tenant_id=tenant-id&client_id=client-id&client_secret=client-secret&location=westeurope",
|
||||
cloudServiceAccountURI: "serviceaccount://azure?tenant_id=tenant-id&client_id=client-id&client_secret=client-secret&location=westeurope&preferred_auth_method=userassignedidentity&uami_resource_id=subscriptions%2F9b352db0-82af-408c-a02c-36fbffbf7015%2FresourceGroups%2FresourceGroupName%2Fproviders%2FMicrosoft.ManagedIdentity%2FuserAssignedIdentities%2FUAMIName",
|
||||
wantConfig: cloudConfig{
|
||||
Cloud: "AzurePublicCloud",
|
||||
TenantID: "tenant-id",
|
||||
SubscriptionID: "subscription-id",
|
||||
ResourceGroup: "resource-group",
|
||||
LoadBalancerSku: "standard",
|
||||
SecurityGroupName: "security-group",
|
||||
LoadBalancerName: "load-balancer",
|
||||
UseInstanceMetadata: true,
|
||||
UseManagedIdentityExtension: true,
|
||||
UserAssignedIdentityID: uamiClientID,
|
||||
VMType: "vmss",
|
||||
Location: "westeurope",
|
||||
AADClientID: "client-id",
|
||||
AADClientSecret: "client-secret",
|
||||
},
|
||||
},
|
||||
"no app registration": {
|
||||
imdsAPI: &stubIMDSAPI{
|
||||
uidVal: "uid",
|
||||
},
|
||||
loadBalancerAPI: &stubLoadBalancersAPI{
|
||||
pager: &stubLoadBalancersClientListPager{
|
||||
list: []armnetwork.LoadBalancer{goodLB},
|
||||
},
|
||||
},
|
||||
secGroupAPI: &stubSecurityGroupsAPI{
|
||||
pager: &stubSecurityGroupsClientListPager{
|
||||
list: []armnetwork.SecurityGroup{goodSecurityGroup},
|
||||
},
|
||||
},
|
||||
providerID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set/virtualMachines/0",
|
||||
cloudServiceAccountURI: "serviceaccount://azure?tenant_id=tenant-id&location=westeurope",
|
||||
wantConfig: cloudConfig{
|
||||
Cloud: "AzurePublicCloud",
|
||||
TenantID: "tenant-id",
|
||||
|
|
@ -88,8 +133,6 @@ func TestGetCCMConfig(t *testing.T) {
|
|||
UseInstanceMetadata: true,
|
||||
VMType: "vmss",
|
||||
Location: "westeurope",
|
||||
AADClientID: "client-id",
|
||||
AADClientSecret: "client-secret",
|
||||
},
|
||||
},
|
||||
"missing UID tag": {
|
||||
|
|
@ -303,6 +346,7 @@ func TestGetCCMConfig(t *testing.T) {
|
|||
imds: tc.imdsAPI,
|
||||
loadBalancerAPI: tc.loadBalancerAPI,
|
||||
secGroupAPI: tc.secGroupAPI,
|
||||
scaleSetsVMAPI: tc.scaleSetsVMAPI,
|
||||
}
|
||||
config, err := cloud.GetCCMConfig(context.Background(), tc.providerID, tc.cloudServiceAccountURI)
|
||||
if tc.wantErr {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ go_library(
|
|||
name = "azureshared",
|
||||
srcs = [
|
||||
"appcredentials.go",
|
||||
"authmethod_string.go",
|
||||
"azureshared.go",
|
||||
"metadata.go",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -9,15 +9,19 @@ package azureshared
|
|||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ApplicationCredentials is a set of Azure AD application credentials.
|
||||
// ApplicationCredentials is a set of Azure API credentials.
|
||||
// It can contain a client secret and carries the preferred authentication method.
|
||||
// It is the equivalent of a service account key in other cloud providers.
|
||||
type ApplicationCredentials struct {
|
||||
TenantID string
|
||||
AppClientID string
|
||||
ClientSecretValue string
|
||||
Location string
|
||||
TenantID string
|
||||
AppClientID string
|
||||
ClientSecretValue string
|
||||
Location string
|
||||
UamiResourceID string
|
||||
PreferredAuthMethod AuthMethod
|
||||
}
|
||||
|
||||
// ApplicationCredentialsFromURI converts a cloudServiceAccountURI into Azure ApplicationCredentials.
|
||||
|
|
@ -33,11 +37,14 @@ func ApplicationCredentialsFromURI(cloudServiceAccountURI string) (ApplicationCr
|
|||
return ApplicationCredentials{}, fmt.Errorf("invalid service account URI: invalid host: %s", uri.Host)
|
||||
}
|
||||
query := uri.Query()
|
||||
preferredAuthMethod := FromString(query.Get("preferred_auth_method"))
|
||||
return ApplicationCredentials{
|
||||
TenantID: query.Get("tenant_id"),
|
||||
AppClientID: query.Get("client_id"),
|
||||
ClientSecretValue: query.Get("client_secret"),
|
||||
Location: query.Get("location"),
|
||||
TenantID: query.Get("tenant_id"),
|
||||
AppClientID: query.Get("client_id"),
|
||||
ClientSecretValue: query.Get("client_secret"),
|
||||
Location: query.Get("location"),
|
||||
UamiResourceID: query.Get("uami_resource_id"),
|
||||
PreferredAuthMethod: preferredAuthMethod,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -45,9 +52,19 @@ func ApplicationCredentialsFromURI(cloudServiceAccountURI string) (ApplicationCr
|
|||
func (c ApplicationCredentials) ToCloudServiceAccountURI() string {
|
||||
query := url.Values{}
|
||||
query.Add("tenant_id", c.TenantID)
|
||||
query.Add("client_id", c.AppClientID)
|
||||
query.Add("client_secret", c.ClientSecretValue)
|
||||
query.Add("location", c.Location)
|
||||
if c.AppClientID != "" {
|
||||
query.Add("client_id", c.AppClientID)
|
||||
}
|
||||
if c.ClientSecretValue != "" {
|
||||
query.Add("client_secret", c.ClientSecretValue)
|
||||
}
|
||||
if c.UamiResourceID != "" {
|
||||
query.Add("uami_resource_id", c.UamiResourceID)
|
||||
}
|
||||
if c.PreferredAuthMethod != AuthMethodUnknown {
|
||||
query.Add("preferred_auth_method", c.PreferredAuthMethod.String())
|
||||
}
|
||||
uri := url.URL{
|
||||
Scheme: "serviceaccount",
|
||||
Host: "azure",
|
||||
|
|
@ -55,3 +72,29 @@ func (c ApplicationCredentials) ToCloudServiceAccountURI() string {
|
|||
}
|
||||
return uri.String()
|
||||
}
|
||||
|
||||
//go:generate stringer -type=AuthMethod -trimprefix=AuthMethod
|
||||
|
||||
// AuthMethod is the authentication method used for the Azure API.
|
||||
type AuthMethod uint32
|
||||
|
||||
// FromString converts a string into an AuthMethod.
|
||||
func FromString(s string) AuthMethod {
|
||||
switch strings.ToLower(s) {
|
||||
case strings.ToLower(AuthMethodServicePrincipal.String()):
|
||||
return AuthMethodServicePrincipal
|
||||
case strings.ToLower(AuthMethodUserAssignedIdentity.String()):
|
||||
return AuthMethodUserAssignedIdentity
|
||||
default:
|
||||
return AuthMethodUnknown
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// AuthMethodUnknown is default value for AuthMethod.
|
||||
AuthMethodUnknown AuthMethod = iota
|
||||
// AuthMethodServicePrincipal uses a client ID and secret.
|
||||
AuthMethodServicePrincipal
|
||||
// AuthMethodUserAssignedIdentity uses a user assigned identity.
|
||||
AuthMethodUserAssignedIdentity
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,20 @@ func TestMain(m *testing.M) {
|
|||
|
||||
func TestApplicationCredentialsFromURI(t *testing.T) {
|
||||
creds := ApplicationCredentials{
|
||||
TenantID: "tenant-id",
|
||||
AppClientID: "client-id",
|
||||
ClientSecretValue: "client-secret",
|
||||
Location: "location",
|
||||
UamiResourceID: "subscriptions/9b352db0-82af-408c-a02c-36fbffbf7015/resourceGroups/resourceGroupName/providers/Microsoft.ManagedIdentity/userAssignedIdentities/UAMIName",
|
||||
PreferredAuthMethod: AuthMethodServicePrincipal,
|
||||
}
|
||||
credsWithoutSecret := ApplicationCredentials{
|
||||
TenantID: "tenant-id",
|
||||
Location: "location",
|
||||
UamiResourceID: "subscriptions/9b352db0-82af-408c-a02c-36fbffbf7015/resourceGroups/resourceGroupName/providers/Microsoft.ManagedIdentity/userAssignedIdentities/UAMIName",
|
||||
PreferredAuthMethod: AuthMethodUserAssignedIdentity,
|
||||
}
|
||||
credsWithoutPreferrredAuthMethod := ApplicationCredentials{
|
||||
TenantID: "tenant-id",
|
||||
AppClientID: "client-id",
|
||||
ClientSecretValue: "client-secret",
|
||||
|
|
@ -32,9 +46,17 @@ func TestApplicationCredentialsFromURI(t *testing.T) {
|
|||
wantErr bool
|
||||
}{
|
||||
"getApplicationCredentials works": {
|
||||
cloudServiceAccountURI: "serviceaccount://azure?tenant_id=tenant-id&client_id=client-id&client_secret=client-secret&location=location",
|
||||
cloudServiceAccountURI: "serviceaccount://azure?tenant_id=tenant-id&client_id=client-id&client_secret=client-secret&location=location&preferred_auth_method=serviceprincipal&uami_resource_id=subscriptions%2F9b352db0-82af-408c-a02c-36fbffbf7015%2FresourceGroups%2FresourceGroupName%2Fproviders%2FMicrosoft.ManagedIdentity%2FuserAssignedIdentities%2FUAMIName",
|
||||
wantCreds: creds,
|
||||
},
|
||||
"can parse URI without app registration / secret": {
|
||||
cloudServiceAccountURI: "serviceaccount://azure?tenant_id=tenant-id&location=location&preferred_auth_method=userassignedidentity&uami_resource_id=subscriptions%2F9b352db0-82af-408c-a02c-36fbffbf7015%2FresourceGroups%2FresourceGroupName%2Fproviders%2FMicrosoft.ManagedIdentity%2FuserAssignedIdentities%2FUAMIName",
|
||||
wantCreds: credsWithoutSecret,
|
||||
},
|
||||
"can parse URI without preferred auth method": {
|
||||
cloudServiceAccountURI: "serviceaccount://azure?tenant_id=tenant-id&client_id=client-id&client_secret=client-secret&location=location",
|
||||
wantCreds: credsWithoutPreferrredAuthMethod,
|
||||
},
|
||||
"invalid URI fails": {
|
||||
cloudServiceAccountURI: "\x00",
|
||||
wantErr: true,
|
||||
|
|
@ -66,25 +88,66 @@ func TestApplicationCredentialsFromURI(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestToCloudServiceAccountURI(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
key := ApplicationCredentials{
|
||||
TenantID: "tenant-id",
|
||||
AppClientID: "client-id",
|
||||
ClientSecretValue: "client-secret",
|
||||
Location: "location",
|
||||
testCases := map[string]struct {
|
||||
credentials ApplicationCredentials
|
||||
wantURLValues url.Values
|
||||
}{
|
||||
"client id and secret without preferred auth method": {
|
||||
credentials: ApplicationCredentials{
|
||||
TenantID: "tenant-id",
|
||||
AppClientID: "client-id",
|
||||
ClientSecretValue: "client-secret",
|
||||
Location: "location",
|
||||
},
|
||||
wantURLValues: url.Values{
|
||||
"tenant_id": []string{"tenant-id"},
|
||||
"client_id": []string{"client-id"},
|
||||
"client_secret": []string{"client-secret"},
|
||||
"location": []string{"location"},
|
||||
},
|
||||
},
|
||||
"client id and secret with preferred auth method": {
|
||||
credentials: ApplicationCredentials{
|
||||
TenantID: "tenant-id",
|
||||
AppClientID: "client-id",
|
||||
ClientSecretValue: "client-secret",
|
||||
Location: "location",
|
||||
PreferredAuthMethod: AuthMethodServicePrincipal,
|
||||
},
|
||||
wantURLValues: url.Values{
|
||||
"tenant_id": []string{"tenant-id"},
|
||||
"client_id": []string{"client-id"},
|
||||
"client_secret": []string{"client-secret"},
|
||||
"location": []string{"location"},
|
||||
"preferred_auth_method": []string{"ServicePrincipal"},
|
||||
},
|
||||
},
|
||||
"only preferred auth method": {
|
||||
credentials: ApplicationCredentials{
|
||||
TenantID: "tenant-id",
|
||||
Location: "location",
|
||||
PreferredAuthMethod: AuthMethodUserAssignedIdentity,
|
||||
},
|
||||
wantURLValues: url.Values{
|
||||
"tenant_id": []string{"tenant-id"},
|
||||
"location": []string{"location"},
|
||||
"preferred_auth_method": []string{"UserAssignedIdentity"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cloudServiceAccountURI := key.ToCloudServiceAccountURI()
|
||||
uri, err := url.Parse(cloudServiceAccountURI)
|
||||
require.NoError(err)
|
||||
query := uri.Query()
|
||||
assert.Equal("serviceaccount", uri.Scheme)
|
||||
assert.Equal("azure", uri.Host)
|
||||
assert.Equal(url.Values{
|
||||
"tenant_id": []string{"tenant-id"},
|
||||
"client_id": []string{"client-id"},
|
||||
"client_secret": []string{"client-secret"},
|
||||
"location": []string{"location"},
|
||||
}, query)
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
cloudServiceAccountURI := tc.credentials.ToCloudServiceAccountURI()
|
||||
uri, err := url.Parse(cloudServiceAccountURI)
|
||||
require.NoError(err)
|
||||
query := uri.Query()
|
||||
assert.Equal("serviceaccount", uri.Scheme)
|
||||
assert.Equal("azure", uri.Host)
|
||||
assert.Equal(tc.wantURLValues, query)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
25
internal/cloud/azureshared/authmethod_string.go
Normal file
25
internal/cloud/azureshared/authmethod_string.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Code generated by "stringer -type=AuthMethod -trimprefix=AuthMethod"; DO NOT EDIT.
|
||||
|
||||
package azureshared
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[AuthMethodUnknown-0]
|
||||
_ = x[AuthMethodServicePrincipal-1]
|
||||
_ = x[AuthMethodUserAssignedIdentity-2]
|
||||
}
|
||||
|
||||
const _AuthMethod_name = "UnknownServicePrincipalUserAssignedIdentity"
|
||||
|
||||
var _AuthMethod_index = [...]uint8{0, 7, 23, 43}
|
||||
|
||||
func (i AuthMethod) String() string {
|
||||
if i >= AuthMethod(len(_AuthMethod_index)-1) {
|
||||
return "AuthMethod(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _AuthMethod_name[_AuthMethod_index[i]:_AuthMethod_index[i+1]]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue