Exemplo n.º 1
0
        private async Task CopyKeysFromFileSystemToBlobStorage(BlobStorageSecretsRepository blobStorageSecretsRepository)
        {
            string migrateSentinelPath = Path.Combine(blobStorageSecretsRepository.SecretsSentinelFilePath, "migrate-sentinel.json");

            if (File.Exists(migrateSentinelPath))
            {
                // Migration is already done
                _logger?.LogTrace("Sentinel file is detected.");
                return;
            }

            try
            {
                using (var stream = new FileStream(migrateSentinelPath, FileMode.CreateNew))
                    using (var writer = new StreamWriter(stream))
                    {
                        //write file
                        _logger?.LogTrace("Sentinel file created.");
                    }
            }
            catch (IOException)
            {
                _logger?.LogTrace("Sentinel file is already created by another instance.");
                return;
            }

            string[] files = Directory.GetFiles(blobStorageSecretsRepository.SecretsSentinelFilePath.Replace("Sentinels", string.Empty));
            if (await blobStorageSecretsRepository.BlobContainer.ExistsAsync())
            {
                BlobResultSegment resultSegment = await blobStorageSecretsRepository.BlobContainer.ListBlobsSegmentedAsync(blobStorageSecretsRepository.SecretsBlobPath + "/", null);

                // Check for conflicts
                if (resultSegment.Results.ToArray().Length > 0)
                {
                    _logger?.LogTrace("Conflict detected. Secrets container is not empty.");
                    return;
                }
            }
            else
            {
                await blobStorageSecretsRepository.BlobContainer.CreateIfNotExistsAsync();
            }

            if (files.Length > 0)
            {
                List <Task> copyTasks = new List <Task>();
                foreach (string file in files)
                {
                    string         blobName       = Path.GetFileName(file);
                    CloudBlockBlob cloudBlockBlob = blobStorageSecretsRepository.BlobContainer.GetBlockBlobReference(blobStorageSecretsRepository.SecretsBlobPath + "/" + blobName);

                    string contents = File.ReadAllText(file);
                    Task   copyTask = cloudBlockBlob.UploadTextAsync(contents);
                    copyTasks.Add(copyTask);
                    _logger?.LogTrace("'{0}' was migrated.", cloudBlockBlob.StorageUri.PrimaryUri.AbsoluteUri.ToString());
                }
                await Task.WhenAll(copyTasks);
            }
            _logger?.LogTrace("Finished successfully.");
        }
        internal ISecretsRepository CreateSecretsRepository()
        {
            ISecretsRepository repository = null;

            if (TryGetSecretsRepositoryType(out Type repositoryType))
            {
                if (repositoryType == typeof(FileSystemSecretsRepository))
                {
                    repository = new FileSystemSecretsRepository(_options.CurrentValue.SecretsPath, _loggerFactory.CreateLogger <FileSystemSecretsRepository>(), _environment);
                }
                else if (repositoryType == typeof(KeyVaultSecretsRepository))
                {
                    string azureWebJobsSecretStorageKeyVaultUri          = _environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageKeyVaultUri);
                    string azureWebJobsSecretStorageKeyVaultClientId     = _environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageKeyVaultClientId);
                    string azureWebJobsSecretStorageKeyVaultClientSecret = _environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageKeyVaultClientSecret);
                    string azureWebJobsSecretStorageKeyVaultTenantId     = _environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageKeyVaultTenantId);

                    var keyVaultLogger = _loggerFactory.CreateLogger <KeyVaultSecretsRepository>();

                    return(new KeyVaultSecretsRepository(Path.Combine(_options.CurrentValue.SecretsPath, "Sentinels"), azureWebJobsSecretStorageKeyVaultUri, azureWebJobsSecretStorageKeyVaultClientId,
                                                         azureWebJobsSecretStorageKeyVaultClientSecret, azureWebJobsSecretStorageKeyVaultTenantId, keyVaultLogger, _environment));
                }
                else if (repositoryType == typeof(KubernetesSecretsRepository))
                {
                    repository = new KubernetesSecretsRepository(_environment, new SimpleKubernetesClient(_environment, _loggerFactory.CreateLogger <SimpleKubernetesClient>()));
                }
                else if (repositoryType == typeof(BlobStorageSasSecretsRepository))
                {
                    string secretStorageSas = _environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageSas);
                    string siteSlotName     = _environment.GetAzureWebsiteUniqueSlotName() ?? _hostIdProvider.GetHostIdAsync(CancellationToken.None).GetAwaiter().GetResult();
                    repository = new BlobStorageSasSecretsRepository(Path.Combine(_options.CurrentValue.SecretsPath, "Sentinels"),
                                                                     secretStorageSas,
                                                                     siteSlotName,
                                                                     _loggerFactory.CreateLogger <BlobStorageSasSecretsRepository>(),
                                                                     _environment,
                                                                     _azureBlobStorageProvider);
                }
                else if (repositoryType == typeof(BlobStorageSecretsRepository))
                {
                    string siteSlotName = _environment.GetAzureWebsiteUniqueSlotName() ?? _hostIdProvider.GetHostIdAsync(CancellationToken.None).GetAwaiter().GetResult();
                    repository = new BlobStorageSecretsRepository(Path.Combine(_options.CurrentValue.SecretsPath, "Sentinels"),
                                                                  ConnectionStringNames.Storage,
                                                                  siteSlotName,
                                                                  _loggerFactory.CreateLogger <BlobStorageSecretsRepository>(),
                                                                  _environment,
                                                                  _azureBlobStorageProvider);
                }
            }

            if (repository == null)
            {
                throw new InvalidOperationException("Secret initialization from Blob storage failed due to missing both an Azure Storage connection string and a SAS connection uri. " +
                                                    $"For Blob Storage, please provide at least one of these. If you intend to use files for secrets, add an App Setting key '{EnvironmentSettingNames.AzureWebJobsSecretStorageType}' with value '{FileStorage}'.");
            }

            _logger.LogInformation(new EventId(3, "CreatedSecretRespository"), "Resolved secret storage provider {provider}", repository.Name);

            return(repository);
        }
Exemplo n.º 3
0
        private async Task <BlobStorageSecretsRepository> BlobStorageSecretsRepositoryFactory()
        {
            BlobStorageSecretsRepository blobStorageSecretsRepository = new BlobStorageSecretsRepository(_secretSentinelDirectoryPath, _accountConnectionString, _siteSlotName);

            blobStorageSecretsRepository.SecretsChanged += BlobStorageSecretsMigrationRepository_SecretsChanged;
            try
            {
                await CopyKeysFromFileSystemToBlobStorage(blobStorageSecretsRepository);
            }
            catch (Exception ex)
            {
                _logger?.LogTrace("{0}", ex.ToString());
            }
            return(blobStorageSecretsRepository);
        }