commit
f9f1a50494
|
@ -0,0 +1,47 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
User string
|
||||||
|
Password string
|
||||||
|
IdentityDomain string
|
||||||
|
Endpoint string
|
||||||
|
MaxRetryTimeout int
|
||||||
|
}
|
||||||
|
|
||||||
|
type storageAttachment struct {
|
||||||
|
index int
|
||||||
|
instanceName *compute.InstanceName
|
||||||
|
}
|
||||||
|
|
||||||
|
type OPCClient struct {
|
||||||
|
*compute.AuthenticatedClient
|
||||||
|
MaxRetryTimeout int
|
||||||
|
storageAttachmentsByVolumeCache map[string][]storageAttachment
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) Client() (*OPCClient, error) {
|
||||||
|
u, err := url.ParseRequestURI(c.Endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Invalid endpoint URI: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := compute.NewComputeClient(c.IdentityDomain, c.User, c.Password, u)
|
||||||
|
authenticatedClient, err := client.Authenticate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Authentication failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
opcClient := &OPCClient{
|
||||||
|
AuthenticatedClient: authenticatedClient,
|
||||||
|
MaxRetryTimeout: c.MaxRetryTimeout,
|
||||||
|
storageAttachmentsByVolumeCache: make(map[string][]storageAttachment),
|
||||||
|
}
|
||||||
|
|
||||||
|
return opcClient, nil
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Provider returns a terraform.ResourceProvider.
|
||||||
|
func Provider() terraform.ResourceProvider {
|
||||||
|
return &schema.Provider{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"user": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("OPC_USERNAME", nil),
|
||||||
|
Description: "The user name for OPC API operations.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"password": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("OPC_PASSWORD", nil),
|
||||||
|
Description: "The user password for OPC API operations.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"identityDomain": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("OPC_IDENTITY_DOMAIN", nil),
|
||||||
|
Description: "The OPC identity domain for API operations",
|
||||||
|
},
|
||||||
|
|
||||||
|
"endpoint": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("OPC_ENDPOINT", nil),
|
||||||
|
Description: "The HTTP endpoint for OPC API operations.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"maxRetryTimeout": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("OPC_MAX_RETRY_TIMEOUT", 3000),
|
||||||
|
Description: "Max num seconds to wait for successful response when operating on resources within OPC (defaults to 3000)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
"opc_compute_storage_volume": resourceStorageVolume(),
|
||||||
|
"opc_compute_instance": resourceInstance(),
|
||||||
|
"opc_compute_ssh_key": resourceSSHKey(),
|
||||||
|
"opc_compute_security_application": resourceSecurityApplication(),
|
||||||
|
"opc_compute_security_list": resourceSecurityList(),
|
||||||
|
"opc_compute_security_ip_list": resourceSecurityIPList(),
|
||||||
|
"opc_compute_ip_reservation": resourceIPReservation(),
|
||||||
|
"opc_compute_ip_association": resourceIPAssociation(),
|
||||||
|
"opc_compute_security_rule": resourceSecurityRule(),
|
||||||
|
"opc_compute_security_association": resourceSecurityAssociation(),
|
||||||
|
},
|
||||||
|
|
||||||
|
ConfigureFunc: providerConfigure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||||
|
config := Config{
|
||||||
|
User: d.Get("user").(string),
|
||||||
|
Password: d.Get("password").(string),
|
||||||
|
IdentityDomain: d.Get("identityDomain").(string),
|
||||||
|
Endpoint: d.Get("endpoint").(string),
|
||||||
|
MaxRetryTimeout: d.Get("maxRetryTimeout").(int),
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.Client()
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testAccProviders map[string]terraform.ResourceProvider
|
||||||
|
var testAccProvider *schema.Provider
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testAccProvider = Provider().(*schema.Provider)
|
||||||
|
testAccProviders = map[string]terraform.ResourceProvider{
|
||||||
|
"opc": testAccProvider,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider(t *testing.T) {
|
||||||
|
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider_impl(t *testing.T) {
|
||||||
|
var _ terraform.ResourceProvider = Provider()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccPreCheck(t *testing.T) {
|
||||||
|
required := []string{"OPC_USERNAME", "OPC_PASSWORD", "OPC_IDENTITY_DOMAIN", "OPC_ENDPOINT"}
|
||||||
|
for _, prop := range required {
|
||||||
|
if os.Getenv(prop) == "" {
|
||||||
|
t.Fatalf("%s must be set for acceptance test", prop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type OPCResourceState struct {
|
||||||
|
*OPCClient
|
||||||
|
*terraform.InstanceState
|
||||||
|
}
|
||||||
|
|
||||||
|
func opcResourceCheck(resourceName string, f func(checker *OPCResourceState) error) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[resourceName]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Resource not found: %s", resourceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
state := &OPCResourceState{
|
||||||
|
OPCClient: testAccProvider.Meta().(*OPCClient),
|
||||||
|
InstanceState: rs.Primary,
|
||||||
|
}
|
||||||
|
|
||||||
|
return f(state)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,306 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceInstance() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceInstanceCreate,
|
||||||
|
Read: resourceInstanceRead,
|
||||||
|
Delete: resourceInstanceDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"shape": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"imageList": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"label": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"ip": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: false,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"opcId": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: false,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"sshKeys": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
|
||||||
|
"attributes": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vcable": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"storage": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"index": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"volume": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"bootOrder": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeInt},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAttrs(d *schema.ResourceData) (*map[string]interface{}, error) {
|
||||||
|
var attrs map[string]interface{}
|
||||||
|
|
||||||
|
attrString := d.Get("attributes").(string)
|
||||||
|
if attrString == "" {
|
||||||
|
return &attrs, nil
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(attrString), &attrs); err != nil {
|
||||||
|
return &attrs, fmt.Errorf("Cannot parse '%s' as json", attrString)
|
||||||
|
}
|
||||||
|
return &attrs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceInstanceCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource data: %#v", d.State())
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).Instances()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
shape := d.Get("shape").(string)
|
||||||
|
imageList := d.Get("imageList").(string)
|
||||||
|
label := d.Get("label").(string)
|
||||||
|
storage := getStorageAttachments(d)
|
||||||
|
sshKeys := getSSHKeys(d)
|
||||||
|
bootOrder := getBootOrder(d)
|
||||||
|
|
||||||
|
attrs, err := getAttrs(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating instance with name %s, shape %s, imageList %s, storage %s, bootOrder %s, label %s, sshKeys %s, attrs %#v",
|
||||||
|
name, shape, imageList, storage, bootOrder, label, sshKeys, attrs)
|
||||||
|
|
||||||
|
id, err := client.LaunchInstance(name, label, shape, imageList, storage, bootOrder, sshKeys, *attrs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating instance %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Waiting for instance %s to come online", id.String())
|
||||||
|
info, err := client.WaitForInstanceRunning(id, meta.(*OPCClient).MaxRetryTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error waiting for instance %s to come online: %s", id, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Created instance %s: %#v", id, info)
|
||||||
|
|
||||||
|
attachStorage(
|
||||||
|
&compute.InstanceName{
|
||||||
|
Name: info.Name,
|
||||||
|
ID: info.ID,
|
||||||
|
},
|
||||||
|
d, meta)
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateInstanceResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func attachStorage(name *compute.InstanceName, d *schema.ResourceData, meta interface{}) error {
|
||||||
|
storageClient := meta.(*OPCClient).StorageAttachments()
|
||||||
|
storage := d.Get("storage").(*schema.Set)
|
||||||
|
updatedStorage := schema.NewSet(storage.F, []interface{}{})
|
||||||
|
|
||||||
|
for _, i := range storage.List() {
|
||||||
|
attrs := i.(map[string]interface{})
|
||||||
|
attachmentInfo, err := storageClient.CreateStorageAttachment(
|
||||||
|
attrs["index"].(int),
|
||||||
|
name,
|
||||||
|
attrs["volume"].(string))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Waiting for storage attachment %#v to come online", attachmentInfo)
|
||||||
|
storageClient.WaitForStorageAttachmentCreated(attachmentInfo.Name, meta.(*OPCClient).MaxRetryTimeout)
|
||||||
|
log.Printf("[DEBUG] Storage attachment %s: %s-%s created",
|
||||||
|
attachmentInfo.Name, attachmentInfo.InstanceName, attachmentInfo.StorageVolumeName)
|
||||||
|
attrs["name"] = attachmentInfo.Name
|
||||||
|
updatedStorage.Add(attrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("storage", updatedStorage)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSSHKeys(d *schema.ResourceData) []string {
|
||||||
|
sshKeys := []string{}
|
||||||
|
for _, i := range d.Get("sshKeys").([]interface{}) {
|
||||||
|
sshKeys = append(sshKeys, i.(string))
|
||||||
|
}
|
||||||
|
return sshKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBootOrder(d *schema.ResourceData) []int {
|
||||||
|
bootOrder := []int{}
|
||||||
|
for _, i := range d.Get("bootOrder").([]interface{}) {
|
||||||
|
bootOrder = append(bootOrder, i.(int))
|
||||||
|
}
|
||||||
|
return bootOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStorageAttachments(d *schema.ResourceData) []compute.LaunchPlanStorageAttachmentSpec {
|
||||||
|
storageAttachments := []compute.LaunchPlanStorageAttachmentSpec{}
|
||||||
|
storage := d.Get("storage").(*schema.Set)
|
||||||
|
for _, i := range storage.List() {
|
||||||
|
attrs := i.(map[string]interface{})
|
||||||
|
storageAttachments = append(storageAttachments, compute.LaunchPlanStorageAttachmentSpec{
|
||||||
|
Index: attrs["index"].(int),
|
||||||
|
Volume: attrs["volume"].(string),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return storageAttachments
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateInstanceResourceData(d *schema.ResourceData, info *compute.InstanceInfo) error {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("opcId", info.ID)
|
||||||
|
d.Set("imageList", info.ImageList)
|
||||||
|
d.Set("bootOrder", info.BootOrder)
|
||||||
|
d.Set("sshKeys", info.SSHKeys)
|
||||||
|
d.Set("label", info.Label)
|
||||||
|
d.Set("ip", info.IPAddress)
|
||||||
|
d.Set("vcable", info.VCableID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceInstanceRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource data: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).Instances()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
instanceName := &compute.InstanceName{
|
||||||
|
Name: name,
|
||||||
|
ID: d.Get("opcId").(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of instance %s", instanceName)
|
||||||
|
result, err := client.GetInstance(instanceName)
|
||||||
|
if err != nil {
|
||||||
|
// Instance doesn't exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
log.Printf("[DEBUG] Instance %s not found", instanceName)
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading instance %s: %s", instanceName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of instance %s: %#v", instanceName, result)
|
||||||
|
|
||||||
|
attachments, err := meta.(*OPCClient).StorageAttachments().GetStorageAttachmentsForInstance(instanceName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error reading storage attachments for instance %s: %s", instanceName, err)
|
||||||
|
}
|
||||||
|
updateInstanceResourceData(d, result)
|
||||||
|
updateAttachmentResourceData(d, attachments)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateAttachmentResourceData(d *schema.ResourceData, attachments *[]compute.StorageAttachmentInfo) {
|
||||||
|
attachmentSet := schema.NewSet(d.Get("storage").(*schema.Set).F, []interface{}{})
|
||||||
|
for _, attachment := range *attachments {
|
||||||
|
properties := map[string]interface{}{
|
||||||
|
"index": attachment.Index,
|
||||||
|
"volume": attachment.StorageVolumeName,
|
||||||
|
"name": attachment.Name,
|
||||||
|
}
|
||||||
|
attachmentSet.Add(properties)
|
||||||
|
}
|
||||||
|
d.Set("storage", attachmentSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceInstanceDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource data: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).Instances()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
instanceName := &compute.InstanceName{
|
||||||
|
Name: name,
|
||||||
|
ID: d.Get("opcId").(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting instance %s", instanceName)
|
||||||
|
if err := client.DeleteInstance(instanceName); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting instance %s: %s", instanceName, err)
|
||||||
|
}
|
||||||
|
if err := client.WaitForInstanceDeleted(instanceName, meta.(*OPCClient).MaxRetryTimeout); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting instance %s: %s", instanceName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, attachment := range d.Get("storage").(*schema.Set).List() {
|
||||||
|
name := attachment.(map[string]interface{})["name"].(string)
|
||||||
|
log.Printf("[DEBUG] Deleting storage attachment %s", name)
|
||||||
|
client.StorageAttachments().DeleteStorageAttachment(name)
|
||||||
|
client.StorageAttachments().WaitForStorageAttachmentDeleted(name, meta.(*OPCClient).MaxRetryTimeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,156 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccOPCInstance_Basic(t *testing.T) {
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: opcResourceCheck(
|
||||||
|
instanceResourceName,
|
||||||
|
testAccCheckInstanceDestroyed),
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccInstanceBasic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
opcResourceCheck(
|
||||||
|
instanceResourceName,
|
||||||
|
testAccCheckInstanceExists),
|
||||||
|
opcResourceCheck(
|
||||||
|
keyResourceName,
|
||||||
|
testAccCheckSSHKeyExists),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Config: modifySSHKey,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
opcResourceCheck(
|
||||||
|
instanceResourceName,
|
||||||
|
testAccCheckInstanceExists),
|
||||||
|
opcResourceCheck(
|
||||||
|
keyResourceName,
|
||||||
|
testAccCheckSSHKeyUpdated),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckInstanceExists(state *OPCResourceState) error {
|
||||||
|
instanceName := getInstanceName(state)
|
||||||
|
|
||||||
|
if _, err := state.Instances().GetInstance(instanceName); err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving state of instance %s: %s", instanceName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckSSHKeyExists(state *OPCResourceState) error {
|
||||||
|
keyName := state.Attributes["name"]
|
||||||
|
|
||||||
|
if _, err := state.SSHKeys().GetSSHKey(keyName); err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving state of key %s: %s", keyName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckSSHKeyUpdated(state *OPCResourceState) error {
|
||||||
|
keyName := state.Attributes["name"]
|
||||||
|
info, err := state.SSHKeys().GetSSHKey(keyName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if info.Key != updatedKey {
|
||||||
|
return fmt.Errorf("Expected key\n\t%s\nbut was\n\t%s", updatedKey, info.Key)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInstanceName(rs *OPCResourceState) *compute.InstanceName {
|
||||||
|
return &compute.InstanceName{
|
||||||
|
Name: rs.Attributes["name"],
|
||||||
|
ID: rs.Attributes["opcId"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckInstanceDestroyed(state *OPCResourceState) error {
|
||||||
|
instanceName := getInstanceName(state)
|
||||||
|
if info, err := state.Instances().GetInstance(instanceName); err == nil {
|
||||||
|
return fmt.Errorf("Instance %s still exists: %#v", instanceName, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const instanceName = "test_instance"
|
||||||
|
const keyName = "test_key"
|
||||||
|
|
||||||
|
var instanceResourceName = fmt.Sprintf("opc_compute_instance.%s", instanceName)
|
||||||
|
var keyResourceName = fmt.Sprintf("opc_compute_ssh_key.%s", keyName)
|
||||||
|
|
||||||
|
const originalKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqw6JwbjIkZEr5UcMojtxhk6Zum39NOihHNXEvRWDt5WssX8TH/ghpv3D25K1pJkf+wfAi17HwEmYwPMEyEHENS443v6RZbXvzCkUWzkJzq7Zvbdqld038km31La2QUoMMp1KL5zk1nM65xCeQDVcR/h++03EScB2CuzTpAV6khMdfgOJgxm361kfrDVRwc1HQrAOpOnzkpPfwqBrYWqN1UnKvuO77Wk8z5LBe03EPNru3bLE3s3qHI9hjO0gXMiVUi0KyNxdWfDO8esqQlKavHAeePyrRA55YF8kBB5dEl4tVNOqpY/8TRnGN1mOe0LWxa8Ytz1wbyS49knsNVTel"
|
||||||
|
const updatedKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDHvb/2OSemgzUYLNW1/T3u33r7sZy1qbWtgVWiREH4gS5TVmDVPuvN1MFLdNqiWQA53gK8Gp24jtjNm9ftcPhicv81HVWJTB69C0sJGEfF0l4mgbemJLH3i37Mb6SdWJcGof9qHVDADPgiC8jIBVUhdiJSeq4fUJ3NQA2eUExBkRglQWairkNzPNA0mi3GL9KDGnoBnSCAXNGoKgDgIOqW0dYFP6oHyGWkF7V+/TME9aIQvmMpHjVzl7brZ/wED2t5vTJxxbgogHEmWnfs7p8EP5IsN6Vnjd0VNIt1tu3TduS8kH5npkPqZz8oIP93Ypxn0l7ZNEl9MahbhPj3gJ1YY7Cygrlt1VLC1ibBbOgIS2Lj6vGG/Yjkqs3Vw6qrmTRlsJ9c6bZO2xq0xzV11XQHvjPegBOClF6AztEe1jKU/RUFnzjIF8lUmM63fTaXuVkNERkTSE3E9XL3Uq6eqYdef7wHFFhCMSGotp3ANAb30kflysA9ID0b3o5QU2tB8OBxBicXQy11lh+u204YJuvIzeTXo+JAad5TWFlJcsUlbPFppLQdhUpoWaJouBGJV36DJb9R34i9T8Ze5tnJUQgPmMkERyPvb/+v5j3s2hs1A9WO6/MqmZd70gudsX/1bqWT898vCCOdM+CspNVY7nHVUtde7C6BrHzphr/C1YBXHw=="
|
||||||
|
|
||||||
|
var testAccInstanceBasic = fmt.Sprintf(`
|
||||||
|
resource "opc_compute_instance" "%s" {
|
||||||
|
name = "test"
|
||||||
|
label = "test"
|
||||||
|
shape = "oc3"
|
||||||
|
imageList = "/oracle/public/oel_6.4_2GB_v1"
|
||||||
|
sshKeys = ["${opc_compute_ssh_key.test_key.name}"]
|
||||||
|
attributes = "{\"foo\": \"bar\"}"
|
||||||
|
storage = {
|
||||||
|
index = 1
|
||||||
|
volume = "${opc_compute_storage_volume.test_volume.name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_storage_volume" "test_volume" {
|
||||||
|
size = "3g"
|
||||||
|
description = "My volume"
|
||||||
|
name = "test_volume_b"
|
||||||
|
tags = ["foo", "bar", "baz"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_ssh_key" "%s" {
|
||||||
|
name = "test-key"
|
||||||
|
key = "%s"
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
`, instanceName, keyName, originalKey)
|
||||||
|
|
||||||
|
var modifySSHKey = fmt.Sprintf(`
|
||||||
|
resource "opc_compute_instance" "%s" {
|
||||||
|
name = "test"
|
||||||
|
label = "test"
|
||||||
|
shape = "oc3"
|
||||||
|
imageList = "/oracle/public/oel_6.4_2GB_v1"
|
||||||
|
sshKeys = ["${opc_compute_ssh_key.test_key.name}"]
|
||||||
|
attributes = "{\"foo\": \"bar\"}"
|
||||||
|
storage = {
|
||||||
|
index = 1
|
||||||
|
volume = "${opc_compute_storage_volume.test_volume.name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_storage_volume" "test_volume" {
|
||||||
|
size = "3g"
|
||||||
|
description = "My volume"
|
||||||
|
name = "test_volume_b"
|
||||||
|
tags = ["foo", "bar", "baz"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_ssh_key" "%s" {
|
||||||
|
name = "test-key"
|
||||||
|
key = "%s"
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
`, instanceName, keyName, updatedKey)
|
|
@ -0,0 +1,103 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceIPAssociation() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceIPAssociationCreate,
|
||||||
|
Read: resourceIPAssociationRead,
|
||||||
|
Delete: resourceIPAssociationDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vcable": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"parentpool": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceIPAssociationCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
vcable, parentpool := getIPAssociationResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating ip association between vcable %s and parent pool %s",
|
||||||
|
vcable, parentpool)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).IPAssociations()
|
||||||
|
info, err := client.CreateIPAssociation(vcable, parentpool)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating ip association between vcable %s and parent pool %s: %s",
|
||||||
|
vcable, parentpool, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateIPAssociationResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateIPAssociationResourceData(d *schema.ResourceData, info *compute.IPAssociationInfo) {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("parentpool", info.ParentPool)
|
||||||
|
d.Set("vcable", info.VCable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceIPAssociationRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).IPAssociations()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of ip association %s", name)
|
||||||
|
result, err := client.GetIPAssociation(name)
|
||||||
|
if err != nil {
|
||||||
|
// IP Association does not exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading ip association %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of ip association %s: %#v", name, result)
|
||||||
|
updateIPAssociationResourceData(d, result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIPAssociationResourceData(d *schema.ResourceData) (string, string) {
|
||||||
|
return d.Get("vcable").(string), d.Get("parentpool").(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceIPAssociationDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).IPAssociations()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
vcable, parentpool := getIPAssociationResourceData(d)
|
||||||
|
log.Printf("[DEBUG] Deleting ip association %s between vcable %s and parent pool %s",
|
||||||
|
name, vcable, parentpool)
|
||||||
|
|
||||||
|
if err := client.DeleteIPAssociation(name); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting ip association %s between vcable %s and parent pool %s: %s",
|
||||||
|
name, vcable, parentpool, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccOPCResourceIPAssociation_Basic(t *testing.T) {
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: opcResourceCheck(
|
||||||
|
ipAssociationResourceName,
|
||||||
|
testAccCheckIPAssociationDestroyed),
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccIPAssociationBasic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
opcResourceCheck(
|
||||||
|
ipAssociationResourceName,
|
||||||
|
testAccCheckIPAssociationExists),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckIPAssociationExists(state *OPCResourceState) error {
|
||||||
|
associationName := getIPAssociationName(state)
|
||||||
|
|
||||||
|
if _, err := state.IPAssociations().GetIPAssociation(associationName); err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving state of ip assocation %s: %s", associationName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIPAssociationName(rs *OPCResourceState) string {
|
||||||
|
return rs.Attributes["name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckIPAssociationDestroyed(state *OPCResourceState) error {
|
||||||
|
associationName := getAssociationName(state)
|
||||||
|
if info, err := state.IPAssociations().GetIPAssociation(associationName); err == nil {
|
||||||
|
return fmt.Errorf("IP association %s still exists: %#v", associationName, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const ipAssociationName = "test_ip_association"
|
||||||
|
|
||||||
|
var ipAssociationResourceName = fmt.Sprintf("opc_compute_ip_association.%s", ipAssociationName)
|
||||||
|
|
||||||
|
var testAccIPAssociationBasic = fmt.Sprintf(`
|
||||||
|
resource "opc_compute_ip_reservation" "reservation1" {
|
||||||
|
parentpool = "/oracle/public/ippool"
|
||||||
|
permanent = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_ip_association" "%s" {
|
||||||
|
vcable = "${opc_compute_instance.test-instance1.vcable}"
|
||||||
|
parentpool = "ipreservation:${opc_compute_ip_reservation.reservation1.name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_instance" "test-instance1" {
|
||||||
|
name = "test"
|
||||||
|
label = "test"
|
||||||
|
shape = "oc3"
|
||||||
|
imageList = "/oracle/public/oel_6.4_2GB_v1"
|
||||||
|
}
|
||||||
|
`, ipAssociationName)
|
|
@ -0,0 +1,122 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceIPReservation() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceIPReservationCreate,
|
||||||
|
Read: resourceIPReservationRead,
|
||||||
|
Delete: resourceIPReservationDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"permanent": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"parentpool": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"tags": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
|
||||||
|
"ip": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: false,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceIPReservationCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
parentpool, permanent, tags := getIPReservationResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating ip reservation from parentpool %s with tags=%s",
|
||||||
|
parentpool, tags)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).IPReservations()
|
||||||
|
info, err := client.CreateIPReservation(parentpool, permanent, tags)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating ip reservation from parentpool %s with tags=%s: %s",
|
||||||
|
parentpool, tags, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateIPReservationResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateIPReservationResourceData(d *schema.ResourceData, info *compute.IPReservationInfo) {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("parentpool", info.ParentPool)
|
||||||
|
d.Set("permanent", info.Permanent)
|
||||||
|
d.Set("tags", info.Tags)
|
||||||
|
d.Set("ip", info.IP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceIPReservationRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).IPReservations()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of ip reservation %s", name)
|
||||||
|
result, err := client.GetIPReservation(name)
|
||||||
|
if err != nil {
|
||||||
|
// IP Reservation does not exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading ip reservation %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of ip reservation %s: %#v", name, result)
|
||||||
|
updateIPReservationResourceData(d, result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIPReservationResourceData(d *schema.ResourceData) (string, bool, []string) {
|
||||||
|
tagdata := d.Get("tags").([]interface{})
|
||||||
|
tags := make([]string, len(tagdata))
|
||||||
|
for i, tag := range tagdata {
|
||||||
|
tags[i] = tag.(string)
|
||||||
|
}
|
||||||
|
return d.Get("parentpool").(string),
|
||||||
|
d.Get("permanent").(bool),
|
||||||
|
tags
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceIPReservationDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).IPReservations()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting ip reservation %s", name)
|
||||||
|
|
||||||
|
if err := client.DeleteIPReservation(name); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting ip reservation %s", name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceSecurityApplication() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceSecurityApplicationCreate,
|
||||||
|
Read: resourceSecurityApplicationRead,
|
||||||
|
Delete: resourceSecurityApplicationDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"protocol": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"dport": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"icmptype": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"icmpcode": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"description": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityApplicationCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
name, protocol, dport, icmptype, icmpcode, description := getSecurityApplicationResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating security application %s", name)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SecurityApplications()
|
||||||
|
info, err := client.CreateSecurityApplication(name, protocol, dport, icmptype, icmpcode, description)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating security application %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateSecurityApplicationResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSecurityApplicationResourceData(d *schema.ResourceData, info *compute.SecurityApplicationInfo) {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("protocol", info.Protocol)
|
||||||
|
d.Set("dport", info.DPort)
|
||||||
|
d.Set("icmptype", info.ICMPType)
|
||||||
|
d.Set("icmpcode", info.ICMPCode)
|
||||||
|
d.Set("description", info.Description)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityApplicationRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityApplications()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of security application %s", name)
|
||||||
|
result, err := client.GetSecurityApplication(name)
|
||||||
|
if err != nil {
|
||||||
|
// Security Application does not exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading security application %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of security application %s: %#v", name, result)
|
||||||
|
updateSecurityApplicationResourceData(d, result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSecurityApplicationResourceData(d *schema.ResourceData) (string, string, string, string, string, string) {
|
||||||
|
return d.Get("name").(string),
|
||||||
|
d.Get("protocol").(string),
|
||||||
|
d.Get("dport").(string),
|
||||||
|
d.Get("icmptype").(string),
|
||||||
|
d.Get("icmpcode").(string),
|
||||||
|
d.Get("description").(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityApplicationDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityApplications()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting security application %s", name)
|
||||||
|
|
||||||
|
if err := client.DeleteSecurityApplication(name); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting security application %s: %s", name, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceSecurityAssociation() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceSecurityAssociationCreate,
|
||||||
|
Read: resourceSecurityAssociationRead,
|
||||||
|
Delete: resourceSecurityAssociationDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vcable": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"seclist": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityAssociationCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
vcable, seclist := getSecurityAssociationResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating security association between vcable %s and security list %s",
|
||||||
|
vcable, seclist)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SecurityAssociations()
|
||||||
|
info, err := client.CreateSecurityAssociation(vcable, seclist)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating security association between vcable %s and security list %s: %s",
|
||||||
|
vcable, seclist, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateSecurityAssociationResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSecurityAssociationResourceData(d *schema.ResourceData, info *compute.SecurityAssociationInfo) {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("seclist", info.SecList)
|
||||||
|
d.Set("vcable", info.VCable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityAssociationRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityAssociations()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of security association %s", name)
|
||||||
|
result, err := client.GetSecurityAssociation(name)
|
||||||
|
if err != nil {
|
||||||
|
// Security Association does not exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading security association %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of security association %s: %#v", name, result)
|
||||||
|
updateSecurityAssociationResourceData(d, result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSecurityAssociationResourceData(d *schema.ResourceData) (string, string) {
|
||||||
|
return d.Get("vcable").(string), d.Get("seclist").(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityAssociationDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityAssociations()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
vcable, seclist := getSecurityAssociationResourceData(d)
|
||||||
|
log.Printf("[DEBUG] Deleting security association %s between vcable %s and security list %s",
|
||||||
|
name, vcable, seclist)
|
||||||
|
|
||||||
|
if err := client.DeleteSecurityAssociation(name); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting security association %s between vcable %s and security list %s: %s",
|
||||||
|
name, vcable, seclist, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccOPCResourceSecurityAssociation_Basic(t *testing.T) {
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: opcResourceCheck(
|
||||||
|
associationResourceName,
|
||||||
|
testAccCheckAssociationDestroyed),
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccSecurityAssociationBasic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
opcResourceCheck(
|
||||||
|
associationResourceName,
|
||||||
|
testAccCheckAssociationExists),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAssociationExists(state *OPCResourceState) error {
|
||||||
|
associationName := getAssociationName(state)
|
||||||
|
|
||||||
|
if _, err := state.SecurityAssociations().GetSecurityAssociation(associationName); err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving state of security assocation %s: %s", associationName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAssociationName(rs *OPCResourceState) string {
|
||||||
|
return rs.Attributes["name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAssociationDestroyed(state *OPCResourceState) error {
|
||||||
|
associationName := getAssociationName(state)
|
||||||
|
if info, err := state.SecurityAssociations().GetSecurityAssociation(associationName); err == nil {
|
||||||
|
return fmt.Errorf("Association %s still exists: %#v", associationName, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const associationName = "test_rule"
|
||||||
|
|
||||||
|
var associationResourceName = fmt.Sprintf("opc_compute_security_association.%s", associationName)
|
||||||
|
|
||||||
|
var testAccSecurityAssociationBasic = fmt.Sprintf(`
|
||||||
|
resource "opc_compute_security_list" "sec-list1" {
|
||||||
|
name = "sec-list-1"
|
||||||
|
policy = "PERMIT"
|
||||||
|
outbound_cidr_policy = "DENY"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_security_association" "%s" {
|
||||||
|
vcable = "${opc_compute_instance.test-instance1.vcable}"
|
||||||
|
seclist = "${opc_compute_security_list.sec-list1.name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_instance" "test-instance1" {
|
||||||
|
name = "test"
|
||||||
|
label = "test"
|
||||||
|
shape = "oc3"
|
||||||
|
imageList = "/oracle/public/oel_6.4_2GB_v1"
|
||||||
|
}
|
||||||
|
`, ruleName)
|
|
@ -0,0 +1,117 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceSecurityIPList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceSecurityIPListCreate,
|
||||||
|
Read: resourceSecurityIPListRead,
|
||||||
|
Update: resourceSecurityIPListUpdate,
|
||||||
|
Delete: resourceSecurityIPListDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"ip_entries": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: false,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityIPListCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
name, ipEntries := getSecurityIPListResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating security IP list with name %s, entries %s",
|
||||||
|
name, ipEntries)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SecurityIPLists()
|
||||||
|
info, err := client.CreateSecurityIPList(name, ipEntries)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating security IP list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateSecurityIPListResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSecurityIPListResourceData(d *schema.ResourceData, info *compute.SecurityIPListInfo) {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("entries", info.SecIPEntries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityIPListRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityIPLists()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of security IP list %s", name)
|
||||||
|
result, err := client.GetSecurityIPList(name)
|
||||||
|
if err != nil {
|
||||||
|
// Security IP List does not exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading security IP list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of security IP list %s: %#v", name, result)
|
||||||
|
updateSecurityIPListResourceData(d, result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSecurityIPListResourceData(d *schema.ResourceData) (string, []string) {
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
ipEntries := d.Get("ip_entries").([]interface{})
|
||||||
|
ipEntryStrings := []string{}
|
||||||
|
for _, entry := range ipEntries {
|
||||||
|
ipEntryStrings = append(ipEntryStrings, entry.(string))
|
||||||
|
}
|
||||||
|
return name, ipEntryStrings
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityIPListUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SecurityIPLists()
|
||||||
|
name, entries := getSecurityIPListResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Updating security IP list %s with ip entries %s",
|
||||||
|
name, entries)
|
||||||
|
|
||||||
|
info, err := client.UpdateSecurityIPList(name, entries)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error updating security IP list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSecurityIPListResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityIPListDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityIPLists()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting security IP list %s", name)
|
||||||
|
if err := client.DeleteSecurityIPList(name); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting security IP list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceSecurityList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceSecurityListCreate,
|
||||||
|
Read: resourceSecurityListRead,
|
||||||
|
Update: resourceSecurityListUpdate,
|
||||||
|
Delete: resourceSecurityListDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"policy": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"outbound_cidr_policy": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityListCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
name, policy, outboundCIDRPolicy := getSecurityListResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating security list with name %s, policy %s, outbound CIDR policy %s",
|
||||||
|
name, policy, outboundCIDRPolicy)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SecurityLists()
|
||||||
|
info, err := client.CreateSecurityList(name, policy, outboundCIDRPolicy)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating security list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateSecurityListResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSecurityListResourceData(d *schema.ResourceData, info *compute.SecurityListInfo) {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("policy", info.Policy)
|
||||||
|
d.Set("outbound_cidr_policy", info.OutboundCIDRPolicy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityListRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityLists()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of security list %s", name)
|
||||||
|
result, err := client.GetSecurityList(name)
|
||||||
|
if err != nil {
|
||||||
|
// Security List does not exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading security list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of ssh key %s: %#v", name, result)
|
||||||
|
updateSecurityListResourceData(d, result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSecurityListResourceData(d *schema.ResourceData) (string, string, string) {
|
||||||
|
return d.Get("name").(string),
|
||||||
|
d.Get("policy").(string),
|
||||||
|
d.Get("outbound_cidr_policy").(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityListUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SecurityLists()
|
||||||
|
name, policy, outboundCIDRPolicy := getSecurityListResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Updating security list %s with policy %s, outbound_cidr_policy %s",
|
||||||
|
name, policy, outboundCIDRPolicy)
|
||||||
|
|
||||||
|
info, err := client.UpdateSecurityList(name, policy, outboundCIDRPolicy)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error updating security list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSecurityListResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityListDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityLists()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting ssh key volume %s", name)
|
||||||
|
if err := client.DeleteSecurityList(name); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting security list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceSecurityRule() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceSecurityRuleCreate,
|
||||||
|
Read: resourceSecurityRuleRead,
|
||||||
|
Update: resourceSecurityRuleUpdate,
|
||||||
|
Delete: resourceSecurityRuleDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"source_list": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"destination_list": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"application": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"action": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"disabled": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityRuleCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
name, sourceList, destinationList, application, action, disabled := getSecurityRuleResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating security list with name %s, sourceList %s, destinationList %s, application %s, action %s, disabled %s",
|
||||||
|
name, sourceList, destinationList, application, action, disabled)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SecurityRules()
|
||||||
|
info, err := client.CreateSecurityRule(name, sourceList, destinationList, application, action, disabled)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating security rule %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateSecurityRuleResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSecurityRuleResourceData(d *schema.ResourceData, info *compute.SecurityRuleInfo) {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("source_list", info.SourceList)
|
||||||
|
d.Set("destination_list", info.DestinationList)
|
||||||
|
d.Set("application", info.Application)
|
||||||
|
d.Set("action", info.Action)
|
||||||
|
d.Set("disabled", info.Disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityRuleRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityRules()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of security rule %s", name)
|
||||||
|
result, err := client.GetSecurityRule(name)
|
||||||
|
if err != nil {
|
||||||
|
// Security Rule does not exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading security list %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of ssh key %s: %#v", name, result)
|
||||||
|
updateSecurityRuleResourceData(d, result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSecurityRuleResourceData(d *schema.ResourceData) (string, string, string, string, string, bool) {
|
||||||
|
return d.Get("name").(string),
|
||||||
|
d.Get("source_list").(string),
|
||||||
|
d.Get("destination_list").(string),
|
||||||
|
d.Get("application").(string),
|
||||||
|
d.Get("action").(string),
|
||||||
|
d.Get("disabled").(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityRuleUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SecurityRules()
|
||||||
|
name, sourceList, destinationList, application, action, disabled := getSecurityRuleResourceData(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Updating security list %s with sourceList %s, destinationList %s, application %s, action %s, disabled %s",
|
||||||
|
name, sourceList, destinationList, application, action, disabled)
|
||||||
|
|
||||||
|
info, err := client.UpdateSecurityRule(name, sourceList, destinationList, application, action, disabled)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error updating security rule %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSecurityRuleResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSecurityRuleDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource state: %#v", d.State())
|
||||||
|
client := meta.(*OPCClient).SecurityRules()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting ssh key volume %s", name)
|
||||||
|
if err := client.DeleteSecurityRule(name); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting security rule %s: %s", name, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccOPCResourceSecurityRule_Basic(t *testing.T) {
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: opcResourceCheck(
|
||||||
|
ruleResourceName,
|
||||||
|
testAccCheckRuleDestroyed),
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccSecurityRuleBasic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
opcResourceCheck(
|
||||||
|
ruleResourceName,
|
||||||
|
testAccCheckRuleExists),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckRuleExists(state *OPCResourceState) error {
|
||||||
|
ruleName := getRuleName(state)
|
||||||
|
|
||||||
|
if _, err := state.SecurityRules().GetSecurityRule(ruleName); err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving state of security rule %s: %s", ruleName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRuleName(rs *OPCResourceState) string {
|
||||||
|
return rs.Attributes["name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckRuleDestroyed(state *OPCResourceState) error {
|
||||||
|
ruleName := getRuleName(state)
|
||||||
|
if info, err := state.SecurityRules().GetSecurityRule(ruleName); err == nil {
|
||||||
|
return fmt.Errorf("Rule %s still exists: %#v", ruleName, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const ruleName = "test_rule"
|
||||||
|
const secListName = "sec-list1"
|
||||||
|
const secIpListName = "sec-ip-list1"
|
||||||
|
|
||||||
|
var ruleResourceName = fmt.Sprintf("opc_compute_security_rule.%s", ruleName)
|
||||||
|
|
||||||
|
var testAccSecurityRuleBasic = fmt.Sprintf(`
|
||||||
|
resource "opc_compute_security_rule" "%s" {
|
||||||
|
name = "test"
|
||||||
|
source_list = "seclist:${opc_compute_security_list.sec-list1.name}"
|
||||||
|
destination_list = "seciplist:${opc_compute_security_ip_list.sec-ip-list1.name}"
|
||||||
|
action = "PERMIT"
|
||||||
|
application = "${opc_compute_security_application.spring-boot.name}"
|
||||||
|
disabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_security_list" "%s" {
|
||||||
|
name = "sec-list-1"
|
||||||
|
policy = "PERMIT"
|
||||||
|
outbound_cidr_policy = "DENY"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_security_application" "spring-boot" {
|
||||||
|
name = "spring-boot"
|
||||||
|
protocol = "tcp"
|
||||||
|
dport = "8080"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opc_compute_security_ip_list" "%s" {
|
||||||
|
name = "sec-ip-list1"
|
||||||
|
ip_entries = ["217.138.34.4"]
|
||||||
|
}
|
||||||
|
`, ruleName, secListName, secIpListName)
|
|
@ -0,0 +1,117 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceSSHKey() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceSSHKeyCreate,
|
||||||
|
Read: resourceSSHKeyRead,
|
||||||
|
Update: resourceSSHKeyUpdate,
|
||||||
|
Delete: resourceSSHKeyDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"key": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"enabled": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSSHKeyCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource data: %#v", d)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SSHKeys()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
key := d.Get("key").(string)
|
||||||
|
enabled := d.Get("enabled").(bool)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating ssh key with name %s, key %s, enabled %s",
|
||||||
|
name, key, enabled)
|
||||||
|
|
||||||
|
info, err := client.CreateSSHKey(name, key, enabled)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating ssh key %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(info.Name)
|
||||||
|
updateSSHKeyResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSSHKeyResourceData(d *schema.ResourceData, info *compute.SSHKeyInfo) {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("key", info.Key)
|
||||||
|
d.Set("enabled", info.Enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSSHKeyRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource data: %#v", d)
|
||||||
|
client := meta.(*OPCClient).SSHKeys()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of ssh key %s", name)
|
||||||
|
result, err := client.GetSSHKey(name)
|
||||||
|
if err != nil {
|
||||||
|
// SSH Key does not exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading ssh key %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of ssh key %s: %#v", name, result)
|
||||||
|
updateSSHKeyResourceData(d, result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource data: %#v", d)
|
||||||
|
|
||||||
|
client := meta.(*OPCClient).SSHKeys()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
key := d.Get("key").(string)
|
||||||
|
enabled := d.Get("enabled").(bool)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Updating ssh key with name %s, key %s, enabled %s",
|
||||||
|
name, key, enabled)
|
||||||
|
|
||||||
|
info, err := client.UpdateSSHKey(name, key, enabled)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error updating ssh key %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSSHKeyResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSSHKeyDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource data: %#v", d)
|
||||||
|
client := meta.(*OPCClient).SSHKeys()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting ssh key volume %s", name)
|
||||||
|
if err := client.DeleteSSHKey(name); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting ssh key %s: %s", name, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,301 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/oracle/terraform-provider-compute/sdk/compute"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceStorageVolume() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceStorageVolumeCreate,
|
||||||
|
Read: resourceStorageVolumeRead,
|
||||||
|
Update: resourceStorageVolumeUpdate,
|
||||||
|
Delete: resourceStorageVolumeDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"size": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"sizeInBytes": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"description": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"storage": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Default: "/oracle/public/storage/default",
|
||||||
|
},
|
||||||
|
|
||||||
|
"tags": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: false,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
|
||||||
|
"bootableImage": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"bootableImageVersion": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Default: -1,
|
||||||
|
},
|
||||||
|
|
||||||
|
"snapshot": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"account": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"snapshotId": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceStorageVolumeCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Resource data: %#v", d)
|
||||||
|
|
||||||
|
sv := meta.(*OPCClient).StorageVolumes()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
properties := []string{d.Get("storage").(string)}
|
||||||
|
|
||||||
|
spec := sv.NewStorageVolumeSpec(
|
||||||
|
d.Get("size").(string),
|
||||||
|
properties,
|
||||||
|
name)
|
||||||
|
|
||||||
|
if d.Get("description").(string) != "" {
|
||||||
|
spec.SetDescription(d.Get("description").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
spec.SetTags(getTags(d))
|
||||||
|
|
||||||
|
if d.Get("bootableImage") != "" {
|
||||||
|
spec.SetBootableImage(d.Get("bootableImage").(string), d.Get("bootableImageVersion").(int))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(d.Get("snapshot").(*schema.Set).List()) > 0 {
|
||||||
|
snapshotDetails := d.Get("snapshot").(*schema.Set).List()[0].(map[string]interface{})
|
||||||
|
spec.SetSnapshot(
|
||||||
|
snapshotDetails["name"].(string),
|
||||||
|
snapshotDetails["account"].(string),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Get("snapshotId") != "" {
|
||||||
|
spec.SetSnapshotID(d.Get("snapshotId").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating storage volume %s with spec %#v", name, spec)
|
||||||
|
err := sv.CreateStorageVolume(spec)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating storage volume %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Waiting for storage volume %s to come online", name)
|
||||||
|
info, err := sv.WaitForStorageVolumeOnline(name, meta.(*OPCClient).MaxRetryTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error waiting for storage volume %s to come online: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Created storage volume %s: %#v", name, info)
|
||||||
|
|
||||||
|
cachedAttachments, attachmentsFound := meta.(*OPCClient).storageAttachmentsByVolumeCache[name]
|
||||||
|
if attachmentsFound {
|
||||||
|
log.Printf("[DEBUG] Rebuilding storage attachments for volume %s", name)
|
||||||
|
for _, cachedAttachment := range cachedAttachments {
|
||||||
|
log.Printf("[DEBUG] Rebuilding storage attachments between volume %s and instance %s",
|
||||||
|
name,
|
||||||
|
cachedAttachment.instanceName)
|
||||||
|
|
||||||
|
attachmentInfo, err := meta.(*OPCClient).StorageAttachments().CreateStorageAttachment(
|
||||||
|
cachedAttachment.index,
|
||||||
|
cachedAttachment.instanceName,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Error recreating storage attachment between volume %s and instance %s: %s",
|
||||||
|
name,
|
||||||
|
*cachedAttachment.instanceName,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
err = meta.(*OPCClient).StorageAttachments().WaitForStorageAttachmentCreated(
|
||||||
|
attachmentInfo.Name,
|
||||||
|
meta.(*OPCClient).MaxRetryTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Error recreating storage attachment between volume %s and instance %s: %s",
|
||||||
|
name,
|
||||||
|
*cachedAttachment.instanceName,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
meta.(*OPCClient).storageAttachmentsByVolumeCache[name] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(name)
|
||||||
|
updateResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTags(d *schema.ResourceData) []string {
|
||||||
|
tags := []string{}
|
||||||
|
for _, i := range d.Get("tags").([]interface{}) {
|
||||||
|
tags = append(tags, i.(string))
|
||||||
|
}
|
||||||
|
return tags
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateResourceData(d *schema.ResourceData, info *compute.StorageVolumeInfo) error {
|
||||||
|
d.Set("name", info.Name)
|
||||||
|
d.Set("description", info.Description)
|
||||||
|
d.Set("storage", info.Properties[0])
|
||||||
|
d.Set("sizeInBytes", info.Size)
|
||||||
|
d.Set("tags", info.Tags)
|
||||||
|
d.Set("bootableImage", info.ImageList)
|
||||||
|
d.Set("bootableImageVersion", info.ImageListEntry)
|
||||||
|
if info.Snapshot != "" {
|
||||||
|
d.Set("snapshot", map[string]interface{}{
|
||||||
|
"name": info.Snapshot,
|
||||||
|
"account": info.SnapshotAccount,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
d.Set("snapshotId", info.SnapshotID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceStorageVolumeRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
sv := meta.(*OPCClient).StorageVolumes()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Reading state of storage volume %s", name)
|
||||||
|
result, err := sv.GetStorageVolume(name)
|
||||||
|
if err != nil {
|
||||||
|
// Volume doesn't exist
|
||||||
|
if compute.WasNotFoundError(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error reading storage volume %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result.Result) == 0 {
|
||||||
|
// Volume doesn't exist
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Read state of storage volume %s: %#v", name, &result.Result[0])
|
||||||
|
updateResourceData(d, &result.Result[0])
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceStorageVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
sv := meta.(*OPCClient).StorageVolumes()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
description := d.Get("description").(string)
|
||||||
|
size := d.Get("size").(string)
|
||||||
|
tags := getTags(d)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Updating storage volume %s with size %s, description %s, tags %#v", name, size, description, tags)
|
||||||
|
err := sv.UpdateStorageVolume(name, size, description, tags)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error updating storage volume %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Waiting for updated storage volume %s to come online", name)
|
||||||
|
info, err := sv.WaitForStorageVolumeOnline(name, meta.(*OPCClient).MaxRetryTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error waiting for updated storage volume %s to come online: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Updated storage volume %s: %#v", name, info)
|
||||||
|
updateResourceData(d, info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceStorageVolumeDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
sv := meta.(*OPCClient).StorageVolumes()
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
sva := meta.(*OPCClient).StorageAttachments()
|
||||||
|
attachments, err := sva.GetStorageAttachmentsForVolume(name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving storage attachments for volume %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
attachmentsToCache := make([]storageAttachment, len(*attachments))
|
||||||
|
for index, attachment := range *attachments {
|
||||||
|
log.Printf("[DEBUG] Deleting storage attachment %s for volume %s", attachment.Name, name)
|
||||||
|
sva.DeleteStorageAttachment(attachment.Name)
|
||||||
|
sva.WaitForStorageAttachmentDeleted(attachment.Name, meta.(*OPCClient).MaxRetryTimeout)
|
||||||
|
attachmentsToCache[index] = storageAttachment{
|
||||||
|
index: attachment.Index,
|
||||||
|
instanceName: compute.InstanceNameFromString(attachment.InstanceName),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
meta.(*OPCClient).storageAttachmentsByVolumeCache[name] = attachmentsToCache
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting storage volume %s", name)
|
||||||
|
err = sv.DeleteStorageVolume(name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error deleting storage volume %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Waiting for storage volume %s to finish deleting", name)
|
||||||
|
err = sv.WaitForStorageVolumeDeleted(name, meta.(*OPCClient).MaxRetryTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error waiting for storage volume %s to finish deleting: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleted storage volume %s", name)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package opc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccOPCStorageVolume_Basic(t *testing.T) {
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: opcResourceCheck(
|
||||||
|
"opc_compute_storage_volume.test_volume",
|
||||||
|
testAccCheckStorageVolumeDestroyed),
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccStorageVolumeBasic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
opcResourceCheck(
|
||||||
|
"opc_compute_storage_volume.test_volume",
|
||||||
|
testAccCheckStorageVolumeExists),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckStorageVolumeExists(state *OPCResourceState) error {
|
||||||
|
sv := state.StorageVolumes()
|
||||||
|
volumeName := state.Attributes["name"]
|
||||||
|
|
||||||
|
info, err := sv.GetStorageVolume(volumeName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving state of volume %s: %s", volumeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(info.Result) == 0 {
|
||||||
|
return fmt.Errorf("No info found for volume %s", volumeName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckStorageVolumeDestroyed(state *OPCResourceState) error {
|
||||||
|
sv := state.StorageVolumes()
|
||||||
|
|
||||||
|
volumeName := state.Attributes["name"]
|
||||||
|
|
||||||
|
info, err := sv.GetStorageVolume(volumeName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving state of volume %s: %s", volumeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(info.Result) != 0 {
|
||||||
|
return fmt.Errorf("Volume %s still exists", volumeName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccStorageVolumeBasic = `
|
||||||
|
resource "opc_compute_storage_volume" "test_volume" {
|
||||||
|
size = "3g"
|
||||||
|
description = "My volume"
|
||||||
|
name = "test_volume_b"
|
||||||
|
tags = ["foo", "bar", "baz"]
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,68 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_instance"
|
||||||
|
sidebar_current: "docs-opc-resource-instance"
|
||||||
|
description: |-
|
||||||
|
Creates and manages an instance in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_instance
|
||||||
|
|
||||||
|
The ``opc_compute_instance`` resource creates and manages an instance in an OPC identity domain.
|
||||||
|
|
||||||
|
~> **Caution:** The ``opc_compute_instance`` resource can completely delete your
|
||||||
|
instance just as easily as it can create it. To avoid costly accidents,
|
||||||
|
consider setting
|
||||||
|
[``prevent_destroy``](/docs/configuration/resources.html#prevent_destroy)
|
||||||
|
on your instance resources as an extra safety measure.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_instance" "test_instance" {
|
||||||
|
name = "test"
|
||||||
|
label = "test"
|
||||||
|
shape = "oc3"
|
||||||
|
imageList = "/oracle/public/oel_6.4_2GB_v1"
|
||||||
|
sshKeys = ["${opc_compute_ssh_key.key1.name}"]
|
||||||
|
attributes = "{\"foo\":\"bar\"}"
|
||||||
|
storage = [{
|
||||||
|
index = 1
|
||||||
|
volume = "${opc_compute_storage_volume.test_volume.name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index = 2
|
||||||
|
volume = "${opc_compute_storage_volume.test_volume2.name}"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The name of the instance. This need not be unique, as each instance is assigned a separate
|
||||||
|
computed `opcId`.
|
||||||
|
|
||||||
|
* `shape` - (Required) The shape of the instance, e.g. `oc4`.
|
||||||
|
|
||||||
|
* `imageList` - (Optional) The imageList of the instance, e.g. `/oracle/public/oel_6.4_2GB_v1`
|
||||||
|
|
||||||
|
* `label` - (Optional) The label to apply to the instance.
|
||||||
|
|
||||||
|
* `ip` - (Computed) The internal IP address assigned to the instance.
|
||||||
|
|
||||||
|
* `opcId` - (Computed) The interned ID assigned to the instance.
|
||||||
|
|
||||||
|
* `sshKeys` - (Optional) The names of the SSH Keys that can be used to log into the instance.
|
||||||
|
|
||||||
|
* `attributes` - (Optional) An arbitrary JSON-formatted collection of attributes which is made available to the instance.
|
||||||
|
|
||||||
|
* `vcable` - (Computed) The ID of the instance's VCable, which is used to associate it with reserved IP addresses and
|
||||||
|
add it to Security Lists.
|
||||||
|
|
||||||
|
* `storage` - (Optional) A set of zero or more storage volumes to attach to the instance. Each volume has two arguments:
|
||||||
|
`index`, which is the volume's index in the instance's list of mounted volumes, and `name`, which is the name of the
|
||||||
|
storage volume to mount.
|
||||||
|
|
||||||
|
* `bootOrder` - (Optional) The index number of the bootable storage volume that should be used to boot the instance. e.g. `[ 1 ]`. If you specify both `bootOrder` and `imageList`, the imagelist attribute is ignored.
|
|
@ -0,0 +1,31 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_ip_association"
|
||||||
|
sidebar_current: "docs-opc-resource-ip-association"
|
||||||
|
description: |-
|
||||||
|
Creates and manages an IP association in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_ip\_association
|
||||||
|
|
||||||
|
The ``opc_compute_ip_association`` resource creates and manages an association between an IP address and an instance in
|
||||||
|
an OPC identity domain.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_ip_association" "instance1_reservation1" {
|
||||||
|
vcable = "${opc_compute_instance.test_instance.vcable}"
|
||||||
|
parentpool = "ipreservation:${opc_compute_ip_reservation.reservation1.name}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `vcable` - (Required) The vcable of the instance to associate the IP address with.
|
||||||
|
|
||||||
|
* `parentpool` - (Required) The pool from which to take an IP address. To associate a specific reserved IP address, use
|
||||||
|
the prefix `ipreservation:` followed by the name of the IP reservation. To allocate an IP address from a pool, use the
|
||||||
|
prefix `ippool:`, e.g. `ippool:/oracle/public/ippool`.
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_ip_reservation"
|
||||||
|
sidebar_current: "docs-opc-resource-ip-assocation"
|
||||||
|
description: |-
|
||||||
|
Creates and manages an IP reservation in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_ip\_reservation
|
||||||
|
|
||||||
|
The ``opc_compute_ip_reservation`` resource creates and manages an IP reservation in an OPC identity domain.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_ip_reservation" "reservation1" {
|
||||||
|
parentpool = "/oracle/public/ippool"
|
||||||
|
permanent = true
|
||||||
|
tags = []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `parentpool` - (Required) The pool from which to allocate the IP address.
|
||||||
|
|
||||||
|
* `permanent` - (Required) Whether the IP address remains reserved even when it is no longer associated with an instance
|
||||||
|
(if true), or may be returned to the pool and replaced with a different IP address when an instance is restarted, or
|
||||||
|
deleted and recreated (if false).
|
||||||
|
|
||||||
|
* `tags` - (Optional) List of tags that may be applied to the IP reservation.
|
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_security_application"
|
||||||
|
sidebar_current: "docs-opc-resource-security-application"
|
||||||
|
description: |-
|
||||||
|
Creates and manages a security application in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_ip\_reservation
|
||||||
|
|
||||||
|
The ``opc_compute_security_application`` resource creates and manages a security application in an OPC identity domain.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_security_application" "tomcat" {
|
||||||
|
name = "tomcat"
|
||||||
|
protocol = "tcp"
|
||||||
|
dport = "8080"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The unique (within the identity domain) name of the application
|
||||||
|
|
||||||
|
* `protocol` - (Required) The protocol to enable for this application. Must be either one of
|
||||||
|
`tcp`, `udp`, `icmp`, `igmp`, `ipip`, `rdp`, `esp`, `ah`, `gre`, `icmpv6`, `ospf`, `pim`, `sctp`, `mplsip` or `all`, or
|
||||||
|
the corresponding integer in the range 0-254 from the list of [assigned protocol numbers](http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)
|
||||||
|
|
||||||
|
* `dport` - (Required) The port, or range of ports, to enable for this application, e.g `8080`, `6000-7000`.
|
||||||
|
|
||||||
|
* `icmptype` - (Optional) The ICMP type to enable for this application, if the `protocol` is `icmp`. Must be one of
|
||||||
|
`echo`, `reply`, `ttl`, `traceroute`, `unreachable`.
|
||||||
|
|
||||||
|
* `icmpcode` - (Optional) The ICMP code to enable for this application, if the `protocol` is `icmp`. Must be one of
|
||||||
|
`network`, `host`, `protocol`, `port`, `df`, `admin`.
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_security_association"
|
||||||
|
sidebar_current: "docs-opc-resource-security-association"
|
||||||
|
description: |-
|
||||||
|
Creates and manages a security association in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_ip\_reservation
|
||||||
|
|
||||||
|
The ``opc_compute_security_association`` resource creates and manages an association between an instance and a security
|
||||||
|
list in an OPC identity domain.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_security_association" "test_instance_sec_list_1" {
|
||||||
|
vcable = "${opc_compute_instance.test_instance.vcable}"
|
||||||
|
seclist = "${opc_compute_security_list.sec_list1.name}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `vcable` - (Required) The `vcable` of the instance to associate to the security list.
|
||||||
|
|
||||||
|
* `seclist` - (Required) The name of the security list to associate the instance to.
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_security_ip_list"
|
||||||
|
sidebar_current: "docs-opc-resource-security-list"
|
||||||
|
description: |-
|
||||||
|
Creates and manages a security IP list in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_ip\_reservation
|
||||||
|
|
||||||
|
The ``opc_compute_security_ip_list`` resource creates and manages a security IP list in an OPC identity domain.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_security_ip_list" "sec_ip_list1" {
|
||||||
|
name = "sec-ip-list1"
|
||||||
|
ip_entries = ["217.138.34.4"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The unique (within the identity domain) name of the security IP list.
|
||||||
|
|
||||||
|
* `ip_entries` - (Required) The IP addresses to include in the list.
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_security_list"
|
||||||
|
sidebar_current: "docs-opc-resource-security-list"
|
||||||
|
description: |-
|
||||||
|
Creates and manages a security list in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_ip\_reservation
|
||||||
|
|
||||||
|
The ``opc_compute_security_list`` resource creates and manages a security list in an OPC identity domain.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_security_list" "sec_list1" {
|
||||||
|
name = "sec-list-1"
|
||||||
|
policy = "permit"
|
||||||
|
outbound_cidr_policy = "deny"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The unique (within the identity domain) name of the security list.
|
||||||
|
|
||||||
|
* `policy` - (Required) The policy to apply to instances associated with this list. Must be one of `permit`,
|
||||||
|
`reject` (packets are dropped but a reply is sent) and `deny` (packets are dropped and no reply is sent).
|
||||||
|
|
||||||
|
* `output_cidr_policy` - (Required) The policy for outbound traffic from the security list.Must be one of `permit`,
|
||||||
|
`reject` (packets are dropped but a reply is sent) and `deny` (packets are dropped and no reply is sent).
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_security_rule"
|
||||||
|
sidebar_current: "docs-opc-resource-security-rule"
|
||||||
|
description: |-
|
||||||
|
Creates and manages a security rule in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_ip\_reservation
|
||||||
|
|
||||||
|
The ``opc_compute_security_rule`` resource creates and manages a security rule in an OPC identity domain, which joins
|
||||||
|
together a source security list (or security IP list), a destination security list (or security IP list), and a security
|
||||||
|
application.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_security_rule" "test_rule" {
|
||||||
|
name = "test"
|
||||||
|
source_list = "seclist:${opc_compute_security_list.sec-list1.name}"
|
||||||
|
destination_list = "seciplist:${opc_compute_security_ip_list.sec-ip-list1.name}"
|
||||||
|
action = "permit"
|
||||||
|
application = "${opc_compute_security_application.spring-boot.name}"
|
||||||
|
disabled = false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The unique (within the identity domain) name of the security rule.
|
||||||
|
|
||||||
|
* `source_list` - (Required) The source security list (prefixed with `seclist:`), or security IP list (prefixed with
|
||||||
|
`seciplist:`).
|
||||||
|
|
||||||
|
* `destination_list` - (Required) The destination security list (prefixed with `seclist:`), or security IP list (prefixed with
|
||||||
|
`seciplist:`).
|
||||||
|
|
||||||
|
* `application` - (Required) The name of the application to which the rule applies.
|
||||||
|
|
||||||
|
* `action` - (Required) Whether to `permit`, `refuse` or `deny` packets to which this rule applies. This will ordinarily
|
||||||
|
be `permit`.
|
||||||
|
|
||||||
|
* `disabled` - (Required) Whether to disable this security rule. This is useful if you want to temporarily disable a rule
|
||||||
|
without removing it outright from your Terraform resource definition.
|
|
@ -0,0 +1,32 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_ssh_key"
|
||||||
|
sidebar_current: "docs-opc-resource-instance"
|
||||||
|
description: |-
|
||||||
|
Creates and manages an SSH key in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_ssh_key
|
||||||
|
|
||||||
|
The ``opc_compute_ssh_key`` resource creates and manages an SSH key in an OPC identity domain.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_ssh_key" "%s" {
|
||||||
|
name = "test-key"
|
||||||
|
key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqw6JwbjIk..."
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The unique (within this identity domain) name of the SSH key.
|
||||||
|
|
||||||
|
* `key` - (Required) The SSH key itself
|
||||||
|
|
||||||
|
* `enabled` - (Required) Whether or not the key is enabled. This is useful if you want to temporarily disable an SSH key,
|
||||||
|
without removing it entirely from your Terraform resource definition.
|
|
@ -0,0 +1,49 @@
|
||||||
|
---
|
||||||
|
layout: "oracle"
|
||||||
|
page_title: "Oracle: opc_compute_storage_volume"
|
||||||
|
sidebar_current: "docs-opc-resource-storage_volume"
|
||||||
|
description: |-
|
||||||
|
Creates and manages a storage volume in an OPC identity domain.
|
||||||
|
---
|
||||||
|
|
||||||
|
# opc\_compute\_storage\_volume
|
||||||
|
|
||||||
|
The ``opc_compute_storage_volume`` resource creates and manages a storage volume in an OPC identity domain.
|
||||||
|
|
||||||
|
~> **Caution:** The ``opc_compute_storage_volume`` resource can completely delete your
|
||||||
|
storage volume just as easily as it can create it. To avoid costly accidents,
|
||||||
|
consider setting
|
||||||
|
[``prevent_destroy``](/docs/configuration/resources.html#prevent_destroy)
|
||||||
|
on your storage volume resources as an extra safety measure.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "opc_compute_storage_volume" "test_volume" {
|
||||||
|
size = "3g"
|
||||||
|
description = "My storage volume"
|
||||||
|
name = "test_volume_a"
|
||||||
|
tags = ["xyzzy", "quux"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The unique (within this identity domain) name of the storage volume.
|
||||||
|
|
||||||
|
* `size` - (Required) The size of the storage instance.
|
||||||
|
|
||||||
|
* `description` - (Optional) A description of the storage volume.
|
||||||
|
|
||||||
|
* `tags` - (Optional) A list of tags to apply to the storage volume.
|
||||||
|
|
||||||
|
* `bootableImage` - (Optional) The name of the bootable image the storage volume is loaded with.
|
||||||
|
|
||||||
|
* `bootableImageVersion` - (Optional) The version of the bootable image specified in `bootableImage` to use.
|
||||||
|
|
||||||
|
* `snapshot` - (Optional) The snapshot to initialise the storage volume with. This has two nested properties: `name`,
|
||||||
|
for the name of the snapshot to use, and `account` for the name of the snapshot account to use.
|
||||||
|
|
||||||
|
* `snapshotId` - (Optional) The id of the snapshot to initialise the storage volume with.
|
Loading…
Reference in New Issue