From ac403198f96af5fd574550fd54a5ffa4f092a695 Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Wed, 13 Jan 2021 15:14:39 +0800 Subject: [PATCH 01/13] add ACR repository operations --- src/Accounts/Accounts/ChangeLog.md | 1 + .../Accounts/Context/ClearAzureRmContext.cs | 12 + .../Az.ContainerRegistry.psd1 | 11 +- .../ContainerRegistry/ChangeLog.md | 10 + .../Commands/ConnectAzureContainerRegistry.cs | 12 +- .../GetAzureContainerRegistryRepository.cs | 45 ++++ .../Commands/GetAzureContainerRegistryTag.cs | 46 ++++ .../GetAzureContainerReigstryManifest.cs | 46 ++++ .../RemoveAzureContainerRegistryManifest.cs | 52 ++++ .../RemoveAzureContainerRegistryRepository.cs | 33 +++ .../Commands/RemoveContainerRegistryTag.cs | 36 +++ .../UpdateAzureContainerRegistryManifest.cs | 71 ++++++ .../UpdateAzureContainerRegistryRepository.cs | 50 ++++ .../UpdateAzureContainerRegistryTag.cs | 55 ++++ .../ContainerRegistry.csproj | 4 + ...ContainerRegistryDataPlaneOperationBase.cs | 82 ++++++ .../ContainerRegistryManifestGetOperation.cs | 67 +++++ .../ContainerRegistryManifestListOperation.cs | 65 +++++ ...ontainerRegistryManifestRemoveOperation.cs | 66 +++++ ...ontainerRegistryManifestUpdateOperation.cs | 67 +++++ ...ContainerRegistryRepositoryGetOperation.cs | 65 +++++ ...ontainerRegistryRepositoryListOperation.cs | 91 +++++++ ...tainerRegistryRepositoryRemoveOperation.cs | 65 +++++ ...tainerRegistryRepositoryUpdateOperation.cs | 67 +++++ .../ContainerRegistryTagGetOperation.cs | 67 +++++ .../ContainerRegistryTagListOperation.cs | 65 +++++ .../ContainerRegistryTagRemoveOperation.cs | 67 +++++ .../ContainerRegistryTagUpdateOperation.cs | 67 +++++ .../Models/ContainerRegistryCmdletBase.cs | 3 - .../ContainerRegistryDataPlaneClient.cs | 181 +++++++++++-- .../ContainerRegistryDataPlaneCmdletBase.cs | 51 ++++ .../ContainerRegistry/Models/PSAcrManifest.cs | 46 ++++ .../ContainerRegistry/Models/PSAcrToken.cs | 43 ++++ .../Models/PSChangeableAttribute.cs | 59 +++++ .../Models/PSDeletedRepository.cs | 40 +++ .../Models/PSManifestAttribute.cs | 54 ++++ .../Models/PSManifestAttributeBase.cs | 90 +++++++ .../Models/PSRepositoryAttribute.cs | 60 +++++ .../Models/PSTagAttribute.cs | 58 +++++ .../Models/PSTagAttributeBase.cs | 73 ++++++ .../ContainerRegistry/Models/PSTagList.cs | 61 +++++ .../Models/RepoAccessTokenPermission.cs | 16 ++ .../help/Az.ContainerRegistry.md | 27 ++ .../help/Connect-AzContainerRegistry.md | 2 +- .../help/Get-AzContainerRegistryManifest.md | 134 ++++++++++ .../help/Get-AzContainerRegistryRepository.md | 146 +++++++++++ .../help/Get-AzContainerRegistryTag.md | 134 ++++++++++ .../Remove-AzContainerRegistryManifest.md | 172 +++++++++++++ .../Remove-AzContainerRegistryRepository.md | 127 +++++++++ .../help/Remove-AzContainerRegistryTag.md | 142 +++++++++++ .../Update-AzContainerRegistryManifest.md | 240 ++++++++++++++++++ .../Update-AzContainerRegistryRepository.md | 192 ++++++++++++++ .../help/Update-AzContainerRegistryTag.md | 206 +++++++++++++++ .../MissingAssemblies.csv | 4 +- 54 files changed, 3717 insertions(+), 29 deletions(-) create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryRepository.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryTag.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerReigstryManifest.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryManifest.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryRepository.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/RemoveContainerRegistryTag.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryManifest.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryRepository.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryTag.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestGetOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestListOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestRemoveOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestUpdateOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryGetOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryListOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryRemoveOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryUpdateOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagGetOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagListOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagRemoveOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagUpdateOperation.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneCmdletBase.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSAcrManifest.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSAcrToken.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSChangeableAttribute.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSDeletedRepository.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSManifestAttribute.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSManifestAttributeBase.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSRepositoryAttribute.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSTagAttribute.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSTagAttributeBase.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSTagList.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/RepoAccessTokenPermission.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryManifest.md create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryRepository.md create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryTag.md create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryManifest.md create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryRepository.md create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryTag.md create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryManifest.md create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryRepository.md create mode 100644 src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryTag.md diff --git a/src/Accounts/Accounts/ChangeLog.md b/src/Accounts/Accounts/ChangeLog.md index 0dfa9b194349..4205de043dc5 100644 --- a/src/Accounts/Accounts/ChangeLog.md +++ b/src/Accounts/Accounts/ChangeLog.md @@ -18,6 +18,7 @@ - Additional information about change #1 --> ## Upcoming Release +* Updated `Clear-AzContext` to clean token cache created by Az.ContainerRegistry * Shown correct client request id on debug message [#13745] * Added common Azure PowerShell exception type * Supported storage API 2019-06-01 diff --git a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs index c2649392ed5c..f3a752a7b9f5 100644 --- a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs +++ b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs @@ -12,6 +12,8 @@ // limitations under the License. // ---------------------------------------------------------------------------------- +using System; +using System.Collections.Generic; using System.IO; using System.Management.Automation; @@ -21,6 +23,7 @@ using Microsoft.Azure.Commands.Profile.Common; using Microsoft.Azure.Commands.Profile.Properties; using Microsoft.Azure.Commands.ResourceManager.Common; +using Microsoft.WindowsAzure.Commands.Common; namespace Microsoft.Azure.Commands.Profile.Context { @@ -84,6 +87,15 @@ void ClearContext(AzureRmProfile profile, RMProfileClient client) profile.TrySetDefaultContext(defaultContext); result = true; } + + //clean token cache created by Az.ContainerRegistry + string AcrTokenCacheKey = SharedComponentKeys.AcrTokenCacheKey; + IDictionary> acrTokenCache; + if (AzureSession.Instance.TryGetComponent(AcrTokenCacheKey, out acrTokenCache)) + { + acrTokenCache.Clear(); + AzureSession.Instance.UnregisterComponent>>(AcrTokenCacheKey); + } } if (PassThru.IsPresent) diff --git a/src/ContainerRegistry/ContainerRegistry/Az.ContainerRegistry.psd1 b/src/ContainerRegistry/ContainerRegistry/Az.ContainerRegistry.psd1 index 75f7b4eb874e..6fe7c2d7e0dc 100644 --- a/src/ContainerRegistry/ContainerRegistry/Az.ContainerRegistry.psd1 +++ b/src/ContainerRegistry/ContainerRegistry/Az.ContainerRegistry.psd1 @@ -90,7 +90,16 @@ CmdletsToExport = 'New-AzContainerRegistry', 'Get-AzContainerRegistry', 'Get-AzContainerRegistryWebhookEvent', 'Import-AzContainerRegistryImage', 'Get-AzContainerRegistryUsage', 'Set-AzContainerRegistryNetworkRuleSet', - 'New-AzContainerRegistryNetworkRule', 'Connect-AzContainerRegistry' + 'New-AzContainerRegistryNetworkRule', 'Connect-AzContainerRegistry', + 'Get-AzContainerRegistryRepository', + 'Remove-AzContainerRegistryRepository', + 'Update-AzContainerRegistryRepository', + 'Get-AzContainerRegistryManifest', + 'Remove-AzContainerRegistryManifest', + 'Update-AzContainerRegistryManifest', + 'Get-AzContainerRegistryTag', + 'Update-AzContainerRegistryTag', + 'Remove-AzContainerRegistryTag' # Variables to export from this module # VariablesToExport = @() diff --git a/src/ContainerRegistry/ContainerRegistry/ChangeLog.md b/src/ContainerRegistry/ContainerRegistry/ChangeLog.md index cf238796e9ad..8d7ff100e814 100644 --- a/src/ContainerRegistry/ContainerRegistry/ChangeLog.md +++ b/src/ContainerRegistry/ContainerRegistry/ChangeLog.md @@ -18,6 +18,16 @@ - Additional information about change #1 --> ## Upcoming Release +* Added cmdlets: + - `Get-AzContainerRegistryRepository` + - `Update-AzContainerRegistryRepository` + - `Remove-AzContainerRegistryRepository` + - `Get-AzContainerRegistryManifest` + - `Update-AzContainerRegistryManifest` + - `Remove-AzContainerRegistryManifest` + - `Get-AzContainerRegistryTag` + - `Update-AzContainerRegistryTag` + - `Remove-AzContainerRegistryTag` ## Version 2.1.0 * Supported parameter `Name` for and value from pipeline input for `Get-AzContainerRegistryUsage` [#13605] diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/ConnectAzureContainerRegistry.cs b/src/ContainerRegistry/ContainerRegistry/Commands/ConnectAzureContainerRegistry.cs index 22e52d3a9d85..25782f564e0f 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/ConnectAzureContainerRegistry.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/ConnectAzureContainerRegistry.cs @@ -12,12 +12,8 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Azure.ServiceManagement.Common.Models; -using Microsoft.WindowsAzure.Commands.Common; using Microsoft.WindowsAzure.Commands.Utilities.Common; using System; -using System.Collections.Generic; -using System.Linq; using System.Management.Automation; using System.Text.RegularExpressions; @@ -27,8 +23,12 @@ namespace Microsoft.Azure.Commands.ContainerRegistry [OutputType(typeof(bool))] public class ConnectAzureContainerRegistry : ContainerRegistryCmdletBase { + protected const string WithoutNameAndPasswordParameterSet = "WithoutNameAndPasswordParameterSet"; + protected const string WithNameAndPasswordParameterSet = "WithNameAndPasswordParameterSet"; + [Parameter(Mandatory = true, HelpMessage = "Azure Container Registry Name.", ParameterSetName = WithoutNameAndPasswordParameterSet)] [Parameter(Mandatory = true, HelpMessage = "Azure Container Registry Name.", ParameterSetName = WithNameAndPasswordParameterSet)] + [Alias("RegistryName")] [ValidateNotNullOrEmpty] public string Name { get; set; } @@ -40,8 +40,6 @@ public class ConnectAzureContainerRegistry : ContainerRegistryCmdletBase [ValidateNotNullOrEmpty] public string Password { get; set; } - private RecordingTracingInterceptor _httpTracingInterceptor { get; set; } - protected override void InitDebuggingFilter() { AddDebuggingFilter(new Regex("(\\s*access_token\\s*=\\s*)[^\"]+")); @@ -57,7 +55,7 @@ public override void ExecuteCmdlet() { if (ParameterSetName.Equals(WithoutNameAndPasswordParameterSet)) { this.UserName = new Guid().ToString(); - this.Password = this.RegistryDataPlaneClient.GetRefreshToken(); + this.Password = this.RegistryDataPlaneClient.TryAuthenticate(); } string LoginScript = string.Format("'{2}' | docker login {0} -u {1} --password-stdin", this.RegistryDataPlaneClient.GetEndPoint(), this.UserName, this.Password); diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryRepository.cs b/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryRepository.cs new file mode 100644 index 000000000000..f0a6c60f4240 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryRepository.cs @@ -0,0 +1,45 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry +{ + [Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryRepository", DefaultParameterSetName = ListParameterSet)] + [OutputType(typeof(PSAcrManifest), typeof(PSManifestAttribute))] + public class GetAzureContainerRegistryRepository : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(ParameterSetName = GetParameterSet, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter(ParameterSetName = ListParameterSet, Mandatory = false, HelpMessage = "First n results.")] + [ValidateNotNullOrEmpty] + public int? First { get; set; } = null; + + public override void ExecuteChildCmdlet() + { + if (this.IsParameterBound(c => c.Name)) + { + WriteObject(this.RegistryDataPlaneClient.GetRepository(Name)); + } + else + { + WriteObject(this.RegistryDataPlaneClient.ListRepository(First), true); + } + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryTag.cs b/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryTag.cs new file mode 100644 index 000000000000..cd5de3c82978 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryTag.cs @@ -0,0 +1,46 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry +{ + [Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryTag", DefaultParameterSetName = ListParameterSet)] + [OutputType(typeof(PSTagAttribute), typeof(PSTagList))] + public class GetAzureContainerRegistryTag : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(ParameterSetName = ListParameterSet, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [Parameter(ParameterSetName = GetParameterSet, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string RepositoryName { get; set; } + + [Parameter(ParameterSetName = GetParameterSet, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Tag.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + public override void ExecuteChildCmdlet() + { + if (this.IsParameterBound(c => c.Name)) + { + WriteObject(this.RegistryDataPlaneClient.GetTag(RepositoryName, Name)); + } + else + { + WriteObject(this.RegistryDataPlaneClient.ListTag(RepositoryName), true); + } + } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerReigstryManifest.cs b/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerReigstryManifest.cs new file mode 100644 index 000000000000..33c6eecd8925 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerReigstryManifest.cs @@ -0,0 +1,46 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry +{ + [Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryManifest", DefaultParameterSetName = ListParameterSet)] + [OutputType(typeof(PSManifestAttribute), typeof(PSAcrManifest))] + public class GetAzureContainerRegistryManifest : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(ParameterSetName = ListParameterSet, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [Parameter(ParameterSetName = GetParameterSet, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string RepositoryName { get; set; } + + [Parameter(ParameterSetName = GetParameterSet, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Manifest reference.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + public override void ExecuteChildCmdlet() + { + if (this.IsParameterBound(c => c.Name)) + { + WriteObject(this.RegistryDataPlaneClient.GetManifest(RepositoryName, Name)); + } + else + { + WriteObject(this.RegistryDataPlaneClient.ListManifest(RepositoryName), true); + } + } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryManifest.cs b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryManifest.cs new file mode 100644 index 000000000000..32692c566005 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryManifest.cs @@ -0,0 +1,52 @@ +// ---------------------------------------------------------------------------------- +// +// 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 System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Commands +{ + [Cmdlet("Remove", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryManifest", DefaultParameterSetName = ByManifestParameterSet, SupportsShouldProcess = true)] + [OutputType(typeof(bool))] + public class RemoveAzureContainerRegistryManifest : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(Mandatory = true, ParameterSetName = ByManifestParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [Parameter(Mandatory = true, ParameterSetName = ByTagParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string RepositoryName { get; set; } + + [Parameter(Mandatory = true, ParameterSetName = ByManifestParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "Manifest reference.")] + [ValidateNotNullOrEmpty] + public string Manifest { get; set; } + + [Parameter(Mandatory = true, ParameterSetName = ByTagParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "Tag.")] + [ValidateNotNullOrEmpty] + public string Tag { get; set; } + + public override void ExecuteChildCmdlet() + { + if (ParameterSetName.Equals(ByManifestParameterSet)) + { + WriteObject(this.RegistryDataPlaneClient.RemoveManifest(this.RepositoryName, this.Manifest)); + } + else if (ParameterSetName.Equals(ByTagParameterSet)) + { + WriteObject(this.RegistryDataPlaneClient.RemoveManifestByTag(this.RepositoryName, this.Tag)); + } + else + { + throw new PSArgumentException("Invalid parameter set"); + } + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryRepository.cs b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryRepository.cs new file mode 100644 index 000000000000..8953606c74db --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryRepository.cs @@ -0,0 +1,33 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Commands +{ + [Cmdlet("Remove", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryRepository", SupportsShouldProcess = true)] + [OutputType(typeof(PSDeletedRepository))] + public class RemoveAzureContainerRegistryRepository : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + public override void ExecuteChildCmdlet() + { + WriteObject(this.RegistryDataPlaneClient.RemoveRepository(this.Name)); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveContainerRegistryTag.cs b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveContainerRegistryTag.cs new file mode 100644 index 000000000000..ba6929bf9912 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveContainerRegistryTag.cs @@ -0,0 +1,36 @@ +// ---------------------------------------------------------------------------------- +// +// 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 System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Commands +{ + [Cmdlet("Remove", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryTag", SupportsShouldProcess = true)] + [OutputType(typeof(bool))] + public class RemoveAzureContainerRegistryTag : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string RepositoryName { get; set; } + + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Tag.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + public override void ExecuteChildCmdlet() + { + WriteObject(this.RegistryDataPlaneClient.RemoveTag(this.RepositoryName, this.Name)); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryManifest.cs b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryManifest.cs new file mode 100644 index 000000000000..97cbe9e965b1 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryManifest.cs @@ -0,0 +1,71 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Commands +{ + [Cmdlet("Update", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryManifest", DefaultParameterSetName = ByManifestParameterSet, SupportsShouldProcess = true)] + [OutputType(typeof(PSManifestAttribute))] + public class UpdateAzureContainerRegistryManifest : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(Mandatory = true, ParameterSetName = ByManifestParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [Parameter(Mandatory = true, ParameterSetName = ByTagParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string RepositoryName { get; set; } + + [Parameter(Mandatory = true, ParameterSetName = ByManifestParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "Manifest reference.")] + [ValidateNotNullOrEmpty] + public string Manifest { get; set; } + + [Parameter(Mandatory = true, ParameterSetName = ByTagParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "Tag.")] + [ValidateNotNullOrEmpty] + public string Tag { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Delete enable.")] + [ValidateNotNullOrEmpty] + public bool? DeleteEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Write enable.")] + [ValidateNotNullOrEmpty] + public bool? WriteEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "List enable.")] + [ValidateNotNullOrEmpty] + public bool? ListEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Read enable.")] + [ValidateNotNullOrEmpty] + public bool? ReadEnabled { get; set; } + + public override void ExecuteChildCmdlet() + { + PSChangeableAttribute attribute = new PSChangeableAttribute(DeleteEnabled, WriteEnabled, ListEnabled, ReadEnabled); + if (ParameterSetName.Equals(ByManifestParameterSet)) + { + WriteObject(this.RegistryDataPlaneClient.UpdateManifest(this.RepositoryName, this.Manifest, attribute)); + } + else if(ParameterSetName.Equals(ByTagParameterSet)) + { + WriteObject(this.RegistryDataPlaneClient.UpdateManifestByTag(this.RepositoryName, this.Tag, attribute)); + } + else + { + throw new PSArgumentException("Invalid parameter set"); + } + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryRepository.cs b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryRepository.cs new file mode 100644 index 000000000000..bbc496042c4d --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryRepository.cs @@ -0,0 +1,50 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Commands +{ + [Cmdlet("Update", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryRepository", SupportsShouldProcess = true)] + [OutputType(typeof(PSRepositoryAttribute))] + public class UpdateAzureContainerRegistryRepository : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Delete enable.")] + [ValidateNotNullOrEmpty] + public bool DeleteEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Write enable.")] + [ValidateNotNullOrEmpty] + public bool WriteEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "List enable.")] + [ValidateNotNullOrEmpty] + public bool ListEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Read enable.")] + [ValidateNotNullOrEmpty] + public bool ReadEnabled { get; set; } + + public override void ExecuteChildCmdlet() + { + WriteObject(this.RegistryDataPlaneClient.UpdateRepository(this.Name, new PSChangeableAttribute(DeleteEnabled, WriteEnabled, ListEnabled, ReadEnabled))); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryTag.cs b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryTag.cs new file mode 100644 index 000000000000..a020cad90b85 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryTag.cs @@ -0,0 +1,55 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Commands +{ + [Cmdlet("Update", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryTag", SupportsShouldProcess = true)] + [OutputType(typeof(PSTagAttribute))] + public class UpdateAzureContainerRegistryTag : ContainerRegistryDataPlaneCmdletBase + { + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] + [ValidateNotNullOrEmpty] + public string RepositoryName { get; set; } + + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Tag.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Delete enable.")] + [ValidateNotNullOrEmpty] + public bool? DeleteEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Write enable.")] + [ValidateNotNullOrEmpty] + public bool? WriteEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "List enable.")] + [ValidateNotNullOrEmpty] + public bool? ListEnabled { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Read enable.")] + [ValidateNotNullOrEmpty] + public bool? ReadEnabled { get; set; } + + public override void ExecuteChildCmdlet() + { + PSChangeableAttribute attribute = new PSChangeableAttribute(DeleteEnabled, WriteEnabled, ListEnabled, ReadEnabled); + WriteObject(this.RegistryDataPlaneClient.UpdateTag(this.RepositoryName, this.Name, attribute)); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/ContainerRegistry.csproj b/src/ContainerRegistry/ContainerRegistry/ContainerRegistry.csproj index 606db8621ed4..f70510a00404 100644 --- a/src/ContainerRegistry/ContainerRegistry/ContainerRegistry.csproj +++ b/src/ContainerRegistry/ContainerRegistry/ContainerRegistry.csproj @@ -16,4 +16,8 @@ + + + + \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs new file mode 100644 index 000000000000..93b796c54b3e --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs @@ -0,0 +1,82 @@ +// ---------------------------------------------------------------------------------- +// +// 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 System; +using System.Web; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public abstract class ContainerRegistryDataPlaneOperationBase + { + protected ContainerRegistryDataPlaneClient _client; + protected virtual string _scope + { + get + { + return String.Format("{0}:{1}:{2}", _resource, _name, _permission); + } + set + { + + } + } + + protected virtual string _resource + { + get + { + return "registry"; + } + } + + protected virtual string _name + { + get + { + return "catalog"; + } + } + + protected virtual string _permission + { + get + { + return "*"; + } + } + + public ContainerRegistryDataPlaneOperationBase(ContainerRegistryDataPlaneClient client) + { + this._client = client; + } + + public T ProcessRequest() + { + _client.TryAuthenticate(_scope); + return SendRequest(); + } + + public virtual T SendRequest() + { + throw new NotImplementedException(); + } + + protected string getLastListed(string nextLink) + { + int left = nextLink.IndexOf('='); + int right = nextLink.IndexOf('&'); + return HttpUtility.UrlDecode(nextLink.Substring(left + 1, right - left - 1)); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestGetOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestGetOperation.cs new file mode 100644 index 000000000000..5dd27c8ed1d7 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestGetOperation.cs @@ -0,0 +1,67 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; +using Microsoft.Azure.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryManifestGetOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + private readonly string _manifestReference; + + public ContainerRegistryManifestGetOperation(ContainerRegistryDataPlaneClient client, string repository, string manifest) : base(client) + { + this._repositoryName = repository; + _manifestReference = manifest; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.METADATA_READ; + } + } + + public override PSManifestAttribute SendRequest() + { + ManifestAttributes manifest = _client + .GetClient() + .Manifests + .GetAttributesAsync(_repositoryName, _manifestReference) + .GetAwaiter() + .GetResult(); + return new PSManifestAttribute(manifest); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestListOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestListOperation.cs new file mode 100644 index 000000000000..43ece041ad81 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestListOperation.cs @@ -0,0 +1,65 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; +using Microsoft.Azure.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryManifestListOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + + public ContainerRegistryManifestListOperation(ContainerRegistryDataPlaneClient client, string repository) : base(client) + { + this._repositoryName = repository; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.METADATA_READ; + } + } + + public override PSAcrManifest SendRequest() + { + AcrManifests manifest = _client + .GetClient() + .Manifests + .GetListAsync(_repositoryName) + .GetAwaiter() + .GetResult(); + return new PSAcrManifest(manifest); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestRemoveOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestRemoveOperation.cs new file mode 100644 index 000000000000..c072ab3e82ac --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestRemoveOperation.cs @@ -0,0 +1,66 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryManifestRemoveOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + private readonly string _manifestReference; + + public ContainerRegistryManifestRemoveOperation(ContainerRegistryDataPlaneClient client, string repository, string manifest) : base(client) + { + this._repositoryName = repository; + this._manifestReference = manifest; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.DELETE_META_READ; + } + } + + public override bool SendRequest() + { + _client + .GetClient() + .Manifests + .DeleteAsync(_repositoryName, _manifestReference) + .GetAwaiter() + .GetResult(); + return true; + } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestUpdateOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestUpdateOperation.cs new file mode 100644 index 000000000000..066fad3f76c9 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestUpdateOperation.cs @@ -0,0 +1,67 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryManifestUpdateOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + private readonly string _manifestReference; + private readonly PSChangeableAttribute _attribute; + + public ContainerRegistryManifestUpdateOperation(ContainerRegistryDataPlaneClient client, string repository, string manifest, PSChangeableAttribute attribute) : base(client) + { + this._repositoryName = repository; + this._manifestReference = manifest; + this._attribute = attribute; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.META_WRITE_META_READ; + } + } + + public override PSManifestAttribute SendRequest() + { + _client.GetClient() + .Manifests + .UpdateAttributesAsync(_repositoryName, _manifestReference, _attribute.GetAttribute()) + .GetAwaiter() + .GetResult(); + return new PSManifestAttribute(); + } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryGetOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryGetOperation.cs new file mode 100644 index 000000000000..bdc0642fc661 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryGetOperation.cs @@ -0,0 +1,65 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; +using Microsoft.Azure.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryRepositoryGetOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + + public ContainerRegistryRepositoryGetOperation(ContainerRegistryDataPlaneClient client, string name) : base(client) + { + this._repositoryName = name; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.METADATA_READ; + } + } + + public override PSRepositoryAttribute SendRequest() + { + RepositoryAttributes attribute = _client + .GetClient() + .Repository + .GetAttributesAsync(_repositoryName) + .GetAwaiter() + .GetResult(); + return new PSRepositoryAttribute(attribute); + } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryListOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryListOperation.cs new file mode 100644 index 000000000000..46b97c27a56e --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryListOperation.cs @@ -0,0 +1,91 @@ +// ---------------------------------------------------------------------------------- +// +// 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 System; +using System.Collections.Generic; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryRepositoryListOperation : ContainerRegistryDataPlaneOperationBase> + { + private const int _defaultPagination = 100; + private readonly int? _first; + + public ContainerRegistryRepositoryListOperation(ContainerRegistryDataPlaneClient client, int? first) : base(client) + { + this._first = first; + } + + public override IList SendRequest() + { + int? first = _first; + string last = default(string); + IList repositories = null; + + bool hasNext = true; + while (hasNext) + { + hasNext = false; + int? size = _defaultPagination; + if (first != null) + { + size = first > _defaultPagination ? _defaultPagination : first; + first -= size; + } + + var response = _client + .GetClient() + .Repository + .GetListWithHttpMessagesAsync(last: last, n: size) + .GetAwaiter() + .GetResult(); + + IList names = response.Body.Names; + if (repositories == null) + { + repositories = new List(); + } + if (names != null && names.Count != 0) + { + foreach (string name in names) + { + repositories.Add(name); + } + } + + if (first != null && first <= 0) + { + break; + } + + string nextLink = response.Headers.Link; + if (nextLink != null && nextLink.Length != 0) + { + try + { + last = getLastListed(nextLink); + hasNext = true; + } + catch + { + throw new PSInvalidOperationException(string.Format("Invalid next link: {0}", nextLink)); + } + } + } + + return repositories; + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryRemoveOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryRemoveOperation.cs new file mode 100644 index 000000000000..84b131c43fd9 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryRemoveOperation.cs @@ -0,0 +1,65 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; +using Microsoft.Azure.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryRepositoryRemoveOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + + public ContainerRegistryRepositoryRemoveOperation(ContainerRegistryDataPlaneClient client, string name) : base(client) + { + this._repositoryName = name; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.DELETE_META_READ; + } + } + + public override PSDeletedRepository SendRequest() + { + DeletedRepository deleted = _client + .GetClient() + .Repository + .DeleteAsync(_repositoryName) + .GetAwaiter() + .GetResult(); + return new PSDeletedRepository(deleted); + } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryUpdateOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryUpdateOperation.cs new file mode 100644 index 000000000000..9e3b1f9344a6 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryUpdateOperation.cs @@ -0,0 +1,67 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; +using System; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryRepositoryUpdateOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + private readonly PSChangeableAttribute _attribute; + + public ContainerRegistryRepositoryUpdateOperation(ContainerRegistryDataPlaneClient client, string name, PSChangeableAttribute attribute) : base(client) + { + this._repositoryName = name; + this._attribute = attribute; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.META_WRITE_META_READ; + } + } + + public override PSRepositoryAttribute SendRequest() + { + _client.GetClient() + .Repository + .UpdateAttributesAsync(_repositoryName, _attribute.GetAttribute()) + .GetAwaiter() + .GetResult(); + return new PSRepositoryAttribute(); + } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagGetOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagGetOperation.cs new file mode 100644 index 000000000000..3b02f03804c0 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagGetOperation.cs @@ -0,0 +1,67 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; +using Microsoft.Azure.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryTagGetOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + private readonly string _tag; + + public ContainerRegistryTagGetOperation(ContainerRegistryDataPlaneClient client, string repository, string tag) : base(client) + { + this._repositoryName = repository; + _tag = tag; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.METADATA_READ; + } + } + + public override PSTagAttribute SendRequest() + { + TagAttributes tag = _client + .GetClient() + .Tag + .GetAttributesAsync(_repositoryName, _tag) + .GetAwaiter() + .GetResult(); + return new PSTagAttribute(tag); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagListOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagListOperation.cs new file mode 100644 index 000000000000..6623240c0309 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagListOperation.cs @@ -0,0 +1,65 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; +using Microsoft.Azure.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryTagListOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + + public ContainerRegistryTagListOperation(ContainerRegistryDataPlaneClient client, string repository) : base(client) + { + this._repositoryName = repository; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.METADATA_READ; + } + } + + public override PSTagList SendRequest() + { + TagList tags = _client + .GetClient() + .Tag + .GetListAsync(_repositoryName) + .GetAwaiter() + .GetResult(); + return new PSTagList(tags); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagRemoveOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagRemoveOperation.cs new file mode 100644 index 000000000000..19c451ee45d4 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagRemoveOperation.cs @@ -0,0 +1,67 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; +using Microsoft.Azure.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryTagRemoveOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + private readonly string _tag; + + public ContainerRegistryTagRemoveOperation(ContainerRegistryDataPlaneClient client, string repository, string tag) : base(client) + { + this._repositoryName = repository; + this._tag = tag; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.DELETE; + } + } + + public override bool SendRequest() + { + _client + .GetClient() + .Tag + .DeleteAsync(_repositoryName, _tag) + .GetAwaiter() + .GetResult(); + return true; + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagUpdateOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagUpdateOperation.cs new file mode 100644 index 000000000000..4f2eb404aead --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagUpdateOperation.cs @@ -0,0 +1,67 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using Microsoft.Azure.ContainerRegistry; + +namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations +{ + public class ContainerRegistryTagUpdateOperation : ContainerRegistryDataPlaneOperationBase + { + private readonly string _repositoryName; + private readonly string _tag; + private readonly PSChangeableAttribute _attribute; + + public ContainerRegistryTagUpdateOperation(ContainerRegistryDataPlaneClient client, string repository, string tag, PSChangeableAttribute attribute) : base(client) + { + this._repositoryName = repository; + this._tag = tag; + this._attribute = attribute; + } + + protected override string _resource + { + get + { + return "repository"; + } + } + + protected override string _name + { + get + { + return this._repositoryName; + } + } + + protected override string _permission + { + get + { + return RepoAccessTokenPermission.META_WRITE_META_READ; + } + } + + public override PSTagAttribute SendRequest() + { + _client.GetClient() + .Tag + .UpdateAttributesAsync(_repositoryName, _tag, _attribute.GetAttribute()) + .GetAwaiter() + .GetResult(); + return new PSTagAttribute(); + } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryCmdletBase.cs b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryCmdletBase.cs index aaa5c2cc0294..bad535fd5a26 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryCmdletBase.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryCmdletBase.cs @@ -85,9 +85,6 @@ public abstract class ContainerRegistryCmdletBase : AzureRMCmdlet protected const string InvalidRegistryOrReplicationResourceIdErrorMessage = "This is an invalid container registry resource id or replication resource id"; protected const string InvalidReplicationResourceIdErrorMessage = "This is an invalid replication resource id"; - protected const string WithoutNameAndPasswordParameterSet = "WithoutNameAndPasswordParameterSet"; - protected const string WithNameAndPasswordParameterSet = "WithNameAndPasswordParameterSet"; - protected struct PasswordNameStrings { internal const string Password = "password"; diff --git a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs index d238589d5cbd..76b5b6b87c43 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs @@ -14,23 +14,36 @@ using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; +using Microsoft.Azure.Commands.Common.Authentication.Authentication; +using Microsoft.Azure.Commands.ContainerRegistry.Models; +using Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations; using Microsoft.Azure.ContainerRegistry; using Microsoft.Azure.Management.ContainerRegistry; using Microsoft.Rest; using System; +using System.Collections.Generic; +using Microsoft.WindowsAzure.Commands.Common; +using Microsoft.Azure.Commands.Profile.Utilities; +using System.Text.Json; +using System.Linq; namespace Microsoft.Azure.Commands.ContainerRegistry { public class ContainerRegistryDataPlaneClient { private AzureContainerRegistryClient _client; - private ServiceClientCredentials _clientCredential; - private IAccessToken _accessToken; + private string _accessToken = default(string); private string _endPoint; + private IAzureContext _context; + private readonly string _suffix; + private const string _grantType = "access_token"; - private const string _scope = "registry:catalog:*"; + private const string _scopeDefault = "registry:catalog:*"; private const string _https = "https://"; - private readonly string _suffix; + private const string _refreshTokenKey = "AcrRefreshToken"; + private const string _acrTokenCacheKey = SharedComponentKeys.AcrTokenCacheKey; + private const int _minutesBeforeExpiration = 5; + public Action VerboseLogger { get; set; } public Action ErrorLogger { get; set; } @@ -38,22 +51,63 @@ public class ContainerRegistryDataPlaneClient public ContainerRegistryDataPlaneClient(IAzureContext context) { - _clientCredential = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(context, AzureEnvironment.Endpoint.ResourceManager); - _accessToken = AzureSession.Instance.AuthenticationFactory.Authenticate(context.Account, context.Environment, context.Tenant.Id, null, ShowDialog.Never, null, context.Environment.GetTokenAudience(AzureEnvironment.Endpoint.ResourceManager)); + _context = context; _suffix = context.Environment.ContainerRegistryEndpointSuffix; - _client = AzureSession.Instance.ClientFactory.CreateCustomArmClient(_clientCredential); + ServiceClientCredentials clientCredential = new RenewingTokenCredential(new ExternalAccessToken(_accessToken, () => _accessToken)); + _client = AzureSession.Instance.ClientFactory.CreateCustomArmClient(clientCredential); + } + + public IDictionary> TryGetTokenCache() + { + IDictionary> cache; + if (!AzureSession.Instance.TryGetComponent(_acrTokenCacheKey, out cache)) + { + AzureSession.Instance.RegisterComponent>>(_acrTokenCacheKey, () => new Dictionary>()); + AzureSession.Instance.TryGetComponent(_acrTokenCacheKey, out cache); + } + return cache; + } + + public AzureContainerRegistryClient GetClient() + { + return _client; + } + + public string TryAuthenticate(string scope = _scopeDefault) + { + _accessToken = TryGetToken(scope); + return _accessToken; + } + + private string TryGetToken(string key) + { + IDictionary> cache = TryGetTokenCache(); + Tuple value; + cache.TryGetValue(key, out value); + if (value == null || isTokenExpired(value)) + { + string token = key.Equals(_refreshTokenKey) ? getRefreshToken() : getAccessToken(key); + value = new Tuple(token, getTokenExpiration(token)); + cache[key] = value; + } + return value.Item1; } - public string GetRefreshToken() + private DateTime getTokenExpiration(string token) { - var response = _client.RefreshTokens.GetFromExchangeAsync(grantType: _grantType, service: _endPoint, accessToken: _accessToken.AccessToken); - return response.GetAwaiter().GetResult().RefreshTokenProperty; + string decodedToken = Base64UrlHelper.DecodeToString(token.Split('.')[1]); + int unixTimeSeconds = JsonDocument.Parse(decodedToken) + .RootElement + .EnumerateObject() + .Where(p => p.Name == "exp") + .Select(p => p.Value.GetInt32()) + .First(); + return DateTimeOffset.FromUnixTimeSeconds(unixTimeSeconds).UtcDateTime; } - public string GetAccessToken() + private bool isTokenExpired(Tuple value) { - var response = _client.AccessTokens.GetAsync(service: _endPoint, scope: _scope, refreshToken: GetRefreshToken()); - return response.GetAwaiter().GetResult().AccessTokenProperty; + return (value.Item2 - DateTime.UtcNow).Minutes <= _minutesBeforeExpiration; } public void SetEndPoint(string RegistryName) @@ -66,10 +120,105 @@ public string GetEndPoint() { return _endPoint; } + + private string getAccessToken(string scope) + { + string refreshToken = TryGetToken(_refreshTokenKey); + return GetClient() + .AccessTokens + .GetAsync(service: _endPoint, scope: scope, refreshToken: refreshToken) + .GetAwaiter() + .GetResult() + .AccessTokenProperty; + } + + private string getRefreshToken() + { + string armAccessToken = AzureSession + .Instance.AuthenticationFactory + .Authenticate(_context.Account, _context.Environment, _context.Tenant.Id, null, ShowDialog.Never, null, _context.Environment.GetTokenAudience(AzureEnvironment.Endpoint.ResourceManager)) + .AccessToken; + return GetClient() + .RefreshTokens + .GetFromExchangeAsync(grantType: _grantType, service: _endPoint, accessToken: armAccessToken) + .GetAwaiter() + .GetResult() + .RefreshTokenProperty; + } + + public PSRepositoryAttribute GetRepository(string repository) + { + return new ContainerRegistryRepositoryGetOperation(this, repository).ProcessRequest(); + } + + public IList ListRepository(int? first) + { + return new ContainerRegistryRepositoryListOperation(this, first).ProcessRequest(); + } + + public PSDeletedRepository RemoveRepository(string repository) + { + return new ContainerRegistryRepositoryRemoveOperation(this, repository).ProcessRequest(); + } + + public PSRepositoryAttribute UpdateRepository(string repository, PSChangeableAttribute attribute) + { + new ContainerRegistryRepositoryUpdateOperation(this, repository, attribute).ProcessRequest(); + return GetRepository(repository); + } + + public PSAcrManifest ListManifest(string repository) + { + return new ContainerRegistryManifestListOperation(this, repository).ProcessRequest(); + } + + public PSManifestAttribute GetManifest(string repository, string manifest) + { + return new ContainerRegistryManifestGetOperation(this, repository, manifest).ProcessRequest(); + } + + public PSManifestAttribute UpdateManifest(string repository, string manifest, PSChangeableAttribute attribute) + { + new ContainerRegistryManifestUpdateOperation(this, repository, manifest, attribute).ProcessRequest(); + return GetManifest(repository, manifest); + } + + public PSManifestAttribute UpdateManifestByTag(string repository, string tag, PSChangeableAttribute attribute) + { + PSTagAttribute tagAttribute = GetTag(repository, tag); + return UpdateManifest(repository, tagAttribute.Attributes.Digest, attribute); + } + + public bool RemoveManifest(string repository, string manifest) + { + return new ContainerRegistryManifestRemoveOperation(this, repository, manifest).ProcessRequest(); + } + + public bool RemoveManifestByTag(string repository, string tag) + { + PSTagAttribute tagAttribute = GetTag(repository, tag); + return RemoveManifest(repository, tagAttribute.Attributes.Digest); + } + + public PSTagAttribute GetTag(string repository, string tag) + { + return new ContainerRegistryTagGetOperation(this, repository, tag).ProcessRequest(); + } + + public PSTagList ListTag(string repository) + { + return new ContainerRegistryTagListOperation(this, repository).ProcessRequest(); + } + + public bool RemoveTag(string repository, string tag) + { + return new ContainerRegistryTagRemoveOperation(this, repository, tag).ProcessRequest(); + } - public Rest.Azure.AzureOperationResponse CheckRegistry() + public PSTagAttribute UpdateTag(string repository, string tag, PSChangeableAttribute attribute) { - return _client.V2Support.CheckWithHttpMessagesAsync().GetAwaiter().GetResult(); + new ContainerRegistryTagUpdateOperation(this, repository, tag, attribute).ProcessRequest(); + return GetTag(repository, tag); } } -} +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneCmdletBase.cs b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneCmdletBase.cs new file mode 100644 index 000000000000..0f9d67544a52 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneCmdletBase.cs @@ -0,0 +1,51 @@ +// ---------------------------------------------------------------------------------- +// +// 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 System.Text.RegularExpressions; +using System.Management.Automation; +using System; + +namespace Microsoft.Azure.Commands.ContainerRegistry +{ + public class ContainerRegistryDataPlaneCmdletBase : ContainerRegistryCmdletBase + { + protected const string ListParameterSet = "ListParameterSet"; + protected const string GetParameterSet = "GetParameterSet"; + protected const string ByManifestParameterSet = "ByManifestParameterSet"; + protected const string ByTagParameterSet = "ByTagParameterSet"; + + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Azure Container Registry Name."),] + [ValidateNotNullOrEmpty] + public string RegistryName { get; set; } + + protected override void InitDebuggingFilter() + { + AddDebuggingFilter(new Regex("(\\s*access_token\\s*=\\s*)[^\"]+")); + AddDebuggingFilter(new Regex("(\\s*refresh_token\\s*=\\s*)[^\"]+")); + AddDebuggingFilter(new Regex("(\\s*\"refresh_token\"\\s*:\\s*)\"[^\"]+\"")); + base.InitDebuggingFilter(); + } + + public override void ExecuteCmdlet() + { + this.RegistryDataPlaneClient.SetEndPoint(this.RegistryName); + ExecuteChildCmdlet(); + } + + public virtual void ExecuteChildCmdlet() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSAcrManifest.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSAcrManifest.cs new file mode 100644 index 000000000000..43b6f201d9d2 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSAcrManifest.cs @@ -0,0 +1,46 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSAcrManifest + { + public PSAcrManifest(string registry = default(string), string imageName = default(string), IList manifestsAttributes = default(IList)) + { + Registry = registry; + ImageName = imageName; + ManifestsAttributes = manifestsAttributes; + } + + public PSAcrManifest(AcrManifests manifest) + { + Registry = manifest?.Registry; + ImageName = manifest?.Registry; + if (manifest != null) + { + ManifestsAttributes = manifest.ManifestsAttributes.Select(x => new PSManifestAttributeBase(x)).ToList(); + } + } + + public string Registry { get; set; } + + public string ImageName { get; set; } + + public IList ManifestsAttributes { get; set; } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSAcrToken.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSAcrToken.cs new file mode 100644 index 000000000000..0bab2e71450e --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSAcrToken.cs @@ -0,0 +1,43 @@ +// ---------------------------------------------------------------------------------- +// +// 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.Profile.Utilities; +using System; +using System.Linq; +using System.Text.Json; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSAcrToken + { + public readonly string token; + public readonly DateTime exp; + + public PSAcrToken(string token) + { + this.token = token; + + //header, payload, signature are splitted by '.' in token + string decodedToken = Base64UrlHelper.DecodeToString(token.Split('.')[1]); + int unixTimeSeconds = JsonDocument.Parse(decodedToken) + .RootElement + .EnumerateObject() + .Where(p => p.Name == "exp") + .Select(p => p.Value.GetInt32()) + .First(); + + this.exp = DateTimeOffset.FromUnixTimeSeconds(unixTimeSeconds).UtcDateTime; + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSChangeableAttribute.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSChangeableAttribute.cs new file mode 100644 index 000000000000..719530e60de4 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSChangeableAttribute.cs @@ -0,0 +1,59 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSChangeableAttribute + { + public PSChangeableAttribute(bool? deleteEnabled = default(bool?), bool? writeEnabled = default(bool?), bool? listEnabled = default(bool?), bool? readEnabled = default(bool?)) + { + DeleteEnabled = deleteEnabled; + WriteEnabled = writeEnabled; + ListEnabled = listEnabled; + ReadEnabled = readEnabled; + } + + public PSChangeableAttribute(ChangeableAttributes attribute) + { + DeleteEnabled = attribute?.DeleteEnabled; + WriteEnabled = attribute?.WriteEnabled; + ListEnabled = attribute?.ListEnabled; + ReadEnabled = attribute?.ReadEnabled; + } + + public ChangeableAttributes GetAttribute() + { + return new ChangeableAttributes + { + DeleteEnabled = this.DeleteEnabled, + WriteEnabled = this.WriteEnabled, + ListEnabled = this.ListEnabled, + ReadEnabled = this.ReadEnabled + }; + } + + public bool? DeleteEnabled { get; set; } + + public bool? WriteEnabled { get; set; } + + public bool? ListEnabled { get; set; } + + public bool? ReadEnabled { get; set; } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSDeletedRepository.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSDeletedRepository.cs new file mode 100644 index 000000000000..5f2d86726ce2 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSDeletedRepository.cs @@ -0,0 +1,40 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSDeletedRepository + { + public PSDeletedRepository(IList manifestsDeleted = default(IList), IList tagsDeleted = default(IList)) + { + this.ManifestsDeleted = manifestsDeleted; + this.TagsDeleted = tagsDeleted; + } + + public PSDeletedRepository(DeletedRepository deleted) + { + this.ManifestsDeleted = deleted?.ManifestsDeleted; + this.TagsDeleted = deleted?.TagsDeleted; + } + + public IList ManifestsDeleted { get; set; } + + public IList TagsDeleted { get; set; } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSManifestAttribute.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSManifestAttribute.cs new file mode 100644 index 000000000000..2750c7419492 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSManifestAttribute.cs @@ -0,0 +1,54 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSManifestAttribute + { + public PSManifestAttribute(string registry = default(string), string imageName = default(string), PSManifestAttributeBase attributes = default(PSManifestAttributeBase)) + { + Registry = registry; + ImageName = imageName; + Attributes = attributes; + } + + public PSManifestAttribute(ManifestAttributes manifest) + { + Registry = manifest?.Registry; + ImageName = manifest?.ImageName; + if (manifest != null) + { + Attributes = new PSManifestAttributeBase(manifest.Attributes); + } + } + + public ManifestAttributes GetAttribute() + { + return new ManifestAttributes + { + Registry = this.Registry, + ImageName = this.ImageName, + Attributes = this.Attributes.GetAttribute() + }; + } + + public string Registry { get; set; } + + public string ImageName { get; set; } + + public PSManifestAttributeBase Attributes { get; set; } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSManifestAttributeBase.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSManifestAttributeBase.cs new file mode 100644 index 000000000000..482764c82f4b --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSManifestAttributeBase.cs @@ -0,0 +1,90 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using System.Collections.Generic; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSManifestAttributeBase + { + public PSManifestAttributeBase(string digest = default(string), long? imageSize = default(long?), string createdTime = default(string), string lastUpdateTime = default(string), string architecture = default(string), string os = default(string), string mediaType = default(string), string configMediaType = default(string), IList tags = default(IList), PSChangeableAttribute changeableAttributes = default(PSChangeableAttribute)) + { + Digest = digest; + ImageSize = imageSize; + CreatedTime = createdTime; + LastUpdateTime = lastUpdateTime; + Architecture = architecture; + Os = os; + MediaType = mediaType; + ConfigMediaType = configMediaType; + Tags = tags; + ChangeableAttributes = changeableAttributes; + } + + public PSManifestAttributeBase(ManifestAttributesBase attribute) + { + Digest = attribute?.Digest; + ImageSize = attribute?.ImageSize; + CreatedTime = attribute?.CreatedTime; + LastUpdateTime = attribute?.LastUpdateTime; + Architecture = attribute?.Architecture; + Os = attribute?.Os; + MediaType = attribute?.MediaType; + ConfigMediaType = attribute?.ConfigMediaType; + Tags = attribute?.Tags; + if (attribute != null) + { + ChangeableAttributes = new PSChangeableAttribute(attribute.ChangeableAttributes); + } + } + + public ManifestAttributesBase GetAttribute() + { + return new ManifestAttributesBase + { + Digest = this.Digest, + ImageSize = this.ImageSize, + CreatedTime = this.CreatedTime, + LastUpdateTime = this.LastUpdateTime, + Architecture = this.Architecture, + Os = this.Os, + MediaType = this.MediaType, + ConfigMediaType = this.ConfigMediaType, + Tags = this.Tags, + ChangeableAttributes = this.ChangeableAttributes.GetAttribute() + }; + } + + public string Digest { get; set; } + + public long? ImageSize { get; set; } + + public string CreatedTime { get; set; } + + public string LastUpdateTime { get; set; } + + public string Architecture { get; set; } + + public string Os { get; set; } + + public string MediaType { get; set; } + + public string ConfigMediaType { get; set; } + + public IList Tags { get; set; } + + public PSChangeableAttribute ChangeableAttributes { get; set; } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSRepositoryAttribute.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSRepositoryAttribute.cs new file mode 100644 index 000000000000..8fa90328adf7 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSRepositoryAttribute.cs @@ -0,0 +1,60 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSRepositoryAttribute + { + public PSRepositoryAttribute(string registry = default(string), string imageName = default(string), string createdTime = default(string), string lastUpdateTime = default(string), int? manifestCount = default(int?), int? tagCount = default(int?), PSChangeableAttribute changeableAttributes = default(PSChangeableAttribute)) + { + Registry = registry; + ImageName = imageName; + CreatedTime = createdTime; + LastUpdateTime = lastUpdateTime; + ManifestCount = manifestCount; + TagCount = tagCount; + ChangeableAttributes = changeableAttributes; + } + + public PSRepositoryAttribute(RepositoryAttributes attribute) + { + Registry = attribute?.Registry; + ImageName = attribute?.ImageName; + CreatedTime = attribute?.CreatedTime; + LastUpdateTime = attribute?.LastUpdateTime; + ManifestCount = attribute?.ManifestCount; + TagCount = attribute?.TagCount; + ChangeableAttributes = new PSChangeableAttribute(attribute?.ChangeableAttributes); + } + + public string Registry { get; set; } + + public string ImageName { get; set; } + + public string CreatedTime { get; set; } + + public string LastUpdateTime { get; set; } + + public int? ManifestCount { get; set; } + + public int? TagCount { get; set; } + + public PSChangeableAttribute ChangeableAttributes { get; set; } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSTagAttribute.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSTagAttribute.cs new file mode 100644 index 000000000000..8f4da77fabc5 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSTagAttribute.cs @@ -0,0 +1,58 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSTagAttribute + { + public PSTagAttribute() + { + } + + public PSTagAttribute(string registry = default(string), string imageName = default(string), PSTagAttributeBase attributes = default(PSTagAttributeBase)) + { + Registry = registry; + ImageName = imageName; + Attributes = attributes; + } + + public PSTagAttribute(TagAttributes attribute) + { + Registry = attribute?.Registry; + ImageName = attribute?.ImageName; + if (attribute != null) + { + Attributes = new PSTagAttributeBase(attribute.Attributes); + } + } + + public TagAttributes GetAttribute() + { + return new TagAttributes + { + Registry = this.Registry, + ImageName = this.ImageName, + Attributes = this.Attributes.GetAttribute() + }; + } + + public string Registry { get; set; } + + public string ImageName { get; set; } + + public PSTagAttributeBase Attributes { get; set; } + } +} \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSTagAttributeBase.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSTagAttributeBase.cs new file mode 100644 index 000000000000..7d43d8047343 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSTagAttributeBase.cs @@ -0,0 +1,73 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSTagAttributeBase + { + public PSTagAttributeBase() + { + } + + public PSTagAttributeBase(string name = default(string), string digest = default(string), string createdTime = default(string), string lastUpdateTime = default(string), bool? signed = default(bool?), ChangeableAttributes changeableAttributes = default(ChangeableAttributes)) + { + Name = name; + Digest = digest; + CreatedTime = createdTime; + LastUpdateTime = lastUpdateTime; + Signed = signed; + ChangeableAttributes = new PSChangeableAttribute(changeableAttributes); + } + + public PSTagAttributeBase(TagAttributesBase attribute) + { + Name = attribute?.Name; + Digest = attribute?.Digest; + CreatedTime = attribute?.CreatedTime; + LastUpdateTime = attribute?.LastUpdateTime; + Signed = attribute?.Signed; + if (attribute != null) + { + ChangeableAttributes = new PSChangeableAttribute(attribute.ChangeableAttributes); + } + } + + public TagAttributesBase GetAttribute() + { + return new TagAttributesBase + { + Name = this.Name, + Digest = this.Digest, + CreatedTime = this.CreatedTime, + LastUpdateTime = this.LastUpdateTime, + Signed = this.Signed, + ChangeableAttributes = this.ChangeableAttributes.GetAttribute() + }; + } + + public string Name { get; set; } + + public string Digest { get; set; } + + public string CreatedTime { get; set; } + + public string LastUpdateTime { get; set; } + + public bool? Signed { get; set; } + + public PSChangeableAttribute ChangeableAttributes { get; set; } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSTagList.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSTagList.cs new file mode 100644 index 000000000000..81ae3f1f08b1 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSTagList.cs @@ -0,0 +1,61 @@ +// ---------------------------------------------------------------------------------- +// +// 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.ContainerRegistry.Models; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class PSTagList + { + public PSTagList() + { + } + + public PSTagList(string registry = default(string), string imageName = default(string), IList tags = default(IList)) + { + Registry = registry; + ImageName = imageName; + Tags = tags; + } + + public PSTagList(TagList tag) + { + Registry = tag?.Registry; + ImageName = tag?.ImageName; + if (tag != null && tag.Tags != null) + { + Tags = tag.Tags.Select(x => new PSTagAttributeBase(x)).ToList(); + } + } + + public TagList GetAttribute() + { + return new TagList + { + Registry = this.Registry, + ImageName = this.ImageName, + Tags = this.Tags.Select(x => x.GetAttribute()).ToList() + }; + } + + public string Registry { get; set; } + + public string ImageName { get; set; } + + public IList Tags { get; set; } + + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/RepoAccessTokenPermission.cs b/src/ContainerRegistry/ContainerRegistry/Models/RepoAccessTokenPermission.cs new file mode 100644 index 000000000000..7c2175889535 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/RepoAccessTokenPermission.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class RepoAccessTokenPermission + { + public const string METADATA_READ = "metadata_read"; + public const string METADATA_WRITE = "metadata_write"; + public const string DELETE = "delete"; + public const string META_WRITE_META_READ = "metadata_write,metadata_read"; + public const string DELETE_META_READ = "delete,metadata_read"; + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/help/Az.ContainerRegistry.md b/src/ContainerRegistry/ContainerRegistry/help/Az.ContainerRegistry.md index ee669d4219b6..ddd3d7a74fe9 100644 --- a/src/ContainerRegistry/ContainerRegistry/help/Az.ContainerRegistry.md +++ b/src/ContainerRegistry/ContainerRegistry/help/Az.ContainerRegistry.md @@ -20,9 +20,18 @@ Gets a container registry. ### [Get-AzContainerRegistryCredential](Get-AzContainerRegistryCredential.md) Gets the login credentials for a container registry. +### [Get-AzContainerRegistryManifest](Get-AzContainerRegistryManifest.md) +Get or list ACR manifest. + ### [Get-AzContainerRegistryReplication](Get-AzContainerRegistryReplication.md) Gets a replication of a container registry. +### [Get-AzContainerRegistryRepository](Get-AzContainerRegistryRepository.md) +Get or list ACR repositories. + +### [Get-AzContainerRegistryTag](Get-AzContainerRegistryTag.md) +Get or list ACR tag. + ### [Get-AzContainerRegistryUsage](Get-AzContainerRegistryUsage.md) Get Usage of an azure container registry. @@ -50,9 +59,18 @@ Creates a container registry webhook. ### [Remove-AzContainerRegistry](Remove-AzContainerRegistry.md) Removes a container registry. +### [Remove-AzContainerRegistryManifest](Remove-AzContainerRegistryManifest.md) +Delete ACR manifest. + ### [Remove-AzContainerRegistryReplication](Remove-AzContainerRegistryReplication.md) Removes a container registry replication. +### [Remove-AzContainerRegistryRepository](Remove-AzContainerRegistryRepository.md) +Delete repository from ACR. + +### [Remove-AzContainerRegistryTag](Remove-AzContainerRegistryTag.md) +Untag ACR tag. + ### [Remove-AzContainerRegistryWebhook](Remove-AzContainerRegistryWebhook.md) Removes a container registry webhook. @@ -71,6 +89,15 @@ Updates a container registry. ### [Update-AzContainerRegistryCredential](Update-AzContainerRegistryCredential.md) Regenerates a login credential for a container registry. +### [Update-AzContainerRegistryManifest](Update-AzContainerRegistryManifest.md) +Update ACR manifest. + +### [Update-AzContainerRegistryRepository](Update-AzContainerRegistryRepository.md) +Update ACR repository. + +### [Update-AzContainerRegistryTag](Update-AzContainerRegistryTag.md) +Update Acr tag. + ### [Update-AzContainerRegistryWebhook](Update-AzContainerRegistryWebhook.md) Updates a container registry webhook. diff --git a/src/ContainerRegistry/ContainerRegistry/help/Connect-AzContainerRegistry.md b/src/ContainerRegistry/ContainerRegistry/help/Connect-AzContainerRegistry.md index 960592fcae35..728fa45cbc4c 100644 --- a/src/ContainerRegistry/ContainerRegistry/help/Connect-AzContainerRegistry.md +++ b/src/ContainerRegistry/ContainerRegistry/help/Connect-AzContainerRegistry.md @@ -72,7 +72,7 @@ Azure Container Registry Name. ```yaml Type: System.String Parameter Sets: (All) -Aliases: +Aliases: RegistryName Required: True Position: Named diff --git a/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryManifest.md b/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryManifest.md new file mode 100644 index 000000000000..ddc07bf6c9e7 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryManifest.md @@ -0,0 +1,134 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/get-azcontainerregistrymanifest +schema: 2.0.0 +--- + +# Get-AzContainerRegistryManifest + +## SYNOPSIS +Get or list ACR manifest. + +## SYNTAX + +### ListParameterSet (Default) +``` +Get-AzContainerRegistryManifest -RepositoryName -RegistryName + [-DefaultProfile ] [] +``` + +### GetParameterSet +``` +Get-AzContainerRegistryManifest -RepositoryName -Name -RegistryName + [-DefaultProfile ] [] +``` + +## DESCRIPTION +Get or list ACR manifest. +To use this cmdlet please run +`Update-AzContainerRegistryRepository -RegistryName XXX -Repository XXX -ReadEnable $true -ListEnable $true` +first. + +## EXAMPLES + +### Example 1 +```powershell +Get-AzContainerRegistryManifest -RegistryName registry -RepositoryName alpine + +Registry ImageName ManifestsAttributes +-------- --------- ------------------- +registry.azurecr.io registry.azurecr.io {Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttributeBase, Microsoft.Azure.Comm…} +``` + +List manifests for repository alpine under registry. + +### Example 2 +```powershell +Get-AzContainerRegistryManifest -RegistryName registry -RepositoryName alpine -Name sha256:a5426f084c755f4d6c1d1562a2d456aa574a24a61706f6806415627360c06ac0 + +Registry ImageName Attributes +-------- --------- ---------- +registry.azurecr.io alpine Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttributeBase +``` + +Get manifests sha256:a5426f084c755f4d6c1d1562a2d456aa574a24a61706f6806415627360c06ac0 for repository alpine under registry. + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name +Manifest reference. + +```yaml +Type: System.String +Parameter Sets: GetParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RepositoryName +Repository Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttribute + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSAcrManifest + +## NOTES + +## RELATED LINKS diff --git a/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryRepository.md b/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryRepository.md new file mode 100644 index 000000000000..939b4d5405b0 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryRepository.md @@ -0,0 +1,146 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/get-azcontainerregistryrepository +schema: 2.0.0 +--- + +# Get-AzContainerRegistryRepository + +## SYNOPSIS +Get or list ACR repositories. + +## SYNTAX + +### ListParameterSet (Default) +``` +Get-AzContainerRegistryRepository [-First ] -RegistryName + [-DefaultProfile ] [] +``` + +### GetParameterSet +``` +Get-AzContainerRegistryRepository -Name -RegistryName + [-DefaultProfile ] [] +``` + +## DESCRIPTION +Get or list ACR repositories. +List returns repository names only. + +## EXAMPLES + +### Example 1 +```powershell +Get-AzContainerRegistryRepository -RegistryName registry +alpine +test/busybox0 +test/busybox1 +test/busybox10 +``` + +List all repositories in registry. + +### Example 2 +```powershell +Get-AzContainerRegistryRepository -RegistryName registry -First 3 +alpine +test/busybox0 +test/busybox1 +``` + +List first 3 repositories in registry. + +### Example 3 +```powershell +Get-AzContainerRegistryRepository -RegistryName registry -Name alpine + +Registry : registry.azurecr.io +ImageName : alpine +CreatedTime : 2020-10-13T05:45:25.5896115Z +LastUpdateTime : 2021-01-04T08:31:46.2406505Z +ManifestCount : 7 +TagCount : 1 +ChangeableAttributes : Microsoft.Azure.Commands.ContainerRegistry.Models.PSChangeableAttribute +``` + +Get repository alpine under registry. + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name +Repository Name. + +```yaml +Type: System.String +Parameter Sets: GetParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -First +First n results. + +```yaml +Type: System.Nullable`1[System.Int32] +Parameter Sets: ListParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSAcrManifest + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttribute + +## NOTES + +## RELATED LINKS diff --git a/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryTag.md b/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryTag.md new file mode 100644 index 000000000000..a593e923e37a --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryTag.md @@ -0,0 +1,134 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/get-azcontainerregistrytag +schema: 2.0.0 +--- + +# Get-AzContainerRegistryTag + +## SYNOPSIS +Get or list ACR tag. + +## SYNTAX + +### ListParameterSet (Default) +``` +Get-AzContainerRegistryTag -RepositoryName -RegistryName + [-DefaultProfile ] [] +``` + +### GetParameterSet +``` +Get-AzContainerRegistryTag -RepositoryName -Name -RegistryName + [-DefaultProfile ] [] +``` + +## DESCRIPTION +Get or list ACR tag. +To use this cmdlet please run +`Update-AzContainerRegistryRepository -RegistryName XXX -Repository XXX -ReadEnable $true -ListEnable $true` +first. + +## EXAMPLES + +### Example 1 +```powershell +Get-AzContainerRegistryTag -RegistryName registry -RepositoryName alpine + +Registry ImageName Tags +-------- --------- ---- +registry.azurecr.io alpine {latest} +``` + +List tags for repository alpine under registry. + +### Example 2 +```powershell +Get-AzContainerRegistryTag -RegistryName registry -RepositoryName alpine -name latest + +Registry ImageName Attributes +-------- --------- ---------- +registry.azurecr.io alpine Microsoft.Azure.Commands.ContainerRegistry.Models.PSTagAttributeBase +``` + +Get tag latest for repository alpine under registry. + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name +Tag. + +```yaml +Type: System.String +Parameter Sets: GetParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RepositoryName +Repository Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSTagAttribute + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSTagList + +## NOTES + +## RELATED LINKS diff --git a/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryManifest.md b/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryManifest.md new file mode 100644 index 000000000000..b45e1948dd04 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryManifest.md @@ -0,0 +1,172 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/remove-azcontainerregistrymanifest +schema: 2.0.0 +--- + +# Remove-AzContainerRegistryManifest + +## SYNOPSIS +Delete ACR manifest. + +## SYNTAX + +### ByManifestParameterSet (Default) +``` +Remove-AzContainerRegistryManifest -RepositoryName -Manifest -RegistryName + [-DefaultProfile ] [-WhatIf] [-Confirm] [] +``` + +### ByTagParameterSet +``` +Remove-AzContainerRegistryManifest -RepositoryName -Tag -RegistryName + [-DefaultProfile ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION +Delete ACR manifest. +To use this cmdlet please run +`Update-AzContainerRegistryRepository -RegistryName XXX -Repository XXX -DeleteEnable $true` +first. + +## EXAMPLES + +### Example 1 +```powershell +Remove-AzContainerRegistryManifest -RegistryName registry -RepositoryName test/busybox27 -Manifest sha256:31a54a0cf86d7354788a8265f60ae6acb4b348a67efbcf7c1007dd3cf7af05ab +True +``` + +Delete manifest sha256:31a54a0cf86d7354788a8265f60ae6acb4b348a67efbcf7c1007dd3cf7af05ab for repository test/busybox27 under registry + +### Example 2 +```powershell +Remove-AzContainerRegistryManifest -RegistryName registry -RepositoryName test/busybox27 -Tag latest +True +``` + +Delete manifest with tag latest for repository test/busybox27 under registry + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Manifest +Manifest reference. + +```yaml +Type: System.String +Parameter Sets: ByManifestParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RepositoryName +Repository Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Tag +Tag. + +```yaml +Type: System.String +Parameter Sets: ByTagParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### System.Boolean + +## NOTES + +## RELATED LINKS diff --git a/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryRepository.md b/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryRepository.md new file mode 100644 index 000000000000..e6841d278811 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryRepository.md @@ -0,0 +1,127 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/remove-azcontainerregistryrepository +schema: 2.0.0 +--- + +# Remove-AzContainerRegistryRepository + +## SYNOPSIS +Delete repository from ACR. + +## SYNTAX + +``` +Remove-AzContainerRegistryRepository -Name -RegistryName + [-DefaultProfile ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION +Delete repository from ACR. + +## EXAMPLES + +### Example 1 +```powershell +Remove-AzContainerRegistryRepository -RegistryName registry -Name test/busybox15 + +ManifestsDeleted TagsDeleted +---------------- ----------- +{sha256:31a54a0cf86d7354788a8265f60ae6acb4b348a67efbcf7c1007dd3cf7af05ab} {latest} +``` + +Delete repository test/busybox15 under registry. + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name +Repository Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSDeletedRepository + +## NOTES + +## RELATED LINKS diff --git a/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryTag.md b/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryTag.md new file mode 100644 index 000000000000..cea67bc8b01c --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Remove-AzContainerRegistryTag.md @@ -0,0 +1,142 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/Remove-azcontainerregistrytag +schema: 2.0.0 +--- + +# Remove-AzContainerRegistryTag + +## SYNOPSIS +Untag ACR tag. + +## SYNTAX + +``` +Remove-AzContainerRegistryTag -RepositoryName -Name -RegistryName + [-DefaultProfile ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION +Untag ACR tag. +To use this cmdlet please run +`Update-AzContainerRegistryRepository -RegistryName XXX -Repository XXX -DeleteEnable $true` +first. + +## EXAMPLES + +### Example 1 +```powershell +Remove-AzContainerRegistryTag -RegistryName registry -RepositoryName alpine -Name latest +True +``` + +Untag alpine:tag under registry. + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name +Tag. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RepositoryName +Repository Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### System.Boolean + +## NOTES + +## RELATED LINKS diff --git a/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryManifest.md b/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryManifest.md new file mode 100644 index 000000000000..a3b36001f688 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryManifest.md @@ -0,0 +1,240 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/update-azcontainerregistrymanifest +schema: 2.0.0 +--- + +# Update-AzContainerRegistryManifest + +## SYNOPSIS +Update ACR manifest. + +## SYNTAX + +### ByManifestParameterSet (Default) +``` +Update-AzContainerRegistryManifest -RepositoryName -Manifest [-DeleteEnabled ] + [-WriteEnabled ] [-ListEnabled ] [-ReadEnabled ] -RegistryName + [-DefaultProfile ] [-WhatIf] [-Confirm] [] +``` + +### ByTagParameterSet +``` +Update-AzContainerRegistryManifest -RepositoryName -Tag [-DeleteEnabled ] + [-WriteEnabled ] [-ListEnabled ] [-ReadEnabled ] -RegistryName + [-DefaultProfile ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION +Update ACR manifest. +To use this cmdlet please run +`Update-AzContainerRegistryRepository -RegistryName XXX -Repository XXX -WriteEnable $true` +first. + +## EXAMPLES + +### Example 1 +```powershell +Update-AzContainerRegistryManifest -RegistryName registry -RepositoryName alpine -Manifest sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321 -DeleteEnabled $false -WriteEnabled $true -ListEnabled $true -ReadEnabled $true + +Registry ImageName Attributes +-------- --------- ---------- +registry.azurecr.io alpine Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttributeBase +``` + +Update attributes for manifest sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321 under registry. + +### Example 2 +```powershell +Update-AzContainerRegistryManifest -RegistryName registry -RepositoryName alpine -Tag latest -DeleteEnabled $false -WriteEnabled $true -ListEnabled $true -ReadEnabled $true + +Registry ImageName Attributes +-------- --------- ---------- +registry.azurecr.io alpine Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttributeBase +``` + +Update attributes for manifest with tag latest under registry. + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -DeleteEnabled +Delete enable. + +```yaml +Type: System.Nullable`1[System.Boolean] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ListEnabled +List enable. + +```yaml +Type: System.Nullable`1[System.Boolean] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Manifest +Manifest reference. + +```yaml +Type: System.String +Parameter Sets: ByManifestParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ReadEnabled +Read enable. + +```yaml +Type: System.Nullable`1[System.Boolean] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RepositoryName +Repository Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Tag +Tag. + +```yaml +Type: System.String +Parameter Sets: ByTagParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -WriteEnabled +Write enable. + +```yaml +Type: System.Nullable`1[System.Boolean] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttribute + +## NOTES + +## RELATED LINKS diff --git a/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryRepository.md b/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryRepository.md new file mode 100644 index 000000000000..2f0c835f18a8 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryRepository.md @@ -0,0 +1,192 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/update-azcontainerregistryrepository +schema: 2.0.0 +--- + +# Update-AzContainerRegistryRepository + +## SYNOPSIS +Update ACR repository. + +## SYNTAX + +``` +Update-AzContainerRegistryRepository -Name [-DeleteEnabled ] [-WriteEnabled ] + [-ListEnabled ] [-ReadEnabled ] -RegistryName + [-DefaultProfile ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION +Update ACR repository. + +## EXAMPLES + +### Example 1 +```powershell +Update-AzContainerRegistryRepository -RegistryName registry -Name test/busybox8 -DeleteEnabled $false -WriteEnabled $true -ListEnabled $true -ReadEnabled $true + +Registry : registry.azurecr.io +ImageName : test/busybox8 +CreatedTime : 2020-12-11T08:57:56.2070002Z +LastUpdateTime : 2020-12-11T08:57:56.5188237Z +ManifestCount : 1 +TagCount : 1 +ChangeableAttributes : Microsoft.Azure.Commands.ContainerRegistry.Models.PSChangeableAttribute +``` + +Update attributes for repository alpine under registry. + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -DeleteEnabled +Delete enable. + +```yaml +Type: System.Boolean +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ListEnabled +List enable. + +```yaml +Type: System.Boolean +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name +Repository Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ReadEnabled +Read enable. + +```yaml +Type: System.Boolean +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -WriteEnabled +Write enable. + +```yaml +Type: System.Boolean +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSRepositoryAttribute + +## NOTES + +## RELATED LINKS diff --git a/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryTag.md b/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryTag.md new file mode 100644 index 000000000000..1a1a793628b7 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryTag.md @@ -0,0 +1,206 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.ContainerRegistry.dll-Help.xml +Module Name: Az.ContainerRegistry +online version: https://docs.microsoft.com/en-us/powershell/module/az.containerregistry/update-azcontainerregistrytag +schema: 2.0.0 +--- + +# Update-AzContainerRegistryTag + +## SYNOPSIS +Update Acr tag. + +## SYNTAX + +``` +Update-AzContainerRegistryTag -RepositoryName -Name [-DeleteEnabled ] + [-WriteEnabled ] [-ListEnabled ] [-ReadEnabled ] -RegistryName + [-DefaultProfile ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION +Update ACR tag. +To use this cmdlet please run +`Update-AzContainerRegistryRepository -RegistryName XXX -Repository XXX -WriteEnable $true` +first. + +## EXAMPLES + +### Example 1 +```powershell +Update-AzContainerRegistryTag -RegistryName registry -RepositoryName alpine -Name latest -DeleteEnabled $false -WriteEnabled $true -ListEnabled $true -ReadEnabled $true + +Registry ImageName Attributes +-------- --------- ---------- +registry.azurecr.io alpine Microsoft.Azure.Commands.ContainerRegistry.Models.PSTagAttribute +``` + +Update attributes for tag latest under registry. + +## PARAMETERS + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzContext, AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -DeleteEnabled +Delete enable. + +```yaml +Type: System.Nullable`1[System.Boolean] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ListEnabled +List enable. + +```yaml +Type: System.Nullable`1[System.Boolean] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name +Tag. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ReadEnabled +Read enable. + +```yaml +Type: System.Nullable`1[System.Boolean] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -RegistryName +Azure Container Registry Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -RepositoryName +Repository Name. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -WriteEnabled +Write enable. + +```yaml +Type: System.Nullable`1[System.Boolean] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +## OUTPUTS + +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSTagAttribute + +## NOTES + +## RELATED LINKS diff --git a/tools/StaticAnalysis/Exceptions/Az.ContainerRegistry/MissingAssemblies.csv b/tools/StaticAnalysis/Exceptions/Az.ContainerRegistry/MissingAssemblies.csv index ae7c7af2fa2d..6c6babfa0bf2 100644 --- a/tools/StaticAnalysis/Exceptions/Az.ContainerRegistry/MissingAssemblies.csv +++ b/tools/StaticAnalysis/Exceptions/Az.ContainerRegistry/MissingAssemblies.csv @@ -1,4 +1,6 @@ "Directory","Assembly Name","Assembly Version","Referencing Assembly","Severity","ProblemId","Description","Remediation" "Az.ContainerRegistry","Microsoft.Win32.Registry","4.1.1.0","System.Management.Automation","0","3000","Missing assembly Microsoft.Win32.Registry referenced from System.Management.Automation","Ensure that the assembly is included in the Wix file or directory" "Az.ContainerRegistry","Microsoft.PowerShell.CoreCLR.Eventing","6.1.0.0","System.Management.Automation","0","3000","Missing assembly Microsoft.PowerShell.CoreCLR.Eventing referenced from System.Management.Automation","Ensure that the assembly is included in the Wix file or directory" -"Az.ContainerRegistry","System.IdentityModel.Tokens.Jwt","5.1.2.0","Microsoft.Azure.ContainerRegistry","0","3000","Missing assembly System.IdentityModel.Tokens.Jwt referenced from Microsoft.Azure.ContainerRegistry","Ensure that the assembly is included in the Wix file or directory" \ No newline at end of file +"Az.ContainerRegistry","System.IdentityModel.Tokens.Jwt","5.1.2.0","Microsoft.Azure.ContainerRegistry","0","3000","Missing assembly System.IdentityModel.Tokens.Jwt referenced from Microsoft.Azure.ContainerRegistry","Ensure that the assembly is included in the Wix file or directory" +"Az.ContainerRegistry","System.Text.Encodings.Web","4.0.4.0","Azure.Identity","0","3000","Missing assembly System.Text.Encodings.Web referenced from Azure.Identity","Ensure that the assembly is included in the Wix file or directory" +"Az.ContainerRegistry","System.Net.HttpListener","4.0.1.0","Microsoft.Identity.Client","0","3000","Missing assembly System.Net.HttpListener referenced from Microsoft.Identity.Client","Ensure that the assembly is included in the Wix file or directory" \ No newline at end of file From 6cdf19431ac5528a433aa32fbe889e0eaa5caa9c Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Wed, 13 Jan 2021 16:51:15 +0800 Subject: [PATCH 02/13] add shouldprocess --- .../RemoveAzureContainerRegistryManifest.cs | 10 ++++++++-- .../RemoveAzureContainerRegistryRepository.cs | 5 ++++- .../Commands/RemoveContainerRegistryTag.cs | 5 ++++- .../UpdateAzureContainerRegistryManifest.cs | 14 ++++++++++---- .../UpdateAzureContainerRegistryRepository.cs | 5 ++++- .../Commands/UpdateAzureContainerRegistryTag.cs | 5 ++++- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryManifest.cs b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryManifest.cs index 32692c566005..442c00f3154b 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryManifest.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryManifest.cs @@ -37,11 +37,17 @@ public override void ExecuteChildCmdlet() { if (ParameterSetName.Equals(ByManifestParameterSet)) { - WriteObject(this.RegistryDataPlaneClient.RemoveManifest(this.RepositoryName, this.Manifest)); + if (this.ShouldProcess(string.Format("Delete manitest {0}@{1} under {2}", this.RepositoryName, this.Manifest, this.RegistryName))) + { + WriteObject(this.RegistryDataPlaneClient.RemoveManifest(this.RepositoryName, this.Manifest)); + } } else if (ParameterSetName.Equals(ByTagParameterSet)) { - WriteObject(this.RegistryDataPlaneClient.RemoveManifestByTag(this.RepositoryName, this.Tag)); + if (this.ShouldProcess(string.Format("Delete manitest for {0}:{1} under {2}", this.RepositoryName, this.Tag, this.RegistryName))) + { + WriteObject(this.RegistryDataPlaneClient.RemoveManifestByTag(this.RepositoryName, this.Tag)); + } } else { diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryRepository.cs b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryRepository.cs index 8953606c74db..ce9bf8e615be 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryRepository.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveAzureContainerRegistryRepository.cs @@ -27,7 +27,10 @@ public class RemoveAzureContainerRegistryRepository : ContainerRegistryDataPlane public override void ExecuteChildCmdlet() { - WriteObject(this.RegistryDataPlaneClient.RemoveRepository(this.Name)); + if (this.ShouldProcess(string.Format("Delete {0} under {1}", this.Name, this.RegistryName))) + { + WriteObject(this.RegistryDataPlaneClient.RemoveRepository(this.Name)); + } } } } diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveContainerRegistryTag.cs b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveContainerRegistryTag.cs index ba6929bf9912..2b817a194137 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/RemoveContainerRegistryTag.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/RemoveContainerRegistryTag.cs @@ -30,7 +30,10 @@ public class RemoveAzureContainerRegistryTag : ContainerRegistryDataPlaneCmdletB public override void ExecuteChildCmdlet() { - WriteObject(this.RegistryDataPlaneClient.RemoveTag(this.RepositoryName, this.Name)); + if (this.ShouldProcess(string.Format("Untag {0}:{1} under {2}", this.RepositoryName, this.Name, this.RegistryName))) + { + WriteObject(this.RegistryDataPlaneClient.RemoveTag(this.RepositoryName, this.Name)); + } } } } diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryManifest.cs b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryManifest.cs index 97cbe9e965b1..4022d0297898 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryManifest.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryManifest.cs @@ -56,16 +56,22 @@ public override void ExecuteChildCmdlet() PSChangeableAttribute attribute = new PSChangeableAttribute(DeleteEnabled, WriteEnabled, ListEnabled, ReadEnabled); if (ParameterSetName.Equals(ByManifestParameterSet)) { - WriteObject(this.RegistryDataPlaneClient.UpdateManifest(this.RepositoryName, this.Manifest, attribute)); + if (this.ShouldProcess(string.Format("Update manitest {0}@{1} under {2}", this.RepositoryName, this.Manifest, this.RegistryName))) + { + WriteObject(this.RegistryDataPlaneClient.UpdateManifest(this.RepositoryName, this.Manifest, attribute)); + } } - else if(ParameterSetName.Equals(ByTagParameterSet)) + else if (ParameterSetName.Equals(ByTagParameterSet)) { - WriteObject(this.RegistryDataPlaneClient.UpdateManifestByTag(this.RepositoryName, this.Tag, attribute)); + if (this.ShouldProcess(string.Format("Update manitest for {0}:{1} under {2}", this.RepositoryName, this.Tag, this.RegistryName))) + { + WriteObject(this.RegistryDataPlaneClient.UpdateManifestByTag(this.RepositoryName, this.Tag, attribute)); + } } else { throw new PSArgumentException("Invalid parameter set"); - } + } } } } diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryRepository.cs b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryRepository.cs index bbc496042c4d..11489f7bb0d7 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryRepository.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryRepository.cs @@ -44,7 +44,10 @@ public class UpdateAzureContainerRegistryRepository : ContainerRegistryDataPlane public override void ExecuteChildCmdlet() { - WriteObject(this.RegistryDataPlaneClient.UpdateRepository(this.Name, new PSChangeableAttribute(DeleteEnabled, WriteEnabled, ListEnabled, ReadEnabled))); + if (this.ShouldProcess(string.Format("Update {0} under {1}", this.Name, this.RegistryName))) + { + WriteObject(this.RegistryDataPlaneClient.UpdateRepository(this.Name, new PSChangeableAttribute(DeleteEnabled, WriteEnabled, ListEnabled, ReadEnabled))); + } } } } diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryTag.cs b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryTag.cs index a020cad90b85..a657e0635d1a 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryTag.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/UpdateAzureContainerRegistryTag.cs @@ -49,7 +49,10 @@ public class UpdateAzureContainerRegistryTag : ContainerRegistryDataPlaneCmdletB public override void ExecuteChildCmdlet() { PSChangeableAttribute attribute = new PSChangeableAttribute(DeleteEnabled, WriteEnabled, ListEnabled, ReadEnabled); - WriteObject(this.RegistryDataPlaneClient.UpdateTag(this.RepositoryName, this.Name, attribute)); + if (this.ShouldProcess(string.Format("Update {0}:{1} under {2}", this.RepositoryName, this.Name, this.RegistryName))) + { + WriteObject(this.RegistryDataPlaneClient.UpdateTag(this.RepositoryName, this.Name, attribute)); + } } } } From 599b2547051c27afac3ead27bfd29962f296fa5b Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Wed, 20 Jan 2021 11:10:42 +0800 Subject: [PATCH 03/13] implement iazuresessioncomponentlistener --- .../Accounts/Context/ClearAzureRmContext.cs | 21 +++-- .../Factories/AuthenticationFactory.cs | 5 ++ .../ContainerRegistry.csproj | 5 -- .../ContainerRegistry/Models/AcrToken.cs | 36 ++++++++ .../Models/AcrTokenCacheComponents.cs | 60 +++++++++++++ .../ContainerRegistryDataPlaneClient.cs | 90 ++++++++----------- .../MockCertificateAuthenticationFactory.cs | 5 ++ .../Mocks/MockTokenAuthenticationFactory.cs | 5 ++ 8 files changed, 157 insertions(+), 70 deletions(-) create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCacheComponents.cs diff --git a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs index f3a752a7b9f5..019faf5f27fe 100644 --- a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs +++ b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs @@ -16,14 +16,12 @@ using System.Collections.Generic; using System.IO; using System.Management.Automation; - using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.Profile.Common; using Microsoft.Azure.Commands.Profile.Properties; using Microsoft.Azure.Commands.ResourceManager.Common; -using Microsoft.WindowsAzure.Commands.Common; namespace Microsoft.Azure.Commands.Profile.Context { @@ -87,21 +85,22 @@ void ClearContext(AzureRmProfile profile, RMProfileClient client) profile.TrySetDefaultContext(defaultContext); result = true; } - - //clean token cache created by Az.ContainerRegistry - string AcrTokenCacheKey = SharedComponentKeys.AcrTokenCacheKey; - IDictionary> acrTokenCache; - if (AzureSession.Instance.TryGetComponent(AcrTokenCacheKey, out acrTokenCache)) - { - acrTokenCache.Clear(); - AzureSession.Instance.UnregisterComponent>>(AcrTokenCacheKey); - } } + ClearAzureSessionComponents(); + if (PassThru.IsPresent) { WriteObject(result); } } + + //Clear components with on clear-azcontext events in azure session instance + void ClearAzureSessionComponents() + { + AzureSession.Instance.ClearComponentsOnClearAzContext(); + } } + + } diff --git a/src/Accounts/Authentication/Factories/AuthenticationFactory.cs b/src/Accounts/Authentication/Factories/AuthenticationFactory.cs index 5dc8c058978e..dcd4d0aff4af 100644 --- a/src/Accounts/Authentication/Factories/AuthenticationFactory.cs +++ b/src/Accounts/Authentication/Factories/AuthenticationFactory.cs @@ -349,6 +349,11 @@ public ServiceClientCredentials GetServiceClientCredentials(IAzureContext contex } } + public ServiceClientCredentials GetServiceClientCredentials(string token, Func func = null) + { + return new RenewingTokenCredential(new ExternalAccessToken(token, func)); + } + /// /// Remove a user from token cache. /// diff --git a/src/ContainerRegistry/ContainerRegistry/ContainerRegistry.csproj b/src/ContainerRegistry/ContainerRegistry/ContainerRegistry.csproj index f70510a00404..f65f17786e2d 100644 --- a/src/ContainerRegistry/ContainerRegistry/ContainerRegistry.csproj +++ b/src/ContainerRegistry/ContainerRegistry/ContainerRegistry.csproj @@ -15,9 +15,4 @@ - - - - - \ No newline at end of file diff --git a/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs b/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs new file mode 100644 index 000000000000..2e8f89713d67 --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs @@ -0,0 +1,36 @@ +using Microsoft.Azure.Commands.Profile.Utilities; +using System; +using System.Linq; +using System.Text.Json; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class AcrToken + { + private readonly string _token; + private DateTime _exp; + + public AcrToken(string token) + { + _token = token; + string decodedToken = Base64UrlHelper.DecodeToString(_token.Split('.')[1]); + int unixTimeSeconds = JsonDocument.Parse(decodedToken) + .RootElement + .EnumerateObject() + .Where(p => p.Name == "exp") + .Select(p => p.Value.GetInt32()) + .First(); + _exp = DateTimeOffset.FromUnixTimeSeconds(unixTimeSeconds).UtcDateTime; + } + + public string GetToken() + { + return _token; + } + + public bool IsExpired(int minutesBeforeExpiration) + { + return (_exp - DateTime.UtcNow).Minutes <= minutesBeforeExpiration; + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCacheComponents.cs b/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCacheComponents.cs new file mode 100644 index 000000000000..1fdd21f24a6d --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCacheComponents.cs @@ -0,0 +1,60 @@ +// ---------------------------------------------------------------------------------- +// +// 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.Abstractions; +using System; +using System.Collections.Generic; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class AcrTokenCacheComponents : IAzureSessionComponentListener + { + private IDictionary _component; + + public AcrTokenCacheComponents() + { + } + + public IDictionary GetComponent() + { + return _component; + } + + //clear component on clear-azcontext + public void OnEvent(object sender, EventArgs e) + { + _component.Clear(); + } + + public void Register(string componentName, IAzureSession session) + { + if (!session.TryGetComponent(componentName, out _component)) + { + _component = new Dictionary(); + session.RegisterComponentListener(componentName, this); + session.RegisterComponent>(componentName, () => _component); + } + } + + public void Unregister(string componentName, IAzureSession session) + { + if (!session.TryGetComponent(componentName, out _component)) + { + session.UnregisterComponentListener(componentName); + session.UnregisterComponent>(componentName); + _component = null; + } + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs index 76b5b6b87c43..1a6665e676af 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs @@ -14,7 +14,6 @@ using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using Microsoft.Azure.Commands.Common.Authentication.Authentication; using Microsoft.Azure.Commands.ContainerRegistry.Models; using Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations; using Microsoft.Azure.ContainerRegistry; @@ -23,9 +22,6 @@ using System; using System.Collections.Generic; using Microsoft.WindowsAzure.Commands.Common; -using Microsoft.Azure.Commands.Profile.Utilities; -using System.Text.Json; -using System.Linq; namespace Microsoft.Azure.Commands.ContainerRegistry { @@ -34,9 +30,11 @@ public class ContainerRegistryDataPlaneClient private AzureContainerRegistryClient _client; private string _accessToken = default(string); private string _endPoint; - private IAzureContext _context; private readonly string _suffix; - + + private IAzureContext _context; + private AcrTokenCacheComponents _tokenCacheComponent; + private const string _grantType = "access_token"; private const string _scopeDefault = "registry:catalog:*"; private const string _https = "https://"; @@ -52,22 +50,11 @@ public class ContainerRegistryDataPlaneClient public ContainerRegistryDataPlaneClient(IAzureContext context) { _context = context; - _suffix = context.Environment.ContainerRegistryEndpointSuffix; - ServiceClientCredentials clientCredential = new RenewingTokenCredential(new ExternalAccessToken(_accessToken, () => _accessToken)); + _suffix = _context.Environment.ContainerRegistryEndpointSuffix; + ServiceClientCredentials clientCredential = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(_accessToken, () => _accessToken); _client = AzureSession.Instance.ClientFactory.CreateCustomArmClient(clientCredential); } - public IDictionary> TryGetTokenCache() - { - IDictionary> cache; - if (!AzureSession.Instance.TryGetComponent(_acrTokenCacheKey, out cache)) - { - AzureSession.Instance.RegisterComponent>>(_acrTokenCacheKey, () => new Dictionary>()); - AzureSession.Instance.TryGetComponent(_acrTokenCacheKey, out cache); - } - return cache; - } - public AzureContainerRegistryClient GetClient() { return _client; @@ -81,33 +68,25 @@ public string TryAuthenticate(string scope = _scopeDefault) private string TryGetToken(string key) { - IDictionary> cache = TryGetTokenCache(); - Tuple value; + if (_tokenCacheComponent == null) + { + _tokenCacheComponent = new AcrTokenCacheComponents(); + } + if (_tokenCacheComponent.GetComponent() == null) + { + _tokenCacheComponent.Register(_acrTokenCacheKey, AzureSession.Instance); + } + + IDictionary cache = _tokenCacheComponent.GetComponent(); + AcrToken value; cache.TryGetValue(key, out value); - if (value == null || isTokenExpired(value)) + if (value == null || value.IsExpired(_minutesBeforeExpiration)) { string token = key.Equals(_refreshTokenKey) ? getRefreshToken() : getAccessToken(key); - value = new Tuple(token, getTokenExpiration(token)); + value = new AcrToken(token); cache[key] = value; } - return value.Item1; - } - - private DateTime getTokenExpiration(string token) - { - string decodedToken = Base64UrlHelper.DecodeToString(token.Split('.')[1]); - int unixTimeSeconds = JsonDocument.Parse(decodedToken) - .RootElement - .EnumerateObject() - .Where(p => p.Name == "exp") - .Select(p => p.Value.GetInt32()) - .First(); - return DateTimeOffset.FromUnixTimeSeconds(unixTimeSeconds).UtcDateTime; - } - - private bool isTokenExpired(Tuple value) - { - return (value.Item2 - DateTime.UtcNow).Minutes <= _minutesBeforeExpiration; + return value.GetToken(); } public void SetEndPoint(string RegistryName) @@ -121,31 +100,34 @@ public string GetEndPoint() return _endPoint; } - private string getAccessToken(string scope) + private string getArmAccessToken() { - string refreshToken = TryGetToken(_refreshTokenKey); - return GetClient() - .AccessTokens - .GetAsync(service: _endPoint, scope: scope, refreshToken: refreshToken) - .GetAwaiter() - .GetResult() - .AccessTokenProperty; + return AzureSession + .Instance.AuthenticationFactory + .Authenticate(_context.Account, _context.Environment, _context.Tenant.Id, null, ShowDialog.Never, null, _context.Environment.GetTokenAudience(AzureEnvironment.Endpoint.ResourceManager)) + .AccessToken; } private string getRefreshToken() { - string armAccessToken = AzureSession - .Instance.AuthenticationFactory - .Authenticate(_context.Account, _context.Environment, _context.Tenant.Id, null, ShowDialog.Never, null, _context.Environment.GetTokenAudience(AzureEnvironment.Endpoint.ResourceManager)) - .AccessToken; return GetClient() .RefreshTokens - .GetFromExchangeAsync(grantType: _grantType, service: _endPoint, accessToken: armAccessToken) + .GetFromExchangeAsync(grantType: _grantType, service: _endPoint, accessToken: getArmAccessToken()) .GetAwaiter() .GetResult() .RefreshTokenProperty; } + private string getAccessToken(string scope) + { + return GetClient() + .AccessTokens + .GetAsync(service: _endPoint, scope: scope, refreshToken: TryGetToken(_refreshTokenKey)) + .GetAwaiter() + .GetResult() + .AccessTokenProperty; + } + public PSRepositoryAttribute GetRepository(string repository) { return new ContainerRegistryRepositoryGetOperation(this, repository).ProcessRequest(); diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs b/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs index a5c48f68ddf4..2c87c8afd2d3 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs +++ b/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs @@ -96,6 +96,11 @@ public Rest.ServiceClientCredentials GetServiceClientCredentials(IAzureContext c throw new System.NotImplementedException(); } + public Rest.ServiceClientCredentials GetServiceClientCredentials(string token, Func func = null) + { + throw new System.NotImplementedException(); + } + public void RemoveUser(IAzureAccount account, IAzureTokenCache tokenCache) { throw new NotImplementedException(); diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs b/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs index ffbfd7e845e0..8a41f038f852 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs +++ b/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs @@ -136,6 +136,11 @@ public ServiceClientCredentials GetServiceClientCredentials(IAzureContext contex return new Microsoft.Rest.TokenCredentials(Token.AccessToken); } + public Rest.ServiceClientCredentials GetServiceClientCredentials(string token, Func func = null) + { + throw new System.NotImplementedException(); + } + public void RemoveUser(IAzureAccount account, IAzureTokenCache tokenCache) { throw new NotImplementedException(); From 024ebe1c0ae3143818d4ff839b9bf519f440f50b Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Wed, 20 Jan 2021 13:32:23 +0800 Subject: [PATCH 04/13] add comments and exception --- src/ContainerRegistry/ContainerRegistry.sln | 16 ++++++++++------ .../ContainerRegistryDataPlaneOperationBase.cs | 2 ++ .../Models/ContainerRegistryDataPlaneClient.cs | 10 +++++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/ContainerRegistry/ContainerRegistry.sln b/src/ContainerRegistry/ContainerRegistry.sln index 91928d05ff07..aabd08919c3e 100644 --- a/src/ContainerRegistry/ContainerRegistry.sln +++ b/src/ContainerRegistry/ContainerRegistry.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2042 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30816.121 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ContainerRegistry", "ContainerRegistry\ContainerRegistry.csproj", "{FE330703-623A-4C08-9DA7-1C63B4058034}" EndProject @@ -36,14 +36,18 @@ Global {094709D1-0301-44F4-8BB2-203162006A3D}.Debug|Any CPU.Build.0 = Debug|Any CPU {094709D1-0301-44F4-8BB2-203162006A3D}.Release|Any CPU.ActiveCfg = Release|Any CPU {094709D1-0301-44F4-8BB2-203162006A3D}.Release|Any CPU.Build.0 = Release|Any CPU - {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Release|Any CPU.Build.0 = Release|Any CPU {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Debug|Any CPU.Build.0 = Debug|Any CPU {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Release|Any CPU.ActiveCfg = Release|Any CPU {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Release|Any CPU.Build.0 = Release|Any CPU + {6BD6B80A-06AF-4B5B-9230-69CCFC6C8D64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6BD6B80A-06AF-4B5B-9230-69CCFC6C8D64}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6BD6B80A-06AF-4B5B-9230-69CCFC6C8D64}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6BD6B80A-06AF-4B5B-9230-69CCFC6C8D64}.Release|Any CPU.Build.0 = Release|Any CPU + {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Release|Any CPU.Build.0 = Release|Any CPU {FF81DC73-B8EC-4082-8841-4FBF2B16E7CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FF81DC73-B8EC-4082-8841-4FBF2B16E7CE}.Debug|Any CPU.Build.0 = Debug|Any CPU {FF81DC73-B8EC-4082-8841-4FBF2B16E7CE}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs index 93b796c54b3e..ac0ee4ffcfd0 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs @@ -72,6 +72,8 @@ public virtual T SendRequest() throw new NotImplementedException(); } + //link looks like: ; rel="next" + //repository should be in between of first appeartance of '=' and '&' protected string getLastListed(string nextLink) { int left = nextLink.IndexOf('='); diff --git a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs index 1a6665e676af..109c5d7ca33a 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs @@ -83,7 +83,15 @@ private string TryGetToken(string key) if (value == null || value.IsExpired(_minutesBeforeExpiration)) { string token = key.Equals(_refreshTokenKey) ? getRefreshToken() : getAccessToken(key); - value = new AcrToken(token); + try + { + value = new AcrToken(token); + } + catch + { + throw new InvalidOperationException(string.Format("Invalud token for {0}", key)); + } + cache[key] = value; } return value.GetToken(); From 22f8b8f1f721e517449db5fa0d87ccf806738855 Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Thu, 21 Jan 2021 10:26:52 +0800 Subject: [PATCH 05/13] fix cache impl --- .../Commands/ConnectAzureContainerRegistry.cs | 2 +- ...ContainerRegistryDataPlaneOperationBase.cs | 4 +- .../ContainerRegistry/Models/AcrTokenCache.cs | 33 ++++++++++ .../Models/AcrTokenCacheComponents.cs | 60 ------------------- .../Models/ContainerRegistryCmdletBase.cs | 4 +- .../ContainerRegistryDataPlaneClient.cs | 45 +++++++------- 6 files changed, 59 insertions(+), 89 deletions(-) create mode 100644 src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCache.cs delete mode 100644 src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCacheComponents.cs diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/ConnectAzureContainerRegistry.cs b/src/ContainerRegistry/ContainerRegistry/Commands/ConnectAzureContainerRegistry.cs index 25782f564e0f..8940a6d44723 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/ConnectAzureContainerRegistry.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/ConnectAzureContainerRegistry.cs @@ -55,7 +55,7 @@ public override void ExecuteCmdlet() { if (ParameterSetName.Equals(WithoutNameAndPasswordParameterSet)) { this.UserName = new Guid().ToString(); - this.Password = this.RegistryDataPlaneClient.TryAuthenticate(); + this.Password = this.RegistryDataPlaneClient.Authenticate(); } string LoginScript = string.Format("'{2}' | docker login {0} -u {1} --password-stdin", this.RegistryDataPlaneClient.GetEndPoint(), this.UserName, this.Password); diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs index ac0ee4ffcfd0..e7fdb96e9336 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs @@ -63,7 +63,7 @@ public ContainerRegistryDataPlaneOperationBase(ContainerRegistryDataPlaneClient public T ProcessRequest() { - _client.TryAuthenticate(_scope); + _client.Authenticate(_scope); return SendRequest(); } @@ -72,7 +72,7 @@ public virtual T SendRequest() throw new NotImplementedException(); } - //link looks like: ; rel="next" + //sample link: ; rel="next" //repository should be in between of first appeartance of '=' and '&' protected string getLastListed(string nextLink) { diff --git a/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCache.cs b/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCache.cs new file mode 100644 index 000000000000..89687282ec5a --- /dev/null +++ b/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCache.cs @@ -0,0 +1,33 @@ +using Microsoft.Azure.Commands.Common.Authentication.Abstractions; +using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Models; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Azure.Commands.ContainerRegistry.Models +{ + public class AcrTokenCache : IAzureSessionListener + { + private IDictionary _cache; + + public AcrTokenCache() + { + _cache = new Dictionary(); + } + + public void OnEvent(object sender, AzureSessionEventArgs e) + { + _cache.Clear(); + } + + public bool TryGetToken(string key, out AcrToken value) + { + return _cache.TryGetValue(key, out value); + } + + public void Add(string key, AcrToken token) + { + _cache[key] = token; + } + } +} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCacheComponents.cs b/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCacheComponents.cs deleted file mode 100644 index 1fdd21f24a6d..000000000000 --- a/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCacheComponents.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// 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.Abstractions; -using System; -using System.Collections.Generic; - -namespace Microsoft.Azure.Commands.ContainerRegistry.Models -{ - public class AcrTokenCacheComponents : IAzureSessionComponentListener - { - private IDictionary _component; - - public AcrTokenCacheComponents() - { - } - - public IDictionary GetComponent() - { - return _component; - } - - //clear component on clear-azcontext - public void OnEvent(object sender, EventArgs e) - { - _component.Clear(); - } - - public void Register(string componentName, IAzureSession session) - { - if (!session.TryGetComponent(componentName, out _component)) - { - _component = new Dictionary(); - session.RegisterComponentListener(componentName, this); - session.RegisterComponent>(componentName, () => _component); - } - } - - public void Unregister(string componentName, IAzureSession session) - { - if (!session.TryGetComponent(componentName, out _component)) - { - session.UnregisterComponentListener(componentName); - session.UnregisterComponent>(componentName); - _component = null; - } - } - } -} diff --git a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryCmdletBase.cs b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryCmdletBase.cs index bad535fd5a26..d0855fa2a7b2 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryCmdletBase.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryCmdletBase.cs @@ -139,15 +139,15 @@ public ResourceManagerClient ResourceManagerClient } } + private const string _acrTokenCacheKey = "AcrTokenCacheKey"; private ContainerRegistryDataPlaneClient _RegistryDataPlaneClient; - public ContainerRegistryDataPlaneClient RegistryDataPlaneClient { get { if (_RegistryDataPlaneClient == null) { - _RegistryDataPlaneClient = new ContainerRegistryDataPlaneClient(DefaultContext) + _RegistryDataPlaneClient = new ContainerRegistryDataPlaneClient(DefaultContext, _acrTokenCacheKey) { VerboseLogger = WriteVerboseWithTimestamp, ErrorLogger = WriteErrorWithTimestamp, diff --git a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs index 109c5d7ca33a..1ebc1d73d787 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs @@ -27,19 +27,19 @@ namespace Microsoft.Azure.Commands.ContainerRegistry { public class ContainerRegistryDataPlaneClient { + private const string _defaultGrantType = "access_token"; + private const string _defaultScope = "registry:catalog:*"; + private const string _https = "https://"; + private const string _refreshTokenKey = "AcrRefreshToken"; + private AzureContainerRegistryClient _client; private string _accessToken = default(string); private string _endPoint; private readonly string _suffix; - private IAzureContext _context; - private AcrTokenCacheComponents _tokenCacheComponent; - private const string _grantType = "access_token"; - private const string _scopeDefault = "registry:catalog:*"; - private const string _https = "https://"; - private const string _refreshTokenKey = "AcrRefreshToken"; - private const string _acrTokenCacheKey = SharedComponentKeys.AcrTokenCacheKey; + private readonly string _acrTokenCacheKey; + private const int _minutesBeforeExpiration = 5; @@ -47,12 +47,13 @@ public class ContainerRegistryDataPlaneClient public Action ErrorLogger { get; set; } public Action WarningLogger { get; set; } - public ContainerRegistryDataPlaneClient(IAzureContext context) + public ContainerRegistryDataPlaneClient(IAzureContext context, string acrTokenCacheKey) { _context = context; _suffix = _context.Environment.ContainerRegistryEndpointSuffix; ServiceClientCredentials clientCredential = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(_accessToken, () => _accessToken); _client = AzureSession.Instance.ClientFactory.CreateCustomArmClient(clientCredential); + _acrTokenCacheKey = acrTokenCacheKey; } public AzureContainerRegistryClient GetClient() @@ -60,27 +61,23 @@ public AzureContainerRegistryClient GetClient() return _client; } - public string TryAuthenticate(string scope = _scopeDefault) + public string Authenticate(string scope = _defaultScope) { - _accessToken = TryGetToken(scope); + _accessToken = GetToken(scope); return _accessToken; } - private string TryGetToken(string key) + private string GetToken(string key) { - if (_tokenCacheComponent == null) + AcrTokenCache cache; + if (!AzureSession.Instance.TryGetComponent(_acrTokenCacheKey, out cache)) { - _tokenCacheComponent = new AcrTokenCacheComponents(); - } - if (_tokenCacheComponent.GetComponent() == null) - { - _tokenCacheComponent.Register(_acrTokenCacheKey, AzureSession.Instance); + AzureSession.Instance.RegisterComponent(_acrTokenCacheKey, () => new AcrTokenCache()); + AzureSession.Instance.TryGetComponent(_acrTokenCacheKey, out cache); } - IDictionary cache = _tokenCacheComponent.GetComponent(); AcrToken value; - cache.TryGetValue(key, out value); - if (value == null || value.IsExpired(_minutesBeforeExpiration)) + if (!cache.TryGetToken(key, out value) || value.IsExpired(_minutesBeforeExpiration)) { string token = key.Equals(_refreshTokenKey) ? getRefreshToken() : getAccessToken(key); try @@ -91,8 +88,8 @@ private string TryGetToken(string key) { throw new InvalidOperationException(string.Format("Invalud token for {0}", key)); } - - cache[key] = value; + + cache.Add(key, value); } return value.GetToken(); } @@ -120,7 +117,7 @@ private string getRefreshToken() { return GetClient() .RefreshTokens - .GetFromExchangeAsync(grantType: _grantType, service: _endPoint, accessToken: getArmAccessToken()) + .GetFromExchangeAsync(grantType: _defaultGrantType, service: _endPoint, accessToken: getArmAccessToken()) .GetAwaiter() .GetResult() .RefreshTokenProperty; @@ -130,7 +127,7 @@ private string getAccessToken(string scope) { return GetClient() .AccessTokens - .GetAsync(service: _endPoint, scope: scope, refreshToken: TryGetToken(_refreshTokenKey)) + .GetAsync(service: _endPoint, scope: scope, refreshToken: GetToken(_refreshTokenKey)) .GetAwaiter() .GetResult() .AccessTokenProperty; From a2188f7d5e6bb5cb38fcbe97124525a0c387b481 Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Thu, 28 Jan 2021 14:56:35 +0800 Subject: [PATCH 06/13] resolve comments --- src/Accounts/Accounts/ChangeLog.md | 1 - .../Accounts/Context/ClearAzureRmContext.cs | 12 ------------ .../Authentication/ExternalAccessToken.cs | 6 +++--- .../Factories/AuthenticationFactory.cs | 4 ++-- ...ContainerRegistryDataPlaneOperationBase.cs | 19 ++++++++----------- .../ContainerRegistryManifestGetOperation.cs | 6 +++--- .../ContainerRegistryManifestListOperation.cs | 6 +++--- ...ontainerRegistryManifestRemoveOperation.cs | 6 +++--- ...ontainerRegistryManifestUpdateOperation.cs | 6 +++--- ...ContainerRegistryRepositoryGetOperation.cs | 6 +++--- ...ontainerRegistryRepositoryListOperation.cs | 2 +- ...tainerRegistryRepositoryRemoveOperation.cs | 6 +++--- ...tainerRegistryRepositoryUpdateOperation.cs | 6 +++--- .../ContainerRegistryTagGetOperation.cs | 6 +++--- .../ContainerRegistryTagListOperation.cs | 6 +++--- .../ContainerRegistryTagRemoveOperation.cs | 6 +++--- .../ContainerRegistryTagUpdateOperation.cs | 6 +++--- .../ContainerRegistry/Models/AcrToken.cs | 2 +- .../ContainerRegistry/Models/AcrTokenCache.cs | 2 +- .../ContainerRegistryDataPlaneClient.cs | 12 ++++++------ 20 files changed, 55 insertions(+), 71 deletions(-) diff --git a/src/Accounts/Accounts/ChangeLog.md b/src/Accounts/Accounts/ChangeLog.md index 86e223957363..cf24c834181b 100644 --- a/src/Accounts/Accounts/ChangeLog.md +++ b/src/Accounts/Accounts/ChangeLog.md @@ -18,7 +18,6 @@ - Additional information about change #1 --> ## Upcoming Release -* Updated `Clear-AzContext` to clean token cache created by Az.ContainerRegistry ## Version 2.2.4 * Shown correct client request id on debug message [#13745] diff --git a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs index 019faf5f27fe..2e646d8571d4 100644 --- a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs +++ b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs @@ -12,8 +12,6 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System; -using System.Collections.Generic; using System.IO; using System.Management.Automation; using Microsoft.Azure.Commands.Common.Authentication; @@ -87,20 +85,10 @@ void ClearContext(AzureRmProfile profile, RMProfileClient client) } } - ClearAzureSessionComponents(); - if (PassThru.IsPresent) { WriteObject(result); } } - - //Clear components with on clear-azcontext events in azure session instance - void ClearAzureSessionComponents() - { - AzureSession.Instance.ClearComponentsOnClearAzContext(); - } } - - } diff --git a/src/Accounts/Authentication/Authentication/ExternalAccessToken.cs b/src/Accounts/Authentication/Authentication/ExternalAccessToken.cs index 0f3d4a2a0e05..979708c6eb5b 100644 --- a/src/Accounts/Authentication/Authentication/ExternalAccessToken.cs +++ b/src/Accounts/Authentication/Authentication/ExternalAccessToken.cs @@ -32,10 +32,10 @@ public string UserId private readonly Func _refresh; - public ExternalAccessToken(string token, Func refresh = null) + public ExternalAccessToken(string accessToken, Func renew = null) { - this.AccessToken = token; - this._refresh = refresh; + this.AccessToken = accessToken; + this._refresh = renew; } public void AuthorizeRequest(Action authTokenSetter) diff --git a/src/Accounts/Authentication/Factories/AuthenticationFactory.cs b/src/Accounts/Authentication/Factories/AuthenticationFactory.cs index dcd4d0aff4af..d8f22e6f5967 100644 --- a/src/Accounts/Authentication/Factories/AuthenticationFactory.cs +++ b/src/Accounts/Authentication/Factories/AuthenticationFactory.cs @@ -349,9 +349,9 @@ public ServiceClientCredentials GetServiceClientCredentials(IAzureContext contex } } - public ServiceClientCredentials GetServiceClientCredentials(string token, Func func = null) + public ServiceClientCredentials GetServiceClientCredentials(string accessToken, Func renew = null) { - return new RenewingTokenCredential(new ExternalAccessToken(token, func)); + return new RenewingTokenCredential(new ExternalAccessToken(accessToken, renew)); } /// diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs index e7fdb96e9336..03a4169310fb 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs @@ -20,11 +20,11 @@ namespace Microsoft.Azure.Commands.ContainerRegistry.DataPlaneOperations public abstract class ContainerRegistryDataPlaneOperationBase { protected ContainerRegistryDataPlaneClient _client; - protected virtual string _scope + protected virtual string Scope { get { - return String.Format("{0}:{1}:{2}", _resource, _name, _permission); + return String.Format("{0}:{1}:{2}", Resource, Name, Permission); } set { @@ -32,7 +32,7 @@ protected virtual string _scope } } - protected virtual string _resource + protected virtual string Resource { get { @@ -40,7 +40,7 @@ protected virtual string _resource } } - protected virtual string _name + protected virtual string Name { get { @@ -48,7 +48,7 @@ protected virtual string _name } } - protected virtual string _permission + protected virtual string Permission { get { @@ -63,18 +63,15 @@ public ContainerRegistryDataPlaneOperationBase(ContainerRegistryDataPlaneClient public T ProcessRequest() { - _client.Authenticate(_scope); + _client.Authenticate(Scope); return SendRequest(); } - public virtual T SendRequest() - { - throw new NotImplementedException(); - } + public abstract T SendRequest(); //sample link: ; rel="next" //repository should be in between of first appeartance of '=' and '&' - protected string getLastListed(string nextLink) + protected string GetLastListed(string nextLink) { int left = nextLink.IndexOf('='); int right = nextLink.IndexOf('&'); diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestGetOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestGetOperation.cs index 5dd27c8ed1d7..32fe478f8684 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestGetOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestGetOperation.cs @@ -29,7 +29,7 @@ public ContainerRegistryManifestGetOperation(ContainerRegistryDataPlaneClient cl _manifestReference = manifest; } - protected override string _resource + protected override string Resource { get { @@ -37,7 +37,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -45,7 +45,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestListOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestListOperation.cs index 43ece041ad81..29e29ae54a7e 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestListOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestListOperation.cs @@ -27,7 +27,7 @@ public ContainerRegistryManifestListOperation(ContainerRegistryDataPlaneClient c this._repositoryName = repository; } - protected override string _resource + protected override string Resource { get { @@ -35,7 +35,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -43,7 +43,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestRemoveOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestRemoveOperation.cs index c072ab3e82ac..ed17d7200245 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestRemoveOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestRemoveOperation.cs @@ -28,7 +28,7 @@ public ContainerRegistryManifestRemoveOperation(ContainerRegistryDataPlaneClient this._manifestReference = manifest; } - protected override string _resource + protected override string Resource { get { @@ -36,7 +36,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -44,7 +44,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestUpdateOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestUpdateOperation.cs index 066fad3f76c9..f3c31d24f428 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestUpdateOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryManifestUpdateOperation.cs @@ -30,7 +30,7 @@ public ContainerRegistryManifestUpdateOperation(ContainerRegistryDataPlaneClient this._attribute = attribute; } - protected override string _resource + protected override string Resource { get { @@ -38,7 +38,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -46,7 +46,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryGetOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryGetOperation.cs index bdc0642fc661..2dc854ba5214 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryGetOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryGetOperation.cs @@ -27,7 +27,7 @@ public ContainerRegistryRepositoryGetOperation(ContainerRegistryDataPlaneClient this._repositoryName = name; } - protected override string _resource + protected override string Resource { get { @@ -35,7 +35,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -43,7 +43,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryListOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryListOperation.cs index 46b97c27a56e..4a4d6c5579fc 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryListOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryListOperation.cs @@ -75,7 +75,7 @@ public override IList SendRequest() { try { - last = getLastListed(nextLink); + last = GetLastListed(nextLink); hasNext = true; } catch diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryRemoveOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryRemoveOperation.cs index 84b131c43fd9..30e83a3514c5 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryRemoveOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryRemoveOperation.cs @@ -27,7 +27,7 @@ public ContainerRegistryRepositoryRemoveOperation(ContainerRegistryDataPlaneClie this._repositoryName = name; } - protected override string _resource + protected override string Resource { get { @@ -35,7 +35,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -43,7 +43,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryUpdateOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryUpdateOperation.cs index 9e3b1f9344a6..2de8b5099d73 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryUpdateOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryRepositoryUpdateOperation.cs @@ -30,7 +30,7 @@ public ContainerRegistryRepositoryUpdateOperation(ContainerRegistryDataPlaneClie this._attribute = attribute; } - protected override string _resource + protected override string Resource { get { @@ -38,7 +38,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -46,7 +46,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagGetOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagGetOperation.cs index 3b02f03804c0..9f1f030cb860 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagGetOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagGetOperation.cs @@ -29,7 +29,7 @@ public ContainerRegistryTagGetOperation(ContainerRegistryDataPlaneClient client, _tag = tag; } - protected override string _resource + protected override string Resource { get { @@ -37,7 +37,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -45,7 +45,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagListOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagListOperation.cs index 6623240c0309..487ba3fa2e78 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagListOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagListOperation.cs @@ -27,7 +27,7 @@ public ContainerRegistryTagListOperation(ContainerRegistryDataPlaneClient client this._repositoryName = repository; } - protected override string _resource + protected override string Resource { get { @@ -35,7 +35,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -43,7 +43,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagRemoveOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagRemoveOperation.cs index 19c451ee45d4..ce9655644fde 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagRemoveOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagRemoveOperation.cs @@ -29,7 +29,7 @@ public ContainerRegistryTagRemoveOperation(ContainerRegistryDataPlaneClient clie this._tag = tag; } - protected override string _resource + protected override string Resource { get { @@ -37,7 +37,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -45,7 +45,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagUpdateOperation.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagUpdateOperation.cs index 4f2eb404aead..a5d56ce51ecd 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagUpdateOperation.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryTagUpdateOperation.cs @@ -30,7 +30,7 @@ public ContainerRegistryTagUpdateOperation(ContainerRegistryDataPlaneClient clie this._attribute = attribute; } - protected override string _resource + protected override string Resource { get { @@ -38,7 +38,7 @@ protected override string _resource } } - protected override string _name + protected override string Name { get { @@ -46,7 +46,7 @@ protected override string _name } } - protected override string _permission + protected override string Permission { get { diff --git a/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs b/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs index 2e8f89713d67..e0b210002ee3 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs @@ -30,7 +30,7 @@ public string GetToken() public bool IsExpired(int minutesBeforeExpiration) { - return (_exp - DateTime.UtcNow).Minutes <= minutesBeforeExpiration; + return DateTime.UtcNow.AddMinutes(minutesBeforeExpiration) >= _exp; } } } diff --git a/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCache.cs b/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCache.cs index 89687282ec5a..f13438646b13 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCache.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/AcrTokenCache.cs @@ -25,7 +25,7 @@ public bool TryGetToken(string key, out AcrToken value) return _cache.TryGetValue(key, out value); } - public void Add(string key, AcrToken token) + public void Set(string key, AcrToken token) { _cache[key] = token; } diff --git a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs index 1ebc1d73d787..fcb3f41e9cf5 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/ContainerRegistryDataPlaneClient.cs @@ -79,7 +79,7 @@ private string GetToken(string key) AcrToken value; if (!cache.TryGetToken(key, out value) || value.IsExpired(_minutesBeforeExpiration)) { - string token = key.Equals(_refreshTokenKey) ? getRefreshToken() : getAccessToken(key); + string token = key.Equals(_refreshTokenKey) ? GetRefreshToken() : GetAccessToken(key); try { value = new AcrToken(token); @@ -89,7 +89,7 @@ private string GetToken(string key) throw new InvalidOperationException(string.Format("Invalud token for {0}", key)); } - cache.Add(key, value); + cache.Set(key, value); } return value.GetToken(); } @@ -105,7 +105,7 @@ public string GetEndPoint() return _endPoint; } - private string getArmAccessToken() + private string GetArmAccessToken() { return AzureSession .Instance.AuthenticationFactory @@ -113,17 +113,17 @@ private string getArmAccessToken() .AccessToken; } - private string getRefreshToken() + private string GetRefreshToken() { return GetClient() .RefreshTokens - .GetFromExchangeAsync(grantType: _defaultGrantType, service: _endPoint, accessToken: getArmAccessToken()) + .GetFromExchangeAsync(grantType: _defaultGrantType, service: _endPoint, accessToken: GetArmAccessToken()) .GetAwaiter() .GetResult() .RefreshTokenProperty; } - private string getAccessToken(string scope) + private string GetAccessToken(string scope) { return GetClient() .AccessTokens From 0f7467d0346524d8c734021564892bd2c58014a9 Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Thu, 28 Jan 2021 15:53:46 +0800 Subject: [PATCH 07/13] getlastlisted --- .../ContainerRegistryDataPlaneOperationBase.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs index 03a4169310fb..3ffdf8f532e7 100644 --- a/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs +++ b/src/ContainerRegistry/ContainerRegistry/DataPlaneOperations/ContainerRegistryDataPlaneOperationBase.cs @@ -73,9 +73,11 @@ public T ProcessRequest() //repository should be in between of first appeartance of '=' and '&' protected string GetLastListed(string nextLink) { - int left = nextLink.IndexOf('='); - int right = nextLink.IndexOf('&'); - return HttpUtility.UrlDecode(nextLink.Substring(left + 1, right - left - 1)); + int startOfParam = nextLink.IndexOf('<') + 1; + int endOfParam = nextLink.IndexOf('>') - startOfParam - 1; + string param = nextLink.Substring(startOfParam, endOfParam).Substring(nextLink.IndexOf('?') + 1); + string last = param.Split('&')[0].Split('=')[1]; + return HttpUtility.UrlDecode(last); } } } From d1dbead6c802dcb8771263dbe8ab98c3009246b3 Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Mon, 1 Feb 2021 15:30:48 +0800 Subject: [PATCH 08/13] remove unused class --- .../ContainerRegistry/Models/AcrToken.cs | 2 +- .../ContainerRegistry/Models/PSAcrToken.cs | 43 ------------------- 2 files changed, 1 insertion(+), 44 deletions(-) delete mode 100644 src/ContainerRegistry/ContainerRegistry/Models/PSAcrToken.cs diff --git a/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs b/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs index e0b210002ee3..a9bfc8b0cf2d 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/AcrToken.cs @@ -1,4 +1,4 @@ -using Microsoft.Azure.Commands.Profile.Utilities; +using Microsoft.WindowsAzure.Commands.Utilities.Common; using System; using System.Linq; using System.Text.Json; diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSAcrToken.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSAcrToken.cs deleted file mode 100644 index 0bab2e71450e..000000000000 --- a/src/ContainerRegistry/ContainerRegistry/Models/PSAcrToken.cs +++ /dev/null @@ -1,43 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// 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.Profile.Utilities; -using System; -using System.Linq; -using System.Text.Json; - -namespace Microsoft.Azure.Commands.ContainerRegistry.Models -{ - public class PSAcrToken - { - public readonly string token; - public readonly DateTime exp; - - public PSAcrToken(string token) - { - this.token = token; - - //header, payload, signature are splitted by '.' in token - string decodedToken = Base64UrlHelper.DecodeToString(token.Split('.')[1]); - int unixTimeSeconds = JsonDocument.Parse(decodedToken) - .RootElement - .EnumerateObject() - .Where(p => p.Name == "exp") - .Select(p => p.Value.GetInt32()) - .First(); - - this.exp = DateTimeOffset.FromUnixTimeSeconds(unixTimeSeconds).UtcDateTime; - } - } -} From 3a62d87ec337e1cfc35e4526e870b36e21fef651 Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Mon, 1 Feb 2021 15:58:18 +0800 Subject: [PATCH 09/13] remove unneeded changes --- src/Accounts/Accounts/Context/ClearAzureRmContext.cs | 1 + .../Authentication/ExternalAccessToken.cs | 6 +++--- .../Factories/AuthenticationFactory.cs | 5 ----- src/ContainerRegistry/ContainerRegistry.sln | 12 ++++-------- .../Mocks/MockCertificateAuthenticationFactory.cs | 5 ----- .../Mocks/MockTokenAuthenticationFactory.cs | 5 ----- 6 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs index 2e646d8571d4..c2649392ed5c 100644 --- a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs +++ b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs @@ -14,6 +14,7 @@ using System.IO; using System.Management.Automation; + using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Models; diff --git a/src/Accounts/Authentication/Authentication/ExternalAccessToken.cs b/src/Accounts/Authentication/Authentication/ExternalAccessToken.cs index 979708c6eb5b..0f3d4a2a0e05 100644 --- a/src/Accounts/Authentication/Authentication/ExternalAccessToken.cs +++ b/src/Accounts/Authentication/Authentication/ExternalAccessToken.cs @@ -32,10 +32,10 @@ public string UserId private readonly Func _refresh; - public ExternalAccessToken(string accessToken, Func renew = null) + public ExternalAccessToken(string token, Func refresh = null) { - this.AccessToken = accessToken; - this._refresh = renew; + this.AccessToken = token; + this._refresh = refresh; } public void AuthorizeRequest(Action authTokenSetter) diff --git a/src/Accounts/Authentication/Factories/AuthenticationFactory.cs b/src/Accounts/Authentication/Factories/AuthenticationFactory.cs index d8f22e6f5967..5dc8c058978e 100644 --- a/src/Accounts/Authentication/Factories/AuthenticationFactory.cs +++ b/src/Accounts/Authentication/Factories/AuthenticationFactory.cs @@ -349,11 +349,6 @@ public ServiceClientCredentials GetServiceClientCredentials(IAzureContext contex } } - public ServiceClientCredentials GetServiceClientCredentials(string accessToken, Func renew = null) - { - return new RenewingTokenCredential(new ExternalAccessToken(accessToken, renew)); - } - /// /// Remove a user from token cache. /// diff --git a/src/ContainerRegistry/ContainerRegistry.sln b/src/ContainerRegistry/ContainerRegistry.sln index aabd08919c3e..86dadcb3f231 100644 --- a/src/ContainerRegistry/ContainerRegistry.sln +++ b/src/ContainerRegistry/ContainerRegistry.sln @@ -36,18 +36,14 @@ Global {094709D1-0301-44F4-8BB2-203162006A3D}.Debug|Any CPU.Build.0 = Debug|Any CPU {094709D1-0301-44F4-8BB2-203162006A3D}.Release|Any CPU.ActiveCfg = Release|Any CPU {094709D1-0301-44F4-8BB2-203162006A3D}.Release|Any CPU.Build.0 = Release|Any CPU - {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Release|Any CPU.Build.0 = Release|Any CPU - {6BD6B80A-06AF-4B5B-9230-69CCFC6C8D64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6BD6B80A-06AF-4B5B-9230-69CCFC6C8D64}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6BD6B80A-06AF-4B5B-9230-69CCFC6C8D64}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6BD6B80A-06AF-4B5B-9230-69CCFC6C8D64}.Release|Any CPU.Build.0 = Release|Any CPU {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Debug|Any CPU.Build.0 = Debug|Any CPU {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Release|Any CPU.ActiveCfg = Release|Any CPU {2EF2B093-6C82-4AC4-A073-89DA030980E7}.Release|Any CPU.Build.0 = Release|Any CPU + {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {142D7B0B-388A-4CEB-A228-7F6D423C5C2E}.Release|Any CPU.Build.0 = Release|Any CPU {FF81DC73-B8EC-4082-8841-4FBF2B16E7CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FF81DC73-B8EC-4082-8841-4FBF2B16E7CE}.Debug|Any CPU.Build.0 = Debug|Any CPU {FF81DC73-B8EC-4082-8841-4FBF2B16E7CE}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs b/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs index 2c87c8afd2d3..a5c48f68ddf4 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs +++ b/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs @@ -96,11 +96,6 @@ public Rest.ServiceClientCredentials GetServiceClientCredentials(IAzureContext c throw new System.NotImplementedException(); } - public Rest.ServiceClientCredentials GetServiceClientCredentials(string token, Func func = null) - { - throw new System.NotImplementedException(); - } - public void RemoveUser(IAzureAccount account, IAzureTokenCache tokenCache) { throw new NotImplementedException(); diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs b/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs index 8a41f038f852..ffbfd7e845e0 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs +++ b/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs @@ -136,11 +136,6 @@ public ServiceClientCredentials GetServiceClientCredentials(IAzureContext contex return new Microsoft.Rest.TokenCredentials(Token.AccessToken); } - public Rest.ServiceClientCredentials GetServiceClientCredentials(string token, Func func = null) - { - throw new System.NotImplementedException(); - } - public void RemoveUser(IAzureAccount account, IAzureTokenCache tokenCache) { throw new NotImplementedException(); From 59f63462522820490d667055610be247834cba9b Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Tue, 2 Feb 2021 11:46:25 +0800 Subject: [PATCH 10/13] fix null reference in PSAcrManifest and remove unused suppression --- .../ContainerRegistry/Models/PSAcrManifest.cs | 2 +- .../Exceptions/Az.ContainerRegistry/MissingAssemblies.csv | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ContainerRegistry/ContainerRegistry/Models/PSAcrManifest.cs b/src/ContainerRegistry/ContainerRegistry/Models/PSAcrManifest.cs index 43b6f201d9d2..be4cc7854276 100644 --- a/src/ContainerRegistry/ContainerRegistry/Models/PSAcrManifest.cs +++ b/src/ContainerRegistry/ContainerRegistry/Models/PSAcrManifest.cs @@ -31,7 +31,7 @@ public PSAcrManifest(AcrManifests manifest) { Registry = manifest?.Registry; ImageName = manifest?.Registry; - if (manifest != null) + if (manifest != null && manifest.ManifestsAttributes != null) { ManifestsAttributes = manifest.ManifestsAttributes.Select(x => new PSManifestAttributeBase(x)).ToList(); } diff --git a/tools/StaticAnalysis/Exceptions/Az.ContainerRegistry/MissingAssemblies.csv b/tools/StaticAnalysis/Exceptions/Az.ContainerRegistry/MissingAssemblies.csv index 6c6babfa0bf2..ae7c7af2fa2d 100644 --- a/tools/StaticAnalysis/Exceptions/Az.ContainerRegistry/MissingAssemblies.csv +++ b/tools/StaticAnalysis/Exceptions/Az.ContainerRegistry/MissingAssemblies.csv @@ -1,6 +1,4 @@ "Directory","Assembly Name","Assembly Version","Referencing Assembly","Severity","ProblemId","Description","Remediation" "Az.ContainerRegistry","Microsoft.Win32.Registry","4.1.1.0","System.Management.Automation","0","3000","Missing assembly Microsoft.Win32.Registry referenced from System.Management.Automation","Ensure that the assembly is included in the Wix file or directory" "Az.ContainerRegistry","Microsoft.PowerShell.CoreCLR.Eventing","6.1.0.0","System.Management.Automation","0","3000","Missing assembly Microsoft.PowerShell.CoreCLR.Eventing referenced from System.Management.Automation","Ensure that the assembly is included in the Wix file or directory" -"Az.ContainerRegistry","System.IdentityModel.Tokens.Jwt","5.1.2.0","Microsoft.Azure.ContainerRegistry","0","3000","Missing assembly System.IdentityModel.Tokens.Jwt referenced from Microsoft.Azure.ContainerRegistry","Ensure that the assembly is included in the Wix file or directory" -"Az.ContainerRegistry","System.Text.Encodings.Web","4.0.4.0","Azure.Identity","0","3000","Missing assembly System.Text.Encodings.Web referenced from Azure.Identity","Ensure that the assembly is included in the Wix file or directory" -"Az.ContainerRegistry","System.Net.HttpListener","4.0.1.0","Microsoft.Identity.Client","0","3000","Missing assembly System.Net.HttpListener referenced from Microsoft.Identity.Client","Ensure that the assembly is included in the Wix file or directory" \ No newline at end of file +"Az.ContainerRegistry","System.IdentityModel.Tokens.Jwt","5.1.2.0","Microsoft.Azure.ContainerRegistry","0","3000","Missing assembly System.IdentityModel.Tokens.Jwt referenced from Microsoft.Azure.ContainerRegistry","Ensure that the assembly is included in the Wix file or directory" \ No newline at end of file From 53e1feeba035631eab2388535a6e25bbc8a4bbeb Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Tue, 2 Feb 2021 12:33:21 +0800 Subject: [PATCH 11/13] Update ChangeLog.md --- src/ContainerRegistry/ContainerRegistry/ChangeLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ContainerRegistry/ContainerRegistry/ChangeLog.md b/src/ContainerRegistry/ContainerRegistry/ChangeLog.md index 8d7ff100e814..5801c1ffb656 100644 --- a/src/ContainerRegistry/ContainerRegistry/ChangeLog.md +++ b/src/ContainerRegistry/ContainerRegistry/ChangeLog.md @@ -18,7 +18,7 @@ - Additional information about change #1 --> ## Upcoming Release -* Added cmdlets: +* Added cmdlets to supported repository, manifest, and tag operations: - `Get-AzContainerRegistryRepository` - `Update-AzContainerRegistryRepository` - `Remove-AzContainerRegistryRepository` From 86d845a833a99a947b36fda07fe1c037b3a5bd5e Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Tue, 2 Feb 2021 13:28:12 +0800 Subject: [PATCH 12/13] fix Acr to ACR in help markdown --- .../ContainerRegistry/help/Az.ContainerRegistry.md | 2 +- .../ContainerRegistry/help/Update-AzContainerRegistryTag.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ContainerRegistry/ContainerRegistry/help/Az.ContainerRegistry.md b/src/ContainerRegistry/ContainerRegistry/help/Az.ContainerRegistry.md index ddd3d7a74fe9..c0d62f4f317f 100644 --- a/src/ContainerRegistry/ContainerRegistry/help/Az.ContainerRegistry.md +++ b/src/ContainerRegistry/ContainerRegistry/help/Az.ContainerRegistry.md @@ -96,7 +96,7 @@ Update ACR manifest. Update ACR repository. ### [Update-AzContainerRegistryTag](Update-AzContainerRegistryTag.md) -Update Acr tag. +Update ACR tag. ### [Update-AzContainerRegistryWebhook](Update-AzContainerRegistryWebhook.md) Updates a container registry webhook. diff --git a/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryTag.md b/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryTag.md index 1a1a793628b7..e53e6d739326 100644 --- a/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryTag.md +++ b/src/ContainerRegistry/ContainerRegistry/help/Update-AzContainerRegistryTag.md @@ -8,7 +8,7 @@ schema: 2.0.0 # Update-AzContainerRegistryTag ## SYNOPSIS -Update Acr tag. +Update ACR tag. ## SYNTAX From 191b4b69349cf0f24f6a424d9ab19b1af6e25b1c Mon Sep 17 00:00:00 2001 From: Yabo Hu Date: Tue, 2 Feb 2021 14:01:39 +0800 Subject: [PATCH 13/13] fix output type for Get-AzContainerRegistryRepository --- .../Commands/GetAzureContainerRegistryRepository.cs | 2 +- .../help/Get-AzContainerRegistryRepository.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryRepository.cs b/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryRepository.cs index f0a6c60f4240..fd262c6aa64a 100644 --- a/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryRepository.cs +++ b/src/ContainerRegistry/ContainerRegistry/Commands/GetAzureContainerRegistryRepository.cs @@ -19,7 +19,7 @@ namespace Microsoft.Azure.Commands.ContainerRegistry { [Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContainerRegistryRepository", DefaultParameterSetName = ListParameterSet)] - [OutputType(typeof(PSAcrManifest), typeof(PSManifestAttribute))] + [OutputType(typeof(string), typeof(PSRepositoryAttribute))] public class GetAzureContainerRegistryRepository : ContainerRegistryDataPlaneCmdletBase { [Parameter(ParameterSetName = GetParameterSet, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Repository Name.")] diff --git a/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryRepository.md b/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryRepository.md index 939b4d5405b0..8abf0c42d0d3 100644 --- a/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryRepository.md +++ b/src/ContainerRegistry/ContainerRegistry/help/Get-AzContainerRegistryRepository.md @@ -137,9 +137,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ## OUTPUTS -### Microsoft.Azure.Commands.ContainerRegistry.Models.PSAcrManifest +### System.String -### Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttribute +### Microsoft.Azure.Commands.ContainerRegistry.Models.PSRepositoryAttribute ## NOTES