caddy lables
This commit is contained in:
+3
-3
@@ -61,15 +61,15 @@
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="text-[10px] uppercase tracking-wider font-bold text-gray-500">Маршрутизация сети:</span>
|
||||
|
||||
<ng-container *ngIf="getContainerDomain(container.name) as domain; else noDomain">
|
||||
<ng-container *ngIf="getContainerDomain(container) as domain; else noDomain">
|
||||
<div class="flex items-center gap-2 mt-1">
|
||||
<a [href]="'https://' + domain" target="_blank" class="text-xs font-semibold text-blue-400 hover:text-blue-300 hover:underline flex items-center gap-1 font-mono">
|
||||
<mat-icon class="!w-3.5 !h-3.5 !text-sm text-blue-400 shrink-0">open_in_new</mat-icon>
|
||||
<span class="truncate max-w-[200px]">{{ domain }}</span>
|
||||
</a>
|
||||
<span class="text-[10px] text-gray-400 font-mono bg-gray-950 px-2 py-0.5 rounded border border-gray-850 shrink-0">
|
||||
порт {{ getContainerPort(container.name) }}
|
||||
</span>
|
||||
порт {{ getContainerPort(container) }}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
||||
+53
-36
@@ -264,64 +264,81 @@ export class ProjectDetailsComponent implements OnInit, OnDestroy, AfterViewChec
|
||||
* Безопасно извлекает имя сервиса (например, 'web') из имени Docker-контейнера.
|
||||
* Проверяет префиксы как по ID, так и по Name проекта.
|
||||
*/
|
||||
getServiceName(containerName: string): string | null {
|
||||
if (!containerName || !this.project) return null;
|
||||
getServiceName(container: any): string | null {
|
||||
if (!container) return null;
|
||||
|
||||
const prefixId = `jambotron-${this.project.id}-`;
|
||||
const prefixName = `jambotron-${this.project.name}-`;
|
||||
|
||||
let servicePart = '';
|
||||
|
||||
if (containerName.startsWith(prefixId)) {
|
||||
servicePart = containerName.substring(prefixId.length);
|
||||
} else if (containerName.startsWith(prefixName)) {
|
||||
servicePart = containerName.substring(prefixName.length);
|
||||
} else {
|
||||
// Резервный разбор по токенам (jambotron-проект-сервис)
|
||||
const parts = containerName.split('-');
|
||||
if (parts.length >= 3 && parts[0] === 'jambotron') {
|
||||
servicePart = parts.slice(2).join('-');
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
// 1. Идеальный путь созидания: берем стабильный ID из меток Docker
|
||||
if (container.labels && container.labels['jambotron.service.id']) {
|
||||
return container.labels['jambotron.service.id'];
|
||||
}
|
||||
|
||||
// Отрезаем индекс реплики Docker Compose (например, "-1")
|
||||
if (servicePart.endsWith('-1')) {
|
||||
servicePart = servicePart.substring(0, servicePart.length - 2);
|
||||
// 2. Если меток нет, переходим к парсингу имени контейнера
|
||||
const containerName = container.name || '';
|
||||
|
||||
// Проверяем базовый маркер нашей системы
|
||||
if (!containerName.startsWith('jambotron-')) {
|
||||
console.warn(`[Jambotron] Контейнер не принадлежит системе Jambotron: ${containerName}`);
|
||||
return null;
|
||||
}
|
||||
return servicePart;
|
||||
|
||||
// Отрезаем индекс реплики (-1, -2) и префикс "jambotron-"
|
||||
let cleanName = containerName.replace(/-\d+$/, '').replace(/^jambotron-/, '');
|
||||
|
||||
// 3. Проверяем массив известных имен сервисов из YAML
|
||||
const validServices: string[] = this.config?.serviceNames || [];
|
||||
if (validServices.length > 0) {
|
||||
const match = validServices.find((service: string) => cleanName.endsWith(service) || cleanName.includes(service));
|
||||
if (match) return match;
|
||||
}
|
||||
|
||||
// 4. Финальный пуленепробиваемый фоллбэк для старых контейнеров (вырезаем имя проекта)
|
||||
// Для "test-web" -> cleanName = "test-web" -> parts = ['test', 'web'] -> возвращает "web"
|
||||
const parts = cleanName.split('-');
|
||||
if (parts.length >= 2) {
|
||||
return parts.slice(1).join('-');
|
||||
}
|
||||
|
||||
// Только если вообще ничего не получилось извлечь — выводим реальное предупреждение
|
||||
if (!cleanName) {
|
||||
console.warn(`[Jambotron] Не удалось определить имя сервиса для: ${containerName}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return cleanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает текущий сформированный домен для вывода в UI
|
||||
*/
|
||||
getContainerDomain(containerName: string): string | null {
|
||||
const serviceName = this.getServiceName(containerName);
|
||||
if (!serviceName || !this.config?.serviceConfigs) return null;
|
||||
getContainerDomain(container: any): string | null {
|
||||
const serviceId = this.getServiceName(container);
|
||||
if (!serviceId || !this.config?.serviceConfigs) return null;
|
||||
|
||||
const serviceConfig = this.config.serviceConfigs[serviceName];
|
||||
// Ищем настройки в мапе по системному ID (например, srv-0)
|
||||
const serviceConfig = this.config.serviceConfigs[serviceId];
|
||||
return serviceConfig && serviceConfig.subdomain ? `${serviceConfig.subdomain}.jambotron.com` : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает порт сервиса из конфигурации MongoDB
|
||||
*/
|
||||
getContainerPort(containerName: string): number {
|
||||
const serviceName = this.getServiceName(containerName);
|
||||
if (!serviceName || !this.config?.serviceConfigs) return 80;
|
||||
getContainerPort(container: any): number {
|
||||
const serviceId = this.getServiceName(container);
|
||||
if (!serviceId || !this.config?.serviceConfigs) return 80;
|
||||
|
||||
const serviceConfig = this.config.serviceConfigs[serviceName];
|
||||
// Ищем настройки в мапе по системному ID (например, srv-0)
|
||||
const serviceConfig = this.config.serviceConfigs[serviceId];
|
||||
return serviceConfig && serviceConfig.port ? serviceConfig.port : 80;
|
||||
}
|
||||
|
||||
/**
|
||||
* Активация режима редактирования. Теперь полностью безопасна.
|
||||
* Активация режима редактирования.
|
||||
*/
|
||||
startEditDomain(container: any) {
|
||||
const serviceName = this.getServiceName(container.name);
|
||||
// ПЕРЕДАЕМ КОНТЕЙНЕР ЦЕЛИКОМ, а не container.name
|
||||
const serviceName = this.getServiceName(container);
|
||||
if (!serviceName) {
|
||||
console.warn(`[Jambotron] Не удалось определить имя сервиса для: ${container.name}`);
|
||||
console.warn(`[Jambotron] Не удалось определить имя сервиса для:`, container);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -338,7 +355,8 @@ export class ProjectDetailsComponent implements OnInit, OnDestroy, AfterViewChec
|
||||
* Сохранение изменённого поддомена и порта в MongoDB базы данных
|
||||
*/
|
||||
saveDomainConfig(container: any) {
|
||||
const serviceName = this.getServiceName(container.name);
|
||||
// ПЕРЕДАЕМ КОНТЕЙНЕР ЦЕЛИКОМ, а не container.name
|
||||
const serviceName = this.getServiceName(container);
|
||||
if (!serviceName || !this.project?.id || !this.config) return;
|
||||
|
||||
if (!this.config.serviceConfigs) {
|
||||
@@ -360,7 +378,6 @@ export class ProjectDetailsComponent implements OnInit, OnDestroy, AfterViewChec
|
||||
// Отправка монолитного конфига на бэкенд
|
||||
this.projectService.updateProjectConfig(this.project.id, this.config).subscribe({
|
||||
next: () => {
|
||||
// Бэкенд возвращает void (200 OK). Нам НЕ нужно затирать config!
|
||||
this.editingDomains[container.id] = false;
|
||||
console.log(`[Caddy] Маршрут для сервиса ${serviceName} успешно сохранён.`);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user