-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ovh_iploadbalancing_http_route_rule
- Loading branch information
Elie CHARRA
committed
Jun 1, 2018
1 parent
d47a944
commit 845a891
Showing
4 changed files
with
429 additions
and
0 deletions.
There are no files selected for viewing
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
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,155 @@ | ||
package ovh | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
//IPLoadbalancingRouteHTTPRule HTTP Route Rule | ||
type IPLoadbalancingRouteHTTPRule struct { | ||
RuleID int `json:"ruleId,omitempty"` //Id of your rule | ||
RouteID int `json:"routeId,omitempty"` //Id of your route | ||
DisplayName string `json:"displayName,omitempty"` //Human readable name for your rule | ||
Field string `json:"field,omitempty"` //Name of the field to match like "protocol" or "host". See "/ipLoadbalancing/{serviceName}/availableRouteRules" for a list of available rules | ||
Match string `json:"match,omitempty"` //Matching operator. Not all operators are available for all fields. See "/ipLoadbalancing/{serviceName}/availableRouteRules" | ||
Negate bool `json:"negate,omitempty"` //Invert the matching operator effect | ||
Pattern string `json:"pattern,omitempty"` //Value to match against this match. Interpretation if this field depends on the match and field | ||
SubField string `json:"subField,omitempty"` //Name of sub-field, if applicable. This may be a Cookie or Header name for instance | ||
} | ||
|
||
func resourceIPLoadbalancingRouteHTTPRule() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceIPLoadbalancingRouteHTTPRuleCreate, | ||
Read: resourceIPLoadbalancingRouteHTTPRuleRead, | ||
Update: resourceIPLoadbalancingRouteHTTPRuleUpdate, | ||
Delete: resourceIPLoadbalancingRouteHTTPRuleDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"service_name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"route_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"display_name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"field": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"match": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { | ||
err := validateStringEnum(v.(string), []string{"contains", "endswith", "exists", "in", "internal", "is", "matches", "startswith"}) | ||
if err != nil { | ||
errors = append(errors, err) | ||
} | ||
return | ||
}, | ||
}, | ||
"negate": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
}, | ||
"pattern": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"sub_field": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceIPLoadbalancingRouteHTTPRuleCreate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
rule := &IPLoadbalancingRouteHTTPRule{ | ||
DisplayName: d.Get("display_name").(string), | ||
Field: d.Get("field").(string), | ||
Match: d.Get("match").(string), | ||
Negate: d.Get("negate").(bool), | ||
Pattern: d.Get("pattern").(string), | ||
SubField: d.Get("sub_field").(string), | ||
} | ||
|
||
service := d.Get("service_name").(string) | ||
routeID := d.Get("route_id").(string) | ||
resp := &IPLoadbalancingRouteHTTPRule{} | ||
endpoint := fmt.Sprintf("/ipLoadbalancing/%s/http/route/%s/rule", service, routeID) | ||
|
||
err := config.OVHClient.Post(endpoint, rule, resp) | ||
if err != nil { | ||
return fmt.Errorf("calling POST %s :\n\t %s", endpoint, err.Error()) | ||
} | ||
|
||
d.SetId(fmt.Sprintf("%d", resp.RuleID)) | ||
|
||
return nil | ||
} | ||
|
||
func resourceIPLoadbalancingRouteHTTPRuleRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
service := d.Get("service_name").(string) | ||
routeID := d.Get("route_id").(string) | ||
r := &IPLoadbalancingRouteHTTPRule{} | ||
endpoint := fmt.Sprintf("/ipLoadbalancing/%s/http/route/%s/rule/%s", service, routeID, d.Id()) | ||
|
||
err := config.OVHClient.Get(endpoint, &r) | ||
if err != nil { | ||
return CheckDeleted(d, err, endpoint) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceIPLoadbalancingRouteHTTPRuleUpdate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
service := d.Get("service_name").(string) | ||
routeID := d.Get("route_id").(string) | ||
|
||
endpoint := fmt.Sprintf("/ipLoadbalancing/%s/http/route/%s/rule/%s", service, routeID, d.Id()) | ||
|
||
rule := &IPLoadbalancingRouteHTTPRule{ | ||
DisplayName: d.Get("display_name").(string), | ||
Field: d.Get("field").(string), | ||
Match: d.Get("match").(string), | ||
Negate: d.Get("negate").(bool), | ||
Pattern: d.Get("pattern").(string), | ||
SubField: d.Get("sub_field").(string), | ||
} | ||
|
||
err := config.OVHClient.Put(endpoint, rule, nil) | ||
if err != nil { | ||
return fmt.Errorf("calling %s:\n\t %s", endpoint, err.Error()) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceIPLoadbalancingRouteHTTPRuleDelete(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
service := d.Get("service_name").(string) | ||
routeID := d.Get("route_id").(string) | ||
|
||
r := &IPLoadbalancingRouteHTTPRule{} | ||
endpoint := fmt.Sprintf("/ipLoadbalancing/%s/http/route/%s/rule/%s", service, routeID, d.Id()) | ||
|
||
err := config.OVHClient.Delete(endpoint, &r) | ||
if err != nil { | ||
return fmt.Errorf("Error calling %s: %s \n", endpoint, err.Error()) | ||
} | ||
|
||
return nil | ||
} |
192 changes: 192 additions & 0 deletions
192
ovh/resource_ovh_iploadbalancing_http_route_rule_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,192 @@ | ||
package ovh | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"os" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
var TestAccIPLoadbalancingRouteHTTPRulePlan = [][]map[string]interface{}{ | ||
{ | ||
{"DisplayName": "Test rule", "Field": "header", "Match": "is", "Negate": false, "Pattern": "example.com", "SubField": "Host"}, | ||
}, | ||
} | ||
|
||
type TestAccIPLoadbalancingRouteHTTPRule struct { | ||
ServiceName string | ||
RuleID int `json:"ruleId"` | ||
RouteID int `json:"routeId"` | ||
DisplayName string `json:"displayName"` | ||
Field string `json:"field"` | ||
Match string `json:"match"` | ||
Negate bool `json:"negate"` | ||
Pattern string `json:"pattern"` | ||
SubField string `json:"subField"` | ||
} | ||
|
||
type TestAccIPLoadbalancingRouteHTTPRuleWrapper struct { | ||
Expected *TestAccIPLoadbalancingRouteHTTPRule | ||
} | ||
|
||
func (w *TestAccIPLoadbalancingRouteHTTPRuleWrapper) Config() string { | ||
var config bytes.Buffer | ||
config.WriteString(fmt.Sprintf(` | ||
resource "ovh_iploadbalancing_http_route" "testroute" { | ||
service_name = "%s" | ||
display_name = "Test route" | ||
weight = 0 | ||
action { | ||
status = 302 | ||
target = "http://example.com" | ||
type = "redirect" | ||
} | ||
} | ||
resource "ovh_iploadbalancing_http_route_rule" "testrule" { | ||
service_name = "%s" | ||
route_id = "${ovh_iploadbalancing_http_route.testroute.id}" | ||
display_name = "%s" | ||
field = "%s" | ||
match = "%s" | ||
negate = %t | ||
pattern = "%s" | ||
sub_field = "%s" | ||
} | ||
`, w.Expected.ServiceName, | ||
w.Expected.ServiceName, | ||
w.Expected.DisplayName, | ||
w.Expected.Field, | ||
w.Expected.Match, | ||
w.Expected.Negate, | ||
w.Expected.Pattern, | ||
w.Expected.SubField)) | ||
|
||
return config.String() | ||
} | ||
|
||
func (rule *TestAccIPLoadbalancingRouteHTTPRule) MustEqual(compared *TestAccIPLoadbalancingRouteHTTPRule) error { | ||
if !reflect.DeepEqual(rule.DisplayName, compared.DisplayName) { | ||
return fmt.Errorf("DisplayName differs") | ||
} | ||
if !reflect.DeepEqual(rule.Field, compared.Field) { | ||
return fmt.Errorf("Field differs") | ||
} | ||
if !reflect.DeepEqual(rule.Match, compared.Match) { | ||
return fmt.Errorf("Match differs") | ||
} | ||
if !reflect.DeepEqual(rule.Negate, compared.Negate) { | ||
return fmt.Errorf("Negate differs") | ||
} | ||
if !reflect.DeepEqual(rule.Pattern, compared.Pattern) { | ||
return fmt.Errorf("Pattern differs") | ||
} | ||
if !reflect.DeepEqual(rule.SubField, compared.SubField) { | ||
return fmt.Errorf("SubField differs") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
type TestAccIPLoadbalancingRouteHTTPRuleStep struct { | ||
Response *TestAccIPLoadbalancingRouteHTTPRule | ||
Expected *TestAccIPLoadbalancingRouteHTTPRule | ||
} | ||
|
||
func (w *TestAccIPLoadbalancingRouteHTTPRuleWrapper) TestStep(c map[string]interface{}) resource.TestStep { | ||
if val, ok := c["DisplayName"]; ok { | ||
w.Expected.DisplayName = val.(string) | ||
} | ||
if val, ok := c["Field"]; ok { | ||
w.Expected.Field = val.(string) | ||
} | ||
if val, ok := c["Match"]; ok { | ||
w.Expected.Match = val.(string) | ||
} | ||
if val, ok := c["Negate"]; ok { | ||
w.Expected.Negate = val.(bool) | ||
} | ||
if val, ok := c["Pattern"]; ok { | ||
w.Expected.Pattern = val.(string) | ||
} | ||
if val, ok := c["SubField"]; ok { | ||
w.Expected.SubField = val.(string) | ||
} | ||
expected := *w.Expected | ||
|
||
return resource.TestStep{ | ||
Config: w.Config(), | ||
Check: resource.ComposeTestCheckFunc( | ||
w.TestCheck(expected), | ||
), | ||
} | ||
} | ||
|
||
func (w *TestAccIPLoadbalancingRouteHTTPRuleWrapper) TestCheck(expected TestAccIPLoadbalancingRouteHTTPRule) resource.TestCheckFunc { | ||
return func(state *terraform.State) error { | ||
response := &TestAccIPLoadbalancingRouteHTTPRule{} | ||
name := "ovh_iploadbalancing_http_route_rule.testrule" | ||
resource, ok := state.RootModule().Resources[name] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", name) | ||
} | ||
config := testAccProvider.Meta().(*Config) | ||
endpoint := fmt.Sprintf("/ipLoadbalancing/%s/http/route/%s/rule/%s", os.Getenv("OVH_IPLB_SERVICE"), resource.Primary.Attributes["route_id"], resource.Primary.ID) | ||
err := config.OVHClient.Get(endpoint, response) | ||
if err != nil { | ||
return fmt.Errorf("calling GET %s :\n\t %s", endpoint, err.Error()) | ||
} | ||
|
||
err = expected.MustEqual(response) | ||
if err != nil { | ||
return fmt.Errorf("%s %s state differs from expected : %s", name, resource.Primary.ID, err.Error()) | ||
} | ||
return nil | ||
} | ||
} | ||
|
||
func (w *TestAccIPLoadbalancingRouteHTTPRuleWrapper) TestDestroy(state *terraform.State) error { | ||
leftovers := false | ||
for _, resource := range state.RootModule().Resources { | ||
if resource.Type != "ovh_iploadbalancing_http_route_rule" { | ||
continue | ||
} | ||
|
||
config := testAccProvider.Meta().(*Config) | ||
endpoint := fmt.Sprintf("/ipLoadbalancing/%s/http/route/%d/rule/%s", os.Getenv("OVH_IPLB_SERVICE"), w.Expected.RouteID, resource.Primary.ID) | ||
err := config.OVHClient.Get(endpoint, nil) | ||
if err == nil { | ||
leftovers = true | ||
} | ||
} | ||
if leftovers { | ||
return fmt.Errorf("IpLoadbalancing http route rule still exists") | ||
} | ||
return nil | ||
} | ||
|
||
func newTestAccIPLoadbalancingRouteHTTPRuleWrapper() *TestAccIPLoadbalancingRouteHTTPRuleWrapper { | ||
return &TestAccIPLoadbalancingRouteHTTPRuleWrapper{ | ||
Expected: &TestAccIPLoadbalancingRouteHTTPRule{ServiceName: os.Getenv("OVH_IPLB_SERVICE")}, | ||
} | ||
} | ||
|
||
func TestAccIpLoadbalancingRouteHTTPRuleBasicCreate(t *testing.T) { | ||
for _, plan := range TestAccIPLoadbalancingRouteHTTPRulePlan { | ||
w := newTestAccIPLoadbalancingRouteHTTPRuleWrapper() | ||
var steps []resource.TestStep | ||
for _, tcase := range plan { | ||
steps = append(steps, w.TestStep(tcase)) | ||
} | ||
resource.Test(t, resource.TestCase{ | ||
Providers: testAccProviders, | ||
CheckDestroy: w.TestDestroy, | ||
Steps: steps, | ||
}) | ||
} | ||
} |
Oops, something went wrong.