mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(scripts): add generator for template builder module catalog (#26193)
> [!NOTE]
> This PR was authored by Coder Agents on behalf of @jeremyruppel.
Adds `scripts/templatebuildermodulegen/`, a Go tool that fetches module metadata from the Coder registry HTTP API and generates the `module.json` manifests and `.tf.tmpl` files used by the template builder catalog.
The generator calls `GET /api/modules/{id}` for per-module metadata (display name, description, icon, tags, variables) and the Terraform protocol versions endpoint for semver resolution. No git clone or HCL parsing required.
Split into four files:
- `main.go`: orchestration, module config map, CLI flags
- `types.go`: output types (`ModuleManifest`, `ModuleVariable`) and API response types
- `fetch.go`: HTTP fetching, version resolution, variable conversion, icon normalization
- `write.go`: JSON writer, `.tf.tmpl` Go template and writer
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func writeModuleJSON(path string, m ModuleManifest) error {
|
||||
data, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data = append(data, '\n')
|
||||
return os.WriteFile(path, data, 0o600)
|
||||
}
|
||||
|
||||
var tfTmplTemplate = template.Must(template.New("tf.tmpl").Funcs(template.FuncMap{
|
||||
"hclValue": func(v ModuleVariable) string {
|
||||
if v.Sensitive {
|
||||
return "var." + v.Name
|
||||
}
|
||||
return "{{ .Variables." + v.Name + " }}"
|
||||
},
|
||||
}).Parse(`{{- range .SensitiveVars }}
|
||||
variable "{{ .Name }}" {
|
||||
description = "{{ .Description }}"
|
||||
type = {{ .Type }}
|
||||
sensitive = true
|
||||
}
|
||||
{{ end -}}
|
||||
module "{{ .ID }}" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "{{"{{"}} .RegistryBase {{"}}"}}/coder/{{ .ID }}/coder"
|
||||
version = "{{"{{"}} .PinnedVersion {{"}}"}}"
|
||||
agent_id = coder_agent.{{"{{"}} .AgentResourceName {{"}}"}}.id
|
||||
{{- range .NonComputedVars }}
|
||||
{{- if .Sensitive }}
|
||||
{{ .Name }} = var.{{ .Name }}
|
||||
{{- else }}
|
||||
{{ .Name }} = {{"{{"}} .Variables.{{ .Name }} {{"}}"}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
`))
|
||||
|
||||
type tfTmplData struct {
|
||||
ID string
|
||||
SensitiveVars []ModuleVariable
|
||||
NonComputedVars []ModuleVariable
|
||||
}
|
||||
|
||||
func writeTFTmpl(path string, m ModuleManifest) error {
|
||||
var sensitiveVars []ModuleVariable
|
||||
var nonComputedVars []ModuleVariable
|
||||
for _, v := range m.Variables {
|
||||
if v.Computed {
|
||||
continue
|
||||
}
|
||||
nonComputedVars = append(nonComputedVars, v)
|
||||
if v.Sensitive {
|
||||
sensitiveVars = append(sensitiveVars, v)
|
||||
}
|
||||
}
|
||||
|
||||
data := tfTmplData{
|
||||
ID: m.ID,
|
||||
SensitiveVars: sensitiveVars,
|
||||
NonComputedVars: nonComputedVars,
|
||||
}
|
||||
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tfTmplTemplate.Execute(f, data)
|
||||
if closeErr := f.Close(); err == nil {
|
||||
err = closeErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user