terraform/vendor/github.com/terraform-providers/terraform-provider-openstack/openstack/resource_openstack_vpnaas_i...

438 lines
12 KiB
Go

package openstack
import (
"fmt"
"log"
"time"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/vpnaas/ipsecpolicies"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceIPSecPolicyV2() *schema.Resource {
return &schema.Resource{
Create: resourceIPSecPolicyV2Create,
Read: resourceIPSecPolicyV2Read,
Update: resourceIPSecPolicyV2Update,
Delete: resourceIPSecPolicyV2Delete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(10 * time.Minute),
},
Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
},
"auth_algorithm": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"encapsulation_mode": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"pfs": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"encryption_algorithm": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"transform_protocol": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"lifetime": {
Type: schema.TypeSet,
Computed: true,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"units": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"value": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
},
},
},
},
"value_specs": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},
},
}
}
func resourceIPSecPolicyV2Create(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
encapsulationMode := resourceIPSecPolicyV2EncapsulationMode(d.Get("encapsulation_mode").(string))
authAlgorithm := resourceIPSecPolicyV2AuthAlgorithm(d.Get("auth_algorithm").(string))
encryptionAlgorithm := resourceIPSecPolicyV2EncryptionAlgorithm(d.Get("encryption_algorithm").(string))
pfs := resourceIPSecPolicyV2PFS(d.Get("pfs").(string))
transformProtocol := resourceIPSecPolicyV2TransformProtocol(d.Get("transform_protocol").(string))
lifetime := resourceIPSecPolicyV2LifetimeCreateOpts(d.Get("lifetime").(*schema.Set))
opts := IPSecPolicyCreateOpts{
ipsecpolicies.CreateOpts{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
TenantID: d.Get("tenant_id").(string),
EncapsulationMode: encapsulationMode,
AuthAlgorithm: authAlgorithm,
EncryptionAlgorithm: encryptionAlgorithm,
PFS: pfs,
TransformProtocol: transformProtocol,
Lifetime: &lifetime,
},
MapValueSpecs(d),
}
log.Printf("[DEBUG] Create IPSec policy: %#v", opts)
policy, err := ipsecpolicies.Create(networkingClient, opts).Extract()
if err != nil {
return err
}
stateConf := &resource.StateChangeConf{
Pending: []string{"PENDING_CREATE"},
Target: []string{"ACTIVE"},
Refresh: waitForIPSecPolicyCreation(networkingClient, policy.ID),
Timeout: d.Timeout(schema.TimeoutCreate),
Delay: 0,
MinTimeout: 2 * time.Second,
}
_, err = stateConf.WaitForState()
log.Printf("[DEBUG] IPSec policy created: %#v", policy)
d.SetId(policy.ID)
return resourceIPSecPolicyV2Read(d, meta)
}
func resourceIPSecPolicyV2Read(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Retrieve information about IPSec policy: %s", d.Id())
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
policy, err := ipsecpolicies.Get(networkingClient, d.Id()).Extract()
if err != nil {
return CheckDeleted(d, err, "IPSec policy")
}
log.Printf("[DEBUG] Read OpenStack IPSec policy %s: %#v", d.Id(), policy)
d.Set("name", policy.Name)
d.Set("description", policy.Description)
d.Set("tenant_id", policy.TenantID)
d.Set("encapsulation_mode", policy.EncapsulationMode)
d.Set("encryption_algorithm", policy.EncryptionAlgorithm)
d.Set("transform_protocol", policy.TransformProtocol)
d.Set("pfs", policy.PFS)
d.Set("auth_algorithm", policy.AuthAlgorithm)
d.Set("region", GetRegion(d, config))
// Set the lifetime
var lifetimeMap map[string]interface{}
lifetimeMap = make(map[string]interface{})
lifetimeMap["units"] = policy.Lifetime.Units
lifetimeMap["value"] = policy.Lifetime.Value
var lifetime []map[string]interface{}
lifetime = append(lifetime, lifetimeMap)
if err := d.Set("lifetime", &lifetime); err != nil {
log.Printf("[WARN] unable to set IPSec policy lifetime")
}
return nil
}
func resourceIPSecPolicyV2Update(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
var hasChange bool
opts := ipsecpolicies.UpdateOpts{}
if d.HasChange("name") {
name := d.Get("name").(string)
opts.Name = &name
hasChange = true
}
if d.HasChange("description") {
description := d.Get("description").(string)
opts.Description = &description
hasChange = true
}
if d.HasChange("auth_algorithm") {
opts.AuthAlgorithm = resourceIPSecPolicyV2AuthAlgorithm(d.Get("auth_algorithm").(string))
hasChange = true
}
if d.HasChange("encryption_algorithm") {
opts.EncryptionAlgorithm = resourceIPSecPolicyV2EncryptionAlgorithm(d.Get("encryption_algorithm").(string))
hasChange = true
}
if d.HasChange("transform_protocol") {
opts.TransformProtocol = resourceIPSecPolicyV2TransformProtocol(d.Get("transform_protocol").(string))
hasChange = true
}
if d.HasChange("pfs") {
opts.PFS = resourceIPSecPolicyV2PFS(d.Get("pfs").(string))
hasChange = true
}
if d.HasChange("encapsulation_mode") {
opts.EncapsulationMode = resourceIPSecPolicyV2EncapsulationMode(d.Get("encapsulation_mode").(string))
hasChange = true
}
if d.HasChange("lifetime") {
lifetime := resourceIPSecPolicyV2LifetimeUpdateOpts(d.Get("lifetime").(*schema.Set))
opts.Lifetime = &lifetime
hasChange = true
}
log.Printf("[DEBUG] Updating IPSec policy with id %s: %#v", d.Id(), opts)
if hasChange {
_, err = ipsecpolicies.Update(networkingClient, d.Id(), opts).Extract()
if err != nil {
return err
}
stateConf := &resource.StateChangeConf{
Pending: []string{"PENDING_UPDATE"},
Target: []string{"ACTIVE"},
Refresh: waitForIPSecPolicyUpdate(networkingClient, d.Id()),
Timeout: d.Timeout(schema.TimeoutCreate),
Delay: 0,
MinTimeout: 2 * time.Second,
}
if _, err = stateConf.WaitForState(); err != nil {
return err
}
}
return resourceIPSecPolicyV2Read(d, meta)
}
func resourceIPSecPolicyV2Delete(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Destroy IPSec policy: %s", d.Id())
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
stateConf := &resource.StateChangeConf{
Pending: []string{"ACTIVE"},
Target: []string{"DELETED"},
Refresh: waitForIPSecPolicyDeletion(networkingClient, d.Id()),
Timeout: d.Timeout(schema.TimeoutCreate),
Delay: 0,
MinTimeout: 2 * time.Second,
}
if _, err = stateConf.WaitForState(); err != nil {
return err
}
return nil
}
func waitForIPSecPolicyDeletion(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
err := ipsecpolicies.Delete(networkingClient, id).Err
if err == nil {
return "", "DELETED", nil
}
if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok {
if errCode.Actual == 409 {
return nil, "ACTIVE", nil
}
}
return nil, "ACTIVE", err
}
}
func waitForIPSecPolicyCreation(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
policy, err := ipsecpolicies.Get(networkingClient, id).Extract()
if err != nil {
return "", "PENDING_CREATE", nil
}
return policy, "ACTIVE", nil
}
}
func waitForIPSecPolicyUpdate(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
policy, err := ipsecpolicies.Get(networkingClient, id).Extract()
if err != nil {
return "", "PENDING_UPDATE", nil
}
return policy, "ACTIVE", nil
}
}
func resourceIPSecPolicyV2TransformProtocol(trp string) ipsecpolicies.TransformProtocol {
var protocol ipsecpolicies.TransformProtocol
switch trp {
case "esp":
protocol = ipsecpolicies.TransformProtocolESP
case "ah":
protocol = ipsecpolicies.TransformProtocolAH
case "ah-esp":
protocol = ipsecpolicies.TransformProtocolAHESP
}
return protocol
}
func resourceIPSecPolicyV2PFS(pfsString string) ipsecpolicies.PFS {
var pfs ipsecpolicies.PFS
switch pfsString {
case "group2":
pfs = ipsecpolicies.PFSGroup2
case "group5":
pfs = ipsecpolicies.PFSGroup5
case "group14":
pfs = ipsecpolicies.PFSGroup14
}
return pfs
}
func resourceIPSecPolicyV2EncryptionAlgorithm(encryptionAlgo string) ipsecpolicies.EncryptionAlgorithm {
var alg ipsecpolicies.EncryptionAlgorithm
switch encryptionAlgo {
case "3des":
alg = ipsecpolicies.EncryptionAlgorithm3DES
case "aes-128":
alg = ipsecpolicies.EncryptionAlgorithmAES128
case "aes-256":
alg = ipsecpolicies.EncryptionAlgorithmAES256
case "aes-192":
alg = ipsecpolicies.EncryptionAlgorithmAES192
}
return alg
}
func resourceIPSecPolicyV2AuthAlgorithm(authAlgo string) ipsecpolicies.AuthAlgorithm {
var alg ipsecpolicies.AuthAlgorithm
switch authAlgo {
case "sha1":
alg = ipsecpolicies.AuthAlgorithmSHA1
case "sha256":
alg = ipsecpolicies.AuthAlgorithmSHA256
case "sha384":
alg = ipsecpolicies.AuthAlgorithmSHA384
case "sha512":
alg = ipsecpolicies.AuthAlgorithmSHA512
}
return alg
}
func resourceIPSecPolicyV2EncapsulationMode(encMode string) ipsecpolicies.EncapsulationMode {
var mode ipsecpolicies.EncapsulationMode
switch encMode {
case "tunnel":
mode = ipsecpolicies.EncapsulationModeTunnel
case "transport":
mode = ipsecpolicies.EncapsulationModeTransport
}
return mode
}
func resourceIPSecPolicyV2LifetimeCreateOpts(d *schema.Set) ipsecpolicies.LifetimeCreateOpts {
lifetime := ipsecpolicies.LifetimeCreateOpts{}
rawPairs := d.List()
for _, raw := range rawPairs {
rawMap := raw.(map[string]interface{})
lifetime.Units = resourceIPSecPolicyV2Unit(rawMap["units"].(string))
value := rawMap["value"].(int)
lifetime.Value = value
}
return lifetime
}
func resourceIPSecPolicyV2Unit(units string) ipsecpolicies.Unit {
var unit ipsecpolicies.Unit
switch units {
case "seconds":
unit = ipsecpolicies.UnitSeconds
case "kilobytes":
unit = ipsecpolicies.UnitKilobytes
}
return unit
}
func resourceIPSecPolicyV2LifetimeUpdateOpts(d *schema.Set) ipsecpolicies.LifetimeUpdateOpts {
lifetimeUpdateOpts := ipsecpolicies.LifetimeUpdateOpts{}
rawPairs := d.List()
for _, raw := range rawPairs {
rawMap := raw.(map[string]interface{})
lifetimeUpdateOpts.Units = resourceIPSecPolicyV2Unit(rawMap["units"].(string))
value := rawMap["value"].(int)
lifetimeUpdateOpts.Value = value
}
return lifetimeUpdateOpts
}