Example #1
0
        public BlobFeedAction(string expectedFeedUrl, string accountKey, MSBuild.TaskLoggingHelper Log)
        {
            // This blob feed action regex is custom because of the way that nuget handles query strings (it doesn't)
            // Instead of encoding the query string containing the SAS at the end of the URL we encode it at the beginning.
            // As a result, we can't parse this feed url like a traditional feed url.  When this changes, this code could be simplified and
            // BlobUriParser could be used instead.
            this.Log = Log;
            Match m = Regex.Match(expectedFeedUrl, feedRegex);

            if (m.Success)
            {
                string accountName   = m.Groups["accountname"].Value;
                string containerName = m.Groups["containername"].Value;
                string relativePath  = m.Groups["relativepath"].Value;
                feed     = new BlobFeed(accountName, accountKey, containerName, relativePath, Log);
                feedUrl  = m.Groups["feedurl"].Value;
                hasToken = !string.IsNullOrEmpty(m.Groups["token"].Value);

                source = new SleetSource
                {
                    Name             = feed.ContainerName,
                    Type             = "azure",
                    Path             = feedUrl,
                    Container        = feed.ContainerName,
                    FeedSubPath      = feed.RelativePath,
                    ConnectionString = $"DefaultEndpointsProtocol=https;AccountName={feed.AccountName};AccountKey={feed.AccountKey};EndpointSuffix=core.windows.net"
                };
            }
            else
            {
                throw new Exception("Unable to parse expected feed. Please check ExpectedFeedUrl.");
            }
        }
Example #2
0
        public BlobFeedAction(string expectedFeedUrl, string accountKey, MSBuild.TaskLoggingHelper Log)
        {
            this.Log = Log;
            Match m = Regex.Match(expectedFeedUrl, feedRegex);

            if (m.Success)
            {
                string accountName   = m.Groups["accountname"].Value;
                string containerName = m.Groups["containername"].Value;
                string relativePath  = m.Groups["relativepath"].Value;
                feed     = new BlobFeed(accountName, accountKey, containerName, relativePath, Log);
                feedUrl  = m.Groups["feedurl"].Value;
                hasToken = !string.IsNullOrEmpty(m.Groups["token"].Value);

                source = new SleetSource
                {
                    Name             = feed.ContainerName,
                    Type             = "azure",
                    Path             = feedUrl,
                    Container        = feed.ContainerName,
                    FeedSubPath      = feed.RelativePath,
                    ConnectionString = $"DefaultEndpointsProtocol=https;AccountName={feed.AccountName};AccountKey={feed.AccountKey};EndpointSuffix=core.windows.net"
                };
            }
            else
            {
                throw new Exception("Unable to parse expected feed. Please check ExpectedFeedUrl.");
            }
        }
Example #3
0
 public BlobFeedAction(SleetSource sleetSource, string accountKey, MSBuild.TaskLoggingHelper log)
 {
     ContainerName = sleetSource.Container;
     RelativePath  = sleetSource.FeedSubPath;
     AccountName   = sleetSource.AccountName;
     AccountKey    = accountKey;
     hasToken      = true;
     Log           = log;
     source        = sleetSource;
 }
        private BlobFeedAction CreateBlobFeedAction(FeedConfig feedConfig)
        {
            // Matches package feeds like
            // https://dotnet-feed-internal.azurewebsites.net/container/dotnet-core-internal/sig/dsdfasdfasdf234234s/se/2020-02-02/darc-int-dotnet-arcade-services-babababababe-08/index.json
            const string azureStorageProxyFeedPattern =
                @"(?<feedURL>https://([a-z-]+).azurewebsites.net/container/(?<container>[^/]+)/sig/\w+/se/([0-9]{4}-[0-9]{2}-[0-9]{2})/(?<baseFeedName>darc-(?<type>int|pub)-(?<repository>.+?)-(?<sha>[A-Fa-f0-9]{7,40})-?(?<subversion>\d*)/))index.json";

            // Matches package feeds like the one below. Special case for static internal proxy-backed feed
            // https://dotnet-feed-internal.azurewebsites.net/container/dotnet-core-internal/sig/dsdfasdfasdf234234s/se/2020-02-02/darc-int-dotnet-arcade-services-babababababe-08/index.json
            const string azureStorageProxyFeedStaticPattern =
                @"(?<feedURL>https://([a-z-]+).azurewebsites.net/container/(?<container>[^/]+)/sig/\w+/se/([0-9]{4}-[0-9]{2}-[0-9]{2})/(?<baseFeedName>[^/]+/))index.json";

            // Matches package feeds like
            // https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json
            const string azureStorageStaticBlobFeedPattern =
                @"https://([a-z-]+).blob.core.windows.net/[^/]+/index.json";

            var proxyBackedFeedMatch            = Regex.Match(feedConfig.TargetFeedURL, azureStorageProxyFeedPattern);
            var proxyBackedStaticFeedMatch      = Regex.Match(feedConfig.TargetFeedURL, azureStorageProxyFeedStaticPattern);
            var azureStorageStaticBlobFeedMatch = Regex.Match(feedConfig.TargetFeedURL, azureStorageStaticBlobFeedPattern);

            if (proxyBackedFeedMatch.Success || proxyBackedStaticFeedMatch.Success)
            {
                var regexMatch         = (proxyBackedFeedMatch.Success) ? proxyBackedFeedMatch : proxyBackedStaticFeedMatch;
                var containerName      = regexMatch.Groups["container"].Value;
                var baseFeedName       = regexMatch.Groups["baseFeedName"].Value;
                var feedURL            = regexMatch.Groups["feedURL"].Value;
                var storageAccountName = "dotnetfeed";

                // Initialize the feed using sleet
                SleetSource sleetSource = new SleetSource()
                {
                    Name             = baseFeedName,
                    Type             = "azure",
                    BaseUri          = feedURL,
                    AccountName      = storageAccountName,
                    Container        = containerName,
                    FeedSubPath      = baseFeedName,
                    ConnectionString = $"DefaultEndpointsProtocol=https;AccountName={storageAccountName};AccountKey={feedConfig.FeedKey};EndpointSuffix=core.windows.net"
                };

                return(new BlobFeedAction(sleetSource, feedConfig.FeedKey, Log));
            }
            else if (azureStorageStaticBlobFeedMatch.Success)
            {
                return(new BlobFeedAction(feedConfig.TargetFeedURL, feedConfig.FeedKey, Log));
            }
            else
            {
                Log.LogError($"Could not parse Azure feed URL: '{feedConfig.TargetFeedURL}'");
                return(null);
            }
        }
        private BlobFeedAction CreateBlobFeedAction(FeedConfig feedConfig)
        {
            var proxyBackedFeedMatch            = Regex.Match(feedConfig.TargetFeedURL, AzureStorageProxyFeedPattern);
            var proxyBackedStaticFeedMatch      = Regex.Match(feedConfig.TargetFeedURL, AzureStorageProxyFeedStaticPattern);
            var azureStorageStaticBlobFeedMatch = Regex.Match(feedConfig.TargetFeedURL, AzureStorageStaticBlobFeedPattern);

            if (proxyBackedFeedMatch.Success || proxyBackedStaticFeedMatch.Success)
            {
                var regexMatch         = (proxyBackedFeedMatch.Success) ? proxyBackedFeedMatch : proxyBackedStaticFeedMatch;
                var containerName      = regexMatch.Groups["container"].Value;
                var baseFeedName       = regexMatch.Groups["baseFeedName"].Value;
                var feedURL            = regexMatch.Groups["feedURL"].Value;
                var storageAccountName = "dotnetfeed";

                // Initialize the feed using sleet
                SleetSource sleetSource = new SleetSource()
                {
                    Name             = baseFeedName,
                    Type             = "azure",
                    BaseUri          = feedURL,
                    AccountName      = storageAccountName,
                    Container        = containerName,
                    FeedSubPath      = baseFeedName,
                    ConnectionString = $"DefaultEndpointsProtocol=https;AccountName={storageAccountName};AccountKey={feedConfig.FeedKey};EndpointSuffix=core.windows.net"
                };

                return(new BlobFeedAction(sleetSource, feedConfig.FeedKey, Log));
            }
            else if (azureStorageStaticBlobFeedMatch.Success)
            {
                return(new BlobFeedAction(feedConfig.TargetFeedURL, feedConfig.FeedKey, Log));
            }
            else
            {
                Log.LogError($"Could not parse Azure feed URL: '{feedConfig.TargetFeedURL}'");
                return(null);
            }
        }
        private async Task <bool> ExecuteAsync()
        {
            try
            {
                string accessId          = IsInternal ? "int" : "pub";
                string baseFeedName      = $"darc-{accessId}-{RepositoryName}-{CommitSha}";
                string versionedFeedName = baseFeedName;
                bool   needsUniqueName   = false;
                int    subVersion        = 0;
                var    containerName     = string.Empty;

                Log.LogMessage(MessageImportance.High, $"Creating a new Azure Storage internal feed ...");

                Match m = Regex.Match(AzureStorageFeedsBaseUrl, baseUrlRegex);
                if (m.Success)
                {
                    containerName = m.Groups["containername"].Value;
                }
                else
                {
                    Log.LogError($"Could not parse {nameof(AzureStorageFeedsBaseUrl)} to extract the container name: '{AzureStorageFeedsBaseUrl}'");
                    return(false);
                }

                AzureStorageUtils azUtils = new AzureStorageUtils(AzureStorageAccountName, AzureStorageAccountKey, containerName);

                // Create container if it doesn't already exist
                if (!await azUtils.CheckIfContainerExistsAsync())
                {
                    BlobContainerPermissions permissions = new BlobContainerPermissions
                    {
                        PublicAccess = IsInternal ? BlobContainerPublicAccessType.Off : BlobContainerPublicAccessType.Container
                    };

                    await azUtils.CreateContainerAsync(permissions);
                }

                // Create folder inside the container. Note that AzureStorage requires a folder
                // to have at least one file.
                do
                {
                    if (await azUtils.CheckIfBlobExistsAsync($"{versionedFeedName}/index.json"))
                    {
                        versionedFeedName = $"{baseFeedName}-{++subVersion}";
                        needsUniqueName   = true;
                    }
                    else
                    {
                        baseFeedName    = versionedFeedName;
                        needsUniqueName = false;
                    }
                } while (needsUniqueName);

                // Initialize the feed using sleet
                SleetSource sleetSource = new SleetSource()
                {
                    Name             = baseFeedName,
                    Type             = "azure",
                    BaseUri          = $"{AzureStorageFeedsBaseUrl}{baseFeedName}",
                    AccountName      = AzureStorageAccountName,
                    Container        = containerName,
                    FeedSubPath      = $"{baseFeedName}",
                    ConnectionString = $"DefaultEndpointsProtocol=https;AccountName={AzureStorageAccountName};AccountKey={AzureStorageAccountKey};EndpointSuffix=core.windows.net"
                };

                BlobFeedAction bfAction = new BlobFeedAction(sleetSource, AzureStorageAccountKey, Log);
                await bfAction.InitAsync();

                TargetFeedURL = $"{AzureStorageFeedsBaseUrl}{baseFeedName}";

                Log.LogMessage(MessageImportance.High, $"Feed '{TargetFeedURL}' created successfully!");
            }
            catch (Exception e)
            {
                Log.LogErrorFromException(e, true);
            }

            return(!Log.HasLoggedErrors);
        }