@r8s/netbird 0.3.4

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.
@@ -0,0 +1,245 @@
1
+ import { type DatabaseProps } from '@r8s/recipes';
2
+ /**
3
+ * Keycloak is the documented IdP (docs.netbird.io → Self-hosted → Identity
4
+ * providers → Keycloak): a dedicated `netbird` realm with a confidential
5
+ * OIDC client `netbird`. The
6
+ * management store uses client credentials (`client_credentials` grant) —
7
+ * render that client with `<Client groupsClaim>` (the Auth recipe) so
8
+ * Keycloak puts group memberships in the JWT `groups` claim for
9
+ * user-group sync; netbird reads the claim, this package only carries the
10
+ * identity endpoints derived from `issuer`.
11
+ */
12
+ export interface NetbirdIdpProps {
13
+ /**
14
+ * OIDC issuer, e.g. 'https://auth.example.com/realms/netbird'. Token,
15
+ * JWKS, device-authorize and authorize endpoints are derived from it
16
+ * (Keycloak realm layout: <issuer>/protocol/openid-connect/...).
17
+ *
18
+ * Alternative: pass `realm` + `host` instead and the issuer is derived
19
+ * as `https://<host>/realms/<realm>` — the Auth recipe's layout. The
20
+ * two forms are mutually exclusive.
21
+ */
22
+ issuer?: string;
23
+ /** OIDC client id — the confidential `netbird` client in the realm */
24
+ clientId: string;
25
+ /**
26
+ * Reference a pre-created Secret holding the client secret (key:
27
+ * `client-secret`). Payload: the OIDC client's secret from the
28
+ * Keycloak realm (Clients → netbird → Credentials). Without it the
29
+ * secrets backend provisions `${name}-oidc` from the store path.
30
+ */
31
+ clientSecretRef?: string;
32
+ /**
33
+ * Keycloak realm name — with `host`, derives the issuer as
34
+ * `https://<host>/realms/<realm>` (mirrors <Realm id="netbird"> in the
35
+ * Auth recipe on the same host). Mutually exclusive with `issuer`.
36
+ */
37
+ realm?: string;
38
+ /**
39
+ * Auth hostname (the AUTH host, NOT <Netbird host>) — with `realm`,
40
+ * derives the issuer as `https://<host>/realms/<realm>`. Mutually
41
+ * exclusive with `issuer`.
42
+ */
43
+ host?: string;
44
+ }
45
+ export interface NetbirdProps {
46
+ /** Release / chart name (defaults to 'netbird'; also the namespace-internal resource prefix) */
47
+ name?: string;
48
+ /** Kubernetes namespace for the release + data (inherited from <Platform> unless set) */
49
+ namespace?: string;
50
+ /**
51
+ * Single public hostname: dashboard, management API/gRPC, signal and
52
+ * relay are all routed on it (ingress-nginx merges the rules; TLS via
53
+ * one shared certificate).
54
+ */
55
+ host: string;
56
+ /**
57
+ * Keycloak OIDC identity provider wired into the management config.
58
+ *
59
+ * Group sync with the Auth recipe: give the realm's `netbird` client
60
+ * <Client groupsClaim> so Keycloak puts group memberships in the JWT
61
+ * `groups` claim — Netbird auto-creates groups from it (map Netbird
62
+ * policies to those groups). Netbird's Keycloak group/user reads
63
+ * authenticate via client_credentials — grant the netbird client's
64
+ * service account the realm-management view-users/view-groups roles
65
+ * (a dedicated `netbird-manager` client is the upstream pattern for
66
+ * splitting those reads onto separate credentials). See the compose
67
+ * example below.
68
+ */
69
+ idp: NetbirdIdpProps;
70
+ /**
71
+ * Expose the relay Service as a raw LoadBalancer on this TCP port in
72
+ * addition to the `rels://host:443/relay` ingress path. The chart's
73
+ * relay is the TCP websocket relay — it does NOT speak UDP, and the
74
+ * chart ships no coturn: add an external STUN/TURN server (+ its own
75
+ * LoadBalancer) separately if peers need it.
76
+ */
77
+ relayPort?: number;
78
+ /**
79
+ * Chart version (defaults to the pinned '1.9.0'). Flux applies chart
80
+ * upgrades automatically on the repo interval — bump deliberately.
81
+ */
82
+ chartVersion?: string;
83
+ /** HelmRepository URL (defaults to https://netbirdio.github.io/helms — the gh-pages index of netbirdio/helms) */
84
+ repoUrl?: string;
85
+ /** Namespace the HelmRepository lives in (defaults to 'flux-system') */
86
+ repoNamespace?: string;
87
+ /**
88
+ * Image tag for the three core services (management, signal, relay —
89
+ * netbirdio/{management,signal,relay}). Defaults to '0.46.0', the
90
+ * chart 1.9.0 appVersion the management.json template is written
91
+ * against — newer netbird images may expect a different config shape,
92
+ * so bump chart + images together. PINNED — 'latest' is rejected. The
93
+ * dashboard keeps its own chart default (v2.13.1, also pinned).
94
+ */
95
+ imageTag?: string;
96
+ /**
97
+ * Management data PVC sizing. The chart only needs it for the sqlite
98
+ * store — with the CNPG Postgres contract below the management data
99
+ * dir is disposable, so the PVC is DISABLED by default. Pass a size
100
+ * (e.g. '1Gi') to keep it, or `false` to disable it explicitly.
101
+ */
102
+ storage?: string | false;
103
+ /** CNPG cluster name (defaults to 'netbird-db'). Database + owner are 'netbird'. */
104
+ dbName?: string;
105
+ /** Number of CNPG instances (defaults to 2) */
106
+ dbInstances?: number;
107
+ /** CNPG data volume size (defaults to '10Gi' — management store, small) */
108
+ dbStorage?: string;
109
+ /** CNPG storage class (defaults to cluster default) */
110
+ dbStorageClass?: string;
111
+ /** CNPG backup passthrough — defaults to **enabled** via the platform S3Provider; `false` opts out */
112
+ backup?: DatabaseProps['backup'];
113
+ /**
114
+ * Reference a pre-created Secret holding the relay auth secret + the
115
+ * datastore encryption key (keys `relay-secret`,
116
+ * `datastore-encryption-key`) instead of backend provisioning. The
117
+ * relay secret also travels to peers in management.json — rotating it
118
+ * restarts management + relay.
119
+ */
120
+ credentialsSecretName?: string;
121
+ /** User-ID claim netbird matches accounts on (e.g. 'preferred_username' — depends on the IdP mapper) */
122
+ userIdClaim?: string;
123
+ /** TLS: one shared cert for every ingress the chart creates (defaults to `netbird-tls` via letsencrypt-prod). The cert-manager annotation sits on the dashboard catch-all ingress only — the other ingresses reference the same secret without triggering duplicate issuances (LE duplicate-cert limit is 5/week). */
124
+ tls?: {
125
+ secretName: string;
126
+ clusterIssuer: string;
127
+ };
128
+ }
129
+ /**
130
+ * Netbird — WireGuard-based mesh VPN (management + signal + relay +
131
+ * dashboard behind one hostname), facit-aligned via the official chart.
132
+ *
133
+ * @title Netbird
134
+ * @category Networking
135
+ *
136
+ * The chart owns all app workloads (management/signal/relay/dashboard +
137
+ * their services and ingresses). This package owns the platform contract
138
+ * around it:
139
+ * - Flux `HelmRepository` + `HelmRelease` (pinned chart, facit values).
140
+ * netbirdio publishes packaged chart .tgz releases against a gh-pages
141
+ * Helm index (no OCI artifact exists) — a plain HelmRepository works.
142
+ * - external CNPG cluster (`credentialsMode: 'cnpg'`): the management
143
+ * store reads the DSN from the CNPG-generated `<db>-app` secret's
144
+ * `fqdn-uri` key via `management.envFromSecret` — the raw DSN never
145
+ * appears in rendered YAML beyond its secretKeyRef
146
+ * - management.json rendered into the chart's `management.configmap`
147
+ * with `{{ .VAR }}` env placeholders (netbird ≥ 0.30.1 substitutes
148
+ * them from process env — the chart's own IdP examples rely on it)
149
+ * - IdP credentials + relay secret + datastore encryption key via the
150
+ * Platform secrets backend (pre-created Secret references win)
151
+ * - cert-manager TLS on the dashboard catch-all ingress; the management/
152
+ * gRPC/signal/relay ingresses reference the same TLS secret
153
+ * - optional raw LoadBalancer face for the relay via `relayPort`
154
+ *
155
+ * Encoded decisions (do not "fix" these):
156
+ * - NO Stuns/TURNConfig entries: the chart deploys no coturn server and
157
+ * pointing peers at a dead `host:3478` is worse than none — peers
158
+ * connect via the relay (rels://host:443/relay); add an external
159
+ * STUN/TURN server if you need direct hairpin/wifi-less connectivity
160
+ * - `useBackwardsGrpcService: true` (the chart's own tested example):
161
+ * the management gRPC ingress routes to the dedicated 33073 listener
162
+ * - `persistentVolume.enabled: false` (facit: postgres-backed store —
163
+ * the docker-compose template also ships `"Datadir": ""` for postgres)
164
+ * - images pinned to the chart appVersion (0.46.0); chart 1.9.0's
165
+ * management.json schema matches that generation — bump together
166
+ *
167
+ * @example
168
+ * import { Platform, S3Provider, MinIO } from '@r8s/recipes'
169
+ * import { Netbird } from '@r8s/netbird'
170
+ *
171
+ * // CNPG backups derive from the S3Provider; the IdP client secret +
172
+ * // relay/datastore credentials provision from the openbao store
173
+ * export default (
174
+ * <S3Provider
175
+ * provider={
176
+ * <MinIO endpoint="https://rustfs:9000" bucket="infra" credentialsSecret="infra-s3-creds" />
177
+ * }
178
+ * >
179
+ * <Platform secrets={{ backend: 'openbao', mount: 'secret', path: 'apps' }}>
180
+ * <Netbird
181
+ * host="netbird.example.com"
182
+ * idp={{
183
+ * issuer: 'https://auth.example.com/realms/netbird',
184
+ * clientId: 'netbird',
185
+ * }}
186
+ * />
187
+ * </Platform>
188
+ * </S3Provider>
189
+ * )
190
+ *
191
+ * @example
192
+ * // Compose with the Auth recipe — realm-level group sync for policies
193
+ * import { Platform, S3Provider, MinIO, Auth } from '@r8s/recipes'
194
+ * import { Realms, Realm, Clients, Client } from '@r8s/recipes/auth'
195
+ * import { Netbird } from '@r8s/netbird'
196
+ *
197
+ * // groupsClaim puts Keycloak group memberships in the JWT `groups`
198
+ * // claim — Netbird auto-creates groups from it (map Netbird policies
199
+ * // to those groups). Netbird's group/user reads authenticate via
200
+ * // client_credentials — grant the netbird client's service account
201
+ * // realm-management view-users/view-groups; `netbird-manager` is the
202
+ * // upstream pattern for splitting those reads onto separate
203
+ * // credentials. localhost:53000 is the netbird CLI/desktop PKCE
204
+ * // redirect; the auth host gets TLS so the https issuer is reachable.
205
+ * export default (
206
+ * <S3Provider
207
+ * provider={
208
+ * <MinIO endpoint="https://rustfs:9000" bucket="infra" credentialsSecret="infra-s3-creds" />
209
+ * }
210
+ * >
211
+ * <Platform secrets={{ backend: 'openbao', mount: 'secret', path: 'apps' }}>
212
+ * <Auth
213
+ * name="auth"
214
+ * host="auth.example.com"
215
+ * tls={{ secretName: 'auth-tls', clusterIssuer: 'letsencrypt-prod' }}
216
+ * >
217
+ * <Realms>
218
+ * <Realm id="netbird" displayName="Netbird">
219
+ * <Clients>
220
+ * <Client
221
+ * id="netbird"
222
+ * type="confidential"
223
+ * redirectUris={['https://netbird.example.com/*', 'http://localhost:53000']}
224
+ * groupsClaim
225
+ * clientScopes={['api']}
226
+ * />
227
+ * <Client id="netbird-manager" type="confidential" />
228
+ * </Clients>
229
+ * </Realm>
230
+ * </Realms>
231
+ * </Auth>
232
+ * <Netbird
233
+ * host="netbird.example.com"
234
+ * idp={{
235
+ * issuer: 'https://auth.example.com/realms/netbird',
236
+ * clientId: 'netbird',
237
+ * clientSecretRef: 'netbird-oidc',
238
+ * }}
239
+ * />
240
+ * </Platform>
241
+ * </S3Provider>
242
+ * )
243
+ */
244
+ export declare function Netbird(props: NetbirdProps): import("@r8s/core").r8sElement;
245
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,cAAc,CAAA;AAErB;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,gGAAgG;IAChG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;;;;;;;OAYG;IACH,GAAG,EAAE,eAAe,CAAA;IACpB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iHAAiH;IACjH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACxB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,sGAAsG;IACtG,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IAChC;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,wGAAwG;IACxG,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sTAAsT;IACtT,GAAG,CAAC,EAAE;QACJ,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkHG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,kCAwd1C"}
package/dist/index.js ADDED
@@ -0,0 +1,539 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Netbird = Netbird;
4
+ const core_1 = require("@r8s/core");
5
+ const defaults_1 = require("@r8s/core/defaults");
6
+ const recipes_1 = require("@r8s/recipes");
7
+ /**
8
+ * One env entry backed by a secretKeyRef (the chart's `envRaw` contract —
9
+ * structured valueFrom objects, the plaintext-free way to inject secrets).
10
+ */
11
+ function secretEnv(name, secretName, key) {
12
+ return {
13
+ name,
14
+ valueFrom: { secretKeyRef: { name: secretName, key } },
15
+ };
16
+ }
17
+ /**
18
+ * Netbird — WireGuard-based mesh VPN (management + signal + relay +
19
+ * dashboard behind one hostname), facit-aligned via the official chart.
20
+ *
21
+ * @title Netbird
22
+ * @category Networking
23
+ *
24
+ * The chart owns all app workloads (management/signal/relay/dashboard +
25
+ * their services and ingresses). This package owns the platform contract
26
+ * around it:
27
+ * - Flux `HelmRepository` + `HelmRelease` (pinned chart, facit values).
28
+ * netbirdio publishes packaged chart .tgz releases against a gh-pages
29
+ * Helm index (no OCI artifact exists) — a plain HelmRepository works.
30
+ * - external CNPG cluster (`credentialsMode: 'cnpg'`): the management
31
+ * store reads the DSN from the CNPG-generated `<db>-app` secret's
32
+ * `fqdn-uri` key via `management.envFromSecret` — the raw DSN never
33
+ * appears in rendered YAML beyond its secretKeyRef
34
+ * - management.json rendered into the chart's `management.configmap`
35
+ * with `{{ .VAR }}` env placeholders (netbird ≥ 0.30.1 substitutes
36
+ * them from process env — the chart's own IdP examples rely on it)
37
+ * - IdP credentials + relay secret + datastore encryption key via the
38
+ * Platform secrets backend (pre-created Secret references win)
39
+ * - cert-manager TLS on the dashboard catch-all ingress; the management/
40
+ * gRPC/signal/relay ingresses reference the same TLS secret
41
+ * - optional raw LoadBalancer face for the relay via `relayPort`
42
+ *
43
+ * Encoded decisions (do not "fix" these):
44
+ * - NO Stuns/TURNConfig entries: the chart deploys no coturn server and
45
+ * pointing peers at a dead `host:3478` is worse than none — peers
46
+ * connect via the relay (rels://host:443/relay); add an external
47
+ * STUN/TURN server if you need direct hairpin/wifi-less connectivity
48
+ * - `useBackwardsGrpcService: true` (the chart's own tested example):
49
+ * the management gRPC ingress routes to the dedicated 33073 listener
50
+ * - `persistentVolume.enabled: false` (facit: postgres-backed store —
51
+ * the docker-compose template also ships `"Datadir": ""` for postgres)
52
+ * - images pinned to the chart appVersion (0.46.0); chart 1.9.0's
53
+ * management.json schema matches that generation — bump together
54
+ *
55
+ * @example
56
+ * import { Platform, S3Provider, MinIO } from '@r8s/recipes'
57
+ * import { Netbird } from '@r8s/netbird'
58
+ *
59
+ * // CNPG backups derive from the S3Provider; the IdP client secret +
60
+ * // relay/datastore credentials provision from the openbao store
61
+ * export default (
62
+ * <S3Provider
63
+ * provider={
64
+ * <MinIO endpoint="https://rustfs:9000" bucket="infra" credentialsSecret="infra-s3-creds" />
65
+ * }
66
+ * >
67
+ * <Platform secrets={{ backend: 'openbao', mount: 'secret', path: 'apps' }}>
68
+ * <Netbird
69
+ * host="netbird.example.com"
70
+ * idp={{
71
+ * issuer: 'https://auth.example.com/realms/netbird',
72
+ * clientId: 'netbird',
73
+ * }}
74
+ * />
75
+ * </Platform>
76
+ * </S3Provider>
77
+ * )
78
+ *
79
+ * @example
80
+ * // Compose with the Auth recipe — realm-level group sync for policies
81
+ * import { Platform, S3Provider, MinIO, Auth } from '@r8s/recipes'
82
+ * import { Realms, Realm, Clients, Client } from '@r8s/recipes/auth'
83
+ * import { Netbird } from '@r8s/netbird'
84
+ *
85
+ * // groupsClaim puts Keycloak group memberships in the JWT `groups`
86
+ * // claim — Netbird auto-creates groups from it (map Netbird policies
87
+ * // to those groups). Netbird's group/user reads authenticate via
88
+ * // client_credentials — grant the netbird client's service account
89
+ * // realm-management view-users/view-groups; `netbird-manager` is the
90
+ * // upstream pattern for splitting those reads onto separate
91
+ * // credentials. localhost:53000 is the netbird CLI/desktop PKCE
92
+ * // redirect; the auth host gets TLS so the https issuer is reachable.
93
+ * export default (
94
+ * <S3Provider
95
+ * provider={
96
+ * <MinIO endpoint="https://rustfs:9000" bucket="infra" credentialsSecret="infra-s3-creds" />
97
+ * }
98
+ * >
99
+ * <Platform secrets={{ backend: 'openbao', mount: 'secret', path: 'apps' }}>
100
+ * <Auth
101
+ * name="auth"
102
+ * host="auth.example.com"
103
+ * tls={{ secretName: 'auth-tls', clusterIssuer: 'letsencrypt-prod' }}
104
+ * >
105
+ * <Realms>
106
+ * <Realm id="netbird" displayName="Netbird">
107
+ * <Clients>
108
+ * <Client
109
+ * id="netbird"
110
+ * type="confidential"
111
+ * redirectUris={['https://netbird.example.com/*', 'http://localhost:53000']}
112
+ * groupsClaim
113
+ * clientScopes={['api']}
114
+ * />
115
+ * <Client id="netbird-manager" type="confidential" />
116
+ * </Clients>
117
+ * </Realm>
118
+ * </Realms>
119
+ * </Auth>
120
+ * <Netbird
121
+ * host="netbird.example.com"
122
+ * idp={{
123
+ * issuer: 'https://auth.example.com/realms/netbird',
124
+ * clientId: 'netbird',
125
+ * clientSecretRef: 'netbird-oidc',
126
+ * }}
127
+ * />
128
+ * </Platform>
129
+ * </S3Provider>
130
+ * )
131
+ */
132
+ function Netbird(props) {
133
+ const { name = 'netbird', namespace: namespaceProp, host, idp, relayPort, chartVersion = '1.9.0', repoUrl = 'https://netbirdio.github.io/helms', repoNamespace = 'flux-system', imageTag = '0.46.0', storage, dbName = 'netbird-db', dbInstances = 2, dbStorage = '10Gi', dbStorageClass, backup, credentialsSecretName, userIdClaim = '', tls = { secretName: `${name}-tls`, clusterIssuer: 'letsencrypt-prod' }, } = props;
134
+ const namespace = (0, defaults_1.useNamespace)(namespaceProp);
135
+ const secretProvider = (0, core_1.useContext)(defaults_1.SecretContext);
136
+ const resources_ = [];
137
+ // --- IdP issuer (explicit, or derived from the Auth recipe's realm layout) ---
138
+ if (idp.issuer && (idp.realm || idp.host)) {
139
+ throw new Error(`Netbird "${name}": idp.issuer and idp.realm + idp.host are mutually exclusive.\n` +
140
+ `\n` +
141
+ `Both describe the same Keycloak OIDC issuer — mixing them is\n` +
142
+ `ambiguous about which realm actually backs the mesh.\n` +
143
+ `\n` +
144
+ `Fix: keep one form —\n` +
145
+ ` idp={{ issuer: 'https://auth.example.com/realms/netbird', ... }} or\n` +
146
+ ` idp={{ realm: 'netbird', host: 'auth.example.com', ... }}`);
147
+ }
148
+ if (!idp.issuer && !(idp.realm && idp.host)) {
149
+ throw new Error(`Netbird "${name}": the OIDC issuer is required — give idp.issuer, or\n` +
150
+ `idp.realm + idp.host to derive it as https://<host>/realms/<realm>\n` +
151
+ `(the Auth recipe's <Realm id=...> on the <Auth host>).\n` +
152
+ `\n` +
153
+ `Fix: idp={{ realm: 'netbird', host: 'auth.example.com', clientId: 'netbird' }}`);
154
+ }
155
+ const issuer = idp.issuer ??
156
+ `https://${idp.host.replace(/\/+$/, '')}/realms/${idp.realm.replace(/^\/+|\/+$/g, '')}`;
157
+ // --- Pinned-version policy ---------------------------------------------------
158
+ if (chartVersion === 'latest') {
159
+ throw new Error(`Netbird "${name}" requires a pinned chartVersion.\n` +
160
+ `\n` +
161
+ `A rejected floating chart breaks the pinned-images invariant (the\n` +
162
+ `chart's management.json template moves with its appVersion) and an\n` +
163
+ `untested upgrade can strand every peer.\n` +
164
+ `\n` +
165
+ `Fix: <Netbird chartVersion="1.9.0" ... /> (pin the imageTag to match)`);
166
+ }
167
+ if (imageTag === 'latest') {
168
+ throw new Error(`Netbird "${name}" requires a pinned imageTag.\n` +
169
+ `\n` +
170
+ `Chart ${chartVersion} renders management.json for its appVersion\n` +
171
+ `generation — floating netbird images can expect a different config\n` +
172
+ `shape on the next pull.\n` +
173
+ `\n` +
174
+ `Fix: <Netbird imageTag="0.46.0" ... /> (bump chart + images together)`);
175
+ }
176
+ if (storage !== undefined &&
177
+ storage !== false &&
178
+ // k8s quantity suffixes: binary (Ki/Mi/Gi/Ti/Pi/Ei) + decimal
179
+ // (k/M/G/T/P/E — note decimal kilo is LOWERCASE k; 'K' is invalid)
180
+ !/^\d+(\.\d+)?(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|k)$/.test(storage)) {
181
+ throw new Error(`Netbird "${name}": storage must be a Kubernetes (binary or decimal) quantity\n` +
182
+ `(e.g. '1Gi', '1G', '100M', '2.5Ti'), got "${storage}".`);
183
+ }
184
+ // --- IdP client secret (pre-created wins; else backend provisions) ----------
185
+ const oidcSecretName = idp.clientSecretRef ?? `${name}-oidc`;
186
+ if (!idp.clientSecretRef) {
187
+ if (!(0, recipes_1.canProvisionSecrets)(secretProvider)) {
188
+ throw (0, recipes_1.secretsRequiredError)('Netbird', name, 'the OIDC client secret for the Keycloak netbird client (key client-secret)', {
189
+ propName: 'idp.clientSecretRef',
190
+ exampleValue: `${name}-oidc`,
191
+ keys: ['client-secret'],
192
+ });
193
+ }
194
+ resources_.push((0, core_1.jsx)(recipes_1.StaticSecret, {
195
+ name: `${name}-oidc`,
196
+ namespace,
197
+ path: `${secretProvider.path ?? name}/${name}/oidc`,
198
+ secretName: oidcSecretName,
199
+ keys: { 'client-secret': 'client_secret' },
200
+ restart: [{ kind: 'Deployment', name: `${name}-management` }],
201
+ }));
202
+ }
203
+ // --- Relay secret + datastore encryption key bundle ---------------------------
204
+ const credentialsName = credentialsSecretName ?? `${name}-credentials`;
205
+ if (!credentialsSecretName) {
206
+ if (!(0, recipes_1.canProvisionSecrets)(secretProvider)) {
207
+ throw (0, recipes_1.secretsRequiredError)('Netbird', name, 'the relay auth secret + datastore encryption key (keys relay-secret, datastore-encryption-key)', {
208
+ propName: 'credentialsSecretName',
209
+ exampleValue: `${name}-credentials`,
210
+ keys: ['relay-secret', 'datastore-encryption-key'],
211
+ });
212
+ }
213
+ resources_.push((0, core_1.jsx)(recipes_1.StaticSecret, {
214
+ name: `${name}-credentials`,
215
+ namespace,
216
+ path: `${secretProvider.path ?? name}/${name}/credentials`,
217
+ secretName: credentialsName,
218
+ keys: {
219
+ 'relay-secret': 'relay_secret',
220
+ 'datastore-encryption-key': 'datastore_encryption_key',
221
+ },
222
+ restart: [
223
+ { kind: 'Deployment', name: `${name}-management` },
224
+ { kind: 'Deployment', name: `${name}-relay` },
225
+ ],
226
+ }));
227
+ }
228
+ // --- CNPG cluster (CNPG-managed credentials: the -app fqdn-uri is the DSN) ---
229
+ const dbCredentialsRef = (0, recipes_1.databaseCredentialsRef)(dbName, secretProvider, 'cnpg');
230
+ resources_.push((0, core_1.jsx)(recipes_1.Database, {
231
+ backup: backup ?? true,
232
+ name: dbName,
233
+ namespace,
234
+ database: 'netbird',
235
+ owner: 'netbird',
236
+ instances: dbInstances,
237
+ storage: dbStorage,
238
+ ...(dbStorageClass ? { storageClass: dbStorageClass } : {}),
239
+ parameters: {
240
+ shared_buffers: '128MB',
241
+ max_connections: '100',
242
+ },
243
+ credentialsMode: 'cnpg',
244
+ }));
245
+ // --- Derived identity endpoints (Keycloak realm layout) -----------------------
246
+ const jwks = `${issuer.replace(/\/$/, '')}/protocol/openid-connect/certs`;
247
+ const tokenEndpoint = `${issuer.replace(/\/$/, '')}/protocol/openid-connect/token`;
248
+ const oidcConfigEndpoint = `${issuer.replace(/\/$/, '')}/.well-known/openid-configuration`;
249
+ // management.json — {{ .VAR }} placeholders are substituted by the
250
+ // management binary from process env (netbird ≥ 0.30.1), the mechanism
251
+ // the chart's own IdP examples rely on. Secrets stay env-only: the
252
+ // rendered configmap carries placeholders, never values.
253
+ const managementConfig = JSON.stringify({
254
+ Stuns: [],
255
+ TURNConfig: {
256
+ Turns: [],
257
+ CredentialsTTL: '12h0m0s',
258
+ Secret: 'secret',
259
+ TimeBasedCredentials: false,
260
+ },
261
+ Relay: {
262
+ // The chart's relay ingress terminates TLS at host:443
263
+ Addresses: [`rels://${host}:443/relay`],
264
+ CredentialsTTL: '24h',
265
+ Secret: '{{ .RELAY_PASSWORD }}',
266
+ },
267
+ Signal: {
268
+ Proto: 'https',
269
+ URI: `${host}:443`,
270
+ Username: '',
271
+ Password: '',
272
+ },
273
+ ReverseProxy: {
274
+ TrustedHTTPProxies: null,
275
+ TrustedHTTPProxiesCount: 0,
276
+ TrustedPeers: null,
277
+ },
278
+ Datadir: '',
279
+ DataStoreEncryptionKey: '{{ .DATASTORE_ENCRYPTION_KEY }}',
280
+ StoreConfig: {
281
+ // external CNPG Postgres — the DSN travels via env only
282
+ Engine: 'postgres',
283
+ },
284
+ HttpConfig: {
285
+ LetsEncryptDomain: '',
286
+ CertFile: '',
287
+ CertKey: '',
288
+ AuthAudience: '{{ .IDP_CLIENT_ID }}',
289
+ AuthIssuer: '{{ .NETBIRD_AUTH_ISSUER }}',
290
+ AuthUserIDClaim: userIdClaim,
291
+ AuthKeysLocation: '{{ .NETBIRD_AUTH_JWT_CERTS }}',
292
+ IdpSignKeyRefreshEnabled: false,
293
+ OIDCConfigEndpoint: '{{ .NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT }}',
294
+ },
295
+ IdpManagerConfig: {
296
+ ManagerType: 'keycloak',
297
+ ClientConfig: {
298
+ Issuer: '{{ .NETBIRD_AUTH_ISSUER }}',
299
+ TokenEndpoint: '{{ .NETBIRD_AUTH_TOKEN_ENDPOINT }}',
300
+ ClientID: '{{ .IDP_CLIENT_ID }}',
301
+ ClientSecret: '{{ .IDP_CLIENT_SECRET }}',
302
+ GrantType: 'client_credentials',
303
+ },
304
+ KeycloakClientCredentials: {
305
+ ClientID: '{{ .IDP_CLIENT_ID }}',
306
+ ClientSecret: '{{ .IDP_CLIENT_SECRET }}',
307
+ GrantType: 'client_credentials',
308
+ },
309
+ ExtraConfig: null,
310
+ Auth0ClientCredentials: null,
311
+ AzureClientCredentials: null,
312
+ ZitadelClientCredentials: null,
313
+ },
314
+ DeviceAuthorizationFlow: {
315
+ Provider: 'hosted',
316
+ ProviderConfig: {
317
+ ClientID: '{{ .IDP_CLIENT_ID }}',
318
+ ClientSecret: '',
319
+ Domain: '',
320
+ Audience: '{{ .IDP_CLIENT_ID }}',
321
+ TokenEndpoint: '{{ .NETBIRD_AUTH_TOKEN_ENDPOINT }}',
322
+ DeviceAuthEndpoint: `${issuer.replace(/\/$/, '')}/protocol/openid-connect/auth/device`,
323
+ AuthorizationEndpoint: '',
324
+ Scope: 'openid',
325
+ UseIDToken: false,
326
+ RedirectURLs: null,
327
+ },
328
+ },
329
+ PKCEAuthorizationFlow: {
330
+ Provider: 'hosted',
331
+ ProviderConfig: {
332
+ ClientID: '{{ .IDP_CLIENT_ID }}',
333
+ ClientSecret: '{{ .IDP_CLIENT_SECRET }}',
334
+ Domain: '',
335
+ Audience: '{{ .IDP_CLIENT_ID }}',
336
+ TokenEndpoint: '{{ .NETBIRD_AUTH_TOKEN_ENDPOINT }}',
337
+ DeviceAuthEndpoint: '',
338
+ AuthorizationEndpoint: `${issuer.replace(/\/$/, '')}/protocol/openid-connect/auth`,
339
+ Scope: 'openid profile email offline_access api',
340
+ UseIDToken: false,
341
+ DisablePromptLogin: true,
342
+ // netbird ≥ 0.44 models LoginFlag as common.LoginFlag (uint8 enum:
343
+ // 0 = LoginFlagPrompt, 1 = LoginFlagMaxAge0; no custom
344
+ // UnmarshalJSON) — management 0.46.0 rejects a raw bool at
345
+ // config parse ("cannot unmarshal bool into Go struct field
346
+ // ... LoginFlag of type common.LoginFlag"). 0 (LoginFlagPrompt)
347
+ // is the Go zero value and behavior-neutral behind
348
+ // DisablePromptLogin: only consumed in client/internal/auth/
349
+ // pkce_flow.go when DisablePromptLogin is false.
350
+ LoginFlag: 0,
351
+ RedirectURLs: ['http://localhost:53000'],
352
+ },
353
+ },
354
+ }, null, ' ');
355
+ // --- Common ingress config -----------------------------------------------------
356
+ const grpcTimeouts = {
357
+ 'nginx.ingress.kubernetes.io/backend-protocol': 'GRPC',
358
+ 'nginx.ingress.kubernetes.io/ssl-redirect': 'true',
359
+ 'nginx.ingress.kubernetes.io/proxy-read-timeout': '3600',
360
+ 'nginx.ingress.kubernetes.io/proxy-send-timeout': '3600',
361
+ };
362
+ const tlsEntry = [{ secretName: tls.secretName, hosts: [host] }];
363
+ // --- Flux: HelmRepository + HelmRelease (facit values, decisions encoded) ------
364
+ resources_.push((0, core_1.jsx)('HelmRepository', {
365
+ apiVersion: 'source.toolkit.fluxcd.io/v1',
366
+ kind: 'HelmRepository',
367
+ metadata: { name, namespace: repoNamespace },
368
+ spec: { interval: '24h', url: repoUrl },
369
+ }), (0, core_1.jsx)('HelmRelease', {
370
+ apiVersion: 'helm.toolkit.fluxcd.io/v2',
371
+ kind: 'HelmRelease',
372
+ metadata: { name, namespace },
373
+ spec: {
374
+ interval: '30m',
375
+ chart: {
376
+ spec: {
377
+ chart: 'netbird',
378
+ version: chartVersion,
379
+ sourceRef: { kind: 'HelmRepository', name, namespace: repoNamespace },
380
+ interval: '12h',
381
+ },
382
+ },
383
+ values: {
384
+ management: {
385
+ ...(storage
386
+ ? {
387
+ persistentVolume: {
388
+ enabled: true,
389
+ size: storage,
390
+ accessModes: ['ReadWriteOnce'],
391
+ },
392
+ }
393
+ : { persistentVolume: { enabled: false } }),
394
+ useBackwardsGrpcService: true,
395
+ // The dashboard catch-all carries the cert-manager annotation —
396
+ // one Certificate for the host; the remaining ingresses only
397
+ // reference the same secret (5 identical LE orders = at the
398
+ // duplicate-cert rate limit the chart's tested example dodges)
399
+ ingress: {
400
+ enabled: true,
401
+ className: 'nginx',
402
+ annotations: {
403
+ 'external-dns.alpha.kubernetes.io/hostname': host,
404
+ },
405
+ hosts: [{ host, paths: [{ path: '/api', pathType: 'ImplementationSpecific' }] }],
406
+ tls: tlsEntry,
407
+ },
408
+ ingressGrpc: {
409
+ enabled: true,
410
+ className: 'nginx',
411
+ annotations: {
412
+ ...grpcTimeouts,
413
+ 'external-dns.alpha.kubernetes.io/hostname': host,
414
+ },
415
+ hosts: [
416
+ {
417
+ host,
418
+ paths: [
419
+ { path: '/management.ManagementService', pathType: 'ImplementationSpecific' },
420
+ ],
421
+ },
422
+ ],
423
+ tls: tlsEntry,
424
+ },
425
+ configmap: managementConfig,
426
+ env: {
427
+ NETBIRD_DOMAIN: host,
428
+ NETBIRD_AUTH_ISSUER: issuer,
429
+ NETBIRD_AUTH_JWT_CERTS: jwks,
430
+ NETBIRD_AUTH_TOKEN_ENDPOINT: tokenEndpoint,
431
+ NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT: oidcConfigEndpoint,
432
+ IDP_CLIENT_ID: idp.clientId,
433
+ },
434
+ // envRaw = the chart's structured-var block (standard
435
+ // valueFrom.secretKeyRef contract — the DSN and every secret
436
+ // value stays reference-only, never a rendered literal)
437
+ envRaw: [
438
+ secretEnv('IDP_CLIENT_SECRET', oidcSecretName, 'client-secret'),
439
+ secretEnv('DATASTORE_ENCRYPTION_KEY', credentialsName, 'datastore-encryption-key'),
440
+ secretEnv('RELAY_PASSWORD', credentialsName, 'relay-secret'),
441
+ // CNPG generates <db>-app incl. the full fqdn-uri DSN —
442
+ // netbird's postgres store reads it via this env var
443
+ secretEnv('NETBIRD_STORE_ENGINE_POSTGRES_DSN', dbCredentialsRef.name, 'fqdn-uri'),
444
+ ],
445
+ image: {
446
+ repository: 'netbirdio/management',
447
+ tag: imageTag,
448
+ pullPolicy: 'IfNotPresent',
449
+ },
450
+ },
451
+ signal: {
452
+ enabled: true,
453
+ ingress: {
454
+ enabled: true,
455
+ className: 'nginx',
456
+ annotations: {
457
+ ...grpcTimeouts,
458
+ 'external-dns.alpha.kubernetes.io/hostname': host,
459
+ },
460
+ hosts: [
461
+ {
462
+ host,
463
+ paths: [
464
+ {
465
+ path: '/signalexchange.SignalExchange',
466
+ pathType: 'ImplementationSpecific',
467
+ },
468
+ ],
469
+ },
470
+ ],
471
+ tls: tlsEntry,
472
+ },
473
+ image: {
474
+ repository: 'netbirdio/signal',
475
+ tag: imageTag,
476
+ pullPolicy: 'IfNotPresent',
477
+ },
478
+ },
479
+ relay: {
480
+ enabled: true,
481
+ env: {
482
+ NB_LOG_LEVEL: 'info',
483
+ NB_LISTEN_ADDRESS: ':33080',
484
+ NB_EXPOSED_ADDRESS: `rels://${host}:443/relay`,
485
+ },
486
+ envRaw: [secretEnv('NB_AUTH_SECRET', credentialsName, 'relay-secret')],
487
+ ...(relayPort
488
+ ? { service: { type: 'LoadBalancer', port: relayPort, name: 'http' } }
489
+ : {}),
490
+ ingress: {
491
+ enabled: true,
492
+ className: 'nginx',
493
+ annotations: {
494
+ 'external-dns.alpha.kubernetes.io/hostname': host,
495
+ },
496
+ hosts: [{ host, paths: [{ path: '/relay', pathType: 'ImplementationSpecific' }] }],
497
+ tls: tlsEntry,
498
+ },
499
+ image: {
500
+ repository: 'netbirdio/relay',
501
+ tag: imageTag,
502
+ pullPolicy: 'IfNotPresent',
503
+ },
504
+ },
505
+ dashboard: {
506
+ enabled: true,
507
+ ingress: {
508
+ enabled: true,
509
+ className: 'nginx',
510
+ annotations: {
511
+ // Sole cert-manager annotation — the shared secret's issuer
512
+ 'cert-manager.io/cluster-issuer': tls.clusterIssuer,
513
+ 'external-dns.alpha.kubernetes.io/hostname': host,
514
+ },
515
+ hosts: [{ host, paths: [{ path: '/', pathType: 'ImplementationSpecific' }] }],
516
+ tls: tlsEntry,
517
+ },
518
+ env: {
519
+ NETBIRD_MGMT_API_ENDPOINT: `https://${host}`,
520
+ NETBIRD_MGMT_GRPC_API_ENDPOINT: `https://${host}`,
521
+ AUTH_AUTHORITY: issuer,
522
+ AUTH_CLIENT_ID: idp.clientId,
523
+ AUTH_AUDIENCE: idp.clientId,
524
+ AUTH_SUPPORTED_SCOPES: 'openid profile email offline_access api',
525
+ NETBIRD_TOKEN_SOURCE: 'accessToken',
526
+ USE_AUTH0: 'false',
527
+ },
528
+ image: {
529
+ repository: 'netbirdio/dashboard',
530
+ tag: 'v2.13.1',
531
+ pullPolicy: 'IfNotPresent',
532
+ },
533
+ },
534
+ },
535
+ },
536
+ }));
537
+ return (0, core_1.jsx)(core_1.Fragment, { children: resources_ });
538
+ }
539
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@r8s/netbird",
3
+ "version": "0.3.4",
4
+ "description": "Netbird mesh VPN (management + signal + relay + dashboard) — Flux HelmRelease, CNPG persistence, Keycloak IdP for r8s",
5
+ "license": "MIT",
6
+ "author": "Berget AI AB",
7
+ "homepage": "https://r8s.berget.ai",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/berget-ai/r8s.git",
11
+ "directory": "packages/netbird"
12
+ },
13
+ "bugs": "https://github.com/berget-ai/r8s/issues",
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "keywords": [
21
+ "netbird",
22
+ "vpn",
23
+ "mesh",
24
+ "wireguard",
25
+ "networking"
26
+ ],
27
+ "r8s": {
28
+ "category": "Networking"
29
+ },
30
+ "main": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "scripts": {
33
+ "build": "tsc --build",
34
+ "test": "vitest run",
35
+ "clean": "rm -rf dist tsconfig.tsbuildinfo"
36
+ },
37
+ "dependencies": {
38
+ "@r8s/core": "^0.3.0",
39
+ "@r8s/crds": "^0.3.0",
40
+ "@r8s/k8s-types": "^0.3.0",
41
+ "@r8s/recipes": "^0.3.0"
42
+ },
43
+ "devDependencies": {
44
+ "typescript": "^5.3.0",
45
+ "vitest": "^1.0.0"
46
+ }
47
+ }