@envsync-cloud/deploy-cli 0.8.16 → 0.9.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 +1 -1
- package/dist/index.js +133 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -148,4 +148,4 @@ bun run src/index.ts plan-topology /etc/envsync/deploy.yaml
|
|
|
148
148
|
- `upgrade` and `deploy` reconcile managed versioned artifacts from `release.version`.
|
|
149
149
|
- Custom image overrides are still preserved for advanced self-host setups.
|
|
150
150
|
- Enterprise package publication now targets NPM Packages rather than the public npm registry.
|
|
151
|
-
- The full deployment guide lives in [SELFHOSTING.md](
|
|
151
|
+
- The full deployment guide lives in [SELFHOSTING.md](../../SELFHOSTING.md).
|
package/dist/index.js
CHANGED
|
@@ -4117,6 +4117,11 @@ var deployConfigSchema = external_exports.object({
|
|
|
4117
4117
|
frontend: external_exports.object({
|
|
4118
4118
|
dashboard_variant: external_exports.enum(["oss", "enterprise"]).optional(),
|
|
4119
4119
|
include_manage_subtree: external_exports.boolean().optional()
|
|
4120
|
+
}).default({}),
|
|
4121
|
+
vpn: external_exports.object({
|
|
4122
|
+
provider: external_exports.enum(["netbird", "none"]).default("none"),
|
|
4123
|
+
internal_domain: external_exports.string().default("envsync.local"),
|
|
4124
|
+
nb_setup_key: external_exports.string().default("")
|
|
4120
4125
|
}).default({})
|
|
4121
4126
|
});
|
|
4122
4127
|
function readDeployConfigFile(filePath) {
|
|
@@ -4475,7 +4480,9 @@ function buildRuntimeEnv2(config, generated) {
|
|
|
4475
4480
|
OTEL_SERVICE_NAME: "envsync-api",
|
|
4476
4481
|
OTEL_SDK_DISABLED: "false",
|
|
4477
4482
|
CLICKSTACK_URL: publicHttpsUrl(config, hosts.obs),
|
|
4478
|
-
KEYCLOAK_IMAGE_TAG: keycloakImageTag(config.images.keycloak)
|
|
4483
|
+
KEYCLOAK_IMAGE_TAG: keycloakImageTag(config.images.keycloak),
|
|
4484
|
+
// Is this too hacky? We go Shawn way.
|
|
4485
|
+
...config.vpn?.provider && config.vpn.provider !== "none" && config.vpn.nb_setup_key ? { NB_SETUP_KEY: config.vpn.nb_setup_key } : {}
|
|
4479
4486
|
};
|
|
4480
4487
|
}
|
|
4481
4488
|
function renderEnvFile(env) {
|
|
@@ -4789,6 +4796,104 @@ function renderNetutilsService(config) {
|
|
|
4789
4796
|
${ports}
|
|
4790
4797
|
networks: [envsync]`;
|
|
4791
4798
|
}
|
|
4799
|
+
var VPN_SERVICE_RENDERERS = {
|
|
4800
|
+
none: () => null,
|
|
4801
|
+
netbird: renderNetbirdService
|
|
4802
|
+
};
|
|
4803
|
+
function renderNetbirdService(config, paths, runtimeEnv) {
|
|
4804
|
+
const nbSetupKey = runtimeEnv.NB_SETUP_KEY ?? "";
|
|
4805
|
+
return {
|
|
4806
|
+
serviceBlock: `
|
|
4807
|
+
netbird_nginx:
|
|
4808
|
+
image: ghcr.io/envsync-cloud/netbird-nginx
|
|
4809
|
+
cap_add:
|
|
4810
|
+
- NET_ADMIN
|
|
4811
|
+
- SYS_ADMIN
|
|
4812
|
+
- SYS_RESOURCE
|
|
4813
|
+
networks: [envsync]
|
|
4814
|
+
environment:
|
|
4815
|
+
${renderEnvList({ NB_SETUP_KEY: nbSetupKey })}
|
|
4816
|
+
volumes:
|
|
4817
|
+
- netbird_client:/var/lib/netbird
|
|
4818
|
+
- ${paths.nginxVpnConf}:/etc/nginx/nginx.conf:ro`,
|
|
4819
|
+
// Adding comment for readability, extra volume below. We gotta do something about too many ` bhaiya.
|
|
4820
|
+
extraVolumes: ["netbird_client"]
|
|
4821
|
+
};
|
|
4822
|
+
}
|
|
4823
|
+
function renderVpnService(config, paths, runtimeEnv) {
|
|
4824
|
+
const provider = config.vpn?.provider ?? "none";
|
|
4825
|
+
const renderer = VPN_SERVICE_RENDERERS[provider];
|
|
4826
|
+
if (!renderer) return null;
|
|
4827
|
+
return renderer(config, paths, runtimeEnv);
|
|
4828
|
+
}
|
|
4829
|
+
function renderNginxVpnConf(config) {
|
|
4830
|
+
const domain = config.vpn?.internal_domain ?? "envsync.local";
|
|
4831
|
+
return `events {}
|
|
4832
|
+
|
|
4833
|
+
stream {
|
|
4834
|
+
server {
|
|
4835
|
+
listen 5432;
|
|
4836
|
+
proxy_pass postgres:5432;
|
|
4837
|
+
}
|
|
4838
|
+
server {
|
|
4839
|
+
listen 6379;
|
|
4840
|
+
proxy_pass redis:6379;
|
|
4841
|
+
}
|
|
4842
|
+
server {
|
|
4843
|
+
listen 50051;
|
|
4844
|
+
proxy_pass minikms:50051;
|
|
4845
|
+
}
|
|
4846
|
+
server {
|
|
4847
|
+
listen 5544;
|
|
4848
|
+
proxy_pass minikms_db:5432;
|
|
4849
|
+
}
|
|
4850
|
+
server {
|
|
4851
|
+
listen 8091;
|
|
4852
|
+
proxy_pass openfga:8091;
|
|
4853
|
+
}
|
|
4854
|
+
}
|
|
4855
|
+
|
|
4856
|
+
http {
|
|
4857
|
+
server {
|
|
4858
|
+
listen 80;
|
|
4859
|
+
server_name keycloak.${domain};
|
|
4860
|
+
location / {
|
|
4861
|
+
proxy_pass http://keycloak:8080/;
|
|
4862
|
+
proxy_set_header Host $host;
|
|
4863
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
4864
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
4865
|
+
}
|
|
4866
|
+
}
|
|
4867
|
+
server {
|
|
4868
|
+
listen 80;
|
|
4869
|
+
server_name openfga.${domain};
|
|
4870
|
+
location / {
|
|
4871
|
+
proxy_pass http://openfga:8090/;
|
|
4872
|
+
proxy_set_header Host $host;
|
|
4873
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
4874
|
+
}
|
|
4875
|
+
}
|
|
4876
|
+
server {
|
|
4877
|
+
listen 80;
|
|
4878
|
+
server_name clickstack.${domain};
|
|
4879
|
+
location / {
|
|
4880
|
+
proxy_pass http://clickstack:8080/;
|
|
4881
|
+
proxy_set_header Host $host;
|
|
4882
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
4883
|
+
}
|
|
4884
|
+
}
|
|
4885
|
+
server {
|
|
4886
|
+
listen 80;
|
|
4887
|
+
server_name rustfs.${domain};
|
|
4888
|
+
location / {
|
|
4889
|
+
proxy_pass http://rustfs:9001/;
|
|
4890
|
+
proxy_set_header Host $host;
|
|
4891
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
4892
|
+
}
|
|
4893
|
+
}
|
|
4894
|
+
}
|
|
4895
|
+
`;
|
|
4896
|
+
}
|
|
4792
4897
|
function renderOtelAgentConfig(config) {
|
|
4793
4898
|
return [
|
|
4794
4899
|
"receivers:",
|
|
@@ -4846,6 +4951,7 @@ function renderStack(config, runtimeEnv, generated, mode, paths) {
|
|
|
4846
4951
|
const s3ConsoleRouterName = `${stackName}-s3-console-router`;
|
|
4847
4952
|
const s3ConsoleServiceName = `${stackName}-s3-console-service`;
|
|
4848
4953
|
const netutilsService = renderNetutilsService(config);
|
|
4954
|
+
const vpnResult = renderVpnService(config, paths, runtimeEnv);
|
|
4849
4955
|
const apiEnvironment = {
|
|
4850
4956
|
...runtimeEnv,
|
|
4851
4957
|
OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-agent:4318",
|
|
@@ -5113,7 +5219,7 @@ ${renderEnvList({
|
|
|
5113
5219
|
${apiLicenseVolume}
|
|
5114
5220
|
networks: [envsync]
|
|
5115
5221
|
deploy:
|
|
5116
|
-
replicas: ${slotHasApiDeployment(deployment.slots.green) ? 1 : 0}` : ""}${netutilsService}
|
|
5222
|
+
replicas: ${slotHasApiDeployment(deployment.slots.green) ? 1 : 0}` : ""}${netutilsService}${vpnResult?.serviceBlock ?? ""}
|
|
5117
5223
|
|
|
5118
5224
|
networks:
|
|
5119
5225
|
envsync:
|
|
@@ -5130,6 +5236,8 @@ volumes:
|
|
|
5130
5236
|
clickstack_data:
|
|
5131
5237
|
clickstack_ch_data:
|
|
5132
5238
|
clickstack_ch_logs:
|
|
5239
|
+
${vpnResult?.extraVolumes.map((v) => `
|
|
5240
|
+
${v}:`).join("") ?? ""}
|
|
5133
5241
|
|
|
5134
5242
|
configs:
|
|
5135
5243
|
keycloak_realm:
|
|
@@ -5231,6 +5339,7 @@ var KEYCLOAK_REALM_FILE = path3.join(DEPLOY_ROOT, "keycloak-realm.envsync.json")
|
|
|
5231
5339
|
var NGINX_WEB_CONF = path3.join(DEPLOY_ROOT, "nginx-web.conf");
|
|
5232
5340
|
var NGINX_LANDING_CONF = path3.join(DEPLOY_ROOT, "nginx-landing.conf");
|
|
5233
5341
|
var NGINX_API_MAINTENANCE_CONF = path3.join(DEPLOY_ROOT, "nginx-api-maintenance.conf");
|
|
5342
|
+
var NGINX_VPN_CONF = path3.join(DEPLOY_ROOT, "nginx-vpn.conf");
|
|
5234
5343
|
var OTEL_AGENT_CONF = path3.join(DEPLOY_ROOT, "otel-agent.yaml");
|
|
5235
5344
|
var CLICKSTACK_CLICKHOUSE_CONF = path3.join(DEPLOY_ROOT, "clickhouse-listen.xml");
|
|
5236
5345
|
var INTERNAL_CONFIG_JSON = path3.join(DEPLOY_ROOT, "config.json");
|
|
@@ -5248,7 +5357,8 @@ var DEPLOY_RENDER_PATHS = {
|
|
|
5248
5357
|
otelAgentConf: OTEL_AGENT_CONF,
|
|
5249
5358
|
nginxLandingConf: NGINX_LANDING_CONF,
|
|
5250
5359
|
nginxWebConf: NGINX_WEB_CONF,
|
|
5251
|
-
nginxApiMaintenanceConf: NGINX_API_MAINTENANCE_CONF
|
|
5360
|
+
nginxApiMaintenanceConf: NGINX_API_MAINTENANCE_CONF,
|
|
5361
|
+
nginxVpnConf: NGINX_VPN_CONF
|
|
5252
5362
|
};
|
|
5253
5363
|
var REMOVE_TARGETS = [
|
|
5254
5364
|
DEPLOY_ROOT,
|
|
@@ -6137,6 +6247,11 @@ function normalizeConfig(raw) {
|
|
|
6137
6247
|
keep_failed_upgrade_db_snapshot: raw.upgrade?.keep_failed_upgrade_db_snapshot ?? true
|
|
6138
6248
|
},
|
|
6139
6249
|
netutils: normalizeNetutilsForwards(raw.netutils?.forwards, stackName, raw.netutils?.enabled ?? false),
|
|
6250
|
+
vpn: {
|
|
6251
|
+
provider: raw.vpn?.provider ?? "none",
|
|
6252
|
+
internal_domain: raw.vpn?.internal_domain ?? "envsync.local",
|
|
6253
|
+
nb_setup_key: raw.vpn?.nb_setup_key ?? ""
|
|
6254
|
+
},
|
|
6140
6255
|
license: raw.license ? {
|
|
6141
6256
|
server_url: raw.license.server_url,
|
|
6142
6257
|
key: raw.license.key,
|
|
@@ -6470,6 +6585,9 @@ function writeDeployArtifacts(config, generated) {
|
|
|
6470
6585
|
writeFileMaybe(NGINX_API_MAINTENANCE_CONF, renderApiMaintenanceConf());
|
|
6471
6586
|
writeFileMaybe(OTEL_AGENT_CONF, renderOtelAgentConfig(config));
|
|
6472
6587
|
writeFileMaybe(CLICKSTACK_CLICKHOUSE_CONF, renderClickstackClickHouseConfig());
|
|
6588
|
+
if (config.vpn?.provider && config.vpn.provider !== "none") {
|
|
6589
|
+
writeFileMaybe(NGINX_VPN_CONF, renderNginxVpnConf(config));
|
|
6590
|
+
}
|
|
6473
6591
|
logSuccess(currentOptions.dryRun ? "Deploy artifacts previewed" : "Deploy artifacts written");
|
|
6474
6592
|
}
|
|
6475
6593
|
function saveDesiredConfig(config) {
|
|
@@ -7585,6 +7703,13 @@ async function cmdSetup() {
|
|
|
7585
7703
|
}
|
|
7586
7704
|
}
|
|
7587
7705
|
const licenseServerUrl = await ask("Enterprise license server URL", DEFAULT_ENTERPRISE_LICENSE_SERVER_URL);
|
|
7706
|
+
const vpnProvider = (await ask("VPN provider for internal service access (netbird/none)", "none")).toLowerCase();
|
|
7707
|
+
let vpnInternalDomain = "envsync.local";
|
|
7708
|
+
let vpnNbSetupKey = "";
|
|
7709
|
+
if (vpnProvider !== "none") {
|
|
7710
|
+
vpnInternalDomain = await ask("Internal root domain", "envsync.local");
|
|
7711
|
+
vpnNbSetupKey = await ask("Netbird setup key", "");
|
|
7712
|
+
}
|
|
7588
7713
|
const licenseKey = licenseServerUrl ? await ask("Enterprise license key", "") : "";
|
|
7589
7714
|
const certificateBundleFile = licenseServerUrl ? "" : await ask("Enterprise certificate bundle file (optional)", "");
|
|
7590
7715
|
const installFingerprint = deterministicInstallFingerprint(rootDomain, "envsync");
|
|
@@ -7664,6 +7789,11 @@ async function cmdSetup() {
|
|
|
7664
7789
|
netutils: {
|
|
7665
7790
|
enabled: netutilsEnabled,
|
|
7666
7791
|
forwards: netutilsForwards
|
|
7792
|
+
},
|
|
7793
|
+
vpn: {
|
|
7794
|
+
provider: vpnProvider,
|
|
7795
|
+
internal_domain: vpnInternalDomain,
|
|
7796
|
+
nb_setup_key: vpnNbSetupKey
|
|
7667
7797
|
}
|
|
7668
7798
|
};
|
|
7669
7799
|
saveDesiredConfig(config);
|