(feature): release 3.3.1

This commit is contained in:
Maksym Sadovnychyy 2025-11-21 21:29:30 +01:00
parent 18c5f72cf2
commit 40c23c61ef
35 changed files with 242 additions and 726 deletions

369
README.md
View File

@ -1,7 +1,10 @@
# MaksIT.CertsUI - Container-based Let's Encrypt ACME client with WebUI
# MaksIT.CertsUI Modern container-native ACME client with a full WebUI experience
Powerful client to obtain and manage Let's Encrypt HTTPS certificates.
This client currently supports the HTTP-01 challenge and is designed to follow the official [Let's Encrypt requirements and guidelines](https://letsencrypt.org/docs/), implementing the ACME protocol and adhering to recommended security and operational practices.
MaksIT.CertsUI is a powerful, container-native ACMEv2 client built to simplify and automate the entire lifecycle of HTTPS certificates issued by Lets Encrypt. It is an independent, unofficial project and is not affiliated with or endorsed by Lets Encrypt or ISRG.
Designed for modern infrastructure, it combines a robust WebAPI, intuitive WebUI, and lightweight edge Agent to deliver fully automated certificate issuance, renewal, and deployment across Docker, Podman, and Kubernetes environments. MaksIT.CertsUI supports the HTTP-01 challenge and follows the official [Lets Encrypt guidelines](https://letsencrypt.org/docs/) while implementing recommended security and operational best practices.
---
If you find this project useful, please consider supporting its development:
@ -13,34 +16,30 @@ If you find this project useful, please consider supporting its development:
## Table of Contents
- [MaksIT.CertsUI - Container-based Let's Encrypt ACME client with WebUI](#maksitcertsui---container-based-lets-encrypt-acme-client-with-webui)
- [Table of Contents](#table-of-contents)
- [Versions History](#versions-history)
- [Architecture](#architecture)
- [Current Limitations](#current-limitations)
- [Architecture Scheme](#architecture-scheme)
- [Architecture Description](#architecture-description)
- [MaksIT.CertsUI Agent](#maksitcertsui-agent)
- [MaksIT.CertsUI WebUI](#maksitcertsui-webui)
- [MaksIT.CertsUI WebAPI](#maksitcertsui-webapi)
- [Flow Overview](#flow-overview)
- [HAProxy configuration](#haproxy-configuration)
- [Explanation](#explanation)
- [MaksIT.CertsUI Agent installation](#maksitcertsui-agent-installation)
- [MaksIT.CertsUI Server Installation on Linux with Podman Compose](#maksitcertsui-server-installation-on-linux-with-podman-compose)
- [Prerequisites](#prerequisites)
- [Running the Project with Podman Compose](#running-the-project-with-podman-compose)
- [MaksIT.CertsUI Server Installation on Windows with Docker Compose](#maksitcertsui-server-installation-on-windows-with-docker-compose)
- [Prerequisites](#prerequisites-1)
- [Secrets and Configuration](#secrets-and-configuration)
- [Running the Project with Docker Compose](#running-the-project-with-docker-compose)
- [MaksIT.CertsUI Server installation on Kubernetes](#maksitcertsui-server-installation-on-kubernetes)
- [1. Add MaksIT Helm Repository](#1-add-maksit-helm-repository)
- [2. Prepare Namespace, Secrets, and ConfigMap](#2-prepare-namespace-secrets-and-configmap)
- [3. Create a Minimal Custom Values File](#3-create-a-minimal-custom-values-file)
- [4. Install the Helm Chart](#4-install-the-helm-chart)
- [MaksIT.CertsUI Interface Overview](#maksitcertsui-interface-overview)
- [Contact](#contact)
- [Versions History](#versions-history)
- [Architecture](#architecture)
- [Current Limitations](#current-limitations)
- [Architecture Scheme](#architecture-scheme)
- [Architecture Description](#architecture-description)
- [MaksIT.CertsUI Agent](#maksitcertsui-agent)
- [MaksIT.CertsUI WebUI](#maksitcertsui-webui)
- [MaksIT.CertsUI WebAPI](#maksitcertsui-webapi)
- [Flow Overview](#flow-overview)
- [MaksIT.CertsUI Agent installation](https://github.com/MAKS-IT-COM/maksit-certs-ui-agent)
- [MaksIT.CertsUI Server Installation on Linux with Podman Compose](#maksitcertsui-server-installation-on-linux-with-podman-compose)
- [Prerequisites](#prerequisites)
- [Running the Project with Podman Compose](#running-the-project-with-podman-compose)
- [MaksIT.CertsUI Server Installation on Windows with Docker Compose](#maksitcertsui-server-installation-on-windows-with-docker-compose)
- [Prerequisites](#prerequisites-1)
- [Secrets and Configuration](#secrets-and-configuration)
- [Running the Project with Docker Compose](#running-the-project-with-docker-compose)
- [MaksIT.CertsUI Server installation on Kubernetes](#maksitcertsui-server-installation-on-kubernetes)
- [1. Add MaksIT Helm Repository](#1-add-maksit-helm-repository)
- [2. Prepare Namespace, Secrets, and ConfigMap](#2-prepare-namespace-secrets-and-configmap)
- [3. Create a Minimal Custom Values File](#3-create-a-minimal-custom-values-file)
- [4. Install the Helm Chart](#4-install-the-helm-chart)
- [MaksIT.CertsUI Interface Overview](#maksitcertsui-interface-overview)
- [Contact](#contact)
## Versions History
@ -51,6 +50,7 @@ If you find this project useful, please consider supporting its development:
* 11 Aug, 2024 - V3.1.0 (Release)
* 11 Sep, 2025 - V3.2.0 New WebUI with authentication
* 15 Nov, 2025 - V3.3.0 Pre release
* 22 Nov, 2025 - V3.3.1 Public release
---
@ -108,21 +108,7 @@ These limitations are intentional to keep the architecture simple and reliable f
The **MaksIT.CertsUI Agent** is a lightweight service responsible for **receiving cached certificates** from the **MaksIT.CertsUI** server and **deploying them to the local file system** used by your reverse proxy (e.g., **HAProxy** or **Nginx**). It also handles **proxy service reloads** to activate new certificates.
**Language Independence:**
A standard **C# WebAPI implementation** of the Agent is available in this repository for immediate use or customization. However, the Agent is fully independent from the MaksIT.CertsUI server and communicates via standard **HTTP APIs**. This means you can implement the Agent in **any programming language or framework** that supports HTTP endpoints (such as **C#**, **Go**, **Python**, **Rust**, **Node.js**, etc.). The only requirements are:
- Ability to **receive certificate files via HTTP**
- Ability to **write files** to the proxys certificate directory
- Ability to **reload or restart** the proxy process
**Security:**
Communication between the Agent and the **MaksIT.CertsUI** server is secured using a **shared API key**. This ensures that only authorized servers can deploy certificates and trigger proxy reloads, protecting your edge infrastructure from unauthorized access.
> **Warning:** Never commit secrets or API keys to version control. Always use strong, unique secrets and passwords.
This flexibility allows you to integrate the Agent into diverse environments and choose the best technology stack for your edge server.
Check **Agent** repository for more details and installation instructions: [MaksIT.CertsUI Agent](https://github.com/MAKS-IT-COM/maksit-certs-ui-agent.git)
#### MaksIT.CertsUI WebUI
@ -204,158 +190,6 @@ The Webapi is designed for deployment in secure environments such as Kubernetes
> **Note:** Currently, only HTTP-01 challenges and a single Kubernetes replica are supported by this solution.
---
## HAProxy configuration
```bash
sudo mkdir /etc/haproxy/certs
```
```bash
sudo nano /etc/haproxy/haproxy.cfg
```
```cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# Frontend for HTTP traffic on port 80
#---------------------------------------------------------------------
frontend http_frontend
bind *:80
acl acme_path path_beg /.well-known/acme-challenge/
# Redirect all HTTP traffic to HTTPS except ACME challenge requests
redirect scheme https if !acme_path
# Use the appropriate backend based on hostname if it's an ACME challenge request
use_backend acme_backend if acme_path
#---------------------------------------------------------------------
# Backend to handle ACME challenge requests
#---------------------------------------------------------------------
backend acme_backend
#server local_acme 172.16.0.5:8080
#---------------------------------------------------------------------
# Frontend for HTTPS traffic (port 443) with SNI and strict-sni
#---------------------------------------------------------------------
frontend https_frontend
bind *:443 ssl crt /etc/haproxy/certs strict-sni
http-request capture req.hdr(host) len 64
# Define ACLs for routing based on hostname
acl host_homepage hdr(host) -i maks-it.com
# Use appropriate backend based on SNI hostname
use_backend homepage_backend if host_homepage
default_backend homepage_backend
#---------------------------------------------------------------------
# Backend for maks-it.com
#---------------------------------------------------------------------
backend homepage_backend
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-Host %[hdr(host)]
server homepage_server 172.16.0.10:8080
```
### Explanation
* ACME Challenge Handling:
The http_frontend listens on port 80 and checks if the request path starts with /.well-known/acme-challenge/. These requests are required by Let's Encrypt for domain validation and are forwarded to the acme_backend. All other HTTP requests are redirected to HTTPS.
* HTTPS Frontend:
The https_frontend listens on port 443, uses SNI (Server Name Indication) to serve the correct certificate, and routes requests to the appropriate backend based on the hostname.
* Backends:
* acme_backend should point to your ACME challenge responder (such as your LetsEncrypt client).
* homepage_backend is an example backend for your main site, forwarding requests to your application server.
* Certificate Storage:
Place your SSL certificates in /etc/haproxy/certs. Each certificate file should contain the full certificate chain and private key.
## MaksIT.CertsUI Agent installation
Agent should be installed on same machine with your reverse proxy.
From your home directory
```bash
git clone https://github.com/MAKS-IT-COM/certs-ui.git
```
```bash
cd certs-ui/src/Agent
```
Edit `appsettings.json` configuration:
```json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Configuration": {
"ApiKey": "<your-agent-key>",
"CertsPath": "<your-certs-dir-path>"
}
}
```
**Note:**
Replace `<your-auth-secret>` with your shared API key and `<your-certs-dir-path>` with the path to your certificates directory (e.g., `/etc/haproxy/certs` as referenced in `haproxy.cfg`).
> **Warning:** Never commit secrets or API keys to version control. Always use strong, unique secrets and passwords.
If you are using a **RHEL-based** distribution, you can deploy the agent with:
```bash
sudo sh ./build_and_deploy.sh
```
This script will create the `maks-it-agent` service and open port `5000` for communication.
---
## MaksIT.CertsUI Server Installation on Linux with Podman Compose
@ -365,6 +199,11 @@ Podman Compose usage to orchestrate multiple **MaksIT.CertsUI** services on Linu
### Prerequisites
- [Podman](https://podman.io/getting-started/installation)
- sudo dnf install podman-compose -y
- Create these folders:
- `/opt/Compose/MaksIT.CertsUI/acme`
- `/opt/Compose/MaksIT.CertsUI/cache`
@ -377,7 +216,7 @@ Podman Compose usage to orchestrate multiple **MaksIT.CertsUI** services on Linu
Bash command to use:
```bash
mkdir -p /opt/Compose/MaksIT.CertsUI/acme \
sudo mkdir -p /opt/Compose/MaksIT.CertsUI/acme \
/opt/Compose/MaksIT.CertsUI/cache \
/opt/Compose/MaksIT.CertsUI/data \
/opt/Compose/MaksIT.CertsUI/tmp \
@ -391,7 +230,7 @@ Create the following files in the appropriate folders:
**1. Create the file `/opt/Compose/MaksIT.CertsUI/secrets/appsecrets.json` with this command:**
```bash
cat > /opt/Compose/MaksIT.CertsUI/secrets/appsecrets.json <<EOF
sudo tee /opt/Compose/MaksIT.CertsUI/secrets/appsecrets.json > /dev/null <<EOF
{
"Configuration": {
"Auth": {
@ -413,7 +252,7 @@ Make sure `<your-agent-key>` matches the key configured in your agent deployment
**2. Create the file `/opt/Compose/MaksIT.CertsUI/configMap/appsettings.json` with this command:**
```bash
cat > /opt/Compose/MaksIT.CertsUI/configMap/appsettings.json <<EOF
sudo tee /opt/Compose/MaksIT.CertsUI/configMap/appsettings.json <<EOF
{
"Logging": {
"LogLevel": {
@ -450,7 +289,7 @@ Replace all JWT-related placeholder values `<your-issuer>`, `<your-audience>` an
**3. Create the file `/opt/Compose/MaksIT.CertsUI/client/config.js` with this command:**
```bash
cat > /opt/Compose/MaksIT.CertsUI/configMap/appsettings.json <<EOF
sudo tee /opt/Compose/MaksIT.CertsUI/client/config.js <<EOF
window.RUNTIME_CONFIG = {
API_URL: "http://<your-server-hostname>/api"
};
@ -464,7 +303,8 @@ EOF
In the project root (`/opt/Compose/MaksIT.CertsUI`), create a new file named `docker-compose.yml` with the following content:
```yaml
```bash
sudo tee /opt/Compose/MaksIT.CertsUI/docker-compose.yml <<EOF
services:
reverse-proxy:
image: cr.maks-it.com/certs-ui/reverseproxy:latest
@ -504,11 +344,72 @@ services:
networks:
certs-ui-network:
driver: bridge
EOF
```
**Note:**
- Adjust volume paths if changed
**1. Run Podman compose in Rootfull mode (The only supported by podman-compose):**
```bash
sudo chown -R 1654:1654 /opt/Compose/MaksIT.CertsUI/{data,cache,acme}
sudo chmod -R 775 /opt/Compose/MaksIT.CertsUI/{data,cache,acme}
sudo chown -R 1654:1654 /opt/Compose/MaksIT.CertsUI/tmp
sudo chmod 1777 /opt/Compose/MaksIT.CertsUI/tmp
sudo su -
sudo bash -c 'echo "export PATH=/usr/local/bin:/usr/local/sbin:\$PATH" >> /root/.bashrc'
exit
sudo su -
podman compose -f docker-compose.yml up --build
```
**2. Run Podman compose in Rootless mode (Not supported by podman-compose on Alma10, havent tested):**
Correct UID and GID for `app` user inside container:
```bash
[root@test-podman maksym]# podman exec certs-ui-server id -u app
1654
[root@test-podman maksym]# podman exec certs-ui-server id -g app
1654
```
Then you have to find your `subuid` and `subgid` ranges:
```bash
[<youruser>@<yourdomain> ~]$ grep $(whoami) /etc/subuid
<youruser>:524288:65536
[<youruser>@<yourdomain> ~]$ grep $(whoami) /etc/subgid
<youruser>:524288:65536
```
Calculate host UID and GID that maps to container's `app
```
host_uid = subuid_start + container_uid
= 524288 + 1654
= 525942
host_gid = 525942
```
Apply correct ownership and permissions to the volumes:
```bash
sudo chown -R 525942:525942 /opt/Compose/MaksIT.CertsUI/{data,cache,acme}
sudo chmod -R 775 /opt/Compose/MaksIT.CertsUI/{data,cache,acme}
sudo chown -R 525942:525942 /opt/Compose/MaksIT.CertsUI/tmp
sudo chmod 1777 /opt/Compose/MaksIT.CertsUI/tmp
```
Then run podman compose as normal user:
```bash
podman compose -f docker-compose.yml up --build
```
@ -708,14 +609,10 @@ docker compose -f docker-compose.yml down
## MaksIT.CertsUI Server installation on Kubernetes
### 1. Add MaksIT Helm Repository
The MaksIT.CertsUI Helm chart is distributed via the MaksIT container registry using the Helm OCI (Open Container Initiative) protocol.
The MaksIT.CertsUI Helm chart is available from the MaksIT container registry. Add the MaksIT Helm repository to your Helm client:
```bash
helm repo add maksit https://cr.maks-it.com/chartrepo/charts
helm repo update
```
**What is Helm OCI?**
Helm OCI support enables you to pull and install Helm charts directly from container registries (such as Harbor, Docker Hub, or GitHub Container Registry), just like you would with Docker images. This approach is secure, versioned, and recommended for modern Kubernetes deployments.
### 2. Prepare Namespace, Secrets, and ConfigMap
@ -832,7 +729,7 @@ Replace all JWT-related placeholder values `<your-issuer>`, `<your-audience>` an
### 3. Create a Minimal Custom Values File
Below is a minimal example of a `custom-values.yaml` for most users. It disables image pull secrets by default (since the chart and images are public), sets the storage class for persistent volumes, and configures the reverse proxy service. You can further customize this file as needed for your environment.
Below is a minimal example of a `custom-values.yaml` for most users. It sets the storage class for persistent volumes, and configures the reverse proxy service. You can further customize this file as needed for your environment.
```yaml
global:
@ -845,32 +742,54 @@ components:
reverseproxy:
service:
type: LoadBalancer
enabled: true
type: ClusterIP
port: 8080
targetPort: 8080
# Remove or comment out the next two lines to let your cloud provider assign a dynamic IP
# loadBalancerIP: "172.16.0.5"
# annotations:
# lbipam.cilium.io/ips: "172.16.0.5"
externalTrafficPolicy: Local
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
```
### 4. Install the Helm Chart
Install the MaksIT.CertsUI chart using your custom values file:
Install the MaksIT.CertsUI chart using your custom values file.
**On Linux:**
```bash
helm install certs-ui maksit/certs-ui -n certs-ui -f custom-values.yaml
helm upgrade certs-ui oci://cr.maks-it.com/charts/certs-ui \
-n certs-ui \
-f custom-values.yaml \
--version 3.3.1 \
```
**On Windows PowerShell:*
```powershell
helm upgrade certs-ui oci://cr.maks-it.com/charts/certs-ui `
-n certs-ui `
-f custom-values.yaml `
--version 3.3.1 `
```
**Note:**
Chart version follows app version. To install a specific version, use the `--version` flag:
### 5. Uninstall the Helm Chart
To uninstall the MaksIT.CertsUI chart and remove all associated resources, run the following command:
**On Linux:**
```bash
helm uninstall certs-ui oci://cr.maks-it.com/charts/certs-ui \
-n certs-ui
```
**On Windows PowerShell:**
```powershell
helm uninstall certs-ui oci://cr.maks-it.com/charts/certs-ui `
-n certs-ui-test
```
---
@ -929,7 +848,3 @@ For any inquiries or contributions, feel free to reach out:
- **Email**: maksym.sadovnychyy@gmail.com
- **Author**: Maksym Sadovnychyy (MAKS-IT)
---
> **Tip:** For the latest updates, documentation, and source code, visit the [GitHub repository](https://github.com/MAKS-IT-COM/certs-ui).

View File

@ -1,31 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<None Include="../../README.md" Pack="true" PackagePath="" />
<None Include="../../LICENSE.md" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.22.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MaksIT.Models\MaksIT.Models.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="build_and_deploy.sh">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -1,37 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Agent - Backup (1)", "Agent - Backup (1).csproj", "{392E9E34-E17C-4118-9C83-52AF52A56E54}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Agent - Backup", "Agent - Backup.csproj", "{18049E33-180E-41F1-8343-5BCD4755B2A8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Agent", "Agent.csproj", "{2C1A9C83-0B26-450C-A874-0B8DBD251B0F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{392E9E34-E17C-4118-9C83-52AF52A56E54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{392E9E34-E17C-4118-9C83-52AF52A56E54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{392E9E34-E17C-4118-9C83-52AF52A56E54}.Release|Any CPU.ActiveCfg = Release|Any CPU
{392E9E34-E17C-4118-9C83-52AF52A56E54}.Release|Any CPU.Build.0 = Release|Any CPU
{18049E33-180E-41F1-8343-5BCD4755B2A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18049E33-180E-41F1-8343-5BCD4755B2A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18049E33-180E-41F1-8343-5BCD4755B2A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18049E33-180E-41F1-8343-5BCD4755B2A8}.Release|Any CPU.Build.0 = Release|Any CPU
{2C1A9C83-0B26-450C-A874-0B8DBD251B0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C1A9C83-0B26-450C-A874-0B8DBD251B0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C1A9C83-0B26-450C-A874-0B8DBD251B0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C1A9C83-0B26-450C-A874-0B8DBD251B0F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {281E7450-1EDC-4E77-B04F-C14F65273D90}
EndGlobalSection
EndGlobal

View File

@ -1,28 +0,0 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace MaksIT.Agent.AuthorizationFilters;
public class ApiKeyAuthorizationFilter : IAuthorizationFilter {
private readonly Configuration _appSettings;
public ApiKeyAuthorizationFilter(
IOptions<Configuration> appSettings
) {
_appSettings = appSettings.Value;
}
public void OnAuthorization(AuthorizationFilterContext context) {
if (!context.HttpContext.Request.Headers.TryGetValue("X-API-KEY", out var extractedApiKey)) {
context.Result = new UnauthorizedResult();
return;
}
if (!_appSettings.ApiKey.Equals(extractedApiKey)) {
context.Result = new UnauthorizedResult();
return;
}
}
}

View File

@ -1,29 +0,0 @@
namespace MaksIT.Agent {
public class Configuration {
private string? _apiKey;
public string ApiKey {
get {
var env = Environment.GetEnvironmentVariable("MAKS-IT_AGENT_API_KEY");
return env ?? _apiKey ?? string.Empty;
}
set {
_apiKey = value;
}
}
private string? _certsPath;
public string CertsPath {
get {
var env = Environment.GetEnvironmentVariable("MAKS-IT_AGENT_CERTS_PATH");
return env ?? _certsPath ?? string.Empty;
}
set {
_certsPath = value;
}
}
}
}

View File

@ -1,35 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using MaksIT.Models.Agent.Requests;
using MaksIT.Agent.AuthorizationFilters;
namespace MaksIT.Agent.Controllers;
[ApiController]
[Route("[controller]")]
[ServiceFilter(typeof(ApiKeyAuthorizationFilter))]
public class CertsController : ControllerBase {
private readonly Configuration _appSettings;
private readonly ILogger<CertsController> _logger;
public CertsController(
IOptions<Configuration> appSettings,
ILogger<CertsController> logger
) {
_logger = logger;
_appSettings = appSettings.Value;
}
[HttpPost("[action]")]
public IActionResult Upload([FromBody] CertsUploadRequest requestData) {
_logger.LogInformation("Uploading certificates");
foreach (var (fileName, fileContent) in requestData.Certs) {
System.IO.File.WriteAllText(Path.Combine(_appSettings.CertsPath, fileName), fileContent);
}
return Ok("Certificates uploaded successfully");
}
}

View File

@ -1,17 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using MaksIT.Agent.AuthorizationFilters;
namespace Agent.Controllers {
[ApiController]
[Route("[controller]")]
[ServiceFilter(typeof(ApiKeyAuthorizationFilter))]
public class HelloWorldController : ControllerBase {
[HttpGet]
public IActionResult Get() {
return Ok("Hello, World!");
}
}
}

View File

@ -1,57 +0,0 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using MaksIT.Agent.AuthorizationFilters;
using MaksIT.Models.Agent.Requests;
namespace MaksIT.Agent.Controllers;
[ApiController]
[Route("[controller]")]
[ServiceFilter(typeof(ApiKeyAuthorizationFilter))]
public class ServiceController : ControllerBase {
private readonly Configuration _appSettings;
public ServiceController(
IOptions<Configuration> appSettings
) {
_appSettings = appSettings.Value;
}
[HttpPost("[action]")]
public IActionResult Reload([FromBody] ServiceReloadRequest requestData) {
var serviceName = requestData.ServiceName;
try {
var processStartInfo = new ProcessStartInfo {
FileName = "/bin/systemctl",
Arguments = $"reload {serviceName}",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (var process = new Process { StartInfo = processStartInfo }) {
process.Start();
process.WaitForExit();
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
if (process.ExitCode != 0) {
return StatusCode(500, $"Error reloading service: {error}");
}
return Ok($"Service {serviceName} reloaded successfully: {output}");
}
}
catch (Exception ex) {
return StatusCode(500, $"Exception: {ex.Message}");
}
}
}

View File

@ -1,37 +0,0 @@
using MaksIT.Agent;
using MaksIT.Agent.AuthorizationFilters;
var builder = WebApplication.CreateBuilder(args);
// Extract configuration
var configuration = builder.Configuration;
// Configure strongly typed settings objects
var configurationSection = configuration.GetSection("Configuration");
var appSettings = configurationSection.Get<Configuration>() ?? throw new ArgumentNullException();
// Allow configurations to be available through IOptions<Configuration>
builder.Services.Configure<Configuration>(configurationSection);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<ApiKeyAuthorizationFilter>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -1,40 +0,0 @@
{
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5000"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Container (Dockerfile)": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"environmentVariables": {
"ASPNETCORE_HTTP_PORTS": "5000"
},
"publishAllPorts": true
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:7748",
"sslPort": 0
}
}
}

View File

@ -1,6 +0,0 @@
@ServiceReloader_HostAddress = http://localhost:5186
GET {{ServiceReloader_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -1,14 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Configuration": {
"ApiKey": "UGnCaElLLJClHgUeet/yr7vNvPf13b1WkDJQMfsiP6I=",
"CertsPath": "/etc/haproxy/certs"
}
}

View File

@ -1,77 +0,0 @@
#!/bin/bash
# Variables
SERVICE_NAME="maks-it-agent"
SERVICE_PORT="5000"
SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME.service"
INSTALL_DIR="/opt/$SERVICE_NAME"
DOTNET_EXEC="/usr/bin/dotnet"
EXEC_CMD="$DOTNET_EXEC $INSTALL_DIR/Agent.dll --urls \"http://*:$SERVICE_PORT\""
APPSETTINGS_FILE="appsettings.json"
NO_NEW_KEY_FLAG="--no-new-key"
# Update package index and install the Microsoft package repository
# sudo rpm -Uvh https://packages.microsoft.com/config/centos/8/packages-microsoft-prod.rpm
sudo dnf install -y dotnet-sdk-8.0
# Check if the service exists and stop it if it does
if systemctl list-units --full -all | grep -Fq "$SERVICE_NAME.service"; then
sudo systemctl stop $SERVICE_NAME.service
sudo systemctl disable $SERVICE_NAME.service
sudo rm -f $SERVICE_FILE
fi
# Clean up the old files if they exist
sudo rm -rf $INSTALL_DIR
# Create the application directory
sudo mkdir -p $INSTALL_DIR
# Update appsettings.json if --no-new-key flag is not provided
if [[ "$1" != "$NO_NEW_KEY_FLAG" ]]; then
NEW_API_KEY=$(openssl rand -base64 32)
jq --arg newApiKey "$NEW_API_KEY" '.Configuration.ApiKey = $newApiKey' $APPSETTINGS_FILE > tmp.$$.json && mv tmp.$$.json $APPSETTINGS_FILE
fi
# Build and publish the .NET application
sudo dotnet build Agent.csproj --configuration Release
sudo dotnet publish Agent.csproj -c Release -o $INSTALL_DIR
# Create the systemd service unit file
sudo bash -c "cat > $SERVICE_FILE <<EOL
[Unit]
Description=Maks-IT Agent
After=network.target
[Service]
WorkingDirectory=$INSTALL_DIR
ExecStart=$EXEC_CMD
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-servicereloader
User=root
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
EOL"
# Reload systemd to recognize the new service, enable it to start on boot, and start the service now
sudo systemctl daemon-reload
sudo systemctl enable --now $SERVICE_NAME.service
# Create the firewall service rule
echo '<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Maks-IT Agent</short>
<port protocol="tcp" port="'$SERVICE_PORT'"/>
</service>' > /etc/firewalld/services/maks-it-agent.xml
sleep 10
# Add the services to the firewall
firewall-cmd --permanent --add-service=maks-it-agent
# Reload the firewall
firewall-cmd --reload

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>MaksIT.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
@ -9,11 +9,6 @@
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<None Include="../../README.md" Pack="true" PackagePath="" />
<None Include="../../LICENSE.md" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MaksIT.Core" Version="1.5.9" />
<PackageReference Include="MaksIT.Results" Version="1.1.1" />

View File

@ -5,14 +5,16 @@ VisualStudioVersion = 17.6.33815.320
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LetsEncrypt", "LetsEncrypt\LetsEncrypt.csproj", "{7DE431E5-889C-434E-AD02-9F89D7A0ED27}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3374FDB1-C95E-4103-8E14-5BBF0BDC4E9D}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{3374FDB1-C95E-4103-8E14-5BBF0BDC4E9D}"
ProjectSection(SolutionItems) = preProject
..\LICENSE.md = ..\LICENSE.md
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MaksIT.Webapi", "MaksIT.Webapi\MaksIT.Webapi.csproj", "{B5F39E04-C2E3-49BF-82C2-9DEBAA949E3D}"
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{0233E43F-435D-4309-B20C-ECD4BFBD2E63}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Agent", "Agent\Agent.csproj", "{871BDED3-C6AE-437D-9B45-3AA3F184D002}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MaksIT.Models", "MaksIT.Models\MaksIT.Models.csproj", "{6814169B-D4D0-40B2-9FA9-89997DD44C30}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReverseProxy", "ReverseProxy\ReverseProxy.csproj", "{BE051147-7AB7-4358-9C24-5CB40FAFF4FC}"
@ -35,10 +37,6 @@ Global
{0233E43F-435D-4309-B20C-ECD4BFBD2E63}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0233E43F-435D-4309-B20C-ECD4BFBD2E63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0233E43F-435D-4309-B20C-ECD4BFBD2E63}.Release|Any CPU.Build.0 = Release|Any CPU
{871BDED3-C6AE-437D-9B45-3AA3F184D002}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{871BDED3-C6AE-437D-9B45-3AA3F184D002}.Debug|Any CPU.Build.0 = Debug|Any CPU
{871BDED3-C6AE-437D-9B45-3AA3F184D002}.Release|Any CPU.ActiveCfg = Release|Any CPU
{871BDED3-C6AE-437D-9B45-3AA3F184D002}.Release|Any CPU.Build.0 = Release|Any CPU
{6814169B-D4D0-40B2-9FA9-89997DD44C30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6814169B-D4D0-40B2-9FA9-89997DD44C30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6814169B-D4D0-40B2-9FA9-89997DD44C30}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@ -1,15 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="LetsEncryptServer\CertsFlow\Responses\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MaksIT.Core" Version="1.5.9" />
</ItemGroup>

View File

@ -2,7 +2,12 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon/favicon.svg" />
<link rel="shortcut icon" href="/favicon/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="CertsUI" />
<link rel="manifest" href="/favicon/site.webmanifest" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MaksIT.CertsUI</title>
</head>

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 286 KiB

View File

@ -0,0 +1,21 @@
{
"name": "CertsUI",
"short_name": "CertsUI",
"icons": [
{
"src": "/web-app-manifest-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/web-app-manifest-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

View File

@ -33,10 +33,12 @@ const LoginScreen: FC = () => {
const handleLogin = () => {
if (!formIsValid) return
if (formState.twoFactorCode === '') delete formState.twoFactorCode
if (formState.twoFactorRecoveryCode === '') delete formState.twoFactorRecoveryCode
const newFormState = { ...formState }
dispatch(login(formState))
if (newFormState.twoFactorCode === '') delete newFormState.twoFactorCode
if (newFormState.twoFactorRecoveryCode === '') delete newFormState.twoFactorRecoveryCode
dispatch(login(newFormState))
}
const handleSubmit = (e: KeyboardEvent<HTMLDivElement>) => {

View File

@ -1,11 +1,11 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
USER app
WORKDIR /app
EXPOSE 5000
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["MaksIT.Models/MaksIT.Models.csproj", "MaksIT.Models/"]

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
@ -11,11 +11,6 @@
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<None Include="../../README.md" Pack="true" PackagePath="" />
<None Include="../../LICENSE.md" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MaksIT.Results" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />

View File

@ -74,6 +74,24 @@ foreach ($service in $services.Keys) {
}
# --- Helm Chart Release Section ---
# Backup Chart.yaml
Copy-Item "helm/Chart.yaml" "helm/Chart.yaml.bak" -Force
# Use the same tags, but choose the first non-'latest' for Helm
$helmTag = $tags | Where-Object { $_ -ne "latest" } | Select-Object -First 1
if (-not $helmTag) { throw "No valid SemVer tag found for Helm chart release." }
Write-Output "Using Helm chart version: $helmTag"
# Update Chart.yaml version and appVersion
$content = Get-Content "helm/Chart.yaml" -Raw
$content = $content `
-replace '(?m)^\s*version:\s*.*$', "version: $helmTag" `
-replace '(?m)^\s*appVersion:\s*.*$', "appVersion: $helmTag"
Set-Content "helm/Chart.yaml" $content
# Package the Helm chart
$chartDir = "helm"
$chartPackageOutput = helm package $chartDir
@ -85,8 +103,9 @@ if (-not $chartPackage) {
throw "Helm chart packaging failed. Output: $chartPackageOutput"
}
# Push the Helm chart to the same Harbor project/repo as Docker images
$helmRepoUrl = "oci://$harborUrl/$projectName/charts"
# Push the Helm chart to Harbor
$helmRepoUrl = "oci://$harborUrl/charts"
Write-Output "Pushing Helm chart $chartPackage to $helmRepoUrl..."
helm push $chartPackage $helmRepoUrl --username $harborUsername --password $harborPassword
if ($LASTEXITCODE -ne 0) {
@ -98,8 +117,8 @@ if ($chartPackage) {
Write-Output "Cleaned up $chartPackage"
}
# Restore Chart.yaml
Move-Item "helm/Chart.yaml.bak" "helm/Chart.yaml" -Force
docker logout $harborUrl | Out-Null
Write-Output "Completed successfully."
# Logout after pushing images

View File

@ -1,11 +1,11 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["ReverseProxy/ReverseProxy.csproj", "ReverseProxy/"]

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>

View File

@ -3,28 +3,28 @@
"Routes": {
"well-known-acme-challenge-route": {
"Match": { "Path": "/.well-known/acme-challenge/{**catch-all}" },
"ClusterId": "letsencrypt-server"
"ClusterId": "certs-ui-server"
},
"swagger-route": {
"Match": { "Path": "/swagger/{**catch-all}" },
"ClusterId": "letsencrypt-server"
"ClusterId": "certs-ui-server"
},
"api-route": {
"Match": { "Path": "/api/{**catch-all}" },
"ClusterId": "letsencrypt-server"
"ClusterId": "certs-ui-server"
},
"default-route": {
"Match": { "Path": "{**catch-all}" },
"ClusterId": "letsencrypt-app"
"ClusterId": "certs-ui-client"
}
},
"Clusters": {
"letsencrypt-server": {
"certs-ui-server": {
"Destinations": {
"d1": { "Address": "http://certs-ui-server:5000/" }
}
},
"letsencrypt-app": {
"certs-ui-client": {
"Destinations": {
"d1": { "Address": "http://certs-ui-client:5173/" }
}

View File

@ -7,7 +7,7 @@
<ProjectGuid>0233e43f-435d-4309-b20c-ecd4bfbd2e63</ProjectGuid>
<DockerLaunchAction>LaunchBrowser</DockerLaunchAction>
<DockerServiceUrl>{Scheme}://localhost:{ServicePort}/swagger</DockerServiceUrl>
<DockerServiceName>letsencryptserver</DockerServiceName>
<DockerServiceName>maksit-certs-ui</DockerServiceName>
</PropertyGroup>
<ItemGroup>
<None Include="docker-compose.override.yml">

View File

@ -22,15 +22,13 @@ spec:
labels:
{{- include "certs-ui.labels" $root | nindent 8 }}
app.kubernetes.io/component: {{ $compName }}
{{- if and $comp.secretsFile $comp.secretsFile.forceUpdate }}
annotations:
rollme: "{{$roll}}"
{{- end }}
spec:
{{- include "certs-ui.imagePullSecrets" $root | nindent 6 }}
containers:
- name: {{ $compName }}
image: "{{ $comp.image.registry }}/{{ $comp.image.repository }}:{{ $comp.image.tag }}"
image: "{{ $comp.image.registry }}/{{ $comp.image.repository }}:{{ $.Chart.AppVersion }}"
imagePullPolicy: {{ default "IfNotPresent" $comp.image.pullPolicy }}
{{ $svc := default dict $comp.service }}
{{ $tgt := default 8080 $svc.targetPort }}
@ -46,15 +44,6 @@ spec:
value: {{ .value | quote }}
{{- end }}
{{- end }}
{{- if eq $compName "client" }}
- name: VITE_API_URL
value: >
{{- if eq $root.Values.components.reverseproxy.service.type "LoadBalancer" -}}
http://{{ $root.Values.components.reverseproxy.service.loadBalancerIP }}:{{ $root.Values.components.reverseproxy.service.port }}
{{- else -}}
http://{{ include "certs-ui.fullname" $root }}-reverseproxy:{{ $root.Values.components.reverseproxy.service.port }}
{{- end }}
{{- end }}
{{- $p := default dict $comp.persistence -}}
{{- $vols := default (list) $p.volumes -}}
{{- $hasVols := gt (len $vols) 0 -}}

View File

@ -1,17 +1,17 @@
global:
imagePullSecrets:
- name: cr-maksit-pull
imagePullSecrets: [] # Keep empty
# imagePullSecrets:
# - name: cr-maksit-pull
components:
server:
image:
registry: cr.maks-it.com
repository: certs-ui/server
tag: latest
pullPolicy: Always
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
value: Production
- name: ASPNETCORE_HTTP_PORTS
value: "5000"
service:
@ -57,7 +57,7 @@ components:
},
}
keep: true
forceUpdate: false
configMapFile:
key: appsettings.json
mountPath: /configMap/appsettings.json
@ -93,47 +93,43 @@ components:
}
}
keep: true
forceUpdate: false
client:
image:
registry: cr.maks-it.com
repository: certs-ui/client
tag: latest
pullPolicy: Always
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
service:
enabled: true
type: ClusterIP
port: 5173
targetPort: 5173
reverseproxy:
image:
registry: cr.maks-it.com
repository: certs-ui/reverseproxy
tag: latest
pullPolicy: Always
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
value: Production
- name: ASPNETCORE_HTTP_PORTS
value: "8080"
service:
enabled: true
type: LoadBalancer
type: ClusterIP
port: 8080
targetPort: 8080
loadBalancerIP: "172.16.0.5"
annotations:
lbipam.cilium.io/ips: "172.16.0.5"
labels:
export: "bgp"
externalTrafficPolicy: Local
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
# type: LoadBalancer
# port: 8080
# targetPort: 8080
# loadBalancerIP: "172.16.0.5"
# annotations:
# lbipam.cilium.io/ips: "172.16.0.5"
# labels:
# export: "bgp"
# externalTrafficPolicy: Local
# sessionAffinity: ClientIP
# sessionAffinityConfig:
# clientIP:
# timeoutSeconds: 10800