Skip to content

[Aks] Added acr support in Set-AzAksCluster #14796

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Aks/Aks.Test/ScenarioTests/KubernetesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ public void TestAzureKubernetesAddons()
TestController.NewInstance.RunPowerShellTest(_logger, "Test-NewAzAksAddons");
}

[Fact(Skip = "Please make sure you have graph directory.read permission which is required for grant acrpull permission.")]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void TestNewAzAksWithAcr()
{
TestController.NewInstance.RunPowerShellTest(_logger, "Test-NewAzAksWithAcr");
}

[Fact(Skip = "Updating service principal profile is not allowed on MSI cluster.")]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void TestResetAzureKubernetesServicePrincipal()
Expand Down
10 changes: 9 additions & 1 deletion src/Aks/Aks.Test/ScenarioTests/KubernetesTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function Test-NewAzAksWithAcr
$kubeClusterName = Get-RandomClusterName
$acrName = Get-RandomRegistryName
$location = Get-ProviderLocation "Microsoft.ContainerService/managedClusters"
$nodeVmSize = "Standard_A2"
$nodeVmSize = "Standard_D2_v2"

try
{
Expand All @@ -59,6 +59,14 @@ function Test-NewAzAksWithAcr
Assert-AreEqual 2 $cluster.AgentPoolProfiles[0].Count;
$cluster | Import-AzAksCredential -Force
$cluster | Remove-AzAksCluster -Force
$roleAssignment = Get-AzRoleAssignment -ResourceGroupName $resourceGroupName | Where-Object { ($_.RoleDefinitionName -eq 'AcrPull') -and ($_.DisplayName -eq $acrName) }
Assert-NotNull $roleAssignment
Set-AzAksCluster -ResourceGroupName $resourceGroupName -Name $kubeClusterName -AcrNameToDetach $acrName
$roleAssignment = Get-AzRoleAssignment -ResourceGroupName $resourceGroupName | Where-Object { ($_.RoleDefinitionName -eq 'AcrPull') -and ($_.DisplayName -eq $acrName) }
Assert-Null $roleAssignment
Set-AzAksCluster -ResourceGroupName $resourceGroupName -Name $kubeClusterName -AcrNameToAttach $acrName
$roleAssignment = Get-AzRoleAssignment -ResourceGroupName $resourceGroupName | Where-Object { ($_.RoleDefinitionName -eq 'AcrPull') -and ($_.DisplayName -eq $acrName) }
Assert-NotNull $roleAssignment
}
finally
{
Expand Down
21 changes: 20 additions & 1 deletion src/Aks/Aks.Test/ScenarioTests/TestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
using Microsoft.Azure.ServiceManagement.Common.Models;
using Microsoft.Azure.Management.ContainerService;
using Microsoft.Azure.Management.Authorization.Version2015_07_01;
using Microsoft.Azure.Graph.RBAC.Version1_6;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;

namespace Commands.Aks.Test.ScenarioTests
{
Expand All @@ -30,6 +32,9 @@ public TestController()

public static TestController NewInstance => new TestController();

public string UserDomain { get; private set; }
public GraphRbacManagementClient InternalGraphRbacManagementClient { get; private set; }

public ResourceManagementClient InternalResourceManagementClient { get; private set; }

public AuthorizationManagementClient InternalAuthorizationManagementClient { get; private set; }
Expand All @@ -44,6 +49,7 @@ public void RunPowerShellTest(XunitTracingInterceptor logger, params string[] sc

var d = new Dictionary<string, string>
{
{"Microsoft.Resources", null},
{"Microsoft.Features", null},
{"Microsoft.Authorization", null}
};
Expand Down Expand Up @@ -108,13 +114,26 @@ private void SetupManagementClients(MockContext context)
{
ContainerServiceClient = GetContainerServiceClient(context);
InternalResourceManagementClient = GetInternalResourceManagementClient(context);
_helper.SetupManagementClients(ContainerServiceClient, InternalResourceManagementClient);
InternalAuthorizationManagementClient = GetAuthorizationManagementClient(context);
InternalGraphRbacManagementClient = GetGraphRbacManagementClient(context);
_helper.SetupManagementClients(ContainerServiceClient,
InternalResourceManagementClient,
InternalAuthorizationManagementClient,
InternalGraphRbacManagementClient);
}

private static ContainerServiceClient GetContainerServiceClient(MockContext context)
{
return context.GetServiceClient<ContainerServiceClient>();
}
private GraphRbacManagementClient GetGraphRbacManagementClient(MockContext context)
{
return context.GetServiceClient<GraphRbacManagementClient>();
}
private static AuthorizationManagementClient GetAuthorizationManagementClient(MockContext context)
{
return context.GetServiceClient<AuthorizationManagementClient>();
}
private static ResourceManagementClient GetInternalResourceManagementClient(MockContext context)
{
return context.GetServiceClient<ResourceManagementClient>();
Expand Down
4 changes: 3 additions & 1 deletion src/Aks/Aks/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
- Additional information about change #1
-->
## Upcoming Release
* Add `Set-AzAksClusterCredential` to reset the ServicePrincipal of an existing AKS cluster.
* Added support `AcrNameToAttach` in `Set-AzAksCluster`. [#14692]
* Added support `AcrNameToDetach` in `Set-AzAksCluster`. [#14693]
* Added `Set-AzAksClusterCredential` to reset the ServicePrincipal of an existing AKS cluster.

## Version 2.0.2
* Refined error messages of cmdlet failure.
Expand Down
86 changes: 30 additions & 56 deletions src/Aks/Aks/Commands/CreateOrUpdateKubeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,61 +116,15 @@ public abstract class CreateOrUpdateKubeBase : KubeCmdletBase
[Alias("SshKeyPath")]
public string SshKeyValue { get; set; }

[Parameter(Mandatory = false, HelpMessage = "Grant the 'acrpull' role of the specified ACR to AKS Service Principal, e.g. myacr")]
public string AcrNameToAttach { get; set; }

[Parameter(Mandatory = false, HelpMessage = "Run cmdlet in the background")]
public SwitchParameter AsJob { get; set; }

[Parameter(Mandatory = false)]
public Hashtable Tag { get; set; }

protected virtual ManagedCluster BuildNewCluster()
{
BeforeBuildNewCluster();

var defaultAgentPoolProfile = new ManagedClusterAgentPoolProfile(
name: NodeName ?? "default",
count: NodeCount,
vmSize: NodeVmSize,
osDiskSizeGB: NodeOsDiskSize);

if (this.IsParameterBound(c => c.NodeMinCount))
{
defaultAgentPoolProfile.MinCount = NodeMinCount;
}
if (this.IsParameterBound(c => c.NodeMaxCount))
{
defaultAgentPoolProfile.MaxCount = NodeMaxCount;
}
if (EnableNodeAutoScaling.IsPresent)
{
defaultAgentPoolProfile.EnableAutoScaling = EnableNodeAutoScaling.ToBool();
}

var pubKey =
new List<ContainerServiceSshPublicKey> { new ContainerServiceSshPublicKey(SshKeyValue) };

var linuxProfile =
new ContainerServiceLinuxProfile(LinuxProfileAdminUserName,
new ContainerServiceSshConfiguration(pubKey));

var acsServicePrincipal = EnsureServicePrincipal(ServicePrincipalIdAndSecret?.UserName, ServicePrincipalIdAndSecret?.Password?.ConvertToString());

var spProfile = new ManagedClusterServicePrincipalProfile(
acsServicePrincipal.SpId,
acsServicePrincipal.ClientSecret);

WriteVerbose(string.Format(Resources.DeployingYourManagedKubeCluster, AcsSpFilePath));
var managedCluster = new ManagedCluster(
Location,
name: Name,
tags: TagsConversionHelper.CreateTagDictionary(Tag, true),
dnsPrefix: DnsNamePrefix,
kubernetesVersion: KubernetesVersion,
agentPoolProfiles: new List<ManagedClusterAgentPoolProfile> { defaultAgentPoolProfile },
linuxProfile: linuxProfile,
servicePrincipalProfile: spProfile);
return managedCluster;
}

protected void BeforeBuildNewCluster()
{
if (!string.IsNullOrEmpty(ResourceGroupName) && string.IsNullOrEmpty(Location))
Expand Down Expand Up @@ -271,17 +225,15 @@ protected AcsServicePrincipal EnsureServicePrincipal(string spId = null, string
{
clientSecret = RandomBase64String(16);
}
var salt = RandomBase64String(3);
var url = $"http://{salt}.{DnsNamePrefix}.{Location}.cloudapp.azure.com";

acsServicePrincipal = BuildServicePrincipal(Name, url, clientSecret);
acsServicePrincipal = BuildServicePrincipal(Name, clientSecret);
WriteVerbose(Resources.CreatedANewServicePrincipalAndAssignedTheContributorRole);
StoreServicePrincipal(acsServicePrincipal);
}
return acsServicePrincipal;
}

private AcsServicePrincipal BuildServicePrincipal(string name, string url, string clientSecret)
private AcsServicePrincipal BuildServicePrincipal(string name, string clientSecret)
{
var pwCreds = new PasswordCredential(
value: clientSecret,
Expand All @@ -291,8 +243,8 @@ private AcsServicePrincipal BuildServicePrincipal(string name, string url, strin
var app = GraphClient.Applications.Create(new ApplicationCreateParameters(
false,
name,
new List<string> { url },
url,
new List<string> { },
null,
passwordCredentials: new List<PasswordCredential> { pwCreds }));

ServicePrincipal sp = null;
Expand All @@ -316,6 +268,22 @@ private AcsServicePrincipal BuildServicePrincipal(string name, string url, strin
return new AcsServicePrincipal { SpId = app.AppId, ClientSecret = clientSecret, ObjectId = app.ObjectId };
}

protected RoleAssignment GetRoleAssignmentWithRoleDefinitionId(string roleDefinitionId)
{
RoleAssignment roleAssignment = null;
var actionSuccess = RetryAction(() =>
{
roleAssignment = AuthClient.RoleAssignments.List().Where(x => x.Properties.RoleDefinitionId == roleDefinitionId && x.Name == Name).FirstOrDefault();
});
if (!actionSuccess)
{
throw new AzPSInvalidOperationException(
Resources.CouldNotGetAcrRoleAssignment,
desensitizedMessage: Resources.CouldNotGetAcrRoleAssignment);
}
return roleAssignment;
}

protected void AddAcrRoleAssignment(string acrName, string acrParameterName, AcsServicePrincipal acsServicePrincipal)
{
string acrResourceId = null;
Expand All @@ -335,8 +303,14 @@ protected void AddAcrRoleAssignment(string acrName, string acrParameterName, Acs
}

var roleId = GetRoleId("acrpull", acrResourceId);
RoleAssignment roleAssignment = GetRoleAssignmentWithRoleDefinitionId(roleId);
if (roleAssignment != null)
{
WriteWarning(string.Format(Resources.AcrRoleAssignmentIsAlreadyExist, acrResourceId));
return;
}
var spObjectId = acsServicePrincipal.ObjectId;
if(spObjectId == null)
if (spObjectId == null)
{
try
{
Expand Down
Loading