2017-09-12 11:30:39 -04:00
|
|
|
package oci
|
2017-02-13 05:35:14 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
|
2017-09-12 11:30:39 -04:00
|
|
|
client "github.com/hashicorp/packer/builder/oracle/oci/client"
|
2017-02-13 05:35:14 -05:00
|
|
|
)
|
|
|
|
|
2017-09-12 11:30:39 -04:00
|
|
|
// driverOCI implements the Driver interface and communicates with Oracle
|
|
|
|
// OCI.
|
|
|
|
type driverOCI struct {
|
2017-02-13 05:35:14 -05:00
|
|
|
client *client.Client
|
|
|
|
cfg *Config
|
|
|
|
}
|
|
|
|
|
2017-09-12 11:30:39 -04:00
|
|
|
// NewDriverOCI Creates a new driverOCI with a connected client.
|
|
|
|
func NewDriverOCI(cfg *Config) (Driver, error) {
|
2017-02-13 05:35:14 -05:00
|
|
|
client, err := client.NewClient(cfg.AccessCfg)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-09-12 11:30:39 -04:00
|
|
|
return &driverOCI{client: client, cfg: cfg}, nil
|
2017-02-13 05:35:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// CreateInstance creates a new compute instance.
|
2017-09-12 11:30:39 -04:00
|
|
|
func (d *driverOCI) CreateInstance(publicKey string) (string, error) {
|
2017-02-13 05:35:14 -05:00
|
|
|
params := &client.LaunchInstanceParams{
|
|
|
|
AvailabilityDomain: d.cfg.AvailabilityDomain,
|
|
|
|
CompartmentID: d.cfg.CompartmentID,
|
|
|
|
ImageID: d.cfg.BaseImageID,
|
|
|
|
Shape: d.cfg.Shape,
|
|
|
|
SubnetID: d.cfg.SubnetID,
|
|
|
|
Metadata: map[string]string{
|
|
|
|
"ssh_authorized_keys": publicKey,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
instance, err := d.client.Compute.Instances.Launch(params)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return instance.ID, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateImage creates a new custom image.
|
2017-09-12 11:30:39 -04:00
|
|
|
func (d *driverOCI) CreateImage(id string) (client.Image, error) {
|
2017-02-13 05:35:14 -05:00
|
|
|
params := &client.CreateImageParams{
|
|
|
|
CompartmentID: d.cfg.CompartmentID,
|
|
|
|
InstanceID: id,
|
|
|
|
DisplayName: d.cfg.ImageName,
|
|
|
|
}
|
|
|
|
image, err := d.client.Compute.Images.Create(params)
|
|
|
|
if err != nil {
|
|
|
|
return client.Image{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return image, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteImage deletes a custom image.
|
2017-09-12 11:30:39 -04:00
|
|
|
func (d *driverOCI) DeleteImage(id string) error {
|
2017-02-13 05:35:14 -05:00
|
|
|
return d.client.Compute.Images.Delete(&client.DeleteImageParams{ID: id})
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetInstanceIP returns the public IP corresponding to the given instance id.
|
2017-09-12 11:30:39 -04:00
|
|
|
func (d *driverOCI) GetInstanceIP(id string) (string, error) {
|
2017-02-13 05:35:14 -05:00
|
|
|
// get nvic and cross ref to find pub ip address
|
|
|
|
vnics, err := d.client.Compute.VNICAttachments.List(
|
|
|
|
&client.ListVnicAttachmentsParams{
|
|
|
|
InstanceID: id,
|
|
|
|
CompartmentID: d.cfg.CompartmentID,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(vnics) < 1 {
|
|
|
|
return "", errors.New("instance has zero VNICs")
|
|
|
|
}
|
|
|
|
|
|
|
|
vnic, err := d.client.Compute.VNICs.Get(&client.GetVNICParams{ID: vnics[0].VNICID})
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("Error getting VNIC details: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return vnic.PublicIP, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// TerminateInstance terminates a compute instance.
|
2017-09-12 11:30:39 -04:00
|
|
|
func (d *driverOCI) TerminateInstance(id string) error {
|
2017-02-13 05:35:14 -05:00
|
|
|
params := &client.TerminateInstanceParams{ID: id}
|
|
|
|
return d.client.Compute.Instances.Terminate(params)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WaitForImageCreation waits for a provisioning custom image to reach the
|
|
|
|
// "AVAILABLE" state.
|
2017-09-12 11:30:39 -04:00
|
|
|
func (d *driverOCI) WaitForImageCreation(id string) error {
|
2017-02-13 05:35:14 -05:00
|
|
|
return client.NewWaiter().WaitForResourceToReachState(
|
|
|
|
d.client.Compute.Images,
|
|
|
|
id,
|
|
|
|
[]string{"PROVISIONING"},
|
|
|
|
"AVAILABLE",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WaitForInstanceState waits for an instance to reach the a given terminal
|
|
|
|
// state.
|
2017-09-12 11:30:39 -04:00
|
|
|
func (d *driverOCI) WaitForInstanceState(id string, waitStates []string, terminalState string) error {
|
2017-02-13 05:35:14 -05:00
|
|
|
return client.NewWaiter().WaitForResourceToReachState(
|
|
|
|
d.client.Compute.Instances,
|
|
|
|
id,
|
|
|
|
waitStates,
|
|
|
|
terminalState,
|
|
|
|
)
|
|
|
|
}
|