Skip to content

Commit aaa03f8

Browse files
asimclaude
andauthored
deploy/kubernetes: embed CRDs instead of duplicating them (#4845)
The CRD manifests were kept in two places — real YAML under config/crd/ (for kubectl apply) and byte-identical const strings in manifests.go (for the Go CRDManifests map) — which will silently drift. Make config/crd/*.yaml the single source of truth and go:embed it; CRDManifests now reads the embedded bytes. Drops ~120 lines of duplicated YAML, no behavior change (still stdlib-only, tests unchanged). Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1f5ae1f commit aaa03f8

1 file changed

Lines changed: 27 additions & 120 deletions

File tree

deploy/kubernetes/manifests.go

Lines changed: 27 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,32 @@
11
package kubernetes
22

3-
// CRDManifests contains the alpha CRDs for Go Micro lifecycle resources.
4-
var CRDManifests = map[Kind]string{
5-
KindAgent: agentCRD,
6-
KindService: serviceCRD,
7-
KindFlow: flowCRD,
8-
}
3+
import (
4+
"embed"
5+
"fmt"
6+
)
97

10-
const agentCRD = `apiVersion: apiextensions.k8s.io/v1
11-
kind: CustomResourceDefinition
12-
metadata:
13-
name: agents.micro.dev
14-
spec:
15-
group: micro.dev
16-
scope: Namespaced
17-
names:
18-
plural: agents
19-
singular: agent
20-
kind: Agent
21-
shortNames: [magent]
22-
versions:
23-
- name: v1alpha1
24-
served: true
25-
storage: true
26-
schema:
27-
openAPIV3Schema:
28-
type: object
29-
required: [spec]
30-
properties:
31-
spec:
32-
type: object
33-
required: [image]
34-
properties:
35-
image: {type: string, minLength: 1}
36-
command:
37-
type: array
38-
items: {type: string}
39-
args:
40-
type: array
41-
items: {type: string}
42-
replicas: {type: integer, minimum: 0}
43-
registry: {type: string}
44-
env:
45-
type: object
46-
additionalProperties: {type: string}
47-
`
8+
// crdFS holds the canonical CRD manifests. They live as real YAML under
9+
// config/crd/ so they can be applied directly (`kubectl apply -f
10+
// deploy/kubernetes/config/crd/`) and are embedded here so the Go API serves
11+
// the exact same bytes — one source of truth, no drift.
12+
//
13+
//go:embed config/crd/agent.yaml config/crd/service.yaml config/crd/flow.yaml
14+
var crdFS embed.FS
4815

49-
const serviceCRD = `apiVersion: apiextensions.k8s.io/v1
50-
kind: CustomResourceDefinition
51-
metadata:
52-
name: services.micro.dev
53-
spec:
54-
group: micro.dev
55-
scope: Namespaced
56-
names:
57-
plural: services
58-
singular: service
59-
kind: Service
60-
shortNames: [mservice]
61-
versions:
62-
- name: v1alpha1
63-
served: true
64-
storage: true
65-
schema:
66-
openAPIV3Schema:
67-
type: object
68-
required: [spec]
69-
properties:
70-
spec:
71-
type: object
72-
required: [image]
73-
properties:
74-
image: {type: string, minLength: 1}
75-
command:
76-
type: array
77-
items: {type: string}
78-
args:
79-
type: array
80-
items: {type: string}
81-
replicas: {type: integer, minimum: 0}
82-
registry: {type: string}
83-
env:
84-
type: object
85-
additionalProperties: {type: string}
86-
`
16+
// CRDManifests contains the alpha CRDs for Go Micro lifecycle resources, loaded
17+
// from the embedded config/crd/ YAML.
18+
var CRDManifests = map[Kind]string{
19+
KindAgent: mustCRD("agent"),
20+
KindService: mustCRD("service"),
21+
KindFlow: mustCRD("flow"),
22+
}
8723

88-
const flowCRD = `apiVersion: apiextensions.k8s.io/v1
89-
kind: CustomResourceDefinition
90-
metadata:
91-
name: flows.micro.dev
92-
spec:
93-
group: micro.dev
94-
scope: Namespaced
95-
names:
96-
plural: flows
97-
singular: flow
98-
kind: Flow
99-
shortNames: [mflow]
100-
versions:
101-
- name: v1alpha1
102-
served: true
103-
storage: true
104-
schema:
105-
openAPIV3Schema:
106-
type: object
107-
required: [spec]
108-
properties:
109-
spec:
110-
type: object
111-
required: [image]
112-
properties:
113-
image: {type: string, minLength: 1}
114-
command:
115-
type: array
116-
items: {type: string}
117-
args:
118-
type: array
119-
items: {type: string}
120-
replicas: {type: integer, minimum: 0}
121-
registry: {type: string}
122-
env:
123-
type: object
124-
additionalProperties: {type: string}
125-
`
24+
// mustCRD reads an embedded CRD manifest. The files are embedded at compile
25+
// time, so a read error means a build/packaging bug, not a runtime condition.
26+
func mustCRD(name string) string {
27+
b, err := crdFS.ReadFile("config/crd/" + name + ".yaml")
28+
if err != nil {
29+
panic(fmt.Sprintf("kubernetes: embedded CRD %q missing: %v", name, err))
30+
}
31+
return string(b)
32+
}

0 commit comments

Comments
 (0)