Skip to content

Commit

Permalink
Vpnaas: Create IPSec Policy (#768)
Browse files Browse the repository at this point in the history
* Added requests.go file and necessary methods for ipsecpolicy creation

* created results file

* Updated results description

* Created urls.go file

* Put correct root and resource urls

* Added unit test for ipsecpolicy creation. Also renamed LifetimeName to LifetimeValue

* Formatted inline comments, put LifetimeCreateOpts and Lifetime into their own structs

* Added acceptance test, formatted struct fields

* Added doc.go file

* Added comparison between expected and actual struct to tests

* Removed Lifetime prefix before Units and Value fields. Updated unit test to compare struct instead of fields

* added types to pass into createopts

* Added missing 'id' field to results struct, fixed typo in comment to TransformProtocol

* fixed typo
  • Loading branch information
simonre authored and jtopjian committed Feb 22, 2018
1 parent 94986f2 commit 6c823a6
Show file tree
Hide file tree
Showing 7 changed files with 352 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// +build acceptance networking vpnaas

package vpnaas

import (
"testing"

"github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/acceptance/tools"
)

func TestPolicyCRUD(t *testing.T) {
client, err := clients.NewNetworkV2Client()
if err != nil {
t.Fatalf("Unable to create a network client: %v", err)
}

policy, err := CreateIPSecPolicy(t, client)
if err != nil {
t.Fatalf("Unable to create policy: %v", err)
}

tools.PrintResource(t, policy)
}
22 changes: 22 additions & 0 deletions acceptance/openstack/networking/v2/extensions/vpnaas/vpnaas.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/acceptance/tools"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/vpnaas/ipsecpolicies"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/vpnaas/services"
)

Expand Down Expand Up @@ -44,3 +45,24 @@ func DeleteService(t *testing.T, client *gophercloud.ServiceClient, serviceID st

t.Logf("Service deleted: %s", serviceID)
}

// CreateIPSecPolicy will create an IPSec Policy with a random name and given
// rule. An error will be returned if the rule could not be created.
func CreateIPSecPolicy(t *testing.T, client *gophercloud.ServiceClient) (*ipsecpolicies.Policy, error) {
policyName := tools.RandomString("TESTACC-", 8)

t.Logf("Attempting to create policy %s", policyName)

createOpts := ipsecpolicies.CreateOpts{
Name: policyName,
}

policy, err := ipsecpolicies.Create(client, createOpts).Extract()
if err != nil {
return policy, err
}

t.Logf("Successfully created IPSec policy %s", policyName)

return policy, nil
}
16 changes: 16 additions & 0 deletions openstack/networking/v2/extensions/vpnaas/ipsecpolicies/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
Package ipsecpolicies allows management and retrieval of IPSec Policies in the
OpenStack Networking Service.
Example to Create a Policy
createOpts := ipsecpolicies.CreateOpts{
Name: "IPSecPolicy_1",
}
policy, err := policies.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
*/
package ipsecpolicies
110 changes: 110 additions & 0 deletions openstack/networking/v2/extensions/vpnaas/ipsecpolicies/requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package ipsecpolicies

import "github.com/gophercloud/gophercloud"

type TransformProtocol string
type AuthAlgorithm string
type EncapsulationMode string
type EncryptionAlgorithm string
type PFS string
type Unit string

const (
TransformProtocolESP TransformProtocol = "esp"
TransformProtocolAH TransformProtocol = "ah"
TransformProtocolAHESP TransformProtocol = "ah-esp"
AuthAlgorithmSHA1 AuthAlgorithm = "sha1"
AuthAlgorithmSHA256 AuthAlgorithm = "sha256"
AuthAlgorithmSHA384 AuthAlgorithm = "sha384"
AuthAlgorithmSHA512 AuthAlgorithm = "sha512"
EncryptionAlgorithm3DES EncryptionAlgorithm = "3des"
EncryptionAlgorithmAES128 EncryptionAlgorithm = "aes-128"
EncryptionAlgorithmAES256 EncryptionAlgorithm = "aes-256"
EncryptionAlgorithmAES192 EncryptionAlgorithm = "aes-192"
EncapsulationModeTunnel EncapsulationMode = "tunnel"
EncapsulationModeTransport EncapsulationMode = "transport"
UnitSeconds Unit = "seconds"
UnitKilobytes Unit = "kilobytes"
PFSGroup2 PFS = "group2"
PFSGroup5 PFS = "group5"
PFSGroup14 PFS = "group14"
)

// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToPolicyCreateMap() (map[string]interface{}, error)
}

// CreateOpts contains all the values needed to create a new IPSec policy
type CreateOpts struct {
// TenantID specifies a tenant to own the IPSec policy. The caller must have
// an admin role in order to set this. Otherwise, this field is left unset
// and the caller will be the owner.
TenantID string `json:"tenant_id,omitempty"`

// Description is the human readable description of the policy.
Description string `json:"description,omitempty"`

// Name is the human readable name of the policy.
// Does not have to be unique.
Name string `json:"name,omitempty"`

// AuthAlgorithm is the authentication hash algorithm.
// Valid values are sha1, sha256, sha384, sha512.
// The default is sha1.
AuthAlgorithm AuthAlgorithm `json:"auth_algorithm,omitempty"`

// EncapsulationMode is the encapsulation mode.
// A valid value is tunnel or transport.
// Default is tunnel.
EncapsulationMode EncapsulationMode `json:"encapsulation_mode,omitempty"`

// EncryptionAlgorithm is the encryption algorithm.
// A valid value is 3des, aes-128, aes-192, aes-256, and so on.
// Default is aes-128.
EncryptionAlgorithm EncryptionAlgorithm `json:"encryption_algorithm,omitempty"`

// PFS is the Perfect forward secrecy mode.
// A valid value is Group2, Group5, Group14, and so on.
// Default is Group5.
PFS PFS `json:"pfs,omitempty"`

// TransformProtocol is the transform protocol.
// A valid value is ESP, AH, or AH- ESP.
// Default is ESP.
TransformProtocol TransformProtocol `json:"transform_protocol,omitempty"`

//Lifetime is the lifetime of the security association
Lifetime *LifetimeCreateOpts `json:"lifetime,omitempty"`
}

// The lifetime consists of a unit and integer value
// You can omit either the unit or value portion of the lifetime
type LifetimeCreateOpts struct {
// Units is the units for the lifetime of the security association
// Default unit is seconds
Units Unit `json:"units,omitempty"`

// The lifetime value.
// Must be a positive integer.
// Default value is 3600.
Value int `json:"value,omitempty"`
}

// ToPolicyCreateMap casts a CreateOpts struct to a map.
func (opts CreateOpts) ToPolicyCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "ipsecpolicy")
}

// Create accepts a CreateOpts struct and uses the values to create a new
// IPSec policy
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
b, err := opts.ToPolicyCreateMap()
if err != nil {
r.Err = err
return
}
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
return
}
67 changes: 67 additions & 0 deletions openstack/networking/v2/extensions/vpnaas/ipsecpolicies/results.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package ipsecpolicies

import (
"github.com/gophercloud/gophercloud"
)

// Policy is an IPSec Policy
type Policy struct {
// TenantID is the ID of the project
TenantID string `json:"tenant_id"`

// Description is the human readable description of the policy
Description string `json:"description"`

// Name is the human readable name of the policy
Name string `json:"name"`

// AuthAlgorithm is the authentication hash algorithm
AuthAlgorithm string `json:"auth_algorithm"`

// EncapsulationMode is the encapsulation mode
EncapsulationMode string `json:"encapsulation_mode"`

// EncryptionAlgorithm is the encryption algorithm
EncryptionAlgorithm string `json:"encryption_algorithm"`

// PFS is the Perfect forward secrecy (PFS) mode
PFS string `json:"pfs"`

// TransformProtocol is the transform protocol
TransformProtocol string `json:"transform_protocol"`

// Lifetime is the lifetime of the security association
Lifetime Lifetime `json:"lifetime"`

// ID is the ID of the policy
ID string `json:"id"`
}

type Lifetime struct {
// Units is the unit for the lifetime
// Default is seconds
Units string `json:"units"`

// Value is the lifetime
// Default is 3600
Value int `json:"value"`
}

type commonResult struct {
gophercloud.Result
}

// Extract is a function that accepts a result and extracts an IPSec Policy.
func (r commonResult) Extract() (*Policy, error) {
var s struct {
Policy *Policy `json:"ipsecpolicy"`
}
err := r.ExtractInto(&s)
return s.Policy, err
}

// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Policy.
type CreateResult struct {
commonResult
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package testing

import (
"fmt"
"net/http"
"testing"

fake "github.com/gophercloud/gophercloud/openstack/networking/v2/common"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/vpnaas/ipsecpolicies"
th "github.com/gophercloud/gophercloud/testhelper"
)

func TestCreate(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

th.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "POST")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "Content-Type", "application/json")
th.TestHeader(t, r, "Accept", "application/json")
th.TestJSONRequest(t, r, `
{
"ipsecpolicy": {
"name": "ipsecpolicy1",
"transform_protocol": "esp",
"auth_algorithm": "sha1",
"encapsulation_mode": "tunnel",
"encryption_algorithm": "aes-128",
"pfs": "group5",
"lifetime": {
"units": "seconds",
"value": 7200
},
"tenant_id": "b4eedccc6fb74fa8a7ad6b08382b852b"
}
} `)

w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)

fmt.Fprintf(w, `
{
"ipsecpolicy": {
"name": "ipsecpolicy1",
"transform_protocol": "esp",
"auth_algorithm": "sha1",
"encapsulation_mode": "tunnel",
"encryption_algorithm": "aes-128",
"pfs": "group5",
"tenant_id": "b4eedccc6fb74fa8a7ad6b08382b852b",
"lifetime": {
"units": "seconds",
"value": 7200
},
"id": "5291b189-fd84-46e5-84bd-78f40c05d69c",
"description": ""
}
}
`)
})

lifetime := ipsecpolicies.LifetimeCreateOpts{
Units: ipsecpolicies.UnitSeconds,
Value: 7200,
}
options := ipsecpolicies.CreateOpts{
TenantID: "b4eedccc6fb74fa8a7ad6b08382b852b",
Name: "ipsecpolicy1",
TransformProtocol: ipsecpolicies.TransformProtocolESP,
AuthAlgorithm: ipsecpolicies.AuthAlgorithmSHA1,
EncapsulationMode: ipsecpolicies.EncapsulationModeTunnel,
EncryptionAlgorithm: ipsecpolicies.EncryptionAlgorithmAES128,
PFS: ipsecpolicies.PFSGroup5,
Lifetime: &lifetime,
Description: "",
}
actual, err := ipsecpolicies.Create(fake.ServiceClient(), options).Extract()
th.AssertNoErr(t, err)
expectedLifetime := ipsecpolicies.Lifetime{
Units: "seconds",
Value: 7200,
}
expected := ipsecpolicies.Policy{
TenantID: "b4eedccc6fb74fa8a7ad6b08382b852b",
Name: "ipsecpolicy1",
TransformProtocol: "esp",
AuthAlgorithm: "sha1",
EncapsulationMode: "tunnel",
EncryptionAlgorithm: "aes-128",
PFS: "group5",
Description: "",
Lifetime: expectedLifetime,
ID: "5291b189-fd84-46e5-84bd-78f40c05d69c",
}
th.AssertDeepEquals(t, expected, *actual)
}
16 changes: 16 additions & 0 deletions openstack/networking/v2/extensions/vpnaas/ipsecpolicies/urls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ipsecpolicies

import "github.com/gophercloud/gophercloud"

const (
rootPath = "vpn"
resourcePath = "ipsecpolicies"
)

func rootURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL(rootPath, resourcePath)
}

func resourceURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL(rootPath, resourcePath, id)
}

0 comments on commit 6c823a6

Please sign in to comment.