diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 8418cd540..417174a54 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -1,4 +1,4 @@ -//go:generate mapstructure-to-hcl2 -type Config +//go:generate mapstructure-to-hcl2 -type Config,CreateVnicDetailsRaw package oci @@ -22,6 +22,17 @@ import ( ociauth "github.com/oracle/oci-go-sdk/common/auth" ) +type CreateVnicDetailsRaw struct { + // fields that can be specified under "create_vnic_details" + AssignPublicIp *bool `mapstructure:"assign_public_ip" required:"false"` + DisplayName *string `mapstructure:"display_name" required:"false"` + HostnameLabel *string `mapstructure:"hostname_label" required:"false"` + NsgIds []string `mapstructure:"nsg_ids" required:"false"` + PrivateIp *string `mapstructure:"private_ip" required:"false"` + SkipSourceDestCheck *bool `mapstructure:"skip_source_dest_check" required:"false"` + SubnetId *string `mapstructure:"subnet_id" required:"false"` +} + type Config struct { common.PackerConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` @@ -77,8 +88,8 @@ type Config struct { UserDataFile string `mapstructure:"user_data_file"` // Networking - SubnetID string `mapstructure:"subnet_ocid"` - CreateVnicDetails map[string]interface{} `mapstructure:"create_vnic_details"` + SubnetID string `mapstructure:"subnet_ocid"` + CreateVnicDetails CreateVnicDetailsRaw `mapstructure:"create_vnic_details"` // Tagging Tags map[string]string `mapstructure:"tags"` diff --git a/builder/oracle/oci/config.hcl2spec.go b/builder/oracle/oci/config.hcl2spec.go index b4853c51a..45a9b12dc 100644 --- a/builder/oracle/oci/config.hcl2spec.go +++ b/builder/oracle/oci/config.hcl2spec.go @@ -1,4 +1,4 @@ -// Code generated by "mapstructure-to-hcl2 -type Config"; DO NOT EDIT. +// Code generated by "mapstructure-to-hcl2 -type Config,CreateVnicDetailsRaw"; DO NOT EDIT. package oci import ( @@ -85,7 +85,7 @@ type FlatConfig struct { UserData *string `mapstructure:"user_data" cty:"user_data" hcl:"user_data"` UserDataFile *string `mapstructure:"user_data_file" cty:"user_data_file" hcl:"user_data_file"` SubnetID *string `mapstructure:"subnet_ocid" cty:"subnet_ocid" hcl:"subnet_ocid"` - CreateVnicDetails map[string]interface{} `mapstructure:"create_vnic_details" cty:"create_vnic_details" hcl:"create_vnic_details"` + CreateVnicDetails *FlatCreateVnicDetailsRaw `mapstructure:"create_vnic_details" cty:"create_vnic_details" hcl:"create_vnic_details"` Tags map[string]string `mapstructure:"tags" cty:"tags" hcl:"tags"` DefinedTags map[string]map[string]interface{} `mapstructure:"defined_tags" cty:"defined_tags" hcl:"defined_tags"` } @@ -178,9 +178,44 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false}, "user_data_file": &hcldec.AttrSpec{Name: "user_data_file", Type: cty.String, Required: false}, "subnet_ocid": &hcldec.AttrSpec{Name: "subnet_ocid", Type: cty.String, Required: false}, - "create_vnic_details": &hcldec.AttrSpec{Name: "create_vnic_details", Type: cty.Map(cty.String), Required: false}, + "create_vnic_details": &hcldec.BlockSpec{TypeName: "create_vnic_details", Nested: hcldec.ObjectSpec((*FlatCreateVnicDetailsRaw)(nil).HCL2Spec())}, "tags": &hcldec.AttrSpec{Name: "tags", Type: cty.Map(cty.String), Required: false}, "defined_tags": &hcldec.AttrSpec{Name: "defined_tags", Type: cty.Map(cty.String), Required: false}, } return s } + +// FlatCreateVnicDetailsRaw is an auto-generated flat version of CreateVnicDetailsRaw. +// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. +type FlatCreateVnicDetailsRaw struct { + AssignPublicIp *bool `mapstructure:"assign_public_ip" required:"false" cty:"assign_public_ip" hcl:"assign_public_ip"` + DisplayName *string `mapstructure:"display_name" required:"false" cty:"display_name" hcl:"display_name"` + HostnameLabel *string `mapstructure:"hostname_label" required:"false" cty:"hostname_label" hcl:"hostname_label"` + NsgIds []string `mapstructure:"nsg_ids" required:"false" cty:"nsg_ids" hcl:"nsg_ids"` + PrivateIp *string `mapstructure:"private_ip" required:"false" cty:"private_ip" hcl:"private_ip"` + SkipSourceDestCheck *bool `mapstructure:"skip_source_dest_check" required:"false" cty:"skip_source_dest_check" hcl:"skip_source_dest_check"` + SubnetId *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id" hcl:"subnet_id"` +} + +// FlatMapstructure returns a new FlatCreateVnicDetailsRaw. +// FlatCreateVnicDetailsRaw is an auto-generated flat version of CreateVnicDetailsRaw. +// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. +func (*CreateVnicDetailsRaw) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { + return new(FlatCreateVnicDetailsRaw) +} + +// HCL2Spec returns the hcl spec of a CreateVnicDetailsRaw. +// This spec is used by HCL to read the fields of CreateVnicDetailsRaw. +// The decoded values from this spec will then be applied to a FlatCreateVnicDetailsRaw. +func (*FlatCreateVnicDetailsRaw) HCL2Spec() map[string]hcldec.Spec { + s := map[string]hcldec.Spec{ + "assign_public_ip": &hcldec.AttrSpec{Name: "assign_public_ip", Type: cty.Bool, Required: false}, + "display_name": &hcldec.AttrSpec{Name: "display_name", Type: cty.String, Required: false}, + "hostname_label": &hcldec.AttrSpec{Name: "hostname_label", Type: cty.String, Required: false}, + "nsg_ids": &hcldec.AttrSpec{Name: "nsg_ids", Type: cty.List(cty.String), Required: false}, + "private_ip": &hcldec.AttrSpec{Name: "private_ip", Type: cty.String, Required: false}, + "skip_source_dest_check": &hcldec.AttrSpec{Name: "skip_source_dest_check", Type: cty.Bool, Required: false}, + "subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false}, + } + return s +} diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index d0e6b96a8..f698ae7da 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "strconv" "time" core "github.com/oracle/oci-go-sdk/core" @@ -69,14 +68,18 @@ func (d *driverOCI) CreateInstance(ctx context.Context, publicKey string) (strin } // Pass VNIC details, if specified, to the instance - if len(d.cfg.CreateVnicDetails) > 0 { - CreateVnicDetails, err := mapToCreateVnicDetails(d.cfg.CreateVnicDetails) - if err != nil { - return "", err - } - instanceDetails.CreateVnicDetails = &CreateVnicDetails + CreateVnicDetails := core.CreateVnicDetails{ + AssignPublicIp: d.cfg.CreateVnicDetails.AssignPublicIp, + DisplayName: d.cfg.CreateVnicDetails.DisplayName, + HostnameLabel: d.cfg.CreateVnicDetails.HostnameLabel, + NsgIds: d.cfg.CreateVnicDetails.NsgIds, + PrivateIp: d.cfg.CreateVnicDetails.PrivateIp, + SkipSourceDestCheck: d.cfg.CreateVnicDetails.SkipSourceDestCheck, + SubnetId: d.cfg.CreateVnicDetails.SubnetId, } + instanceDetails.CreateVnicDetails = &CreateVnicDetails + instance, err := d.computeClient.LaunchInstance(context.TODO(), core.LaunchInstanceRequest{LaunchInstanceDetails: instanceDetails}) if err != nil { @@ -227,69 +230,3 @@ func stringSliceContains(slice []string, value string) bool { } return false } - -// interfaceToBool converts a variable of type interface to type bool -func interfaceToBool(b interface{}) (bool, error) { - var boolVal bool - var err error - - switch t := b.(type) { - case bool: - boolVal = t - case string: - boolVal, err = strconv.ParseBool(t) - default: - boolVal, err = false, fmt.Errorf("failed to convert %v to boolean type", b) - } - - return boolVal, err -} - -// mapToCreateVnicDetails creates variable of type core.CreateVnicDetails from map -func mapToCreateVnicDetails(m map[string]interface{}) (core.CreateVnicDetails, error) { - result := core.CreateVnicDetails{} - - if val, ok := m["assign_public_ip"]; ok { - boolVal, err := interfaceToBool(val) - if err != nil { - return result, fmt.Errorf("assign_public_ip is incorrect type: %v", err) - } - result.AssignPublicIp = &boolVal - } - if val, ok := m["display_name"]; ok { - tmp := val.(string) - result.DisplayName = &tmp - } - if val, ok := m["hostname_label"]; ok { - tmp := val.(string) - result.HostnameLabel = &tmp - } - if val, ok := m["nsg_ids"]; ok { - tmp, tmpok := val.([]interface{}) - if !tmpok { - return result, errors.New("nsg_ids not in correct list format") - } - valStr := make([]string, len(tmp)) //convert []interface{} to []string - for i, v := range tmp { - valStr[i] = fmt.Sprint(v) - } - result.NsgIds = valStr - } - if val, ok := m["private_ip"]; ok { - tmp := val.(string) - result.PrivateIp = &tmp - } - if val, ok := m["skip_source_dest_check"]; ok { - boolVal, err := interfaceToBool(val) - if err != nil { - return result, fmt.Errorf("skip_source_dest_check is incorrect type: %v", err) - } - result.SkipSourceDestCheck = &boolVal - } - if val, ok := m["subnet_id"]; ok { - tmp := val.(string) - result.SubnetId = &tmp - } - - return result, nil -}