Skip to content

Commit

Permalink
Merge pull request #136 from Lombiq/issue/OFFI-164
Browse files Browse the repository at this point in the history
OFFI-164: Adding maintenance
  • Loading branch information
barthamark authored Dec 13, 2024
2 parents 9f423d6 + 7511e79 commit 6334b44
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/Constants/FeatureNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public static class FeatureNames
public const string ChangeUserSensitiveContent = Maintenance + "." + nameof(ChangeUserSensitiveContent);
public const string DeleteOrRebuildElasticsearchIndices = Maintenance + "." + nameof(DeleteOrRebuildElasticsearchIndices);
public const string DeleteElasticsearchIndicesBeforeSetup = Maintenance + "." + nameof(DeleteElasticsearchIndicesBeforeSetup);
public const string UpdateEnabledFeatures = Maintenance + "." + nameof(UpdateEnabledFeatures);
public const string CustomMaintenance = Maintenance + "." + nameof(CustomMaintenance);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<PackageReference Include="OrchardCore.Search.Elasticsearch.Core" Version="2.1.0" />
<PackageReference Include="OrchardCore.Users.Abstractions" Version="2.1.0" />
<PackageReference Include="OrchardCore.Users.Core" Version="2.1.0" />
<PackageReference Include="OrchardCore.Features.Core" Version="2.0.0" />
<PackageReference Include="RandomNameGeneratorLibrary" Version="1.2.2" />
<!-- Only needed because RandomNameGeneratorLibrary indirectly referenced a vulnerable version. -->
<PackageReference Include="System.Net.Http" Version="4.3.4" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Lombiq.HelpfulLibraries.OrchardCore.Mvc;
using Lombiq.Hosting.Tenants.Maintenance.Constants;
using Lombiq.Hosting.Tenants.Maintenance.Services;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.Modules;

namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.UpdateEnabledFeatures;

[Feature(FeatureNames.UpdateEnabledFeatures)]
public sealed class Startup : StartupBase
{
private readonly IShellConfiguration _shellConfiguration;

public Startup(IShellConfiguration shellConfiguration) =>
_shellConfiguration = shellConfiguration;

public override void ConfigureServices(IServiceCollection services)
{
services.BindAndConfigureSection<UpdateEnabledFeaturesMaintenanceOptions>(
_shellConfiguration,
"Lombiq_Hosting_Tenants_Maintenance:UpdateEnabledFeatures");

services.AddScoped<IMaintenanceProvider, UpdateEnabledFeaturesMaintenanceProvider>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.UpdateEnabledFeatures;

public class UpdateEnabledFeaturesMaintenanceOptions
{
public bool IsEnabled { get; set; }
public string EnableFeatures { get; set; }
public string DisableFeatures { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using Lombiq.Hosting.Tenants.Maintenance.Extensions;
using Lombiq.Hosting.Tenants.Maintenance.Models;
using Lombiq.Hosting.Tenants.Maintenance.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OrchardCore.Environment.Extensions.Features;
using OrchardCore.Environment.Shell;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.UpdateEnabledFeatures;

public class UpdateEnabledFeaturesMaintenanceProvider : MaintenanceProviderBase
{
private readonly UpdateEnabledFeaturesMaintenanceOptions _options;
private readonly IShellFeaturesManager _shellFeaturesManager;
private readonly ILogger<UpdateEnabledFeaturesMaintenanceProvider> _logger;

public UpdateEnabledFeaturesMaintenanceProvider(
IOptions<UpdateEnabledFeaturesMaintenanceOptions> options,
IShellFeaturesManager shellFeaturesManager,
ILogger<UpdateEnabledFeaturesMaintenanceProvider> logger)
{
_options = options.Value;
_shellFeaturesManager = shellFeaturesManager;
_logger = logger;
}

public override Task<bool> ShouldExecuteAsync(MaintenanceTaskExecutionContext context) =>
Task.FromResult(_options.IsEnabled && !context.WasLatestExecutionSuccessful());

public override async Task ExecuteAsync(MaintenanceTaskExecutionContext context)
{
var availableFeatures = (await _shellFeaturesManager.GetAvailableFeaturesAsync()).ToList();

if (ReplaceAndSplitByCommas(_options.EnableFeatures) is { } enableFeaturesOption)
{
var enableFeatures = availableFeatures.Where(feature =>
enableFeaturesOption.Contains(feature.Id)).ToList();
await _shellFeaturesManager.EnableFeaturesAsync(enableFeatures, force: true);
await NotifyAsync(enableFeatures);
}

if (ReplaceAndSplitByCommas(_options.DisableFeatures) is { } disableFeaturesOption)
{
var disableFeatures = availableFeatures.Where(feature =>
disableFeaturesOption.Contains(feature.Id)).ToList();
await _shellFeaturesManager.DisableFeaturesAsync(disableFeatures, force: true);
await NotifyAsync(disableFeatures, enabled: false);
}
}

private ValueTask NotifyAsync(IEnumerable<IFeatureInfo> features, bool enabled = true)
{
foreach (var feature in features)
{
_logger.LogInformation("{FeatureName} was {Action} by maintenance.", feature.Name ?? feature.Id, enabled ? "enabled" : "disabled");
}

return ValueTask.CompletedTask;
}

private static string[] ReplaceAndSplitByCommas(string input) =>
input?.Replace(" ", string.Empty).SplitByCommas();
}
8 changes: 8 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/Manifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,11 @@
Category = "Maintenance",
Dependencies = []
)]

[assembly: Feature(
Id = UpdateEnabledFeatures,
Name = "Lombiq Hosting - Tenants Maintenance Update Enabled Features",
Description = "Updates the enabled features of tenants.",
Category = "Maintenance",
Dependencies = []
)]
20 changes: 20 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,23 @@ The following configuration should be used to allow the maintenance to run and f
}
}
```

### `Lombiq.Hosting.Tenants.Maintenance.UpdateEnabledFeatures`

It's a maintenance task that updates the enabled features of a tenant based on the app configuration. It is available on any tenant.

The following configuration options are available to set the enabled features:

```json
{
"OrchardCore": {
"Lombiq_Hosting_Tenants_Maintenance": {
"UpdateEnabledFeatures": {
"IsEnabled": true,
"EnableFeatures": "OrchardCore.Admin, OrchardCore.Alias, OrchardCore.AuditTrail",
"DisableFeatures": "OrchardCore.BackgroundTasks, OrchardCore.ContentFields"
}
}
}
}
```

0 comments on commit 6334b44

Please sign in to comment.