@r8s/r8s-controller 0.1.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 +43 -0
- package/dist/controller.d.ts +11 -0
- package/dist/controller.d.ts.map +1 -0
- package/dist/controller.js +138 -0
- package/dist/controller.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# r8s-controller
|
|
2
|
+
|
|
3
|
+
Kubernetes-native controller for r8s. Renders TSX to YAML in-cluster.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────┐ ┌─────────────────┐ ┌─────────────┐
|
|
9
|
+
│ Git Repo │────▶│ r8s-controller │────▶│ Kubernetes │
|
|
10
|
+
│ (r8s.tsx) │ │ (renders YAML) │ │ (applied) │
|
|
11
|
+
└─────────────┘ └─────────────────┘ └─────────────┘
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
kubectl apply -f config/crd.yaml
|
|
18
|
+
kubectl apply -f config/deploy.yaml
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
apiVersion: r8s.berget.ai/v1
|
|
25
|
+
kind: R8sSource
|
|
26
|
+
metadata:
|
|
27
|
+
name: my-app
|
|
28
|
+
namespace: default
|
|
29
|
+
spec:
|
|
30
|
+
git:
|
|
31
|
+
url: https://github.com/my-org/my-app
|
|
32
|
+
ref: main
|
|
33
|
+
entry: k8s/r8s.tsx
|
|
34
|
+
includeOperators: false
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Status
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
kubectl get r8ssource
|
|
41
|
+
# NAME READY REVISION RESOURCES AGE
|
|
42
|
+
# my-app True main 12 5m
|
|
43
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class R8sController {
|
|
2
|
+
private k8sApi;
|
|
3
|
+
private watch;
|
|
4
|
+
private namespace;
|
|
5
|
+
constructor(namespace?: string);
|
|
6
|
+
start(): Promise<void>;
|
|
7
|
+
private handleEvent;
|
|
8
|
+
private reconcile;
|
|
9
|
+
private updateStatus;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"AA2CA,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAAO;IACpB,OAAO,CAAC,SAAS,CAAQ;gBAEb,SAAS,SAAY;IAQ3B,KAAK;YAmBG,WAAW;YAeX,SAAS;YA0FT,YAAY;CAkB3B"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { KubeConfig, CustomObjectsApi, Watch } from '@kubernetes/client-node';
|
|
2
|
+
import { renderToYaml } from '@r8s/cli/src/renderer.js';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { mkdtempSync, writeFileSync, mkdirSync, rmSync } from 'fs';
|
|
5
|
+
import { tmpdir } from 'os';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
const GROUP = 'r8s.berget.ai';
|
|
8
|
+
const VERSION = 'v1';
|
|
9
|
+
const PLURAL = 'r8ssources';
|
|
10
|
+
export class R8sController {
|
|
11
|
+
k8sApi;
|
|
12
|
+
watch;
|
|
13
|
+
namespace;
|
|
14
|
+
constructor(namespace = 'default') {
|
|
15
|
+
const kc = new KubeConfig();
|
|
16
|
+
kc.loadFromDefault();
|
|
17
|
+
this.k8sApi = kc.makeApiClient(CustomObjectsApi);
|
|
18
|
+
this.watch = new Watch(kc);
|
|
19
|
+
this.namespace = namespace;
|
|
20
|
+
}
|
|
21
|
+
async start() {
|
|
22
|
+
console.log('[r8s-controller] Starting...');
|
|
23
|
+
console.log(`[r8s-controller] Watching ${PLURAL} in namespace ${this.namespace}`);
|
|
24
|
+
// Watch for R8sSource changes
|
|
25
|
+
await this.watch.watch(`/apis/${GROUP}/${VERSION}/namespaces/${this.namespace}/${PLURAL}`, {}, (type, obj) => {
|
|
26
|
+
this.handleEvent(type, obj);
|
|
27
|
+
}, (err) => {
|
|
28
|
+
console.error('[r8s-controller] Watch error:', err);
|
|
29
|
+
// Restart watch after error
|
|
30
|
+
setTimeout(() => this.start(), 5000);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async handleEvent(type, obj) {
|
|
34
|
+
if (type === 'DELETED') {
|
|
35
|
+
console.log(`[r8s-controller] Deleted: ${obj.metadata?.name}`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (obj.spec.suspend) {
|
|
39
|
+
console.log(`[r8s-controller] Suspended: ${obj.metadata?.name}`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log(`[r8s-controller] Reconciling: ${obj.metadata?.name}`);
|
|
43
|
+
await this.reconcile(obj);
|
|
44
|
+
}
|
|
45
|
+
async reconcile(obj) {
|
|
46
|
+
const name = obj.metadata?.name || 'unknown';
|
|
47
|
+
const namespace = obj.metadata?.namespace || 'default';
|
|
48
|
+
const generation = obj.metadata?.generation || 0;
|
|
49
|
+
try {
|
|
50
|
+
// Update status to Progressing
|
|
51
|
+
await this.updateStatus(name, namespace, {
|
|
52
|
+
observedGeneration: generation,
|
|
53
|
+
conditions: [
|
|
54
|
+
{
|
|
55
|
+
type: 'Ready',
|
|
56
|
+
status: 'Unknown',
|
|
57
|
+
reason: 'Progressing',
|
|
58
|
+
message: 'Reconciliation in progress',
|
|
59
|
+
lastTransitionTime: new Date().toISOString(),
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
// 1. Clone repo
|
|
64
|
+
const tmpDir = mkdtempSync(join(tmpdir(), 'r8s-'));
|
|
65
|
+
const repoUrl = obj.spec.git.url;
|
|
66
|
+
const ref = obj.spec.git.ref || 'main';
|
|
67
|
+
console.log(`[r8s-controller] Cloning ${repoUrl}@${ref}`);
|
|
68
|
+
execSync(`git clone --depth 1 --branch ${ref} ${repoUrl} ${tmpDir}`, {
|
|
69
|
+
timeout: 60000,
|
|
70
|
+
});
|
|
71
|
+
// 2. Render TSX → YAML
|
|
72
|
+
const entryPath = join(tmpDir, obj.spec.entry || 'k8s/r8s.tsx');
|
|
73
|
+
const outputDir = join(tmpDir, obj.spec.output || 'rendered/');
|
|
74
|
+
mkdirSync(outputDir, { recursive: true });
|
|
75
|
+
console.log(`[r8s-controller] Rendering ${entryPath}`);
|
|
76
|
+
const yaml = await renderToYaml(entryPath, {
|
|
77
|
+
includeOperators: obj.spec.includeOperators,
|
|
78
|
+
});
|
|
79
|
+
const outputFile = join(outputDir, 'manifest.yaml');
|
|
80
|
+
writeFileSync(outputFile, yaml);
|
|
81
|
+
// 3. Apply with kubectl
|
|
82
|
+
console.log(`[r8s-controller] Applying ${outputFile}`);
|
|
83
|
+
execSync(`kubectl apply -f ${outputFile} --server-side`, {
|
|
84
|
+
timeout: 60000,
|
|
85
|
+
});
|
|
86
|
+
// 4. Count resources
|
|
87
|
+
const resourceCount = yaml.split('---').length - 1;
|
|
88
|
+
// 5. Update status to Ready
|
|
89
|
+
await this.updateStatus(name, namespace, {
|
|
90
|
+
observedGeneration: generation,
|
|
91
|
+
lastAppliedRevision: ref,
|
|
92
|
+
resources: resourceCount,
|
|
93
|
+
conditions: [
|
|
94
|
+
{
|
|
95
|
+
type: 'Ready',
|
|
96
|
+
status: 'True',
|
|
97
|
+
reason: 'ReconciliationSucceeded',
|
|
98
|
+
message: `Applied ${resourceCount} resources`,
|
|
99
|
+
lastTransitionTime: new Date().toISOString(),
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
console.log(`[r8s-controller] Reconciled: ${name} (${resourceCount} resources)`);
|
|
104
|
+
// Cleanup
|
|
105
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error(`[r8s-controller] Failed: ${name}:`, error.message);
|
|
109
|
+
await this.updateStatus(name, namespace, {
|
|
110
|
+
observedGeneration: generation,
|
|
111
|
+
conditions: [
|
|
112
|
+
{
|
|
113
|
+
type: 'Ready',
|
|
114
|
+
status: 'False',
|
|
115
|
+
reason: 'ReconciliationFailed',
|
|
116
|
+
message: error.message,
|
|
117
|
+
lastTransitionTime: new Date().toISOString(),
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async updateStatus(name, namespace, status) {
|
|
124
|
+
try {
|
|
125
|
+
await this.k8sApi.patchNamespacedCustomObjectStatus(GROUP, VERSION, namespace, PLURAL, name, { status }, undefined, undefined, undefined, { headers: { 'Content-Type': 'application/merge-patch+json' } });
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error(`[r8s-controller] Failed to update status:`, error.message);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Start controller if run directly
|
|
133
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
134
|
+
const namespace = process.env.NAMESPACE || 'default';
|
|
135
|
+
const controller = new R8sController(namespace);
|
|
136
|
+
controller.start().catch(console.error);
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@r8s/r8s-controller",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "r8s Kubernetes controller - renders TSX to YAML in-cluster",
|
|
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/r8s-controller"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/berget-ai/r8s/issues",
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"main": "./dist/controller.js",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"dev": "tsx src/controller.ts",
|
|
25
|
+
"start": "node dist/controller.js",
|
|
26
|
+
"test": "echo 'No tests for r8s-controller'",
|
|
27
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@kubernetes/client-node": "^0.20.0",
|
|
31
|
+
"@r8s/core": "^0.1.0",
|
|
32
|
+
"@r8s/cli": "^0.1.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^20.0.0",
|
|
36
|
+
"tsx": "^4.0.0",
|
|
37
|
+
"typescript": "^5.3.0"
|
|
38
|
+
}
|
|
39
|
+
}
|