Skip to content

Commit f25a9f8

Browse files
committed
chore: echo provisioner reponses to include terraform to match
1 parent 9bbd2b2 commit f25a9f8

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

provisioner/echo/parameter.tpl

Whitespace-only changes.

provisioner/echo/serve.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os"
99
"path/filepath"
1010
"strings"
11+
"text/template"
1112

1213
"github.com/google/uuid"
1314
"golang.org/x/xerrors"
@@ -377,6 +378,45 @@ func TarWithOptions(ctx context.Context, logger slog.Logger, responses *Response
377378

378379
logger.Debug(context.Background(), "extra file written", slog.F("name", name), slog.F("bytes_written", n))
379380
}
381+
382+
// Write a main.tf with the appropriate parameters. This is to write terraform
383+
// that matches the parameters defined in the responses. Dynamic parameters
384+
// parsed these, even in the echo provisioner.
385+
var mainTF bytes.Buffer
386+
for _, respPlan := range responses.ProvisionPlan {
387+
plan := respPlan.GetPlan()
388+
if plan == nil {
389+
continue
390+
}
391+
392+
for _, param := range plan.Parameters {
393+
paramTF, err := ParameterTerraform(param)
394+
if err != nil {
395+
return nil, xerrors.Errorf("parameter terraform: %w", err)
396+
}
397+
mainTF.WriteString(paramTF)
398+
}
399+
}
400+
401+
if mainTF.Len() > 0 {
402+
mainTFData := `
403+
terraform {
404+
required_providers {
405+
coder = {
406+
source = "coder/coder"
407+
}
408+
}
409+
}
410+
` + mainTF.String()
411+
412+
_ = writer.WriteHeader(&tar.Header{
413+
Name: `main.tf`,
414+
Size: int64(len(mainTFData)),
415+
Mode: 0o644,
416+
})
417+
_, _ = writer.Write([]byte(mainTFData))
418+
}
419+
380420
// `writer.Close()` function flushes the writer buffer, and adds extra padding to create a legal tarball.
381421
err := writer.Close()
382422
if err != nil {
@@ -385,6 +425,65 @@ func TarWithOptions(ctx context.Context, logger slog.Logger, responses *Response
385425
return buffer.Bytes(), nil
386426
}
387427

428+
// ParameterTerraform will create a Terraform data block for the provided parameter.
429+
func ParameterTerraform(param *proto.RichParameter) (string, error) {
430+
tmpl := template.Must(template.New("parameter").Funcs(map[string]any{
431+
"showValidation": func(v *proto.RichParameter) bool {
432+
return v != nil && (v.ValidationMax != nil || v.ValidationMin != nil ||
433+
v.ValidationError != "" || v.ValidationRegex != "" ||
434+
v.ValidationMonotonic != "")
435+
},
436+
}).Parse(`
437+
data "coder_parameter" "{{ .Name }}" {
438+
name = "{{ .Name }}"
439+
display_name = "{{ .DisplayName }}"
440+
description = "{{ .Description }}"
441+
icon = "{{ .Icon }}"
442+
mutable = {{ .Mutable }}
443+
ephemeral = {{ .Ephemeral }}
444+
order = {{ .Order }}
445+
{{- if .DefaultValue }}
446+
default = "{{ .DefaultValue }}"
447+
{{- end }}
448+
{{- if .Type }}
449+
type = "{{ .Type }}"
450+
{{- end }}
451+
{{- if .FormType }}
452+
form_type = "{{ .FormType }}"
453+
{{- end }}
454+
{{- range .Options }}
455+
option {
456+
name = "{{ .Name }}"
457+
value = "{{ .Value }}"
458+
}
459+
{{- end }}
460+
{{- if showValidation .}}
461+
validation {
462+
{{- if .ValidationRegex }}
463+
regex = "{{ .ValidationRegex }}"
464+
{{- end }}
465+
{{- if .ValidationError }}
466+
error = "{{ .ValidationError }}"
467+
{{- end }}
468+
{{- if .ValidationMin }}
469+
min = {{ .ValidationMin }}
470+
{{- end }}
471+
{{- if .ValidationMax }}
472+
max = {{ .ValidationMax }}
473+
{{- end }}
474+
{{- if .ValidationMonotonic }}
475+
monotonic = {{ .ValidationMonotonic }}
476+
{{- end }}
477+
}
478+
{{- end }}
479+
}
480+
`))
481+
482+
var buf bytes.Buffer
483+
err := tmpl.Execute(&buf, param)
484+
return buf.String(), err
485+
}
486+
388487
func WithResources(resources []*proto.Resource) *Responses {
389488
return &Responses{
390489
Parse: ParseComplete,

0 commit comments

Comments
 (0)