Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Bicep.sln
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bicep.MSBuild", "src\Bicep.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bicep.Core.RegistryClient", "src\Bicep.Core.RegistryClient\Bicep.Core.RegistryClient.csproj", "{AA51BD66-BD30-432C-82B6-C783F232D989}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Containers.ContainerRegistry", "..\azure-sdk-for-net\sdk\containerregistry\Azure.Containers.ContainerRegistry\src\Azure.Containers.ContainerRegistry.csproj", "{3F04EBA8-F6BB-4A24-8AAE-9FE629F50ABE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -142,6 +144,10 @@ Global
{AA51BD66-BD30-432C-82B6-C783F232D989}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA51BD66-BD30-432C-82B6-C783F232D989}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA51BD66-BD30-432C-82B6-C783F232D989}.Release|Any CPU.Build.0 = Release|Any CPU
{3F04EBA8-F6BB-4A24-8AAE-9FE629F50ABE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F04EBA8-F6BB-4A24-8AAE-9FE629F50ABE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F04EBA8-F6BB-4A24-8AAE-9FE629F50ABE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F04EBA8-F6BB-4A24-8AAE-9FE629F50ABE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -163,6 +169,7 @@ Global
{F3AF01F6-24E8-4129-80B6-84AC070B5C7D} = {61643BA1-BE82-4430-A3D3-CB7A16E747E3}
{61026689-70A0-403E-B616-DFAEEF259444} = {38A0A11F-72BD-4512-A4A9-AC953936C09F}
{AA51BD66-BD30-432C-82B6-C783F232D989} = {FE323E78-E865-46E2-859A-E4F6FB312C0F}
{3F04EBA8-F6BB-4A24-8AAE-9FE629F50ABE} = {FE323E78-E865-46E2-859A-E4F6FB312C0F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {21F77282-91E7-4304-B1EF-FADFA4F39E37}
Expand Down
204 changes: 102 additions & 102 deletions src/Bicep.Core.RegistryClient/BicepRegistryBlobClient.cs
Original file line number Diff line number Diff line change
@@ -1,105 +1,105 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Azure;
using Azure.Core;
using Azure.Core.Pipeline;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using Bicep.Core.Registry.Oci;
using Bicep.Core.RegistryClient.Models;

namespace Bicep.Core.RegistryClient
{
public class BicepRegistryBlobClient
{
private readonly Uri _endpoint;
private readonly string _registryName;
private readonly HttpPipeline _pipeline;
private readonly HttpPipeline _acrAuthPipeline;
private readonly ClientDiagnostics _clientDiagnostics;
private readonly ContainerRegistryRestClient _restClient;
private readonly AuthenticationRestClient _acrAuthClient;
private readonly ContainerRegistryBlobRestClient _blobRestClient;
private readonly string _repositoryName;

public BicepRegistryBlobClient(Uri endpoint, TokenCredential credential, string repositoryName) : this(endpoint, credential, repositoryName, new ContainerRegistryClientOptions())
{
}

public BicepRegistryBlobClient(Uri endpoint, TokenCredential credential, string repositoryName, ContainerRegistryClientOptions options)
{
Argument.AssertNotNull(endpoint, nameof(endpoint));
Argument.AssertNotNull(credential, nameof(credential));
Argument.AssertNotNull(options, nameof(options));

_endpoint = endpoint;
_registryName = endpoint.Host.Split('.')[0];
_repositoryName = repositoryName;
_clientDiagnostics = new ClientDiagnostics(options);

_acrAuthPipeline = HttpPipelineBuilder.Build(options);
_acrAuthClient = new AuthenticationRestClient(_clientDiagnostics, _acrAuthPipeline, endpoint.AbsoluteUri);

_pipeline = HttpPipelineBuilder.Build(options, new ContainerRegistryChallengeAuthenticationPolicy(credential, options.AuthenticationScope, _acrAuthClient));
_restClient = new ContainerRegistryRestClient(_clientDiagnostics, _pipeline, _endpoint.AbsoluteUri);
_blobRestClient = new ContainerRegistryBlobRestClient(_clientDiagnostics, _pipeline, _endpoint.AbsoluteUri);
}

// allows mocking
protected BicepRegistryBlobClient()
{
}

public virtual async Task<Response<UploadBlobResult>> UploadBlobAsync(Stream stream, CancellationToken cancellationToken = default)
{
string digest = DigestHelper.ComputeDigest(DigestHelper.AlgorithmIdentifierSha256, stream);

ResponseWithHeaders<ContainerRegistryBlobStartUploadHeaders> startUploadResult =
await _blobRestClient.StartUploadAsync(_repositoryName, cancellationToken).ConfigureAwait(false);

stream.Position = 0;
ResponseWithHeaders<ContainerRegistryBlobUploadChunkHeaders> uploadChunkResult =
await _blobRestClient.UploadChunkAsync(startUploadResult.Headers.Location, stream, cancellationToken).ConfigureAwait(false);

ResponseWithHeaders<ContainerRegistryBlobCompleteUploadHeaders> completeUploadResult =
await _blobRestClient.CompleteUploadAsync(digest, uploadChunkResult.Headers.Location, null, cancellationToken).ConfigureAwait(false);

return Response.FromValue(new UploadBlobResult(), completeUploadResult.GetRawResponse());
}

public virtual async Task<Response<UploadManifestResult>> UploadManifestAsync(Stream stream, UploadManifestOptions options = default, CancellationToken cancellationToken = default)
{
options ??= new UploadManifestOptions();

string reference = options.Tag ?? DigestHelper.ComputeDigest(DigestHelper.AlgorithmIdentifierSha256, stream);
stream.Position = 0;
ResponseWithHeaders<ContainerRegistryCreateManifestHeaders> response = await _restClient.CreateManifestAsync(_repositoryName, reference, options.MediaType, stream, cancellationToken).ConfigureAwait(false);

return Response.FromValue(new UploadManifestResult(), response.GetRawResponse());
}

public virtual async Task<Response<DownloadManifestResult>> DownloadManifestAsync(string reference, DownloadManifestOptions options = default, CancellationToken cancellationToken = default)
{
options ??= new DownloadManifestOptions();

Response<ManifestWrapper> manifestWrapper = await _restClient.GetManifestAsync(_repositoryName, reference, options.MediaType.ToSerialString(), cancellationToken).ConfigureAwait(false);

manifestWrapper.GetRawResponse().Headers.TryGetValue("Docker-Content-Digest", out var digest);

Stream stream = manifestWrapper.GetRawResponse().ContentStream;
stream.Position = 0;

return Response.FromValue(new DownloadManifestResult(digest, stream), manifestWrapper.GetRawResponse());
}

public virtual async Task<Response<DownloadBlobResult>> DownloadBlobAsync(string digest, DownloadBlobOptions options = default, CancellationToken cancellationToken = default)
{
options ??= new DownloadBlobOptions();
ResponseWithHeaders<Stream, ContainerRegistryBlobGetBlobHeaders> blobResult = await _blobRestClient.GetBlobAsync(_repositoryName, digest, cancellationToken).ConfigureAwait(false);
return Response.FromValue(new DownloadBlobResult(digest, blobResult.Value), blobResult.GetRawResponse());
}
}
}
//using Azure;
//using Azure.Core;
//using Azure.Core.Pipeline;
//using System;
//using System.IO;
//using System.Threading.Tasks;
//using System.Threading;
//using Bicep.Core.Registry.Oci;
//using Bicep.Core.RegistryClient.Models;

//namespace Bicep.Core.RegistryClient
//{
// public class BicepRegistryBlobClient
// {
// private readonly Uri _endpoint;
// private readonly string _registryName;
// private readonly HttpPipeline _pipeline;
// private readonly HttpPipeline _acrAuthPipeline;
// private readonly ClientDiagnostics _clientDiagnostics;
// private readonly ContainerRegistryRestClient _restClient;
// private readonly AuthenticationRestClient _acrAuthClient;
// private readonly ContainerRegistryBlobRestClient _blobRestClient;
// private readonly string _repositoryName;

// public BicepRegistryBlobClient(Uri endpoint, TokenCredential credential, string repositoryName) : this(endpoint, credential, repositoryName, new ContainerRegistryClientOptions())
// {
// }

// public BicepRegistryBlobClient(Uri endpoint, TokenCredential credential, string repositoryName, ContainerRegistryClientOptions options)
// {
// Argument.AssertNotNull(endpoint, nameof(endpoint));
// Argument.AssertNotNull(credential, nameof(credential));
// Argument.AssertNotNull(options, nameof(options));

// _endpoint = endpoint;
// _registryName = endpoint.Host.Split('.')[0];
// _repositoryName = repositoryName;
// _clientDiagnostics = new ClientDiagnostics(options);

// _acrAuthPipeline = HttpPipelineBuilder.Build(options);
// _acrAuthClient = new AuthenticationRestClient(_clientDiagnostics, _acrAuthPipeline, endpoint.AbsoluteUri);

// _pipeline = HttpPipelineBuilder.Build(options, new ContainerRegistryChallengeAuthenticationPolicy(credential, options.AuthenticationScope, _acrAuthClient));
// _restClient = new ContainerRegistryRestClient(_clientDiagnostics, _pipeline, _endpoint.AbsoluteUri);
// _blobRestClient = new ContainerRegistryBlobRestClient(_clientDiagnostics, _pipeline, _endpoint.AbsoluteUri);
// }

// // allows mocking
// protected BicepRegistryBlobClient()
// {
// }

// public virtual async Task<Response<UploadBlobResult>> UploadBlobAsync(Stream stream, CancellationToken cancellationToken = default)
// {
// string digest = DigestHelper.ComputeDigest(DigestHelper.AlgorithmIdentifierSha256, stream);

// ResponseWithHeaders<ContainerRegistryBlobStartUploadHeaders> startUploadResult =
// await _blobRestClient.StartUploadAsync(_repositoryName, cancellationToken).ConfigureAwait(false);

// stream.Position = 0;
// ResponseWithHeaders<ContainerRegistryBlobUploadChunkHeaders> uploadChunkResult =
// await _blobRestClient.UploadChunkAsync(startUploadResult.Headers.Location, stream, cancellationToken).ConfigureAwait(false);

// ResponseWithHeaders<ContainerRegistryBlobCompleteUploadHeaders> completeUploadResult =
// await _blobRestClient.CompleteUploadAsync(digest, uploadChunkResult.Headers.Location, null, cancellationToken).ConfigureAwait(false);

// return Response.FromValue(new UploadBlobResult(), completeUploadResult.GetRawResponse());
// }

// public virtual async Task<Response<UploadManifestResult>> UploadManifestAsync(Stream stream, UploadManifestOptions options = default, CancellationToken cancellationToken = default)
// {
// options ??= new UploadManifestOptions();

// string reference = options.Tag ?? DigestHelper.ComputeDigest(DigestHelper.AlgorithmIdentifierSha256, stream);
// stream.Position = 0;
// ResponseWithHeaders<ContainerRegistryCreateManifestHeaders> response = await _restClient.CreateManifestAsync(_repositoryName, reference, options.MediaType, stream, cancellationToken).ConfigureAwait(false);

// return Response.FromValue(new UploadManifestResult(), response.GetRawResponse());
// }

// public virtual async Task<Response<DownloadManifestResult>> DownloadManifestAsync(string reference, DownloadManifestOptions options = default, CancellationToken cancellationToken = default)
// {
// options ??= new DownloadManifestOptions();

// Response<ManifestWrapper> manifestWrapper = await _restClient.GetManifestAsync(_repositoryName, reference, options.MediaType.ToSerialString(), cancellationToken).ConfigureAwait(false);

// manifestWrapper.GetRawResponse().Headers.TryGetValue("Docker-Content-Digest", out var digest);

// Stream stream = manifestWrapper.GetRawResponse().ContentStream;
// stream.Position = 0;

// return Response.FromValue(new DownloadManifestResult(digest, stream), manifestWrapper.GetRawResponse());
// }

// public virtual async Task<Response<DownloadBlobResult>> DownloadBlobAsync(string digest, DownloadBlobOptions options = default, CancellationToken cancellationToken = default)
// {
// options ??= new DownloadBlobOptions();
// ResponseWithHeaders<Stream, ContainerRegistryBlobGetBlobHeaders> blobResult = await _blobRestClient.GetBlobAsync(_repositoryName, digest, cancellationToken).ConfigureAwait(false);
// return Response.FromValue(new DownloadBlobResult(digest, blobResult.Value), blobResult.GetRawResponse());
// }
// }
//}
2 changes: 1 addition & 1 deletion src/Bicep.Core/Bicep.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Bicep.Core.RegistryClient\Bicep.Core.RegistryClient.csproj" />
<ProjectReference Include="..\..\..\azure-sdk-for-net\sdk\containerregistry\Azure.Containers.ContainerRegistry\src\Azure.Containers.ContainerRegistry.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="CoreResources.Designer.cs">
Expand Down
Loading