Fix HCL2 code generation for slices within another slice (#8669)
This commit is contained in:
parent
df18187032
commit
08b0bd1d2c
|
@ -120,7 +120,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
|
||||
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
|
||||
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
|
||||
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
|
||||
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"command_wrapper": &hcldec.AttrSpec{Name: "command_wrapper", Type: cty.String, Required: false},
|
||||
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
|
||||
"device_path": &hcldec.AttrSpec{Name: "device_path", Type: cty.String, Required: false},
|
||||
|
|
|
@ -78,7 +78,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"mount_partition": &hcldec.AttrSpec{Name: "mount_partition", Type: cty.String, Required: false},
|
||||
"mount_path": &hcldec.AttrSpec{Name: "mount_path", Type: cty.String, Required: false},
|
||||
"post_mount_commands": &hcldec.AttrSpec{Name: "post_mount_commands", Type: cty.List(cty.String), Required: false},
|
||||
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
|
||||
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
|
||||
"temporary_os_disk_name": &hcldec.AttrSpec{Name: "temporary_os_disk_name", Type: cty.String, Required: false},
|
||||
"os_disk_size_gb": &hcldec.AttrSpec{Name: "os_disk_size_gb", Type: cty.Number, Required: false},
|
||||
|
|
|
@ -174,7 +174,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"chroot_disk_size": &hcldec.AttrSpec{Name: "chroot_disk_size", Type: cty.Number, Required: false},
|
||||
"chroot_disk_type": &hcldec.AttrSpec{Name: "chroot_disk_type", Type: cty.String, Required: false},
|
||||
"chroot_mount_path": &hcldec.AttrSpec{Name: "chroot_mount_path", Type: cty.String, Required: false},
|
||||
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
|
||||
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"chroot_copy_files": &hcldec.AttrSpec{Name: "chroot_copy_files", Type: cty.List(cty.String), Required: false},
|
||||
"chroot_command_wrapper": &hcldec.AttrSpec{Name: "chroot_command_wrapper", Type: cty.String, Required: false},
|
||||
"mount_options": &hcldec.AttrSpec{Name: "mount_options", Type: cty.List(cty.String), Required: false},
|
||||
|
|
|
@ -103,7 +103,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
|
||||
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
|
||||
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
|
||||
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
|
||||
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"command_wrapper": &hcldec.AttrSpec{Name: "command_wrapper", Type: cty.String, Required: false},
|
||||
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
|
||||
"device_path": &hcldec.AttrSpec{Name: "device_path", Type: cty.String, Required: false},
|
||||
|
|
|
@ -135,8 +135,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"memory": &hcldec.AttrSpec{Name: "memory", Type: cty.Number, Required: false},
|
||||
"sound": &hcldec.AttrSpec{Name: "sound", Type: cty.Bool, Required: false},
|
||||
"usb": &hcldec.AttrSpec{Name: "usb", Type: cty.Bool, Required: false},
|
||||
"prlctl": &hcldec.BlockListSpec{TypeName: "prlctl", Nested: &hcldec.AttrSpec{Name: "prlctl", Type: cty.List(cty.String), Required: false}},
|
||||
"prlctl_post": &hcldec.BlockListSpec{TypeName: "prlctl_post", Nested: &hcldec.AttrSpec{Name: "prlctl_post", Type: cty.List(cty.String), Required: false}},
|
||||
"prlctl": &hcldec.AttrSpec{Name: "prlctl", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"prlctl_post": &hcldec.AttrSpec{Name: "prlctl_post", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"prlctl_version_file": &hcldec.AttrSpec{Name: "prlctl_version_file", Type: cty.String, Required: false},
|
||||
"shutdown_command": &hcldec.AttrSpec{Name: "shutdown_command", Type: cty.String, Required: false},
|
||||
"shutdown_timeout": &hcldec.AttrSpec{Name: "shutdown_timeout", Type: cty.String, Required: false},
|
||||
|
|
|
@ -101,8 +101,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false},
|
||||
"floppy_label": &hcldec.AttrSpec{Name: "floppy_label", Type: cty.String, Required: false},
|
||||
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
|
||||
"prlctl": &hcldec.BlockListSpec{TypeName: "prlctl", Nested: &hcldec.AttrSpec{Name: "prlctl", Type: cty.List(cty.String), Required: false}},
|
||||
"prlctl_post": &hcldec.BlockListSpec{TypeName: "prlctl_post", Nested: &hcldec.AttrSpec{Name: "prlctl_post", Type: cty.List(cty.String), Required: false}},
|
||||
"prlctl": &hcldec.AttrSpec{Name: "prlctl", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"prlctl_post": &hcldec.AttrSpec{Name: "prlctl_post", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"prlctl_version_file": &hcldec.AttrSpec{Name: "prlctl_version_file", Type: cty.String, Required: false},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
|
|
|
@ -210,7 +210,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"memory": &hcldec.AttrSpec{Name: "memory", Type: cty.Number, Required: false},
|
||||
"net_device": &hcldec.AttrSpec{Name: "net_device", Type: cty.String, Required: false},
|
||||
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
|
||||
"qemuargs": &hcldec.BlockListSpec{TypeName: "qemuargs", Nested: &hcldec.AttrSpec{Name: "qemuargs", Type: cty.List(cty.String), Required: false}},
|
||||
"qemuargs": &hcldec.AttrSpec{Name: "qemuargs", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"qemu_binary": &hcldec.AttrSpec{Name: "qemu_binary", Type: cty.String, Required: false},
|
||||
"qmp_enable": &hcldec.AttrSpec{Name: "qmp_enable", Type: cty.Bool, Required: false},
|
||||
"qmp_socket_path": &hcldec.AttrSpec{Name: "qmp_socket_path", Type: cty.String, Required: false},
|
||||
|
|
|
@ -215,8 +215,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"memory": &hcldec.AttrSpec{Name: "memory", Type: cty.Number, Required: false},
|
||||
"sound": &hcldec.AttrSpec{Name: "sound", Type: cty.String, Required: false},
|
||||
"usb": &hcldec.AttrSpec{Name: "usb", Type: cty.Bool, Required: false},
|
||||
"vboxmanage": &hcldec.BlockListSpec{TypeName: "vboxmanage", Nested: &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.String), Required: false}},
|
||||
"vboxmanage_post": &hcldec.BlockListSpec{TypeName: "vboxmanage_post", Nested: &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.String), Required: false}},
|
||||
"vboxmanage": &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"vboxmanage_post": &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false},
|
||||
"bundle_iso": &hcldec.AttrSpec{Name: "bundle_iso", Type: cty.Bool, Required: false},
|
||||
"guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false},
|
||||
|
|
|
@ -190,8 +190,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"post_shutdown_delay": &hcldec.AttrSpec{Name: "post_shutdown_delay", Type: cty.String, Required: false},
|
||||
"disable_shutdown": &hcldec.AttrSpec{Name: "disable_shutdown", Type: cty.Bool, Required: false},
|
||||
"acpi_shutdown": &hcldec.AttrSpec{Name: "acpi_shutdown", Type: cty.Bool, Required: false},
|
||||
"vboxmanage": &hcldec.BlockListSpec{TypeName: "vboxmanage", Nested: &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.String), Required: false}},
|
||||
"vboxmanage_post": &hcldec.BlockListSpec{TypeName: "vboxmanage_post", Nested: &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.String), Required: false}},
|
||||
"vboxmanage": &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"vboxmanage_post": &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false},
|
||||
"guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false},
|
||||
"checksum": &hcldec.AttrSpec{Name: "checksum", Type: cty.String, Required: false},
|
||||
|
|
|
@ -186,8 +186,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"post_shutdown_delay": &hcldec.AttrSpec{Name: "post_shutdown_delay", Type: cty.String, Required: false},
|
||||
"disable_shutdown": &hcldec.AttrSpec{Name: "disable_shutdown", Type: cty.Bool, Required: false},
|
||||
"acpi_shutdown": &hcldec.AttrSpec{Name: "acpi_shutdown", Type: cty.Bool, Required: false},
|
||||
"vboxmanage": &hcldec.BlockListSpec{TypeName: "vboxmanage", Nested: &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.String), Required: false}},
|
||||
"vboxmanage_post": &hcldec.BlockListSpec{TypeName: "vboxmanage_post", Nested: &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.String), Required: false}},
|
||||
"vboxmanage": &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"vboxmanage_post": &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false},
|
||||
"guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false},
|
||||
"guest_additions_path": &hcldec.AttrSpec{Name: "guest_additions_path", Type: cty.String, Required: false},
|
||||
|
|
|
@ -201,6 +201,10 @@ type StructDef struct {
|
|||
Struct *types.Struct
|
||||
}
|
||||
|
||||
// outputStructHCL2SpecBody writes the map[string]hcldec.Spec that defines the HCL spec of a
|
||||
// struct. Based on the layout of said struct.
|
||||
// If a field of s is a struct then the HCL2Spec() function of that struct will be called, otherwise a
|
||||
// cty.Type is outputed.
|
||||
func outputStructHCL2SpecBody(w io.Writer, s *types.Struct) {
|
||||
fmt.Fprintf(w, "s := map[string]hcldec.Spec{\n")
|
||||
|
||||
|
@ -217,72 +221,99 @@ func outputStructHCL2SpecBody(w io.Writer, s *types.Struct) {
|
|||
fmt.Fprintln(w, `return s`)
|
||||
}
|
||||
|
||||
// outputHCL2SpecField is called on each field of a struct.
|
||||
// outputHCL2SpecField writes the values of the `map[string]hcldec.Spec` map
|
||||
// supposed to define the HCL spec of a struct.
|
||||
func outputHCL2SpecField(w io.Writer, accessor string, fieldType types.Type, tag *structtag.Tags) {
|
||||
if m2h, err := tag.Get(""); err == nil && m2h.HasOption("self-defined") {
|
||||
fmt.Fprintf(w, `(&%s{}).HCL2Spec()`, fieldType.String())
|
||||
return
|
||||
}
|
||||
spec, _ := writeSpecField(accessor, fieldType)
|
||||
switch spec := spec.(type) {
|
||||
case string:
|
||||
fmt.Fprintf(w, spec)
|
||||
default:
|
||||
fmt.Fprintf(w, `%#v`, spec)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// goFieldToCtyType is a recursive method that returns a cty.Type (or a string) based on the fieldType.
|
||||
// goFieldToCtyType returns the values of the `map[string]hcldec.Spec` map
|
||||
// supposed to define the HCL spec of a struct.
|
||||
// To allow it to be recursive, the method returns two values: an interface that can either be
|
||||
// a cty.Type or a string. The second argument is used for recursion and is the
|
||||
// type that will be used by the parent. For example when fieldType is a []string; a
|
||||
// recursive goFieldToCtyType call will return a cty.String.
|
||||
func writeSpecField(accessor string, fieldType types.Type) (interface{}, cty.Type) {
|
||||
switch f := fieldType.(type) {
|
||||
case *types.Pointer:
|
||||
outputHCL2SpecField(w, accessor, f.Elem(), tag)
|
||||
return writeSpecField(accessor, f.Elem())
|
||||
case *types.Basic:
|
||||
fmt.Fprintf(w, `%#v`, &hcldec.AttrSpec{
|
||||
ctyType := basicKindToCtyType(f.Kind())
|
||||
return &hcldec.AttrSpec{
|
||||
Name: accessor,
|
||||
Type: basicKindToCtyType(f.Kind()),
|
||||
Type: ctyType,
|
||||
Required: false,
|
||||
})
|
||||
}, ctyType
|
||||
case *types.Map:
|
||||
fmt.Fprintf(w, `%#v`, &hcldec.BlockAttrsSpec{
|
||||
return &hcldec.BlockAttrsSpec{
|
||||
TypeName: accessor,
|
||||
ElementType: cty.String, // for now everything can be simplified to a map[string]string
|
||||
Required: false,
|
||||
})
|
||||
}, cty.Map(cty.String)
|
||||
case *types.Named:
|
||||
// Named is the relative type when of a field with a struct.
|
||||
// E.g. SourceAmiFilter *common.FlatAmiFilterOptions
|
||||
// SourceAmiFilter will become a block with nested elements from the struct itself.
|
||||
underlyingType := f.Underlying()
|
||||
switch underlyingType.(type) {
|
||||
case *types.Struct:
|
||||
// A struct returns NilType because its HCL2Spec is written in the related file
|
||||
// and we don't need to write it again.
|
||||
return fmt.Sprintf(`&hcldec.BlockSpec{TypeName: "%s",`+
|
||||
` Nested: hcldec.ObjectSpec((*%s)(nil).HCL2Spec())}`, accessor, f.String()), cty.NilType
|
||||
default:
|
||||
return writeSpecField(accessor, underlyingType)
|
||||
}
|
||||
case *types.Slice:
|
||||
elem := f.Elem()
|
||||
if ptr, isPtr := elem.(*types.Pointer); isPtr {
|
||||
elem = ptr.Elem()
|
||||
}
|
||||
switch elem := elem.(type) {
|
||||
case *types.Basic:
|
||||
fmt.Fprintf(w, `%#v`, &hcldec.AttrSpec{
|
||||
Name: accessor,
|
||||
Type: cty.List(basicKindToCtyType(elem.Kind())),
|
||||
Required: false,
|
||||
})
|
||||
case *types.Named:
|
||||
// A Slice of Named is the relative type of a filed with a slice of structs.
|
||||
// E.g. LaunchMappings []common.FlatBlockDevice
|
||||
// LaunchMappings will validate more than one block with nested elements.
|
||||
b := bytes.NewBuffer(nil)
|
||||
underlyingType := elem.Underlying()
|
||||
switch underlyingType.(type) {
|
||||
case *types.Struct:
|
||||
fmt.Fprintf(b, `hcldec.ObjectSpec((*%s)(nil).HCL2Spec())`, elem.String())
|
||||
default:
|
||||
outputHCL2SpecField(b, accessor, elem, tag)
|
||||
}
|
||||
fmt.Fprintf(w, `&hcldec.BlockListSpec{TypeName: "%s", Nested: %s}`, accessor, b.String())
|
||||
case *types.Slice:
|
||||
b := bytes.NewBuffer(nil)
|
||||
outputHCL2SpecField(b, accessor, elem.Underlying(), tag)
|
||||
fmt.Fprintf(w, `&hcldec.BlockListSpec{TypeName: "%s", Nested: %s}`, accessor, b.String())
|
||||
return fmt.Sprintf(`&hcldec.BlockListSpec{TypeName: "%s", Nested: %s}`, accessor, b.String()), cty.NilType
|
||||
default:
|
||||
outputHCL2SpecField(w, accessor, elem.Underlying(), tag)
|
||||
_, specType := writeSpecField(accessor, elem)
|
||||
if specType == cty.NilType {
|
||||
return writeSpecField(accessor, elem.Underlying())
|
||||
}
|
||||
return &hcldec.AttrSpec{
|
||||
Name: accessor,
|
||||
Type: cty.List(specType),
|
||||
Required: false,
|
||||
}, cty.List(specType)
|
||||
}
|
||||
case *types.Named:
|
||||
underlyingType := f.Underlying()
|
||||
switch underlyingType.(type) {
|
||||
case *types.Struct:
|
||||
fmt.Fprintf(w, `&hcldec.BlockSpec{TypeName: "%s",`+
|
||||
` Nested: hcldec.ObjectSpec((*%s)(nil).HCL2Spec())}`, accessor, f.String())
|
||||
default:
|
||||
outputHCL2SpecField(w, accessor, underlyingType, tag)
|
||||
}
|
||||
default:
|
||||
fmt.Fprintf(w, `%#v`, &hcldec.AttrSpec{
|
||||
Name: accessor,
|
||||
Type: basicKindToCtyType(types.Bool),
|
||||
Required: false,
|
||||
})
|
||||
fmt.Fprintf(w, `/* TODO(azr): could not find type */`)
|
||||
}
|
||||
b := bytes.NewBuffer(nil)
|
||||
fmt.Fprintf(b, `%#v`, &hcldec.AttrSpec{
|
||||
Name: accessor,
|
||||
Type: basicKindToCtyType(types.Bool),
|
||||
Required: false,
|
||||
})
|
||||
fmt.Fprintf(b, `/* TODO(azr): could not find type */`)
|
||||
return b.String(), cty.NilType
|
||||
}
|
||||
|
||||
func basicKindToCtyType(kind types.BasicKind) cty.Type {
|
||||
|
|
|
@ -194,6 +194,10 @@ var (
|
|||
"b",
|
||||
"c",
|
||||
},
|
||||
SliceSliceString: [][]string{
|
||||
{"a", "b"},
|
||||
{"c", "d"},
|
||||
},
|
||||
}
|
||||
|
||||
basicMockBuilder = &MockBuilder{
|
||||
|
|
|
@ -20,6 +20,7 @@ type NestedMockConfig struct {
|
|||
Duration time.Duration `mapstructure:"duration"`
|
||||
MapStringString map[string]string `mapstructure:"map_string_string"`
|
||||
SliceString []string `mapstructure:"slice_string"`
|
||||
SliceSliceString [][]string `mapstructure:"slice_slice_string"`
|
||||
NamedMapStringString NamedMapStringString `mapstructure:"named_map_string_string"`
|
||||
NamedString NamedString `mapstructure:"named_string"`
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ type FlatMockConfig struct {
|
|||
Duration *string `mapstructure:"duration" cty:"duration"`
|
||||
MapStringString map[string]string `mapstructure:"map_string_string" cty:"map_string_string"`
|
||||
SliceString []string `mapstructure:"slice_string" cty:"slice_string"`
|
||||
SliceSliceString [][]string `mapstructure:"slice_slice_string" cty:"slice_slice_string"`
|
||||
NamedMapStringString NamedMapStringString `mapstructure:"named_map_string_string" cty:"named_map_string_string"`
|
||||
NamedString *NamedString `mapstructure:"named_string" cty:"named_string"`
|
||||
Nested *FlatNestedMockConfig `mapstructure:"nested" cty:"nested"`
|
||||
|
@ -43,6 +44,7 @@ func (*FlatMockConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"duration": &hcldec.AttrSpec{Name: "duration", Type: cty.String, Required: false},
|
||||
"map_string_string": &hcldec.BlockAttrsSpec{TypeName: "map_string_string", ElementType: cty.String, Required: false},
|
||||
"slice_string": &hcldec.AttrSpec{Name: "slice_string", Type: cty.List(cty.String), Required: false},
|
||||
"slice_slice_string": &hcldec.AttrSpec{Name: "slice_slice_string", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"named_map_string_string": &hcldec.BlockAttrsSpec{TypeName: "named_map_string_string", ElementType: cty.String, Required: false},
|
||||
"named_string": &hcldec.AttrSpec{Name: "named_string", Type: cty.String, Required: false},
|
||||
"nested": &hcldec.BlockSpec{TypeName: "nested", Nested: hcldec.ObjectSpec((*FlatNestedMockConfig)(nil).HCL2Spec())},
|
||||
|
@ -62,6 +64,7 @@ type FlatNestedMockConfig struct {
|
|||
Duration *string `mapstructure:"duration" cty:"duration"`
|
||||
MapStringString map[string]string `mapstructure:"map_string_string" cty:"map_string_string"`
|
||||
SliceString []string `mapstructure:"slice_string" cty:"slice_string"`
|
||||
SliceSliceString [][]string `mapstructure:"slice_slice_string" cty:"slice_slice_string"`
|
||||
NamedMapStringString NamedMapStringString `mapstructure:"named_map_string_string" cty:"named_map_string_string"`
|
||||
NamedString *NamedString `mapstructure:"named_string" cty:"named_string"`
|
||||
}
|
||||
|
@ -86,6 +89,7 @@ func (*FlatNestedMockConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"duration": &hcldec.AttrSpec{Name: "duration", Type: cty.String, Required: false},
|
||||
"map_string_string": &hcldec.BlockAttrsSpec{TypeName: "map_string_string", ElementType: cty.String, Required: false},
|
||||
"slice_string": &hcldec.AttrSpec{Name: "slice_string", Type: cty.List(cty.String), Required: false},
|
||||
"slice_slice_string": &hcldec.AttrSpec{Name: "slice_slice_string", Type: cty.List(cty.List(cty.String)), Required: false},
|
||||
"named_map_string_string": &hcldec.BlockAttrsSpec{TypeName: "named_map_string_string", ElementType: cty.String, Required: false},
|
||||
"named_string": &hcldec.AttrSpec{Name: "named_string", Type: cty.String, Required: false},
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -39,6 +43,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
|
@ -61,6 +69,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -78,6 +90,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
|
@ -100,6 +116,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -117,6 +137,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
|
|
|
@ -22,6 +22,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -39,6 +43,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
|
@ -61,6 +69,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -78,6 +90,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
|
@ -101,6 +117,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -118,6 +138,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
|
@ -140,6 +164,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -157,6 +185,10 @@ build {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
|
|
|
@ -14,6 +14,10 @@ source "virtualbox-iso" "ubuntu-1204" {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -31,23 +35,9 @@ source "virtualbox-iso" "ubuntu-1204" {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
string = "string"
|
||||
int = 42
|
||||
int64 = 43
|
||||
bool = true
|
||||
trilean = true
|
||||
duration = "10s"
|
||||
map_string_string {
|
||||
a = "b"
|
||||
c = "d"
|
||||
}
|
||||
slice_string = [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -67,5 +57,31 @@ source "virtualbox-iso" "ubuntu-1204" {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
string = "string"
|
||||
int = 42
|
||||
int64 = 43
|
||||
bool = true
|
||||
trilean = true
|
||||
duration = "10s"
|
||||
map_string_string {
|
||||
a = "b"
|
||||
c = "d"
|
||||
}
|
||||
slice_string = [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
}
|
|
@ -15,6 +15,10 @@ source "virtualbox-iso" "ubuntu-1204" {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
|
@ -32,23 +36,9 @@ source "virtualbox-iso" "ubuntu-1204" {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
string = "string"
|
||||
int = 42
|
||||
int64 = 43
|
||||
bool = true
|
||||
trilean = true
|
||||
duration = "10s"
|
||||
map_string_string {
|
||||
a = "b"
|
||||
c = "d"
|
||||
}
|
||||
slice_string = [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -68,5 +58,31 @@ source "virtualbox-iso" "ubuntu-1204" {
|
|||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
string = "string"
|
||||
int = 42
|
||||
int64 = 43
|
||||
bool = true
|
||||
trilean = true
|
||||
duration = "10s"
|
||||
map_string_string {
|
||||
a = "b"
|
||||
c = "d"
|
||||
}
|
||||
slice_string = [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
]
|
||||
slice_slice_string = [
|
||||
["a","b"],
|
||||
["c","d"]
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue