diff --git a/src/code/ACRServerAPICalls.cs b/src/code/ACRServerAPICalls.cs index 6582c2fd6..a96734b0e 100644 --- a/src/code/ACRServerAPICalls.cs +++ b/src/code/ACRServerAPICalls.cs @@ -130,12 +130,53 @@ public override FindResults FindCommandOrDscResource(string[] tags, bool include /// public override FindResults FindName(string packageName, bool includePrerelease, ResourceType type, out ErrorRecord errRecord) { + errRecord = null; _cmdletPassedIn.WriteDebug("In ACRServerAPICalls::FindName()"); - errRecord = new ErrorRecord( - new InvalidOperationException($"Find name is not supported for the ACR server protocol repository '{Repository.Name}'"), - "FindNameFailure", - ErrorCategory.InvalidOperation, - this); + string accessToken = string.Empty; + string tenantID = string.Empty; + + // Need to set up secret management vault before hand + var repositoryCredentialInfo = Repository.CredentialInfo; + if (repositoryCredentialInfo != null) + { + accessToken = Utils.GetACRAccessTokenFromSecretManagement( + Repository.Name, + repositoryCredentialInfo, + _cmdletPassedIn); + + _cmdletPassedIn.WriteVerbose("Access token retrieved."); + + tenantID = Utils.GetSecretInfoFromSecretManagement( + Repository.Name, + repositoryCredentialInfo, + _cmdletPassedIn); + } + + // Call asynchronous network methods in a try/catch block to handle exceptions. + string registry = Repository.Uri.Host; + + _cmdletPassedIn.WriteVerbose("Getting acr refresh token"); + var acrRefreshToken = GetAcrRefreshTokenAsync(registry, tenantID, accessToken).Result; + _cmdletPassedIn.WriteVerbose("Getting acr access token"); + var acrAccessToken = GetAcrAccessTokenAsync(registry, acrRefreshToken).Result; + + _cmdletPassedIn.WriteVerbose("Getting tags"); + var foundTags = FindAcrImageTags(registry, packageName, "*", acrAccessToken).Result; + Console.WriteLine(foundTags.ToString(Formatting.None)); + + if (foundTags != null) + { + foreach (var item in foundTags["tags"]) + { + // digest: {item["digest"]"; + string tagVersion = item["name"].ToString(); + Console.WriteLine("tag version: " + tagVersion); + + /* + foundPkgs.Add(new PSResourceInfo(name: pkgName, version: tagVersion, repository: repo.Name)); + */ + } + } return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v3FindResponseType); } @@ -227,13 +268,49 @@ public override FindResults FindVersionGlobbing(string packageName, VersionRange /// public override FindResults FindVersion(string packageName, string version, ResourceType type, out ErrorRecord errRecord) { - + errRecord = null; _cmdletPassedIn.WriteDebug("In ACRServerAPICalls::FindVersion()"); - errRecord = new ErrorRecord( - new InvalidOperationException($"Find version is not supported for the ACR server protocol repository '{Repository.Name}'"), - "FindVersionFailure", - ErrorCategory.InvalidOperation, - this); + string accessToken = string.Empty; + string tenantID = string.Empty; + + // Need to set up secret management vault before hand + var repositoryCredentialInfo = Repository.CredentialInfo; + if (repositoryCredentialInfo != null) + { + accessToken = Utils.GetACRAccessTokenFromSecretManagement( + Repository.Name, + repositoryCredentialInfo, + _cmdletPassedIn); + + _cmdletPassedIn.WriteVerbose("Access token retrieved."); + + tenantID = Utils.GetSecretInfoFromSecretManagement( + Repository.Name, + repositoryCredentialInfo, + _cmdletPassedIn); + } + + // Call asynchronous network methods in a try/catch block to handle exceptions. + string registry = Repository.Uri.Host; + + _cmdletPassedIn.WriteVerbose("Getting acr refresh token"); + var acrRefreshToken = GetAcrRefreshTokenAsync(registry, tenantID, accessToken).Result; + _cmdletPassedIn.WriteVerbose("Getting acr access token"); + var acrAccessToken = GetAcrAccessTokenAsync(registry, acrRefreshToken).Result; + + _cmdletPassedIn.WriteVerbose("Getting tags"); + var foundTags = FindAcrImageTags(registry, packageName, version, acrAccessToken).Result; + + if (foundTags != null) + { + var digest = foundTags["tag"]["digest"]; + Console.WriteLine("digest: " + digest); + // pkgVersion was used in the API call (same as foundTags["name"]) + // digest: foundTags["tag"]["digest"]"; + /* + foundPkgs.Add(new PSResourceInfo(name: pkgName, version: pkgVersion, repository: repo.Name)); + */ + } return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v3FindResponseType); } diff --git a/src/code/PSRepositoryInfo.cs b/src/code/PSRepositoryInfo.cs index 2ab93b192..4700d5d2a 100644 --- a/src/code/PSRepositoryInfo.cs +++ b/src/code/PSRepositoryInfo.cs @@ -19,7 +19,8 @@ public enum APIVersion v2, v3, local, - nugetServer + nugetServer, + acr } #endregion diff --git a/src/code/RepositorySettings.cs b/src/code/RepositorySettings.cs index 1ba44e8d4..b7d4e226e 100644 --- a/src/code/RepositorySettings.cs +++ b/src/code/RepositorySettings.cs @@ -840,6 +840,10 @@ private static PSRepositoryInfo.APIVersion GetRepoAPIVersion(Uri repoUri) // repositories with Uri Scheme "temp" may have PSPath Uri's like: "Temp:\repo" and we should consider them as local repositories. return PSRepositoryInfo.APIVersion.local; } + else if (repoUri.AbsoluteUri.EndsWith(".azurecr.io") || repoUri.AbsoluteUri.EndsWith(".azurecr.io/")) + { + return PSRepositoryInfo.APIVersion.acr; + } else { return PSRepositoryInfo.APIVersion.unknown; diff --git a/src/code/ResponseUtilFactory.cs b/src/code/ResponseUtilFactory.cs index 3f25d63c3..843f9042b 100644 --- a/src/code/ResponseUtilFactory.cs +++ b/src/code/ResponseUtilFactory.cs @@ -30,6 +30,10 @@ public static ResponseUtil GetResponseUtil(PSRepositoryInfo repository) currentResponseUtil = new NuGetServerResponseUtil(repository); break; + case PSRepositoryInfo.APIVersion.acr: + currentResponseUtil = new ACRResponseUtil(repository); + break; + case PSRepositoryInfo.APIVersion.unknown: break; } diff --git a/src/code/ServerFactory.cs b/src/code/ServerFactory.cs index 8be08662e..b3e85187d 100644 --- a/src/code/ServerFactory.cs +++ b/src/code/ServerFactory.cs @@ -58,6 +58,10 @@ public static ServerApiCall GetServer(PSRepositoryInfo repository, PSCmdlet cmdl currentServer = new NuGetServerAPICalls(repository, cmdletPassedIn, networkCredential, userAgentString); break; + case PSRepositoryInfo.APIVersion.acr: + currentServer = new ACRServerAPICalls(repository, cmdletPassedIn, networkCredential, userAgentString); + break; + case PSRepositoryInfo.APIVersion.unknown: break; } diff --git a/src/code/Utils.cs b/src/code/Utils.cs index a6d8a10ca..04dfba6af 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -684,6 +684,11 @@ public static string GetACRAccessTokenFromSecretManagement( string password = new NetworkCredential(string.Empty, secretSecureString).Password; return password; } + else if(secretValue is PSCredential psCredSecret) + { + string password = new NetworkCredential(string.Empty, psCredSecret.Password).Password; + return password; + } cmdletPassedIn.ThrowTerminatingError( new ErrorRecord(