@owlmeans/kluster 0.1.18-rc.8 → 0.1.18
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 +2 -2
- package/agent-meta/manifest.json +3 -3
- package/agent-meta/skills/kluster/SKILL.md +96 -14
- package/build/service.d.ts.map +1 -1
- package/build/service.js +4 -2
- package/build/service.js.map +1 -1
- package/build/types.local.d.ts +5 -0
- package/build/types.local.d.ts.map +1 -0
- package/build/types.local.js +2 -0
- package/build/types.local.js.map +1 -0
- package/package.json +9 -8
- package/src/service.ts +7 -6
- package/src/types.local.ts +6 -0
- package/build/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Kubernetes integration service — service discovery and pod/service IP resoluti
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @owlmeans/kluster
|
|
15
|
+
bun add @owlmeans/kluster@^0.1.18
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
@@ -74,7 +74,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
74
74
|
your project's skill store (`.agents/skills/`):
|
|
75
75
|
|
|
76
76
|
```sh
|
|
77
|
-
npx @owlmeans/agent-skills
|
|
77
|
+
npx @owlmeans/agent-skills@^0.1.18
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
2
|
+
"schemaVersion": 3,
|
|
3
3
|
"package": "@owlmeans/kluster",
|
|
4
|
-
"version": "0.1.18
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18",
|
|
5
|
+
"generatedAt": "2026-10-28T00:31:34.762Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: kluster
|
|
3
|
-
description: How to use @owlmeans/kluster — Kubernetes API client service
|
|
3
|
+
description: How to use @owlmeans/kluster — the Kubernetes API client service, klusterize() wiring, the kluster:<action>:<query> config directive that resolves cluster addresses at boot, and the typed API accessors for pods, services, deployments, ingress and CRDs. Auto-invoked when interacting with the cluster from app code or when a config value names a cluster lookup.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
@@ -8,31 +8,113 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/kluster
|
|
9
9
|
|
|
10
10
|
**Layer:** Infra
|
|
11
|
-
**Install:** `"@owlmeans/kluster": "^0.1.18
|
|
11
|
+
**Install:** `"@owlmeans/kluster": "^0.1.18"` in `dependencies`
|
|
12
|
+
|
|
13
|
+
Two things in one package: a service that talks to the Kubernetes API, and a config middleware that
|
|
14
|
+
lets a config value *be* a cluster lookup instead of a hardcoded address.
|
|
12
15
|
|
|
13
16
|
## Key Exports
|
|
14
17
|
|
|
15
18
|
| Export | Description |
|
|
16
19
|
|--------|-------------|
|
|
17
|
-
| `
|
|
18
|
-
| `makeKlusterService()` |
|
|
19
|
-
| `
|
|
20
|
-
|
|
|
20
|
+
| `klusterize(ctx, alias?)` | Register the service **and** the config middleware — the one call an app makes |
|
|
21
|
+
| `makeKlusterService(alias?)` | The service alone, for a context that wires its own middleware |
|
|
22
|
+
| `createMiddleware(alias?)` | The config middleware alone |
|
|
23
|
+
| `KlusterService` | Service interface — the lookups and API factories below, plus `api` (`CoreV1Api`) and `config` (the loaded `KubeConfig`) |
|
|
24
|
+
| `KlusterConfig` | Server config plus `kluster?: { namespace? }` |
|
|
25
|
+
| `isNotFoundError(e)` | True for a 404 across every shape the client library reports one in |
|
|
26
|
+
| `DEFAULT_ALIAS` / `KLUSTER_SERVICE_ALIAS` | The service alias (`kluster`) |
|
|
27
|
+
| `DIRECTIVE` (`kluster`), `SEP` (`:`) | The config-directive prefix and separator |
|
|
28
|
+
| `ACT_HOST` (`hostname`), `ACT_SERVICE` (`service`) | The directive actions |
|
|
29
|
+
| `DEFAULT_NAMESPACE` (`default`) | Namespace used when the config names none |
|
|
21
30
|
|
|
22
|
-
##
|
|
31
|
+
## Wiring
|
|
23
32
|
|
|
24
33
|
```typescript
|
|
25
|
-
|
|
26
|
-
import {
|
|
34
|
+
// klusterize is re-exported by @owlmeans/server-app, alongside the server context factory
|
|
35
|
+
import { klusterize, makeContext as makeBackendContext } from '@owlmeans/server-app'
|
|
36
|
+
|
|
37
|
+
export const makeContext = <C extends Config, T extends Context<C>>(cfg: C): T => {
|
|
38
|
+
const context = makeBackendContext<C, T>(cfg)
|
|
39
|
+
klusterize<C, T>(context)
|
|
40
|
+
return context
|
|
41
|
+
}
|
|
42
|
+
```
|
|
27
43
|
|
|
28
|
-
context
|
|
29
|
-
context.kluster = () => context.service(KLUSTER_SERVICE)
|
|
44
|
+
Expose it the way any other service is exposed, and declare the accessor on the app's context type:
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
|
|
46
|
+
```typescript
|
|
47
|
+
import { DEFAULT_ALIAS as KLUSTER } from '@owlmeans/kluster'
|
|
48
|
+
import type { KlusterService } from '@owlmeans/kluster'
|
|
49
|
+
|
|
50
|
+
context.kluster = () => context.service<KlusterService>(KLUSTER)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The service is **lazy**: nothing touches the cluster until the first call, at which point the
|
|
54
|
+
kubeconfig is loaded from the default location — the mounted service account inside a pod, the
|
|
55
|
+
developer's kubeconfig outside one — and a core API client is built.
|
|
56
|
+
|
|
57
|
+
## Config directives
|
|
58
|
+
|
|
59
|
+
A config string of the form `kluster:<action>:<query>` is replaced, during `init()`, with what the
|
|
60
|
+
cluster answers. That is how a service declaration names a peer by label rather than by address:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
sservice({ service: AGENT, internalHost: 'kluster:service:agent', internalPort: 8081 }, cfg)
|
|
33
64
|
```
|
|
34
65
|
|
|
66
|
+
| Action | Query | Becomes |
|
|
67
|
+
|--------|-------|---------|
|
|
68
|
+
| `service` | a label selector | The `clusterIP` of the first matching Service, or `null` when none matches |
|
|
69
|
+
| `hostname` | a label selector | The list of pod IPs matching the selector |
|
|
70
|
+
|
|
71
|
+
Rules that follow from how it runs:
|
|
72
|
+
|
|
73
|
+
- The namespace is `cfg.kluster.namespace`, falling back to `default`. A directive never names one.
|
|
74
|
+
- A query rooted at `/` is read from that file first, so a selector can be mounted rather than baked
|
|
75
|
+
into the config. That is the only mounted form the directive carries: the value is split on `:`
|
|
76
|
+
into three parts, so a `file://` URL — or any query holding a `:` of its own — is truncated at
|
|
77
|
+
that colon and the fragment before it is sent as the selector.
|
|
78
|
+
- `hostname` yields an **array**, so the config key it replaces must be one that accepts a list.
|
|
79
|
+
- Resolution happens at the config-loading stage — after services have initialized and before
|
|
80
|
+
resources do. A value read at call time therefore sees the resolved address; one a service copied
|
|
81
|
+
into a field while initializing does not.
|
|
82
|
+
- An unknown action is a `SyntaxError` at boot.
|
|
83
|
+
- Only an `ApiException` from the client library is swallowed. It is logged, `service` leaves the
|
|
84
|
+
selector in place as the host and `hostname` yields an empty list — so a peer that answers
|
|
85
|
+
"connection refused to `app=agent`" is that failure, not a bad hostname.
|
|
86
|
+
- **Everything else propagates.** A transport failure, an unusable or absent kubeconfig, or a failed
|
|
87
|
+
context assertion is rethrown out of the lookup, and because the directive is resolved by a
|
|
88
|
+
`Config`/`Loading` middleware that means `init()` rejects and the process never boots. An app that
|
|
89
|
+
must survive a cluster it cannot reach has to keep the directive out of its config, not rely on a
|
|
90
|
+
fallback here.
|
|
91
|
+
|
|
92
|
+
## Talking to the cluster directly
|
|
93
|
+
|
|
94
|
+
| Member | Use |
|
|
95
|
+
|--------|-----|
|
|
96
|
+
| `getServiceHostname(selector, namespace?)` | The first matching Service's cluster IP |
|
|
97
|
+
| `getHostnames(selector, namespace?)` | Pod IPs matching the selector |
|
|
98
|
+
| `dispatch(action, query)` | What the middleware calls — the same two actions by name |
|
|
99
|
+
| `api` | The core API client (pods, services, secrets, config maps) |
|
|
100
|
+
| `makeAppsApi()` | Deployments, StatefulSets, DaemonSets |
|
|
101
|
+
| `makeNetworkingApi()` | Ingress and network policy |
|
|
102
|
+
| `makeCustomObjectsApi()` | CRDs, which is how Gateway API resources are reached |
|
|
103
|
+
|
|
104
|
+
**Await `ready()` before touching any of them.** Resolving a lazy service starts its initialization
|
|
105
|
+
but does not wait for it, and `api` and the factories are only populated once that finishes — so the
|
|
106
|
+
first caller after a boot dereferences `undefined` unless it waits:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
const kluster = context.service<KlusterService>(KLUSTER)
|
|
110
|
+
await kluster.ready()
|
|
111
|
+
const apps = kluster.makeAppsApi()
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Wrap a get whose absence is expected with `isNotFoundError` instead of matching on a status field —
|
|
115
|
+
the client library reports 404 under several different shapes.
|
|
116
|
+
|
|
35
117
|
## Depends On
|
|
36
118
|
|
|
37
|
-
- `@owlmeans/server-
|
|
119
|
+
- `@owlmeans/context`, `@owlmeans/config`, `@owlmeans/server-config`, `@owlmeans/server-context`
|
|
38
120
|
- `@kubernetes/client-node` (runtime)
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAUhD,eAAO,MAAM,eAAe,MAAO,OAAO,KAAG,OAa5C,CAAA;AAED,eAAO,MAAM,kBAAkB,WAAW,MAAM,KAAmB,cAuElE,CAAA"}
|
package/build/service.js
CHANGED
|
@@ -2,6 +2,8 @@ import { ACT_HOST, ACT_SERVICE, DEFAULT_ALIAS, DEFAULT_NAMESPACE } from './const
|
|
|
2
2
|
import { assertContext, createLazyService } from '@owlmeans/context';
|
|
3
3
|
import { KubeConfig, CoreV1Api, ApiException, NetworkingV1Api, AppsV1Api, CustomObjectsApi } from '@kubernetes/client-node';
|
|
4
4
|
import { readConfigValue } from '@owlmeans/server-config';
|
|
5
|
+
import { logger } from '@owlmeans/log';
|
|
6
|
+
const log = logger('kluster');
|
|
5
7
|
export const isNotFoundError = (e) => {
|
|
6
8
|
if (e == null || typeof e !== 'object')
|
|
7
9
|
return false;
|
|
@@ -35,7 +37,7 @@ export const makeKlusterService = (alias = DEFAULT_ALIAS) => {
|
|
|
35
37
|
}
|
|
36
38
|
catch (e) {
|
|
37
39
|
if (e instanceof ApiException) {
|
|
38
|
-
|
|
40
|
+
log.warn('Kubernetes pod lookup failed', { selector, namespace, code: e.code, error: e });
|
|
39
41
|
}
|
|
40
42
|
else {
|
|
41
43
|
throw e;
|
|
@@ -52,7 +54,7 @@ export const makeKlusterService = (alias = DEFAULT_ALIAS) => {
|
|
|
52
54
|
}
|
|
53
55
|
catch (e) {
|
|
54
56
|
if (e instanceof ApiException) {
|
|
55
|
-
|
|
57
|
+
log.warn('Kubernetes service lookup failed', { selector, namespace, code: e.code, error: e });
|
|
56
58
|
}
|
|
57
59
|
else {
|
|
58
60
|
throw e;
|
package/build/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAErF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACpE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAExD,MAAM,MAAM,MAAM,GAAG,aAAa,CAAA;AAElC,MAAM,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.local.js","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/kluster",
|
|
3
|
-
"version": "0.1.18
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -21,15 +21,16 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@kubernetes/client-node": "^
|
|
25
|
-
"@owlmeans/config": "^0.1.18
|
|
26
|
-
"@owlmeans/context": "^0.1.18
|
|
27
|
-
"@owlmeans/
|
|
28
|
-
"@owlmeans/server-
|
|
24
|
+
"@kubernetes/client-node": "^2.0.0",
|
|
25
|
+
"@owlmeans/config": "^0.1.18",
|
|
26
|
+
"@owlmeans/context": "^0.1.18",
|
|
27
|
+
"@owlmeans/log": "^0.1.18",
|
|
28
|
+
"@owlmeans/server-config": "^0.1.18",
|
|
29
|
+
"@owlmeans/server-context": "^0.1.18"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
|
-
"@owlmeans/dep-config": "
|
|
32
|
-
"@types/node": "^26.
|
|
32
|
+
"@owlmeans/dep-config": "^0.1.18",
|
|
33
|
+
"@types/node": "^26.6.4",
|
|
33
34
|
"nodemon": "^3.1.14",
|
|
34
35
|
"typescript": "^7.0.2"
|
|
35
36
|
},
|
package/src/service.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ACT_HOST, ACT_SERVICE, DEFAULT_ALIAS, DEFAULT_NAMESPACE } from './consts.js'
|
|
2
|
-
import type {
|
|
2
|
+
import type { KlusterService } from './types.js'
|
|
3
3
|
import { assertContext, createLazyService } from '@owlmeans/context'
|
|
4
4
|
import { KubeConfig, CoreV1Api, ApiException, NetworkingV1Api, AppsV1Api, CustomObjectsApi } from '@kubernetes/client-node'
|
|
5
|
-
import { ServerContext } from '@owlmeans/server-context'
|
|
6
5
|
import { readConfigValue } from '@owlmeans/server-config'
|
|
6
|
+
import { logger } from '@owlmeans/log'
|
|
7
|
+
import type { Config, Context } from './types.local.js'
|
|
8
|
+
|
|
9
|
+
const log = logger('kluster')
|
|
7
10
|
|
|
8
|
-
type Config = KlusterConfig
|
|
9
|
-
type Context = ServerContext<Config>
|
|
10
11
|
|
|
11
12
|
export const isNotFoundError = (e: unknown): boolean => {
|
|
12
13
|
if (e == null || typeof e !== 'object') return false
|
|
@@ -41,7 +42,7 @@ export const makeKlusterService = (alias: string = DEFAULT_ALIAS): KlusterServic
|
|
|
41
42
|
return result.items.map(item => item.status?.podIP).filter(name => name != null)
|
|
42
43
|
} catch (e) {
|
|
43
44
|
if (e instanceof ApiException) {
|
|
44
|
-
|
|
45
|
+
log.warn('Kubernetes pod lookup failed', { selector, namespace, code: e.code, error: e })
|
|
45
46
|
} else {
|
|
46
47
|
throw e
|
|
47
48
|
}
|
|
@@ -59,7 +60,7 @@ export const makeKlusterService = (alias: string = DEFAULT_ALIAS): KlusterServic
|
|
|
59
60
|
return result.items?.[0]?.spec?.clusterIP ?? null
|
|
60
61
|
} catch (e) {
|
|
61
62
|
if (e instanceof ApiException) {
|
|
62
|
-
|
|
63
|
+
log.warn('Kubernetes service lookup failed', { selector, namespace, code: e.code, error: e })
|
|
63
64
|
} else {
|
|
64
65
|
throw e
|
|
65
66
|
}
|
package/build/.gitkeep
DELETED
|
File without changes
|