Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jay Wang 2017-04-20 14:17:09 -07:00
commit 85ecb06926
241 changed files with 35987 additions and 1095 deletions

View File

@ -2,7 +2,9 @@
FEATURES:
* **New Provider:** `opc` - Oracle Public Cloud [GH-13468]
* **New Data Source:** `aws_kms_alias` [GH-13669]
* **New Data Source:** `aws_kinesis_stream` [GH-13562]
* **New Data Source:** `google_compute_network` [GH-12442]
* **New Data Source:** `google_compute_subnetwork` [GH-12442]
* **New Resource:** `local_file` for creating local files (please see the docs for caveats) [GH-12757]
@ -12,13 +14,18 @@ FEATURES:
* **New Resource:** `alicloud_ess_schedule` [GH-13731]
* **New Resource:** `alicloud_snat_entry` [GH-13731]
* **New Resource:** `alicloud_forward_entry` [GH-13731]
* **New Resource:** `github_branch_protection` [GH-10476]
* **New Resource:** `google_bigquery_dataset` [GH-13436]
IMPROVEMENTS:
* config: The interpolation function `cidrhost` now accepts a negative host number to count backwards from the end of the range [GH-13765]
* state/remote/swift: Support Openstack request logging [GH-13583]
* provider/aws: Add an option to skip getting the supported EC2 platforms [GH-13672]
* provider/aws: Add `name_prefix` support to `aws_cloudwatch_log_group` [GH-13273]
* provider/aws: Add `bucket_prefix` to `aws_s3_bucket` [GH-13274]
* provider/azurerm: VM Scale Sets - import support [GH-13464]
* provider/azurerm: Allow Azure China region support [GH-13767]
* provider/digitalocean: Export droplet prices [GH-13720]
* provider/google: `google_compute_address` and `google_compute_global_address` are now importable [GH-13270]
* provider/vault: `vault_generic_secret` resource can now optionally detect drift if it has appropriate access [GH-11776]
@ -39,10 +46,15 @@ BUG FIXES:
* provider/aws: Allow GovCloud KMS ARNs to pass validation in `kms_key_id` attributes [GH-13699]
* provider/azurerm: azurerm_redis_cache resource missing hostname [GH-13650]
* provider/azurerm: Locking around Network Security Group / Subnets [GH-13637]
* provider/azurerm: Locking route table on subnet create/delete [GH-13791]
* provider/azurerm: VM's - fixes a bug where ssh_keys could contain a null entry [GH-13755]
* provider/fastly: Fix issue with using 0 for `default_ttl` [GH-13648]
* provider/fastly: Add ability to associate a healthcheck to a backend [GH-13539]
* provider/google: Stop setting the id when project creation fails [GH-13644]
* provider/logentries: Refresh from state when resources not found [GH-13810]
* provider/newrelic: newrelic_alert_condition - `condition_scope` must be `application` or `instance` [GH-12972]
* provider/openstack: Fix updating Ports [GH-13604]
* provider/rabbitmq: Allow users without tags [GH-13798]
## 0.9.3 (April 12, 2017)

View File

@ -0,0 +1,12 @@
package main
import (
"github.com/hashicorp/terraform/builtin/providers/opc"
"github.com/hashicorp/terraform/plugin"
)
func main() {
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: opc.Provider,
})
}

View File

@ -0,0 +1,95 @@
package aws
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/kinesis"
"github.com/hashicorp/terraform/helper/schema"
)
func dataSourceAwsKinesisStream() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsKinesisStreamRead,
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"arn": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"creation_timestamp": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
},
"status": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"retention_period": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
},
"open_shards": &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"closed_shards": &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"shard_level_metrics": &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"tags": &schema.Schema{
Type: schema.TypeMap,
Computed: true,
},
},
}
}
func dataSourceAwsKinesisStreamRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).kinesisconn
sn := d.Get("name").(string)
state, err := readKinesisStreamState(conn, sn)
if err != nil {
return err
}
d.SetId(state.arn)
d.Set("arn", state.arn)
d.Set("name", sn)
d.Set("open_shards", state.openShards)
d.Set("closed_shards", state.closedShards)
d.Set("status", state.status)
d.Set("creation_timestamp", state.creationTimestamp)
d.Set("retention_period", state.retentionPeriod)
d.Set("shard_level_metrics", state.shardLevelMetrics)
tags, err := conn.ListTagsForStream(&kinesis.ListTagsForStreamInput{
StreamName: aws.String(sn),
})
if err != nil {
return err
}
d.Set("tags", tagsToMapKinesis(tags.Tags))
return nil
}

View File

@ -0,0 +1,94 @@
package aws
import (
"fmt"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/kinesis"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccAWSKinesisStreamDataSource(t *testing.T) {
var stream kinesis.StreamDescription
sn := fmt.Sprintf("terraform-kinesis-test-%d", acctest.RandInt())
config := fmt.Sprintf(testAccCheckAwsKinesisStreamDataSourceConfig, sn)
updateShardCount := func() {
conn := testAccProvider.Meta().(*AWSClient).kinesisconn
_, err := conn.UpdateShardCount(&kinesis.UpdateShardCountInput{
ScalingType: aws.String(kinesis.ScalingTypeUniformScaling),
StreamName: aws.String(sn),
TargetShardCount: aws.Int64(3),
})
if err != nil {
t.Fatalf("Error calling UpdateShardCount: %s", err)
}
if err := waitForKinesisToBeActive(conn, sn); err != nil {
t.Fatal(err)
}
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckKinesisStreamDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccCheckKinesisStreamExists("aws_kinesis_stream.test_stream", &stream),
resource.TestCheckResourceAttrSet("data.aws_kinesis_stream.test_stream", "arn"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "name", sn),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "status", "ACTIVE"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "open_shards.#", "2"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "closed_shards.#", "0"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "shard_level_metrics.#", "2"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "retention_period", "72"),
resource.TestCheckResourceAttrSet("data.aws_kinesis_stream.test_stream", "creation_timestamp"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "tags.Name", "tf-test"),
),
},
{
Config: config,
PreConfig: updateShardCount,
Check: resource.ComposeTestCheckFunc(
testAccCheckKinesisStreamExists("aws_kinesis_stream.test_stream", &stream),
resource.TestCheckResourceAttrSet("data.aws_kinesis_stream.test_stream", "arn"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "name", sn),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "status", "ACTIVE"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "open_shards.#", "3"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "closed_shards.#", "4"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "shard_level_metrics.#", "2"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "retention_period", "72"),
resource.TestCheckResourceAttrSet("data.aws_kinesis_stream.test_stream", "creation_timestamp"),
resource.TestCheckResourceAttr("data.aws_kinesis_stream.test_stream", "tags.Name", "tf-test"),
),
},
},
})
}
var testAccCheckAwsKinesisStreamDataSourceConfig = `
resource "aws_kinesis_stream" "test_stream" {
name = "%s"
shard_count = 2
retention_period = 72
tags {
Name = "tf-test"
}
shard_level_metrics = [
"IncomingBytes",
"OutgoingBytes"
]
lifecycle {
ignore_changes = ["shard_count"]
}
}
data "aws_kinesis_stream" "test_stream" {
name = "${aws_kinesis_stream.test_stream.name}"
}
`

View File

@ -72,7 +72,7 @@ func testAccDataSourceAwsRoute53ZoneCheck(rsName, dsName, zName string) resource
func testAccDataSourceAwsRoute53ZoneConfig(rInt int) string {
return fmt.Sprintf(`
provider "aws" {
region = "us-east-2"
region = "us-east-1"
}
resource "aws_vpc" "test" {

View File

@ -179,6 +179,7 @@ func Provider() terraform.ResourceProvider {
"aws_eip": dataSourceAwsEip(),
"aws_elb_hosted_zone_id": dataSourceAwsElbHostedZoneId(),
"aws_elb_service_account": dataSourceAwsElbServiceAccount(),
"aws_kinesis_stream": dataSourceAwsKinesisStream(),
"aws_iam_account_alias": dataSourceAwsIamAccountAlias(),
"aws_iam_policy_document": dataSourceAwsIamPolicyDocument(),
"aws_iam_role": dataSourceAwsIAMRole(),

View File

@ -121,7 +121,7 @@ func resourceAwsIamInstanceProfileCreate(d *schema.ResourceData, meta interface{
_, hasRole := d.GetOk("role")
if hasRole == false && hasRoles == false {
return fmt.Errorf("Either `roles` or `role` must be specified when creating an IAM Instance Profile")
return fmt.Errorf("Either `role` or `roles` (deprecated) must be specified when creating an IAM Instance Profile")
}
request := &iam.CreateInstanceProfileInput{

View File

@ -140,7 +140,7 @@ func resourceAwsIamRolePolicyDelete(d *schema.ResourceData, meta interface{}) er
func resourceAwsIamRolePolicyParseId(id string) (roleName, policyName string, err error) {
parts := strings.SplitN(id, ":", 2)
if len(parts) != 2 {
err = fmt.Errorf("role_policy id must be of the for <role name>:<policy name>")
err = fmt.Errorf("role_policy id must be of the form <role name>:<policy name>")
return
}

View File

@ -95,10 +95,10 @@ func resourceAwsKinesisStreamCreate(d *schema.ResourceData, meta interface{}) er
sn, err)
}
s := streamRaw.(kinesisStreamState)
s := streamRaw.(*kinesisStreamState)
d.SetId(s.arn)
d.Set("arn", s.arn)
d.Set("shard_count", s.shardCount)
d.Set("shard_count", len(s.openShards))
return resourceAwsKinesisStreamUpdate(d, meta)
}
@ -141,7 +141,7 @@ func resourceAwsKinesisStreamRead(d *schema.ResourceData, meta interface{}) erro
}
d.Set("arn", state.arn)
d.Set("shard_count", state.shardCount)
d.Set("shard_count", len(state.openShards))
d.Set("retention_period", state.retentionPeriod)
if len(state.shardLevelMetrics) > 0 {
@ -290,23 +290,27 @@ func updateKinesisShardLevelMetrics(conn *kinesis.Kinesis, d *schema.ResourceDat
type kinesisStreamState struct {
arn string
creationTimestamp int64
status string
shardCount int
retentionPeriod int64
openShards []string
closedShards []string
shardLevelMetrics []string
}
func readKinesisStreamState(conn *kinesis.Kinesis, sn string) (kinesisStreamState, error) {
func readKinesisStreamState(conn *kinesis.Kinesis, sn string) (*kinesisStreamState, error) {
describeOpts := &kinesis.DescribeStreamInput{
StreamName: aws.String(sn),
}
var state kinesisStreamState
state := &kinesisStreamState{}
err := conn.DescribeStreamPages(describeOpts, func(page *kinesis.DescribeStreamOutput, last bool) (shouldContinue bool) {
state.arn = aws.StringValue(page.StreamDescription.StreamARN)
state.creationTimestamp = aws.TimeValue(page.StreamDescription.StreamCreationTimestamp).Unix()
state.status = aws.StringValue(page.StreamDescription.StreamStatus)
state.shardCount += len(openShards(page.StreamDescription.Shards))
state.retentionPeriod = aws.Int64Value(page.StreamDescription.RetentionPeriodHours)
state.openShards = append(state.openShards, flattenShards(openShards(page.StreamDescription.Shards))...)
state.closedShards = append(state.closedShards, flattenShards(closedShards(page.StreamDescription.Shards))...)
state.shardLevelMetrics = flattenKinesisShardLevelMetrics(page.StreamDescription.EnhancedMonitoring)
return !last
})
@ -349,14 +353,31 @@ func waitForKinesisToBeActive(conn *kinesis.Kinesis, sn string) error {
return nil
}
// See http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-using-sdk-java-resharding-merge.html
func openShards(shards []*kinesis.Shard) []*kinesis.Shard {
var open []*kinesis.Shard
return filterShards(shards, true)
}
func closedShards(shards []*kinesis.Shard) []*kinesis.Shard {
return filterShards(shards, false)
}
// See http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-using-sdk-java-resharding-merge.html
func filterShards(shards []*kinesis.Shard, open bool) []*kinesis.Shard {
res := make([]*kinesis.Shard, 0, len(shards))
for _, s := range shards {
if s.SequenceNumberRange.EndingSequenceNumber == nil {
open = append(open, s)
if open && s.SequenceNumberRange.EndingSequenceNumber == nil {
res = append(res, s)
} else if !open && s.SequenceNumberRange.EndingSequenceNumber != nil {
res = append(res, s)
}
}
return open
return res
}
func flattenShards(shards []*kinesis.Shard) []string {
res := make([]string, len(shards))
for i, s := range shards {
res[i] = aws.StringValue(s.ShardId)
}
return res
}

View File

@ -31,8 +31,15 @@ func resourceAwsS3Bucket() *schema.Resource {
Schema: map[string]*schema.Schema{
"bucket": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"bucket_prefix"},
},
"bucket_prefix": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
},
@ -389,7 +396,15 @@ func resourceAwsS3BucketCreate(d *schema.ResourceData, meta interface{}) error {
s3conn := meta.(*AWSClient).s3conn
// Get the bucket and acl
bucket := d.Get("bucket").(string)
var bucket string
if v, ok := d.GetOk("bucket"); ok {
bucket = v.(string)
} else if v, ok := d.GetOk("bucket_prefix"); ok {
bucket = resource.PrefixedUniqueId(v.(string))
} else {
bucket = resource.UniqueId()
}
d.Set("bucket", bucket)
acl := d.Get("acl").(string)
log.Printf("[DEBUG] S3 bucket create: %s, ACL: %s", bucket, acl)

View File

@ -56,6 +56,40 @@ func TestAccAWSS3Bucket_basic(t *testing.T) {
})
}
func TestAccAWSS3Bucket_namePrefix(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSS3BucketDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSS3BucketConfig_namePrefix,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSS3BucketExists("aws_s3_bucket.test"),
resource.TestMatchResourceAttr(
"aws_s3_bucket.test", "bucket", regexp.MustCompile("^tf-test-")),
),
},
},
})
}
func TestAccAWSS3Bucket_generatedName(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSS3BucketDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSS3BucketConfig_generatedName,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSS3BucketExists("aws_s3_bucket.test"),
),
},
},
})
}
func TestAccAWSS3Bucket_region(t *testing.T) {
rInt := acctest.RandInt()
@ -1601,3 +1635,15 @@ resource "aws_s3_bucket" "destination" {
}
`, randInt, randInt, randInt)
}
const testAccAWSS3BucketConfig_namePrefix = `
resource "aws_s3_bucket" "test" {
bucket_prefix = "tf-test-"
}
`
const testAccAWSS3BucketConfig_generatedName = `
resource "aws_s3_bucket" "test" {
bucket_prefix = "tf-test-"
}
`

View File

@ -12,7 +12,7 @@ func TestAccAzureRMSubnet_importBasic(t *testing.T) {
resourceName := "azurerm_subnet.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri)
config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },

View File

@ -104,6 +104,14 @@ func resourceArmSubnetCreate(d *schema.ResourceData, meta interface{}) error {
properties.RouteTable = &network.RouteTable{
ID: &rtId,
}
routeTableName, err := parseRouteTableName(rtId)
if err != nil {
return err
}
armMutexKV.Lock(routeTableName)
defer armMutexKV.Unlock(routeTableName)
}
subnet := network.Subnet{
@ -201,6 +209,17 @@ func resourceArmSubnetDelete(d *schema.ResourceData, meta interface{}) error {
defer armMutexKV.Unlock(networkSecurityGroupName)
}
if v, ok := d.GetOk("route_table_id"); ok {
rtId := v.(string)
routeTableName, err := parseRouteTableName(rtId)
if err != nil {
return err
}
armMutexKV.Lock(routeTableName)
defer armMutexKV.Unlock(routeTableName)
}
armMutexKV.Lock(vnetName)
defer armMutexKV.Unlock(vnetName)

View File

@ -13,7 +13,7 @@ import (
func TestAccAzureRMSubnet_basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri)
config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
@ -33,7 +33,7 @@ func TestAccAzureRMSubnet_basic(t *testing.T) {
func TestAccAzureRMSubnet_disappears(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri)
config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
@ -152,5 +152,22 @@ resource "azurerm_subnet" "test" {
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.0.2.0/24"
route_table_id = "${azurerm_route_table.test.id}"
}
resource "azurerm_route_table" "test" {
name = "acctestroutetable%d"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "West US"
}
resource "azurerm_route" "test" {
name = "acctestroute%d"
resource_group_name = "${azurerm_resource_group.test.name}"
route_table_name = "${azurerm_route_table.test.name}"
address_prefix = "10.100.0.0/14"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = "10.10.1.1"
}
`

View File

@ -1033,7 +1033,7 @@ func flattenAzureRmVirtualMachineOsProfileLinuxConfiguration(config *compute.Lin
result["disable_password_authentication"] = *config.DisablePasswordAuthentication
if config.SSH != nil && len(*config.SSH.PublicKeys) > 0 {
ssh_keys := make([]map[string]interface{}, len(*config.SSH.PublicKeys))
ssh_keys := make([]map[string]interface{}, 0, len(*config.SSH.PublicKeys))
for _, i := range *config.SSH.PublicKeys {
key := make(map[string]interface{})
key["path"] = *i.Path

View File

@ -53,6 +53,11 @@ func parseAzureResourceID(id string) (*ResourceID, error) {
key := components[current]
value := components[current+1]
// Check key/value for empty strings.
if key == "" || value == "" {
return nil, fmt.Errorf("Key/Value cannot be empty strings. Key: '%s', Value: '%s'", key, value)
}
// Catch the subscriptionID before it can be overwritten by another "subscriptions"
// value in the ID which is the case for the Service Bus subscription resource
if key == "subscriptions" && subscriptionID == "" {
@ -104,3 +109,12 @@ func parseNetworkSecurityGroupName(networkSecurityGroupId string) (string, error
return id.Path["networkSecurityGroups"], nil
}
func parseRouteTableName(routeTableId string) (string, error) {
id, err := parseAzureResourceID(routeTableId)
if err != nil {
return "", fmt.Errorf("[ERROR] Unable to parse Route Table ID '%s': %+v", routeTableId, err)
}
return id.Path["routeTables"], nil
}

View File

@ -11,6 +11,18 @@ func TestParseAzureResourceID(t *testing.T) {
expectedResourceID *ResourceID
expectError bool
}{
{
// Missing "resourceGroups".
"/subscriptions/00000000-0000-0000-0000-000000000000//myResourceGroup/",
nil,
true,
},
{
// Empty resource group ID.
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//",
nil,
true,
},
{
"random",
nil,

View File

@ -334,11 +334,11 @@ func testAccCheckDigitalOceanDropletAttributes(droplet *godo.Droplet) resource.T
}
if droplet.Size.PriceHourly != 0.00744 {
return fmt.Errorf("Bad price_hourly: %s", droplet.Size.PriceHourly)
return fmt.Errorf("Bad price_hourly: %v", droplet.Size.PriceHourly)
}
if droplet.Size.PriceMonthly != 5.0 {
return fmt.Errorf("Bad price_monthly: %s", droplet.Size.PriceMonthly)
return fmt.Errorf("Bad price_monthly: %v", droplet.Size.PriceMonthly)
}
if droplet.Region.Slug != "nyc3" {

View File

@ -107,6 +107,80 @@ func resourceServiceV1() *schema.Resource {
Description: "The default hostname for the version",
},
"healthcheck": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
// required fields
"name": {
Type: schema.TypeString,
Required: true,
Description: "A name to refer to this healthcheck",
},
"host": {
Type: schema.TypeString,
Required: true,
Description: "Which host to check",
},
"path": {
Type: schema.TypeString,
Required: true,
Description: "The path to check",
},
// optional fields
"check_interval": {
Type: schema.TypeInt,
Optional: true,
Default: 5000,
Description: "How often to run the healthcheck in milliseconds",
},
"expected_response": {
Type: schema.TypeInt,
Optional: true,
Default: 200,
Description: "The status code expected from the host",
},
"http_version": {
Type: schema.TypeString,
Optional: true,
Default: "1.1",
Description: "Whether to use version 1.0 or 1.1 HTTP",
},
"initial": {
Type: schema.TypeInt,
Optional: true,
Default: 2,
Description: "When loading a config, the initial number of probes to be seen as OK",
},
"method": {
Type: schema.TypeString,
Optional: true,
Default: "HEAD",
Description: "Which HTTP method to use",
},
"threshold": {
Type: schema.TypeInt,
Optional: true,
Default: 3,
Description: "How many healthchecks must succeed to be considered healthy",
},
"timeout": {
Type: schema.TypeInt,
Optional: true,
Default: 500,
Description: "Timeout in milliseconds",
},
"window": {
Type: schema.TypeInt,
Optional: true,
Default: 5,
Description: "The number of most recent healthcheck queries to keep for this healthcheck",
},
},
},
},
"backend": {
Type: schema.TypeSet,
Optional: true,
@ -154,6 +228,12 @@ func resourceServiceV1() *schema.Resource {
Default: 15000,
Description: "How long to wait for the first bytes in milliseconds",
},
"healthcheck": {
Type: schema.TypeString,
Optional: true,
Default: "",
Description: "The healthcheck name that should be used for this Backend",
},
"max_conn": {
Type: schema.TypeInt,
Optional: true,
@ -403,80 +483,6 @@ func resourceServiceV1() *schema.Resource {
},
},
"healthcheck": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
// required fields
"name": {
Type: schema.TypeString,
Required: true,
Description: "A name to refer to this healthcheck",
},
"host": {
Type: schema.TypeString,
Required: true,
Description: "Which host to check",
},
"path": {
Type: schema.TypeString,
Required: true,
Description: "The path to check",
},
// optional fields
"check_interval": {
Type: schema.TypeInt,
Optional: true,
Default: 5000,
Description: "How often to run the healthcheck in milliseconds",
},
"expected_response": {
Type: schema.TypeInt,
Optional: true,
Default: 200,
Description: "The status code expected from the host",
},
"http_version": {
Type: schema.TypeString,
Optional: true,
Default: "1.1",
Description: "Whether to use version 1.0 or 1.1 HTTP",
},
"initial": {
Type: schema.TypeInt,
Optional: true,
Default: 2,
Description: "When loading a config, the initial number of probes to be seen as OK",
},
"method": {
Type: schema.TypeString,
Optional: true,
Default: "HEAD",
Description: "Which HTTP method to use",
},
"threshold": {
Type: schema.TypeInt,
Optional: true,
Default: 3,
Description: "How many healthchecks must succeed to be considered healthy",
},
"timeout": {
Type: schema.TypeInt,
Optional: true,
Default: 500,
Description: "Timeout in milliseconds",
},
"window": {
Type: schema.TypeInt,
Optional: true,
Default: 5,
Description: "The number of most recent healthcheck queries to keep for this healthcheck",
},
},
},
},
"s3logging": {
Type: schema.TypeSet,
Optional: true,
@ -1028,6 +1034,65 @@ func resourceServiceV1Update(d *schema.ResourceData, meta interface{}) error {
}
}
// Healthchecks need to be updated BEFORE backends
if d.HasChange("healthcheck") {
oh, nh := d.GetChange("healthcheck")
if oh == nil {
oh = new(schema.Set)
}
if nh == nil {
nh = new(schema.Set)
}
ohs := oh.(*schema.Set)
nhs := nh.(*schema.Set)
removeHealthCheck := ohs.Difference(nhs).List()
addHealthCheck := nhs.Difference(ohs).List()
// DELETE old healthcheck configurations
for _, hRaw := range removeHealthCheck {
hf := hRaw.(map[string]interface{})
opts := gofastly.DeleteHealthCheckInput{
Service: d.Id(),
Version: latestVersion,
Name: hf["name"].(string),
}
log.Printf("[DEBUG] Fastly Healthcheck removal opts: %#v", opts)
err := conn.DeleteHealthCheck(&opts)
if err != nil {
return err
}
}
// POST new/updated Healthcheck
for _, hRaw := range addHealthCheck {
hf := hRaw.(map[string]interface{})
opts := gofastly.CreateHealthCheckInput{
Service: d.Id(),
Version: latestVersion,
Name: hf["name"].(string),
Host: hf["host"].(string),
Path: hf["path"].(string),
CheckInterval: uint(hf["check_interval"].(int)),
ExpectedResponse: uint(hf["expected_response"].(int)),
HTTPVersion: hf["http_version"].(string),
Initial: uint(hf["initial"].(int)),
Method: hf["method"].(string),
Threshold: uint(hf["threshold"].(int)),
Timeout: uint(hf["timeout"].(int)),
Window: uint(hf["window"].(int)),
}
log.Printf("[DEBUG] Create Healthcheck Opts: %#v", opts)
_, err := conn.CreateHealthCheck(&opts)
if err != nil {
return err
}
}
}
// find difference in backends
if d.HasChange("backend") {
ob, nb := d.GetChange("backend")
@ -1081,6 +1146,7 @@ func resourceServiceV1Update(d *schema.ResourceData, meta interface{}) error {
MaxConn: uint(df["max_conn"].(int)),
Weight: uint(df["weight"].(int)),
RequestCondition: df["request_condition"].(string),
HealthCheck: df["healthcheck"].(string),
}
log.Printf("[DEBUG] Create Backend Opts: %#v", opts)
@ -1210,65 +1276,6 @@ func resourceServiceV1Update(d *schema.ResourceData, meta interface{}) error {
}
}
// find difference in Healthcheck
if d.HasChange("healthcheck") {
oh, nh := d.GetChange("healthcheck")
if oh == nil {
oh = new(schema.Set)
}
if nh == nil {
nh = new(schema.Set)
}
ohs := oh.(*schema.Set)
nhs := nh.(*schema.Set)
removeHealthCheck := ohs.Difference(nhs).List()
addHealthCheck := nhs.Difference(ohs).List()
// DELETE old healthcheck configurations
for _, hRaw := range removeHealthCheck {
hf := hRaw.(map[string]interface{})
opts := gofastly.DeleteHealthCheckInput{
Service: d.Id(),
Version: latestVersion,
Name: hf["name"].(string),
}
log.Printf("[DEBUG] Fastly Healthcheck removal opts: %#v", opts)
err := conn.DeleteHealthCheck(&opts)
if err != nil {
return err
}
}
// POST new/updated Healthcheck
for _, hRaw := range addHealthCheck {
hf := hRaw.(map[string]interface{})
opts := gofastly.CreateHealthCheckInput{
Service: d.Id(),
Version: latestVersion,
Name: hf["name"].(string),
Host: hf["host"].(string),
Path: hf["path"].(string),
CheckInterval: uint(hf["check_interval"].(int)),
ExpectedResponse: uint(hf["expected_response"].(int)),
HTTPVersion: hf["http_version"].(string),
Initial: uint(hf["initial"].(int)),
Method: hf["method"].(string),
Threshold: uint(hf["threshold"].(int)),
Timeout: uint(hf["timeout"].(int)),
Window: uint(hf["window"].(int)),
}
log.Printf("[DEBUG] Create Healthcheck Opts: %#v", opts)
_, err := conn.CreateHealthCheck(&opts)
if err != nil {
return err
}
}
}
// find difference in s3logging
if d.HasChange("s3logging") {
os, ns := d.GetChange("s3logging")
@ -1664,7 +1671,7 @@ func resourceServiceV1Update(d *schema.ResourceData, meta interface{}) error {
}
// validate version
log.Printf("[DEBUG] Validating Fastly Service (%s), Version (%s)", d.Id(), latestVersion)
log.Printf("[DEBUG] Validating Fastly Service (%s), Version (%v)", d.Id(), latestVersion)
valid, msg, err := conn.ValidateVersion(&gofastly.ValidateVersionInput{
Service: d.Id(),
Version: latestVersion,
@ -1678,7 +1685,7 @@ func resourceServiceV1Update(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("[ERR] Invalid configuration for Fastly Service (%s): %s", d.Id(), msg)
}
log.Printf("[DEBUG] Activating Fastly Service (%s), Version (%s)", d.Id(), latestVersion)
log.Printf("[DEBUG] Activating Fastly Service (%s), Version (%v)", d.Id(), latestVersion)
_, err = conn.ActivateVersion(&gofastly.ActivateVersionInput{
Service: d.Id(),
Version: latestVersion,
@ -1735,7 +1742,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
d.Set("default_host", settings.DefaultHost)
d.Set("default_ttl", settings.DefaultTTL)
} else {
return fmt.Errorf("[ERR] Error looking up Version settings for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Version settings for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
// TODO: update go-fastly to support an ActiveVersion struct, which contains
@ -1748,7 +1755,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Domains for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Domains for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
// Refresh Domains
@ -1766,7 +1773,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Backends for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Backends for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
bl := flattenBackends(backendList)
@ -1783,7 +1790,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Headers for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Headers for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
hl := flattenHeaders(headerList)
@ -1800,7 +1807,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Gzips for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Gzips for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
gl := flattenGzips(gzipsList)
@ -1817,7 +1824,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Healthcheck for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Healthcheck for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
hcl := flattenHealthchecks(healthcheckList)
@ -1834,7 +1841,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up S3 Logging for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up S3 Logging for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
sl := flattenS3s(s3List)
@ -1851,7 +1858,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Papertrail for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Papertrail for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
pl := flattenPapertrails(papertrailList)
@ -1868,7 +1875,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Sumologic for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Sumologic for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
sul := flattenSumologics(sumologicList)
@ -1884,7 +1891,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Response Object for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Response Object for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
rol := flattenResponseObjects(responseObjectList)
@ -1901,7 +1908,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Conditions for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Conditions for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
cl := flattenConditions(conditionList)
@ -1918,7 +1925,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Request Settings for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Request Settings for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
rl := flattenRequestSettings(rsList)
@ -1934,7 +1941,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
Version: s.ActiveVersion.Number,
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up VCLs for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up VCLs for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
vl := flattenVCLs(vclList)
@ -1950,7 +1957,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error {
Version: s.ActiveVersion.Number,
})
if err != nil {
return fmt.Errorf("[ERR] Error looking up Cache Settings for (%s), version (%d): %s", d.Id(), s.ActiveVersion.Number, err)
return fmt.Errorf("[ERR] Error looking up Cache Settings for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err)
}
csl := flattenCacheSettings(cslList)
@ -2051,6 +2058,7 @@ func flattenBackends(backendList []*gofastly.Backend) []map[string]interface{} {
"ssl_sni_hostname": b.SSLSNIHostname,
"weight": int(b.Weight),
"request_condition": b.RequestCondition,
"healthcheck": b.HealthCheck,
}
bl = append(bl, nb)

View File

@ -71,6 +71,7 @@ func TestResourceFastlyFlattenBackend(t *testing.T) {
FirstByteTimeout: uint(15000),
MaxConn: uint(200),
RequestCondition: "",
HealthCheck: "",
SSLCheckCert: true,
SSLHostname: "",
SSLCertHostname: "",
@ -91,6 +92,7 @@ func TestResourceFastlyFlattenBackend(t *testing.T) {
"first_byte_timeout": 15000,
"max_conn": 200,
"request_condition": "",
"healthcheck": "",
"ssl_check_cert": true,
"ssl_hostname": "",
"ssl_cert_hostname": "",

View File

@ -41,6 +41,7 @@ func Provider() terraform.ResourceProvider {
"github_organization_webhook": resourceGithubOrganizationWebhook(),
"github_repository_collaborator": resourceGithubRepositoryCollaborator(),
"github_issue_label": resourceGithubIssueLabel(),
"github_branch_protection": resourceGithubBranchProtection(),
},
ConfigureFunc: providerConfigure,

View File

@ -0,0 +1,278 @@
package github
import (
"context"
"errors"
"github.com/google/go-github/github"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceGithubBranchProtection() *schema.Resource {
return &schema.Resource{
Create: resourceGithubBranchProtectionCreate,
Read: resourceGithubBranchProtectionRead,
Update: resourceGithubBranchProtectionUpdate,
Delete: resourceGithubBranchProtectionDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"repository": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"branch": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"required_status_checks": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"include_admins": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"strict": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"contexts": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
"required_pull_request_reviews": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"include_admins": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
},
},
"restrictions": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"users": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"teams": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
}
}
func resourceGithubBranchProtectionCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r := d.Get("repository").(string)
b := d.Get("branch").(string)
protectionRequest, err := buildProtectionRequest(d)
if err != nil {
return err
}
_, _, err = client.Repositories.UpdateBranchProtection(context.TODO(), meta.(*Organization).name, r, b, protectionRequest)
if err != nil {
return err
}
d.SetId(buildTwoPartID(&r, &b))
return resourceGithubBranchProtectionRead(d, meta)
}
func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r, b := parseTwoPartID(d.Id())
githubProtection, _, err := client.Repositories.GetBranchProtection(context.TODO(), meta.(*Organization).name, r, b)
if err != nil {
d.SetId("")
return nil
}
d.Set("repository", r)
d.Set("branch", b)
rsc := githubProtection.RequiredStatusChecks
if rsc != nil {
d.Set("required_status_checks", []interface{}{
map[string]interface{}{
"include_admins": rsc.IncludeAdmins,
"strict": rsc.Strict,
"contexts": rsc.Contexts,
},
})
} else {
d.Set("required_status_checks", []interface{}{})
}
rprr := githubProtection.RequiredPullRequestReviews
if rprr != nil {
d.Set("required_pull_request_reviews", []interface{}{
map[string]interface{}{
"include_admins": rprr.IncludeAdmins,
},
})
} else {
d.Set("required_pull_request_reviews", []interface{}{})
}
restrictions := githubProtection.Restrictions
if restrictions != nil {
var userLogins []string
for _, u := range restrictions.Users {
if u.Login != nil {
userLogins = append(userLogins, *u.Login)
}
}
var teamSlugs []string
for _, t := range restrictions.Teams {
if t.Slug != nil {
teamSlugs = append(teamSlugs, *t.Slug)
}
}
d.Set("restrictions", []interface{}{
map[string]interface{}{
"users": userLogins,
"teams": teamSlugs,
},
})
} else {
d.Set("restrictions", []interface{}{})
}
return nil
}
func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r, b := parseTwoPartID(d.Id())
protectionRequest, err := buildProtectionRequest(d)
if err != nil {
return err
}
_, _, err = client.Repositories.UpdateBranchProtection(context.TODO(), meta.(*Organization).name, r, b, protectionRequest)
if err != nil {
return err
}
d.SetId(buildTwoPartID(&r, &b))
return resourceGithubBranchProtectionRead(d, meta)
}
func resourceGithubBranchProtectionDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r, b := parseTwoPartID(d.Id())
_, err := client.Repositories.RemoveBranchProtection(context.TODO(), meta.(*Organization).name, r, b)
return err
}
func buildProtectionRequest(d *schema.ResourceData) (*github.ProtectionRequest, error) {
protectionRequest := new(github.ProtectionRequest)
if v, ok := d.GetOk("required_status_checks"); ok {
vL := v.([]interface{})
if len(vL) > 1 {
return nil, errors.New("cannot specify required_status_checks more than one time")
}
for _, v := range vL {
m := v.(map[string]interface{})
rsc := new(github.RequiredStatusChecks)
rsc.IncludeAdmins = m["include_admins"].(bool)
rsc.Strict = m["strict"].(bool)
rsc.Contexts = []string{}
if contexts, ok := m["contexts"].([]interface{}); ok {
for _, c := range contexts {
rsc.Contexts = append(rsc.Contexts, c.(string))
}
}
protectionRequest.RequiredStatusChecks = rsc
}
}
if v, ok := d.GetOk("required_pull_request_reviews"); ok {
vL := v.([]interface{})
if len(vL) > 1 {
return nil, errors.New("cannot specify required_pull_request_reviews more than one time")
}
for _, v := range vL {
m := v.(map[string]interface{})
rprr := new(github.RequiredPullRequestReviews)
rprr.IncludeAdmins = m["include_admins"].(bool)
protectionRequest.RequiredPullRequestReviews = rprr
}
}
if v, ok := d.GetOk("restrictions"); ok {
vL := v.([]interface{})
if len(vL) > 1 {
return nil, errors.New("cannot specify restrictions more than one time")
}
for _, v := range vL {
m := v.(map[string]interface{})
restrictions := new(github.BranchRestrictionsRequest)
restrictions.Users = []string{}
if users, ok := m["users"].([]interface{}); ok {
for _, u := range users {
restrictions.Users = append(restrictions.Users, u.(string))
}
}
restrictions.Teams = []string{}
if teams, ok := m["teams"].([]interface{}); ok {
for _, t := range teams {
restrictions.Teams = append(restrictions.Teams, t.(string))
}
}
protectionRequest.Restrictions = restrictions
}
}
return protectionRequest, nil
}

View File

@ -0,0 +1,220 @@
package github
import (
"context"
"fmt"
"reflect"
"testing"
"github.com/google/go-github/github"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccGithubBranchProtection_basic(t *testing.T) {
var protection github.Protection
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccGithubBranchProtectionDestroy,
Steps: []resource.TestStep{
{
Config: testAccGithubBranchProtectionConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckGithubProtectedBranchExists("github_branch_protection.master", &protection),
testAccCheckGithubBranchProtectionRequiredStatusChecks(&protection, true, true, []string{"github/foo"}),
testAccCheckGithubBranchProtectionRestrictions(&protection, []string{testUser}, []string{}),
resource.TestCheckResourceAttr("github_branch_protection.master", "repository", testRepo),
resource.TestCheckResourceAttr("github_branch_protection.master", "branch", "master"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_status_checks.0.include_admins", "true"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_status_checks.0.strict", "true"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_status_checks.0.contexts.#", "1"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_status_checks.0.contexts.0", "github/foo"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_pull_request_reviews.0.include_admins", "true"),
resource.TestCheckResourceAttr("github_branch_protection.master", "restrictions.0.users.#", "1"),
resource.TestCheckResourceAttr("github_branch_protection.master", "restrictions.0.users.0", testUser),
resource.TestCheckResourceAttr("github_branch_protection.master", "restrictions.0.teams.#", "0"),
),
},
{
Config: testAccGithubBranchProtectionUpdateConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckGithubProtectedBranchExists("github_branch_protection.master", &protection),
testAccCheckGithubBranchProtectionRequiredStatusChecks(&protection, false, false, []string{"github/bar"}),
testAccCheckGithubBranchProtectionNoRestrictionsExist(&protection),
resource.TestCheckResourceAttr("github_branch_protection.master", "repository", testRepo),
resource.TestCheckResourceAttr("github_branch_protection.master", "branch", "master"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_status_checks.0.include_admins", "false"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_status_checks.0.strict", "false"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_status_checks.0.contexts.#", "1"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_status_checks.0.contexts.0", "github/bar"),
resource.TestCheckResourceAttr("github_branch_protection.master", "required_pull_request_reviews.#", "0"),
resource.TestCheckResourceAttr("github_branch_protection.master", "restrictions.#", "0"),
),
},
},
})
}
func TestAccGithubBranchProtection_importBasic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccGithubBranchProtectionDestroy,
Steps: []resource.TestStep{
{
Config: testAccGithubBranchProtectionConfig,
},
{
ResourceName: "github_branch_protection.master",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccCheckGithubProtectedBranchExists(n string, protection *github.Protection) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not Found: %s", n)
}
if rs.Primary.ID != "test-repo:master" {
return fmt.Errorf("Expected ID to be %v, got %v", "test-repo:master", rs.Primary.ID)
}
conn := testAccProvider.Meta().(*Organization).client
o := testAccProvider.Meta().(*Organization).name
r, b := parseTwoPartID(rs.Primary.ID)
githubProtection, _, err := conn.Repositories.GetBranchProtection(context.TODO(), o, r, b)
if err != nil {
return err
}
*protection = *githubProtection
return nil
}
}
func testAccCheckGithubBranchProtectionRequiredStatusChecks(protection *github.Protection, expectedIncludeAdmins bool, expectedStrict bool, expectedContexts []string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rsc := protection.RequiredStatusChecks
if rsc == nil {
return fmt.Errorf("Expected RequiredStatusChecks to be present, but was nil")
}
if rsc.IncludeAdmins != expectedIncludeAdmins {
return fmt.Errorf("Expected RequiredStatusChecks.IncludeAdmins to be %v, got %v", expectedIncludeAdmins, rsc.IncludeAdmins)
}
if rsc.Strict != expectedStrict {
return fmt.Errorf("Expected RequiredStatusChecks.Strict to be %v, got %v", expectedStrict, rsc.Strict)
}
if !reflect.DeepEqual(rsc.Contexts, expectedContexts) {
return fmt.Errorf("Expected RequiredStatusChecks.Contexts to be %v, got %v", expectedContexts, rsc.Contexts)
}
return nil
}
}
func testAccCheckGithubBranchProtectionRestrictions(protection *github.Protection, expectedUserLogins []string, expectedTeamNames []string) resource.TestCheckFunc {
return func(s *terraform.State) error {
restrictions := protection.Restrictions
if restrictions == nil {
return fmt.Errorf("Expected Restrictions to be present, but was nil")
}
userLogins := []string{}
for _, u := range restrictions.Users {
userLogins = append(userLogins, *u.Login)
}
if !reflect.DeepEqual(userLogins, expectedUserLogins) {
return fmt.Errorf("Expected Restrictions.Users to be %v, got %v", expectedUserLogins, userLogins)
}
teamLogins := []string{}
for _, t := range restrictions.Teams {
teamLogins = append(teamLogins, *t.Name)
}
if !reflect.DeepEqual(teamLogins, expectedTeamNames) {
return fmt.Errorf("Expected Restrictions.Teams to be %v, got %v", expectedTeamNames, teamLogins)
}
return nil
}
}
func testAccCheckGithubBranchProtectionNoRestrictionsExist(protection *github.Protection) resource.TestCheckFunc {
return func(s *terraform.State) error {
if protection.Restrictions != nil {
return fmt.Errorf("Expected Restrictions to be nil, but was %v", protection.Restrictions)
}
return nil
}
}
func testAccGithubBranchProtectionDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*Organization).client
for _, rs := range s.RootModule().Resources {
if rs.Type != "github_branch_protection" {
continue
}
o := testAccProvider.Meta().(*Organization).name
r, b := parseTwoPartID(rs.Primary.ID)
protection, res, err := conn.Repositories.GetBranchProtection(context.TODO(), o, r, b)
if err == nil {
if protection != nil {
return fmt.Errorf("Branch protection still exists")
}
}
if res.StatusCode != 404 {
return err
}
return nil
}
return nil
}
var testAccGithubBranchProtectionConfig string = fmt.Sprintf(`
resource "github_branch_protection" "master" {
repository = "%s"
branch = "master"
required_status_checks = {
include_admins = true
strict = true
contexts = ["github/foo"]
}
required_pull_request_reviews {
include_admins = true
}
restrictions {
users = ["%s"]
}
}
`, testRepo, testUser)
var testAccGithubBranchProtectionUpdateConfig string = fmt.Sprintf(`
resource "github_branch_protection" "master" {
repository = "%s"
branch = "master"
required_status_checks = {
include_admins = false
strict = false
contexts = ["github/bar"]
}
}
`, testRepo)

View File

@ -13,6 +13,7 @@ import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/jwt"
"google.golang.org/api/bigquery/v2"
"google.golang.org/api/cloudbilling/v1"
"google.golang.org/api/cloudresourcemanager/v1"
"google.golang.org/api/compute/v1"
@ -42,6 +43,7 @@ type Config struct {
clientSqlAdmin *sqladmin.Service
clientIAM *iam.Service
clientServiceMan *servicemanagement.APIService
clientBigQuery *bigquery.Service
}
func (c *Config) loadAndValidate() error {
@ -169,6 +171,13 @@ func (c *Config) loadAndValidate() error {
}
c.clientBilling.UserAgent = userAgent
log.Printf("[INFO] Instantiating Google Cloud BigQuery Client...")
c.clientBigQuery, err = bigquery.New(client)
if err != nil {
return err
}
c.clientBigQuery.UserAgent = userAgent
return nil
}

View File

@ -0,0 +1,31 @@
package google
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccBigQueryDataset_importBasic(t *testing.T) {
resourceName := "google_bigquery_dataset.test"
datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckBigQueryDatasetDestroy,
Steps: []resource.TestStep{
{
Config: testAccBigQueryDataset(datasetID),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -55,6 +55,7 @@ func Provider() terraform.ResourceProvider {
},
ResourcesMap: map[string]*schema.Resource{
"google_bigquery_dataset": resourceBigQueryDataset(),
"google_compute_autoscaler": resourceComputeAutoscaler(),
"google_compute_address": resourceComputeAddress(),
"google_compute_backend_service": resourceComputeBackendService(),

View File

@ -0,0 +1,285 @@
package google
import (
"fmt"
"log"
"regexp"
"strings"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"google.golang.org/api/bigquery/v2"
"google.golang.org/api/googleapi"
)
func resourceBigQueryDataset() *schema.Resource {
return &schema.Resource{
Create: resourceBigQueryDatasetCreate,
Read: resourceBigQueryDatasetRead,
Update: resourceBigQueryDatasetUpdate,
Delete: resourceBigQueryDatasetDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
// DatasetId: [Required] A unique ID for this dataset, without the
// project name. The ID must contain only letters (a-z, A-Z), numbers
// (0-9), or underscores (_). The maximum length is 1,024 characters.
"dataset_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9A-Za-z_]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q must contain only letters (a-z, A-Z), numbers (0-9), or underscores (_)", k))
}
if len(value) > 1024 {
errors = append(errors, fmt.Errorf(
"%q cannot be greater than 1,024 characters", k))
}
return
},
},
// ProjectId: [Optional] The ID of the project containing this dataset.
"project": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
// FriendlyName: [Optional] A descriptive name for the dataset.
"friendly_name": {
Type: schema.TypeString,
Optional: true,
},
// Description: [Optional] A user-friendly description of the dataset.
"description": {
Type: schema.TypeString,
Optional: true,
},
// Location: [Experimental] The geographic location where the dataset
// should reside. Possible values include EU and US. The default value
// is US.
"location": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: "US",
ValidateFunc: validation.StringInSlice([]string{"US", "EU"}, false),
},
// DefaultTableExpirationMs: [Optional] The default lifetime of all
// tables in the dataset, in milliseconds. The minimum value is 3600000
// milliseconds (one hour). Once this property is set, all newly-created
// tables in the dataset will have an expirationTime property set to the
// creation time plus the value in this property, and changing the value
// will only affect new tables, not existing ones. When the
// expirationTime for a given table is reached, that table will be
// deleted automatically. If a table's expirationTime is modified or
// removed before the table expires, or if you provide an explicit
// expirationTime when creating a table, that value takes precedence
// over the default expiration time indicated by this property.
"default_table_expiration_ms": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
value := v.(int)
if value < 3600000 {
errors = append(errors, fmt.Errorf("%q cannot be shorter than 3600000 milliseconds (one hour)", k))
}
return
},
},
// Labels: [Experimental] The labels associated with this dataset. You
// can use these to organize and group your datasets. You can set this
// property when inserting or updating a dataset.
"labels": &schema.Schema{
Type: schema.TypeMap,
Optional: true,
Elem: schema.TypeString,
},
// SelfLink: [Output-only] A URL that can be used to access the resource
// again. You can use this URL in Get or Update requests to the
// resource.
"self_link": {
Type: schema.TypeString,
Computed: true,
},
// Etag: [Output-only] A hash of the resource.
"etag": {
Type: schema.TypeString,
Computed: true,
},
// CreationTime: [Output-only] The time when this dataset was created,
// in milliseconds since the epoch.
"creation_time": {
Type: schema.TypeInt,
Computed: true,
},
// LastModifiedTime: [Output-only] The date when this dataset or any of
// its tables was last modified, in milliseconds since the epoch.
"last_modified_time": {
Type: schema.TypeInt,
Computed: true,
},
},
}
}
func resourceDataset(d *schema.ResourceData, meta interface{}) (*bigquery.Dataset, error) {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return nil, err
}
dataset := &bigquery.Dataset{
DatasetReference: &bigquery.DatasetReference{
DatasetId: d.Get("dataset_id").(string),
ProjectId: project,
},
}
if v, ok := d.GetOk("friendly_name"); ok {
dataset.FriendlyName = v.(string)
}
if v, ok := d.GetOk("description"); ok {
dataset.Description = v.(string)
}
if v, ok := d.GetOk("location"); ok {
dataset.Location = v.(string)
}
if v, ok := d.GetOk("default_table_expiration_ms"); ok {
dataset.DefaultTableExpirationMs = int64(v.(int))
}
if v, ok := d.GetOk("labels"); ok {
labels := map[string]string{}
for k, v := range v.(map[string]interface{}) {
labels[k] = v.(string)
}
dataset.Labels = labels
}
return dataset, nil
}
func resourceBigQueryDatasetCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
dataset, err := resourceDataset(d, meta)
if err != nil {
return err
}
log.Printf("[INFO] Creating BigQuery dataset: %s", dataset.DatasetReference.DatasetId)
res, err := config.clientBigQuery.Datasets.Insert(project, dataset).Do()
if err != nil {
return err
}
log.Printf("[INFO] BigQuery dataset %s has been created", res.Id)
d.SetId(res.Id)
return resourceBigQueryDatasetRead(d, meta)
}
func resourceBigQueryDatasetParseID(id string) (string, string) {
// projectID, datasetID
parts := strings.Split(id, ":")
return parts[0], parts[1]
}
func resourceBigQueryDatasetRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
log.Printf("[INFO] Reading BigQuery dataset: %s", d.Id())
projectID, datasetID := resourceBigQueryDatasetParseID(d.Id())
res, err := config.clientBigQuery.Datasets.Get(projectID, datasetID).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
log.Printf("[WARN] Removing BigQuery dataset %q because it's gone", datasetID)
// The resource doesn't exist anymore
d.SetId("")
return nil
}
return err
}
d.Set("etag", res.Etag)
d.Set("labels", res.Labels)
d.Set("location", res.Location)
d.Set("self_link", res.SelfLink)
d.Set("description", res.Description)
d.Set("friendly_name", res.FriendlyName)
d.Set("creation_time", res.CreationTime)
d.Set("last_modified_time", res.LastModifiedTime)
d.Set("dataset_id", res.DatasetReference.DatasetId)
d.Set("default_table_expiration_ms", res.DefaultTableExpirationMs)
return nil
}
func resourceBigQueryDatasetUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
dataset, err := resourceDataset(d, meta)
if err != nil {
return err
}
log.Printf("[INFO] Updating BigQuery dataset: %s", d.Id())
projectID, datasetID := resourceBigQueryDatasetParseID(d.Id())
if _, err = config.clientBigQuery.Datasets.Update(projectID, datasetID, dataset).Do(); err != nil {
return err
}
return resourceBigQueryDatasetRead(d, meta)
}
func resourceBigQueryDatasetDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
log.Printf("[INFO] Deleting BigQuery dataset: %s", d.Id())
projectID, datasetID := resourceBigQueryDatasetParseID(d.Id())
if err := config.clientBigQuery.Datasets.Delete(projectID, datasetID).Do(); err != nil {
return err
}
d.SetId("")
return nil
}

View File

@ -0,0 +1,112 @@
package google
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccBigQueryDataset_basic(t *testing.T) {
datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckBigQueryDatasetDestroy,
Steps: []resource.TestStep{
{
Config: testAccBigQueryDataset(datasetID),
Check: resource.ComposeTestCheckFunc(
testAccCheckBigQueryDatasetExists(
"google_bigquery_dataset.test"),
),
},
{
Config: testAccBigQueryDatasetUpdated(datasetID),
Check: resource.ComposeTestCheckFunc(
testAccCheckBigQueryDatasetExists(
"google_bigquery_dataset.test"),
),
},
},
})
}
func testAccCheckBigQueryDatasetDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
for _, rs := range s.RootModule().Resources {
if rs.Type != "google_bigquery_dataset" {
continue
}
_, err := config.clientBigQuery.Datasets.Get(config.Project, rs.Primary.Attributes["dataset_id"]).Do()
if err == nil {
return fmt.Errorf("Dataset still exists")
}
}
return nil
}
func testAccCheckBigQueryDatasetExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}
config := testAccProvider.Meta().(*Config)
found, err := config.clientBigQuery.Datasets.Get(config.Project, rs.Primary.Attributes["dataset_id"]).Do()
if err != nil {
return err
}
if found.Id != rs.Primary.ID {
return fmt.Errorf("Dataset not found")
}
return nil
}
}
func testAccBigQueryDataset(datasetID string) string {
return fmt.Sprintf(`
resource "google_bigquery_dataset" "test" {
dataset_id = "%s"
friendly_name = "foo"
description = "This is a foo description"
location = "EU"
default_table_expiration_ms = 3600000
labels {
env = "foo"
default_table_expiration_ms = 3600000
}
}`, datasetID)
}
func testAccBigQueryDatasetUpdated(datasetID string) string {
return fmt.Sprintf(`
resource "google_bigquery_dataset" "test" {
dataset_id = "%s"
friendly_name = "bar"
description = "This is a bar description"
location = "EU"
default_table_expiration_ms = 7200000
labels {
env = "bar"
default_table_expiration_ms = 7200000
}
}`, datasetID)
}

View File

@ -15,10 +15,7 @@ func resourceComputeAddress() *schema.Resource {
Read: resourceComputeAddressRead,
Delete: resourceComputeAddressDelete,
Importer: &schema.ResourceImporter{
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
d.Set("name", d.Id())
return []*schema.ResourceData{d}, nil
},
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
@ -113,6 +110,7 @@ func resourceComputeAddressRead(d *schema.ResourceData, meta interface{}) error
d.Set("address", addr.Address)
d.Set("self_link", addr.SelfLink)
d.Set("name", addr.Name)
return nil
}

View File

@ -15,10 +15,7 @@ func resourceComputeGlobalAddress() *schema.Resource {
Read: resourceComputeGlobalAddressRead,
Delete: resourceComputeGlobalAddressDelete,
Importer: &schema.ResourceImporter{
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
d.Set("name", d.Id())
return []*schema.ResourceData{d}, nil
},
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
@ -97,6 +94,7 @@ func resourceComputeGlobalAddressRead(d *schema.ResourceData, meta interface{})
d.Set("address", addr.Address)
d.Set("self_link", addr.SelfLink)
d.Set("name", addr.Name)
return nil
}

View File

@ -2,9 +2,12 @@ package logentries
import (
"fmt"
"log"
"strconv"
"strings"
"github.com/hashicorp/terraform/helper/schema"
logentries "github.com/logentries/le_goclient"
"strconv"
)
func resourceLogentriesLog() *schema.Resource {
@ -16,25 +19,25 @@ func resourceLogentriesLog() *schema.Resource {
Delete: resourceLogentriesLogDelete,
Schema: map[string]*schema.Schema{
"token": &schema.Schema{
"token": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
},
"logset_id": &schema.Schema{
"logset_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": &schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"filename": &schema.Schema{
"filename": {
Type: schema.TypeString,
Optional: true,
},
"retention_period": &schema.Schema{
"retention_period": {
Type: schema.TypeString,
Optional: true,
Default: "ACCOUNT_DEFAULT",
@ -47,7 +50,7 @@ func resourceLogentriesLog() *schema.Resource {
return
},
},
"source": &schema.Schema{
"source": {
Type: schema.TypeString,
Optional: true,
Default: "token",
@ -60,7 +63,7 @@ func resourceLogentriesLog() *schema.Resource {
return
},
},
"type": &schema.Schema{
"type": {
Type: schema.TypeString,
Default: "",
Optional: true,
@ -100,6 +103,11 @@ func resourceLogentriesLogRead(d *schema.ResourceData, meta interface{}) error {
Key: d.Id(),
})
if err != nil {
if strings.Contains(err.Error(), "not found") {
log.Printf("Logentries Log Not Found - Refreshing from State")
d.SetId("")
return nil
}
return err
}

View File

@ -1,8 +1,11 @@
package logentries
import (
"log"
"strings"
"github.com/hashicorp/terraform/helper/schema"
"github.com/logentries/le_goclient"
logentries "github.com/logentries/le_goclient"
)
func resourceLogentriesLogSet() *schema.Resource {
@ -49,6 +52,11 @@ func resourceLogentriesLogSetRead(d *schema.ResourceData, meta interface{}) erro
Key: d.Id(),
})
if err != nil {
if strings.Contains(err.Error(), "No such log set") {
log.Printf("Logentries LogSet Not Found - Refreshing from State")
d.SetId("")
return nil
}
return err
}

View File

@ -0,0 +1,60 @@
package opc
import (
"fmt"
"log"
"net/url"
"strings"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/go-oracle-terraform/opc"
"github.com/hashicorp/terraform/helper/logging"
)
type Config struct {
User string
Password string
IdentityDomain string
Endpoint string
MaxRetryTimeout int
}
type OPCClient struct {
Client *compute.Client
MaxRetryTimeout int
}
func (c *Config) Client() (*compute.Client, error) {
u, err := url.ParseRequestURI(c.Endpoint)
if err != nil {
return nil, fmt.Errorf("Invalid endpoint URI: %s", err)
}
config := opc.Config{
IdentityDomain: &c.IdentityDomain,
Username: &c.User,
Password: &c.Password,
APIEndpoint: u,
HTTPClient: cleanhttp.DefaultClient(),
}
if logging.IsDebugOrHigher() {
config.LogLevel = opc.LogDebug
config.Logger = opcLogger{}
}
return compute.NewComputeClient(&config)
}
type opcLogger struct{}
func (l opcLogger) Log(args ...interface{}) {
tokens := make([]string, 0, len(args))
for _, arg := range args {
if token, ok := arg.(string); ok {
tokens = append(tokens, token)
}
}
log.Printf("[DEBUG] [go-oracle-terraform]: %s", strings.Join(tokens, " "))
}

View File

@ -0,0 +1,176 @@
package opc
import (
"fmt"
"log"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func dataSourceNetworkInterface() *schema.Resource {
return &schema.Resource{
Read: dataSourceNetworkInterfaceRead,
Schema: map[string]*schema.Schema{
"instance_id": {
Type: schema.TypeString,
Required: true,
},
"instance_name": {
Type: schema.TypeString,
Required: true,
},
"interface": {
Type: schema.TypeString,
Required: true,
},
// Computed Values returned from the data source lookup
"dns": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
},
"ip_network": {
Type: schema.TypeString,
Computed: true,
},
"mac_address": {
Type: schema.TypeString,
Computed: true,
},
"model": {
Type: schema.TypeString,
Computed: true,
},
"name_servers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"nat": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"search_domains": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"sec_lists": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"shared_network": {
Type: schema.TypeBool,
Computed: true,
},
"vnic": {
Type: schema.TypeString,
Computed: true,
},
"vnic_sets": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}
func dataSourceNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).Instances()
// Get required attributes
instance_name := d.Get("instance_name").(string)
instance_id := d.Get("instance_id").(string)
targetInterface := d.Get("interface").(string)
// Get instance
input := &compute.GetInstanceInput{
Name: instance_name,
ID: instance_id,
}
instance, err := client.GetInstance(input)
if err != nil {
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading instance %q: %v", instance_name, err)
}
result := compute.NetworkingInfo{}
// If the target instance has no network interfaces, return
if instance.Networking == nil {
d.SetId("")
return nil
}
// Set the computed fields
result = instance.Networking[targetInterface]
// Check if the target interface exists or not
if &result == nil {
log.Printf("[WARN] %q networking interface not found on instance %q", targetInterface, instance_name)
}
d.SetId(fmt.Sprintf("%s-%s", instance_name, targetInterface))
// vNIC is a required field for an IP Network interface, and can only be set if the network
// interface is inside an IP Network. Use this key to determine shared_network status
if result.Vnic != "" {
d.Set("shared_network", false)
} else {
d.Set("shared_network", true)
}
d.Set("ip_address", result.IPAddress)
d.Set("ip_network", result.IPNetwork)
d.Set("mac_address", result.MACAddress)
d.Set("model", result.Model)
d.Set("vnic", result.Vnic)
if err := setStringList(d, "dns", result.DNS); err != nil {
return err
}
if err := setStringList(d, "name_servers", result.NameServers); err != nil {
return err
}
if err := setStringList(d, "nat", result.Nat); err != nil {
return err
}
if err := setStringList(d, "search_domains", result.SearchDomains); err != nil {
return err
}
if err := setStringList(d, "sec_lists", result.SecLists); err != nil {
return err
}
if err := setStringList(d, "vnic_sets", result.VnicSets); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,101 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCDataSourceNetworkInterface_basic(t *testing.T) {
rInt := acctest.RandInt()
resName := "data.opc_compute_network_interface.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceNetworkInterfaceBasic(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resName, "ip_network", fmt.Sprintf("testing-ip-network-%d", rInt)),
resource.TestCheckResourceAttr(resName, "vnic", fmt.Sprintf("ip-network-test-%d", rInt)),
resource.TestCheckResourceAttr(resName, "shared_network", "false"),
),
},
},
})
}
func TestAccOPCDataSourceNetworkInterface_sharedNetwork(t *testing.T) {
rInt := acctest.RandInt()
resName := "data.opc_compute_network_interface.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceNetworkInterfaceShared(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resName, "nat.#", "1"),
resource.TestCheckResourceAttr(resName, "shared_network", "true"),
resource.TestCheckResourceAttr(resName, "sec_lists.#", "1"),
resource.TestCheckResourceAttr(resName, "name_servers.#", "0"),
resource.TestCheckResourceAttr(resName, "vnic_sets.#", "0"),
),
},
},
})
}
func testAccDataSourceNetworkInterfaceBasic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_network" "foo" {
name = "testing-ip-network-%d"
description = "testing-ip-network-instance"
ip_address_prefix = "10.1.12.0/24"
}
resource "opc_compute_instance" "test" {
name = "test-%d"
label = "test"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
networking_info {
index = 0
ip_network = "${opc_compute_ip_network.foo.id}"
vnic = "ip-network-test-%d"
shared_network = false
}
}
data "opc_compute_network_interface" "test" {
instance_name = "${opc_compute_instance.test.name}"
instance_id = "${opc_compute_instance.test.id}"
interface = "eth0"
}`, rInt, rInt, rInt)
}
func testAccDataSourceNetworkInterfaceShared(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_instance" "test" {
name = "test-%d"
label = "test"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
tags = ["tag1", "tag2"]
networking_info {
index = 0
nat = ["ippool:/oracle/public/ippool"]
shared_network = true
}
}
data "opc_compute_network_interface" "test" {
instance_name = "${opc_compute_instance.test.name}"
instance_id = "${opc_compute_instance.test.id}"
interface = "eth0"
}`, rInt)
}

View File

@ -0,0 +1,72 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func dataSourceVNIC() *schema.Resource {
return &schema.Resource{
Read: dataSourceVNICRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"mac_address": {
Type: schema.TypeString,
Computed: true,
},
"tags": tagsComputedSchema(),
"transit_flag": {
Type: schema.TypeBool,
Computed: true,
},
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func dataSourceVNICRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).VirtNICs()
name := d.Get("name").(string)
input := &compute.GetVirtualNICInput{
Name: name,
}
vnic, err := client.GetVirtualNIC(input)
if err != nil {
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading vnic %s: %s", name, err)
}
d.SetId(name)
d.Set("description", vnic.Description)
d.Set("mac_address", vnic.MACAddress)
d.Set("transit_flag", vnic.TransitFlag)
d.Set("uri", vnic.Uri)
if err := setStringList(d, "tags", vnic.Tags); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,62 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCVNIC_Basic(t *testing.T) {
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccVnicBasic(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"data.opc_compute_vnic.foo", "mac_address", "02:5a:cd:ec:2e:4c"),
resource.TestCheckResourceAttr(
"data.opc_compute_vnic.foo", "transit_flag", "false"),
),
},
},
})
}
func testAccVnicBasic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_network" "foo" {
name = "testing-vnic-data-%d"
description = "testing-vnic-data"
ip_address_prefix = "10.1.13.0/24"
}
resource "opc_compute_instance" "test" {
name = "test-%d"
label = "test"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
networking_info {
index = 0
ip_network = "${opc_compute_ip_network.foo.id}"
vnic = "test-vnic-data-%d"
shared_network = false
mac_address = "02:5a:cd:ec:2e:4c"
}
}
data "opc_compute_network_interface" "eth0" {
instance_name = "${opc_compute_instance.test.name}"
instance_id = "${opc_compute_instance.test.id}"
interface = "eth0"
}
data "opc_compute_vnic" "foo" {
name = "${data.opc_compute_network_interface.eth0.vnic}"
}`, rInt, rInt, rInt)
}

View File

@ -0,0 +1,47 @@
package opc
import (
"sort"
"github.com/hashicorp/terraform/helper/schema"
)
// Helper function to get a string list from the schema, and alpha-sort it
func getStringList(d *schema.ResourceData, key string) []string {
if _, ok := d.GetOk(key); !ok {
return nil
}
l := d.Get(key).([]interface{})
res := make([]string, len(l))
for i, v := range l {
res[i] = v.(string)
}
sort.Strings(res)
return res
}
// Helper function to set a string list in the schema, in an alpha-sorted order.
func setStringList(d *schema.ResourceData, key string, value []string) error {
sort.Strings(value)
return d.Set(key, value)
}
// Helper function to get an int list from the schema, and numerically sort it
func getIntList(d *schema.ResourceData, key string) []int {
if _, ok := d.GetOk(key); !ok {
return nil
}
l := d.Get(key).([]interface{})
res := make([]int, len(l))
for i, v := range l {
res[i] = v.(int)
}
sort.Ints(res)
return res
}
func setIntList(d *schema.ResourceData, key string, value []int) error {
sort.Ints(value)
return d.Set(key, value)
}

View File

@ -0,0 +1,58 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCACL_importBasic(t *testing.T) {
resourceName := "opc_compute_acl.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccACLBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckACLDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCACL_importDisabled(t *testing.T) {
resourceName := "opc_compute_acl.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccACLDisabled, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckACLDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,57 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCImageList_importBasic(t *testing.T) {
resourceName := "opc_compute_image_list.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccImageList_basic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckImageListDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCImageList_importComplete(t *testing.T) {
resourceName := "opc_compute_image_list.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccImageList_complete, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckImageListDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,36 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCInstance_importBasic(t *testing.T) {
rInt := acctest.RandInt()
resourceName := "opc_compute_instance.test"
instanceName := fmt.Sprintf("acc-test-instance-%d", rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceBasic(rInt),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: instanceName + "/",
ImportStateVerifyIgnore: []string{"instance_attributes"},
},
},
})
}

View File

@ -0,0 +1,29 @@
package opc
import (
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCIPAddressAssociation_importBasic(t *testing.T) {
resourceName := "opc_compute_ip_address_association.test"
ri := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckIPAddressAssociationDestroy,
Steps: []resource.TestStep{
{
Config: testAccIPAddressAssociationBasic(ri),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,33 @@
package opc
import (
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCIPAddressPrefixSet_importBasic(t *testing.T) {
resourceName := "opc_compute_ip_address_prefix_set.test"
ri := acctest.RandInt()
config := testAccIPAddressPrefixSetBasic(ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckIPAddressPrefixSetDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,57 @@
package opc
import (
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCIPAddressReservation_importBasic(t *testing.T) {
resourceName := "opc_compute_ip_address_reservation.test"
ri := acctest.RandInt()
config := testAccOPCIPAddressReservationConfig_Basic(ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckIPAddressReservationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCIPAddressReservation_importDisabled(t *testing.T) {
resourceName := "opc_compute_ip_address_reservation.test"
ri := acctest.RandInt()
config := testAccOPCIPAddressReservationConfig_Basic(ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckIPAddressReservationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,34 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCIPAssociation_importBasic(t *testing.T) {
resourceName := "opc_compute_ip_association.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccIPAssociationBasic, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckIPAssociationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,34 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCIPNetworkExchange_importBasic(t *testing.T) {
resourceName := "opc_compute_ip_network_exchange.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccIPNetworkExchangeBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckIPNetworkExchangeDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,33 @@
package opc
import (
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCIPNetwork_importBasic(t *testing.T) {
resourceName := "opc_compute_ip_network.test"
rInt := acctest.RandInt()
config := testAccOPCIPNetworkConfig_Basic(rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccOPCCheckIPNetworkDestroyed),
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,34 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCIPReservation_importBasic(t *testing.T) {
resourceName := "opc_compute_ip_reservation.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccIPReservationBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckIPReservationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,33 @@
package opc
import (
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCRoute_importBasic(t *testing.T) {
resourceName := "opc_compute_route.test"
ri := acctest.RandInt()
config := testAccOPCRouteConfig_Basic(ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckRouteDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,59 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCSecRule_importBasic(t *testing.T) {
resourceName := "opc_compute_sec_rule.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecRuleBasic, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecRuleDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCSecRule_importComplete(t *testing.T) {
resourceName := "opc_compute_sec_rule.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecRuleComplete, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecRuleDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,59 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCSecurityApplication_importICMP(t *testing.T) {
resourceName := "opc_compute_security_application.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityApplicationICMP, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSecurityApplicationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCSecurityApplication_importTCP(t *testing.T) {
resourceName := "opc_compute_security_application.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityApplicationTCP, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSecurityApplicationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,59 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCSecurityAssociation_importBasic(t *testing.T) {
resourceName := "opc_compute_security_association.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccSecurityAssociationBasic, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSecurityAssociationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCSecurityAssociation_importComplete(t *testing.T) {
resourceName := "opc_compute_security_association.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccSecurityAssociationComplete, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSecurityAssociationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,34 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCSecurityIPList_importBasic(t *testing.T) {
resourceName := "opc_compute_security_ip_list.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityIPListBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityIPListDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,59 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCSecurityList_importBasic(t *testing.T) {
resourceName := "opc_compute_security_list.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityListBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityListDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCSecurityList_importComplete(t *testing.T) {
resourceName := "opc_compute_security_list.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityListComplete, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityListDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,58 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCSecurityProtocol_importBasic(t *testing.T) {
resourceName := "opc_compute_security_protocol.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityProtocolBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityProtocolDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCSecurityProtocol_importComplete(t *testing.T) {
resourceName := "opc_compute_security_protocol.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityProtocolComplete, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityProtocolDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,58 @@
package opc
import (
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCSecurityRule_importBasic(t *testing.T) {
resourceName := "opc_compute_security_rule.test"
ri := acctest.RandInt()
config := testAccOPCSecurityRuleConfig_Basic(ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityRuleDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCSecurityRule_importFull(t *testing.T) {
resourceName := "opc_compute_security_rule.test"
ri := acctest.RandInt()
config := testAccOPCSecurityRuleConfig_Full(ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityRuleDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,59 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCSSHKey_importBasic(t *testing.T) {
resourceName := "opc_compute_ssh_key.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSSHKeyBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSSHKeyDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCSSHKey_importDisabled(t *testing.T) {
resourceName := "opc_compute_ssh_key.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSSHKeyDisabled, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSSHKeyDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,29 @@
package opc
import (
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCStorageVolumeSnapshot_importBasic(t *testing.T) {
resourceName := "opc_compute_storage_volume_snapshot.test"
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeSnapshotDestroyed),
Steps: []resource.TestStep{
{
Config: testAccStorageVolumeSnapshot_basic(rInt),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,163 @@
package opc
import (
"testing"
"fmt"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCStorageVolume_importBasic(t *testing.T) {
resourceName := "opc_compute_storage_volume.test"
rInt := acctest.RandInt()
config := fmt.Sprintf(testAccStorageVolumeBasic, rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeDestroyed),
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCStorageVolume_importComplete(t *testing.T) {
resourceName := "opc_compute_storage_volume.test"
rInt := acctest.RandInt()
config := fmt.Sprintf(testAccStorageVolumeComplete, rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeDestroyed),
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCStorageVolume_importMaxSize(t *testing.T) {
resourceName := "opc_compute_storage_volume.test"
rInt := acctest.RandInt()
config := fmt.Sprintf(testAccStorageVolumeBasicMaxSize, rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeDestroyed),
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCStorageVolume_importBootable(t *testing.T) {
resourceName := "opc_compute_storage_volume.test"
rInt := acctest.RandInt()
config := fmt.Sprintf(testAccStorageVolumeBootable, rInt, rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeDestroyed),
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCStorageVolume_importImageListEntry(t *testing.T) {
resourceName := "opc_compute_storage_volume.test"
rInt := acctest.RandInt()
config := fmt.Sprintf(testAccStorageVolumeImageListEntry, rInt, rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeDestroyed),
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCStorageVolume_importLowLatency(t *testing.T) {
resourceName := "opc_compute_storage_volume.test"
rInt := acctest.RandInt()
config := testAccStorageVolumeLowLatency(rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeDestroyed),
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccOPCStorageVolume_importFromSnapshot(t *testing.T) {
resourceName := "opc_compute_storage_volume.test"
rInt := acctest.RandInt()
config := testAccStorageVolumeFromSnapshot(rInt)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeDestroyed),
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,93 @@
package opc
import (
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)
func Provider() terraform.ResourceProvider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
"user": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OPC_USERNAME", nil),
Description: "The user name for OPC API operations.",
},
"password": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OPC_PASSWORD", nil),
Description: "The user password for OPC API operations.",
},
"identity_domain": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OPC_IDENTITY_DOMAIN", nil),
Description: "The OPC identity domain for API operations",
},
"endpoint": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OPC_ENDPOINT", nil),
Description: "The HTTP endpoint for OPC API operations.",
},
// TODO Actually implement this
"max_retry_timeout": {
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)",
},
},
DataSourcesMap: map[string]*schema.Resource{
"opc_compute_network_interface": dataSourceNetworkInterface(),
"opc_compute_vnic": dataSourceVNIC(),
},
ResourcesMap: map[string]*schema.Resource{
"opc_compute_ip_network": resourceOPCIPNetwork(),
"opc_compute_acl": resourceOPCACL(),
"opc_compute_image_list": resourceOPCImageList(),
"opc_compute_image_list_entry": resourceOPCImageListEntry(),
"opc_compute_instance": resourceInstance(),
"opc_compute_ip_address_reservation": resourceOPCIPAddressReservation(),
"opc_compute_ip_association": resourceOPCIPAssociation(),
"opc_compute_ip_network_exchange": resourceOPCIPNetworkExchange(),
"opc_compute_ip_reservation": resourceOPCIPReservation(),
"opc_compute_route": resourceOPCRoute(),
"opc_compute_security_application": resourceOPCSecurityApplication(),
"opc_compute_security_association": resourceOPCSecurityAssociation(),
"opc_compute_security_ip_list": resourceOPCSecurityIPList(),
"opc_compute_security_list": resourceOPCSecurityList(),
"opc_compute_security_rule": resourceOPCSecurityRule(),
"opc_compute_sec_rule": resourceOPCSecRule(),
"opc_compute_ssh_key": resourceOPCSSHKey(),
"opc_compute_storage_volume": resourceOPCStorageVolume(),
"opc_compute_storage_volume_snapshot": resourceOPCStorageVolumeSnapshot(),
"opc_compute_vnic_set": resourceOPCVNICSet(),
"opc_compute_security_protocol": resourceOPCSecurityProtocol(),
"opc_compute_ip_address_prefix_set": resourceOPCIPAddressPrefixSet(),
"opc_compute_ip_address_association": resourceOPCIPAddressAssociation(),
},
ConfigureFunc: providerConfigure,
}
}
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
config := Config{
User: d.Get("user").(string),
Password: d.Get("password").(string),
IdentityDomain: d.Get("identity_domain").(string),
Endpoint: d.Get("endpoint").(string),
MaxRetryTimeout: d.Get("max_retry_timeout").(int),
}
return config.Client()
}

View File

@ -0,0 +1,62 @@
package opc
import (
"fmt"
"os"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"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("Error creating Provider: %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 {
*compute.Client
*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{
Client: testAccProvider.Meta().(*compute.Client),
InstanceState: rs.Primary,
}
return f(state)
}
}

View File

@ -0,0 +1,151 @@
package opc
import (
"fmt"
"log"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCACL() *schema.Resource {
return &schema.Resource{
Create: resourceOPCACLCreate,
Read: resourceOPCACLRead,
Update: resourceOPCACLUpdate,
Delete: resourceOPCACLDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"tags": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
ForceNew: true,
},
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCACLCreate(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
log.Print("[DEBUG] Creating acl")
client := meta.(*compute.Client).ACLs()
input := compute.CreateACLInput{
Name: d.Get("name").(string),
Enabled: d.Get("enabled").(bool),
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.CreateACL(&input)
if err != nil {
return fmt.Errorf("Error creating ACL: %s", err)
}
d.SetId(info.Name)
return resourceOPCACLRead(d, meta)
}
func resourceOPCACLRead(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
client := meta.(*compute.Client).ACLs()
log.Printf("[DEBUG] Reading state of ip reservation %s", d.Id())
getInput := compute.GetACLInput{
Name: d.Id(),
}
result, err := client.GetACL(&getInput)
if err != nil {
// ACL does not exist
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading acl %s: %s", d.Id(), err)
}
log.Printf("[DEBUG] Read state of acl %s: %#v", d.Id(), result)
d.Set("name", result.Name)
d.Set("enabled", result.Enabled)
d.Set("description", result.Description)
d.Set("uri", result.URI)
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
return nil
}
func resourceOPCACLUpdate(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
log.Print("[DEBUG] Updating acl")
client := meta.(*compute.Client).ACLs()
input := compute.UpdateACLInput{
Name: d.Get("name").(string),
Enabled: d.Get("enabled").(bool),
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.UpdateACL(&input)
if err != nil {
return fmt.Errorf("Error updating ACL: %s", err)
}
d.SetId(info.Name)
return resourceOPCACLRead(d, meta)
}
func resourceOPCACLDelete(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
client := meta.(*compute.Client).ACLs()
name := d.Id()
log.Printf("[DEBUG] Deleting ACL: %v", name)
input := compute.DeleteACLInput{
Name: name,
}
if err := client.DeleteACL(&input); err != nil {
return fmt.Errorf("Error deleting ACL")
}
return nil
}

View File

@ -0,0 +1,107 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCACL_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccACLBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckACLDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccCheckACLExists,
),
},
},
})
}
func TestAccOPCACL_Update(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccACLBasic, ri)
updatedConfig := fmt.Sprintf(testAccACLDisabled, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckACLDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckACLExists,
},
{
Config: updatedConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckACLExists,
resource.TestCheckResourceAttr("opc_compute_acl.test", "enabled", "false"),
),
},
},
})
}
func testAccCheckACLExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).ACLs()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_acl" {
continue
}
input := compute.GetACLInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetACL(&input); err != nil {
return fmt.Errorf("Error retrieving state of ACL %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckACLDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).ACLs()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_acl" {
continue
}
input := compute.GetACLInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetACL(&input); err == nil {
return fmt.Errorf("ACL %s still exists: %#v", input.Name, info)
}
}
return nil
}
var testAccACLBasic = `
resource "opc_compute_acl" "test" {
name = "test_acl-%d"
description = "test acl"
}
`
var testAccACLDisabled = `
resource "opc_compute_acl" "test" {
name = "test_acl-%d"
description = "test acl"
enabled = false
}
`

View File

@ -0,0 +1,107 @@
package opc
import (
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCImageList() *schema.Resource {
return &schema.Resource{
Create: resourceOPCImageListCreate,
Read: resourceOPCImageListRead,
Update: resourceOPCImageListUpdate,
Delete: resourceOPCImageListDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"description": {
Type: schema.TypeString,
Required: true,
},
"default": {
Type: schema.TypeInt,
Optional: true,
Default: 1,
},
},
}
}
func resourceOPCImageListCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).ImageList()
name := d.Get("name").(string)
createInput := &compute.CreateImageListInput{
Name: name,
Description: d.Get("description").(string),
Default: d.Get("default").(int),
}
createResult, err := client.CreateImageList(createInput)
if err != nil {
return err
}
d.SetId(createResult.Name)
return resourceOPCImageListRead(d, meta)
}
func resourceOPCImageListUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).ImageList()
name := d.Id()
updateInput := &compute.UpdateImageListInput{
Name: name,
Description: d.Get("description").(string),
Default: d.Get("default").(int),
}
_, err := client.UpdateImageList(updateInput)
if err != nil {
return err
}
return resourceOPCImageListRead(d, meta)
}
func resourceOPCImageListRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).ImageList()
getInput := &compute.GetImageListInput{
Name: d.Id(),
}
getResult, err := client.GetImageList(getInput)
if err != nil {
return err
}
d.Set("name", getResult.Name)
d.Set("description", getResult.Description)
d.Set("default", getResult.Default)
return nil
}
func resourceOPCImageListDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).ImageList()
deleteInput := &compute.DeleteImageListInput{
Name: d.Id(),
}
err := client.DeleteImageList(deleteInput)
if err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,160 @@
package opc
import (
"fmt"
"strconv"
"strings"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/structure"
"github.com/hashicorp/terraform/helper/validation"
)
func resourceOPCImageListEntry() *schema.Resource {
return &schema.Resource{
Create: resourceOPCImageListEntryCreate,
Read: resourceOPCImageListEntryRead,
Delete: resourceOPCImageListEntryDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"machine_images": {
Type: schema.TypeList,
Required: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"version": {
Type: schema.TypeInt,
ForceNew: true,
Required: true,
},
"attributes": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
ValidateFunc: validation.ValidateJsonString,
DiffSuppressFunc: structure.SuppressJsonDiff,
},
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCImageListEntryCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).ImageListEntries()
name := d.Get("name").(string)
machineImages := expandOPCImageListEntryMachineImages(d)
version := d.Get("version").(int)
createInput := &compute.CreateImageListEntryInput{
Name: name,
MachineImages: machineImages,
Version: version,
}
if v, ok := d.GetOk("attributes"); ok {
attributesString := v.(string)
attributes, err := structure.ExpandJsonFromString(attributesString)
if err != nil {
return err
}
createInput.Attributes = attributes
}
_, err := client.CreateImageListEntry(createInput)
if err != nil {
return err
}
id := generateOPCImageListEntryID(name, version)
d.SetId(id)
return resourceOPCImageListEntryRead(d, meta)
}
func resourceOPCImageListEntryRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).ImageListEntries()
name, version, err := parseOPCImageListEntryID(d.Id())
if err != nil {
return err
}
getInput := compute.GetImageListEntryInput{
Name: *name,
Version: *version,
}
getResult, err := client.GetImageListEntry(&getInput)
if err != nil {
return err
}
attrs, err := structure.FlattenJsonToString(getResult.Attributes)
if err != nil {
return err
}
d.Set("name", name)
d.Set("machine_images", getResult.MachineImages)
d.Set("version", getResult.Version)
d.Set("attributes", attrs)
d.Set("uri", getResult.Uri)
return nil
}
func resourceOPCImageListEntryDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).ImageListEntries()
name, version, err := parseOPCImageListEntryID(d.Id())
if err != nil {
return err
}
deleteInput := &compute.DeleteImageListEntryInput{
Name: *name,
Version: *version,
}
err = client.DeleteImageListEntry(deleteInput)
if err != nil {
return err
}
return nil
}
func parseOPCImageListEntryID(id string) (*string, *int, error) {
s := strings.Split(id, "|")
name, versionString := s[0], s[1]
version, err := strconv.Atoi(versionString)
if err != nil {
return nil, nil, err
}
return &name, &version, nil
}
func expandOPCImageListEntryMachineImages(d *schema.ResourceData) []string {
machineImages := []string{}
for _, i := range d.Get("machine_images").([]interface{}) {
machineImages = append(machineImages, i.(string))
}
return machineImages
}
func generateOPCImageListEntryID(name string, version int) string {
return fmt.Sprintf("%s|%d", name, version)
}

View File

@ -0,0 +1,161 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCImageListEntry_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccImageListEntry_basic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckImageListEntryDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckImageListEntryExists,
},
},
})
}
func TestAccOPCImageListEntry_Complete(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccImageListEntry_Complete, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckImageListEntryDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckImageListEntryExists,
},
},
})
}
func TestAccOPCImageListEntry_CompleteExpanded(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccImageListEntry_CompleteExpanded, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckImageListEntryDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckImageListEntryExists,
},
},
})
}
func testAccCheckImageListEntryExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).ImageListEntries()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_image_list_entry" {
continue
}
name, version, err := parseOPCImageListEntryID(rs.Primary.ID)
if err != nil {
return fmt.Errorf("Error parsing the Image List ID: '%s': %+v", rs.Primary.ID, err)
}
input := compute.GetImageListEntryInput{
Name: *name,
Version: *version,
}
if _, err := client.GetImageListEntry(&input); err != nil {
return fmt.Errorf("Error retrieving state of Image List Entry %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckImageListEntryDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).ImageListEntries()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_image_list_entry" {
continue
}
name, version, err := parseOPCImageListEntryID(rs.Primary.ID)
if err != nil {
return fmt.Errorf("Error parsing the Image List ID: %+v", err)
}
input := compute.GetImageListEntryInput{
Name: *name,
Version: *version,
}
if info, err := client.GetImageListEntry(&input); err == nil {
return fmt.Errorf("Image List Entry %s still exists: %#v", input.Name, info)
}
}
return nil
}
var testAccImageListEntry_basic = `
resource "opc_compute_image_list" "test" {
name = "test-acc-image-list-entry-basic-%d"
description = "Acceptance Test TestAccOPCImageListEntry_Basic"
default = 1
}
resource "opc_compute_image_list_entry" "test" {
name = "${opc_compute_image_list.test.name}"
machine_images = [ "/oracle/public/oel_6.7_apaas_16.4.5_1610211300" ]
version = 1
}
`
var testAccImageListEntry_Complete = `
resource "opc_compute_image_list" "test" {
name = "test-acc-image-list-entry-basic-%d"
description = "Acceptance Test TestAccOPCImageListEntry_Basic"
default = 1
}
resource "opc_compute_image_list_entry" "test" {
name = "${opc_compute_image_list.test.name}"
machine_images = [ "/oracle/public/oel_6.7_apaas_16.4.5_1610211300" ]
attributes = "{\"hello\":\"world\"}"
version = 1
}
`
var testAccImageListEntry_CompleteExpanded = `
resource "opc_compute_image_list" "test" {
name = "test-acc-image-list-entry-basic-%d"
description = "Acceptance Test TestAccOPCImageListEntry_Basic"
default = 1
}
resource "opc_compute_image_list_entry" "test" {
name = "${opc_compute_image_list.test.name}"
machine_images = [ "/oracle/public/oel_6.7_apaas_16.4.5_1610211300" ]
attributes = <<JSON
{
"hello": "world"
}
JSON
version = 1
}
`

View File

@ -0,0 +1,98 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCImageList_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccImageList_basic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckImageListDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckImageListExists,
},
},
})
}
func TestAccOPCImageList_Complete(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccImageList_complete, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckImageListDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckImageListExists,
},
},
})
}
func testAccCheckImageListExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).ImageList()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_image_list" {
continue
}
input := compute.GetImageListInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetImageList(&input); err != nil {
return fmt.Errorf("Error retrieving state of Image List %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckImageListDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).ImageList()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_image_list" {
continue
}
input := compute.GetImageListInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetImageList(&input); err == nil {
return fmt.Errorf("Image List %s still exists: %#v", input.Name, info)
}
}
return nil
}
var testAccImageList_basic = `
resource "opc_compute_image_list" "test" {
name = "test-acc-image-list-basic-%d"
description = "Image List (Basic)"
}
`
var testAccImageList_complete = `
resource "opc_compute_image_list" "test" {
name = "test-acc-image-list-complete-%d"
description = "Image List (Complete)"
default = 2
}
`

View File

@ -0,0 +1,897 @@
package opc
import (
"bytes"
"encoding/json"
"fmt"
"log"
"strconv"
"strings"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)
func resourceInstance() *schema.Resource {
return &schema.Resource{
Create: resourceInstanceCreate,
Read: resourceInstanceRead,
Delete: resourceInstanceDelete,
Importer: &schema.ResourceImporter{
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
combined := strings.Split(d.Id(), "/")
if len(combined) != 2 {
return nil, fmt.Errorf("Invalid ID specified. Must be in the form of instance_name/instance_id. Got: %s", d.Id())
}
d.Set("name", combined[0])
d.SetId(combined[1])
return []*schema.ResourceData{d}, nil
},
},
Schema: map[string]*schema.Schema{
/////////////////////////
// Required Attributes //
/////////////////////////
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"shape": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
/////////////////////////
// Optional Attributes //
/////////////////////////
"instance_attributes": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.ValidateJsonString,
},
"boot_order": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeInt},
},
"hostname": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"image_list": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"label": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"networking_info": {
Type: schema.TypeSet,
Optional: true,
Computed: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns": {
// Required for Shared Network Interface, will default if unspecified, however
// Optional for IP Network Interface
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"index": {
Type: schema.TypeInt,
ForceNew: true,
Required: true,
},
"ip_address": {
// Optional, IP Network only
Type: schema.TypeString,
ForceNew: true,
Optional: true,
},
"ip_network": {
// Required for an IP Network Interface
Type: schema.TypeString,
ForceNew: true,
Optional: true,
},
"mac_address": {
// Optional, IP Network Only
Type: schema.TypeString,
ForceNew: true,
Computed: true,
Optional: true,
},
"name_servers": {
// Optional, IP Network + Shared Network
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"nat": {
// Optional for IP Network
// Required for Shared Network
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"search_domains": {
// Optional, IP Network + Shared Network
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"sec_lists": {
// Required, Shared Network only. Will default if unspecified however
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"shared_network": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
},
"vnic": {
// Optional, IP Network only.
Type: schema.TypeString,
ForceNew: true,
Optional: true,
},
"vnic_sets": {
// Optional, IP Network only.
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
Set: func(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%d-", m["index"].(int)))
buf.WriteString(fmt.Sprintf("%s-", m["vnic"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["nat"]))
return hashcode.String(buf.String())
},
},
"reverse_dns": {
Type: schema.TypeBool,
Optional: true,
Default: true,
ForceNew: true,
},
"ssh_keys": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"storage": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"index": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 10),
},
"volume": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"tags": tagsForceNewSchema(),
/////////////////////////
// Computed Attributes //
/////////////////////////
"attributes": {
Type: schema.TypeString,
Computed: true,
},
"availability_domain": {
Type: schema.TypeString,
Computed: true,
},
"domain": {
Type: schema.TypeString,
Computed: true,
},
"entry": {
Type: schema.TypeInt,
Computed: true,
},
"fingerprint": {
Type: schema.TypeString,
Computed: true,
},
"image_format": {
Type: schema.TypeString,
Computed: true,
},
"ip_address": {
Type: schema.TypeString,
Computed: true,
},
"placement_requirements": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"platform": {
Type: schema.TypeString,
Computed: true,
},
"priority": {
Type: schema.TypeString,
Computed: true,
},
"quota_reservation": {
Type: schema.TypeString,
Computed: true,
},
"relationships": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"resolvers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"site": {
Type: schema.TypeString,
Computed: true,
},
"start_time": {
Type: schema.TypeString,
Computed: true,
},
"state": {
Type: schema.TypeString,
Computed: true,
},
"vcable": {
Type: schema.TypeString,
Computed: true,
},
"virtio": {
Type: schema.TypeBool,
Computed: true,
},
"vnc_address": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceInstanceCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).Instances()
// Get Required Attributes
input := &compute.CreateInstanceInput{
Name: d.Get("name").(string),
Shape: d.Get("shape").(string),
}
// Get optional instance attributes
attributes, attrErr := getInstanceAttributes(d)
if attrErr != nil {
return attrErr
}
if attributes != nil {
input.Attributes = attributes
}
if bootOrder := getIntList(d, "boot_order"); len(bootOrder) > 0 {
input.BootOrder = bootOrder
}
if v, ok := d.GetOk("hostname"); ok {
input.Hostname = v.(string)
}
if v, ok := d.GetOk("image_list"); ok {
input.ImageList = v.(string)
}
if v, ok := d.GetOk("label"); ok {
input.Label = v.(string)
}
interfaces, err := readNetworkInterfacesFromConfig(d)
if err != nil {
return err
}
if interfaces != nil {
input.Networking = interfaces
}
if v, ok := d.GetOk("reverse_dns"); ok {
input.ReverseDNS = v.(bool)
}
if sshKeys := getStringList(d, "ssh_keys"); len(sshKeys) > 0 {
input.SSHKeys = sshKeys
}
storage := getStorageAttachments(d)
if len(storage) > 0 {
input.Storage = storage
}
if tags := getStringList(d, "tags"); len(tags) > 0 {
input.Tags = tags
}
result, err := client.CreateInstance(input)
if err != nil {
return fmt.Errorf("Error creating instance %s: %s", input.Name, err)
}
log.Printf("[DEBUG] Created instance %s: %#v", input.Name, result.ID)
d.SetId(result.ID)
return resourceInstanceRead(d, meta)
}
func resourceInstanceRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).Instances()
name := d.Get("name").(string)
input := &compute.GetInstanceInput{
ID: d.Id(),
Name: name,
}
log.Printf("[DEBUG] Reading state of instance %s", name)
result, err := client.GetInstance(input)
if err != nil {
// Instance doesn't exist
if compute.WasNotFoundError(err) {
log.Printf("[DEBUG] Instance %s not found", name)
d.SetId("")
return nil
}
return fmt.Errorf("Error reading instance %s: %s", name, err)
}
log.Printf("[DEBUG] Instance '%s' found", name)
// Update attributes
return updateInstanceAttributes(d, result)
}
func updateInstanceAttributes(d *schema.ResourceData, instance *compute.InstanceInfo) error {
d.Set("name", instance.Name)
d.Set("shape", instance.Shape)
if err := setInstanceAttributes(d, instance.Attributes); err != nil {
return err
}
if attrs, ok := d.GetOk("instance_attributes"); ok && attrs != nil {
d.Set("instance_attributes", attrs.(string))
}
if err := setIntList(d, "boot_order", instance.BootOrder); err != nil {
return err
}
d.Set("hostname", instance.Hostname)
d.Set("image_list", instance.ImageList)
d.Set("label", instance.Label)
if err := readNetworkInterfaces(d, instance.Networking); err != nil {
return err
}
d.Set("reverse_dns", instance.ReverseDNS)
if err := setStringList(d, "ssh_keys", instance.SSHKeys); err != nil {
return err
}
if err := readStorageAttachments(d, instance.Storage); err != nil {
return err
}
if err := setStringList(d, "tags", instance.Tags); err != nil {
return err
}
d.Set("availability_domain", instance.AvailabilityDomain)
d.Set("domain", instance.Domain)
d.Set("entry", instance.Entry)
d.Set("fingerprint", instance.Fingerprint)
d.Set("image_format", instance.ImageFormat)
d.Set("ip_address", instance.IPAddress)
if err := setStringList(d, "placement_requirements", instance.PlacementRequirements); err != nil {
return err
}
d.Set("platform", instance.Platform)
d.Set("priority", instance.Priority)
d.Set("quota_reservation", instance.QuotaReservation)
if err := setStringList(d, "relationships", instance.Relationships); err != nil {
return err
}
if err := setStringList(d, "resolvers", instance.Resolvers); err != nil {
return err
}
d.Set("site", instance.Site)
d.Set("start_time", instance.StartTime)
d.Set("state", instance.State)
if err := setStringList(d, "tags", instance.Tags); err != nil {
return err
}
d.Set("vcable", instance.VCableID)
d.Set("virtio", instance.Virtio)
d.Set("vnc_address", instance.VNC)
return nil
}
func resourceInstanceDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).Instances()
name := d.Get("name").(string)
input := &compute.DeleteInstanceInput{
ID: d.Id(),
Name: name,
}
log.Printf("[DEBUG] Deleting instance %s", name)
if err := client.DeleteInstance(input); err != nil {
return fmt.Errorf("Error deleting instance %s: %s", name, err)
}
return nil
}
func getStorageAttachments(d *schema.ResourceData) []compute.StorageAttachmentInput {
storageAttachments := []compute.StorageAttachmentInput{}
storage := d.Get("storage").(*schema.Set)
for _, i := range storage.List() {
attrs := i.(map[string]interface{})
storageAttachments = append(storageAttachments, compute.StorageAttachmentInput{
Index: attrs["index"].(int),
Volume: attrs["volume"].(string),
})
}
return storageAttachments
}
// Parses instance_attributes from a string to a map[string]interface and returns any errors.
func getInstanceAttributes(d *schema.ResourceData) (map[string]interface{}, error) {
var attrs map[string]interface{}
// Empty instance attributes
attributes, ok := d.GetOk("instance_attributes")
if !ok {
return attrs, nil
}
if err := json.Unmarshal([]byte(attributes.(string)), &attrs); err != nil {
return attrs, fmt.Errorf("Cannot parse attributes as json: %s", err)
}
return attrs, nil
}
// Reads attributes from the returned instance object, and sets the computed attributes string
// as JSON
func setInstanceAttributes(d *schema.ResourceData, attributes map[string]interface{}) error {
// Shouldn't ever get nil attributes on an instance, but protect against the case either way
if attributes == nil {
return nil
}
b, err := json.Marshal(attributes)
if err != nil {
return fmt.Errorf("Error marshalling returned attributes: %s", err)
}
return d.Set("attributes", string(b))
}
// Populates and validates shared network and ip network interfaces to return the of map
// objects needed to create/update an instance's networking_info
func readNetworkInterfacesFromConfig(d *schema.ResourceData) (map[string]compute.NetworkingInfo, error) {
interfaces := make(map[string]compute.NetworkingInfo)
if v, ok := d.GetOk("networking_info"); ok {
vL := v.(*schema.Set).List()
for _, v := range vL {
ni := v.(map[string]interface{})
index, ok := ni["index"].(int)
if !ok {
return nil, fmt.Errorf("Index not specified for network interface: %v", ni)
}
deviceIndex := fmt.Sprintf("eth%d", index)
// Verify that the network interface doesn't already exist
if _, ok := interfaces[deviceIndex]; ok {
return nil, fmt.Errorf("Duplicate Network interface at eth%d already specified", index)
}
// Determine if we're creating a shared network interface or an IP Network interface
info := compute.NetworkingInfo{}
var err error
if ni["shared_network"].(bool) {
// Populate shared network parameters
info, err = readSharedNetworkFromConfig(ni)
// Set 'model' since we're configuring a shared network interface
info.Model = compute.NICDefaultModel
} else {
// Populate IP Network Parameters
info, err = readIPNetworkFromConfig(ni)
}
if err != nil {
return nil, err
}
// And you may find yourself in a beautiful house, with a beautiful wife
// And you may ask yourself, well, how did I get here?
interfaces[deviceIndex] = info
}
}
return interfaces, nil
}
// Reads a networking_info config block as a shared network interface
func readSharedNetworkFromConfig(ni map[string]interface{}) (compute.NetworkingInfo, error) {
info := compute.NetworkingInfo{}
// Validate the shared network
if err := validateSharedNetwork(ni); err != nil {
return info, err
}
// Populate shared network fields; checking type casting
dns := []string{}
if v, ok := ni["dns"]; ok && v != nil {
for _, d := range v.([]interface{}) {
dns = append(dns, d.(string))
}
if len(dns) > 0 {
info.DNS = dns
}
}
if v, ok := ni["model"].(string); ok && v != "" {
info.Model = compute.NICModel(v)
}
nats := []string{}
if v, ok := ni["nat"]; ok && v != nil {
for _, nat := range v.([]interface{}) {
nats = append(nats, nat.(string))
}
if len(nats) > 0 {
info.Nat = nats
}
}
slists := []string{}
if v, ok := ni["sec_lists"]; ok && v != nil {
for _, slist := range v.([]interface{}) {
slists = append(slists, slist.(string))
}
if len(slists) > 0 {
info.SecLists = slists
}
}
nservers := []string{}
if v, ok := ni["name_servers"]; ok && v != nil {
for _, nserver := range v.([]interface{}) {
nservers = append(nservers, nserver.(string))
}
if len(nservers) > 0 {
info.NameServers = nservers
}
}
sdomains := []string{}
if v, ok := ni["search_domains"]; ok && v != nil {
for _, sdomain := range v.([]interface{}) {
sdomains = append(sdomains, sdomain.(string))
}
if len(sdomains) > 0 {
info.SearchDomains = sdomains
}
}
return info, nil
}
// Unfortunately this cannot take place during plan-phase, because we currently cannot have a validation
// function based off of multiple fields in the supplied schema.
func validateSharedNetwork(ni map[string]interface{}) error {
// A Shared Networking Interface MUST have the following attributes set:
// - "nat"
// The following attributes _cannot_ be set for a shared network:
// - "ip_address"
// - "ip_network"
// - "mac_address"
// - "vnic"
// - "vnic_sets"
if _, ok := ni["nat"]; !ok {
return fmt.Errorf("'nat' field needs to be set for a Shared Networking Interface")
}
// Strings only
nilAttrs := []string{
"ip_address",
"ip_network",
"mac_address",
"vnic",
}
for _, v := range nilAttrs {
if d, ok := ni[v]; ok && d.(string) != "" {
return fmt.Errorf("%q field cannot be set in a Shared Networking Interface", v)
}
}
if _, ok := ni["vnic_sets"].([]string); ok {
return fmt.Errorf("%q field cannot be set in a Shared Networking Interface", "vnic_sets")
}
return nil
}
// Populates fields for an IP Network
func readIPNetworkFromConfig(ni map[string]interface{}) (compute.NetworkingInfo, error) {
info := compute.NetworkingInfo{}
// Validate the IP Network
if err := validateIPNetwork(ni); err != nil {
return info, err
}
// Populate fields
if v, ok := ni["ip_network"].(string); ok && v != "" {
info.IPNetwork = v
}
dns := []string{}
if v, ok := ni["dns"]; ok && v != nil {
for _, d := range v.([]interface{}) {
dns = append(dns, d.(string))
}
if len(dns) > 0 {
info.DNS = dns
}
}
if v, ok := ni["ip_address"].(string); ok && v != "" {
info.IPAddress = v
}
if v, ok := ni["mac_address"].(string); ok && v != "" {
info.MACAddress = v
}
nservers := []string{}
if v, ok := ni["name_servers"]; ok && v != nil {
for _, nserver := range v.([]interface{}) {
nservers = append(nservers, nserver.(string))
}
if len(nservers) > 0 {
info.NameServers = nservers
}
}
nats := []string{}
if v, ok := ni["nat"]; ok && v != nil {
for _, nat := range v.([]interface{}) {
nats = append(nats, nat.(string))
}
if len(nats) > 0 {
info.Nat = nats
}
}
sdomains := []string{}
if v, ok := ni["search_domains"]; ok && v != nil {
for _, sdomain := range v.([]interface{}) {
sdomains = append(sdomains, sdomain.(string))
}
if len(sdomains) > 0 {
info.SearchDomains = sdomains
}
}
if v, ok := ni["vnic"].(string); ok && v != "" {
info.Vnic = v
}
vnicSets := []string{}
if v, ok := ni["vnic_sets"]; ok && v != nil {
for _, vnic := range v.([]interface{}) {
vnicSets = append(vnicSets, vnic.(string))
}
if len(vnicSets) > 0 {
info.VnicSets = vnicSets
}
}
return info, nil
}
// Validates an IP Network config block
func validateIPNetwork(ni map[string]interface{}) error {
// An IP Networking Interface MUST have the following attributes set:
// - "ip_network"
// Required to be set
if d, ok := ni["ip_network"]; !ok || d.(string) == "" {
return fmt.Errorf("'ip_network' field is required for an IP Network interface")
}
return nil
}
// Reads network interfaces from the config
func readNetworkInterfaces(d *schema.ResourceData, ifaces map[string]compute.NetworkingInfo) error {
result := make([]map[string]interface{}, 0)
// Nil check for import case
if ifaces == nil {
return d.Set("networking_info", result)
}
for index, iface := range ifaces {
res := make(map[string]interface{})
// The index returned from the SDK holds the full device_index from the instance.
// For users convenience, we simply allow them to specify the integer equivalent of the device_index
// so a user could implement several network interfaces via `count`.
// Convert the full device_index `ethN` to `N` as an integer.
index := strings.TrimPrefix(index, "eth")
indexInt, err := strconv.Atoi(index)
if err != nil {
return err
}
res["index"] = indexInt
// Set the proper attributes for this specific network interface
if iface.DNS != nil {
res["dns"] = iface.DNS
}
if iface.IPAddress != "" {
res["ip_address"] = iface.IPAddress
}
if iface.IPNetwork != "" {
res["ip_network"] = iface.IPNetwork
}
if iface.MACAddress != "" {
res["mac_address"] = iface.MACAddress
}
if iface.Model != "" {
// Model can only be set on Shared networks
res["shared_network"] = true
}
if iface.NameServers != nil {
res["name_servers"] = iface.NameServers
}
if iface.Nat != nil {
res["nat"] = iface.Nat
}
if iface.SearchDomains != nil {
res["search_domains"] = iface.SearchDomains
}
if iface.SecLists != nil {
res["sec_lists"] = iface.SecLists
}
if iface.Vnic != "" {
res["vnic"] = iface.Vnic
// VNIC can only be set on an IP Network
res["shared_network"] = false
}
if iface.VnicSets != nil {
res["vnic_sets"] = iface.VnicSets
}
result = append(result, res)
}
return d.Set("networking_info", result)
}
// Flattens the returned slice of storage attachments to a map
func readStorageAttachments(d *schema.ResourceData, attachments []compute.StorageAttachment) error {
result := make([]map[string]interface{}, 0)
if attachments == nil || len(attachments) == 0 {
return d.Set("storage", nil)
}
for _, attachment := range attachments {
res := make(map[string]interface{})
res["index"] = attachment.Index
res["volume"] = attachment.StorageVolumeName
res["name"] = attachment.Name
result = append(result, res)
}
return d.Set("storage", result)
}

View File

@ -0,0 +1,273 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCInstance_basic(t *testing.T) {
resName := "opc_compute_instance.test"
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceBasic(rInt),
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckInstanceExists,
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("acc-test-instance-%d", rInt)),
resource.TestCheckResourceAttr(resName, "label", "TestAccOPCInstance_basic"),
),
},
},
})
}
func TestAccOPCInstance_sharedNetworking(t *testing.T) {
rInt := acctest.RandInt()
resName := "opc_compute_instance.test"
dataName := "data.opc_compute_network_interface.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceSharedNetworking(rInt),
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckInstanceExists,
resource.TestCheckResourceAttrSet(resName, "id"),
resource.TestCheckResourceAttrSet(resName, "availability_domain"),
resource.TestCheckResourceAttrSet(resName, "domain"),
resource.TestCheckResourceAttrSet(resName, "hostname"),
resource.TestCheckResourceAttrSet(resName, "ip_address"),
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("acc-test-instance-%d", rInt)),
resource.TestCheckResourceAttr(resName, "networking_info.#", "1"),
// Default Placement Reqs
resource.TestCheckResourceAttr(resName, "placement_requirements.#", "2"),
resource.TestCheckResourceAttr(resName, "placement_requirements.0", "/system/compute/allow_instances"),
resource.TestCheckResourceAttr(resName, "placement_requirements.1", "/system/compute/placement/default"),
resource.TestCheckResourceAttr(resName, "platform", "linux"),
resource.TestCheckResourceAttr(resName, "priority", "/oracle/public/default"),
resource.TestCheckResourceAttr(resName, "reverse_dns", "true"),
resource.TestCheckResourceAttr(resName, "state", "running"),
resource.TestCheckResourceAttr(resName, "tags.#", "2"),
resource.TestCheckResourceAttrSet(resName, "vcable"),
resource.TestCheckResourceAttr(resName, "virtio", "false"),
// Check Data Source to validate networking attributes
resource.TestCheckResourceAttr(dataName, "shared_network", "true"),
resource.TestCheckResourceAttr(dataName, "nat.#", "1"),
resource.TestCheckResourceAttr(dataName, "sec_lists.#", "1"),
resource.TestCheckResourceAttr(dataName, "name_servers.#", "0"),
resource.TestCheckResourceAttr(dataName, "vnic_sets.#", "0"),
),
},
},
})
}
func TestAccOPCInstance_ipNetwork(t *testing.T) {
rInt := acctest.RandInt()
resName := "opc_compute_instance.test"
dataName := "data.opc_compute_network_interface.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceIPNetworking(rInt),
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckInstanceExists,
resource.TestCheckResourceAttrSet(resName, "id"),
resource.TestCheckResourceAttrSet(resName, "availability_domain"),
resource.TestCheckResourceAttrSet(resName, "domain"),
resource.TestCheckResourceAttrSet(resName, "ip_address"),
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("acc-test-instance-%d", rInt)),
resource.TestCheckResourceAttr(resName, "networking_info.#", "1"),
// Default Placement Reqs
resource.TestCheckResourceAttr(resName, "placement_requirements.#", "2"),
resource.TestCheckResourceAttr(resName, "placement_requirements.0", "/system/compute/allow_instances"),
resource.TestCheckResourceAttr(resName, "placement_requirements.1", "/system/compute/placement/default"),
resource.TestCheckResourceAttr(resName, "platform", "linux"),
resource.TestCheckResourceAttr(resName, "priority", "/oracle/public/default"),
resource.TestCheckResourceAttr(resName, "reverse_dns", "true"),
resource.TestCheckResourceAttr(resName, "state", "running"),
resource.TestCheckResourceAttr(resName, "virtio", "false"),
// Check Data Source to validate networking attributes
resource.TestCheckResourceAttr(dataName, "ip_network", fmt.Sprintf("testing-ip-network-%d", rInt)),
resource.TestCheckResourceAttr(dataName, "vnic", fmt.Sprintf("ip-network-test-%d", rInt)),
resource.TestCheckResourceAttr(dataName, "shared_network", "false"),
),
},
},
})
}
func TestAccOPCInstance_storage(t *testing.T) {
resName := "opc_compute_instance.test"
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceStorage(rInt),
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckInstanceExists,
resource.TestCheckResourceAttr(resName, "storage.#", "2"),
),
},
},
})
}
func testAccOPCCheckInstanceExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).Instances()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_instance" {
continue
}
input := &compute.GetInstanceInput{
ID: rs.Primary.ID,
Name: rs.Primary.Attributes["name"],
}
_, err := client.GetInstance(input)
if err != nil {
return fmt.Errorf("Error retrieving state of Instance %s: %s", input.Name, err)
}
}
return nil
}
func testAccOPCCheckInstanceDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).Instances()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_instance" {
continue
}
input := &compute.GetInstanceInput{
ID: rs.Primary.ID,
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetInstance(input); err == nil {
return fmt.Errorf("Instance %s still exists: %#v", input.Name, info)
}
}
return nil
}
func testAccInstanceBasic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_instance" "test" {
name = "acc-test-instance-%d"
label = "TestAccOPCInstance_basic"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
instance_attributes = <<JSON
{
"foo": "bar"
}
JSON
}`, rInt)
}
func testAccInstanceSharedNetworking(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_instance" "test" {
name = "acc-test-instance-%d"
label = "TestAccOPCInstance_sharedNetworking"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
tags = ["tag1", "tag2"]
networking_info {
index = 0
nat = ["ippool:/oracle/public/ippool"]
shared_network = true
}
}
data "opc_compute_network_interface" "test" {
instance_name = "${opc_compute_instance.test.name}"
instance_id = "${opc_compute_instance.test.id}"
interface = "eth0"
}
`, rInt)
}
func testAccInstanceIPNetworking(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_network" "foo" {
name = "testing-ip-network-%d"
description = "testing-ip-network-instance"
ip_address_prefix = "10.1.12.0/24"
}
resource "opc_compute_instance" "test" {
name = "acc-test-instance-%d"
label = "TestAccOPCInstance_ipNetwork"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
networking_info {
index = 0
ip_network = "${opc_compute_ip_network.foo.id}"
vnic = "ip-network-test-%d"
shared_network = false
}
}
data "opc_compute_network_interface" "test" {
instance_id = "${opc_compute_instance.test.id}"
instance_name = "${opc_compute_instance.test.name}"
interface = "eth0"
}
`, rInt, rInt, rInt)
}
func testAccInstanceStorage(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_storage_volume" "foo" {
name = "acc-test-instance-%d"
size = 1
}
resource "opc_compute_storage_volume" "bar" {
name = "acc-test-instance-2-%d"
size = 1
}
resource "opc_compute_instance" "test" {
name = "acc-test-instance-%d"
label = "TestAccOPCInstance_basic"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
storage {
volume = "${opc_compute_storage_volume.foo.name}"
index = 1
}
storage {
volume = "${opc_compute_storage_volume.bar.name}"
index = 2
}
}`, rInt, rInt, rInt)
}

View File

@ -0,0 +1,156 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCIPAddressAssociation() *schema.Resource {
return &schema.Resource{
Create: resourceOPCIPAddressAssociationCreate,
Read: resourceOPCIPAddressAssociationRead,
Update: resourceOPCIPAddressAssociationUpdate,
Delete: resourceOPCIPAddressAssociationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"ip_address_reservation": {
Type: schema.TypeString,
Optional: true,
},
"vnic": {
Type: schema.TypeString,
Optional: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"tags": tagsOptionalSchema(),
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCIPAddressAssociationCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressAssociations()
input := compute.CreateIPAddressAssociationInput{
Name: d.Get("name").(string),
}
if ipAddressReservation, ok := d.GetOk("ip_address_reservation"); ok {
input.IPAddressReservation = ipAddressReservation.(string)
}
if vnic, ok := d.GetOk("vnic"); ok {
input.Vnic = vnic.(string)
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.CreateIPAddressAssociation(&input)
if err != nil {
return fmt.Errorf("Error creating IP Address Association: %s", err)
}
d.SetId(info.Name)
return resourceOPCIPAddressAssociationRead(d, meta)
}
func resourceOPCIPAddressAssociationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressAssociations()
name := d.Id()
getInput := compute.GetIPAddressAssociationInput{
name,
}
result, err := client.GetIPAddressAssociation(&getInput)
if err != nil {
// IP Address Association does not exist
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading IP Address Association %s: %s", name, err)
}
if result == nil {
d.SetId("")
return fmt.Errorf("Error reading IP Address Association %s: %s", name, err)
}
d.Set("name", result.Name)
d.Set("ip_address_reservation", result.IPAddressReservation)
d.Set("vnic", result.Vnic)
d.Set("description", result.Description)
d.Set("uri", result.Uri)
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
return nil
}
func resourceOPCIPAddressAssociationUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressAssociations()
input := compute.UpdateIPAddressAssociationInput{
Name: d.Get("name").(string),
}
if ipAddressReservation, ok := d.GetOk("ip_address_reservation"); ok {
input.IPAddressReservation = ipAddressReservation.(string)
}
if vnic, ok := d.GetOk("vnic"); ok {
input.Vnic = vnic.(string)
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.UpdateIPAddressAssociation(&input)
if err != nil {
return fmt.Errorf("Error updating IP Address Association: %s", err)
}
d.SetId(info.Name)
return resourceOPCIPAddressAssociationRead(d, meta)
}
func resourceOPCIPAddressAssociationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressAssociations()
name := d.Id()
input := compute.DeleteIPAddressAssociationInput{
Name: name,
}
if err := client.DeleteIPAddressAssociation(&input); err != nil {
return fmt.Errorf("Error deleting IP Address Association: %s", err)
}
return nil
}

View File

@ -0,0 +1,155 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCIPAddressAssociation_Basic(t *testing.T) {
rInt := acctest.RandInt()
resourceName := "opc_compute_ip_address_association.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckIPAddressAssociationDestroy,
Steps: []resource.TestStep{
{
Config: testAccIPAddressAssociationBasic(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckIPAddressAssociationExists,
resource.TestCheckResourceAttr(
resourceName, "tags.#", "2"),
),
},
{
Config: testAccIPAddressAssociationBasic_Update(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
resourceName, "tags.#", "1"),
),
},
},
})
}
func TestAccOPCIPAddressAssociation_Full(t *testing.T) {
rInt := acctest.RandInt()
resourceName := "opc_compute_ip_address_association.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckIPAddressAssociationDestroy,
Steps: []resource.TestStep{
{
Config: testAccIPAddressAssociationFull(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckIPAddressAssociationExists,
resource.TestCheckResourceAttr(
resourceName, "vnic", fmt.Sprintf("test-vnic-data-%d", rInt)),
resource.TestCheckResourceAttr(
resourceName, "ip_address_reservation", fmt.Sprintf("testing-ip-address-association-%d", rInt)),
),
},
},
})
}
func testAccCheckIPAddressAssociationExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPAddressAssociations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_address_association" {
continue
}
input := compute.GetIPAddressAssociationInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetIPAddressAssociation(&input); err != nil {
return fmt.Errorf("Error retrieving state of IP Address Association %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckIPAddressAssociationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPAddressAssociations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_address_association" {
continue
}
input := compute.GetIPAddressAssociationInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetIPAddressAssociation(&input); err == nil {
return fmt.Errorf("IP Address Association %s still exists: %#v", input.Name, info)
}
}
return nil
}
func testAccIPAddressAssociationBasic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_address_association" "test" {
name = "testing-acc-%d"
description = "acctesting ip address association test %d"
tags = ["tag1", "tag2"]
}`, rInt, rInt)
}
func testAccIPAddressAssociationBasic_Update(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_address_association" "test" {
name = "testing-acc-%d"
description = "acctesting ip address association test updated %d"
tags = ["tag1"]
}`, rInt, rInt)
}
func testAccIPAddressAssociationFull(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_network" "foo" {
name = "testing-vnic-data-%d"
description = "testing-ip-address-association"
ip_address_prefix = "10.1.13.0/24"
}
resource "opc_compute_instance" "test" {
name = "test-%d"
label = "test"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
networking_info {
index = 0
ip_network = "${opc_compute_ip_network.foo.id}"
vnic = "test-vnic-data-%d"
shared_network = false
mac_address = "02:5a:cd:ec:2e:4c"
}
}
data "opc_compute_network_interface" "eth0" {
instance_name = "${opc_compute_instance.test.name}"
instance_id = "${opc_compute_instance.test.id}"
interface = "eth0"
}
resource "opc_compute_ip_address_reservation" "test" {
name = "testing-ip-address-association-%d"
description = "testing-desc-%d"
ip_address_pool = "public-ippool"
}
resource "opc_compute_ip_address_association" "test" {
name = "testing-acc-%d"
ip_address_reservation = "${opc_compute_ip_address_reservation.test.name}"
vnic = "${data.opc_compute_network_interface.eth0.vnic}"
description = "acctesting ip address association test %d"
tags = ["tag1", "tag2"]
}`, rInt, rInt, rInt, rInt, rInt, rInt, rInt)
}

View File

@ -0,0 +1,147 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCIPAddressPrefixSet() *schema.Resource {
return &schema.Resource{
Create: resourceOPCIPAddressPrefixSetCreate,
Read: resourceOPCIPAddressPrefixSetRead,
Update: resourceOPCIPAddressPrefixSetUpdate,
Delete: resourceOPCIPAddressPrefixSetDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"prefixes": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validateIPPrefixCIDR,
},
},
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"tags": tagsOptionalSchema(),
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCIPAddressPrefixSetCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressPrefixSets()
input := compute.CreateIPAddressPrefixSetInput{
Name: d.Get("name").(string),
}
prefixes := getStringList(d, "prefixes")
if len(prefixes) != 0 {
input.IPAddressPrefixes = prefixes
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.CreateIPAddressPrefixSet(&input)
if err != nil {
return fmt.Errorf("Error creating IP Address Prefix Set: %s", err)
}
d.SetId(info.Name)
return resourceOPCIPAddressPrefixSetRead(d, meta)
}
func resourceOPCIPAddressPrefixSetRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressPrefixSets()
getInput := compute.GetIPAddressPrefixSetInput{
Name: d.Id(),
}
result, err := client.GetIPAddressPrefixSet(&getInput)
if err != nil {
// IP Address Prefix Set does not exist
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading IP Address Prefix Set %s: %s", d.Id(), err)
}
d.Set("name", result.Name)
d.Set("description", result.Description)
d.Set("uri", result.Uri)
if err := setStringList(d, "prefixes", result.IPAddressPrefixes); err != nil {
return err
}
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
return nil
}
func resourceOPCIPAddressPrefixSetUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressPrefixSets()
input := compute.UpdateIPAddressPrefixSetInput{
Name: d.Get("name").(string),
}
prefixes := getStringList(d, "prefixes")
if len(prefixes) != 0 {
input.IPAddressPrefixes = prefixes
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.UpdateIPAddressPrefixSet(&input)
if err != nil {
return fmt.Errorf("Error updating IP Address Prefix Set: %s", err)
}
d.SetId(info.Name)
return resourceOPCIPAddressPrefixSetRead(d, meta)
}
func resourceOPCIPAddressPrefixSetDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressPrefixSets()
name := d.Id()
input := compute.DeleteIPAddressPrefixSetInput{
Name: name,
}
if err := client.DeleteIPAddressPrefixSet(&input); err != nil {
return fmt.Errorf("Error deleting IP Address Prefix Set: %s", err)
}
return nil
}

View File

@ -0,0 +1,100 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCIPAddressPrefixSet_Basic(t *testing.T) {
rInt := acctest.RandInt()
resourceName := "opc_compute_ip_address_prefix_set.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckIPAddressPrefixSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccIPAddressPrefixSetBasic(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckIPAddressPrefixSetExists,
resource.TestCheckResourceAttr(
resourceName, "tags.#", "2"),
resource.TestCheckResourceAttr(
resourceName, "prefixes.#", "2"),
),
},
{
Config: testAccIPAddressPrefixSetBasic_Update(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
resourceName, "tags.#", "1"),
resource.TestCheckResourceAttr(
resourceName, "prefixes.0", "171.120.0.0/24"),
),
},
},
})
}
func testAccCheckIPAddressPrefixSetExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPAddressPrefixSets()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_address_prefix_set" {
continue
}
input := compute.GetIPAddressPrefixSetInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetIPAddressPrefixSet(&input); err != nil {
return fmt.Errorf("Error retrieving state of IP Address Prefix Set %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckIPAddressPrefixSetDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPAddressPrefixSets()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_address_prefix_set" {
continue
}
input := compute.GetIPAddressPrefixSetInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetIPAddressPrefixSet(&input); err == nil {
return fmt.Errorf("IP Address Prefix Set %s still exists: %#v", input.Name, info)
}
}
return nil
}
func testAccIPAddressPrefixSetBasic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_address_prefix_set" "test" {
name = "testing-acc-%d"
prefixes = ["172.120.0.0/24", "192.168.0.0/16"]
description = "acctesting ip address prefix test %d"
tags = ["tag1", "tag2"]
}`, rInt, rInt)
}
func testAccIPAddressPrefixSetBasic_Update(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_address_prefix_set" "test" {
name = "testing-acc-%d"
description = "acctesting ip address prefix test updated %d"
prefixes = ["171.120.0.0/24", "192.168.0.0/16"]
tags = ["tag1"]
}`, rInt, rInt)
}

View File

@ -0,0 +1,137 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)
func resourceOPCIPAddressReservation() *schema.Resource {
return &schema.Resource{
Create: resourceOPCIPAddressReservationCreate,
Read: resourceOPCIPAddressReservationRead,
Update: resourceOPCIPAddressReservationUpdate,
Delete: resourceOPCIPAddressReservationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"ip_address_pool": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
string(compute.PublicIPAddressPool),
string(compute.PrivateIPAddressPool),
}, true),
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"tags": tagsOptionalSchema(),
"ip_address": {
Type: schema.TypeString,
Computed: true,
},
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCIPAddressReservationCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressReservations()
input := compute.CreateIPAddressReservationInput{
Name: d.Get("name").(string),
IPAddressPool: d.Get("ip_address_pool").(string),
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.CreateIPAddressReservation(&input)
if err != nil {
return fmt.Errorf("Error creating IP Address Reservation: %s", err)
}
d.SetId(info.Name)
return resourceOPCIPAddressReservationRead(d, meta)
}
func resourceOPCIPAddressReservationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressReservations()
getInput := compute.GetIPAddressReservationInput{
Name: d.Id(),
}
result, err := client.GetIPAddressReservation(&getInput)
if err != nil {
// IP Address Reservation does not exist
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading ip address reservation %s: %s", d.Id(), err)
}
d.Set("name", result.Name)
d.Set("description", result.Description)
d.Set("ip_address_pool", result.IPAddressPool)
d.Set("uri", result.Uri)
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
return nil
}
func resourceOPCIPAddressReservationUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressReservations()
input := compute.UpdateIPAddressReservationInput{
Name: d.Get("name").(string),
IPAddressPool: d.Get("ip_address_pool").(string),
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.UpdateIPAddressReservation(&input)
if err != nil {
return fmt.Errorf("Error updating IP Address Reservation: %s", err)
}
d.SetId(info.Name)
return resourceOPCIPAddressReservationRead(d, meta)
}
func resourceOPCIPAddressReservationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAddressReservations()
name := d.Id()
input := compute.DeleteIPAddressReservationInput{
Name: name,
}
if err := client.DeleteIPAddressReservation(&input); err != nil {
return fmt.Errorf("Error deleting IP Address Reservation: %+v", err)
}
return nil
}

View File

@ -0,0 +1,77 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCIPAddressReservation_Basic(t *testing.T) {
rInt := acctest.RandInt()
resName := "opc_compute_ip_address_reservation.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckIPAddressReservationDestroy,
Steps: []resource.TestStep{
{
Config: testAccOPCIPAddressReservationConfig_Basic(rInt),
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckIPAddressReservationExists,
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("testing-ip-address-reservation-%d", rInt)),
),
},
},
})
}
func testAccOPCCheckIPAddressReservationExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPAddressReservations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_address_reservation" {
continue
}
input := compute.GetIPAddressReservationInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetIPAddressReservation(&input); err != nil {
return fmt.Errorf("Error retrieving state of IP Address Reservation %s: %s", input.Name, err)
}
}
return nil
}
func testAccOPCCheckIPAddressReservationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPAddressReservations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_address_reservation" {
continue
}
input := compute.GetIPAddressReservationInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetIPAddressReservation(&input); err == nil {
return fmt.Errorf("IP Address Reservation %s still exists: %#v", input.Name, info)
}
}
return nil
}
func testAccOPCIPAddressReservationConfig_Basic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_address_reservation" "test" {
name = "testing-ip-address-reservation-%d"
description = "testing-desc-%d"
ip_address_pool = "public-ippool"
}`, rInt, rInt)
}

View File

@ -0,0 +1,96 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCIPAssociation() *schema.Resource {
return &schema.Resource{
Create: resourceOPCIPAssociationCreate,
Read: resourceOPCIPAssociationRead,
Delete: resourceOPCIPAssociationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"vcable": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"parent_pool": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
func resourceOPCIPAssociationCreate(d *schema.ResourceData, meta interface{}) error {
vCable := d.Get("vcable").(string)
parentPool := d.Get("parent_pool").(string)
client := meta.(*compute.Client).IPAssociations()
input := compute.CreateIPAssociationInput{
ParentPool: parentPool,
VCable: vCable,
}
info, err := client.CreateIPAssociation(&input)
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)
return resourceOPCIPAssociationRead(d, meta)
}
func resourceOPCIPAssociationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAssociations()
name := d.Id()
input := compute.GetIPAssociationInput{
Name: name,
}
result, err := client.GetIPAssociation(&input)
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)
}
d.Set("name", result.Name)
d.Set("parent_pool", result.ParentPool)
d.Set("vcable", result.VCable)
return nil
}
func resourceOPCIPAssociationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPAssociations()
name := d.Id()
input := compute.DeleteIPAssociationInput{
Name: name,
}
if err := client.DeleteIPAssociation(&input); err != nil {
return fmt.Errorf("Error deleting ip association '%s': %s", name, err)
}
return nil
}

View File

@ -0,0 +1,88 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCIPAssociation_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccIPAssociationBasic, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckIPAssociationDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckIPAssociationExists,
),
},
},
})
}
func testAccOPCCheckIPAssociationExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPAssociations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_association" {
continue
}
input := compute.GetIPAssociationInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetIPAssociation(&input); err != nil {
return fmt.Errorf("Error retrieving state of IP Association %s: %s", input.Name, err)
}
}
return nil
}
func testAccOPCCheckIPAssociationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPAssociations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_association" {
continue
}
input := compute.GetIPAssociationInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetIPAssociation(&input); err == nil {
return fmt.Errorf("IP Association %s still exists: %#v", input.Name, info)
}
}
return nil
}
var testAccIPAssociationBasic = `
resource "opc_compute_instance" "test" {
name = "test-acc-ip-ass-instance-%d"
label = "testAccIPAssociationBasic"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
}
resource "opc_compute_ip_reservation" "test" {
name = "test-acc-ip-ass-reservation-%d"
parent_pool = "/oracle/public/ippool"
permanent = true
}
resource "opc_compute_ip_association" "test" {
vcable = "${opc_compute_instance.test.vcable}"
parent_pool = "ipreservation:${opc_compute_ip_reservation.test.name}"
}
`

View File

@ -0,0 +1,179 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCIPNetwork() *schema.Resource {
return &schema.Resource{
Create: resourceOPCIPNetworkCreate,
Read: resourceOPCIPNetworkRead,
Update: resourceOPCIPNetworkUpdate,
Delete: resourceOPCIPNetworkDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"ip_address_prefix": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateIPPrefixCIDR,
},
"ip_network_exchange": {
Type: schema.TypeString,
Optional: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"public_napt_enabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"uri": {
Type: schema.TypeString,
Computed: true,
},
"tags": tagsOptionalSchema(),
},
}
}
func resourceOPCIPNetworkCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPNetworks()
// Get required attributes
name := d.Get("name").(string)
ipPrefix := d.Get("ip_address_prefix").(string)
// public_napt_enabled is not required, but bool type allows it to be unspecified
naptEnabled := d.Get("public_napt_enabled").(bool)
input := &compute.CreateIPNetworkInput{
Name: name,
IPAddressPrefix: ipPrefix,
PublicNaptEnabled: naptEnabled,
}
// Get Optional attributes
if desc, ok := d.GetOk("description"); ok && desc != nil {
input.Description = desc.(string)
}
if ipEx, ok := d.GetOk("ip_network_exchange"); ok && ipEx != nil {
input.IPNetworkExchange = ipEx.(string)
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
info, err := client.CreateIPNetwork(input)
if err != nil {
return fmt.Errorf("Error creating IP Network '%s': %v", name, err)
}
d.SetId(info.Name)
return resourceOPCIPNetworkRead(d, meta)
}
func resourceOPCIPNetworkRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPNetworks()
name := d.Id()
input := &compute.GetIPNetworkInput{
Name: name,
}
res, err := client.GetIPNetwork(input)
if err != nil {
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading IP Network '%s': %v", name, err)
}
d.Set("name", res.Name)
d.Set("ip_address_prefix", res.IPAddressPrefix)
d.Set("ip_network_exchanged", res.IPNetworkExchange)
d.Set("description", res.Description)
d.Set("public_napt_enabled", res.PublicNaptEnabled)
d.Set("uri", res.Uri)
if err := setStringList(d, "tags", res.Tags); err != nil {
return err
}
return nil
}
func resourceOPCIPNetworkUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPNetworks()
// Get required attributes
name := d.Get("name").(string)
ipPrefix := d.Get("ip_address_prefix").(string)
// public_napt_enabled is not required, but bool type allows it to be unspecified
naptEnabled := d.Get("public_napt_enabled").(bool)
input := &compute.UpdateIPNetworkInput{
Name: name,
IPAddressPrefix: ipPrefix,
PublicNaptEnabled: naptEnabled,
}
// Get Optional attributes
desc, descOk := d.GetOk("description")
if descOk {
input.Description = desc.(string)
}
ipEx, ipExOk := d.GetOk("ip_network_exchange")
if ipExOk {
input.IPNetworkExchange = ipEx.(string)
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
info, err := client.UpdateIPNetwork(input)
if err != nil {
return fmt.Errorf("Error updating IP Network '%s': %v", name, err)
}
d.SetId(info.Name)
return resourceOPCIPNetworkRead(d, meta)
}
func resourceOPCIPNetworkDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPNetworks()
name := d.Id()
input := &compute.DeleteIPNetworkInput{
Name: name,
}
if err := client.DeleteIPNetwork(input); err != nil {
return fmt.Errorf("Error deleting IP Network '%s': %v", name, err)
}
return nil
}

View File

@ -0,0 +1,105 @@
package opc
import (
"fmt"
"log"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCIPNetworkExchange() *schema.Resource {
return &schema.Resource{
Create: resourceOPCIPNetworkExchangeCreate,
Read: resourceOPCIPNetworkExchangeRead,
Delete: resourceOPCIPNetworkExchangeDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"tags": tagsForceNewSchema(),
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCIPNetworkExchangeCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPNetworkExchanges()
input := compute.CreateIPNetworkExchangeInput{
Name: d.Get("name").(string),
}
log.Printf("[DEBUG] Creating ip network exchange '%s'", input.Name)
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.CreateIPNetworkExchange(&input)
if err != nil {
return fmt.Errorf("Error creating IP Network Exchange: %s", err)
}
d.SetId(info.Name)
return resourceOPCIPNetworkExchangeRead(d, meta)
}
func resourceOPCIPNetworkExchangeRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPNetworkExchanges()
log.Printf("[DEBUG] Reading state of IP Network Exchange %s", d.Id())
getInput := compute.GetIPNetworkExchangeInput{
Name: d.Id(),
}
result, err := client.GetIPNetworkExchange(&getInput)
if err != nil {
// IP NetworkExchange does not exist
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading ip network exchange %s: %s", d.Id(), err)
}
d.Set("name", result.Name)
d.Set("description", result.Description)
d.Set("uri", result.Uri)
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
return nil
}
func resourceOPCIPNetworkExchangeDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).IPNetworkExchanges()
name := d.Id()
log.Printf("[DEBUG] Deleting IP Network Exchange '%s'", name)
input := compute.DeleteIPNetworkExchangeInput{
Name: name,
}
if err := client.DeleteIPNetworkExchange(&input); err != nil {
return fmt.Errorf("Error deleting IP Network Exchange '%s': %+v", name, err)
}
return nil
}

View File

@ -0,0 +1,73 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCIPNetworkExchange_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccIPNetworkExchangeBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckIPNetworkExchangeDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckIPNetworkExchangeExists,
},
},
})
}
func testAccCheckIPNetworkExchangeExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPNetworkExchanges()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_network_exchange" {
continue
}
input := compute.GetIPNetworkExchangeInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetIPNetworkExchange(&input); err != nil {
return fmt.Errorf("Error retrieving state of ip network exchange %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckIPNetworkExchangeDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPNetworkExchanges()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_network_exchange" {
continue
}
input := compute.GetIPNetworkExchangeInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetIPNetworkExchange(&input); err == nil {
return fmt.Errorf("IPNetworkExchange %s still exists: %#v", input.Name, info)
}
}
return nil
}
var testAccIPNetworkExchangeBasic = `
resource "opc_compute_ip_network_exchange" "test" {
name = "test_ip_network_exchange-%d"
description = "test ip network exchange"
}
`

View File

@ -0,0 +1,115 @@
package opc
import (
"fmt"
"regexp"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCIPNetwork_Basic(t *testing.T) {
rInt := acctest.RandInt()
resName := "opc_compute_ip_network.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resName, testAccOPCCheckIPNetworkDestroyed),
Steps: []resource.TestStep{
{
Config: testAccOPCIPNetworkConfig_Basic(rInt),
Check: resource.ComposeTestCheckFunc(
opcResourceCheck(resName, testAccOPCCheckIPNetworkExists),
resource.TestCheckResourceAttr(resName, "ip_address_prefix", "10.0.12.0/24"),
resource.TestCheckResourceAttr(resName, "public_napt_enabled", "false"),
resource.TestCheckResourceAttr(resName, "description", fmt.Sprintf("testing-desc-%d", rInt)),
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("testing-ip-network-%d", rInt)),
resource.TestMatchResourceAttr(resName, "uri", regexp.MustCompile("testing-ip-network")),
),
},
},
})
}
func TestAccOPCIPNetwork_Update(t *testing.T) {
rInt := acctest.RandInt()
resName := "opc_compute_ip_network.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resName, testAccOPCCheckIPNetworkDestroyed),
Steps: []resource.TestStep{
{
Config: testAccOPCIPNetworkConfig_Basic(rInt),
Check: resource.ComposeTestCheckFunc(
opcResourceCheck(resName, testAccOPCCheckIPNetworkExists),
resource.TestCheckResourceAttr(resName, "ip_address_prefix", "10.0.12.0/24"),
resource.TestCheckResourceAttr(resName, "public_napt_enabled", "false"),
resource.TestCheckResourceAttr(resName, "description", fmt.Sprintf("testing-desc-%d", rInt)),
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("testing-ip-network-%d", rInt)),
resource.TestMatchResourceAttr(resName, "uri", regexp.MustCompile("testing-ip-network")),
),
},
{
Config: testAccOPCIPNetworkConfig_BasicUpdate(rInt),
Check: resource.ComposeTestCheckFunc(
opcResourceCheck(resName, testAccOPCCheckIPNetworkExists),
resource.TestCheckResourceAttr(resName, "ip_address_prefix", "10.0.12.0/24"),
resource.TestCheckResourceAttr(resName, "public_napt_enabled", "true"),
resource.TestCheckResourceAttr(resName, "description", fmt.Sprintf("testing-desc-%d", rInt)),
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("testing-ip-network-%d", rInt)),
),
},
},
})
}
func testAccOPCIPNetworkConfig_Basic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_network" "test" {
name = "testing-ip-network-%d"
description = "testing-desc-%d"
ip_address_prefix = "10.0.12.0/24"
}`, rInt, rInt)
}
func testAccOPCIPNetworkConfig_BasicUpdate(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_network" "test" {
name = "testing-ip-network-%d"
description = "testing-desc-%d"
ip_address_prefix = "10.0.12.0/24"
public_napt_enabled = true
}`, rInt, rInt)
}
func testAccOPCCheckIPNetworkExists(state *OPCResourceState) error {
name := state.Attributes["name"]
input := &compute.GetIPNetworkInput{
Name: name,
}
if _, err := state.Client.IPNetworks().GetIPNetwork(input); err != nil {
return fmt.Errorf("Error retrieving state of IP Network '%s': %v", name, err)
}
return nil
}
func testAccOPCCheckIPNetworkDestroyed(state *OPCResourceState) error {
name := state.Attributes["name"]
input := &compute.GetIPNetworkInput{
Name: name,
}
if info, _ := state.Client.IPNetworks().GetIPNetwork(input); info != nil {
return fmt.Errorf("IP Network '%s' still exists: %+v", name, info)
}
return nil
}

View File

@ -0,0 +1,117 @@
package opc
import (
"fmt"
"log"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCIPReservation() *schema.Resource {
return &schema.Resource{
Create: resourceOPCIPReservationCreate,
Read: resourceOPCIPReservationRead,
Delete: resourceOPCIPReservationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"permanent": {
Type: schema.TypeBool,
Required: true,
ForceNew: true,
},
"parent_pool": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"tags": tagsForceNewSchema(),
"ip": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCIPReservationCreate(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
reservation := compute.CreateIPReservationInput{
Name: d.Get("name").(string),
ParentPool: compute.IPReservationPool(d.Get("parent_pool").(string)),
Permanent: d.Get("permanent").(bool),
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
reservation.Tags = tags
}
log.Printf("[DEBUG] Creating ip reservation from parent_pool %s with tags=%s",
reservation.ParentPool, reservation.Tags)
client := meta.(*compute.Client).IPReservations()
info, err := client.CreateIPReservation(&reservation)
if err != nil {
return fmt.Errorf("Error creating ip reservation from parent_pool %s with tags=%s: %s",
reservation.ParentPool, reservation.Tags, err)
}
d.SetId(info.Name)
return resourceOPCIPReservationRead(d, meta)
}
func resourceOPCIPReservationRead(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
client := meta.(*compute.Client).IPReservations()
log.Printf("[DEBUG] Reading state of ip reservation %s", d.Id())
getInput := compute.GetIPReservationInput{
Name: d.Id(),
}
result, err := client.GetIPReservation(&getInput)
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", d.Id(), err)
}
log.Printf("[DEBUG] Read state of ip reservation %s: %#v", d.Id(), result)
d.Set("name", result.Name)
d.Set("parent_pool", result.ParentPool)
d.Set("permanent", result.Permanent)
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
d.Set("ip", result.IP)
return nil
}
func resourceOPCIPReservationDelete(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
client := meta.(*compute.Client).IPReservations()
log.Printf("[DEBUG] Deleting ip reservation %s", d.Id())
input := compute.DeleteIPReservationInput{
Name: d.Id(),
}
if err := client.DeleteIPReservation(&input); err != nil {
return fmt.Errorf("Error deleting ip reservation %s", d.Id())
}
return nil
}

View File

@ -0,0 +1,75 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCIPReservation_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccIPReservationBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckIPReservationDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckIPReservationExists,
},
},
})
}
func testAccCheckIPReservationExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPReservations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_reservation" {
continue
}
input := compute.GetIPReservationInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetIPReservation(&input); err != nil {
return fmt.Errorf("Error retrieving state of IP Reservation %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckIPReservationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).IPReservations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_ip_reservation" {
continue
}
input := compute.GetIPReservationInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetIPReservation(&input); err == nil {
return fmt.Errorf("IP Reservation %s still exists: %#v", input.Name, info)
}
}
return nil
}
var testAccIPReservationBasic = `
resource "opc_compute_ip_reservation" "test" {
name = "acc-test-ip-reservation-%d"
parent_pool = "/oracle/public/ippool"
permanent = true
}
`

View File

@ -0,0 +1,176 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCRoute() *schema.Resource {
return &schema.Resource{
Create: resourceOPCRouteCreate,
Read: resourceOPCRouteRead,
Update: resourceOPCRouteUpdate,
Delete: resourceOPCRouteDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"admin_distance": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validateAdminDistance,
},
"ip_address_prefix": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateIPPrefixCIDR,
},
"next_hop_vnic_set": {
Type: schema.TypeString,
Required: true,
},
"tags": tagsOptionalSchema(),
},
}
}
func resourceOPCRouteCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).Routes()
// Get Required attributes
name := d.Get("name").(string)
ipPrefix := d.Get("ip_address_prefix").(string)
nextHop := d.Get("next_hop_vnic_set").(string)
// Start populating input struct
input := &compute.CreateRouteInput{
Name: name,
IPAddressPrefix: ipPrefix,
NextHopVnicSet: nextHop,
}
// Get Optional Attributes
desc, descOk := d.GetOk("description")
if descOk {
input.Description = desc.(string)
}
dist, distOk := d.GetOk("admin_distance")
if distOk {
input.AdminDistance = dist.(int)
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
// Create Route
info, err := client.CreateRoute(input)
if err != nil {
return fmt.Errorf("Error creating route '%s': %v", name, err)
}
d.SetId(info.Name)
return resourceOPCRouteRead(d, meta)
}
func resourceOPCRouteRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).Routes()
name := d.Id()
input := &compute.GetRouteInput{
Name: name,
}
res, err := client.GetRoute(input)
if err != nil {
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading route '%s': %v", name, err)
}
d.Set("name", res.Name)
d.Set("admin_distance", res.AdminDistance)
d.Set("ip_address_prefix", res.IPAddressPrefix)
d.Set("next_hop_vnic_set", res.NextHopVnicSet)
d.Set("description", res.Description)
if err := setStringList(d, "tags", res.Tags); err != nil {
return err
}
return nil
}
func resourceOPCRouteUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).Routes()
// Get Required attributes
name := d.Get("name").(string)
ipPrefix := d.Get("ip_address_prefix").(string)
nextHop := d.Get("next_hop_vnic_set").(string)
// Start populating input struct
input := &compute.UpdateRouteInput{
Name: name,
IPAddressPrefix: ipPrefix,
NextHopVnicSet: nextHop,
}
// Get Optional Attributes
desc, descOk := d.GetOk("description")
if descOk {
input.Description = desc.(string)
}
dist, distOk := d.GetOk("admin_distance")
if distOk {
input.AdminDistance = dist.(int)
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
// Create Route
info, err := client.UpdateRoute(input)
if err != nil {
return fmt.Errorf("Error creating route '%s': %v", name, err)
}
d.SetId(info.Name)
return resourceOPCRouteRead(d, meta)
}
func resourceOPCRouteDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).Routes()
name := d.Id()
input := &compute.DeleteRouteInput{
Name: name,
}
if err := client.DeleteRoute(input); err != nil {
return fmt.Errorf("Error deleting route '%s': %v", name, err)
}
return nil
}

View File

@ -0,0 +1,163 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCRoute_Basic(t *testing.T) {
rInt := acctest.RandInt()
resName := "opc_compute_route.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckRouteDestroy,
Steps: []resource.TestStep{
{
Config: testAccOPCRouteConfig_Basic(rInt),
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckRouteExists,
resource.TestCheckResourceAttr(resName, "admin_distance", "1"),
resource.TestCheckResourceAttr(resName, "ip_address_prefix", "10.0.12.0/24"),
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("testing-route-%d", rInt)),
),
},
{
Config: testAccOPCRouteConfig_BasicUpdate(rInt),
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckRouteExists,
resource.TestCheckResourceAttr(resName, "admin_distance", "2"),
resource.TestCheckResourceAttr(resName, "ip_address_prefix", "10.0.14.0/24"),
),
},
},
})
}
func testAccOPCRouteConfig_Basic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_network" "foo" {
name = "testing-route-%d"
description = "testing-route"
ip_address_prefix = "10.1.14.0/24"
}
resource "opc_compute_instance" "foo" {
name = "test-route-%d"
label = "testing"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
networking_info {
index = 0
ip_network = "${opc_compute_ip_network.foo.id}"
vnic = "test-vnic-set-%d"
shared_network = false
}
}
data "opc_compute_network_interface" "foo" {
instance_name = "${opc_compute_instance.foo.name}"
instance_id = "${opc_compute_instance.foo.id}"
interface = "eth0"
}
resource "opc_compute_vnic_set" "test" {
name = "route-test-%d"
description = "route-testing-%d"
virtual_nics = ["${data.opc_compute_network_interface.foo.vnic}"]
}
resource "opc_compute_route" "test" {
name = "testing-route-%d"
description = "testing-desc-%d"
admin_distance = 1
ip_address_prefix = "10.0.12.0/24"
next_hop_vnic_set = "${opc_compute_vnic_set.test.name}"
}`, rInt, rInt, rInt, rInt, rInt, rInt, rInt)
}
func testAccOPCRouteConfig_BasicUpdate(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_ip_network" "foo" {
name = "testing-route-%d"
description = "testing-route"
ip_address_prefix = "10.1.14.0/24"
}
resource "opc_compute_instance" "foo" {
name = "test-route-%d"
label = "testing"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
networking_info {
index = 0
ip_network = "${opc_compute_ip_network.foo.id}"
vnic = "test-vnic-set-%d"
shared_network = false
}
}
data "opc_compute_network_interface" "foo" {
instance_name = "${opc_compute_instance.foo.name}"
instance_id = "${opc_compute_instance.foo.id}"
interface = "eth0"
}
resource "opc_compute_vnic_set" "test" {
name = "route-test-%d"
description = "route-testing-%d"
virtual_nics = ["${data.opc_compute_network_interface.foo.vnic}"]
}
resource "opc_compute_route" "test" {
name = "testing-route-%d"
description = "testing-desc-%d"
admin_distance = 2
ip_address_prefix = "10.0.14.0/24"
next_hop_vnic_set = "${opc_compute_vnic_set.test.name}"
}`, rInt, rInt, rInt, rInt, rInt, rInt, rInt)
}
func testAccOPCCheckRouteExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).Routes()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_route" {
continue
}
input := compute.GetRouteInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetRoute(&input); err != nil {
return fmt.Errorf("Error retrieving state of Rule %s: %s", input.Name, err)
}
}
return nil
}
func testAccOPCCheckRouteDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).Routes()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_route" {
continue
}
input := compute.GetRouteInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetRoute(&input); err == nil {
return fmt.Errorf("Rule %s still exists: %#v", input.Name, info)
}
}
return nil
}

View File

@ -0,0 +1,163 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCSecRule() *schema.Resource {
return &schema.Resource{
Create: resourceOPCSecRuleCreate,
Read: resourceOPCSecRuleRead,
Update: resourceOPCSecRuleUpdate,
Delete: resourceOPCSecRuleDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"source_list": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"destination_list": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"application": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"action": {
Type: schema.TypeString,
Required: true,
},
"disabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
}
}
func resourceOPCSecRuleCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecRules()
name := d.Get("name").(string)
sourceList := d.Get("source_list").(string)
destinationList := d.Get("destination_list").(string)
application := d.Get("application").(string)
action := d.Get("action").(string)
disabled := d.Get("disabled").(bool)
input := compute.CreateSecRuleInput{
Name: name,
Action: action,
SourceList: sourceList,
DestinationList: destinationList,
Disabled: disabled,
Application: application,
}
desc, descOk := d.GetOk("description")
if descOk {
input.Description = desc.(string)
}
info, err := client.CreateSecRule(&input)
if err != nil {
return fmt.Errorf("Error creating sec rule %s: %s", name, err)
}
d.SetId(info.Name)
return resourceOPCSecRuleRead(d, meta)
}
func resourceOPCSecRuleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecRules()
name := d.Id()
input := compute.GetSecRuleInput{
Name: name,
}
result, err := client.GetSecRule(&input)
if err != nil {
// Sec Rule does not exist
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading sec list %s: %s", name, err)
}
d.Set("name", result.Name)
d.Set("description", result.Description)
d.Set("source_list", result.SourceList)
d.Set("destination_list", result.DestinationList)
d.Set("application", result.Application)
d.Set("action", result.Action)
d.Set("disabled", result.Disabled)
return nil
}
func resourceOPCSecRuleUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecRules()
name := d.Get("name").(string)
sourceList := d.Get("source_list").(string)
destinationList := d.Get("destination_list").(string)
application := d.Get("application").(string)
action := d.Get("action").(string)
disabled := d.Get("disabled").(bool)
input := compute.UpdateSecRuleInput{
Action: action,
Application: application,
DestinationList: destinationList,
Disabled: disabled,
Name: name,
SourceList: sourceList,
}
desc, descOk := d.GetOk("description")
if descOk {
input.Description = desc.(string)
}
_, err := client.UpdateSecRule(&input)
if err != nil {
return fmt.Errorf("Error updating sec rule %s: %s", name, err)
}
return resourceOPCSecRuleRead(d, meta)
}
func resourceOPCSecRuleDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecRules()
name := d.Id()
input := compute.DeleteSecRuleInput{
Name: name,
}
if err := client.DeleteSecRule(&input); err != nil {
return fmt.Errorf("Error deleting sec rule %s: %s", name, err)
}
return nil
}

View File

@ -0,0 +1,138 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCSecRule_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecRuleBasic, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecRuleDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckSecRuleExists,
},
},
})
}
func TestAccOPCSecRule_Complete(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecRuleComplete, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecRuleDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckSecRuleExists,
},
},
})
}
func testAccCheckSecRuleExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecRules()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_sec_rule" {
continue
}
input := compute.GetSecRuleInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetSecRule(&input); err != nil {
return fmt.Errorf("Error retrieving state of Sec Rule %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckSecRuleDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecRules()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_sec_rule" {
continue
}
input := compute.GetSecRuleInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetSecRule(&input); err == nil {
return fmt.Errorf("Sec Rule %s still exists: %#v", input.Name, info)
}
}
return nil
}
var testAccOPCSecRuleBasic = `
resource "opc_compute_security_list" "test" {
name = "acc-test-sec-rule-list-%d"
policy = "PERMIT"
outbound_cidr_policy = "DENY"
}
resource "opc_compute_security_application" "test" {
name = "acc-test-sec-rule-app-%d"
protocol = "tcp"
dport = "8080"
}
resource "opc_compute_security_ip_list" "test" {
name = "acc-test-sec-rule-ip-list-%d"
ip_entries = ["217.138.34.4"]
}
resource "opc_compute_sec_rule" "test" {
name = "acc-test-sec-rule-%d"
source_list = "seclist:${opc_compute_security_list.test.name}"
destination_list = "seciplist:${opc_compute_security_ip_list.test.name}"
action = "PERMIT"
application = "${opc_compute_security_application.test.name}"
}
`
var testAccOPCSecRuleComplete = `
resource "opc_compute_security_list" "test" {
name = "acc-test-sec-rule-list-%d"
policy = "PERMIT"
outbound_cidr_policy = "DENY"
}
resource "opc_compute_security_application" "test" {
name = "acc-test-sec-rule-app-%d"
protocol = "tcp"
dport = "8080"
}
resource "opc_compute_security_ip_list" "test" {
name = "acc-test-sec-rule-ip-list-%d"
ip_entries = ["217.138.34.4"]
}
resource "opc_compute_sec_rule" "test" {
name = "acc-test-sec-rule-%d"
source_list = "seclist:${opc_compute_security_list.test.name}"
destination_list = "seciplist:${opc_compute_security_ip_list.test.name}"
action = "PERMIT"
application = "${opc_compute_security_application.test.name}"
disabled = false
description = "This is a test description"
}
`

View File

@ -0,0 +1,140 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)
func resourceOPCSecurityApplication() *schema.Resource {
return &schema.Resource{
Create: resourceOPCSecurityApplicationCreate,
Read: resourceOPCSecurityApplicationRead,
Delete: resourceOPCSecurityApplicationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"protocol": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateIPProtocol,
ForceNew: true,
},
"dport": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"icmptype": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
string(compute.Echo),
string(compute.Reply),
string(compute.TTL),
string(compute.TraceRoute),
string(compute.Unreachable),
}, true),
ForceNew: true,
},
"icmpcode": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
string(compute.Admin),
string(compute.Df),
string(compute.Host),
string(compute.Network),
string(compute.Port),
string(compute.Protocol),
}, true),
ForceNew: true,
},
},
}
}
func resourceOPCSecurityApplicationCreate(d *schema.ResourceData, meta interface{}) error {
name := d.Get("name").(string)
protocol := d.Get("protocol").(string)
dport := d.Get("dport").(string)
icmptype := d.Get("icmptype").(string)
icmpcode := d.Get("icmpcode").(string)
description := d.Get("description").(string)
client := meta.(*compute.Client).SecurityApplications()
input := compute.CreateSecurityApplicationInput{
Name: name,
Description: description,
Protocol: compute.SecurityApplicationProtocol(protocol),
DPort: dport,
ICMPCode: compute.SecurityApplicationICMPCode(icmpcode),
ICMPType: compute.SecurityApplicationICMPType(icmptype),
}
info, err := client.CreateSecurityApplication(&input)
if err != nil {
return fmt.Errorf("Error creating security application %s: %s", name, err)
}
d.SetId(info.Name)
return resourceOPCSecurityApplicationRead(d, meta)
}
func resourceOPCSecurityApplicationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityApplications()
name := d.Id()
input := compute.GetSecurityApplicationInput{
Name: name,
}
result, err := client.GetSecurityApplication(&input)
if err != nil {
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading security application %s: %s", name, err)
}
d.Set("name", result.Name)
d.Set("protocol", result.Protocol)
d.Set("dport", result.DPort)
d.Set("icmptype", result.ICMPType)
d.Set("icmpcode", result.ICMPCode)
d.Set("description", result.Description)
return nil
}
func resourceOPCSecurityApplicationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityApplications()
name := d.Id()
input := compute.DeleteSecurityApplicationInput{
Name: name,
}
if err := client.DeleteSecurityApplication(&input); err != nil {
return fmt.Errorf("Error deleting security application '%s': %s", name, err)
}
return nil
}

View File

@ -0,0 +1,101 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCSecurityApplication_ICMP(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityApplicationICMP, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSecurityApplicationDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccOPCCheckSecurityApplicationExists,
},
},
})
}
func TestAccOPCSecurityApplication_TCP(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityApplicationTCP, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSecurityApplicationDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccOPCCheckSecurityApplicationExists,
},
},
})
}
func testAccOPCCheckSecurityApplicationExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityApplications()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_application" {
continue
}
input := compute.GetSecurityApplicationInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetSecurityApplication(&input); err != nil {
return fmt.Errorf("Error retrieving state of Security Application %s: %s", input.Name, err)
}
}
return nil
}
func testAccOPCCheckSecurityApplicationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityApplications()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_application" {
continue
}
input := compute.GetSecurityApplicationInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetSecurityApplication(&input); err == nil {
return fmt.Errorf("Security Application %s still exists: %#v", input.Name, info)
}
}
return nil
}
const testAccOPCSecurityApplicationTCP = `
resource "opc_compute_security_application" "test" {
name = "acc-security-application-tcp-%d"
protocol = "tcp"
dport = "8080"
description = "Terraform Acceptance Test"
}
`
const testAccOPCSecurityApplicationICMP = `
resource "opc_compute_security_application" "test" {
name = "acc-security-application-tcp-%d"
protocol = "icmp"
icmptype = "echo"
description = "Terraform Acceptance Test"
}
`

View File

@ -0,0 +1,101 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCSecurityAssociation() *schema.Resource {
return &schema.Resource{
Create: resourceOPCSecurityAssociationCreate,
Read: resourceOPCSecurityAssociationRead,
Delete: resourceOPCSecurityAssociationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"vcable": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"seclist": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
func resourceOPCSecurityAssociationCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityAssociations()
name := d.Get("name").(string)
vcable := d.Get("vcable").(string)
seclist := d.Get("seclist").(string)
input := compute.CreateSecurityAssociationInput{
Name: name,
SecList: seclist,
VCable: vcable,
}
info, err := client.CreateSecurityAssociation(&input)
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)
return resourceOPCSecurityAssociationRead(d, meta)
}
func resourceOPCSecurityAssociationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityAssociations()
name := d.Id()
input := compute.GetSecurityAssociationInput{
Name: name,
}
result, err := client.GetSecurityAssociation(&input)
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)
}
d.Set("name", result.Name)
d.Set("seclist", result.SecList)
d.Set("vcable", result.VCable)
return nil
}
func resourceOPCSecurityAssociationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityAssociations()
name := d.Id()
input := compute.DeleteSecurityAssociationInput{
Name: name,
}
if err := client.DeleteSecurityAssociation(&input); err != nil {
return fmt.Errorf("Error deleting Security Association '%s': %v", name, err)
}
return nil
}

View File

@ -0,0 +1,128 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCSecurityAssociation_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccSecurityAssociationBasic, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSecurityAssociationDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckSecurityAssociationExists,
),
},
},
})
}
func TestAccOPCSecurityAssociation_Complete(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccSecurityAssociationComplete, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckSecurityAssociationDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckSecurityAssociationExists,
),
},
},
})
}
func testAccOPCCheckSecurityAssociationExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityAssociations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_association" {
continue
}
input := compute.GetSecurityAssociationInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetSecurityAssociation(&input); err != nil {
return fmt.Errorf("Error retrieving state of Security Association %s: %s", input.Name, err)
}
}
return nil
}
func testAccOPCCheckSecurityAssociationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityAssociations()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_association" {
continue
}
input := compute.GetSecurityAssociationInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetSecurityAssociation(&input); err == nil {
return fmt.Errorf("Security Association %s still exists: %#v", input.Name, info)
}
}
return nil
}
var testAccSecurityAssociationBasic = `
resource "opc_compute_security_list" "test" {
name = "acc-test-sec-ass-sec-list-%d"
policy = "PERMIT"
outbound_cidr_policy = "DENY"
}
resource "opc_compute_instance" "test" {
name = "acc-test-sec-ass-instance-%d"
label = "Security Associations Test Instance"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
}
resource "opc_compute_security_association" "test" {
vcable = "${opc_compute_instance.test.vcable}"
seclist = "${opc_compute_security_list.test.name}"
}
`
var testAccSecurityAssociationComplete = `
resource "opc_compute_security_list" "test" {
name = "acc-test-sec-ass-sec-list-%d"
policy = "PERMIT"
outbound_cidr_policy = "DENY"
}
resource "opc_compute_instance" "test" {
name = "acc-test-sec-ass-instance-%d"
label = "Security Associations Test Instance"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
}
resource "opc_compute_security_association" "test" {
name = "acc-test-sec-ass-%d"
vcable = "${opc_compute_instance.test.vcable}"
seclist = "${opc_compute_security_list.test.name}"
}
`

View File

@ -0,0 +1,135 @@
package opc
import (
"fmt"
"log"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCSecurityIPList() *schema.Resource {
return &schema.Resource{
Create: resourceOPCSecurityIPListCreate,
Read: resourceOPCSecurityIPListRead,
Update: resourceOPCSecurityIPListUpdate,
Delete: resourceOPCSecurityIPListDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"ip_entries": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"description": {
Type: schema.TypeString,
Optional: true,
},
},
}
}
func resourceOPCSecurityIPListCreate(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
client := meta.(*compute.Client).SecurityIPLists()
ipEntries := d.Get("ip_entries").([]interface{})
ipEntryStrings := []string{}
for _, entry := range ipEntries {
ipEntryStrings = append(ipEntryStrings, entry.(string))
}
input := compute.CreateSecurityIPListInput{
Name: d.Get("name").(string),
SecIPEntries: ipEntryStrings,
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
log.Printf("[DEBUG] Creating security IP list with %+v", input)
info, err := client.CreateSecurityIPList(&input)
if err != nil {
return fmt.Errorf("Error creating security IP list %s: %s", input.Name, err)
}
d.SetId(info.Name)
return resourceOPCSecurityIPListRead(d, meta)
}
func resourceOPCSecurityIPListRead(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
client := meta.(*compute.Client).SecurityIPLists()
name := d.Id()
log.Printf("[DEBUG] Reading state of security IP list %s", name)
input := compute.GetSecurityIPListInput{
Name: name,
}
result, err := client.GetSecurityIPList(&input)
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)
d.Set("name", result.Name)
d.Set("ip_entries", result.SecIPEntries)
d.Set("description", result.Description)
return nil
}
func resourceOPCSecurityIPListUpdate(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
client := meta.(*compute.Client).SecurityIPLists()
ipEntries := d.Get("ip_entries").([]interface{})
ipEntryStrings := []string{}
for _, entry := range ipEntries {
ipEntryStrings = append(ipEntryStrings, entry.(string))
}
input := compute.UpdateSecurityIPListInput{
Name: d.Get("name").(string),
SecIPEntries: ipEntryStrings,
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
log.Printf("[DEBUG] Updating security IP list with %+v", input)
info, err := client.UpdateSecurityIPList(&input)
if err != nil {
return fmt.Errorf("Error updating security IP list %s: %s", input.Name, err)
}
d.SetId(info.Name)
return resourceOPCSecurityIPListRead(d, meta)
}
func resourceOPCSecurityIPListDelete(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Resource state: %#v", d.State())
client := meta.(*compute.Client).SecurityIPLists()
name := d.Id()
log.Printf("[DEBUG] Deleting security IP list %s", name)
input := compute.DeleteSecurityIPListInput{
Name: name,
}
if err := client.DeleteSecurityIPList(&input); err != nil {
return fmt.Errorf("Error deleting security IP list %s: %s", name, err)
}
return nil
}

View File

@ -0,0 +1,117 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCSecurityIPList_Basic(t *testing.T) {
listResourceName := "opc_compute_security_ip_list.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityIPListBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityIPListDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityIPListExists,
resource.TestCheckResourceAttr(listResourceName, "ip_entries.0", "192.168.0.1"),
resource.TestCheckResourceAttr(listResourceName, "ip_entries.1", "192.168.0.2"),
),
},
},
})
}
func TestAccOPCSecurityIPList_Updated(t *testing.T) {
listResourceName := "opc_compute_security_ip_list.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityIPListBasic, ri)
config2 := fmt.Sprintf(testAccOPCSecurityIPListUpdated, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityIPListDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityIPListExists,
resource.TestCheckResourceAttr(listResourceName, "description", "Terraform Acceptance Test"),
),
},
{
Config: config2,
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityIPListExists,
resource.TestCheckResourceAttr(listResourceName, "description", ""),
resource.TestCheckResourceAttr(listResourceName, "ip_entries.0", "192.168.0.1"),
resource.TestCheckResourceAttr(listResourceName, "ip_entries.1", "192.168.0.3"),
),
},
},
})
}
func testAccCheckSecurityIPListExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityIPLists()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_ip_list" {
continue
}
input := compute.GetSecurityIPListInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetSecurityIPList(&input); err != nil {
return fmt.Errorf("Error retrieving state of Security IP List %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckSecurityIPListDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityIPLists()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_ip_list" {
continue
}
input := compute.GetSecurityIPListInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetSecurityIPList(&input); err == nil {
return fmt.Errorf("Security IP List %s still exists: %#v", input.Name, info)
}
}
return nil
}
const testAccOPCSecurityIPListBasic = `
resource "opc_compute_security_ip_list" "test" {
name = "acc-security-application-tcp-%d"
ip_entries = ["192.168.0.1", "192.168.0.2"]
description = "Terraform Acceptance Test"
}
`
const testAccOPCSecurityIPListUpdated = `
resource "opc_compute_security_ip_list" "test" {
name = "acc-security-application-tcp-%d"
ip_entries = ["192.168.0.1", "192.168.0.3"]
}
`

View File

@ -0,0 +1,141 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)
func resourceOPCSecurityList() *schema.Resource {
return &schema.Resource{
Create: resourceOPCSecurityListCreate,
Read: resourceOPCSecurityListRead,
Update: resourceOPCSecurityListUpdate,
Delete: resourceOPCSecurityListDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"policy": {
Type: schema.TypeString,
Optional: true,
Default: "deny",
ValidateFunc: validation.StringInSlice([]string{
string(compute.SecurityListPolicyDeny),
string(compute.SecurityListPolicyPermit),
string(compute.SecurityListPolicyReject),
}, true),
},
"outbound_cidr_policy": {
Type: schema.TypeString,
Optional: true,
Default: "permit",
ValidateFunc: validation.StringInSlice([]string{
string(compute.SecurityListPolicyDeny),
string(compute.SecurityListPolicyPermit),
string(compute.SecurityListPolicyReject),
}, true),
},
},
}
}
func resourceOPCSecurityListCreate(d *schema.ResourceData, meta interface{}) error {
name := d.Get("name").(string)
description := d.Get("description").(string)
policy := d.Get("policy").(string)
outboundCIDRPolicy := d.Get("outbound_cidr_policy").(string)
client := meta.(*compute.Client).SecurityLists()
input := compute.CreateSecurityListInput{
Name: name,
Description: description,
Policy: compute.SecurityListPolicy(policy),
OutboundCIDRPolicy: compute.SecurityListPolicy(outboundCIDRPolicy),
}
info, err := client.CreateSecurityList(&input)
if err != nil {
return fmt.Errorf("Error creating security list %s: %s", name, err)
}
d.SetId(info.Name)
return resourceOPCSecurityListRead(d, meta)
}
func resourceOPCSecurityListUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityLists()
name := d.Get("name").(string)
description := d.Get("description").(string)
policy := d.Get("policy").(string)
outboundCIDRPolicy := d.Get("outbound_cidr_policy").(string)
input := compute.UpdateSecurityListInput{
Name: name,
Description: description,
Policy: compute.SecurityListPolicy(policy),
OutboundCIDRPolicy: compute.SecurityListPolicy(outboundCIDRPolicy),
}
_, err := client.UpdateSecurityList(&input)
if err != nil {
return fmt.Errorf("Error updating security list %s: %s", name, err)
}
return resourceOPCSecurityListRead(d, meta)
}
func resourceOPCSecurityListRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityLists()
name := d.Id()
input := compute.GetSecurityListInput{
Name: name,
}
result, err := client.GetSecurityList(&input)
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)
}
d.Set("name", result.Name)
d.Set("description", result.Description)
d.Set("policy", string(result.Policy))
d.Set("outbound_cidr_policy", string(result.OutboundCIDRPolicy))
return nil
}
func resourceOPCSecurityListDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityLists()
name := d.Id()
input := compute.DeleteSecurityListInput{
Name: name,
}
if err := client.DeleteSecurityList(&input); err != nil {
return fmt.Errorf("Error deleting security list %s: %s", name, err)
}
return nil
}

View File

@ -0,0 +1,100 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCSecurityList_basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityListBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityListDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckSecurityListExists,
},
},
})
}
func TestAccOPCSecurityList_complete(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityListComplete, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityListDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: testAccCheckSecurityListExists,
},
},
})
}
func testAccCheckSecurityListExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityLists()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_list" {
continue
}
input := compute.GetSecurityListInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetSecurityList(&input); err != nil {
return fmt.Errorf("Error retrieving state of Security List %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckSecurityListDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityLists()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_list" {
continue
}
input := compute.GetSecurityListInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetSecurityList(&input); err == nil {
return fmt.Errorf("Security List %s still exists: %#v", input.Name, info)
}
}
return nil
}
const testAccOPCSecurityListBasic = `
resource "opc_compute_security_list" "test" {
name = "acc-test-sec-list-%d"
policy = "PERMIT"
outbound_cidr_policy = "DENY"
}
`
const testAccOPCSecurityListComplete = `
resource "opc_compute_security_list" "test" {
name = "acc-test-sec-list-%d"
description = "Acceptance Test Security List Complete"
policy = "PERMIT"
outbound_cidr_policy = "DENY"
}
`

View File

@ -0,0 +1,160 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCSecurityProtocol() *schema.Resource {
return &schema.Resource{
Create: resourceOPCSecurityProtocolCreate,
Read: resourceOPCSecurityProtocolRead,
Update: resourceOPCSecurityProtocolUpdate,
Delete: resourceOPCSecurityProtocolDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"dst_ports": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"ip_protocol": {
Type: schema.TypeString,
Optional: true,
Default: string(compute.All),
ValidateFunc: validateIPProtocol,
},
"src_ports": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"tags": tagsForceNewSchema(),
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCSecurityProtocolCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityProtocols()
input := compute.CreateSecurityProtocolInput{
Name: d.Get("name").(string),
IPProtocol: d.Get("ip_protocol").(string),
}
dstPorts := getStringList(d, "dst_ports")
if len(dstPorts) != 0 {
input.DstPortSet = dstPorts
}
srcPorts := getStringList(d, "src_ports")
if len(srcPorts) != 0 {
input.SrcPortSet = srcPorts
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.CreateSecurityProtocol(&input)
if err != nil {
return fmt.Errorf("Error creating Security Protocol: %s", err)
}
d.SetId(info.Name)
return resourceOPCSecurityProtocolRead(d, meta)
}
func resourceOPCSecurityProtocolRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityProtocols()
getInput := compute.GetSecurityProtocolInput{
Name: d.Id(),
}
result, err := client.GetSecurityProtocol(&getInput)
if err != nil {
// Security Protocol does not exist
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading security protocol %s: %s", d.Id(), err)
}
d.Set("name", result.Name)
d.Set("ip_protocol", result.IPProtocol)
d.Set("description", result.Description)
if err := setStringList(d, "dst_ports", result.DstPortSet); err != nil {
return err
}
if err := setStringList(d, "src_ports", result.SrcPortSet); err != nil {
return err
}
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
return nil
}
func resourceOPCSecurityProtocolUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityProtocols()
input := compute.UpdateSecurityProtocolInput{
Name: d.Get("name").(string),
IPProtocol: d.Get("ip_protocol").(string),
}
dstPorts := getStringList(d, "dst_ports")
if len(dstPorts) != 0 {
input.DstPortSet = dstPorts
}
srcPorts := getStringList(d, "src_ports")
if len(srcPorts) != 0 {
input.SrcPortSet = srcPorts
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.UpdateSecurityProtocol(&input)
if err != nil {
return fmt.Errorf("Error updating Security Protocol: %s", err)
}
d.SetId(info.Name)
return resourceOPCSecurityProtocolRead(d, meta)
}
func resourceOPCSecurityProtocolDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityProtocols()
name := d.Id()
input := compute.DeleteSecurityProtocolInput{
Name: name,
}
if err := client.DeleteSecurityProtocol(&input); err != nil {
return fmt.Errorf("Error deleting Security Protocol: %s", err)
}
return nil
}

View File

@ -0,0 +1,153 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCSecurityProtocol_Basic(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityProtocolBasic, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityProtocolDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityProtocolExists,
),
},
},
})
}
func TestAccOPCSecurityProtocol_Complete(t *testing.T) {
protocolResourceName := "opc_compute_security_protocol.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityProtocolComplete, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityProtocolDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityProtocolExists,
resource.TestCheckResourceAttr(protocolResourceName, "description", "Terraform Acceptance Test"),
resource.TestCheckResourceAttr(protocolResourceName, "dst_ports.0", "2025-2030"),
resource.TestCheckResourceAttr(protocolResourceName, "src_ports.0", "3025-3030"),
resource.TestCheckResourceAttr(protocolResourceName, "ip_protocol", "tcp"),
),
},
},
})
}
func TestAccOPCSecurityProtocol_Update(t *testing.T) {
protocolResourceName := "opc_compute_security_protocol.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccOPCSecurityProtocolComplete, ri)
config2 := fmt.Sprintf(testAccOPCSecurityProtocolUpdated, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityProtocolDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityProtocolExists,
resource.TestCheckResourceAttr(protocolResourceName, "description", "Terraform Acceptance Test"),
resource.TestCheckResourceAttr(protocolResourceName, "dst_ports.0", "2025-2030"),
resource.TestCheckResourceAttr(protocolResourceName, "src_ports.0", "3025-3030"),
resource.TestCheckResourceAttr(protocolResourceName, "ip_protocol", "tcp"),
),
},
{
Config: config2,
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityProtocolExists,
resource.TestCheckResourceAttr(protocolResourceName, "description", ""),
resource.TestCheckResourceAttr(protocolResourceName, "dst_ports.1", "2040-2050"),
resource.TestCheckResourceAttr(protocolResourceName, "src_ports.1", "3040-3050"),
resource.TestCheckResourceAttr(protocolResourceName, "ip_protocol", "udp"),
),
},
},
})
}
func testAccCheckSecurityProtocolExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityProtocols()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_protocol" {
continue
}
input := compute.GetSecurityProtocolInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetSecurityProtocol(&input); err != nil {
return fmt.Errorf("Error retrieving state of Security Protocol %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckSecurityProtocolDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityProtocols()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_protocol" {
continue
}
input := compute.GetSecurityProtocolInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetSecurityProtocol(&input); err == nil {
return fmt.Errorf("Security Protocol %s still exists: %#v", input.Name, info)
}
}
return nil
}
const testAccOPCSecurityProtocolBasic = `
resource "opc_compute_security_protocol" "test" {
name = "acc-security-protocol-%d"
description = "Terraform Acceptance Test"
}
`
const testAccOPCSecurityProtocolComplete = `
resource "opc_compute_security_protocol" "test" {
name = "acc-security-protocol-%d"
description = "Terraform Acceptance Test"
dst_ports = ["2025-2030"]
src_ports = ["3025-3030"]
ip_protocol = "tcp"
}
`
const testAccOPCSecurityProtocolUpdated = `
resource "opc_compute_security_protocol" "test" {
name = "acc-security-protocol-%d"
dst_ports = ["2025-2030", "2040-2050"]
src_ports = ["3025-3030", "3040-3050"]
ip_protocol = "udp"
}
`

View File

@ -0,0 +1,231 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCSecurityRule() *schema.Resource {
return &schema.Resource{
Create: resourceOPCSecurityRuleCreate,
Read: resourceOPCSecurityRuleRead,
Update: resourceOPCSecurityRuleUpdate,
Delete: resourceOPCSecurityRuleDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"flow_direction": {
Type: schema.TypeString,
Required: true,
},
"acl": {
Type: schema.TypeString,
Optional: true,
},
"dst_ip_address_prefixes": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"src_ip_address_prefixes": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"security_protocols": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"dst_vnic_set": {
Type: schema.TypeString,
Optional: true,
},
"src_vnic_set": {
Type: schema.TypeString,
Optional: true,
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"tags": tagsOptionalSchema(),
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCSecurityRuleCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityRules()
input := compute.CreateSecurityRuleInput{
Name: d.Get("name").(string),
FlowDirection: d.Get("flow_direction").(string),
Enabled: d.Get("enabled").(bool),
}
if acl, ok := d.GetOk("acl"); ok {
input.ACL = acl.(string)
}
if srcVNicSet, ok := d.GetOk("src_vnic_set"); ok {
input.SrcVnicSet = srcVNicSet.(string)
}
if dstVNicSet, ok := d.GetOk("dst_vnic_set"); ok {
input.DstVnicSet = dstVNicSet.(string)
}
securityProtocols := getStringList(d, "security_protocols")
if len(securityProtocols) != 0 {
input.SecProtocols = securityProtocols
}
srcIPAdressPrefixes := getStringList(d, "src_ip_address_prefixes")
if len(srcIPAdressPrefixes) != 0 {
input.SrcIpAddressPrefixSets = srcIPAdressPrefixes
}
dstIPAdressPrefixes := getStringList(d, "dst_ip_address_prefixes")
if len(dstIPAdressPrefixes) != 0 {
input.DstIpAddressPrefixSets = dstIPAdressPrefixes
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.CreateSecurityRule(&input)
if err != nil {
return fmt.Errorf("Error creating Security Rule: %s", err)
}
d.SetId(info.Name)
return resourceOPCSecurityRuleRead(d, meta)
}
func resourceOPCSecurityRuleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityRules()
getInput := compute.GetSecurityRuleInput{
Name: d.Id(),
}
result, err := client.GetSecurityRule(&getInput)
if err != nil {
// SecurityRule does not exist
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading security rule %s: %s", d.Id(), err)
}
d.Set("name", result.Name)
d.Set("flow_direction", result.FlowDirection)
d.Set("enabled", result.Enabled)
d.Set("acl", result.ACL)
d.Set("src_vnic_set", result.SrcVnicSet)
d.Set("dst_vnic_set", result.DstVnicSet)
d.Set("description", result.Description)
d.Set("uri", result.Uri)
if err := setStringList(d, "security_protocols", result.SecProtocols); err != nil {
return err
}
if err := setStringList(d, "dst_ip_address_prefixes", result.DstIpAddressPrefixSets); err != nil {
return err
}
if err := setStringList(d, "src_ip_address_prefixes", result.SrcIpAddressPrefixSets); err != nil {
return err
}
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
return nil
}
func resourceOPCSecurityRuleUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityRules()
input := compute.UpdateSecurityRuleInput{
Name: d.Get("name").(string),
FlowDirection: d.Get("flow_direction").(string),
Enabled: d.Get("enabled").(bool),
}
if acl, ok := d.GetOk("acl"); ok {
input.ACL = acl.(string)
}
if srcVNicSet, ok := d.GetOk("src_vnic_set"); ok {
input.SrcVnicSet = srcVNicSet.(string)
}
if dstVNicSet, ok := d.GetOk("dst_vnic_set"); ok {
input.DstVnicSet = dstVNicSet.(string)
}
securityProtocols := getStringList(d, "security_protocols")
if len(securityProtocols) != 0 {
input.SecProtocols = securityProtocols
}
srcIPAdressPrefixes := getStringList(d, "src_ip_address_prefixes")
if len(srcIPAdressPrefixes) != 0 {
input.SrcIpAddressPrefixSets = srcIPAdressPrefixes
}
dstIPAdressPrefixes := getStringList(d, "dst_ip_address_prefixes")
if len(dstIPAdressPrefixes) != 0 {
input.DstIpAddressPrefixSets = dstIPAdressPrefixes
}
tags := getStringList(d, "tags")
if len(tags) != 0 {
input.Tags = tags
}
if description, ok := d.GetOk("description"); ok {
input.Description = description.(string)
}
info, err := client.UpdateSecurityRule(&input)
if err != nil {
return fmt.Errorf("Error updating Security Rule: %s", err)
}
d.SetId(info.Name)
return resourceOPCSecurityRuleRead(d, meta)
}
func resourceOPCSecurityRuleDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SecurityRules()
name := d.Id()
input := compute.DeleteSecurityRuleInput{
Name: name,
}
if err := client.DeleteSecurityRule(&input); err != nil {
return fmt.Errorf("Error deleting Security Rule: %s", err)
}
return nil
}

View File

@ -0,0 +1,159 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccOPCSecurityRule_Basic(t *testing.T) {
rInt := acctest.RandInt()
resName := "opc_compute_security_rule.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityRuleDestroy,
Steps: []resource.TestStep{
{
Config: testAccOPCSecurityRuleConfig_Basic(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityRuleExists,
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("testing-security-rule-%d", rInt)),
),
},
{
Config: testAccOPCSecurityRuleConfig_BasicUpdate(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityRuleExists,
resource.TestCheckResourceAttr(resName, "enabled", "false"),
),
},
},
})
}
func TestAccOPCSecurityRule_Full(t *testing.T) {
rInt := acctest.RandInt()
resName := "opc_compute_security_rule.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSecurityRuleDestroy,
Steps: []resource.TestStep{
{
Config: testAccOPCSecurityRuleConfig_Full(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckSecurityRuleExists,
resource.TestCheckResourceAttr(resName, "name", fmt.Sprintf("testing-security-rule-%d", rInt)),
resource.TestCheckResourceAttr(resName, "acl", fmt.Sprintf("test-security-rule-%d", rInt)),
resource.TestCheckResourceAttr(resName, "src_vnic_set", fmt.Sprintf("test-security-rule-src-%d", rInt)),
resource.TestCheckResourceAttr(resName, "dst_vnic_set", fmt.Sprintf("test-security-rule-dst-%d", rInt)),
resource.TestCheckResourceAttr(resName, "dst_ip_address_prefixes.0", fmt.Sprintf("test-security-rule-dst-%d", rInt)),
resource.TestCheckResourceAttr(resName, "src_ip_address_prefixes.0", fmt.Sprintf("test-security-rule-src-%d", rInt)),
resource.TestCheckResourceAttr(resName, "security_protocols.0", fmt.Sprintf("test-security-rule-%d", rInt)),
),
},
},
})
}
func testAccCheckSecurityRuleExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityRules()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_sec_rule" {
continue
}
input := compute.GetSecurityRuleInput{
Name: rs.Primary.Attributes["name"],
}
if _, err := client.GetSecurityRule(&input); err != nil {
return fmt.Errorf("Error retrieving state of Security Rule %s: %s", input.Name, err)
}
}
return nil
}
func testAccCheckSecurityRuleDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).SecurityRules()
for _, rs := range s.RootModule().Resources {
if rs.Type != "opc_compute_security_rule" {
continue
}
input := compute.GetSecurityRuleInput{
Name: rs.Primary.Attributes["name"],
}
if info, err := client.GetSecurityRule(&input); err == nil {
return fmt.Errorf("Security Rule %s still exists: %#v", input.Name, info)
}
}
return nil
}
func testAccOPCSecurityRuleConfig_Basic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_security_rule" "test" {
name = "testing-security-rule-%d"
description = "testing-desc-%d"
flow_direction = "ingress"
}`, rInt, rInt)
}
func testAccOPCSecurityRuleConfig_BasicUpdate(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_security_rule" "test" {
name = "testing-security-rule-%d"
description = "testing-desc-%d"
flow_direction = "egress"
enabled = false
}`, rInt, rInt)
}
func testAccOPCSecurityRuleConfig_Full(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_acl" "test" {
name = "test-security-rule-%d"
}
resource "opc_compute_vnic_set" "src" {
name = "test-security-rule-src-%d"
}
resource "opc_compute_vnic_set" "dst" {
name = "test-security-rule-dst-%d"
}
resource "opc_compute_security_protocol" "test" {
name = "test-security-rule-%d"
}
resource "opc_compute_ip_address_prefix_set" "src" {
name = "test-security-rule-src-%d"
}
resource "opc_compute_ip_address_prefix_set" "dst" {
name = "test-security-rule-dst-%d"
}
resource "opc_compute_security_rule" "test" {
name = "testing-security-rule-%d"
description = "testing-desc-%d"
flow_direction = "ingress"
acl = "${opc_compute_acl.test.name}"
src_vnic_set = "${opc_compute_vnic_set.src.name}"
dst_vnic_set = "${opc_compute_vnic_set.dst.name}"
dst_ip_address_prefixes = ["${opc_compute_ip_address_prefix_set.dst.name}"]
src_ip_address_prefixes = ["${opc_compute_ip_address_prefix_set.src.name}"]
security_protocols = ["${opc_compute_security_protocol.test.name}"]
}`, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt)
}

View File

@ -0,0 +1,118 @@
package opc
import (
"fmt"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCSSHKey() *schema.Resource {
return &schema.Resource{
Create: resourceOPCSSHKeyCreate,
Read: resourceOPCSSHKeyRead,
Update: resourceOPCSSHKeyUpdate,
Delete: resourceOPCSSHKeyDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"key": {
Type: schema.TypeString,
Required: true,
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
},
}
}
func resourceOPCSSHKeyCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SSHKeys()
name := d.Get("name").(string)
key := d.Get("key").(string)
enabled := d.Get("enabled").(bool)
input := compute.CreateSSHKeyInput{
Name: name,
Key: key,
Enabled: enabled,
}
info, err := client.CreateSSHKey(&input)
if err != nil {
return fmt.Errorf("Error creating ssh key %s: %s", name, err)
}
d.SetId(info.Name)
return resourceOPCSSHKeyRead(d, meta)
}
func resourceOPCSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SSHKeys()
name := d.Get("name").(string)
key := d.Get("key").(string)
enabled := d.Get("enabled").(bool)
input := compute.UpdateSSHKeyInput{
Name: name,
Key: key,
Enabled: enabled,
}
_, err := client.UpdateSSHKey(&input)
if err != nil {
return fmt.Errorf("Error updating ssh key %s: %s", name, err)
}
return resourceOPCSSHKeyRead(d, meta)
}
func resourceOPCSSHKeyRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SSHKeys()
name := d.Id()
input := compute.GetSSHKeyInput{
Name: name,
}
result, err := client.GetSSHKey(&input)
if err != nil {
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading ssh key %s: %s", name, err)
}
d.Set("name", result.Name)
d.Set("key", result.Key)
d.Set("enabled", result.Enabled)
return nil
}
func resourceOPCSSHKeyDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).SSHKeys()
name := d.Id()
input := compute.DeleteSSHKeyInput{
Name: name,
}
if err := client.DeleteSSHKey(&input); err != nil {
return fmt.Errorf("Error deleting ssh key %s: %s", name, err)
}
return nil
}

Some files were not shown because too many files have changed in this diff Show More