Merge pull request #9468 from hashicorp/azr-ft-hcl2-inspect
[hcl2] inspect command
This commit is contained in:
commit
7eda9eacc6
|
@ -121,3 +121,12 @@ type ValidateArgs struct {
|
||||||
MetaArgs
|
MetaArgs
|
||||||
SyntaxOnly bool
|
SyntaxOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (va *InspectArgs) AddFlagSets(flags *flag.FlagSet) {
|
||||||
|
va.MetaArgs.AddFlagSets(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectArgs represents a parsed cli line for a `packer inspect`
|
||||||
|
type InspectArgs struct {
|
||||||
|
MetaArgs
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_piping(t *testing.T) {
|
func Test_console(t *testing.T) {
|
||||||
|
|
||||||
tc := []struct {
|
tc := []struct {
|
||||||
piped string
|
piped string
|
||||||
|
|
|
@ -85,6 +85,8 @@ func TestHelperProcess(*testing.T) {
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case "console":
|
case "console":
|
||||||
os.Exit((&ConsoleCommand{Meta: commandMeta()}).Run(args))
|
os.Exit((&ConsoleCommand{Meta: commandMeta()}).Run(args))
|
||||||
|
case "inspect":
|
||||||
|
os.Exit((&InspectCommand{Meta: commandMeta()}).Run(args))
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
|
fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"context"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/packer/template"
|
"github.com/hashicorp/packer/packer"
|
||||||
|
|
||||||
"github.com/posener/complete"
|
"github.com/posener/complete"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,142 +13,40 @@ type InspectCommand struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *InspectCommand) Run(args []string) int {
|
func (c *InspectCommand) Run(args []string) int {
|
||||||
flags := c.Meta.FlagSet("inspect", FlagSetNone)
|
ctx := context.Background()
|
||||||
|
|
||||||
|
cfg, ret := c.ParseArgs(args)
|
||||||
|
if ret != 0 {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.RunContext(ctx, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *InspectCommand) ParseArgs(args []string) (*InspectArgs, int) {
|
||||||
|
var cfg InspectArgs
|
||||||
|
flags := c.Meta.FlagSet("inspect", FlagSetVars)
|
||||||
flags.Usage = func() { c.Ui.Say(c.Help()) }
|
flags.Usage = func() { c.Ui.Say(c.Help()) }
|
||||||
|
cfg.AddFlagSets(flags)
|
||||||
if err := flags.Parse(args); err != nil {
|
if err := flags.Parse(args); err != nil {
|
||||||
return 1
|
return &cfg, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
args = flags.Args()
|
args = flags.Args()
|
||||||
if len(args) != 1 {
|
if len(args) == 1 {
|
||||||
flags.Usage()
|
cfg.Path = args[0]
|
||||||
return 1
|
}
|
||||||
|
return &cfg, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the template
|
func (c *InspectCommand) RunContext(ctx context.Context, cla *InspectArgs) int {
|
||||||
tpl, err := template.ParseFile(args[0])
|
packerStarter, ret := c.GetConfig(&cla.MetaArgs)
|
||||||
if err != nil {
|
if ret != 0 {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to parse template: %s", err))
|
return ret
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
|
return packerStarter.InspectConfig(packer.InspectConfigOptions{
|
||||||
// Convenience...
|
Ui: c.Ui,
|
||||||
ui := c.Ui
|
})
|
||||||
|
|
||||||
// Description
|
|
||||||
if tpl.Description != "" {
|
|
||||||
ui.Say("Description:\n")
|
|
||||||
ui.Say(tpl.Description + "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
if len(tpl.Variables) == 0 {
|
|
||||||
ui.Say("Variables:\n")
|
|
||||||
ui.Say(" <No variables>")
|
|
||||||
} else {
|
|
||||||
requiredHeader := false
|
|
||||||
for k, v := range tpl.Variables {
|
|
||||||
for _, sensitive := range tpl.SensitiveVariables {
|
|
||||||
if ok := strings.Compare(sensitive.Default, v.Default); ok == 0 {
|
|
||||||
v.Default = "<sensitive>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if v.Required {
|
|
||||||
if !requiredHeader {
|
|
||||||
requiredHeader = true
|
|
||||||
ui.Say("Required variables:\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.Machine("template-variable", k, v.Default, "1")
|
|
||||||
ui.Say(" " + k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if requiredHeader {
|
|
||||||
ui.Say("")
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.Say("Optional variables and their defaults:\n")
|
|
||||||
keys := make([]string, 0, len(tpl.Variables))
|
|
||||||
max := 0
|
|
||||||
for k := range tpl.Variables {
|
|
||||||
keys = append(keys, k)
|
|
||||||
if len(k) > max {
|
|
||||||
max = len(k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
for _, k := range keys {
|
|
||||||
v := tpl.Variables[k]
|
|
||||||
if v.Required {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, sensitive := range tpl.SensitiveVariables {
|
|
||||||
if ok := strings.Compare(sensitive.Default, v.Default); ok == 0 {
|
|
||||||
v.Default = "<sensitive>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
padding := strings.Repeat(" ", max-len(k))
|
|
||||||
output := fmt.Sprintf(" %s%s = %s", k, padding, v.Default)
|
|
||||||
|
|
||||||
ui.Machine("template-variable", k, v.Default, "0")
|
|
||||||
ui.Say(output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.Say("")
|
|
||||||
|
|
||||||
// Builders
|
|
||||||
ui.Say("Builders:\n")
|
|
||||||
if len(tpl.Builders) == 0 {
|
|
||||||
ui.Say(" <No builders>")
|
|
||||||
} else {
|
|
||||||
keys := make([]string, 0, len(tpl.Builders))
|
|
||||||
max := 0
|
|
||||||
for k := range tpl.Builders {
|
|
||||||
keys = append(keys, k)
|
|
||||||
if len(k) > max {
|
|
||||||
max = len(k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
for _, k := range keys {
|
|
||||||
v := tpl.Builders[k]
|
|
||||||
padding := strings.Repeat(" ", max-len(k))
|
|
||||||
output := fmt.Sprintf(" %s%s", k, padding)
|
|
||||||
if v.Name != v.Type {
|
|
||||||
output = fmt.Sprintf("%s (%s)", output, v.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.Machine("template-builder", k, v.Type)
|
|
||||||
ui.Say(output)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.Say("")
|
|
||||||
|
|
||||||
// Provisioners
|
|
||||||
ui.Say("Provisioners:\n")
|
|
||||||
if len(tpl.Provisioners) == 0 {
|
|
||||||
ui.Say(" <No provisioners>")
|
|
||||||
} else {
|
|
||||||
for _, v := range tpl.Provisioners {
|
|
||||||
ui.Machine("template-provisioner", v.Type)
|
|
||||||
ui.Say(fmt.Sprintf(" %s", v.Type))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.Say("\nNote: If your build names contain user variables or template\n" +
|
|
||||||
"functions such as 'timestamp', these are processed at build time,\n" +
|
|
||||||
"and therefore only show in their raw form here.")
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*InspectCommand) Help() string {
|
func (*InspectCommand) Help() string {
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_commands(t *testing.T) {
|
||||||
|
|
||||||
|
tc := []struct {
|
||||||
|
command []string
|
||||||
|
env []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{[]string{"inspect", "-var=fruit=banana", filepath.Join(testFixture("var-arg"), "fruit_builder.pkr.hcl")}, nil, `Packer Inspect: HCL2 mode
|
||||||
|
|
||||||
|
> input-variables:
|
||||||
|
|
||||||
|
var.fruit: "banana" [debug: {Type:cty.String,CmdValue:banana,VarfileValue:null,EnvValue:null,DefaultValue:null}]
|
||||||
|
|
||||||
|
> local-variables:
|
||||||
|
|
||||||
|
local.fruit: "banana"
|
||||||
|
|
||||||
|
> builds:
|
||||||
|
|
||||||
|
> <unnamed build 0>:
|
||||||
|
|
||||||
|
sources:
|
||||||
|
|
||||||
|
null.builder
|
||||||
|
|
||||||
|
provisioners:
|
||||||
|
|
||||||
|
shell-local
|
||||||
|
|
||||||
|
post-processors:
|
||||||
|
|
||||||
|
<no post-processor>
|
||||||
|
|
||||||
|
`},
|
||||||
|
{[]string{"inspect", "-var=fruit=peach", filepath.Join(testFixture("hcl"), "inspect", "fruit_string.pkr.hcl")}, nil, `Packer Inspect: HCL2 mode
|
||||||
|
|
||||||
|
> input-variables:
|
||||||
|
|
||||||
|
var.fruit: "peach" [debug: {Type:cty.String,CmdValue:peach,VarfileValue:null,EnvValue:null,DefaultValue:banana}]
|
||||||
|
|
||||||
|
> local-variables:
|
||||||
|
|
||||||
|
|
||||||
|
> builds:
|
||||||
|
|
||||||
|
`},
|
||||||
|
{[]string{"inspect", "-var=fruit=peach", filepath.Join(testFixture("hcl"), "inspect")}, nil, `Packer Inspect: HCL2 mode
|
||||||
|
|
||||||
|
> input-variables:
|
||||||
|
|
||||||
|
var.fruit: "peach" [debug: {Type:cty.String,CmdValue:peach,VarfileValue:null,EnvValue:null,DefaultValue:banana}]
|
||||||
|
|
||||||
|
> local-variables:
|
||||||
|
|
||||||
|
|
||||||
|
> builds:
|
||||||
|
|
||||||
|
> aws_example_builder:
|
||||||
|
|
||||||
|
> Description: The builder of clouds !!
|
||||||
|
|
||||||
|
Use it at will.
|
||||||
|
|
||||||
|
|
||||||
|
sources:
|
||||||
|
|
||||||
|
amazon-ebs.example-1
|
||||||
|
|
||||||
|
amazon-ebs.example-2
|
||||||
|
|
||||||
|
provisioners:
|
||||||
|
|
||||||
|
shell
|
||||||
|
|
||||||
|
post-processors:
|
||||||
|
|
||||||
|
manifest
|
||||||
|
|
||||||
|
`},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tc {
|
||||||
|
t.Run(fmt.Sprintf("packer %s", tc.command), func(t *testing.T) {
|
||||||
|
p := helperCommand(t, tc.command...)
|
||||||
|
p.Env = append(p.Env, tc.env...)
|
||||||
|
bs, err := p.Output()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%v: %s", err, bs)
|
||||||
|
}
|
||||||
|
actual := string(bs)
|
||||||
|
if diff := cmp.Diff(tc.expected, actual); diff != "" {
|
||||||
|
t.Fatalf("unexpected ouput %s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
|
||||||
|
build {
|
||||||
|
name = "aws_example_builder"
|
||||||
|
description = <<EOF
|
||||||
|
The builder of clouds !!
|
||||||
|
|
||||||
|
Use it at will.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"source.amazon-ebs.example-1",
|
||||||
|
|
||||||
|
// this one is not defined but we don't want to error there, we just
|
||||||
|
// would like to show what sources are being referenced.
|
||||||
|
"source.amazon-ebs.example-2",
|
||||||
|
]
|
||||||
|
|
||||||
|
provisioner "shell" {
|
||||||
|
files = [
|
||||||
|
"bins/install-this.sh",
|
||||||
|
"bins/install-that.sh",
|
||||||
|
"bins/conf-this.sh",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
post-processor "manifest" {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
variable "fruit" {
|
||||||
|
type = string
|
||||||
|
default = "banana"
|
||||||
|
}
|
|
@ -38,6 +38,10 @@ type BuildBlock struct {
|
||||||
// Name is a string representing the named build to show in the logs
|
// Name is a string representing the named build to show in the logs
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
|
// A description of what this build does, it could be used in a inspect
|
||||||
|
// call for example.
|
||||||
|
Description string
|
||||||
|
|
||||||
// Sources is the list of sources that we want to start in this build block.
|
// Sources is the list of sources that we want to start in this build block.
|
||||||
Sources []SourceRef
|
Sources []SourceRef
|
||||||
|
|
||||||
|
@ -61,6 +65,7 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnosti
|
||||||
|
|
||||||
var b struct {
|
var b struct {
|
||||||
Name string `hcl:"name,optional"`
|
Name string `hcl:"name,optional"`
|
||||||
|
Description string `hcl:"description,optional"`
|
||||||
FromSources []string `hcl:"sources,optional"`
|
FromSources []string `hcl:"sources,optional"`
|
||||||
Config hcl.Body `hcl:",remain"`
|
Config hcl.Body `hcl:",remain"`
|
||||||
}
|
}
|
||||||
|
@ -70,6 +75,7 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnosti
|
||||||
}
|
}
|
||||||
|
|
||||||
build.Name = b.Name
|
build.Name = b.Name
|
||||||
|
build.Description = b.Description
|
||||||
|
|
||||||
for _, buildFrom := range b.FromSources {
|
for _, buildFrom := range b.FromSources {
|
||||||
ref := sourceRefFromString(buildFrom)
|
ref := sourceRefFromString(buildFrom)
|
||||||
|
|
|
@ -439,6 +439,13 @@ func (p *PackerConfig) EvaluateExpression(line string) (out string, exit bool, d
|
||||||
case line == "help":
|
case line == "help":
|
||||||
return PackerConsoleHelp, false, nil
|
return PackerConsoleHelp, false, nil
|
||||||
case line == "variables":
|
case line == "variables":
|
||||||
|
return p.printVariables(), false, nil
|
||||||
|
default:
|
||||||
|
return p.handleEval(line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PackerConfig) printVariables() string {
|
||||||
out := &strings.Builder{}
|
out := &strings.Builder{}
|
||||||
out.WriteString("> input-variables:\n\n")
|
out.WriteString("> input-variables:\n\n")
|
||||||
for _, v := range p.InputVariables {
|
for _, v := range p.InputVariables {
|
||||||
|
@ -450,11 +457,52 @@ func (p *PackerConfig) EvaluateExpression(line string) (out string, exit bool, d
|
||||||
val, _ := v.Value()
|
val, _ := v.Value()
|
||||||
fmt.Fprintf(out, "local.%s: %q\n", v.Name, PrintableCtyValue(val))
|
fmt.Fprintf(out, "local.%s: %q\n", v.Name, PrintableCtyValue(val))
|
||||||
}
|
}
|
||||||
|
return out.String()
|
||||||
return out.String(), false, nil
|
|
||||||
default:
|
|
||||||
return p.handleEval(line)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PackerConfig) printBuilds() string {
|
||||||
|
out := &strings.Builder{}
|
||||||
|
out.WriteString("> builds:\n")
|
||||||
|
for i, build := range p.Builds {
|
||||||
|
name := build.Name
|
||||||
|
if name == "" {
|
||||||
|
name = fmt.Sprintf("<unnamed build %d>", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, "\n > %s:\n", name)
|
||||||
|
if build.Description != "" {
|
||||||
|
fmt.Fprintf(out, "\n > Description: %s\n", build.Description)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, "\n sources:\n")
|
||||||
|
if len(build.Sources) == 0 {
|
||||||
|
fmt.Fprintf(out, "\n <no source>\n")
|
||||||
|
}
|
||||||
|
for _, source := range build.Sources {
|
||||||
|
fmt.Fprintf(out, "\n %s\n", source)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, "\n provisioners:\n\n")
|
||||||
|
if len(build.ProvisionerBlocks) == 0 {
|
||||||
|
fmt.Fprintf(out, " <no provisioner>\n")
|
||||||
|
}
|
||||||
|
for _, prov := range build.ProvisionerBlocks {
|
||||||
|
str := prov.PType
|
||||||
|
if prov.PName != "" {
|
||||||
|
str = strings.Join([]string{prov.PType, prov.PName}, ".")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, " %s\n", str)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, "\n post-processors:\n\n")
|
||||||
|
if len(build.PostProcessors) == 0 {
|
||||||
|
fmt.Fprintf(out, " <no post-processor>\n")
|
||||||
|
}
|
||||||
|
for _, pp := range build.PostProcessors {
|
||||||
|
str := pp.PType
|
||||||
|
if pp.PName != "" {
|
||||||
|
str = strings.Join([]string{pp.PType, pp.PName}, ".")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, " %s\n", str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PackerConfig) handleEval(line string) (out string, exit bool, diags hcl.Diagnostics) {
|
func (p *PackerConfig) handleEval(line string) (out string, exit bool, diags hcl.Diagnostics) {
|
||||||
|
@ -479,3 +527,12 @@ func (p *PackerConfig) FixConfig(_ packer.FixConfigOptions) (diags hcl.Diagnosti
|
||||||
// No Fixers exist for HCL2 configs so there is nothing to do here for now.
|
// No Fixers exist for HCL2 configs so there is nothing to do here for now.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PackerConfig) InspectConfig(opts packer.InspectConfigOptions) int {
|
||||||
|
|
||||||
|
ui := opts.Ui
|
||||||
|
ui.Say("Packer Inspect: HCL2 mode\n")
|
||||||
|
ui.Say(p.printVariables())
|
||||||
|
ui.Say(p.printBuilds())
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
123
packer/core.go
123
packer/core.go
|
@ -424,6 +424,129 @@ func (c *Core) EvaluateExpression(line string) (string, bool, hcl.Diagnostics) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Core) InspectConfig(opts InspectConfigOptions) int {
|
||||||
|
|
||||||
|
// Convenience...
|
||||||
|
ui := opts.Ui
|
||||||
|
tpl := c.Template
|
||||||
|
ui.Say("Packer Inspect: JSON mode")
|
||||||
|
|
||||||
|
// Description
|
||||||
|
if tpl.Description != "" {
|
||||||
|
ui.Say("Description:\n")
|
||||||
|
ui.Say(tpl.Description + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
if len(tpl.Variables) == 0 {
|
||||||
|
ui.Say("Variables:\n")
|
||||||
|
ui.Say(" <No variables>")
|
||||||
|
} else {
|
||||||
|
requiredHeader := false
|
||||||
|
for k, v := range tpl.Variables {
|
||||||
|
for _, sensitive := range tpl.SensitiveVariables {
|
||||||
|
if ok := strings.Compare(sensitive.Default, v.Default); ok == 0 {
|
||||||
|
v.Default = "<sensitive>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v.Required {
|
||||||
|
if !requiredHeader {
|
||||||
|
requiredHeader = true
|
||||||
|
ui.Say("Required variables:\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Machine("template-variable", k, v.Default, "1")
|
||||||
|
ui.Say(" " + k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if requiredHeader {
|
||||||
|
ui.Say("")
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Say("Optional variables and their defaults:\n")
|
||||||
|
keys := make([]string, 0, len(tpl.Variables))
|
||||||
|
max := 0
|
||||||
|
for k := range tpl.Variables {
|
||||||
|
keys = append(keys, k)
|
||||||
|
if len(k) > max {
|
||||||
|
max = len(k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(keys)
|
||||||
|
|
||||||
|
for _, k := range keys {
|
||||||
|
v := tpl.Variables[k]
|
||||||
|
if v.Required {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, sensitive := range tpl.SensitiveVariables {
|
||||||
|
if ok := strings.Compare(sensitive.Default, v.Default); ok == 0 {
|
||||||
|
v.Default = "<sensitive>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
padding := strings.Repeat(" ", max-len(k))
|
||||||
|
output := fmt.Sprintf(" %s%s = %s", k, padding, v.Default)
|
||||||
|
|
||||||
|
ui.Machine("template-variable", k, v.Default, "0")
|
||||||
|
ui.Say(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Say("")
|
||||||
|
|
||||||
|
// Builders
|
||||||
|
ui.Say("Builders:\n")
|
||||||
|
if len(tpl.Builders) == 0 {
|
||||||
|
ui.Say(" <No builders>")
|
||||||
|
} else {
|
||||||
|
keys := make([]string, 0, len(tpl.Builders))
|
||||||
|
max := 0
|
||||||
|
for k := range tpl.Builders {
|
||||||
|
keys = append(keys, k)
|
||||||
|
if len(k) > max {
|
||||||
|
max = len(k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(keys)
|
||||||
|
|
||||||
|
for _, k := range keys {
|
||||||
|
v := tpl.Builders[k]
|
||||||
|
padding := strings.Repeat(" ", max-len(k))
|
||||||
|
output := fmt.Sprintf(" %s%s", k, padding)
|
||||||
|
if v.Name != v.Type {
|
||||||
|
output = fmt.Sprintf("%s (%s)", output, v.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Machine("template-builder", k, v.Type)
|
||||||
|
ui.Say(output)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Say("")
|
||||||
|
|
||||||
|
// Provisioners
|
||||||
|
ui.Say("Provisioners:\n")
|
||||||
|
if len(tpl.Provisioners) == 0 {
|
||||||
|
ui.Say(" <No provisioners>")
|
||||||
|
} else {
|
||||||
|
for _, v := range tpl.Provisioners {
|
||||||
|
ui.Machine("template-provisioner", v.Type)
|
||||||
|
ui.Say(fmt.Sprintf(" %s", v.Type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Say("\nNote: If your build names contain user variables or template\n" +
|
||||||
|
"functions such as 'timestamp', these are processed at build time,\n" +
|
||||||
|
"and therefore only show in their raw form here.")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Core) FixConfig(opts FixConfigOptions) hcl.Diagnostics {
|
func (c *Core) FixConfig(opts FixConfigOptions) hcl.Diagnostics {
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ type Handler interface {
|
||||||
Evaluator
|
Evaluator
|
||||||
BuildGetter
|
BuildGetter
|
||||||
ConfigFixer
|
ConfigFixer
|
||||||
|
ConfigInspector
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate enumer -type FixConfigMode
|
//go:generate enumer -type FixConfigMode
|
||||||
|
@ -52,3 +53,12 @@ type ConfigFixer interface {
|
||||||
// FixConfig will output the config in a fixed manner.
|
// FixConfig will output the config in a fixed manner.
|
||||||
FixConfig(FixConfigOptions) hcl.Diagnostics
|
FixConfig(FixConfigOptions) hcl.Diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InspectConfigOptions struct {
|
||||||
|
Ui
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigInspector interface {
|
||||||
|
// Inspect will output self inspection for a configuration
|
||||||
|
InspectConfig(InspectConfigOptions) (ret int)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue