mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-11-13 00:50:38 -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue