diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 36f8bb8e9..881ed1e35 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -26,12 +26,13 @@ type Config struct { AccessCfgFileAccount string `mapstructure:"access_cfg_file_account"` // Access config overrides - UserID string `mapstructure:"user_ocid"` - TenancyID string `mapstructure:"tenancy_ocid"` - Region string `mapstructure:"region"` - Fingerprint string `mapstructure:"fingerprint"` - KeyFile string `mapstructure:"key_file"` - PassPhrase string `mapstructure:"pass_phrase"` + UserID string `mapstructure:"user_ocid"` + TenancyID string `mapstructure:"tenancy_ocid"` + Region string `mapstructure:"region"` + Fingerprint string `mapstructure:"fingerprint"` + KeyFile string `mapstructure:"key_file"` + PassPhrase string `mapstructure:"pass_phrase"` + UsePrivateIP bool `mapstructure:"use_private_ip"` AvailabilityDomain string `mapstructure:"availability_domain"` CompartmentID string `mapstructure:"compartment_ocid"` diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index f1352aafa..84002e937 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -24,7 +24,8 @@ func testConfig(accessConfFile *os.File) map[string]interface{} { "subnet_ocid": "ocd1...", // Comm - "ssh_username": "opc", + "ssh_username": "opc", + "use_private_ip": false, } } diff --git a/builder/oracle/oci/driver_mock.go b/builder/oracle/oci/driver_mock.go index 6173760fc..f8bd9f920 100644 --- a/builder/oracle/oci/driver_mock.go +++ b/builder/oracle/oci/driver_mock.go @@ -24,6 +24,8 @@ type driverMock struct { WaitForImageCreationErr error WaitForInstanceStateErr error + + cfg *Config } // CreateInstance creates a new compute instance. @@ -57,11 +59,14 @@ func (d *driverMock) DeleteImage(id string) error { return nil } -// GetInstanceIP returns the public IP corresponding to the given instance id. +// GetInstanceIP returns the public or private IP corresponding to the given instance id. func (d *driverMock) GetInstanceIP(id string) (string, error) { if d.GetInstanceIPErr != nil { return "", d.GetInstanceIPErr } + if d.cfg.UsePrivateIP { + return "private_ip", nil + } return "ip", nil } diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index 1d6f943c0..ead05a12d 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -63,7 +63,7 @@ func (d *driverOCI) DeleteImage(id string) error { return d.client.Compute.Images.Delete(&client.DeleteImageParams{ID: id}) } -// GetInstanceIP returns the public IP corresponding to the given instance id. +// GetInstanceIP returns the public or private IP corresponding to the given instance id. func (d *driverOCI) GetInstanceIP(id string) (string, error) { // get nvic and cross ref to find pub ip address vnics, err := d.client.Compute.VNICAttachments.List( @@ -85,6 +85,9 @@ func (d *driverOCI) GetInstanceIP(id string) (string, error) { return "", fmt.Errorf("Error getting VNIC details: %s", err) } + if d.cfg.UsePrivateIP { + return vnic.PrivateIP, nil + } return vnic.PublicIP, nil } diff --git a/builder/oracle/oci/step_instance_info.go b/builder/oracle/oci/step_instance_info.go index d3e024978..891a261cd 100644 --- a/builder/oracle/oci/step_instance_info.go +++ b/builder/oracle/oci/step_instance_info.go @@ -19,7 +19,7 @@ func (s *stepInstanceInfo) Run(_ context.Context, state multistep.StateBag) mult ip, err := driver.GetInstanceIP(id) if err != nil { - err = fmt.Errorf("Error getting instance's public IP: %s", err) + err = fmt.Errorf("Error getting instance's IP: %s", err) ui.Error(err.Error()) state.Put("error", err) return multistep.ActionHalt @@ -27,7 +27,7 @@ func (s *stepInstanceInfo) Run(_ context.Context, state multistep.StateBag) mult state.Put("instance_ip", ip) - ui.Say(fmt.Sprintf("Instance has public IP: %s.", ip)) + ui.Say(fmt.Sprintf("Instance has IP: %s.", ip)) return multistep.ActionContinue } diff --git a/builder/oracle/oci/step_instance_info_test.go b/builder/oracle/oci/step_instance_info_test.go index 7117ec44a..d4e18dd44 100644 --- a/builder/oracle/oci/step_instance_info_test.go +++ b/builder/oracle/oci/step_instance_info_test.go @@ -1,11 +1,13 @@ package oci import ( + "bytes" "context" "errors" "testing" "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" ) func TestInstanceInfo(t *testing.T) { @@ -29,6 +31,36 @@ func TestInstanceInfo(t *testing.T) { } } +func TestInstanceInfoPrivateIP(t *testing.T) { + baseTestConfig := baseTestConfig() + baseTestConfig.UsePrivateIP = true + state := new(multistep.BasicStateBag) + state.Put("config", baseTestConfig) + state.Put("driver", &driverMock{cfg: baseTestConfig}) + state.Put("hook", &packer.MockHook{}) + state.Put("ui", &packer.BasicUi{ + Reader: new(bytes.Buffer), + Writer: new(bytes.Buffer), + }) + state.Put("instance_id", "ocid1...") + + step := new(stepInstanceInfo) + defer step.Cleanup(state) + + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + + instanceIPRaw, ok := state.GetOk("instance_ip") + if !ok { + t.Fatalf("should have instance_ip") + } + + if instanceIPRaw.(string) != "private_ip" { + t.Fatalf("should've got ip ('%s' != 'private_ip')", instanceIPRaw.(string)) + } +} + func TestInstanceInfo_GetInstanceIPErr(t *testing.T) { state := testState() state.Put("instance_id", "ocid1...") diff --git a/builder/oracle/oci/step_test.go b/builder/oracle/oci/step_test.go index f46ffa1e4..cca58666c 100644 --- a/builder/oracle/oci/step_test.go +++ b/builder/oracle/oci/step_test.go @@ -36,7 +36,8 @@ func baseTestConfig() *Config { "key_file": keyFile.Name(), // Comm - "ssh_username": "opc", + "ssh_username": "opc", + "use_private_ip": false, }) // Once we have a config object they key file isn't re-read so we can @@ -50,9 +51,10 @@ func baseTestConfig() *Config { } func testState() multistep.StateBag { + baseTestConfig := baseTestConfig() state := new(multistep.BasicStateBag) - state.Put("config", baseTestConfig()) - state.Put("driver", &driverMock{}) + state.Put("config", baseTestConfig) + state.Put("driver", &driverMock{cfg: baseTestConfig}) state.Put("hook", &packer.MockHook{}) state.Put("ui", &packer.BasicUi{ Reader: new(bytes.Buffer), diff --git a/website/source/docs/builders/oracle-oci.html.md b/website/source/docs/builders/oracle-oci.html.md index 6271c5830..ea4b08404 100644 --- a/website/source/docs/builders/oracle-oci.html.md +++ b/website/source/docs/builders/oracle-oci.html.md @@ -123,6 +123,8 @@ builder. value provided by the [OCI config file](https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/sdkconfig.htm) if present. + - `use_private_ip` (boolean) - Use private ip addresses to connect to the instance via ssh. + ## Basic Example