/// <summary>
        /// Process a single renewal
        /// </summary>
        /// <param name="renewal"></param>
        internal async Task ProcessRenewal(Renewal renewal, RunLevel runLevel)
        {
            var notification = _container.Resolve <NotificationService>();

            try
            {
                var result = await _renewalExecutor.Execute(renewal, runLevel);

                if (result != null)
                {
                    _renewalStore.Save(renewal, result);
                    if (result.Success)
                    {
                        notification.NotifySuccess(runLevel, renewal);
                    }
                    else
                    {
                        notification.NotifyFailure(runLevel, renewal, result.ErrorMessage);
                    }
                }
            }
            catch (Exception ex)
            {
                _exceptionHandler.HandleException(ex);
                notification.NotifyFailure(runLevel, renewal, ex.Message);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Setup a new scheduled renewal
        /// </summary>
        /// <param name="runLevel"></param>
        internal async Task SetupRenewal(RunLevel runLevel)
        {
            if (_args.Test)
            {
                runLevel |= RunLevel.Test;
            }
            if (_args.Force)
            {
                runLevel |= RunLevel.IgnoreCache;
            }
            _log.Information(LogType.All, "Running in mode: {runLevel}", runLevel);
            var tempRenewal = Renewal.Create(_args.Id, _settings.ScheduledTask.RenewalDays, _passwordGenerator);

            using var configScope = _scopeBuilder.Configuration(_container, tempRenewal, runLevel);
            // Choose target plugin
            var targetPluginOptionsFactory = configScope.Resolve <ITargetPluginOptionsFactory>();

            if (targetPluginOptionsFactory is INull)
            {
                _exceptionHandler.HandleException(message: $"No target plugin could be selected");
                return;
            }
            if (targetPluginOptionsFactory.Disabled.Item1)
            {
                _exceptionHandler.HandleException(message: $"Target plugin {targetPluginOptionsFactory.Name} is not available. {targetPluginOptionsFactory.Disabled.Item2}");
                return;
            }
            var targetPluginOptions = runLevel.HasFlag(RunLevel.Unattended) ?
                                      await targetPluginOptionsFactory.Default() :
                                      await targetPluginOptionsFactory.Aquire(_input, runLevel);

            if (targetPluginOptions == null)
            {
                _exceptionHandler.HandleException(message: $"Target plugin {targetPluginOptionsFactory.Name} aborted or failed");
                return;
            }
            tempRenewal.TargetPluginOptions = targetPluginOptions;

            // Generate Target and validation plugin choice
            Target?initialTarget = null;
            IValidationPluginOptionsFactory?validationPluginOptionsFactory = null;

            using (var targetScope = _scopeBuilder.Target(_container, tempRenewal, runLevel))
            {
                initialTarget = targetScope.Resolve <Target>();
                if (initialTarget is INull)
                {
                    _exceptionHandler.HandleException(message: $"Target plugin {targetPluginOptionsFactory.Name} was unable to generate a target");
                    return;
                }
                if (!initialTarget.IsValid(_log))
                {
                    _exceptionHandler.HandleException(message: $"Target plugin {targetPluginOptionsFactory.Name} generated an invalid target");
                    return;
                }
                _log.Information("Target generated using plugin {name}: {target}", targetPluginOptions.Name, initialTarget);

                // Choose FriendlyName
                if (!string.IsNullOrEmpty(_args.FriendlyName))
                {
                    tempRenewal.FriendlyName = _args.FriendlyName;
                }
                else if (runLevel.HasFlag(RunLevel.Advanced | RunLevel.Interactive))
                {
                    var alt = await _input.RequestString($"Suggested friendly name '{initialTarget.FriendlyName}', press <ENTER> to accept or type an alternative");

                    if (!string.IsNullOrEmpty(alt))
                    {
                        tempRenewal.FriendlyName = alt;
                    }
                }
                tempRenewal.LastFriendlyName = tempRenewal.FriendlyName ?? initialTarget.FriendlyName;

                // Choose validation plugin
                validationPluginOptionsFactory = targetScope.Resolve <IValidationPluginOptionsFactory>();
                if (validationPluginOptionsFactory is INull)
                {
                    _exceptionHandler.HandleException(message: $"No validation plugin could be selected");
                    return;
                }
            }

            // Configure validation
            try
            {
                var validationOptions = runLevel.HasFlag(RunLevel.Unattended)
                    ? await validationPluginOptionsFactory.Default(initialTarget)
                    : await validationPluginOptionsFactory.Aquire(initialTarget, _input, runLevel);

                if (validationOptions == null)
                {
                    _exceptionHandler.HandleException(message: $"Validation plugin {validationPluginOptionsFactory.Name} was unable to generate options");
                    return;
                }
                tempRenewal.ValidationPluginOptions = validationOptions;
            }
            catch (Exception ex)
            {
                _exceptionHandler.HandleException(ex, $"Validation plugin {validationPluginOptionsFactory.Name} aborted or failed");
                return;
            }

            // Choose CSR plugin
            if (initialTarget.CsrBytes == null)
            {
                var csrPluginOptionsFactory = configScope.Resolve <ICsrPluginOptionsFactory>();
                if (csrPluginOptionsFactory is INull)
                {
                    _exceptionHandler.HandleException(message: $"No CSR plugin could be selected");
                    return;
                }

                // Configure CSR
                try
                {
                    var csrOptions = runLevel.HasFlag(RunLevel.Unattended) ?
                                     await csrPluginOptionsFactory.Default() :
                                     await csrPluginOptionsFactory.Aquire(_input, runLevel);

                    if (csrOptions == null)
                    {
                        _exceptionHandler.HandleException(message: $"CSR plugin {csrPluginOptionsFactory.Name} was unable to generate options");
                        return;
                    }
                    tempRenewal.CsrPluginOptions = csrOptions;
                }
                catch (Exception ex)
                {
                    _exceptionHandler.HandleException(ex, $"CSR plugin {csrPluginOptionsFactory.Name} aborted or failed");
                    return;
                }
            }

            // Choose and configure store plugins
            var resolver = configScope.Resolve <IResolver>();
            var storePluginOptionsFactories = new List <IStorePluginOptionsFactory>();

            try
            {
                while (true)
                {
                    var storePluginOptionsFactory = await resolver.GetStorePlugin(configScope, storePluginOptionsFactories);

                    if (storePluginOptionsFactory == null)
                    {
                        _exceptionHandler.HandleException(message: $"Store could not be selected");
                        return;
                    }
                    StorePluginOptions?storeOptions;
                    try
                    {
                        storeOptions = runLevel.HasFlag(RunLevel.Unattended)
                            ? await storePluginOptionsFactory.Default()
                            : await storePluginOptionsFactory.Aquire(_input, runLevel);
                    }
                    catch (Exception ex)
                    {
                        _exceptionHandler.HandleException(ex, $"Store plugin {storePluginOptionsFactory.Name} aborted or failed");
                        return;
                    }
                    if (storeOptions == null)
                    {
                        _exceptionHandler.HandleException(message: $"Store plugin {storePluginOptionsFactory.Name} was unable to generate options");
                        return;
                    }
                    var isNull = storePluginOptionsFactory is NullStoreOptionsFactory;
                    if (!isNull || storePluginOptionsFactories.Count == 0)
                    {
                        tempRenewal.StorePluginOptions.Add(storeOptions);
                        storePluginOptionsFactories.Add(storePluginOptionsFactory);
                    }
                    if (isNull)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                _exceptionHandler.HandleException(ex, "Invalid selection of store plugins");
                return;
            }

            // Choose and configure installation plugins
            var installationPluginFactories = new List <IInstallationPluginOptionsFactory>();

            try
            {
                while (true)
                {
                    var installationPluginOptionsFactory = await resolver.GetInstallationPlugin(configScope,
                                                                                                tempRenewal.StorePluginOptions.Select(x => x.Instance),
                                                                                                installationPluginFactories);

                    if (installationPluginOptionsFactory == null)
                    {
                        _exceptionHandler.HandleException(message: $"Installation plugin could not be selected");
                        return;
                    }
                    InstallationPluginOptions installOptions;
                    try
                    {
                        installOptions = runLevel.HasFlag(RunLevel.Unattended)
                            ? await installationPluginOptionsFactory.Default(initialTarget)
                            : await installationPluginOptionsFactory.Aquire(initialTarget, _input, runLevel);
                    }
                    catch (Exception ex)
                    {
                        _exceptionHandler.HandleException(ex, $"Installation plugin {installationPluginOptionsFactory.Name} aborted or failed");
                        return;
                    }
                    if (installOptions == null)
                    {
                        _exceptionHandler.HandleException(message: $"Installation plugin {installationPluginOptionsFactory.Name} was unable to generate options");
                        return;
                    }
                    var isNull = installationPluginOptionsFactory is NullInstallationOptionsFactory;
                    if (!isNull || installationPluginFactories.Count == 0)
                    {
                        tempRenewal.InstallationPluginOptions.Add(installOptions);
                        installationPluginFactories.Add(installationPluginOptionsFactory);
                    }
                    if (isNull)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                _exceptionHandler.HandleException(ex, "Invalid selection of installation plugins");
                return;
            }

            // Try to run for the first time
            var renewal = await CreateRenewal(tempRenewal, runLevel);

retry:
            var result = await _renewalExecution.Execute(renewal, runLevel);

            if (result == null)
            {
                _exceptionHandler.HandleException(message: $"Create certificate cancelled");
            }
            else if (!result.Success)
            {
                if (runLevel.HasFlag(RunLevel.Interactive) &&
                    await _input.PromptYesNo("Create certificate failed, retry?", false))
                {
                    goto retry;
                }
                _exceptionHandler.HandleException(message: $"Create certificate failed: {result?.ErrorMessage}");
            }
            else
            {
                _renewalStore.Save(renewal, result);
            }
        }