stuff
This commit is contained in:
@@ -14,16 +14,18 @@
|
||||
".": "./dist/exports.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@morten-olsen/box-configs": "workspace:*",
|
||||
"@morten-olsen/box-tests": "workspace:*",
|
||||
"@types/node": "catalog:",
|
||||
"@vitest/coverage-v8": "catalog:",
|
||||
"tsx": "^4.20.6",
|
||||
"typescript": "catalog:",
|
||||
"vitest": "catalog:",
|
||||
"@morten-olsen/box-configs": "workspace:*",
|
||||
"@morten-olsen/box-tests": "workspace:*"
|
||||
"vitest": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@morten-olsen/box-k8s": "workspace:*",
|
||||
"@morten-olsen/box-utils": "workspace:*"
|
||||
},
|
||||
"name": "@morten-olsen/box-bootstrap",
|
||||
"version": "1.0.0",
|
||||
"imports": {
|
||||
"#root/*": "./src/*"
|
||||
}
|
||||
"version": "1.0.0"
|
||||
}
|
||||
|
||||
35
packages/bootstrap/src/bootstrap.ts
Normal file
35
packages/bootstrap/src/bootstrap.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { Services } from '@morten-olsen/box-utils/services';
|
||||
import { HelmRelease, HelmRepo, Namespace, ResourceService } from '@morten-olsen/box-k8s';
|
||||
|
||||
import { NamespaceService } from './namespaces/namespaces.js';
|
||||
import { ReleaseService } from './releases/releases.js';
|
||||
import { RepoService } from './repos/repos.js';
|
||||
|
||||
class BootstrapService {
|
||||
#services: Services;
|
||||
|
||||
constructor(services: Services) {
|
||||
this.#services = services;
|
||||
}
|
||||
public get namespaces() {
|
||||
return this.#services.get(NamespaceService);
|
||||
}
|
||||
|
||||
public get repos() {
|
||||
return this.#services.get(RepoService);
|
||||
}
|
||||
|
||||
public get releases() {
|
||||
return this.#services.get(ReleaseService);
|
||||
}
|
||||
|
||||
public ensure = async () => {
|
||||
const resourceService = this.#services.get(ResourceService);
|
||||
await resourceService.register(Namespace, HelmRepo, HelmRelease);
|
||||
await this.namespaces.ensure();
|
||||
await this.repos.ensure();
|
||||
await this.releases.ensure();
|
||||
};
|
||||
}
|
||||
|
||||
export { BootstrapService };
|
||||
@@ -0,0 +1 @@
|
||||
export { BootstrapService } from './bootstrap.js';
|
||||
|
||||
45
packages/bootstrap/src/namespaces/namespaces.ts
Normal file
45
packages/bootstrap/src/namespaces/namespaces.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Namespace, ResourceService } from '@morten-olsen/box-k8s';
|
||||
import type { Services } from '@morten-olsen/box-utils/services';
|
||||
|
||||
import { NAMESPACE } from '../utils/consts.js';
|
||||
|
||||
class NamespaceService {
|
||||
#homelab: Namespace;
|
||||
#istioSystem: Namespace;
|
||||
#certManager: Namespace;
|
||||
|
||||
constructor(services: Services) {
|
||||
const resourceService = services.get(ResourceService);
|
||||
this.#homelab = resourceService.get(Namespace, NAMESPACE);
|
||||
this.#istioSystem = resourceService.get(Namespace, 'istio-system');
|
||||
this.#certManager = resourceService.get(Namespace, 'cert-manager');
|
||||
|
||||
this.#homelab.on('changed', this.ensure);
|
||||
this.#istioSystem.on('changed', this.ensure);
|
||||
this.#certManager.on('changed', this.ensure);
|
||||
}
|
||||
|
||||
public get homelab() {
|
||||
return this.#homelab;
|
||||
}
|
||||
public get istioSystem() {
|
||||
return this.#istioSystem;
|
||||
}
|
||||
public get certManager() {
|
||||
return this.#certManager;
|
||||
}
|
||||
|
||||
public ensure = async () => {
|
||||
await this.#homelab.ensure({
|
||||
metadata: {
|
||||
labels: {
|
||||
'istio-injection': 'enabled',
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.#istioSystem.ensure({});
|
||||
await this.#certManager.ensure({});
|
||||
};
|
||||
}
|
||||
|
||||
export { NamespaceService };
|
||||
210
packages/bootstrap/src/releases/releases.ts
Normal file
210
packages/bootstrap/src/releases/releases.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
import type { Services } from '@morten-olsen/box-utils/services';
|
||||
import { HelmRelease, ResourceService } from '@morten-olsen/box-k8s';
|
||||
|
||||
import { NamespaceService } from '../namespaces/namespaces.js';
|
||||
import { RepoService } from '../repos/repos.js';
|
||||
import { NAMESPACE } from '../utils/consts.js';
|
||||
|
||||
class ReleaseService {
|
||||
#services: Services;
|
||||
#certManager: HelmRelease;
|
||||
#istioBase: HelmRelease;
|
||||
#istiod: HelmRelease;
|
||||
#istioGateway: HelmRelease;
|
||||
#trivy: HelmRelease;
|
||||
#kyverno: HelmRelease;
|
||||
#cloudnativepg: HelmRelease;
|
||||
|
||||
constructor(services: Services) {
|
||||
this.#services = services;
|
||||
const resourceService = services.get(ResourceService);
|
||||
this.#certManager = resourceService.get(HelmRelease, 'cert-manager', NAMESPACE);
|
||||
this.#istioBase = resourceService.get(HelmRelease, 'istio-base', NAMESPACE);
|
||||
this.#istiod = resourceService.get(HelmRelease, 'istiod', NAMESPACE);
|
||||
this.#istioGateway = resourceService.get(HelmRelease, 'istio-gateway', NAMESPACE);
|
||||
this.#trivy = resourceService.get(HelmRelease, 'trivy', NAMESPACE);
|
||||
this.#kyverno = resourceService.get(HelmRelease, 'kyverno', NAMESPACE);
|
||||
this.#cloudnativepg = resourceService.get(HelmRelease, 'cloudnative-pg', NAMESPACE);
|
||||
|
||||
this.#certManager.on('changed', this.ensure);
|
||||
this.#istioBase.on('changed', this.ensure);
|
||||
this.#istiod.on('changed', this.ensure);
|
||||
this.#istioGateway.on('changed', this.ensure);
|
||||
this.#trivy.on('changed', this.ensure);
|
||||
this.#kyverno.on('changed', this.ensure);
|
||||
this.#cloudnativepg.on('changed', this.ensure);
|
||||
}
|
||||
|
||||
public get certManager() {
|
||||
return this.#certManager;
|
||||
}
|
||||
|
||||
public get istioBase() {
|
||||
return this.#istioBase;
|
||||
}
|
||||
|
||||
public get istiod() {
|
||||
return this.#istiod;
|
||||
}
|
||||
|
||||
public get trivy() {
|
||||
return this.#trivy;
|
||||
}
|
||||
|
||||
public get kyverno() {
|
||||
return this.#kyverno;
|
||||
}
|
||||
|
||||
public get cloudnativepg() {
|
||||
return this.#cloudnativepg;
|
||||
}
|
||||
|
||||
public ensure = async () => {
|
||||
const namespaceService = this.#services.get(NamespaceService);
|
||||
const repoService = this.#services.get(RepoService);
|
||||
await this.#certManager.ensure({
|
||||
spec: {
|
||||
targetNamespace: namespaceService.certManager.name,
|
||||
interval: '1h',
|
||||
values: {
|
||||
installCRDs: true,
|
||||
},
|
||||
chart: {
|
||||
spec: {
|
||||
chart: 'cert-manager',
|
||||
sourceRef: {
|
||||
apiVersion: 'source.toolkit.fluxcd.io/v1',
|
||||
kind: 'HelmRepository',
|
||||
name: repoService.jetstack.name,
|
||||
namespace: repoService.jetstack.namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.#istioBase.ensure({
|
||||
spec: {
|
||||
targetNamespace: namespaceService.istioSystem.name,
|
||||
interval: '1h',
|
||||
values: {
|
||||
defaultRevision: 'default',
|
||||
profile: 'ambient',
|
||||
},
|
||||
chart: {
|
||||
spec: {
|
||||
chart: 'base',
|
||||
sourceRef: {
|
||||
apiVersion: 'source.toolkit.fluxcd.io/v1',
|
||||
kind: 'HelmRepository',
|
||||
name: repoService.istio.name,
|
||||
namespace: repoService.istio.namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.#istiod.ensure({
|
||||
spec: {
|
||||
targetNamespace: namespaceService.istioSystem.name,
|
||||
interval: '1h',
|
||||
dependsOn: [
|
||||
{
|
||||
name: this.#istioBase.name,
|
||||
namespace: this.#istioBase.namespace,
|
||||
},
|
||||
],
|
||||
chart: {
|
||||
spec: {
|
||||
chart: 'istiod',
|
||||
sourceRef: {
|
||||
apiVersion: 'source.toolkit.fluxcd.io/v1',
|
||||
kind: 'HelmRepository',
|
||||
name: repoService.istio.name,
|
||||
namespace: repoService.istio.namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.#istioGateway.ensure({
|
||||
spec: {
|
||||
targetNamespace: NAMESPACE,
|
||||
interval: '1h',
|
||||
dependsOn: [
|
||||
{
|
||||
name: this.#istioBase.name,
|
||||
namespace: this.#istioBase.namespace,
|
||||
},
|
||||
{
|
||||
name: this.#istiod.name,
|
||||
namespace: this.#istiod.namespace,
|
||||
},
|
||||
],
|
||||
chart: {
|
||||
spec: {
|
||||
chart: 'gateway',
|
||||
sourceRef: {
|
||||
apiVersion: 'source.toolkit.fluxcd.io/v1',
|
||||
kind: 'HelmRepository',
|
||||
name: repoService.istio.name,
|
||||
namespace: repoService.istio.namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.#trivy.ensure({
|
||||
spec: {
|
||||
targetNamespace: NAMESPACE,
|
||||
interval: '1h',
|
||||
chart: {
|
||||
spec: {
|
||||
chart: 'trivy-operator',
|
||||
sourceRef: {
|
||||
apiVersion: 'source.toolkit.fluxcd.io/v1',
|
||||
kind: 'HelmRepository',
|
||||
name: repoService.aqua.name,
|
||||
namespace: repoService.aqua.namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.#kyverno.ensure({
|
||||
spec: {
|
||||
targetNamespace: NAMESPACE,
|
||||
interval: '1h',
|
||||
chart: {
|
||||
spec: {
|
||||
chart: 'kyverno',
|
||||
sourceRef: {
|
||||
apiVersion: 'source.toolkit.fluxcd.io/v1',
|
||||
kind: 'HelmRepository',
|
||||
name: repoService.kyverno.name,
|
||||
namespace: repoService.kyverno.namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.#cloudnativepg.ensure({
|
||||
spec: {
|
||||
targetNamespace: NAMESPACE,
|
||||
interval: '1h',
|
||||
chart: {
|
||||
spec: {
|
||||
chart: 'cloudnative-pg',
|
||||
sourceRef: {
|
||||
apiVersion: 'source.toolkit.fluxcd.io/v1',
|
||||
kind: 'HelmRepository',
|
||||
name: repoService.cloudnativepg.name,
|
||||
namespace: repoService.cloudnativepg.namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export { ReleaseService };
|
||||
104
packages/bootstrap/src/repos/repos.ts
Normal file
104
packages/bootstrap/src/repos/repos.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import type { Services } from '@morten-olsen/box-utils/services';
|
||||
import { HelmRepo, ResourceService } from '@morten-olsen/box-k8s';
|
||||
|
||||
import { NAMESPACE } from '../utils/consts.js';
|
||||
|
||||
class RepoService {
|
||||
#jetstack: HelmRepo;
|
||||
#istio: HelmRepo;
|
||||
#authentik: HelmRepo;
|
||||
#cloudflare: HelmRepo;
|
||||
#argo: HelmRepo;
|
||||
#aqua: HelmRepo;
|
||||
#kyverno: HelmRepo;
|
||||
#cloudnativepg: HelmRepo;
|
||||
|
||||
constructor(services: Services) {
|
||||
const resourceService = services.get(ResourceService);
|
||||
this.#jetstack = resourceService.get(HelmRepo, 'jetstack', NAMESPACE);
|
||||
this.#istio = resourceService.get(HelmRepo, 'istio', NAMESPACE);
|
||||
this.#authentik = resourceService.get(HelmRepo, 'authentik', NAMESPACE);
|
||||
this.#cloudflare = resourceService.get(HelmRepo, 'cloudflare', NAMESPACE);
|
||||
this.#argo = resourceService.get(HelmRepo, 'argo', NAMESPACE);
|
||||
this.#aqua = resourceService.get(HelmRepo, 'aqua', NAMESPACE);
|
||||
this.#kyverno = resourceService.get(HelmRepo, 'kyverno', NAMESPACE);
|
||||
this.#cloudnativepg = resourceService.get(HelmRepo, 'cloudnative-pg', NAMESPACE);
|
||||
|
||||
this.#jetstack.on('changed', this.ensure);
|
||||
this.#istio.on('changed', this.ensure);
|
||||
this.#authentik.on('changed', this.ensure);
|
||||
this.#cloudflare.on('changed', this.ensure);
|
||||
this.#argo.on('changed', this.ensure);
|
||||
this.#aqua.on('changed', this.ensure);
|
||||
this.#kyverno.on('changed', this.ensure);
|
||||
this.#cloudnativepg.on('changed', this.ensure);
|
||||
}
|
||||
|
||||
public get jetstack() {
|
||||
return this.#jetstack;
|
||||
}
|
||||
|
||||
public get istio() {
|
||||
return this.#istio;
|
||||
}
|
||||
|
||||
public get authentik() {
|
||||
return this.#authentik;
|
||||
}
|
||||
|
||||
public get cloudflare() {
|
||||
return this.#cloudflare;
|
||||
}
|
||||
|
||||
public get argo() {
|
||||
return this.#argo;
|
||||
}
|
||||
|
||||
public get aqua() {
|
||||
return this.#aqua;
|
||||
}
|
||||
|
||||
public get kyverno() {
|
||||
return this.#kyverno;
|
||||
}
|
||||
|
||||
public get cloudnativepg() {
|
||||
return this.#cloudnativepg;
|
||||
}
|
||||
|
||||
public ensure = async () => {
|
||||
await this.#jetstack.set({
|
||||
url: 'https://charts.jetstack.io',
|
||||
});
|
||||
|
||||
await this.#istio.set({
|
||||
url: 'https://istio-release.storage.googleapis.com/charts',
|
||||
});
|
||||
|
||||
await this.#authentik.set({
|
||||
url: 'https://charts.goauthentik.io',
|
||||
});
|
||||
|
||||
await this.#cloudflare.set({
|
||||
url: 'https://cloudflare.github.io/helm-charts',
|
||||
});
|
||||
|
||||
await this.#argo.set({
|
||||
url: 'https://argoproj.github.io/argo-helm',
|
||||
});
|
||||
|
||||
await this.#aqua.set({
|
||||
url: 'https://aquasecurity.github.io/helm-charts/',
|
||||
});
|
||||
|
||||
await this.#kyverno.set({
|
||||
url: 'https://kyverno.github.io/kyverno/',
|
||||
});
|
||||
|
||||
await this.#cloudnativepg.set({
|
||||
url: 'https://cloudnative-pg.github.io/charts',
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export { RepoService };
|
||||
7
packages/bootstrap/src/start.ts
Normal file
7
packages/bootstrap/src/start.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Services } from '@morten-olsen/box-utils/services';
|
||||
|
||||
import { BootstrapService } from './bootstrap.js';
|
||||
|
||||
const services = new Services();
|
||||
const bootstrap = services.get(BootstrapService);
|
||||
await bootstrap.ensure();
|
||||
3
packages/bootstrap/src/utils/consts.ts
Normal file
3
packages/bootstrap/src/utils/consts.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
const NAMESPACE = 'homelab';
|
||||
|
||||
export { NAMESPACE };
|
||||
Reference in New Issue
Block a user