public ProviderActionWorkflow(RekeyingAttemptLogger logger, IEnumerable <IAuthJanitorProvider> providers)
        {
            Logger    = logger;
            Providers = providers;

            Logger.LogInformation("Created Provider Action Workflow for {0} ApplicationLifecycleProviders and {1} RekeyableObjectProviders",
                                  ApplicationLifecycleProviders.Count(),
                                  RekeyableObjectProviders.Count());

            Logger.LogInformation("The following providers will participate in this workflow: {0}",
                                  string.Join(", ", Providers.Select(p => p.GetType().Name)));
        }
Beispiel #2
0
        public async Task ExecuteRekeyingWorkflow(
            RekeyingAttemptLogger logger,
            TimeSpan validPeriod,
            IEnumerable <IAuthJanitorProvider> providers)
        {
            logger.LogInformation("########## BEGIN REKEYING WORKFLOW ##########");
            var rkoProviders = providers.OfType <IRekeyableObjectProvider>().ToList();
            var alcProviders = providers.OfType <IApplicationLifecycleProvider>().ToList();

            // NOTE: avoid costs of generating list of providers if information logging not turned on
            if (logger.IsEnabled(LogLevel.Information))
            {
                logger.LogInformation("RKO: {ProviderTypeNames}", string.Join(", ", rkoProviders.Select(p => p.GetType().Name)));
                logger.LogInformation("ALC: {ProviderTypeNames}", string.Join(", ", alcProviders.Select(p => p.GetType().Name)));
            }

            // -----

            logger.LogInformation("### Performing Provider Tests.");

            await PerformProviderActions(
                logger,
                providers,
                p => p.Test(),
                "Error running sanity test on provider '{ProviderName}'",
                "Error running one or more sanity tests!");

            logger.LogInformation("### Retrieving/generating temporary secrets.");

            var temporarySecrets = new List <RegeneratedSecret>();

            await PerformProviderActions(
                logger,
                rkoProviders,
                p => p.GetSecretToUseDuringRekeying()
                .ContinueWith(t =>
            {
                if (t.Result != null)
                {
                    temporarySecrets.Add(t.Result);
                }
            }),
                "Error getting temporary secret from provider '{ProviderName}'",
                "Error retrieving temporary secrets from one or more Rekeyable Object Providers!");

            logger.LogInformation("{SecretCount} temporary secrets were created/read to be used during operation.", temporarySecrets.Count);

            // ---

            logger.LogInformation("### Preparing {ProviderCount} Application Lifecycle Providers for rekeying...", alcProviders.Count);
            await PerformProviderActions(
                logger,
                alcProviders,
                p => p.BeforeRekeying(temporarySecrets),
                "Error preparing ALC provider '{ProviderName}'",
                "Error preparing one or more Application Lifecycle Providers for rekeying!");

            // -----

            logger.LogInformation("### Rekeying {ProviderCount} Rekeyable Object Providers...", rkoProviders.Count);
            var newSecrets = new List <RegeneratedSecret>();

            await PerformProviderActions(
                logger,
                rkoProviders,
                p => p.Rekey(validPeriod)
                .ContinueWith(t =>
            {
                if (t.Result != null)
                {
                    newSecrets.Add(t.Result);
                }
            }),
                "Error rekeying provider '{ProviderName}'",
                "Error rekeying one or more Rekeyable Object Providers!");

            logger.LogInformation("{SecretCount} secrets were regenerated.", newSecrets.Count);

            // -----

            logger.LogInformation("### Committing {SecretCount} regenerated secrets to {ProviderCount} Application Lifecycle Providers...",
                                  newSecrets.Count,
                                  alcProviders.Count);

            await PerformProviderActions(
                logger,
                alcProviders,
                p => p.CommitNewSecrets(newSecrets),
                "Error committing to provider '{ProviderName}'",
                "Error committing regenerated secrets!");

            // -----

            logger.LogInformation("### Completing post-rekey operations on Application Lifecycle Providers...");

            await PerformProviderActions(
                logger,
                alcProviders,
                p => p.AfterRekeying(),
                "Error running post-rekey operations on provider '{ProviderName}'",
                "Error running post-rekey operations on one or more Application Lifecycle Providers!");

            // -----

            logger.LogInformation("### Completing finalizing operations on Rekeyable Object Providers...");

            await PerformProviderActions(
                logger,
                rkoProviders,
                p => p.OnConsumingApplicationSwapped(),
                "Error running after-swap operations on provider '{ProviderName}'",
                "Error running after-swap operations on one or more Rekeyable Object Providers!");

            logger.LogInformation("########## END REKEYING WORKFLOW ##########");
        }
        public async Task ExecuteRekeyingWorkflow(
            RekeyingAttemptLogger logger,
            TimeSpan validPeriod,
            IEnumerable <IAuthJanitorProvider> providers)
        {
            logger.LogInformation("########## BEGIN REKEYING WORKFLOW ##########");

            // -----

            logger.LogInformation("### Performing provider tests...");

            await PerformActionsInParallel(
                logger,
                providers.OfType <ICanRunSanityTests>(),
                p => p.Test(),
                "Error running sanity test on provider '{ProviderName}'",
                "Error running one or more sanity tests!");

            // -----

            logger.LogInformation("### Retrieving/generating temporary secrets...");

            var temporarySecrets = new List <RegeneratedSecret>();

            await PerformActionsInParallel(
                logger,
                providers.OfType <ICanGenerateTemporarySecretValue>(),
                p => p.GenerateTemporarySecretValue()
                .ContinueWith(t =>
            {
                if (t.Result != null)
                {
                    temporarySecrets.Add(t.Result);
                }
            }),
                "Error getting temporary secret from provider '{ProviderName}'",
                "Error retrieving temporary secrets from one or more Rekeyable Object Providers!");

            logger.LogInformation("{SecretCount} temporary secrets were created/read to be used during operation.", temporarySecrets.Count);

            // -----

            logger.LogInformation("### Distributing temporary secrets...");

            await PerformActionsInParallelGroups(
                logger,
                providers.OfType <ICanDistributeTemporarySecretValues>()
                .GroupBy(p => p.GenerateResourceIdentifierHashCode()),
                p => p.DistributeTemporarySecretValues(temporarySecrets),
                "Error distributing secrets to ALC provider '{ProviderName}'",
                "Error distributing secrets!");

            // -----

            logger.LogInformation("### Performing commits for temporary secrets...");

            await PerformActionsInParallel(
                logger,
                providers.OfType <ICanPerformUnifiedCommitForTemporarySecretValues>()
                .GroupBy(p => p.GenerateResourceIdentifierHashCode())
                .Select(g => g.First()),
                p => p.UnifiedCommitForTemporarySecretValues(),
                "Error committing temporary secrets for ALC provider '{ProviderName}'",
                "Error committing temporary secrets!");

            // -----

            logger.LogInformation("### Rekeying objects and services...");

            var newSecrets = new List <RegeneratedSecret>();

            await PerformActionsInParallel(
                logger,
                providers.OfType <IRekeyableObjectProvider>(),
                p => p.Rekey(validPeriod)
                .ContinueWith(t =>
            {
                if (t.Result != null)
                {
                    newSecrets.Add(t.Result);
                }
            }),
                "Error rekeying provider '{ProviderName}'",
                "Error rekeying one or more Rekeyable Object Providers!");

            logger.LogInformation("{SecretCount} secrets were regenerated.", newSecrets.Count);

            // -----

            logger.LogInformation("### Distributing regenerated secrets...");

            await PerformActionsInParallelGroups(
                logger,
                providers.OfType <IApplicationLifecycleProvider>()
                .GroupBy(p => p.GenerateResourceIdentifierHashCode()),
                p => p.DistributeLongTermSecretValues(newSecrets),
                "Error committing to provider '{ProviderName}'",
                "Error committing regenerated secrets!");

            // -----

            logger.LogInformation("### Performing commits...");

            await PerformActionsInParallel(
                logger,
                providers.OfType <ICanPerformUnifiedCommit>()
                .GroupBy(p => p.GenerateResourceIdentifierHashCode())
                .Select(g => g.First()),
                p => p.UnifiedCommit(),
                "Error committing secrets for ALC provider '{ProviderName}'",
                "Error committing secrets!");

            // -----

            logger.LogInformation("### Running cleanup operations...");

            await PerformActionsInParallelGroups(
                logger,
                providers.OfType <ICanCleanup>()
                .GroupBy(p => p.GenerateResourceIdentifierHashCode()),
                p => p.Cleanup(),
                "Error cleaning up provider '{ProviderName}'",
                "Error cleaning up!");

            logger.LogInformation("########## END REKEYING WORKFLOW ##########");

            logger.IsComplete = true;
        }