mirror of
https://github.com/tale/headplane.git
synced 2026-08-24 11:36:31 +00:00
feat: fix acl api logic to work correctly
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { ApiClient } from '~/server/headscale/api-client';
|
||||
import type { RuntimeApiClient } from '~/server/headscale/api/endpoints';
|
||||
|
||||
export abstract class Integration<T> {
|
||||
protected context: NonNullable<T>;
|
||||
@@ -11,6 +11,6 @@ export abstract class Integration<T> {
|
||||
}
|
||||
|
||||
abstract isAvailable(): Promise<boolean> | boolean;
|
||||
abstract onConfigChange(client: ApiClient): Promise<void> | void;
|
||||
abstract onConfigChange(client: RuntimeApiClient): Promise<void> | void;
|
||||
abstract get name(): string;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { constants, access } from 'node:fs/promises';
|
||||
import { access, constants } from 'node:fs/promises';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
import { Client } from 'undici';
|
||||
import { ApiClient } from '~/server/headscale/api-client';
|
||||
import type { RuntimeApiClient } from '~/server/headscale/api/endpoints';
|
||||
import log from '~/utils/log';
|
||||
import type { HeadplaneConfig } from '../schema';
|
||||
import { Integration } from './abstract';
|
||||
@@ -193,7 +193,7 @@ export default class DockerIntegration extends Integration<T> {
|
||||
return this.client !== undefined && this.containerId !== undefined;
|
||||
}
|
||||
|
||||
async onConfigChange(client: ApiClient) {
|
||||
async onConfigChange(client: RuntimeApiClient) {
|
||||
if (!this.client) {
|
||||
return;
|
||||
}
|
||||
@@ -233,14 +233,14 @@ export default class DockerIntegration extends Integration<T> {
|
||||
while (attempts <= this.maxAttempts) {
|
||||
try {
|
||||
log.debug('config', 'Checking Headscale status (attempt %d)', attempts);
|
||||
const status = await client.healthcheck();
|
||||
const status = await client.isHealthy();
|
||||
if (status === false) {
|
||||
throw new Error('Headscale is not running');
|
||||
}
|
||||
|
||||
log.info('config', 'Headscale is up and running');
|
||||
return;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
if (attempts < this.maxAttempts) {
|
||||
attempts++;
|
||||
await setTimeout(1000);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { readFile, readdir } from 'node:fs/promises';
|
||||
import { readdir, readFile } from 'node:fs/promises';
|
||||
import { platform } from 'node:os';
|
||||
import { join, resolve } from 'node:path';
|
||||
import { kill } from 'node:process';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
import { CoreV1Api, KubeConfig } from '@kubernetes/client-node';
|
||||
import { ApiClient } from '~/server/headscale/api-client';
|
||||
import type { RuntimeApiClient } from '~/server/headscale/api/endpoints';
|
||||
import log from '~/utils/log';
|
||||
import { HeadplaneConfig } from '../schema';
|
||||
import type { HeadplaneConfig } from '../schema';
|
||||
import { Integration } from './abstract';
|
||||
|
||||
// https://github.com/kubernetes-client/javascript/blob/055b83c6504dfd1b2a2d081efd974163c6cbb808/src/config.ts#L40
|
||||
@@ -202,7 +202,7 @@ export default class KubernetesIntegration extends Integration<T> {
|
||||
}
|
||||
}
|
||||
|
||||
async onConfigChange(client: ApiClient) {
|
||||
async onConfigChange(client: RuntimeApiClient) {
|
||||
if (!this.pid) {
|
||||
return;
|
||||
}
|
||||
@@ -220,14 +220,14 @@ export default class KubernetesIntegration extends Integration<T> {
|
||||
while (attempts <= this.maxAttempts) {
|
||||
try {
|
||||
log.debug('config', 'Checking Headscale status (attempt %d)', attempts);
|
||||
const status = await client.healthcheck();
|
||||
const status = await client.isHealthy();
|
||||
if (status === false) {
|
||||
throw new Error('Headscale is not running');
|
||||
}
|
||||
|
||||
log.info('config', 'Headscale is up and running');
|
||||
return;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
if (attempts < this.maxAttempts) {
|
||||
attempts++;
|
||||
await setTimeout(1000);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { readFile, readdir } from 'node:fs/promises';
|
||||
import { readdir, readFile } from 'node:fs/promises';
|
||||
import { platform } from 'node:os';
|
||||
import { join, resolve } from 'node:path';
|
||||
import { kill } from 'node:process';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
import { ApiClient } from '~/server/headscale/api-client';
|
||||
import type { RuntimeApiClient } from '~/server/headscale/api/endpoints';
|
||||
import log from '~/utils/log';
|
||||
import { HeadplaneConfig } from '../schema';
|
||||
import type { HeadplaneConfig } from '../schema';
|
||||
import { Integration } from './abstract';
|
||||
|
||||
type T = NonNullable<HeadplaneConfig['integration']>['proc'];
|
||||
@@ -68,30 +68,37 @@ export default class ProcIntegration extends Integration<T> {
|
||||
pids.join(', '),
|
||||
);
|
||||
|
||||
log.debug('config', 'Checking if any of them have Parent PID = 1, assuming thats the correct PID');
|
||||
const ppidRegex = /(?:PPid:\s)(\d+)(?:\n?)/;
|
||||
for (const pid of pids) {
|
||||
const pidStatusPath = join('/proc', pid.toString(), 'status');
|
||||
try {
|
||||
log.debug('config', 'Reading %s', pidStatusPath);
|
||||
const pidData = await readFile(pidStatusPath, 'utf8');
|
||||
const ppidResult = pidData.match(ppidRegex);
|
||||
log.debug(
|
||||
'config',
|
||||
'Checking if any of them have Parent PID = 1, assuming thats the correct PID',
|
||||
);
|
||||
const ppidRegex = /(?:PPid:\s)(\d+)(?:\n?)/;
|
||||
for (const pid of pids) {
|
||||
const pidStatusPath = join('/proc', pid.toString(), 'status');
|
||||
try {
|
||||
log.debug('config', 'Reading %s', pidStatusPath);
|
||||
const pidData = await readFile(pidStatusPath, 'utf8');
|
||||
const ppidResult = pidData.match(ppidRegex);
|
||||
|
||||
if (ppidResult !== null) {
|
||||
const potentialPPid = Number.parseInt(ppidResult[1], 10);
|
||||
if (potentialPPid === 1) {
|
||||
this.pid = pid;
|
||||
log.info('config', 'Found potential Headscale process with PID: %d based on Parent PID = 1', this.pid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
log.error('config', 'Failed to read %s: %s', pidStatusPath, error);
|
||||
}
|
||||
}
|
||||
if (ppidResult !== null) {
|
||||
const potentialPPid = Number.parseInt(ppidResult[1], 10);
|
||||
if (potentialPPid === 1) {
|
||||
this.pid = pid;
|
||||
log.info(
|
||||
'config',
|
||||
'Found potential Headscale process with PID: %d based on Parent PID = 1',
|
||||
this.pid,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
log.error('config', 'Failed to read %s: %s', pidStatusPath, error);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pids.length === 0) {
|
||||
log.error('config', 'Could not find Headscale process');
|
||||
@@ -107,7 +114,7 @@ export default class ProcIntegration extends Integration<T> {
|
||||
}
|
||||
}
|
||||
|
||||
async onConfigChange(client: ApiClient) {
|
||||
async onConfigChange(client: RuntimeApiClient) {
|
||||
if (!this.pid) {
|
||||
return;
|
||||
}
|
||||
@@ -125,7 +132,7 @@ export default class ProcIntegration extends Integration<T> {
|
||||
while (attempts <= this.maxAttempts) {
|
||||
try {
|
||||
log.debug('config', 'Checking Headscale status (attempt %d)', attempts);
|
||||
const status = await client.healthcheck();
|
||||
const status = await client.isHealthy();
|
||||
if (status === false) {
|
||||
log.error('config', 'Headscale is not running');
|
||||
return;
|
||||
@@ -133,7 +140,7 @@ export default class ProcIntegration extends Integration<T> {
|
||||
|
||||
log.info('config', 'Headscale is up and running');
|
||||
return;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
if (attempts < this.maxAttempts) {
|
||||
attempts++;
|
||||
await setTimeout(1000);
|
||||
|
||||
Reference in New Issue
Block a user