forked from gophercloud/gophercloud
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LBaaS v2 l7 support: create l7policy
For gophercloud#832 L7policy functionality in Octavia is backward compatible with Neutron-LBaaS. Octavia L7 policy create API: https://developer.openstack.org/api-ref/load-balancer/v2/index.html#create-an-l7-policy
- Loading branch information
1 parent
35000af
commit e8992e1
Showing
7 changed files
with
356 additions
and
0 deletions.
There are no files selected for viewing
19 changes: 19 additions & 0 deletions
19
openstack/networking/v2/extensions/lbaas_v2/l7policies/doc.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
Package l7policies provides information and interaction with L7Policies and | ||
Rules of the LBaaS v2 extension for the OpenStack Networking service. | ||
Example to Create a L7Policy | ||
createOpts := l7policies.CreateOpts{ | ||
Name: "redirect-example.com", | ||
ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d", | ||
Action: l7policies.ActionRedirectToURL, | ||
RedirectURL: "http://www.example.com", | ||
} | ||
l7policy, err := l7policies.Create(networkClient, createOpts).Extract() | ||
if err != nil { | ||
panic(err) | ||
} | ||
*/ | ||
package l7policies |
84 changes: 84 additions & 0 deletions
84
openstack/networking/v2/extensions/lbaas_v2/l7policies/requests.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package l7policies | ||
|
||
import ( | ||
"github.com/gophercloud/gophercloud" | ||
) | ||
|
||
// CreateOptsBuilder allows extensions to add additional parameters to the | ||
// Create request. | ||
type CreateOptsBuilder interface { | ||
ToL7PolicyCreateMap() (map[string]interface{}, error) | ||
} | ||
|
||
type Action string | ||
type RuleType string | ||
type CompareType string | ||
|
||
const ( | ||
ActionRedirectToPool Action = "REDIRECT_TO_POOL" | ||
ActionRedirectToURL Action = "REDIRECT_TO_URL" | ||
ActionReject Action = "REJECT" | ||
|
||
TypeCookie RuleType = "COOKIE" | ||
TypeFileType RuleType = "FILE_TYPE" | ||
TypeHeader RuleType = "HEADER" | ||
TypeHostName RuleType = "HOST_NAME" | ||
TypePath RuleType = "PATH" | ||
|
||
CompareTypeContains CompareType = "CONTAINS" | ||
CompareTypeEndWith CompareType = "ENDS_WITH" | ||
CompareTypeEqual CompareType = "EQUAL_TO" | ||
CompareTypeRegex CompareType = "REGEX" | ||
CompareTypeStartWith CompareType = "STARTS_WITH" | ||
) | ||
|
||
// CreateOpts is the common options struct used in this package's Create | ||
// operation. | ||
type CreateOpts struct { | ||
// Name of the L7 policy. | ||
Name string `json:"name,omitempty"` | ||
|
||
// The ID of the listener. | ||
ListenerID string `json:"listener_id" required:"true"` | ||
|
||
// The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT. | ||
Action Action `json:"action" required:"true"` | ||
|
||
// The position of this policy on the listener. | ||
Position int32 `json:"position,omitempty"` | ||
|
||
// A human-readable description for the resource. | ||
Description string `json:"description,omitempty"` | ||
|
||
// TenantID is the UUID of the project who owns the L7 policy in neutron-lbaas. | ||
// Only administrative users can specify a project UUID other than their own. | ||
TenantID string `json:"tenant_id,omitempty"` | ||
|
||
// ProjectID is the UUID of the project who owns the L7 policy in octavia. | ||
// Only administrative users can specify a project UUID other than their own. | ||
ProjectID string `json:"project_id,omitempty"` | ||
|
||
// Requests matching this policy will be redirected to the pool with this ID. | ||
// Only valid if action is REDIRECT_TO_POOL. | ||
RedirectPoolID string `json:"redirect_pool_id,omitempty" xor:"RedirectURL"` | ||
|
||
// Requests matching this policy will be redirected to this URL. | ||
// Only valid if action is REDIRECT_TO_URL. | ||
RedirectURL string `json:"redirect_url,omitempty" xor:"RedirectPoolID"` | ||
} | ||
|
||
// ToL7PolicyCreateMap builds a request body from CreateOpts. | ||
func (opts CreateOpts) ToL7PolicyCreateMap() (map[string]interface{}, error) { | ||
return gophercloud.BuildRequestBody(opts, "l7policy") | ||
} | ||
|
||
// Create accepts a CreateOpts struct and uses the values to create a new l7policy. | ||
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { | ||
b, err := opts.ToL7PolicyCreateMap() | ||
if err != nil { | ||
r.Err = err | ||
return | ||
} | ||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil) | ||
return | ||
} |
108 changes: 108 additions & 0 deletions
108
openstack/networking/v2/extensions/lbaas_v2/l7policies/results.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package l7policies | ||
|
||
import ( | ||
"github.com/gophercloud/gophercloud" | ||
) | ||
|
||
// L7Policy is a collection of L7 rules associated with a Listener, and which | ||
// may also have an association to a back-end pool. | ||
type L7Policy struct { | ||
// The unique ID for the L7 policy. | ||
ID string `json:"id"` | ||
|
||
// Name of the L7 policy. | ||
Name string `json:"name"` | ||
|
||
// The ID of the listener. | ||
ListenerID string `json:"listener_id"` | ||
|
||
// The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT. | ||
Action Action `json:"action"` | ||
|
||
// The position of this policy on the listener. | ||
Position int `json:"position"` | ||
|
||
// A human-readable description for the resource. | ||
Description string `json:"description"` | ||
|
||
// TenantID is the UUID of the project who owns the L7 policy in neutron-lbaas. | ||
// Only administrative users can specify a project UUID other than their own. | ||
TenantID string `json:"tenant_id"` | ||
|
||
// ProjectID is the UUID of the project who owns the L7 policy in octavia. | ||
// Only administrative users can specify a project UUID other than their own. | ||
ProjectID string `json:"project_id"` | ||
|
||
// Requests matching this policy will be redirected to the pool with this ID. | ||
// Only valid if action is REDIRECT_TO_POOL. | ||
RedirectPoolID string `json:"redirect_pool_id"` | ||
|
||
// Requests matching this policy will be redirected to this URL. | ||
// Only valid if action is REDIRECT_TO_URL. | ||
RedirectURL string `json:"redirect_url"` | ||
|
||
// The administrative state of the L7 policy, which is up (true) or down (false). | ||
AdminStateUp bool `json:"admin_state_up"` | ||
|
||
// The operating status of the L7 policy. This value is ONLINE or OFFLINE. | ||
OperatingStatus string `json:"operating_status"` | ||
|
||
// The provisioning status of the L7 policy. | ||
// This value is ACTIVE, PENDING_CREATE or ERROR. | ||
ProvisioningStatus string `json:"provisioning_status"` | ||
|
||
// Rules are List of associated L7 rule IDs. | ||
Rules []Rule `json:"rules"` | ||
} | ||
|
||
// Rule represents layer 7 load balancing rule. | ||
type Rule struct { | ||
// The unique ID for the L7 rule. | ||
ID string `json:"id"` | ||
|
||
// The L7 rule type. One of COOKIE, FILE_TYPE, HEADER, HOST_NAME, or PATH. | ||
RuleType RuleType `json:"type"` | ||
|
||
// The comparison type for the L7 rule. One of CONTAINS, ENDS_WITH, EQUAL_TO, REGEX, or STARTS_WITH. | ||
CompareType CompareType `json:"compare_type"` | ||
|
||
// The value to use for the comparison. For example, the file type to compare. | ||
Value string `json:"value"` | ||
|
||
// TenantID is the UUID of the project who owns the rule in neutron-lbaas. | ||
// Only administrative users can specify a project UUID other than their own. | ||
TenantID string `json:"tenant_id"` | ||
|
||
// ProjectID is the UUID of the project who owns the rule in octavia. | ||
// Only administrative users can specify a project UUID other than their own. | ||
ProjectID string `json:"project_id"` | ||
|
||
// The key to use for the comparison. For example, the name of the cookie to evaluate. | ||
Key string `json:"key"` | ||
|
||
// When true the logic of the rule is inverted. For example, with invert true, | ||
// equal to would become not equal to. Default is false. | ||
Invert bool `json:"invert"` | ||
|
||
// The administrative state of the L7 rule, which is up (true) or down (false). | ||
AdminStateUp bool `json:"admin_state_up"` | ||
} | ||
|
||
type commonResult struct { | ||
gophercloud.Result | ||
} | ||
|
||
// Extract is a function that accepts a result and extracts a l7policy. | ||
func (r commonResult) Extract() (*L7Policy, error) { | ||
var s struct { | ||
L7Policy *L7Policy `json:"l7policy"` | ||
} | ||
err := r.ExtractInto(&s) | ||
return s.L7Policy, err | ||
} | ||
|
||
// CreateResult represents the result of a Create operation. Call its Extract | ||
// method to interpret the result as a L7Policy. | ||
type CreateResult struct { | ||
commonResult | ||
} |
2 changes: 2 additions & 0 deletions
2
openstack/networking/v2/extensions/lbaas_v2/l7policies/testing/doc.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// l7policies unit tests | ||
package testing |
78 changes: 78 additions & 0 deletions
78
openstack/networking/v2/extensions/lbaas_v2/l7policies/testing/fixtures.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package testing | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies" | ||
th "github.com/gophercloud/gophercloud/testhelper" | ||
"github.com/gophercloud/gophercloud/testhelper/client" | ||
) | ||
|
||
// SingleL7PolicyBody is the canned body of a Get request on an existing l7policy. | ||
const SingleL7PolicyBody = ` | ||
{ | ||
"l7policy": { | ||
"listener_id": "023f2e34-7806-443b-bfae-16c324569a3d", | ||
"description": "Redirect requests to example.com", | ||
"admin_state_up": true, | ||
"created_at": "2017-06-24T23:25:14", | ||
"provisioning_status": "ACTIVE", | ||
"updated_at": "2017-06-24T23:30:05", | ||
"redirect_pool_id": null, | ||
"redirect_url": "http://www.example.com", | ||
"action": "REDIRECT_TO_URL", | ||
"position": 1, | ||
"project_id": "e3cd678b11784734bc366148aa37580e", | ||
"id": "8a1412f0-4c32-4257-8b07-af4770b604fd", | ||
"operating_status": "ONLINE", | ||
"name": "redirect-example.com", | ||
"rules": [ | ||
{ | ||
"id": "efd6a3f8-73bf-47f0-8ae6-503ebda57372" | ||
} | ||
] | ||
} | ||
} | ||
` | ||
|
||
var ( | ||
L7PolicyToURL = l7policies.L7Policy{ | ||
ID: "8a1412f0-4c32-4257-8b07-af4770b604fd", | ||
Name: "redirect-example.com", | ||
ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d", | ||
Action: l7policies.ActionRedirectToURL, | ||
Position: 1, | ||
Description: "Redirect requests to example.com", | ||
ProjectID: "e3cd678b11784734bc366148aa37580e", | ||
RedirectPoolID: "", | ||
RedirectURL: "http://www.example.com", | ||
AdminStateUp: true, | ||
ProvisioningStatus: "ACTIVE", | ||
OperatingStatus: "ONLINE", | ||
Rules: []l7policies.Rule{{ID: "efd6a3f8-73bf-47f0-8ae6-503ebda57372"}}, | ||
} | ||
) | ||
|
||
// HandleL7PolicyCreationSuccessfully sets up the test server to respond to a l7policy creation request | ||
// with a given response. | ||
func HandleL7PolicyCreationSuccessfully(t *testing.T, response string) { | ||
th.Mux.HandleFunc("/v2.0/lbaas/l7policies", func(w http.ResponseWriter, r *http.Request) { | ||
th.TestMethod(t, r, "POST") | ||
th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||
th.TestJSONRequest(t, r, `{ | ||
"l7policy": { | ||
"description": "Redirect requests to example.com", | ||
"listener_id": "023f2e34-7806-443b-bfae-16c324569a3d", | ||
"redirect_url": "http://www.example.com", | ||
"name": "redirect-example.com", | ||
"action": "REDIRECT_TO_URL" | ||
} | ||
}`) | ||
|
||
w.WriteHeader(http.StatusAccepted) | ||
w.Header().Add("Content-Type", "application/json") | ||
fmt.Fprintf(w, response) | ||
}) | ||
} |
53 changes: 53 additions & 0 deletions
53
openstack/networking/v2/extensions/lbaas_v2/l7policies/testing/requests_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package testing | ||
|
||
import ( | ||
"testing" | ||
|
||
fake "github.com/gophercloud/gophercloud/openstack/networking/v2/common" | ||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies" | ||
th "github.com/gophercloud/gophercloud/testhelper" | ||
) | ||
|
||
func TestCreateL7Policy(t *testing.T) { | ||
th.SetupHTTP() | ||
defer th.TeardownHTTP() | ||
HandleL7PolicyCreationSuccessfully(t, SingleL7PolicyBody) | ||
|
||
actual, err := l7policies.Create(fake.ServiceClient(), l7policies.CreateOpts{ | ||
Name: "redirect-example.com", | ||
Description: "Redirect requests to example.com", | ||
ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d", | ||
Action: l7policies.ActionRedirectToURL, | ||
RedirectURL: "http://www.example.com", | ||
}).Extract() | ||
|
||
th.AssertNoErr(t, err) | ||
th.CheckDeepEquals(t, L7PolicyToURL, *actual) | ||
} | ||
|
||
func TestRequiredL7PolicyCreateOpts(t *testing.T) { | ||
// no param specified. | ||
res := l7policies.Create(fake.ServiceClient(), l7policies.CreateOpts{}) | ||
if res.Err == nil { | ||
t.Fatalf("Expected error, got none") | ||
} | ||
|
||
// RedirectPoolID or RedirectURL is missing. | ||
res = l7policies.Create(fake.ServiceClient(), l7policies.CreateOpts{ | ||
ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d", | ||
Action: l7policies.ActionRedirectToPool, | ||
}) | ||
if res.Err == nil { | ||
t.Fatalf("Expected error, but got none") | ||
} | ||
|
||
// Action is invalid. | ||
res = l7policies.Create(fake.ServiceClient(), l7policies.CreateOpts{ | ||
ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d", | ||
Action: l7policies.Action("invalid"), | ||
RedirectPoolID: "bac433c6-5bea-4311-80da-bd1cd90fbd25", | ||
}) | ||
if res.Err == nil { | ||
t.Fatalf("Expected error, but got none") | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
openstack/networking/v2/extensions/lbaas_v2/l7policies/urls.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package l7policies | ||
|
||
import "github.com/gophercloud/gophercloud" | ||
|
||
const ( | ||
rootPath = "lbaas" | ||
resourcePath = "l7policies" | ||
) | ||
|
||
func rootURL(c *gophercloud.ServiceClient) string { | ||
return c.ServiceURL(rootPath, resourcePath) | ||
} |