Skip to content

upgrade list tag api to track 2 #20528

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 12 commits into from
Jan 5, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ RequiredModules = @(@{ModuleName = 'Az.Accounts'; ModuleVersion = '2.8.0'; })

# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = 'Microsoft.Azure.PowerShell.ContainerRegistry.Sdk.dll',
'Microsoft.Azure.ContainerRegistry.dll'
'Microsoft.Azure.ContainerRegistry.dll',
"Azure.Containers.ContainerRegistry.dll"

# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
Expand Down
2 changes: 1 addition & 1 deletion src/ContainerRegistry/ContainerRegistry/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- Additional information about change #1
-->
## Upcoming Release

* Fixed bug in `Get-AzContainerRegistryTag` to show correct tags [#20528]
## Version 3.0.0
* Updated parameter types from bool to bool? for `Update-AzContainerRegistryRepository` [#17857]
- `ReadEnabled`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Containers.ContainerRegistry" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.ContainerRegistry" Version="1.0.0-preview.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.6.0" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
using System;
using System.Collections.Generic;
using Microsoft.Azure.Commands.Common.Exceptions;
using Track2 = Azure.Containers.ContainerRegistry;
using Azure.Containers.ContainerRegistry;
using Microsoft.Azure.Commands.Common.Strategies;
using Microsoft.Azure.Commands.ContainerRegistry.Track2Models;
using Azure;

namespace Microsoft.Azure.Commands.ContainerRegistry
{
Expand All @@ -33,6 +38,8 @@ public class ContainerRegistryDataPlaneClient
private const string _refreshTokenKey = "AcrRefreshToken";

private AzureContainerRegistryClient _client;
private Track2.ContainerRegistryClient _track2Client;
private Track2TokenCredential _credential;
private string _accessToken = default(string);
private string _endPoint;
private readonly string _suffix;
Expand Down Expand Up @@ -100,6 +107,12 @@ public void SetEndPoint(string RegistryName)
{
_endPoint = RegistryName.ToLower() + '.' + _suffix;
_client.LoginUri = _https + _endPoint;
_credential = new Track2TokenCredential(new DataServiceCredential(AzureSession.Instance.AuthenticationFactory,
_context, AzureEnvironment.ExtendedEndpoint.ContainerRegistryEndpointResourceId));
_track2Client = new Track2.ContainerRegistryClient(new Uri(_https + _endPoint), _credential, new Track2.ContainerRegistryClientOptions()
{
Audience = _context.Environment.ExtendedProperties[AzureEnvironment.ExtendedEndpoint.ContainerRegistryEndpointResourceId]
});
}

public string GetEndPoint()
Expand Down Expand Up @@ -196,7 +209,11 @@ public PSTagAttribute GetTag(string repository, string tag)

public PSTagList ListTag(string repository)
{
return new ContainerRegistryTagListOperation(this, repository).ProcessRequest();
ContainerRepository image = _track2Client.GetRepository(repository);

Pageable<ArtifactManifestProperties> properties = image.GetAllManifestProperties();

return new PSTagList(properties);
}

public bool RemoveTag(string repository, string tag)
Expand Down
18 changes: 18 additions & 0 deletions src/ContainerRegistry/ContainerRegistry/Models/PSTagList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using Azure.Containers.ContainerRegistry;
using Azure;
using Microsoft.Azure.ContainerRegistry.Models;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Azure.Commands.Common.Compute.Version2016_04_preview.Models;
using System.Collections;

namespace Microsoft.Azure.Commands.ContainerRegistry.Models
{
Expand All @@ -24,6 +28,20 @@ public PSTagList()
{
}

public PSTagList(Pageable<ArtifactManifestProperties> properties)
{
this.Tags = new List<PSTagAttributeBase>();
foreach (ArtifactManifestProperties property in properties)
{
foreach (string tag in property.Tags)
{
PSTagAttributeBase newTag = new PSTagAttributeBase(tag, property.Digest, property.CreatedOn.ToString(), property.LastUpdatedOn.ToString(),null ,new ChangeableAttributes(property.CanDelete, property.CanWrite, property.CanList, property.CanRead));
Tags.Add(newTag);
}
this.ImageName = property.RepositoryName;
this.Registry = property.RegistryLoginServer;
}
}
public PSTagList(string registry = default(string), string imageName = default(string), IList<PSTagAttributeBase> tags = default(IList<PSTagAttributeBase>))
{
Registry = registry;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using Microsoft.Azure.Commands.Common.Authentication;
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
using Microsoft.Rest;

namespace Microsoft.Azure.Commands.ContainerRegistry.Track2Models
{
internal class DataServiceCredential
{
private readonly IAuthenticationFactory _authenticationFactory;
private readonly IAzureContext _context;
private readonly string _endpointName;

public DataServiceCredential(IAuthenticationFactory authFactory, IAzureContext context, string resourceIdEndpoint)
{
if (authFactory == null)
throw new ArgumentNullException("authFactory");
if (context == null)
throw new ArgumentNullException("context");
_authenticationFactory = authFactory;
_context = context;
_endpointName = resourceIdEndpoint;
this.TenantId = GetTenantId(context);
}

public string TenantId { get; private set; }

/// <summary>
/// Authentication callback method required by KeyVaultClient
/// </summary>
/// <param name="authority"></param>
/// <param name="resource"></param>
/// <param name="scope"></param>
/// <returns></returns>
public Task<string> OnAuthentication(string authority, string resource, string scope)
{
// TODO: Add trace to log tokenType, resource, authority, scope etc
string tokenStr = string.Empty;

// overriding the cached resourceId value to resource returned from the server
if (!string.IsNullOrEmpty(resource))
{
_context.Environment.SetEndpoint(_endpointName, resource);
}

var bundle = GetTokenInternal(this.TenantId, this._authenticationFactory, this._context, this._endpointName);
bundle.Item1.AuthorizeRequest((tokenType, tokenValue) =>
{
tokenStr = tokenValue;
});
return Task.FromResult<string>(tokenStr);
}

public string GetToken()
{
return GetAccessToken().AccessToken;
}

public IAccessToken GetAccessToken()
{
return GetTokenInternal(TenantId, _authenticationFactory, _context, _endpointName).Item1;
}

private static string GetTenantId(IAzureContext context)
{
if (context.Account == null)
{
throw new ArgumentException("No account found in the context. Please login using Connect-AzAccount.");
}

var tenantId = string.Empty;
if (context.Tenant != null && context.Tenant.GetId() != Guid.Empty)
{
tenantId = context.Tenant.Id.ToString();
}
else if (string.IsNullOrWhiteSpace(tenantId) && context.Subscription != null && context.Account != null)
{
tenantId = context.Subscription.GetPropertyAsArray(AzureSubscription.Property.Tenants)
.Intersect(context.Account.GetPropertyAsArray(AzureAccount.Property.Tenants))
.FirstOrDefault();
}

return tenantId;
}

private static Tuple<IAccessToken, string> GetTokenInternal(string tenantId, IAuthenticationFactory authFactory, IAzureContext context, string resourceIdEndpoint)
{
if (string.IsNullOrWhiteSpace(tenantId))
throw new ArgumentException("No tenant found in the context. Please ensure that the credentials you provided are authorized to access an Azure subscription, then run Connect-AzAccount to login.");

try
{
var tokenCache = AzureSession.Instance.TokenCache;
if (context.TokenCache != null && context.TokenCache.CacheData != null && context.TokenCache.CacheData.Length > 0)
{
tokenCache = context.TokenCache;
}

var accesstoken = authFactory.Authenticate(context.Account, context.Environment, tenantId, null, ShowDialog.Never,
null, tokenCache, resourceIdEndpoint);

if (context.TokenCache != null && context.TokenCache.CacheData != null && context.TokenCache.CacheData.Length > 0)
{
context.TokenCache = tokenCache;
}

return Tuple.Create(accesstoken, context.Environment.GetEndpoint(resourceIdEndpoint));
}
catch (Exception ex)
{
throw new ArgumentException("Your Azure credentials have not been set up or have expired, please run Connect-AzAccount to set up your Azure credentials.", ex);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core;

namespace Microsoft.Azure.Commands.ContainerRegistry.Track2Models
{
internal class Track2TokenCredential : TokenCredential
{
private readonly DataServiceCredential dataServiceCredential;

public Track2TokenCredential(DataServiceCredential dataServiceCredential)
{
this.dataServiceCredential = dataServiceCredential;
}

public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
return new AccessToken(dataServiceCredential.GetToken(), DateTimeOffset.UtcNow);
}

public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
return new ValueTask<AccessToken>(this.GetToken(requestContext, cancellationToken));
}
}
}
34 changes: 17 additions & 17 deletions tools/Common.Netcore.Dependencies.targets
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
<ItemGroup>
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.24"/>
<PackageReference Include="Microsoft.Rest.ClientRuntime.Azure" Version="3.3.19"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Aks" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Authentication.Abstractions" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Authorization" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Common" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Compute" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Graph.Rbac" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.KeyVault" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Monitor" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Network" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.PolicyInsights" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.ResourceManager" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Storage" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Storage.Management" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Strategies" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Websites" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Common.Share" Version="1.3.67-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Aks" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Authentication.Abstractions" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Authorization" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Common" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Compute" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Graph.Rbac" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.KeyVault" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Monitor" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Network" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.PolicyInsights" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.ResourceManager" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Storage" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Storage.Management" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Strategies" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Clients.Websites" Version="1.3.68-preview"/>
<PackageReference Include="Microsoft.Azure.PowerShell.Common.Share" Version="1.3.68-preview"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Azure.Core" Version="1.25.0"/>
Expand All @@ -36,7 +36,7 @@
<PackageReference Include="PowerShellStandard.Library" Version="5.1.0" PrivateAssets="All" />
</ItemGroup>
<PropertyGroup>
<StorageToolsPath>$(NugetPackageRoot)\microsoft.azure.powershell.storage\1.3.67-preview\tools\</StorageToolsPath>
<StorageToolsPath>$(NugetPackageRoot)\microsoft.azure.powershell.storage\1.3.68-preview\tools\</StorageToolsPath>
</PropertyGroup>
<ItemGroup Condition="'$(OmitJsonPackage)' != 'true'">
<PackageReference Include="Newtonsoft.Json" Version="10.0.3"/>
Expand Down