Skip to content

Commit

Permalink
Convert the BlobCollection into a ComponentResource (#1)
Browse files Browse the repository at this point in the history
* throw new NotSupportedException("The source provided is not a folder.");

* 0.1.0
  • Loading branch information
StefH committed May 3, 2020
1 parent aaec2fa commit ef5c0ea
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</PropertyGroup>

<PropertyGroup>
<VersionPrefix>0.0.2</VersionPrefix>
<VersionPrefix>0.1.0</VersionPrefix>
<Copyright>Copyright © 2020 Stef Heyenrath</Copyright>
<Authors>Stef Heyenrath</Authors>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
Expand Down
2 changes: 1 addition & 1 deletion GitHubReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
https://github.com/StefH/GitHubReleaseNotes

GitHubReleaseNotes.exe --output CHANGELOG.md --exclude-labels question invalid doc --version 0.0.2
GitHubReleaseNotes.exe --output CHANGELOG.md --exclude-labels question invalid doc --version 0.1.0
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
# Pulumi.Azure.Extensions
[![NuGet](https://buildstats.info/nuget/Pulumi.Azure.Extensions)](https://www.nuget.org/packages/Pulumi.Azure.Extensions)

# Pulumi.Azure.Constants
Additional extensions for Microsoft Azure resources with [Pulumi Azure](https://github.com/pulumi/pulumi-azure).

The following extensions are defined:

### Storage

#### BlobCollection
_Type:_ `azure-extensions:storage:BlobCollection`

When you want to publish all files from a Blazor WASM website to an Azure Storage Static Website, use the code below:

``` c#
string sourceFolder = "C:\Users\xxx\Documents\GitHub\BlazorApp\publish\wwwroot";
var blobCollection = new BlobCollection(sourceFolder, new BlobCollectionArgs
var blobCollection = new BlobCollection("static-website-files", new BlobCollectionArgs
{
// Required
Source = sourcefolder,
Type = BlobTypes.Block,
StorageAccountName = storageAccount.Name,
StorageContainerName = "$web",
AccessTier = BlobAccessTiers.Hot
});
```

There is no need to specify the ContentType for each file, this is automatically resolved using [MimeTypeMap](https://github.com/samuelneff/MimeTypeMap).
Notes:
- empty files are skipped
- there is no need to specify the ContentType for each file, this is automatically resolved using [MimeTypeMap](https://github.com/samuelneff/MimeTypeMap).
75 changes: 52 additions & 23 deletions src/Pulumi.Azure.Extensions/Storage/BlobCollection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Pulumi.Azure.Extensions.Utils;
Expand All @@ -8,6 +9,11 @@ namespace Pulumi.Azure.Extensions.Storage
{
public sealed class BlobCollectionArgs : ResourceArgs
{
/// <summary>
/// An absolute path to a folder on the local file system.
/// </summary>
public string Source { get; set; }

/// <summary>
/// The access tier of the storage blob. Possible values are `Archive`, `Cool` and `Hot`.
/// </summary>
Expand Down Expand Up @@ -40,51 +46,74 @@ public sealed class BlobCollectionArgs : ResourceArgs
public Input<string> Type { get; set; }
}

public sealed class BlobCollection
public sealed class BlobCollection : ComponentResource
{
private const string SearchPattern = "*.*";

/// <summary>
/// Upload all files and folders from a sourceFolder to a Blob Storage Account in Azure.
/// </summary>
/// <param name="sourceFolder">An absolute path to a folder on the local file system.</param>
/// <param name="args">The arguments used to populate the <see cref="Blob"/> resources.</param>
public BlobCollection(string sourceFolder, BlobCollectionArgs args)
/// <param name="name">The unique name of the resource</param>
/// <param name="args">The arguments used to populate this resource's properties</param>
/// <param name="options">A bag of options that control this resource's behavior</param>
public BlobCollection(string name, BlobCollectionArgs args, ComponentResourceOptions? options = null) :
base("azure-extensions:storage:BlobCollection", name, options)
{
if (string.IsNullOrEmpty(sourceFolder))
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(sourceFolder));
throw new ArgumentNullException(nameof(name));
}

if (args == null)
{
throw new ArgumentNullException(nameof(args));
}

int sourceFolderLength = sourceFolder.Length + 1;

var files = Directory.EnumerateFiles(sourceFolder, SearchPattern, SearchOption.AllDirectories)
.Select(path => new
{
info = new FileInfo(path),
name = path.Remove(0, sourceFolderLength).Replace(Path.PathSeparator, '/'), // Make the name Azure Storage compatible
})
.Where(file => file.info.Length > 0) // https://github.com/pulumi/pulumi-azure/issues/544
;
if (string.IsNullOrEmpty(args.Source))
{
throw new ArgumentNullException(nameof(args.Source));
}

foreach (var file in files)
foreach (var (fileInfo, blobName) in GetAllFiles(args.Source))
{
_ = new Blob(file.name, new BlobArgs
var blobArgs = new BlobArgs
{
AccessTier = args.AccessTier,
Name = file.name,
ContentType = MimeTypeMap.GetMimeType(fileInfo.Extension),
Name = blobName,
Parallelism = args.Parallelism,
Source = new FileAsset(fileInfo.FullName),
StorageAccountName = args.StorageAccountName,
StorageContainerName = args.StorageContainerName,
Type = args.Type,
Source = new FileAsset(file.info.FullName),
ContentType = MimeTypeMap.GetMimeType(file.info.Extension)
});
Type = args.Type
};

var blobOptions = new CustomResourceOptions
{
Parent = this
};

_ = new Blob(blobName, blobArgs, blobOptions);
}
}

private static IEnumerable<(FileInfo fileInfo, string blobName)> GetAllFiles(string source)
{
if (Directory.Exists(source))
{
int sourceFolderLength = source.Length + 1;

return Directory.EnumerateFiles(source, SearchPattern, SearchOption.AllDirectories)
.Select(path =>
(
new FileInfo(path),
path.Remove(0, sourceFolderLength).Replace(Path.PathSeparator, '/') // Make the blobName Azure Storage compatible
))
.Where(file => file.Item1.Length > 0) // https://github.com/pulumi/pulumi-azure/issues/544
;
}

throw new NotSupportedException("The source provided must be a folder.");
}
}
}
4 changes: 2 additions & 2 deletions src/Pulumi.Azure.Extensions/Utils/MimeTypeMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ public static string GetMimeType(string extension)
extension = Dot + extension;
}

return _mappings.Value.TryGetValue(extension, out string mime) ? mime : DefaultMimeType;
return _mappings.Value.TryGetValue(extension, out string? mime) ? mime : DefaultMimeType;
}

public static string GetExtension(string mimeType, bool throwErrorIfNotFound = true)
Expand All @@ -751,7 +751,7 @@ public static string GetExtension(string mimeType, bool throwErrorIfNotFound = t
throw new ArgumentException("Requested mime type is not valid: " + mimeType);
}

if (_mappings.Value.TryGetValue(mimeType, out string extension))
if (_mappings.Value.TryGetValue(mimeType, out string? extension))
{
return extension;
}
Expand Down

0 comments on commit ef5c0ea

Please sign in to comment.