Add enabled local routing rules and gateway version reporting
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { BUILT_IN_DIRECT_RULES, normalizeRouteRules } from '../routingRules.js';
|
||||
import { normalizeRouteRules } from '../routingRules.js';
|
||||
|
||||
const MODES = new Set(['client', 'gateway']);
|
||||
const CONNECTION_STATES = new Set(['running', 'stopped']);
|
||||
@@ -83,10 +83,7 @@ export function createStateSnapshot({
|
||||
gatewayAddress: mode === 'client' ? gatewayAuto?.gateway?.gateway || null : null,
|
||||
lastVerifiedAt: null,
|
||||
reason: mode === 'client' && stored.gatewayAutoEnabled !== false ? 'auto' : 'manual',
|
||||
localRules: {
|
||||
builtIn: BUILT_IN_DIRECT_RULES.map((rule) => ({ ...rule })),
|
||||
custom: stored.routeRules,
|
||||
},
|
||||
localRules: stored.routeRules,
|
||||
},
|
||||
operation: {
|
||||
kind: nullableText(operation.kind),
|
||||
@@ -147,7 +144,8 @@ export function assertStateSnapshot(snapshot) {
|
||||
rule &&
|
||||
['domain', 'domain_suffix', 'domain_keyword'].includes(rule.type) &&
|
||||
typeof rule.value === 'string' &&
|
||||
Boolean(rule.value)
|
||||
Boolean(rule.value) &&
|
||||
typeof rule.enabled === 'boolean'
|
||||
);
|
||||
|
||||
if (
|
||||
@@ -177,11 +175,8 @@ export function assertStateSnapshot(snapshot) {
|
||||
!nullableString(snapshot.route.gatewayAddress) ||
|
||||
!nullableDate(snapshot.route.lastVerifiedAt) ||
|
||||
typeof snapshot.route.reason !== 'string' ||
|
||||
!snapshot.route.localRules ||
|
||||
!Array.isArray(snapshot.route.localRules.builtIn) ||
|
||||
!snapshot.route.localRules.builtIn.every(validRouteRule) ||
|
||||
!Array.isArray(snapshot.route.localRules.custom) ||
|
||||
!snapshot.route.localRules.custom.every(validRouteRule) ||
|
||||
!Array.isArray(snapshot.route.localRules) ||
|
||||
!snapshot.route.localRules.every(validRouteRule) ||
|
||||
!snapshot.operation ||
|
||||
!nullableString(snapshot.operation.kind) ||
|
||||
!OPERATION_STATES.has(snapshot.operation.status) ||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
export const BUILT_IN_DIRECT_RULES = Object.freeze([
|
||||
Object.freeze({ type: 'domain_suffix', value: 'ru' }),
|
||||
export const INITIAL_ROUTE_RULES = Object.freeze([
|
||||
Object.freeze({ type: 'domain_suffix', value: 'ru', enabled: true }),
|
||||
]);
|
||||
|
||||
const RULE_TYPES = new Set(['domain', 'domain_suffix', 'domain_keyword']);
|
||||
const MAX_RULES = 200;
|
||||
export const MAX_ROUTE_RULES = 200;
|
||||
|
||||
function hostname(value) {
|
||||
const input = String(value || '').trim().replace(/^\*\./, '').replace(/^\./, '');
|
||||
@@ -17,13 +17,16 @@ function hostname(value) {
|
||||
function normalizeRule(rule) {
|
||||
const type = String(rule?.type || '').trim();
|
||||
if (!RULE_TYPES.has(type)) throw new TypeError('Invalid domain rule type');
|
||||
if (Object.hasOwn(rule || {}, 'enabled') && typeof rule.enabled !== 'boolean') {
|
||||
throw new TypeError('Invalid domain rule enabled state');
|
||||
}
|
||||
const value = type === 'domain_keyword'
|
||||
? String(rule?.value || '').trim().toLowerCase()
|
||||
: hostname(rule?.value);
|
||||
if (!value || value.length > 253 || /[\s/:?#]/.test(value)) {
|
||||
throw new TypeError('Invalid domain rule value');
|
||||
}
|
||||
return { type, value };
|
||||
return { type, value, enabled: rule?.enabled !== false };
|
||||
}
|
||||
|
||||
export function normalizeRouteRules(value, { strict = false } = {}) {
|
||||
@@ -31,13 +34,13 @@ export function normalizeRouteRules(value, { strict = false } = {}) {
|
||||
if (strict) throw new TypeError('Route rules must be an array');
|
||||
return [];
|
||||
}
|
||||
if (strict && value.length > MAX_RULES) throw new TypeError(`Route rules limit is ${MAX_RULES}`);
|
||||
if (strict && value.length > MAX_ROUTE_RULES) {
|
||||
throw new TypeError(`Route rules limit is ${MAX_ROUTE_RULES}`);
|
||||
}
|
||||
|
||||
const seen = new Set(BUILT_IN_DIRECT_RULES.map(({ type, value: builtInValue }) => (
|
||||
`${type}:${builtInValue}`
|
||||
)));
|
||||
const seen = new Set();
|
||||
const normalized = [];
|
||||
for (const candidate of value.slice(0, MAX_RULES)) {
|
||||
for (const candidate of value.slice(0, MAX_ROUTE_RULES)) {
|
||||
try {
|
||||
const rule = normalizeRule(candidate);
|
||||
const key = `${rule.type}:${rule.value}`;
|
||||
@@ -50,3 +53,9 @@ export function normalizeRouteRules(value, { strict = false } = {}) {
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function canAppendRouteRule(rules) {
|
||||
return Array.isArray(rules) &&
|
||||
rules.length < MAX_ROUTE_RULES &&
|
||||
rules.every((rule) => String(rule?.value || '').trim());
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export const HARBOR_VERSIONS = Object.freeze({
|
||||
macClient: '0.3.0',
|
||||
gatewayClient: '0.3.0',
|
||||
gatewayBackend: '0.3.0',
|
||||
macClient: '0.4.0',
|
||||
gatewayClient: '0.4.0',
|
||||
gatewayBackend: '0.4.0',
|
||||
});
|
||||
|
||||
export function parseVersion(value) {
|
||||
|
||||
Reference in New Issue
Block a user