@kustodian/schema 1.0.0 → 1.2.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 +65 -0
- package/package.json +1 -1
- package/src/common.ts +18 -0
- package/src/index.ts +1 -0
- package/src/sources.ts +142 -0
- package/src/template.ts +2 -0
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# @kustodian/schema
|
|
2
|
+
|
|
3
|
+
Zod schema definitions for validating Kustodian YAML configuration files. This package provides type-safe validation for Cluster, Template, Node, and NodeProfile resources.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @kustodian/schema
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## API Overview
|
|
12
|
+
|
|
13
|
+
### Resource Schemas
|
|
14
|
+
|
|
15
|
+
- **`cluster_schema`** - Cluster resource definition with Git/OCI source, templates, and node configuration
|
|
16
|
+
- **`template_schema`** - Template resource with kustomization definitions
|
|
17
|
+
- **`node_resource_schema`** - Node resource with role, address, SSH config, labels, and taints
|
|
18
|
+
- **`node_profile_resource_schema`** - Reusable node profile with labels, taints, and annotations
|
|
19
|
+
|
|
20
|
+
### Validation Functions
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { validate_cluster, validate_template, validate_node_resource, validate_node_profile_resource } from '@kustodian/schema';
|
|
24
|
+
|
|
25
|
+
const result = validate_cluster(yamlData);
|
|
26
|
+
if (result.success) {
|
|
27
|
+
// result.data is fully typed as ClusterType
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Substitution Types
|
|
32
|
+
|
|
33
|
+
The package supports multiple substitution types for template values:
|
|
34
|
+
|
|
35
|
+
- **Generic** - Simple key-value substitutions
|
|
36
|
+
- **Version** - Container image version tracking with semver constraints
|
|
37
|
+
- **Namespace** - Kubernetes namespace with validation
|
|
38
|
+
- **1Password** - Secrets from 1Password vaults (`op://` references)
|
|
39
|
+
- **Doppler** - Secrets from Doppler projects
|
|
40
|
+
|
|
41
|
+
### Type Guards
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { is_version_substitution, is_onepassword_substitution } from '@kustodian/schema';
|
|
45
|
+
|
|
46
|
+
if (is_version_substitution(sub)) {
|
|
47
|
+
// sub.registry is available
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Exported Types
|
|
52
|
+
|
|
53
|
+
All schemas export corresponding TypeScript types:
|
|
54
|
+
|
|
55
|
+
- `ClusterType`, `TemplateType`, `NodeResourceType`, `NodeProfileResourceType`
|
|
56
|
+
- `SubstitutionType`, `VersionSubstitutionType`, `GenericSubstitutionType`
|
|
57
|
+
- `KustomizationType`, `HealthCheckType`, `TaintSchemaType`
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
MIT
|
|
62
|
+
|
|
63
|
+
## Repository
|
|
64
|
+
|
|
65
|
+
[github.com/lucasilverentand/kustodian](https://github.com/lucasilverentand/kustodian)
|
package/package.json
CHANGED
package/src/common.ts
CHANGED
|
@@ -21,10 +21,27 @@ export const health_check_schema = z.object({
|
|
|
21
21
|
kind: z.string().min(1),
|
|
22
22
|
name: z.string().min(1),
|
|
23
23
|
namespace: z.string().min(1).optional(),
|
|
24
|
+
api_version: z.string().min(1).optional(),
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
export type HealthCheckType = z.infer<typeof health_check_schema>;
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Health check expression configuration using CEL (Common Expression Language).
|
|
31
|
+
* Supports custom health check conditions via CEL expressions.
|
|
32
|
+
*/
|
|
33
|
+
export const health_check_expr_schema = z.object({
|
|
34
|
+
api_version: z.string().min(1),
|
|
35
|
+
kind: z.string().min(1),
|
|
36
|
+
namespace: z.string().min(1).optional(),
|
|
37
|
+
/** CEL expression for when resource is healthy/current */
|
|
38
|
+
current: z.string().min(1).optional(),
|
|
39
|
+
/** CEL expression for when resource has failed */
|
|
40
|
+
failed: z.string().min(1).optional(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export type HealthCheckExprType = z.infer<typeof health_check_expr_schema>;
|
|
44
|
+
|
|
28
45
|
/**
|
|
29
46
|
* Registry configuration for version substitutions.
|
|
30
47
|
*/
|
|
@@ -45,6 +62,7 @@ export const generic_substitution_schema = z.object({
|
|
|
45
62
|
name: z.string().min(1),
|
|
46
63
|
default: z.string().optional(),
|
|
47
64
|
secret: z.string().optional(),
|
|
65
|
+
preserve_case: z.boolean().optional(),
|
|
48
66
|
});
|
|
49
67
|
|
|
50
68
|
export type GenericSubstitutionType = z.infer<typeof generic_substitution_schema>;
|
package/src/index.ts
CHANGED
package/src/sources.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Git reference - exactly one of branch, tag, or commit must be specified.
|
|
5
|
+
*/
|
|
6
|
+
export const git_ref_schema = z
|
|
7
|
+
.object({
|
|
8
|
+
branch: z.string().min(1).optional(),
|
|
9
|
+
tag: z.string().min(1).optional(),
|
|
10
|
+
commit: z.string().min(1).optional(),
|
|
11
|
+
})
|
|
12
|
+
.refine((data) => [data.branch, data.tag, data.commit].filter(Boolean).length === 1, {
|
|
13
|
+
message: "Exactly one of 'branch', 'tag', or 'commit' must be specified",
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export type GitRefType = z.infer<typeof git_ref_schema>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Git source configuration for fetching templates from a Git repository.
|
|
20
|
+
*/
|
|
21
|
+
export const git_source_schema = z.object({
|
|
22
|
+
url: z.string().url(),
|
|
23
|
+
ref: git_ref_schema,
|
|
24
|
+
path: z.string().optional(),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export type GitSourceType = z.infer<typeof git_source_schema>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* HTTP archive source configuration for fetching templates from URLs.
|
|
31
|
+
* Supports tar.gz and zip archives.
|
|
32
|
+
*/
|
|
33
|
+
export const http_source_schema = z.object({
|
|
34
|
+
url: z.string().url(),
|
|
35
|
+
checksum: z.string().optional(),
|
|
36
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export type HttpSourceType = z.infer<typeof http_source_schema>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* OCI artifact source configuration for pulling templates from OCI registries.
|
|
43
|
+
*/
|
|
44
|
+
export const oci_source_schema = z
|
|
45
|
+
.object({
|
|
46
|
+
registry: z.string().min(1),
|
|
47
|
+
repository: z.string().min(1),
|
|
48
|
+
tag: z.string().min(1).optional(),
|
|
49
|
+
digest: z.string().min(1).optional(),
|
|
50
|
+
})
|
|
51
|
+
.refine((data) => data.tag || data.digest, {
|
|
52
|
+
message: "Either 'tag' or 'digest' must be specified",
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export type OciSourceType = z.infer<typeof oci_source_schema>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Duration format for TTL values.
|
|
59
|
+
* Examples: 30m, 1h, 24h, 7d
|
|
60
|
+
*/
|
|
61
|
+
export const duration_schema = z.string().regex(/^(\d+)(m|h|d)$/, {
|
|
62
|
+
message: "Duration must be in format: <number>(m|h|d), e.g., '30m', '1h', '7d'",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Template source configuration - union of all source types.
|
|
67
|
+
* Exactly one of git, http, or oci must be specified.
|
|
68
|
+
*/
|
|
69
|
+
export const template_source_schema = z
|
|
70
|
+
.object({
|
|
71
|
+
name: z.string().min(1),
|
|
72
|
+
git: git_source_schema.optional(),
|
|
73
|
+
http: http_source_schema.optional(),
|
|
74
|
+
oci: oci_source_schema.optional(),
|
|
75
|
+
ttl: duration_schema.optional(),
|
|
76
|
+
})
|
|
77
|
+
.refine((data) => [data.git, data.http, data.oci].filter(Boolean).length === 1, {
|
|
78
|
+
message: "Exactly one of 'git', 'http', or 'oci' must be specified",
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export type TemplateSourceType = z.infer<typeof template_source_schema>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Type guard for Git sources.
|
|
85
|
+
*/
|
|
86
|
+
export function is_git_source(
|
|
87
|
+
source: TemplateSourceType,
|
|
88
|
+
): source is TemplateSourceType & { git: GitSourceType } {
|
|
89
|
+
return source.git !== undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Type guard for HTTP sources.
|
|
94
|
+
*/
|
|
95
|
+
export function is_http_source(
|
|
96
|
+
source: TemplateSourceType,
|
|
97
|
+
): source is TemplateSourceType & { http: HttpSourceType } {
|
|
98
|
+
return source.http !== undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Type guard for OCI sources.
|
|
103
|
+
*/
|
|
104
|
+
export function is_oci_source(
|
|
105
|
+
source: TemplateSourceType,
|
|
106
|
+
): source is TemplateSourceType & { oci: OciSourceType } {
|
|
107
|
+
return source.oci !== undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Determines if a source reference is mutable (requires TTL-based refresh).
|
|
112
|
+
* - Git branches: mutable
|
|
113
|
+
* - Git tags/commits: immutable
|
|
114
|
+
* - HTTP with checksum: immutable
|
|
115
|
+
* - HTTP without checksum: mutable
|
|
116
|
+
* - OCI 'latest' tag: mutable
|
|
117
|
+
* - OCI other tags/digests: immutable
|
|
118
|
+
*/
|
|
119
|
+
export function is_mutable_source(source: TemplateSourceType): boolean {
|
|
120
|
+
if (is_git_source(source)) {
|
|
121
|
+
return source.git.ref.branch !== undefined;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (is_http_source(source)) {
|
|
125
|
+
return source.http.checksum === undefined;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (is_oci_source(source)) {
|
|
129
|
+
return source.oci.tag === 'latest' && source.oci.digest === undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Validates a template source object and returns the result.
|
|
137
|
+
*/
|
|
138
|
+
export function validate_template_source(
|
|
139
|
+
data: unknown,
|
|
140
|
+
): z.SafeParseReturnType<unknown, TemplateSourceType> {
|
|
141
|
+
return template_source_schema.safeParse(data);
|
|
142
|
+
}
|
package/src/template.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
api_version_schema,
|
|
5
|
+
health_check_expr_schema,
|
|
5
6
|
health_check_schema,
|
|
6
7
|
metadata_schema,
|
|
7
8
|
namespace_config_schema,
|
|
@@ -19,6 +20,7 @@ export const kustomization_schema = z.object({
|
|
|
19
20
|
depends_on: z.array(z.string()).optional(),
|
|
20
21
|
substitutions: z.array(substitution_schema).optional(),
|
|
21
22
|
health_checks: z.array(health_check_schema).optional(),
|
|
23
|
+
health_check_exprs: z.array(health_check_expr_schema).optional(),
|
|
22
24
|
prune: z.boolean().optional().default(true),
|
|
23
25
|
wait: z.boolean().optional().default(true),
|
|
24
26
|
timeout: z.string().optional(),
|