diff --git a/builder/powervs/builder.go b/builder/powervs/builder.go index 25a5d60..72d020d 100644 --- a/builder/powervs/builder.go +++ b/builder/powervs/builder.go @@ -97,7 +97,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Source: b.config.Source, }, &StepCreateNetwork{ - SubnetID: b.config.SubnetID, + SubnetIDs: b.config.SubnetIDs, DHCPNetwork: b.config.DHCPNetwork, }, &StepCreateInstance{ diff --git a/builder/powervs/builder.hcl2spec.go b/builder/powervs/builder.hcl2spec.go index 1d9a5c5..a6f9833 100644 --- a/builder/powervs/builder.hcl2spec.go +++ b/builder/powervs/builder.hcl2spec.go @@ -27,7 +27,7 @@ type FlatConfig struct { ServiceInstanceID *string `mapstructure:"service_instance_id" required:"true" cty:"service_instance_id" hcl:"service_instance_id"` InstanceName *string `mapstructure:"instance_name" required:"true" cty:"instance_name" hcl:"instance_name"` KeyPairName *string `mapstructure:"key_pair_name" required:"true" cty:"key_pair_name" hcl:"key_pair_name"` - SubnetID *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id" hcl:"subnet_id"` + SubnetIDs []string `mapstructure:"subnet_ids" required:"false" cty:"subnet_ids" hcl:"subnet_ids"` DHCPNetwork *bool `mapstructure:"dhcp_network" required:"false" cty:"dhcp_network" hcl:"dhcp_network"` Source *common.FlatSource `mapstructure:"source" required:"true" cty:"source" hcl:"source"` Capture *common.FlatCapture `mapstructure:"capture" required:"true" cty:"capture" hcl:"capture"` @@ -110,7 +110,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "service_instance_id": &hcldec.AttrSpec{Name: "service_instance_id", Type: cty.String, Required: false}, "instance_name": &hcldec.AttrSpec{Name: "instance_name", Type: cty.String, Required: false}, "key_pair_name": &hcldec.AttrSpec{Name: "key_pair_name", Type: cty.String, Required: false}, - "subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false}, + "subnet_ids": &hcldec.AttrSpec{Name: "subnet_ids", Type: cty.List(cty.String), Required: false}, "dhcp_network": &hcldec.AttrSpec{Name: "dhcp_network", Type: cty.Bool, Required: false}, "source": &hcldec.BlockSpec{TypeName: "source", Nested: hcldec.ObjectSpec((*common.FlatSource)(nil).HCL2Spec())}, "capture": &hcldec.BlockSpec{TypeName: "capture", Nested: hcldec.ObjectSpec((*common.FlatCapture)(nil).HCL2Spec())}, diff --git a/builder/powervs/common/run_config.go b/builder/powervs/common/run_config.go index b30cb55..f1535f3 100644 --- a/builder/powervs/common/run_config.go +++ b/builder/powervs/common/run_config.go @@ -37,12 +37,12 @@ type CaptureCOS struct { } type RunConfig struct { - InstanceName string `mapstructure:"instance_name" required:"true"` - KeyPairName string `mapstructure:"key_pair_name" required:"true"` - SubnetID string `mapstructure:"subnet_id" required:"false"` - DHCPNetwork bool `mapstructure:"dhcp_network" required:"false"` - Source Source `mapstructure:"source" required:"true"` - Capture Capture `mapstructure:"capture" required:"true"` + InstanceName string `mapstructure:"instance_name" required:"true"` + KeyPairName string `mapstructure:"key_pair_name" required:"true"` + SubnetIDs []string `mapstructure:"subnet_ids" required:"false"` + DHCPNetwork bool `mapstructure:"dhcp_network" required:"false"` + Source Source `mapstructure:"source" required:"true"` + Capture Capture `mapstructure:"capture" required:"true"` // Communicator settings Comm communicator.Config `mapstructure:",squash"` diff --git a/builder/powervs/step_create_instance.go b/builder/powervs/step_create_instance.go index f675a51..67b3236 100644 --- a/builder/powervs/step_create_instance.go +++ b/builder/powervs/step_create_instance.go @@ -28,11 +28,23 @@ func (s *StepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu net := state.Get("network").(*models.Network) imageRef := state.Get("source_image").(*models.ImageReference) - networks := []*models.PVMInstanceAddNetwork{ - { - NetworkID: net.NetworkID, - }, + + networks := []*models.PVMInstanceAddNetwork{} + + if state.Get("networks") != nil { + // Several subnets have been specified -> pass them all for vm creation + networks = []*models.PVMInstanceAddNetwork{} + + for _, subnet := range state.Get("networks").([]string){ + subnetAdd := &models.PVMInstanceAddNetwork{ + NetworkID: &subnet, + } + networks = append(networks, subnetAdd) + } + } else { + networks = append(networks, &models.PVMInstanceAddNetwork{NetworkID: net.NetworkID}) } + body := &models.PVMInstanceCreate{ ImageID: imageRef.ImageID, KeyPairName: s.KeyPairName, diff --git a/builder/powervs/step_create_network.go b/builder/powervs/step_create_network.go index 22ccf86..e6578b1 100644 --- a/builder/powervs/step_create_network.go +++ b/builder/powervs/step_create_network.go @@ -20,29 +20,37 @@ const ( ) type StepCreateNetwork struct { - SubnetID string - DHCPNetwork bool - doCleanup bool + SubnetIDs []string + DHCPNetwork bool + doCleanup bool } + func (s *StepCreateNetwork) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packersdk.Ui) networkClient := state.Get("networkClient").(*instance.IBMPINetworkClient) - if s.SubnetID != "" { - ui.Say("The subnet is specified by the user; reuse it instead of creating a new one.") - net, err := networkClient.Get(s.SubnetID) - if err != nil { - ui.Error(fmt.Sprintf("failed to get subnet: %s, error: %v", s.SubnetID, err)) - return multistep.ActionHalt + if s.SubnetIDs != nil { + for i, subnetID := range s.SubnetIDs { + ui.Say("The subnet is specified by the user; reuse it instead of creating a new one.") + net, err := networkClient.Get(subnetID) + if err != nil { + ui.Error(fmt.Sprintf("failed to get subnet: %s, error: %v", subnetID, err)) + return multistep.ActionHalt + } + ui.Message(fmt.Sprintf("Network found!, Name: %s, ID: %s", *net.Name, *net.NetworkID)) + if i == 0 { + ui.Say(fmt.Sprintf("Registering subnet %s as interface for ssh", subnetID)) + state.Put("network", net) + } } - ui.Message(fmt.Sprintf("Network found!, Name: %s, ID: %s", *net.Name, *net.NetworkID)) - state.Put("network", net) - // do not delete the user specified subnet, hence skipping the cleanup + // The subnets have been validated, let's pass them further as plain ids + state.Put("networks", s.SubnetIDs) + // do not delete user specified subnets, hence skipping the cleanup s.doCleanup = false return multistep.ActionContinue - } + } // If CreateDHCPNetwork is set, Create DHCP network. if s.DHCPNetwork {