backport of commit 1f4f2aebca

This commit is contained in:
Lucas Bajolet
2024-06-07 18:38:20 +00:00
parent 7f407b1bbe
commit fbb0ce8e21
37 changed files with 2682 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
# Packer Test Plugin
This directory is meant to be a minimal plugin that we can use for testing Packer.
Any components defined in this plugin are not for use, as they virtually do nothing, and are only here to test Packer's core capabilitities
@@ -0,0 +1,35 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package dynamic
// packersdk.Artifact implementation
type Artifact struct {
// StateData should store data such as GeneratedData
// to be shared with post-processors
StateData map[string]interface{}
}
func (*Artifact) BuilderId() string {
return BuilderId
}
func (a *Artifact) Files() []string {
return []string{}
}
func (*Artifact) Id() string {
return ""
}
func (a *Artifact) String() string {
return ""
}
func (a *Artifact) State(name string) interface{} {
return a.StateData[name]
}
func (a *Artifact) Destroy() error {
return nil
}
@@ -0,0 +1,92 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,NestedFirst,NestedSecond
package dynamic
import (
"context"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer-plugin-sdk/common"
"github.com/hashicorp/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer-plugin-sdk/multistep/commonsteps"
"github.com/hashicorp/packer-plugin-sdk/packer"
"github.com/hashicorp/packer-plugin-sdk/template/config"
)
const BuilderId = "dynamic.builder"
type NestedSecond struct {
Name string `mapstructure:"name" required:"true"`
}
type NestedFirst struct {
Name string `mapstructure:"name" required:"true"`
Nesteds []NestedSecond `mapstructure:"extra" required:"false"`
}
type Config struct {
common.PackerConfig `mapstructure:",squash"`
Nesteds []NestedFirst `mapstructure:"extra" required:"false"`
}
type Builder struct {
config Config
runner multistep.Runner
}
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
func (b *Builder) Prepare(raws ...interface{}) (generatedVars []string, warnings []string, err error) {
err = config.Decode(&b.config, &config.DecodeOpts{
PluginType: "packer.builder.dynamic",
Interpolate: true,
}, raws...)
if err != nil {
return nil, nil, err
}
// Return the placeholder for the generated data that will become available to provisioners and post-processors.
// If the builder doesn't generate any data, just return an empty slice of string: []string{}
buildGeneratedData := []string{"GeneratedMockData"}
return buildGeneratedData, nil, nil
}
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
steps := []multistep.Step{}
steps = append(steps,
&StepSayConfig{
b.config,
},
new(commonsteps.StepProvision),
)
// Setup the state bag and initial state for the steps
state := new(multistep.BasicStateBag)
state.Put("hook", hook)
state.Put("ui", ui)
// Set the value of the generated data that will become available to provisioners.
// To share the data with post-processors, use the StateData in the artifact.
state.Put("generated_data", map[string]interface{}{
"GeneratedMockData": "mock-build-data",
})
// Run!
b.runner = commonsteps.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(ctx, state)
// If there was an error, return that
if err, ok := state.GetOk("error"); ok {
return nil, err.(error)
}
artifact := &Artifact{
// Add the builder generated data to the artifact StateData so that post-processors
// can access them.
StateData: map[string]interface{}{"generated_data": state.Get("generated_data")},
}
return artifact, nil
}
@@ -0,0 +1,95 @@
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
package dynamic
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
Nesteds []FlatNestedFirst `mapstructure:"extra" required:"false" cty:"extra" hcl:"extra"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
"extra": &hcldec.BlockListSpec{TypeName: "extra", Nested: hcldec.ObjectSpec((*FlatNestedFirst)(nil).HCL2Spec())},
}
return s
}
// FlatNestedFirst is an auto-generated flat version of NestedFirst.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatNestedFirst struct {
Name *string `mapstructure:"name" required:"true" cty:"name" hcl:"name"`
Nesteds []FlatNestedSecond `mapstructure:"extra" required:"false" cty:"extra" hcl:"extra"`
}
// FlatMapstructure returns a new FlatNestedFirst.
// FlatNestedFirst is an auto-generated flat version of NestedFirst.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*NestedFirst) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatNestedFirst)
}
// HCL2Spec returns the hcl spec of a NestedFirst.
// This spec is used by HCL to read the fields of NestedFirst.
// The decoded values from this spec will then be applied to a FlatNestedFirst.
func (*FlatNestedFirst) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
"extra": &hcldec.BlockListSpec{TypeName: "extra", Nested: hcldec.ObjectSpec((*FlatNestedSecond)(nil).HCL2Spec())},
}
return s
}
// FlatNestedSecond is an auto-generated flat version of NestedSecond.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatNestedSecond struct {
Name *string `mapstructure:"name" required:"true" cty:"name" hcl:"name"`
}
// FlatMapstructure returns a new FlatNestedSecond.
// FlatNestedSecond is an auto-generated flat version of NestedSecond.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*NestedSecond) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatNestedSecond)
}
// HCL2Spec returns the hcl spec of a NestedSecond.
// This spec is used by HCL to read the fields of NestedSecond.
// The decoded values from this spec will then be applied to a FlatNestedSecond.
func (*FlatNestedSecond) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
}
return s
}
@@ -0,0 +1,60 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package dynamic
import (
_ "embed"
"fmt"
"io/ioutil"
"os"
"os/exec"
"regexp"
"testing"
"github.com/hashicorp/packer-plugin-sdk/acctest"
)
//go:embed test-fixtures/template.pkr.hcl
var testBuilderHCL2Basic string
// Run with: PACKER_ACC=1 go test -count 1 -v ./builder/scaffolding/builder_acc_test.go -timeout=120m
func TestAccScaffoldingBuilder(t *testing.T) {
testCase := &acctest.PluginTestCase{
Name: "scaffolding_builder_basic_test",
Setup: func() error {
return nil
},
Teardown: func() error {
return nil
},
Template: testBuilderHCL2Basic,
Type: "scaffolding-my-builder",
Check: func(buildCommand *exec.Cmd, logfile string) error {
if buildCommand.ProcessState != nil {
if buildCommand.ProcessState.ExitCode() != 0 {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
logs, err := os.Open(logfile)
if err != nil {
return fmt.Errorf("Unable find %s", logfile)
}
defer logs.Close()
logsBytes, err := ioutil.ReadAll(logs)
if err != nil {
return fmt.Errorf("Unable to read %s", logfile)
}
logsString := string(logsBytes)
buildGeneratedDataLog := "scaffolding-my-builder.basic-example: build generated data: mock-build-data"
if matched, _ := regexp.MatchString(buildGeneratedDataLog+".*", logsString); !matched {
t.Fatalf("logs doesn't contain expected foo value %q", logsString)
}
return nil
},
}
acctest.TestPlugin(t, testCase)
}
@@ -0,0 +1,39 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package dynamic
import (
"context"
"fmt"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
// This is a definition of a builder step and should implement multistep.Step
type StepSayConfig struct {
cfg Config
}
// Run should execute the purpose of this step
func (s *StepSayConfig) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packersdk.Ui)
ui.Say("Dynamic builder invoked!")
for _, nf := range s.cfg.Nesteds {
ui.Say(fmt.Sprintf("Nested first: %s", nf.Name))
for _, ns := range nf.Nesteds {
ui.Say(fmt.Sprintf("Nested second: %s.%s", nf.Name, ns.Name))
}
}
// Determines that should continue to the next step
return multistep.ActionContinue
}
// Cleanup can be used to clean up any artifact created by the step.
// A step's clean up always run at the end of a build, regardless of whether provisioning succeeds or fails.
func (s *StepSayConfig) Cleanup(_ multistep.StateBag) {
// Nothing to clean
}
@@ -0,0 +1,18 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
source "scaffolding-my-builder" "basic-example" {
mock = "mock-config"
}
build {
sources = [
"source.scaffolding-my-builder.basic-example"
]
provisioner "shell-local" {
inline = [
"echo build generated data: ${build.GeneratedMockData}",
]
}
}
@@ -0,0 +1,66 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,NestedFirst,NestedSecond,DatasourceOutput
package dynamic
import (
"log"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer-plugin-sdk/hcl2helper"
"github.com/hashicorp/packer-plugin-sdk/template/config"
"github.com/zclconf/go-cty/cty"
)
type NestedSecond struct {
Name string `mapstructure:"name" required:"true"`
}
type NestedFirst struct {
Name string `mapstructure:"name" required:"true"`
Nesteds []NestedSecond `mapstructure:"extra" required:"false"`
}
type Config struct {
Nesteds []NestedFirst `mapstructure:"extra" required:"false"`
}
type Datasource struct {
config Config
}
type DatasourceOutput struct {
Status string `mapstructure:"data"`
}
func (d *Datasource) ConfigSpec() hcldec.ObjectSpec {
return d.config.FlatMapstructure().HCL2Spec()
}
func (d *Datasource) Configure(raws ...interface{}) error {
err := config.Decode(&d.config, nil, raws...)
if err != nil {
return err
}
return nil
}
func (d *Datasource) OutputSpec() hcldec.ObjectSpec {
return (&DatasourceOutput{}).FlatMapstructure().HCL2Spec()
}
func (d *Datasource) Execute() (cty.Value, error) {
log.Printf("[DATASOURCE-DYNAMIC] Executing datasource dynamic")
for _, nest := range d.config.Nesteds {
log.Printf("[DATASOURCE-DYNAMIC] - First nest: %s", nest.Name)
for _, nestedConfig := range nest.Nesteds {
log.Printf("[DATASOURCE-DYNAMIC] - Second nest: %s.%s", nest.Name, nestedConfig.Name)
}
}
output := DatasourceOutput{
Status: "OK",
}
return hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()), nil
}
@@ -0,0 +1,102 @@
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
package dynamic
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
Nesteds []FlatNestedFirst `mapstructure:"extra" required:"false" cty:"extra" hcl:"extra"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"extra": &hcldec.BlockListSpec{TypeName: "extra", Nested: hcldec.ObjectSpec((*FlatNestedFirst)(nil).HCL2Spec())},
}
return s
}
// FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatDatasourceOutput struct {
Status *string `mapstructure:"data" cty:"data" hcl:"data"`
}
// FlatMapstructure returns a new FlatDatasourceOutput.
// FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*DatasourceOutput) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatDatasourceOutput)
}
// HCL2Spec returns the hcl spec of a DatasourceOutput.
// This spec is used by HCL to read the fields of DatasourceOutput.
// The decoded values from this spec will then be applied to a FlatDatasourceOutput.
func (*FlatDatasourceOutput) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"data": &hcldec.AttrSpec{Name: "data", Type: cty.String, Required: false},
}
return s
}
// FlatNestedFirst is an auto-generated flat version of NestedFirst.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatNestedFirst struct {
Name *string `mapstructure:"name" required:"true" cty:"name" hcl:"name"`
Nesteds []FlatNestedSecond `mapstructure:"extra" required:"false" cty:"extra" hcl:"extra"`
}
// FlatMapstructure returns a new FlatNestedFirst.
// FlatNestedFirst is an auto-generated flat version of NestedFirst.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*NestedFirst) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatNestedFirst)
}
// HCL2Spec returns the hcl spec of a NestedFirst.
// This spec is used by HCL to read the fields of NestedFirst.
// The decoded values from this spec will then be applied to a FlatNestedFirst.
func (*FlatNestedFirst) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
"extra": &hcldec.BlockListSpec{TypeName: "extra", Nested: hcldec.ObjectSpec((*FlatNestedSecond)(nil).HCL2Spec())},
}
return s
}
// FlatNestedSecond is an auto-generated flat version of NestedSecond.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatNestedSecond struct {
Name *string `mapstructure:"name" required:"true" cty:"name" hcl:"name"`
}
// FlatMapstructure returns a new FlatNestedSecond.
// FlatNestedSecond is an auto-generated flat version of NestedSecond.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*NestedSecond) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatNestedSecond)
}
// HCL2Spec returns the hcl spec of a NestedSecond.
// This spec is used by HCL to read the fields of NestedSecond.
// The decoded values from this spec will then be applied to a FlatNestedSecond.
func (*FlatNestedSecond) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
}
return s
}
@@ -0,0 +1,65 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package dynamic
import (
_ "embed"
"fmt"
"io/ioutil"
"os"
"os/exec"
"regexp"
"testing"
"github.com/hashicorp/packer-plugin-sdk/acctest"
)
//go:embed test-fixtures/template.pkr.hcl
var testDatasourceHCL2Basic string
// Run with: PACKER_ACC=1 go test -count 1 -v ./datasource/scaffolding/data_acc_test.go -timeout=120m
func TestAccScaffoldingDatasource(t *testing.T) {
testCase := &acctest.PluginTestCase{
Name: "scaffolding_datasource_basic_test",
Setup: func() error {
return nil
},
Teardown: func() error {
return nil
},
Template: testDatasourceHCL2Basic,
Type: "scaffolding-my-datasource",
Check: func(buildCommand *exec.Cmd, logfile string) error {
if buildCommand.ProcessState != nil {
if buildCommand.ProcessState.ExitCode() != 0 {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
logs, err := os.Open(logfile)
if err != nil {
return fmt.Errorf("Unable find %s", logfile)
}
defer logs.Close()
logsBytes, err := ioutil.ReadAll(logs)
if err != nil {
return fmt.Errorf("Unable to read %s", logfile)
}
logsString := string(logsBytes)
fooLog := "null.basic-example: foo: foo-value"
barLog := "null.basic-example: bar: bar-value"
if matched, _ := regexp.MatchString(fooLog+".*", logsString); !matched {
t.Fatalf("logs doesn't contain expected foo value %q", logsString)
}
if matched, _ := regexp.MatchString(barLog+".*", logsString); !matched {
t.Fatalf("logs doesn't contain expected bar value %q", logsString)
}
return nil
},
}
acctest.TestPlugin(t, testCase)
}
@@ -0,0 +1,28 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
data "scaffolding-my-datasource" "test" {
mock = "mock-config"
}
locals {
foo = data.scaffolding-my-datasource.test.foo
bar = data.scaffolding-my-datasource.test.bar
}
source "null" "basic-example" {
communicator = "none"
}
build {
sources = [
"source.null.basic-example"
]
provisioner "shell-local" {
inline = [
"echo foo: ${local.foo}",
"echo bar: ${local.bar}",
]
}
}
@@ -0,0 +1,52 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,DatasourceOutput
package parrot
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer-plugin-sdk/hcl2helper"
"github.com/hashicorp/packer-plugin-sdk/template/config"
"github.com/zclconf/go-cty/cty"
)
type Config struct {
Input []string `mapstructure:"input" required:"true"`
}
type Datasource struct {
config Config
}
type DatasourceOutput struct {
Output []string `mapstructure:"out"`
}
func (d *Datasource) ConfigSpec() hcldec.ObjectSpec {
return d.config.FlatMapstructure().HCL2Spec()
}
func (d *Datasource) Configure(raws ...interface{}) error {
err := config.Decode(&d.config, nil, raws...)
if err != nil {
return err
}
return nil
}
func (d *Datasource) OutputSpec() hcldec.ObjectSpec {
return (&DatasourceOutput{}).FlatMapstructure().HCL2Spec()
}
func (d *Datasource) Execute() (cty.Value, error) {
out := []string{}
for _, d := range d.config.Input {
out = append(out, d)
}
output := DatasourceOutput{
Output: out,
}
return hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()), nil
}
@@ -0,0 +1,54 @@
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
package parrot
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
Input []string `mapstructure:"input" required:"true" cty:"input" hcl:"input"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"input": &hcldec.AttrSpec{Name: "input", Type: cty.List(cty.String), Required: false},
}
return s
}
// FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatDatasourceOutput struct {
Output []string `mapstructure:"out" cty:"out" hcl:"out"`
}
// FlatMapstructure returns a new FlatDatasourceOutput.
// FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*DatasourceOutput) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatDatasourceOutput)
}
// HCL2Spec returns the hcl spec of a DatasourceOutput.
// This spec is used by HCL to read the fields of DatasourceOutput.
// The decoded values from this spec will then be applied to a FlatDatasourceOutput.
func (*FlatDatasourceOutput) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"out": &hcldec.AttrSpec{Name: "out", Type: cty.List(cty.String), Required: false},
}
return s
}
@@ -0,0 +1,63 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,DatasourceOutput
package sleeper
import (
"log"
"time"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer-plugin-sdk/hcl2helper"
"github.com/hashicorp/packer-plugin-sdk/template/config"
"github.com/zclconf/go-cty/cty"
)
type Config struct {
Duration string `mapstructure:"duration" required:"true"`
}
type Datasource struct {
config Config
durationTime time.Duration
}
type DatasourceOutput struct {
Status bool `mapstructure:"status"`
}
func (d *Datasource) ConfigSpec() hcldec.ObjectSpec {
return d.config.FlatMapstructure().HCL2Spec()
}
func (d *Datasource) Configure(raws ...interface{}) error {
err := config.Decode(&d.config, nil, raws...)
if err != nil {
return err
}
dt, err := time.ParseDuration(d.config.Duration)
if err != nil {
return err
}
d.durationTime = dt
return nil
}
func (d *Datasource) OutputSpec() hcldec.ObjectSpec {
return (&DatasourceOutput{}).FlatMapstructure().HCL2Spec()
}
func (d *Datasource) Execute() (cty.Value, error) {
log.Printf("[sleeper] Sleeping for %s", d.config.Duration)
time.Sleep(d.durationTime)
log.Printf("[sleeper] Done sleeping!")
output := DatasourceOutput{
Status: true,
}
return hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()), nil
}
@@ -0,0 +1,54 @@
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
package sleeper
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
Duration *string `mapstructure:"duration" required:"true" cty:"duration" hcl:"duration"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"duration": &hcldec.AttrSpec{Name: "duration", Type: cty.String, Required: false},
}
return s
}
// FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatDatasourceOutput struct {
Status *bool `mapstructure:"status" cty:"status" hcl:"status"`
}
// FlatMapstructure returns a new FlatDatasourceOutput.
// FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*DatasourceOutput) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatDatasourceOutput)
}
// HCL2Spec returns the hcl spec of a DatasourceOutput.
// This spec is used by HCL to read the fields of DatasourceOutput.
// The decoded values from this spec will then be applied to a FlatDatasourceOutput.
func (*FlatDatasourceOutput) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"status": &hcldec.AttrSpec{Name: "status", Type: cty.Bool, Required: false},
}
return s
}
+78
View File
@@ -0,0 +1,78 @@
# Scaffolding Plugins
<!--
Include a short overview about the plugin.
This document is a great location for creating a table of contents for each
of the components the plugin may provide. This document should load automatically
when navigating to the docs directory for a plugin.
-->
## Installation
### Using pre-built releases
#### Using the `packer init` command
Starting from version 1.7, Packer supports a new `packer init` command allowing
automatic installation of Packer plugins. Read the
[Packer documentation](https://www.packer.io/docs/commands/init) for more information.
To install this plugin, copy and paste this code into your Packer configuration .
Then, run [`packer init`](https://www.packer.io/docs/commands/init).
```hcl
packer {
required_plugins {
name = {
version = ">= 0.0.1"
source = "github.com/hashicorp/name"
}
}
}
```
#### Manual installation
You can find pre-built binary releases of the plugin [here](https://github.com/hashicorp/packer-plugin-name/releases).
Once you have downloaded the latest archive corresponding to your target OS,
uncompress it to retrieve the plugin binary file corresponding to your platform.
To install the plugin, please follow the Packer documentation on
[installing a plugin](https://www.packer.io/docs/extending/plugins/#installing-plugins).
#### From Source
If you prefer to build the plugin from its source code, clone the GitHub
repository locally and run the command `go build` from the root
directory. Upon successful compilation, a `packer-plugin-name` plugin
binary file can be found in the root directory.
To install the compiled plugin, please follow the official Packer documentation
on [installing a plugin](https://www.packer.io/docs/extending/plugins/#installing-plugins).
## Plugin Contents
The Scaffolding plugin is intended as a starting point for creating Packer plugins, containing:
### Builders
- [builder](/docs/builders/builder-name.mdx) - The scaffolding builder is used to create endless Packer
plugins using a consistent plugin structure.
### Provisioners
- [provisioner](/docs/provisioners/provisioner-name.mdx) - The scaffolding provisioner is used to provisioner
Packer builds.
### Post-processors
- [post-processor](/docs/post-processors/postprocessor-name.mdx) - The scaffolding post-processor is used to
export scaffolding builds.
### Data Sources
- [data source](/docs/datasources/datasource-name.mdx) - The scaffolding data source is used to
export scaffolding data.
@@ -0,0 +1,63 @@
---
description: >
The scaffolding builder is used to create endless Packer plugins using
a consistent plugin structure.
page_title: Scaffolding - Builders
nav_title: Scaffolding
---
# Scaffolding
Type: `scaffolding`
<!--
Include a short description about the builder. This is a good place
to call out what the builder does, and any requirements for the given
builder environment. See https://www.packer.io/docs/builders/null
-->
The scaffolding builder is used to create endless Packer plugins using
a consistent plugin structure.
<!-- Builder Configuration Fields -->
### Required
- `mock` (string) - The name of the mock to use for the Scaffolding API.
<!--
Optional Configuration Fields
Configuration options that are not required or have reasonable defaults
should be listed under the optionals section. Defaults values should be
noted in the description of the field
-->
### Optional
- `mock_api_url` (string) - The Scaffolding API endpoint to connect to.
Defaults to https://example.com
<!--
A basic example on the usage of the builder. Multiple examples
can be provided to highlight various build configurations.
-->
### Example Usage
```hcl
source "scaffolding" "example" {
mock = "bird"
}
build {
sources = ["source.scaffolding.example"]
}
```
@@ -0,0 +1,78 @@
---
description: >
The scaffolding data source is used to create endless Packer plugins using
a consistent plugin structure.
page_title: Scaffolding - Data Sources
nav_title: Scaffolding
---
# Scaffolding
Type: `scaffolding`
<!--
Include a short description about the data source. This is a good place
to call out what the data source does, and any requirements for the given
data source environment. See https://www.packer.io/docs/datasources/amazon-ami
-->
The scaffolding data source is used to create endless Packer plugins using
a consistent plugin structure.
<!-- Data source Configuration Fields -->
### Required
- `mock` (string) - The name of the mock to use for the Scaffolding API.
<!--
Optional Configuration Fields
Configuration options that are not required or have reasonable defaults
should be listed under the optionals section. Defaults values should be
noted in the description of the field
-->
### Optional
- `mock_api_url` (string) - The Scaffolding API endpoint to connect to.
Defaults to https://example.com
<!--
A basic example on the usage of the data source. Multiple examples
can be provided to highlight various build configurations.
-->
### OutPut
- `foo` (string) - The Scaffolding output foo value.
- `bar` (string) - The Scaffolding output bar value.
<!--
A basic example on the usage of the data source. Multiple examples
can be provided to highlight various build configurations.
-->
### Example Usage
```hcl
data "scaffolding" "example" {
mock = "bird"
}
source "scaffolding" "example" {
mock = data.scaffolding.example.foo
}
build {
sources = ["source.scaffolding.example"]
}
```
@@ -0,0 +1,59 @@
---
description: >
The scaffolding post-processor is used to export Packer Scaffolding builds.
page_title: Scaffolding - Post-Processors
nav_title: Scaffolding
---
# Scaffolding
Type: `scaffolding`
<!--
Include a short description about the post-processor. This is a good place
to call out what the post-processor does, and any additional text that might
be helpful to a user. See https://www.packer.io/docs/provisioners/null
-->
The scaffolding post-processor is used to export Packer Scaffolding builds.
<!-- Post-Processor Configuration Fields -->
### Required
- `mock` (string) - The output path where to save exported build to.
<!--
Optional Configuration Fields
Configuration options that are not required or have reasonable defaults
should be listed under the optionals section. Defaults values should be
noted in the description of the field
-->
### Optional
<!--
A basic example on the usage of the post-processor. Multiple examples
can be provided to highlight various configurations.
-->
### Example Usage
```hcl
source "scaffolding" "example" {
mock = "jay"
}
build {
sources = ["source.scaffolding.example"]
post-processor "scaffolding" {
mock = "builds/scaffolding.box"
}
}
```
@@ -0,0 +1,62 @@
---
description: >
The scaffolding provisioner is used to provisioner Packer builds.
page_title: Scaffolding - Provisioners
nav_title: Scaffolding
---
# Scaffolding
Type: `scaffolding`
<!--
Include a short description about the provisioner. This is a good place
to call out what the provisioner does, and any additional text that might
be helpful to a user. See https://www.packer.io/docs/provisioners/null
-->
The scaffolding provisioner is used to provisioner Packer builds.
<!-- Provisioner Configuration Fields -->
### Required
- `mock` (string) - The name of the mock string to display.
<!--
Optional Configuration Fields
Configuration options that are not required or have reasonable defaults
should be listed under the optionals section. Defaults values should be
noted in the description of the field
-->
### Optional
<!--
A basic example on the usage of the provisioner. Multiple examples
can be provided to highlight various configurations.
-->
### Example Usage
```hcl
source "null" "example" {
communicator = "none"
}
build {
source "null.example" {
name = "jay"
}
provisioner "scaffolding" {
mock = "mocking ${source.name}"
}
}
```
+20
View File
@@ -0,0 +1,20 @@
## The Example Folder
This folder must contain a fully working example of the plugin usage. The example must define the `required_plugins`
block. A pre-defined GitHub Action will run `packer init`, `packer validate`, and `packer build` to test your plugin
with the latest version available of Packer.
The folder can contain multiple HCL2 compatible files. The action will execute Packer at this folder level
running `packer init -upgrade .` and `packer build .`.
If the plugin requires authentication, the configuration should be provided via GitHub Secrets and set as environment
variables in the [test-plugin-example.yml](/.github/workflows/test-plugin-example.yml) file. Example:
```yml
- name: Build
working-directory: ${{ github.event.inputs.folder }}
run: PACKER_LOG=${{ github.event.inputs.logs }} packer build .
env:
AUTH_KEY: ${{ secrets.AUTH_KEY }}
AUTH_PASSWORD: ${{ secrets.AUTH_PASSWORD }}
```
+43
View File
@@ -0,0 +1,43 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
packer {
required_plugins {
scaffolding = {
version = ">=v0.1.0"
source = "github.com/hashicorp/scaffolding"
}
}
}
source "scaffolding-my-builder" "foo-example" {
mock = local.foo
}
source "scaffolding-my-builder" "bar-example" {
mock = local.bar
}
build {
sources = [
"source.scaffolding-my-builder.foo-example",
]
source "source.scaffolding-my-builder.bar-example" {
name = "bar"
}
provisioner "scaffolding-my-provisioner" {
only = ["scaffolding-my-builder.foo-example"]
mock = "foo: ${local.foo}"
}
provisioner "scaffolding-my-provisioner" {
only = ["scaffolding-my-builder.bar"]
mock = "bar: ${local.bar}"
}
post-processor "scaffolding-my-post-processor" {
mock = "post-processor mock-config"
}
}
+6
View File
@@ -0,0 +1,6 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
data "scaffolding-my-datasource" "mock-data" {
mock = "mock-config"
}
@@ -0,0 +1,7 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
locals {
foo = data.scaffolding-my-datasource.mock-data.foo
bar = data.scaffolding-my-datasource.mock-data.bar
}
+97
View File
@@ -0,0 +1,97 @@
module github.com/hashicorp/packer-plugin-tester
go 1.20
require (
github.com/hashicorp/hcl/v2 v2.19.1
github.com/hashicorp/packer-plugin-sdk v0.5.3
github.com/zclconf/go-cty v1.13.3
)
require (
cloud.google.com/go v0.105.0 // indirect
cloud.google.com/go/compute v1.12.1 // indirect
cloud.google.com/go/compute/metadata v0.1.1 // indirect
cloud.google.com/go/iam v0.6.0 // indirect
cloud.google.com/go/storage v1.27.0 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/aws/aws-sdk-go v1.45.6 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/dylanmei/iso8601 v0.1.0 // indirect
github.com/fatih/color v1.14.1 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gofrs/uuid v4.0.0+incompatible // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.6.0 // indirect
github.com/hashicorp/consul/api v1.25.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter/gcs/v2 v2.2.1 // indirect
github.com/hashicorp/go-getter/s3/v2 v2.2.1 // indirect
github.com/hashicorp/go-getter/v2 v2.2.1 // indirect
github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/hashicorp/vault/api v1.10.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/klauspost/compress v1.11.2 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect
github.com/masterzen/winrm v0.0.0-20210623064412-3b76017826b0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mitchellh/go-fs v0.0.0-20180402235330-b7b9ca407fff // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/iochan v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db // indirect
github.com/pkg/sftp v1.13.2 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/ugorji/go/codec v1.2.6 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
go.opencensus.io v0.23.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.1.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.101.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect
google.golang.org/grpc v1.50.1 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)
replace github.com/zclconf/go-cty => github.com/nywilken/go-cty v1.13.3 // added by packer-sdc fix as noted in github.com/hashicorp/packer-plugin-sdk/issues/187
File diff suppressed because it is too large Load Diff
+34
View File
@@ -0,0 +1,34 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package main
import (
"fmt"
"os"
"github.com/hashicorp/packer-plugin-sdk/plugin"
"github.com/hashicorp/packer-plugin-tester/builder/dynamic"
dynamicDS "github.com/hashicorp/packer-plugin-tester/datasource/dynamic"
"github.com/hashicorp/packer-plugin-tester/datasource/parrot"
"github.com/hashicorp/packer-plugin-tester/datasource/sleeper"
dynamicPP "github.com/hashicorp/packer-plugin-tester/post-processor/dynamic"
dynamicProv "github.com/hashicorp/packer-plugin-tester/provisioner/dynamic"
"github.com/hashicorp/packer-plugin-tester/version"
)
func main() {
pps := plugin.NewSet()
pps.RegisterBuilder("dynamic", new(dynamic.Builder))
pps.RegisterProvisioner("dynamic", new(dynamicProv.Provisioner))
pps.RegisterPostProcessor("dynamic", new(dynamicPP.PostProcessor))
pps.RegisterDatasource("dynamic", new(dynamicDS.Datasource))
pps.RegisterDatasource("parrot", new(parrot.Datasource))
pps.RegisterDatasource("sleeper", new(sleeper.Datasource))
pps.SetVersion(version.PluginVersion)
err := pps.Run()
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
}
@@ -0,0 +1,62 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,NestedFirst,NestedSecond
package dynamic
import (
"context"
"fmt"
"github.com/hashicorp/hcl/v2/hcldec"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
"github.com/hashicorp/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
)
type NestedSecond struct {
Name string `mapstructure:"name" required:"true"`
}
type NestedFirst struct {
Name string `mapstructure:"name" required:"true"`
Nesteds []NestedSecond `mapstructure:"extra" required:"false"`
}
type Config struct {
Nesteds []NestedFirst `mapstructure:"extra" required:"false"`
ctx interpolate.Context
}
type PostProcessor struct {
config Config
}
func (p *PostProcessor) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
func (p *PostProcessor) Configure(raws ...interface{}) error {
err := config.Decode(&p.config, &config.DecodeOpts{
PluginType: "packer.post-processor.dynamic",
Interpolate: true,
InterpolateContext: &p.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{},
},
}, raws...)
if err != nil {
return err
}
return nil
}
func (p *PostProcessor) PostProcess(ctx context.Context, ui packersdk.Ui, source packersdk.Artifact) (packersdk.Artifact, bool, bool, error) {
ui.Say(fmt.Sprintf("Called dynamic post-processor"))
for _, nst := range p.config.Nesteds {
ui.Say(fmt.Sprintf("Post-processor: nested one %s", nst.Name))
for _, sec := range nst.Nesteds {
ui.Say(fmt.Sprintf("Post-processor: nested second %s.%s", nst.Name, sec.Name))
}
}
return source, true, true, nil
}
@@ -0,0 +1,79 @@
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
package dynamic
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
Nesteds []FlatNestedFirst `mapstructure:"extra" required:"false" cty:"extra" hcl:"extra"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"extra": &hcldec.BlockListSpec{TypeName: "extra", Nested: hcldec.ObjectSpec((*FlatNestedFirst)(nil).HCL2Spec())},
}
return s
}
// FlatNestedFirst is an auto-generated flat version of NestedFirst.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatNestedFirst struct {
Name *string `mapstructure:"name" required:"true" cty:"name" hcl:"name"`
Nesteds []FlatNestedSecond `mapstructure:"extra" required:"false" cty:"extra" hcl:"extra"`
}
// FlatMapstructure returns a new FlatNestedFirst.
// FlatNestedFirst is an auto-generated flat version of NestedFirst.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*NestedFirst) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatNestedFirst)
}
// HCL2Spec returns the hcl spec of a NestedFirst.
// This spec is used by HCL to read the fields of NestedFirst.
// The decoded values from this spec will then be applied to a FlatNestedFirst.
func (*FlatNestedFirst) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
"extra": &hcldec.BlockListSpec{TypeName: "extra", Nested: hcldec.ObjectSpec((*FlatNestedSecond)(nil).HCL2Spec())},
}
return s
}
// FlatNestedSecond is an auto-generated flat version of NestedSecond.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatNestedSecond struct {
Name *string `mapstructure:"name" required:"true" cty:"name" hcl:"name"`
}
// FlatMapstructure returns a new FlatNestedSecond.
// FlatNestedSecond is an auto-generated flat version of NestedSecond.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*NestedSecond) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatNestedSecond)
}
// HCL2Spec returns the hcl spec of a NestedSecond.
// This spec is used by HCL to read the fields of NestedSecond.
// The decoded values from this spec will then be applied to a FlatNestedSecond.
func (*FlatNestedSecond) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
}
return s
}

Some files were not shown because too many files have changed in this diff Show More