Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
fe68fcc
Models, setting providers, controller for external requests (draft)
yuskithedeveloper Nov 12, 2025
57f80d3
Models, setting providers
yuskithedeveloper Nov 13, 2025
b7ac441
Comments
yuskithedeveloper Nov 13, 2025
c89cb63
Api key authorization
yuskithedeveloper Nov 13, 2025
c93b0b1
AbstractTypeFactory
yuskithedeveloper Nov 13, 2025
677b923
Compare client, models, controller (draft)
yuskithedeveloper Nov 13, 2025
b2004ea
Comparison result, models
yuskithedeveloper Nov 14, 2025
c4ad9b7
Hashed api key
yuskithedeveloper Nov 14, 2025
6f3b4a6
Settings comparison
yuskithedeveloper Nov 14, 2025
051a1e2
Api environments list
yuskithedeveloper Nov 14, 2025
ff77414
Hashed api key
yuskithedeveloper Nov 14, 2025
8ae3879
App setting sample
yuskithedeveloper Nov 14, 2025
a703a44
SettingsCompareService logic
yuskithedeveloper Nov 14, 2025
8e0c0da
environments-list blade
yuskithedeveloper Nov 17, 2025
e752d14
environments-comparison blade
yuskithedeveloper Nov 17, 2025
fb5ee38
environments-comparison blade
yuskithedeveloper Nov 17, 2025
1bef81d
environments-comparison blade (table layout)
yuskithedeveloper Nov 17, 2025
bda6b34
environments-comparison blade, error and scope styles
yuskithedeveloper Nov 17, 2025
fa27098
environments-comparison blade, changing comparison base
yuskithedeveloper Nov 17, 2025
58ed2be
environments-comparison blade, changing comparison base
yuskithedeveloper Nov 17, 2025
dae9d09
Numbers comparison fix
yuskithedeveloper Nov 17, 2025
65485f9
Refactoring (SonarQube)
yuskithedeveloper Nov 17, 2025
67868e4
Refactoring (SonarQube)
yuskithedeveloper Nov 17, 2025
c5497b8
Providers support for multiple setting scopes
yuskithedeveloper Nov 18, 2025
9ce39ec
BOPIS secret setting magic literal removed
yuskithedeveloper Nov 18, 2025
8a36f9c
Secret settings null value handling
yuskithedeveloper Nov 18, 2025
698ca73
Settings ordering
yuskithedeveloper Nov 18, 2025
66654ff
ComparableAppSettingsProvider
yuskithedeveloper Nov 18, 2025
ba3bc84
ComparableEnvironmentVariablesProvider
yuskithedeveloper Nov 18, 2025
5b076fb
hosting environment, .net and server info
yuskithedeveloper Nov 18, 2025
cf416a1
ComparableModulesProvider
yuskithedeveloper Nov 18, 2025
7cd6616
Minor UI changes
yuskithedeveloper Nov 18, 2025
8a06a42
Not found settings handling
yuskithedeveloper Nov 18, 2025
ba5a794
Object setting type values handling
yuskithedeveloper Nov 18, 2025
a164139
Showing differences only
yuskithedeveloper Nov 18, 2025
68f5637
Localizations
yuskithedeveloper Nov 18, 2025
58c151a
Minor style changes
yuskithedeveloper Nov 18, 2025
fbd8fdd
Readme (by Cursor)
yuskithedeveloper Nov 18, 2025
1e66ea3
Add screenshot to README
yuskithedeveloper Nov 18, 2025
a7199e2
Settings group empty name workaround
yuskithedeveloper Nov 19, 2025
ece7e92
Merge branch 'feat/VCST-3900-environments-compare-initial' of https:/…
yuskithedeveloper Nov 19, 2025
fc0fd2f
Refactoring
yuskithedeveloper Nov 19, 2025
8af0002
Refactoring
yuskithedeveloper Nov 19, 2025
2ee7a8e
No data label
yuskithedeveloper Nov 19, 2025
db486c8
Refactoring
yuskithedeveloper Nov 19, 2025
d18bab8
Refactoring
yuskithedeveloper Nov 19, 2025
9585d5d
Refactoring
yuskithedeveloper Nov 19, 2025
353fe96
Refactoring
yuskithedeveloper Nov 19, 2025
48a52a8
Export API
yuskithedeveloper Nov 19, 2025
666fbf4
Export blade toolbar button
yuskithedeveloper Nov 20, 2025
e1c4c1e
README.md
yuskithedeveloper Nov 20, 2025
9dde791
Empty appSettings.json section handling
yuskithedeveloper Nov 27, 2025
5944bbf
Add setup and usage guide to README
OlegoO Nov 28, 2025
6b9a82f
Refactor authentication to use Virto Commerce API key-based authentic…
OlegoO Nov 28, 2025
0430038
feat: Add ComparableStoreSettingsProvider to retrieve and compare store
OlegoO Nov 28, 2025
541de19
feat: Add configuration whitelist and refactor settings.
OlegoO Dec 3, 2025
d53a917
Refactor CSS and update environments-list.js
OlegoO Dec 3, 2025
f44dd5a
fix: Add search feature and update permissions.
OlegoO Dec 4, 2025
60f9bdf
settings and ui refactoring
OlegoO Dec 4, 2025
76008bc
Update README with new screenshots
OlegoO Dec 4, 2025
5a3c16c
Update README for environment configuration changes
OlegoO Dec 5, 2025
22ff6ae
Refactor EnvironmentResponseItem instantiation.
OlegoO Dec 5, 2025
1963c98
feat: Add environment settings view
OlegoO Dec 5, 2025
829714d
Add setting descriptions and toggle functionality.
OlegoO Dec 5, 2025
92cb34e
Update yaml settings in README.md
kutasinaelena Dec 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
247 changes: 238 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,250 @@
# Virto Commerce Environments Compare Module
# Environments Compare Module

## Overview
Virto Commerce Environments Comparison Module allows backend users to compare platform and store settings across multiple environments

## Key features
The Environments Compare Module enables backend administrators to compare platform settings, environment configurations, and system information across multiple Virto Commerce environments (development, staging, production, etc.). This module helps identify configuration discrepancies, troubleshoot environment-specific issues, and ensure consistency across deployments.

The module provides a web-based interface within the Virto Commerce platform where users can select multiple environments, compare their settings side-by-side, and view differences with visual indicators. It supports secure communication with remote environments using API key authentication and automatically masks sensitive data such as passwords and secure strings.

## Key Features

- **Multi-Environment Comparison**: Compare settings across two or more environments simultaneously, including the current environment and remote environments
- **Comprehensive Settings Coverage**:
- Platform settings (grouped by settings groups)
- Environment variables (system and process variables)
- .NET runtime information (framework version, OS description, architecture)
- Server features and hosting configuration
- **Environment Settings View**: From the environments list, click any environment to open a dedicated blade showing all of its settings in the same structured, filterable layout as the comparison view. This blade focuses on a single environment (without comparison controls), making it easy to inspect, search, and review configuration scopes and groups for one environment at a time.
- **Base Environment Comparison**: Select a base environment and compare all other environments against it to highlight differences
- **Difference Filtering**: Toggle between showing all settings or only differences to focus on what's changed
- **Search**: Quickly filter specific settings using a search bar
- **Settings Export**: Choose an environment and export its settings for future reference
- **Security Features**:
- API key-based authentication for secure communication with remote environments
- Automatic masking of secret/sensitive settings (passwords, secure strings) using SHA1 hashes
- **Visual Indicators**: Clear visual feedback showing which settings differ from the base environment and which environments have errors
- **Error Handling**: Displays connection errors and missing settings with descriptive error messages
- **External API Endpoint**: Provides a secure endpoint for remote environments to expose their settings for comparison

## Screenshots

### Admin UI
<img width="1916" height="927" alt="image" src="https://github.com/user-attachments/assets/578612e4-0a81-43c3-90db-5bbe54f9014d" />

### All Environments are Identical
<img width="946" height="686" alt="image" src="https://github.com/user-attachments/assets/94a74430-b284-40e0-b578-274f75da2304" />

### Filter
<img width="957" height="665" alt="image" src="https://github.com/user-attachments/assets/738f65e0-c3f6-411c-a8be-9f8489d14de2" />

### Connection Error
<img width="956" height="702" alt="image" src="https://github.com/user-attachments/assets/0ee45628-9f2e-43ed-8d45-2bafd38c150b" />

## Setup

### Prerequisites

Before configuring the Environments Compare module, ensure you have:

- At least two running Virto Commerce environments with the Environments Compare module installed on each
- The main environment (from which comparisons are performed) has network access to secondary environments via HTTP/HTTPS protocol
- On each secondary environment:
- Create **Environments Compare** role with **environments-compare:read** permission
- Create an account assigned to the EnvironmentsCompare role
- Create API keys for user
- Valid URLs for all secondary environments that will be compared

### Configuration

#### Main Environment Configuration

> Note: We recommend to keep ApiKey and URL in a secure storage for security reasons.

On the main environment (the environment from which you will perform comparisons), configure the list of secondary environments to compare. Add the following configuration to your `appSettings.json`:

```json
{
"EnvironmentsCompare": {
"CurrentEnvironmentName": "Production",
"ComparableEnvironments": [
{
"Name": "QA",
"Url": "https://qa.mydomaim.com",
"ApiKey": "a4a86441-cabb-4a60-af90-9c6ebe11a401"
},
{
"Name": "Development",
"Url": "https://dev.mydomaim.com",
"ApiKey": "a4a86441-cabb-4a60-af90-9c6ebe11a401"
}
]
}
}
```

For deployment configuration files (`.yml` format), use the following structure:

```yaml
EnvironmentsCompare__CurrentEnvironmentName=Production
EnvironmentsCompare__ComparableEnvironments__0__Name: QA
EnvironmentsCompare__ComparableEnvironments__0__Url: https://qa.mydomaim.com
EnvironmentsCompare__ComparableEnvironments__0__ApiKey: a4a86441-cabb-4a60-af90-9c6ebe11a401
EnvironmentsCompare__ComparableEnvironments__1__Name: Development
EnvironmentsCompare__ComparableEnvironments__1__Url: https://dev.mydomaim.com
EnvironmentsCompare__ComparableEnvironments__1__ApiKey: a4a86441-cabb-4a60-af90-9c6ebe11a401
```

**Configuration Parameters:**
- `Name`: A descriptive name for the environment (e.g., "Staging", "Production", "Development")
- `Url`: The base URL of the secondary environment (must be accessible from the main environment)
- `ApiKey`: The ApiKey authentication for user in Virto Commerce platform on the secondary environment

#### Secondary Environment Configuration

On each secondary environment that will be compared:
1. Configure role (ex. named: `Environment Compare`) with `environments-compare:read` permission
1. Create a new user with this role
1. Create API key for this user

### Configuration Whitelist

By default, the module has a whitelist of appsettings sections and keys that are compared across environments.

You can extend or narrow down which appsettings sections and keys are compared by configuring `EnvironmentsCompare:WhiteList`.
It supports `Include` and `Exclude` lists for both `SectionKeys` and `SettingKeys`.

- `SectionKeys` controls which top-level configuration sections are considered.
- `SettingKeys` controls which specific keys are treated as public (non-secret) during comparison.

Example `appsettings.json`:

```json
{
"EnvironmentsCompare": {
"WhiteList": {
"SectionKeys": {
"Include": [ "Logging", "ConnectionStrings" ],
"Exclude": [ "Notifications" ]
},
"SettingKeys": {
"Include": [ "LoginPageUI:BackgroundUrl" ],
"Exclude": [ "Assets:AzureBlobStorage:CdnUrl" ]
}
}
}
}
```

## Scenarios

### Accessing the Environments List

1. Open the main environment in your browser
2. Navigate to the Environments Compare module
3. The environments list displays:
- **Current** environment (the main environment, always available)
- All secondary environments configured in the `ComparableEnvironments` setting

### Exporting Environment Settings

You can export settings from any environment for documentation or backup purposes:

1. From the environments list, select the environment you want to export
2. Click the export action for that environment
3. The system generates a JSON file containing all settings for the selected environment

**Export Behavior:**
- **Current Environment**: Exports a comprehensive JSON file with all available settings
- **Secondary Environments**: Exports settings retrieved from the remote environment. If the connection fails, the exported file will contain an error description instead of settings

### Comparing Environments

1. From the environments list, select two or more environments to compare (including the current environment if desired)
2. Click the **"Compare"** button
3. The comparison blade opens, displaying settings side-by-side in columns

**Comparison Interface Features:**

- **Environment Status Indicators:**
- Environments that failed to connect are displayed in gray
- The current environment (if selected) is always visible and available
- Error messages are displayed for environments with connection issues

- **Base Environment Selection:**
- The leftmost environment column is used as the base for comparison by default
- To change the base environment, click the column header with the microscope icon (🔬)
- Selecting an unavailable environment as the base will result in all settings being marked as different

- **View Modes:**
- **Show Differences Only** (default): Displays only settings that differ from the base environment
- **Show All**: Toggle to view all settings, including those that match the base environment

- **Visual Indicators:**
- Settings with differences are highlighted
- Setting scopes (e.g., AppSettings, PlatformSettings, StoreSettings) have colored left borders to help identify them when scrolling
- Color coding helps distinguish between different setting groups

### Extending with a custom IComparableSettingsProvider

Use a custom provider when you need to:
- Compare additional configuration sources not covered by the built-in providers (e.g., external services, secrets vaults, tenant-specific configs).
- Add domain/module-specific settings scopes and grouping rules.
- Normalize or transform values before comparison (e.g., redact parts of secrets, map legacy keys, or compute derived values).

Providers are responsible for returning one or more `ComparableSettingScope` objects containing groups and settings ready for the comparison UI.

Minimal implementation:

```csharp
using System.Collections.Generic;
using System.Threading.Tasks;
using VirtoCommerce.EnvironmentsCompare.Core.Models;
using VirtoCommerce.EnvironmentsCompare.Core.Services;
using VirtoCommerce.Platform.Core.Common;

public class MyCustomSettingsProvider : IComparableSettingsProvider
{
public Task<IList<ComparableSettingScope>> GetComparableSettingsAsync() { var scope = AbstractTypeFactory<ComparableSettingScope>.TryCreateInstance(); scope.ScopeName = "MyCustomScope";
var group = AbstractTypeFactory<ComparableSettingGroup>.TryCreateInstance();
group.GroupName = "MyCustomGroup";
scope.SettingGroups.Add(group);

// Example settings (IsSecret = false marks it public for direct comparison)
var s1 = AbstractTypeFactory<ComparableSetting>.TryCreateInstance();
s1.Name = "MySection:MyKey";
s1.Value = "SomeValue";
s1.IsSecret = false;
group.Settings.Add(s1);

var s2 = AbstractTypeFactory<ComparableSetting>.TryCreateInstance();
s2.Name = "MySection:SecretKey";
s2.Value = "redacted"; // or hashed
s2.IsSecret = true; // will be compared as secure
group.Settings.Add(s2);

return Task.FromResult<IList<ComparableSettingScope>>(new List<ComparableSettingScope> { scope });
}
}
```

Register your provider in `Module.cs` (Web project), register the provider in DI so it participates in comparison.

```csharp
serviceCollection.AddTransient<IComparableSettingsProvider, MyCustomSettingsProvider>();
```


## References
* [Deployment](https://docs.virtocommerce.org/platform/developer-guide/Tutorials-and-How-tos/Tutorials/deploy-module-from-source-code/)
* [Installation](https://docs.virtocommerce.org/platform/user-guide/modules-installation/)
* [Home](https://virtocommerce.com)
* [Community](https://www.virtocommerce.org)
* [Download latest release](https://github.com/VirtoCommerce/vc-module-push-messages/releases)

- [Deployment](https://docs.virtocommerce.org/platform/developer-guide/Tutorials-and-How-tos/Tutorials/deploy-module-from-source-code/)
- [Installation](https://docs.virtocommerce.org/platform/user-guide/modules-installation/)
- [Home](https://virtocommerce.com)
- [Community](https://www.virtocommerce.org)
- [Download latest release](https://github.com/VirtoCommerce/vc-module-environments-compare/releases)

## License
Copyright (c) Virto Solutions LTD. All rights reserved.

Copyright (c) Virto Solutions LTD. All rights reserved.

This software is licensed under the Virto Commerce Open Software License (the "License"); you
may not use this file except in compliance with the License. You may
Expand Down
1 change: 0 additions & 1 deletion docs/media/diagram-db-model.drawio

This file was deleted.

Binary file removed docs/media/diagram-db-model.png
Binary file not shown.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparableEnvironment
{
public string Name { get; set; }

public string Url { get; set; }

public string ApiKey { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Collections.Generic;

namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparableEnvironmentSettings
{
public bool IsCurrent { get; set; }

public string EnvironmentName { get; set; }

public IList<ComparableSettingScope> SettingScopes { get; set; } = [];

public string ErrorMessage { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparableSetting
{
public string Name { get; set; }
public string Description { get; set; }

public object Value { get; set; }

public bool IsSecret { get; set; }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparableSettingGroup
{
public string GroupName { get; set; }

public IList<ComparableSetting> Settings { get; set; } = [];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;

namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparableSettingScope
{
/// <summary>
/// Scope of the settings, e.g. "Platform", "AppSettings"
/// </summary>
public string ScopeName { get; set; }

public string ProviderName { get; set; }

public string ErrorMessage { get; set; }

public IList<ComparableSettingGroup> SettingGroups { get; set; } = [];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparedEnvironment
{
public bool IsComparisonBase { get; set; }

public bool IsCurrent { get; set; }

public string EnvironmentName { get; set; }

public string ErrorMessage { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparedEnvironmentSetting
{
public string Name { get; set; }

public IList<ComparedEnvironmentSettingValue> ComparedValues { get; set; } = [];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparedEnvironmentSettingGroup
{
public string GroupName { get; set; }

public IList<ComparedEnvironmentSetting> Settings { get; set; } = [];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparedEnvironmentSettingScope
{
public string ScopeName { get; set; }

public IList<ComparedEnvironmentSettingGroup> SettingGroups { get; set; } = [];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace VirtoCommerce.EnvironmentsCompare.Core.Models;

public class ComparedEnvironmentSettingValue
{
public string EnvironmentName { get; set; }

public object Value { get; set; }

public bool? EqualsBaseValue { get; set; }

public string ErrorMessage { get; set; }
}
Loading
Loading