feat: expose external gateway settings
This commit is contained in:
@@ -41,7 +41,7 @@ export class CloudlySettingsManager {
|
|||||||
const masked: servezoneInterfaces.data.ICloudlySettingsMasked = {};
|
const masked: servezoneInterfaces.data.ICloudlySettingsMasked = {};
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(settings)) {
|
for (const [key, value] of Object.entries(settings)) {
|
||||||
if (typeof value === 'string' && value.length > 4) {
|
if (this.isSensitiveSettingKey(key) && typeof value === 'string' && value.length > 4) {
|
||||||
// Mask the token, showing only last 4 characters
|
// Mask the token, showing only last 4 characters
|
||||||
masked[key] = '****' + value.slice(-4);
|
masked[key] = '****' + value.slice(-4);
|
||||||
} else {
|
} else {
|
||||||
@@ -52,6 +52,21 @@ export class CloudlySettingsManager {
|
|||||||
return masked;
|
return masked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isSensitiveSettingKey(key: string): boolean {
|
||||||
|
const normalizedKey = key.toLowerCase();
|
||||||
|
return [
|
||||||
|
'token',
|
||||||
|
'secret',
|
||||||
|
'apikey',
|
||||||
|
'accesskey',
|
||||||
|
'applicationkey',
|
||||||
|
'consumerkey',
|
||||||
|
'keyjson',
|
||||||
|
'privatekey',
|
||||||
|
'password',
|
||||||
|
].some((sensitivePart) => normalizedKey.includes(sensitivePart));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update multiple settings at once
|
* Update multiple settings at once
|
||||||
*/
|
*/
|
||||||
@@ -65,6 +80,29 @@ export class CloudlySettingsManager {
|
|||||||
await this.settingsStore.deleteKey(key as keyof servezoneInterfaces.data.ICloudlySettings);
|
await this.settingsStore.deleteKey(key as keyof servezoneInterfaces.data.ICloudlySettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Object.keys(updates).some((key) => this.isExternalGatewaySettingKey(key))) {
|
||||||
|
this.refreshExternalGatewayConfig().catch((error) => {
|
||||||
|
console.log(`External gateway settings refresh failed: ${(error as Error).message}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private isExternalGatewaySettingKey(key: string): boolean {
|
||||||
|
return [
|
||||||
|
'dcrouterGatewayUrl',
|
||||||
|
'dcrouterGatewayApiToken',
|
||||||
|
'dcrouterWorkHosterId',
|
||||||
|
'dcrouterTargetHost',
|
||||||
|
'dcrouterTargetPort',
|
||||||
|
].includes(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async refreshExternalGatewayConfig(): Promise<void> {
|
||||||
|
await Promise.all([
|
||||||
|
this.cloudlyRef.domainManager.syncExternalGatewayDomains(),
|
||||||
|
this.cloudlyRef.coreflowManager.pushClusterConfigToConnectedCoreflows(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export class CloudlyViewSettings extends DeesElement {
|
|||||||
try {
|
try {
|
||||||
const updates: Partial<plugins.interfaces.data.ICloudlySettings> = {};
|
const updates: Partial<plugins.interfaces.data.ICloudlySettings> = {};
|
||||||
for (const [key, value] of Object.entries(formData)) {
|
for (const [key, value] of Object.entries(formData)) {
|
||||||
if (value !== undefined && value !== '****' && !value?.toString().endsWith('****')) {
|
if (value !== undefined && value !== '****' && !value?.toString().startsWith('****')) {
|
||||||
updates[key as keyof plugins.interfaces.data.ICloudlySettings] = value as string;
|
updates[key as keyof plugins.interfaces.data.ICloudlySettings] = value as string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,6 +130,20 @@ export class CloudlyViewSettings extends DeesElement {
|
|||||||
</div>
|
</div>
|
||||||
</dees-panel>
|
</dees-panel>
|
||||||
|
|
||||||
|
<dees-panel .title=${'External dcrouter Gateway'} .subtitle=${'Route WorkApps through a dcrouter edge authority'} .variant=${'outline'}>
|
||||||
|
<div class="form-grid">
|
||||||
|
<dees-input-text .key=${'dcrouterGatewayUrl'} .label=${'Gateway URL'} .value=${this.settings.dcrouterGatewayUrl || ''} .description=${'Base URL of the dcrouter OpsServer, for example https://edge.example.com'} .required=${false}></dees-input-text>
|
||||||
|
<dees-input-text .key=${'dcrouterGatewayApiToken'} .label=${'API Token'} .value=${this.settings.dcrouterGatewayApiToken || ''} .isPasswordBool=${true} .description=${'dcrouter API token with workhosters and certificates scopes'} .required=${false}></dees-input-text>
|
||||||
|
</div>
|
||||||
|
<div class="form-grid">
|
||||||
|
<dees-input-text .key=${'dcrouterWorkHosterId'} .label=${'WorkHoster ID'} .value=${this.settings.dcrouterWorkHosterId || ''} .description=${'Optional stable owner ID; defaults to the cluster ID'} .required=${false}></dees-input-text>
|
||||||
|
<dees-input-text .key=${'dcrouterTargetHost'} .label=${'Target Host'} .value=${this.settings.dcrouterTargetHost || ''} .description=${'Host or IP dcrouter forwards workload traffic to'} .required=${false}></dees-input-text>
|
||||||
|
</div>
|
||||||
|
<div class="form-grid single">
|
||||||
|
<dees-input-text .key=${'dcrouterTargetPort'} .label=${'Target Port'} .value=${this.settings.dcrouterTargetPort || '80'} .description=${'Internal HTTP port dcrouter should forward to'} .required=${false}></dees-input-text>
|
||||||
|
</div>
|
||||||
|
</dees-panel>
|
||||||
|
|
||||||
<dees-panel .title=${'Amazon Web Services'} .subtitle=${'Configure AWS credentials'} .variant=${'outline'}>
|
<dees-panel .title=${'Amazon Web Services'} .subtitle=${'Configure AWS credentials'} .variant=${'outline'}>
|
||||||
<div class="test-status">
|
<div class="test-status">
|
||||||
${this.renderProviderStatus('aws')}
|
${this.renderProviderStatus('aws')}
|
||||||
@@ -203,4 +217,3 @@ declare global {
|
|||||||
'cloudly-view-settings': CloudlyViewSettings;
|
'cloudly-view-settings': CloudlyViewSettings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user