@zincapp/zn-vault-agent 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +701 -0
- package/deploy/logrotate.d/zn-vault-agent +14 -0
- package/deploy/systemd/zn-vault-agent.service +75 -0
- package/dist/commands/certs.d.ts +3 -0
- package/dist/commands/certs.d.ts.map +1 -0
- package/dist/commands/certs.js +369 -0
- package/dist/commands/certs.js.map +1 -0
- package/dist/commands/exec.d.ts +3 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +193 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +234 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/secrets.d.ts +3 -0
- package/dist/commands/secrets.d.ts.map +1 -0
- package/dist/commands/secrets.js +445 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/setup.d.ts +9 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +346 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/start.d.ts +3 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +113 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +85 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +3 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +126 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +104 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +338 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/config.d.ts +164 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +299 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/deployer.d.ts +22 -0
- package/dist/lib/deployer.d.ts.map +1 -0
- package/dist/lib/deployer.js +407 -0
- package/dist/lib/deployer.js.map +1 -0
- package/dist/lib/health.d.ts +68 -0
- package/dist/lib/health.d.ts.map +1 -0
- package/dist/lib/health.js +216 -0
- package/dist/lib/health.js.map +1 -0
- package/dist/lib/logger.d.ts +38 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +161 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/metrics.d.ts +50 -0
- package/dist/lib/metrics.d.ts.map +1 -0
- package/dist/lib/metrics.js +273 -0
- package/dist/lib/metrics.js.map +1 -0
- package/dist/lib/secret-deployer.d.ts +22 -0
- package/dist/lib/secret-deployer.d.ts.map +1 -0
- package/dist/lib/secret-deployer.js +201 -0
- package/dist/lib/secret-deployer.js.map +1 -0
- package/dist/lib/validation.d.ts +25 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/dist/lib/validation.js +257 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib/websocket.d.ts +74 -0
- package/dist/lib/websocket.d.ts.map +1 -0
- package/dist/lib/websocket.js +441 -0
- package/dist/lib/websocket.js.map +1 -0
- package/dist/services/api-key-renewal.d.ts +13 -0
- package/dist/services/api-key-renewal.d.ts.map +1 -0
- package/dist/services/api-key-renewal.js +204 -0
- package/dist/services/api-key-renewal.js.map +1 -0
- package/dist/services/npm-auto-update.d.ts +60 -0
- package/dist/services/npm-auto-update.d.ts.map +1 -0
- package/dist/services/npm-auto-update.js +245 -0
- package/dist/services/npm-auto-update.js.map +1 -0
- package/dist/types/update.d.ts +19 -0
- package/dist/types/update.d.ts.map +1 -0
- package/dist/types/update.js +7 -0
- package/dist/types/update.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// Path: src/services/api-key-renewal.ts
|
|
2
|
+
// Automatic API key renewal before expiry
|
|
3
|
+
import https from 'node:https';
|
|
4
|
+
import http from 'node:http';
|
|
5
|
+
import { loadConfig, updateApiKey } from '../lib/config.js';
|
|
6
|
+
import { createLogger } from '../lib/logger.js';
|
|
7
|
+
const log = createLogger({ module: 'api-key-renewal' });
|
|
8
|
+
// Renewal threshold (days before expiry to renew)
|
|
9
|
+
const RENEWAL_THRESHOLD_DAYS = 30;
|
|
10
|
+
// Check interval (once per day)
|
|
11
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
12
|
+
let checkTimer = null;
|
|
13
|
+
let isRunning = false;
|
|
14
|
+
/**
|
|
15
|
+
* Make HTTP request with proper TLS handling
|
|
16
|
+
*/
|
|
17
|
+
function makeRequest(method, path, body) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
const config = loadConfig();
|
|
20
|
+
if (!config.vaultUrl) {
|
|
21
|
+
reject(new Error('Vault URL not configured'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (!config.auth.apiKey) {
|
|
25
|
+
reject(new Error('No API key configured'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const url = new URL(config.vaultUrl);
|
|
29
|
+
const urlPath = new URL(path, config.vaultUrl);
|
|
30
|
+
if (config.tenantId) {
|
|
31
|
+
urlPath.searchParams.set('tenantId', config.tenantId);
|
|
32
|
+
}
|
|
33
|
+
const isHttps = url.protocol === 'https:';
|
|
34
|
+
const protocol = isHttps ? https : http;
|
|
35
|
+
const requestOptions = {
|
|
36
|
+
hostname: url.hostname,
|
|
37
|
+
port: url.port || (isHttps ? 443 : 80),
|
|
38
|
+
path: urlPath.pathname + urlPath.search,
|
|
39
|
+
method,
|
|
40
|
+
headers: {
|
|
41
|
+
'X-API-Key': config.auth.apiKey,
|
|
42
|
+
'Content-Type': 'application/json',
|
|
43
|
+
'Accept': 'application/json',
|
|
44
|
+
},
|
|
45
|
+
timeout: 30000,
|
|
46
|
+
rejectUnauthorized: !config.insecure,
|
|
47
|
+
};
|
|
48
|
+
const req = protocol.request(requestOptions, (res) => {
|
|
49
|
+
let data = '';
|
|
50
|
+
res.on('data', (chunk) => (data += chunk));
|
|
51
|
+
res.on('end', () => {
|
|
52
|
+
try {
|
|
53
|
+
if (res.statusCode && res.statusCode >= 400) {
|
|
54
|
+
const error = data ? JSON.parse(data) : { message: res.statusMessage };
|
|
55
|
+
reject(new Error(error.message || `Request failed: ${res.statusCode}`));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const parsed = data ? JSON.parse(data) : {};
|
|
59
|
+
resolve(parsed);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
reject(new Error(`Failed to parse response: ${err}`));
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
req.on('error', reject);
|
|
67
|
+
req.on('timeout', () => {
|
|
68
|
+
req.destroy();
|
|
69
|
+
reject(new Error('Request timeout'));
|
|
70
|
+
});
|
|
71
|
+
if (body) {
|
|
72
|
+
req.write(JSON.stringify(body));
|
|
73
|
+
}
|
|
74
|
+
req.end();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Check API key status
|
|
79
|
+
*/
|
|
80
|
+
async function checkApiKeyStatus() {
|
|
81
|
+
const config = loadConfig();
|
|
82
|
+
if (!config.auth.apiKey) {
|
|
83
|
+
log.debug('No API key configured, skipping status check');
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const status = await makeRequest('GET', '/auth/api-keys/self');
|
|
88
|
+
return status;
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
log.error({ err }, 'Failed to check API key status');
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Rotate the API key
|
|
97
|
+
*/
|
|
98
|
+
async function rotateApiKey() {
|
|
99
|
+
const config = loadConfig();
|
|
100
|
+
if (!config.auth.apiKey) {
|
|
101
|
+
log.error('No API key configured, cannot rotate');
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
const result = await makeRequest('POST', '/auth/api-keys/self/rotate', {});
|
|
106
|
+
log.info({
|
|
107
|
+
newPrefix: result.apiKey.prefix,
|
|
108
|
+
expiresAt: result.apiKey.expires_at,
|
|
109
|
+
}, 'API key rotated successfully');
|
|
110
|
+
return result.key;
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
log.error({ err }, 'Failed to rotate API key');
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check and renew API key if needed
|
|
119
|
+
*/
|
|
120
|
+
export async function checkAndRenewApiKey() {
|
|
121
|
+
const config = loadConfig();
|
|
122
|
+
// Only works with API key auth
|
|
123
|
+
if (!config.auth.apiKey) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
log.debug('Checking API key expiry...');
|
|
127
|
+
const status = await checkApiKeyStatus();
|
|
128
|
+
if (!status) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
log.info({
|
|
132
|
+
expiresInDays: status.expiresInDays,
|
|
133
|
+
isExpiringSoon: status.isExpiringSoon,
|
|
134
|
+
prefix: status.prefix,
|
|
135
|
+
}, 'API key status');
|
|
136
|
+
// Check if renewal is needed
|
|
137
|
+
if (status.expiresInDays > RENEWAL_THRESHOLD_DAYS) {
|
|
138
|
+
log.debug({ expiresInDays: status.expiresInDays }, 'API key not expiring soon, no renewal needed');
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
log.info({
|
|
142
|
+
expiresInDays: status.expiresInDays,
|
|
143
|
+
threshold: RENEWAL_THRESHOLD_DAYS,
|
|
144
|
+
}, 'API key expiring soon, initiating rotation');
|
|
145
|
+
// Rotate the key
|
|
146
|
+
const newKey = await rotateApiKey();
|
|
147
|
+
if (!newKey) {
|
|
148
|
+
log.error('Failed to rotate API key');
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
// Update config file with new key
|
|
152
|
+
try {
|
|
153
|
+
updateApiKey(newKey);
|
|
154
|
+
log.info('Config file updated with new API key');
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
log.error({ err }, 'Failed to update config file with new API key');
|
|
159
|
+
// The old key is now invalid, this is a critical error
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Start the API key renewal service
|
|
165
|
+
*/
|
|
166
|
+
export function startApiKeyRenewal() {
|
|
167
|
+
if (isRunning) {
|
|
168
|
+
log.warn('API key renewal service already running');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const config = loadConfig();
|
|
172
|
+
// Only start if using API key auth
|
|
173
|
+
if (!config.auth.apiKey) {
|
|
174
|
+
log.debug('Not using API key auth, renewal service not needed');
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
isRunning = true;
|
|
178
|
+
log.info({
|
|
179
|
+
checkIntervalHours: CHECK_INTERVAL_MS / (60 * 60 * 1000),
|
|
180
|
+
renewalThresholdDays: RENEWAL_THRESHOLD_DAYS,
|
|
181
|
+
}, 'Starting API key renewal service');
|
|
182
|
+
// Check immediately on startup
|
|
183
|
+
checkAndRenewApiKey().catch(err => {
|
|
184
|
+
log.error({ err }, 'Initial API key check failed');
|
|
185
|
+
});
|
|
186
|
+
// Schedule periodic checks
|
|
187
|
+
checkTimer = setInterval(() => {
|
|
188
|
+
checkAndRenewApiKey().catch(err => {
|
|
189
|
+
log.error({ err }, 'Periodic API key check failed');
|
|
190
|
+
});
|
|
191
|
+
}, CHECK_INTERVAL_MS);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Stop the API key renewal service
|
|
195
|
+
*/
|
|
196
|
+
export function stopApiKeyRenewal() {
|
|
197
|
+
if (checkTimer) {
|
|
198
|
+
clearInterval(checkTimer);
|
|
199
|
+
checkTimer = null;
|
|
200
|
+
}
|
|
201
|
+
isRunning = false;
|
|
202
|
+
log.debug('API key renewal service stopped');
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=api-key-renewal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key-renewal.js","sourceRoot":"","sources":["../../src/services/api-key-renewal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { UpdateConfig, NpmVersionInfo } from '../types/update.js';
|
|
2
|
+
export declare class NpmAutoUpdateService {
|
|
3
|
+
private checkInterval;
|
|
4
|
+
private initialCheckTimeout;
|
|
5
|
+
private config;
|
|
6
|
+
constructor(config?: Partial<UpdateConfig>);
|
|
7
|
+
/**
|
|
8
|
+
* Start the auto-update service.
|
|
9
|
+
* Performs initial check after 1 minute, then checks periodically.
|
|
10
|
+
*/
|
|
11
|
+
start(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Stop the auto-update service.
|
|
14
|
+
*/
|
|
15
|
+
stop(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Check for updates without installing.
|
|
18
|
+
*/
|
|
19
|
+
checkForUpdates(): Promise<NpmVersionInfo>;
|
|
20
|
+
/**
|
|
21
|
+
* Check for updates and install if available.
|
|
22
|
+
*/
|
|
23
|
+
private checkAndUpdate;
|
|
24
|
+
/**
|
|
25
|
+
* Get current installed version from package.json.
|
|
26
|
+
*/
|
|
27
|
+
private getCurrentVersion;
|
|
28
|
+
/**
|
|
29
|
+
* Get latest version from npm registry.
|
|
30
|
+
*/
|
|
31
|
+
private getLatestVersion;
|
|
32
|
+
/**
|
|
33
|
+
* Compare semver versions.
|
|
34
|
+
* Returns true if `latest` is newer than `current`.
|
|
35
|
+
*/
|
|
36
|
+
private isNewer;
|
|
37
|
+
/**
|
|
38
|
+
* Acquire update lock file.
|
|
39
|
+
* Returns false if another agent is updating.
|
|
40
|
+
*/
|
|
41
|
+
private acquireLock;
|
|
42
|
+
/**
|
|
43
|
+
* Release update lock file.
|
|
44
|
+
*/
|
|
45
|
+
private releaseLock;
|
|
46
|
+
/**
|
|
47
|
+
* Perform the npm update.
|
|
48
|
+
*/
|
|
49
|
+
private performUpdate;
|
|
50
|
+
/**
|
|
51
|
+
* Request daemon restart via SIGTERM.
|
|
52
|
+
* systemd will restart us with the new version.
|
|
53
|
+
*/
|
|
54
|
+
private requestRestart;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Load update config from environment or use defaults.
|
|
58
|
+
*/
|
|
59
|
+
export declare function loadUpdateConfig(): UpdateConfig;
|
|
60
|
+
//# sourceMappingURL=npm-auto-update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-auto-update.d.ts","sourceRoot":"","sources":["../../src/services/npm-auto-update.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAOvE,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAI9C;;;OAGG;IACH,KAAK,IAAI,IAAI;IA0Bb;;OAEG;IACH,IAAI,IAAI,IAAI;IAYZ;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,cAAc,CAAC;IAUhD;;OAEG;YACW,cAAc;IAgC5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAazB;;OAEG;YACW,gBAAgB;IAa9B;;;OAGG;IACH,OAAO,CAAC,OAAO;IAcf;;;OAGG;IACH,OAAO,CAAC,WAAW;IAsBnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;YACW,aAAa;IAiB3B;;;OAGG;IACH,OAAO,CAAC,cAAc;CAOvB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAuB/C"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// Path: zn-vault-agent/src/services/npm-auto-update.ts
|
|
2
|
+
/**
|
|
3
|
+
* npm-based Auto-Update Service
|
|
4
|
+
*
|
|
5
|
+
* Periodically checks npm registry for new versions and auto-updates
|
|
6
|
+
* the agent via `npm install -g`. Uses a lock file to prevent multiple
|
|
7
|
+
* agents from updating simultaneously.
|
|
8
|
+
*/
|
|
9
|
+
import { exec } from 'child_process';
|
|
10
|
+
import { promisify } from 'util';
|
|
11
|
+
import { existsSync, writeFileSync, unlinkSync, readFileSync, statSync } from 'fs';
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
import { dirname, join } from 'path';
|
|
14
|
+
import { logger } from '../lib/logger.js';
|
|
15
|
+
import { DEFAULT_UPDATE_CONFIG } from '../types/update.js';
|
|
16
|
+
const execAsync = promisify(exec);
|
|
17
|
+
const LOCK_FILE = '/var/run/zn-vault-agent.update.lock';
|
|
18
|
+
const PACKAGE_NAME = '@zincapp/zn-vault-agent';
|
|
19
|
+
export class NpmAutoUpdateService {
|
|
20
|
+
checkInterval = null;
|
|
21
|
+
initialCheckTimeout = null;
|
|
22
|
+
config;
|
|
23
|
+
constructor(config = {}) {
|
|
24
|
+
this.config = { ...DEFAULT_UPDATE_CONFIG, ...config };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Start the auto-update service.
|
|
28
|
+
* Performs initial check after 1 minute, then checks periodically.
|
|
29
|
+
*/
|
|
30
|
+
start() {
|
|
31
|
+
if (!this.config.enabled) {
|
|
32
|
+
logger.debug('Auto-update disabled');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
logger.info({ interval: this.config.checkIntervalMs / 1000, channel: this.config.channel }, 'Starting npm auto-update service');
|
|
36
|
+
// Initial check after 1 minute (let daemon stabilize)
|
|
37
|
+
this.initialCheckTimeout = setTimeout(() => {
|
|
38
|
+
this.checkAndUpdate().catch((err) => {
|
|
39
|
+
logger.error({ err }, 'Initial auto-update check failed');
|
|
40
|
+
});
|
|
41
|
+
}, 60_000);
|
|
42
|
+
// Then check periodically
|
|
43
|
+
this.checkInterval = setInterval(() => {
|
|
44
|
+
this.checkAndUpdate().catch((err) => {
|
|
45
|
+
logger.error({ err }, 'Auto-update check failed');
|
|
46
|
+
});
|
|
47
|
+
}, this.config.checkIntervalMs);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Stop the auto-update service.
|
|
51
|
+
*/
|
|
52
|
+
stop() {
|
|
53
|
+
if (this.initialCheckTimeout) {
|
|
54
|
+
clearTimeout(this.initialCheckTimeout);
|
|
55
|
+
this.initialCheckTimeout = null;
|
|
56
|
+
}
|
|
57
|
+
if (this.checkInterval) {
|
|
58
|
+
clearInterval(this.checkInterval);
|
|
59
|
+
this.checkInterval = null;
|
|
60
|
+
}
|
|
61
|
+
logger.debug('Auto-update service stopped');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check for updates without installing.
|
|
65
|
+
*/
|
|
66
|
+
async checkForUpdates() {
|
|
67
|
+
const current = this.getCurrentVersion();
|
|
68
|
+
const latest = await this.getLatestVersion();
|
|
69
|
+
return {
|
|
70
|
+
current,
|
|
71
|
+
latest,
|
|
72
|
+
updateAvailable: this.isNewer(latest, current),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check for updates and install if available.
|
|
77
|
+
*/
|
|
78
|
+
async checkAndUpdate() {
|
|
79
|
+
try {
|
|
80
|
+
const info = await this.checkForUpdates();
|
|
81
|
+
if (!info.updateAvailable) {
|
|
82
|
+
logger.debug({ current: info.current, latest: info.latest }, 'No update available');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
logger.info({ current: info.current, latest: info.latest }, 'Update available, attempting upgrade');
|
|
86
|
+
// Acquire lock (prevents multiple agents updating simultaneously)
|
|
87
|
+
if (!this.acquireLock()) {
|
|
88
|
+
logger.info('Another agent is updating, skipping');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
await this.performUpdate();
|
|
93
|
+
logger.info({ version: info.latest }, 'Update complete, requesting restart');
|
|
94
|
+
this.requestRestart();
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
this.releaseLock();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
logger.error({ err }, 'Auto-update check failed');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get current installed version from package.json.
|
|
106
|
+
*/
|
|
107
|
+
getCurrentVersion() {
|
|
108
|
+
try {
|
|
109
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
110
|
+
const __dirname = dirname(__filename);
|
|
111
|
+
const pkgPath = join(__dirname, '..', '..', 'package.json');
|
|
112
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
113
|
+
return pkg.version;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Fallback: try to read from global npm
|
|
117
|
+
return '0.0.0';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get latest version from npm registry.
|
|
122
|
+
*/
|
|
123
|
+
async getLatestVersion() {
|
|
124
|
+
const tag = this.config.channel;
|
|
125
|
+
try {
|
|
126
|
+
const { stdout } = await execAsync(`npm view ${PACKAGE_NAME}@${tag} version`, {
|
|
127
|
+
timeout: 30_000,
|
|
128
|
+
});
|
|
129
|
+
return stdout.trim();
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
logger.warn({ err, channel: tag }, 'Failed to fetch latest version from npm');
|
|
133
|
+
throw err;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Compare semver versions.
|
|
138
|
+
* Returns true if `latest` is newer than `current`.
|
|
139
|
+
*/
|
|
140
|
+
isNewer(latest, current) {
|
|
141
|
+
const parseSemver = (v) => {
|
|
142
|
+
const parts = v.replace(/^v/, '').split('.');
|
|
143
|
+
return parts.map((p) => parseInt(p, 10) || 0);
|
|
144
|
+
};
|
|
145
|
+
const [lMaj, lMin = 0, lPatch = 0] = parseSemver(latest);
|
|
146
|
+
const [cMaj, cMin = 0, cPatch = 0] = parseSemver(current);
|
|
147
|
+
if (lMaj !== cMaj)
|
|
148
|
+
return lMaj > cMaj;
|
|
149
|
+
if (lMin !== cMin)
|
|
150
|
+
return lMin > cMin;
|
|
151
|
+
return lPatch > cPatch;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Acquire update lock file.
|
|
155
|
+
* Returns false if another agent is updating.
|
|
156
|
+
*/
|
|
157
|
+
acquireLock() {
|
|
158
|
+
try {
|
|
159
|
+
if (existsSync(LOCK_FILE)) {
|
|
160
|
+
// Check if lock is stale (> 10 minutes old)
|
|
161
|
+
const stat = statSync(LOCK_FILE);
|
|
162
|
+
const age = Date.now() - stat.mtimeMs;
|
|
163
|
+
if (age < 10 * 60 * 1000) {
|
|
164
|
+
const pid = readFileSync(LOCK_FILE, 'utf-8').trim();
|
|
165
|
+
logger.debug({ pid, age: Math.round(age / 1000) }, 'Lock file exists');
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
logger.warn({ age: Math.round(age / 1000) }, 'Stale lock file detected, removing');
|
|
169
|
+
}
|
|
170
|
+
writeFileSync(LOCK_FILE, String(process.pid));
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
// Can't write to /var/run - might not be running as root
|
|
175
|
+
logger.debug({ err }, 'Could not acquire lock file (non-root?)');
|
|
176
|
+
return true; // Allow update anyway
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Release update lock file.
|
|
181
|
+
*/
|
|
182
|
+
releaseLock() {
|
|
183
|
+
try {
|
|
184
|
+
unlinkSync(LOCK_FILE);
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// Ignore errors
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Perform the npm update.
|
|
192
|
+
*/
|
|
193
|
+
async performUpdate() {
|
|
194
|
+
const tag = this.config.channel;
|
|
195
|
+
logger.info({ package: PACKAGE_NAME, channel: tag }, 'Installing update via npm');
|
|
196
|
+
try {
|
|
197
|
+
const { stdout, stderr } = await execAsync(`npm install -g ${PACKAGE_NAME}@${tag}`, {
|
|
198
|
+
timeout: 5 * 60 * 1000, // 5 minute timeout
|
|
199
|
+
});
|
|
200
|
+
if (stdout)
|
|
201
|
+
logger.debug({ stdout: stdout.trim() }, 'npm install stdout');
|
|
202
|
+
if (stderr)
|
|
203
|
+
logger.debug({ stderr: stderr.trim() }, 'npm install stderr');
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
logger.error({ err }, 'npm install failed');
|
|
207
|
+
throw err;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Request daemon restart via SIGTERM.
|
|
212
|
+
* systemd will restart us with the new version.
|
|
213
|
+
*/
|
|
214
|
+
requestRestart() {
|
|
215
|
+
logger.info('Sending SIGTERM to self for restart');
|
|
216
|
+
// Give logs time to flush
|
|
217
|
+
setTimeout(() => {
|
|
218
|
+
process.kill(process.pid, 'SIGTERM');
|
|
219
|
+
}, 1000);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Load update config from environment or use defaults.
|
|
224
|
+
*/
|
|
225
|
+
export function loadUpdateConfig() {
|
|
226
|
+
const config = { ...DEFAULT_UPDATE_CONFIG };
|
|
227
|
+
// Check for environment overrides
|
|
228
|
+
if (process.env.AUTO_UPDATE === 'false' || process.env.AUTO_UPDATE === '0') {
|
|
229
|
+
config.enabled = false;
|
|
230
|
+
}
|
|
231
|
+
if (process.env.AUTO_UPDATE_INTERVAL) {
|
|
232
|
+
const interval = parseInt(process.env.AUTO_UPDATE_INTERVAL, 10);
|
|
233
|
+
if (!isNaN(interval) && interval > 0) {
|
|
234
|
+
config.checkIntervalMs = interval * 1000; // Convert seconds to ms
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (process.env.AUTO_UPDATE_CHANNEL) {
|
|
238
|
+
const channel = process.env.AUTO_UPDATE_CHANNEL.toLowerCase();
|
|
239
|
+
if (channel === 'latest' || channel === 'beta' || channel === 'next') {
|
|
240
|
+
config.channel = channel;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return config;
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=npm-auto-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-auto-update.js","sourceRoot":"","sources":["../../src/services/npm-auto-update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simplified Update Types for npm-based Auto-Update
|
|
3
|
+
*
|
|
4
|
+
* Replaces the complex S3/GPG update system (~170 lines) with
|
|
5
|
+
* a simple npm-based approach (~30 lines).
|
|
6
|
+
*/
|
|
7
|
+
export interface NpmVersionInfo {
|
|
8
|
+
current: string;
|
|
9
|
+
latest: string;
|
|
10
|
+
updateAvailable: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type UpdateChannel = 'latest' | 'beta' | 'next';
|
|
13
|
+
export interface UpdateConfig {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
checkIntervalMs: number;
|
|
16
|
+
channel: UpdateChannel;
|
|
17
|
+
}
|
|
18
|
+
export declare const DEFAULT_UPDATE_CONFIG: UpdateConfig;
|
|
19
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/types/update.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/types/update.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAuB3C,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;IAC5C,OAAO,EAAE,QAAQ;CAClB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zincapp/zn-vault-agent",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "ZN-Vault Certificate Agent - Real-time certificate distribution",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"zn-vault-agent": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/",
|
|
12
|
+
"!dist/**/*.test.js",
|
|
13
|
+
"!dist/**/*.test.js.map",
|
|
14
|
+
"!dist/**/*.test.d.ts",
|
|
15
|
+
"!dist/**/*.test.d.ts.map",
|
|
16
|
+
"!dist/*.cjs",
|
|
17
|
+
"!dist/*.cjs.map",
|
|
18
|
+
"deploy/systemd/zn-vault-agent.service",
|
|
19
|
+
"deploy/logrotate.d/"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"build:bundle": "node scripts/bundle.mjs",
|
|
27
|
+
"dev": "tsx watch src/index.ts",
|
|
28
|
+
"start": "node dist/index.js",
|
|
29
|
+
"start:bundle": "node dist/zn-vault-agent.cjs",
|
|
30
|
+
"lint": "eslint src/",
|
|
31
|
+
"lint:fix": "eslint src/ --fix",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"pretest": "npm run build",
|
|
34
|
+
"test": "../scripts/sdk-test-run.sh npm run test:all",
|
|
35
|
+
"test:watch": "vitest",
|
|
36
|
+
"test:coverage": "vitest run --coverage",
|
|
37
|
+
"test:unit": "vitest run",
|
|
38
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
39
|
+
"test:integration:watch": "vitest --config vitest.integration.config.ts",
|
|
40
|
+
"test:all": "npm run test:unit && npm run test:integration"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"znvault",
|
|
44
|
+
"certificates",
|
|
45
|
+
"ssl",
|
|
46
|
+
"tls",
|
|
47
|
+
"agent"
|
|
48
|
+
],
|
|
49
|
+
"author": "ZincApp",
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"chalk": "^5.3.0",
|
|
53
|
+
"commander": "^12.1.0",
|
|
54
|
+
"conf": "^13.0.1",
|
|
55
|
+
"inquirer": "^9.3.7",
|
|
56
|
+
"ora": "^8.1.1",
|
|
57
|
+
"pino": "^9.0.0",
|
|
58
|
+
"ws": "^8.18.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/inquirer": "^9.0.7",
|
|
62
|
+
"@types/node": "^20.17.10",
|
|
63
|
+
"@types/ws": "^8.5.13",
|
|
64
|
+
"@vitest/coverage-v8": "^2.0.0",
|
|
65
|
+
"esbuild": "^0.24.0",
|
|
66
|
+
"pino-pretty": "^11.0.0",
|
|
67
|
+
"tsx": "^4.19.0",
|
|
68
|
+
"typescript": "^5.7.2",
|
|
69
|
+
"vitest": "^2.0.0"
|
|
70
|
+
},
|
|
71
|
+
"engines": {
|
|
72
|
+
"node": ">=18"
|
|
73
|
+
}
|
|
74
|
+
}
|