@owlmeans/kluster 0.1.7 → 0.1.9
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
CHANGED
|
@@ -65,3 +65,20 @@ Extends `ServerConfig` with optional `namespace: string`.
|
|
|
65
65
|
|
|
66
66
|
- [`@owlmeans/server-app`](../server-app) — `makeContext` where `klusterize` is typically called
|
|
67
67
|
- [`@owlmeans/mongo`](../mongo) — MongoDB URL can be a `kluster:` directive
|
|
68
|
+
|
|
69
|
+
<!-- owlmeans:agent-guidance:start -->
|
|
70
|
+
## Agent guidance
|
|
71
|
+
|
|
72
|
+
This package ships embedded Claude Code skills and GitHub Copilot instructions under
|
|
73
|
+
`agent-meta/`. After installing your `@owlmeans/*` packages, run the OwlMeans
|
|
74
|
+
agent-skills installer to place them into your project's native locations
|
|
75
|
+
(`.claude/skills/` and `.github/instructions/`):
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
npx @owlmeans/agent-skills
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The embedded files are version-matched to this package release. Do not edit them
|
|
82
|
+
directly — they are regenerated on each publish. To contribute guidance edits,
|
|
83
|
+
open a PR against the source monorepo.
|
|
84
|
+
<!-- owlmeans:agent-guidance:end -->
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "How to use @owlmeans/kluster — Kubernetes API client service. Resolve via context.service(DEFAULT_ALIAS) to access the cluster API for service discovery, secrets, config maps, and Gateway API (Gateway/HTTPRoute via CustomObjectsApi)."
|
|
3
|
+
applyTo: "**/*.ts, **/*.tsx"
|
|
4
|
+
---
|
|
5
|
+
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
6
|
+
|
|
7
|
+
# @owlmeans/kluster
|
|
8
|
+
|
|
9
|
+
**Layer:** Infra
|
|
10
|
+
**Install:** `"@owlmeans/kluster": "^0.1.9"` in `dependencies`
|
|
11
|
+
|
|
12
|
+
## Key Exports
|
|
13
|
+
|
|
14
|
+
| Export | Description |
|
|
15
|
+
|--------|-------------|
|
|
16
|
+
| `DEFAULT_ALIAS` | Kluster service alias |
|
|
17
|
+
| `makeKlusterService()` | Kubernetes client service factory |
|
|
18
|
+
| `KlusterService` | Service interface |
|
|
19
|
+
| `isNotFoundError(e)` | Returns true if an API error is HTTP 404 |
|
|
20
|
+
| Helpers | Service discovery, secret resolution |
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { DEFAULT_ALIAS as KLUSTER_SERVICE, makeKlusterService } from '@owlmeans/kluster'
|
|
26
|
+
|
|
27
|
+
context.registerService(makeKlusterService())
|
|
28
|
+
context.kluster = () => context.service(KLUSTER_SERVICE)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## KlusterService API
|
|
32
|
+
|
|
33
|
+
After `await kluster.ready()`:
|
|
34
|
+
|
|
35
|
+
| Method | Returns | Purpose |
|
|
36
|
+
|--------|---------|---------|
|
|
37
|
+
| `kluster.api` | `CoreV1Api` | Core APIs — Pods, Services, Secrets, ConfigMaps |
|
|
38
|
+
| `kluster.makeNetworkingApi()` | `NetworkingV1Api` | Legacy networking (kept for compatibility) |
|
|
39
|
+
| `kluster.makeAppsApi()` | `AppsV1Api` | Deployments, StatefulSets |
|
|
40
|
+
| `kluster.makeCustomObjectsApi()` | `CustomObjectsApi` | CRDs — **use for Gateway API resources** |
|
|
41
|
+
| `kluster.getHostnames(selector, ns)` | `string[]` | Pod IPs by label selector |
|
|
42
|
+
| `kluster.getServiceHostname(selector, ns)` | `string \| null` | ClusterIP by label selector |
|
|
43
|
+
|
|
44
|
+
## Gateway API via CustomObjectsApi
|
|
45
|
+
|
|
46
|
+
Gateway API resources (`Gateway`, `HTTPRoute`) are Kubernetes CRDs. Access them via `makeCustomObjectsApi()`:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { DEFAULT_ALIAS as KLUSTER_SERVICE } from '@owlmeans/kluster'
|
|
50
|
+
import type { KlusterService } from '@owlmeans/kluster'
|
|
51
|
+
import { isNotFoundError } from '@owlmeans/kluster'
|
|
52
|
+
|
|
53
|
+
const kluster = context.service<KlusterService>(KLUSTER_SERVICE)
|
|
54
|
+
await kluster.ready()
|
|
55
|
+
const customObjects = kluster.makeCustomObjectsApi()
|
|
56
|
+
const coreV1 = kluster.api! // CoreV1Api for port resolution
|
|
57
|
+
|
|
58
|
+
const GATEWAY_GROUP = 'gateway.networking.k8s.io'
|
|
59
|
+
const GATEWAY_VERSION = 'v1'
|
|
60
|
+
|
|
61
|
+
// Read a Gateway
|
|
62
|
+
const gw = await customObjects.getNamespacedCustomObject({
|
|
63
|
+
group: GATEWAY_GROUP, version: GATEWAY_VERSION,
|
|
64
|
+
namespace: 'default', plural: 'gateways', name: 'my-gateway',
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// Create an HTTPRoute
|
|
68
|
+
await customObjects.createNamespacedCustomObject({
|
|
69
|
+
group: GATEWAY_GROUP, version: GATEWAY_VERSION,
|
|
70
|
+
namespace: 'default', plural: 'httproutes',
|
|
71
|
+
body: {
|
|
72
|
+
apiVersion: 'gateway.networking.k8s.io/v1',
|
|
73
|
+
kind: 'HTTPRoute',
|
|
74
|
+
metadata: { name: 'my-route', namespace: 'default' },
|
|
75
|
+
spec: {
|
|
76
|
+
parentRefs: [{ name: 'my-gateway', sectionName: 'web-https' }],
|
|
77
|
+
hostnames: ['example.com'],
|
|
78
|
+
rules: [{
|
|
79
|
+
matches: [{ path: { type: 'PathPrefix', value: '/' } }],
|
|
80
|
+
backendRefs: [{ name: 'my-service', port: 80 }], // numeric port required
|
|
81
|
+
}],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// Handle 404 gracefully
|
|
87
|
+
try {
|
|
88
|
+
await customObjects.getNamespacedCustomObject({ ... })
|
|
89
|
+
} catch (e) {
|
|
90
|
+
if (isNotFoundError(e)) { /* resource absent */ }
|
|
91
|
+
else throw e
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Important**: HTTPRoute `backendRefs[].port` must be **numeric**. Named ports are not supported.
|
|
96
|
+
To resolve a named port, read the Service via `CoreV1Api`:
|
|
97
|
+
```typescript
|
|
98
|
+
const svc = await coreV1.readNamespacedService({ name: 'my-service', namespace })
|
|
99
|
+
const port = svc.spec?.ports?.find(p => p.name === 'backend-port')?.port ?? 80
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Depends On
|
|
103
|
+
|
|
104
|
+
- `@owlmeans/server-context`, `@owlmeans/config`, `@kubernetes/client-node`
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"package": "@owlmeans/kluster",
|
|
4
|
+
"version": "0.1.9",
|
|
5
|
+
"generatedAt": "2026-06-14T13:34:06.138Z",
|
|
6
|
+
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
|
+
"entries": [
|
|
8
|
+
{
|
|
9
|
+
"kind": "skill",
|
|
10
|
+
"name": "kluster",
|
|
11
|
+
"category": "package-specific",
|
|
12
|
+
"file": "skills/kluster/SKILL.md",
|
|
13
|
+
"canonicalPath": ".claude/skills/kluster/SKILL.md"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"kind": "instruction",
|
|
17
|
+
"name": "kluster",
|
|
18
|
+
"category": "package-specific",
|
|
19
|
+
"file": "instructions/kluster.instructions.md",
|
|
20
|
+
"canonicalPath": ".github/instructions/kluster.instructions.md"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kluster
|
|
3
|
+
description: How to use @owlmeans/kluster — Kubernetes API client service. Resolve via context.service(DEFAULT_ALIAS) to access the cluster API for service discovery, secrets, config maps. Auto-invoked when interacting with the cluster from app code.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
7
|
+
|
|
8
|
+
# @owlmeans/kluster
|
|
9
|
+
|
|
10
|
+
**Layer:** Infra
|
|
11
|
+
**Install:** `"@owlmeans/kluster": "^0.1.9"` in `dependencies`
|
|
12
|
+
|
|
13
|
+
## Key Exports
|
|
14
|
+
|
|
15
|
+
| Export | Description |
|
|
16
|
+
|--------|-------------|
|
|
17
|
+
| `DEFAULT_ALIAS` | Service alias for the kluster service |
|
|
18
|
+
| `makeKlusterService()` | Factory for the Kubernetes client service |
|
|
19
|
+
| `Kluster` types | Service interface (k8s API access) |
|
|
20
|
+
| Helpers | Service discovery, secret resolution |
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { DEFAULT_ALIAS as KLUSTER_SERVICE } from '@owlmeans/kluster'
|
|
26
|
+
import { makeKlusterService } from '@owlmeans/kluster'
|
|
27
|
+
|
|
28
|
+
context.registerService(makeKlusterService())
|
|
29
|
+
context.kluster = () => context.service(KLUSTER_SERVICE)
|
|
30
|
+
|
|
31
|
+
// Later:
|
|
32
|
+
const k8s = ctx.kluster()
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Depends On
|
|
36
|
+
|
|
37
|
+
- `@owlmeans/server-context`, `@owlmeans/config`
|
|
38
|
+
- `@kubernetes/client-node` (runtime)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/kluster",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@kubernetes/client-node": "^1.4.0",
|
|
25
|
-
"@owlmeans/config": "^0.1.
|
|
26
|
-
"@owlmeans/context": "^0.1.
|
|
27
|
-
"@owlmeans/server-config": "^0.1.
|
|
28
|
-
"@owlmeans/server-context": "^0.1.
|
|
25
|
+
"@owlmeans/config": "^0.1.9",
|
|
26
|
+
"@owlmeans/context": "^0.1.9",
|
|
27
|
+
"@owlmeans/server-config": "^0.1.9",
|
|
28
|
+
"@owlmeans/server-context": "^0.1.9"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@owlmeans/dep-config": "workspace:*",
|