Skip to content

Commit 9aa8538

Browse files
Allow wildcard for MAR repository for FindAll and FindByName (#1786)
1 parent 28d241e commit 9aa8538

File tree

2 files changed

+92
-14
lines changed

2 files changed

+92
-14
lines changed

src/code/ContainerRegistryServerAPICalls.cs

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ internal class ContainerRegistryServerAPICalls : ServerApiCall
4646
const string containerRegistryFindImageVersionUrlTemplate = "https://{0}/v2/{1}/tags/list"; // 0 - registry, 1 - repo(modulename)
4747
const string containerRegistryStartUploadTemplate = "https://{0}/v2/{1}/blobs/uploads/"; // 0 - registry, 1 - packagename
4848
const string containerRegistryEndUploadTemplate = "https://{0}{1}&digest=sha256:{2}"; // 0 - registry, 1 - location, 2 - digest
49+
const string containerRegistryRepositoryListTemplate = "https://{0}/v2/_catalog"; // 0 - registry
4950

5051
#endregion
5152

@@ -76,13 +77,13 @@ public ContainerRegistryServerAPICalls(PSRepositoryInfo repository, PSCmdlet cmd
7677
public override FindResults FindAll(bool includePrerelease, ResourceType type, out ErrorRecord errRecord)
7778
{
7879
_cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::FindAll()");
79-
errRecord = new ErrorRecord(
80-
new InvalidOperationException($"Find all is not supported for the ContainerRegistry server protocol repository '{Repository.Name}'"),
81-
"FindAllFailure",
82-
ErrorCategory.InvalidOperation,
83-
this);
80+
var findResult = FindPackages("*", includePrerelease, out errRecord);
81+
if (errRecord != null)
82+
{
83+
return emptyResponseResults;
84+
}
8485

85-
return emptyResponseResults;
86+
return findResult;
8687
}
8788

8889
/// <summary>
@@ -161,13 +162,13 @@ public override FindResults FindNameWithTag(string packageName, string[] tags, b
161162
public override FindResults FindNameGlobbing(string packageName, bool includePrerelease, ResourceType type, out ErrorRecord errRecord)
162163
{
163164
_cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::FindNameGlobbing()");
164-
errRecord = new ErrorRecord(
165-
new InvalidOperationException($"FindNameGlobbing all is not supported for the ContainerRegistry server protocol repository '{Repository.Name}'"),
166-
"FindNameGlobbingFailure",
167-
ErrorCategory.InvalidOperation,
168-
this);
165+
var findResult = FindPackages(packageName, includePrerelease, out errRecord);
166+
if (errRecord != null)
167+
{
168+
return emptyResponseResults;
169+
}
169170

170-
return emptyResponseResults;
171+
return findResult;
171172
}
172173

173174
/// <summary>
@@ -591,6 +592,20 @@ internal JObject FindContainerRegistryImageTags(string packageName, string versi
591592
return GetHttpResponseJObjectUsingDefaultHeaders(findImageUrl, HttpMethod.Get, defaultHeaders, out errRecord);
592593
}
593594

595+
/// <summary>
596+
/// Helper method to find all packages on container registry
597+
/// </summary>
598+
/// <param name="containerRegistryAccessToken"></param>
599+
/// <param name="errRecord"></param>
600+
/// <returns></returns>
601+
internal JObject FindAllRepositories(string containerRegistryAccessToken, out ErrorRecord errRecord)
602+
{
603+
_cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::FindAllRepositories()");
604+
string repositoryListUrl = string.Format(containerRegistryRepositoryListTemplate, Registry);
605+
var defaultHeaders = GetDefaultHeaders(containerRegistryAccessToken);
606+
return GetHttpResponseJObjectUsingDefaultHeaders(repositoryListUrl, HttpMethod.Get, defaultHeaders, out errRecord);
607+
}
608+
594609
/// <summary>
595610
/// Get metadata for a package version.
596611
/// </summary>
@@ -1705,12 +1720,63 @@ private string PrependMARPrefix(string packageName)
17051720

17061721
// If the repostitory is MAR and its not a wildcard search, we need to prefix the package name with MAR prefix.
17071722
string updatedPackageName = Repository.IsMARRepository() && packageName.Trim() != "*"
1708-
? string.Concat(prefix, packageName)
1723+
? packageName.StartsWith(prefix) ? packageName : string.Concat(prefix, packageName)
17091724
: packageName;
17101725

17111726
return updatedPackageName;
17121727
}
17131728

1729+
private FindResults FindPackages(string packageName, bool includePrerelease, out ErrorRecord errRecord)
1730+
{
1731+
_cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::FindPackages()");
1732+
errRecord = null;
1733+
string containerRegistryAccessToken = GetContainerRegistryAccessToken(out errRecord);
1734+
if (errRecord != null)
1735+
{
1736+
return emptyResponseResults;
1737+
}
1738+
1739+
var pkgResult = FindAllRepositories(containerRegistryAccessToken, out errRecord);
1740+
if (errRecord != null)
1741+
{
1742+
return emptyResponseResults;
1743+
}
1744+
1745+
List<Hashtable> repositoriesList = new List<Hashtable>();
1746+
var isMAR = Repository.IsMARRepository();
1747+
1748+
// Convert the list of repositories to a list of hashtables
1749+
foreach (var repository in pkgResult["repositories"].ToList())
1750+
{
1751+
string repositoryName = repository.ToString();
1752+
1753+
if (isMAR && !repositoryName.StartsWith(PSRepositoryInfo.MARPrefix))
1754+
{
1755+
continue;
1756+
}
1757+
1758+
// This remove the 'psresource/' prefix from the repository name for comparison with wildcard.
1759+
string moduleName = repositoryName.Substring(11);
1760+
1761+
WildcardPattern wildcardPattern = new WildcardPattern(packageName, WildcardOptions.IgnoreCase);
1762+
1763+
if (!wildcardPattern.IsMatch(moduleName))
1764+
{
1765+
continue;
1766+
}
1767+
1768+
_cmdletPassedIn.WriteDebug($"Found repository: {repositoryName}");
1769+
1770+
repositoriesList.AddRange(FindPackagesWithVersionHelper(repositoryName, VersionType.VersionRange, versionRange: VersionRange.All, requiredVersion: null, includePrerelease, getOnlyLatest: true, out errRecord));
1771+
if (errRecord != null)
1772+
{
1773+
return emptyResponseResults;
1774+
}
1775+
}
1776+
1777+
return new FindResults(stringResponse: new string[] { }, hashtableResponse: repositoriesList.ToArray(), responseType: containerRegistryFindResponseType);
1778+
}
1779+
17141780
#endregion
17151781
}
17161782
}

test/FindPSResourceTests/FindPSResourceContainerRegistryServer.Tests.ps1

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,24 @@ Describe 'Test Find-PSResource for MAR Repository' -tags 'CI' {
247247
It "Should find resource given specific Name, Version null" {
248248
$res = Find-PSResource -Name "Az.Accounts" -Repository "MAR"
249249
$res.Name | Should -Be "Az.Accounts"
250-
$res.Version | Should -Be "4.0.0"
250+
$res.Version | Should -BeGreaterThan ([Version]"4.0.0")
251251
}
252252

253253
It "Should find resource and its dependency given specific Name and Version" {
254254
$res = Find-PSResource -Name "Az.Storage" -Version "8.0.0" -Repository "MAR"
255255
$res.Dependencies.Length | Should -Be 1
256256
$res.Dependencies[0].Name | Should -Be "Az.Accounts"
257257
}
258+
259+
It "Should find resource with wildcard in Name" {
260+
$res = Find-PSResource -Name "Az.App*" -Repository "MAR"
261+
$res | Should -Not -BeNullOrEmpty
262+
$res.Count | Should -BeGreaterThan 1
263+
}
264+
265+
It "Should find all resource with wildcard in Name" {
266+
$res = Find-PSResource -Name "*" -Repository "MAR"
267+
$res | Should -Not -BeNullOrEmpty
268+
$res.Count | Should -BeGreaterThan 1
269+
}
258270
}

0 commit comments

Comments
 (0)