diff --git a/builder/oracle/oci/builder.go b/builder/oracle/oci/builder.go index 6ceaaf2d2..1554f6013 100644 --- a/builder/oracle/oci/builder.go +++ b/builder/oracle/oci/builder.go @@ -58,6 +58,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &stepCreateInstance{}, &stepInstanceInfo{}, + &stepGetDefaultCredentials{ + Debug: b.config.PackerDebug, + Comm: &b.config.Comm, + BuildName: b.config.PackerBuildName, + }, &communicator.StepConnect{ Config: &b.config.Comm, Host: ocommon.CommHost, diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index 90d05ea0a..ffb3732c1 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -112,6 +112,17 @@ func (d *driverOCI) GetInstanceIP(id string) (string, error) { return *vnic.PublicIp, nil } +func (d *driverOCI) GetInstanceInitialCredentials(id string) (string, string, error) { + credentials, err := d.computeClient.GetWindowsInstanceInitialCredentials(context.TODO(), core.GetWindowsInstanceInitialCredentialsRequest{ + InstanceId: &id, + }) + if err != nil { + return "", "", err + } + + return *credentials.InstanceCredentials.Username, *credentials.InstanceCredentials.Password, err +} + // TerminateInstance terminates a compute instance. func (d *driverOCI) TerminateInstance(id string) error { _, err := d.computeClient.TerminateInstance(context.TODO(), core.TerminateInstanceRequest{ diff --git a/builder/oracle/oci/step_get_default_credentials.go b/builder/oracle/oci/step_get_default_credentials.go new file mode 100644 index 000000000..7503b853c --- /dev/null +++ b/builder/oracle/oci/step_get_default_credentials.go @@ -0,0 +1,62 @@ +package oci + +import ( + "context" + "fmt" + "log" + + commonhelper "github.com/hashicorp/packer/helper/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type stepGetDefaultCredentials struct { + Debug bool + Comm *communicator.Config + BuildName string +} + +func (s *stepGetDefaultCredentials) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + var ( + driver = state.Get("driver").(*driverOCI) + ui = state.Get("ui").(packer.Ui) + id = state.Get("instance_id").(string) + ) + + // Skip if we're not using winrm + if s.Comm.Type != "winrm" { + log.Printf("[INFO] Not using winrm communicator, skipping get password...") + return multistep.ActionContinue + } + + // If we already have a password, skip it + if s.Comm.WinRMPassword != "" { + ui.Say("Skipping waiting for password since WinRM password set...") + return multistep.ActionContinue + } + + username, password, err := driver.GetInstanceInitialCredentials(id) + if err != nil { + err = fmt.Errorf("Error getting instance's credentials: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + s.Comm.WinRMPassword = password + s.Comm.WinRMUser = username + + if s.Debug { + ui.Message(fmt.Sprintf( + "[DEBUG] (OCI default credentials): Credentials (since debug is enabled): %s", password)) + } + + // store so that we can access this later during provisioning + commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName) + + return multistep.ActionContinue +} + +func (s *stepGetDefaultCredentials) Cleanup(state multistep.StateBag) { + // no cleanup +}