Skip to content

Commit

Permalink
feat(lbaas): add support for new rule actions and matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
kangasta committed Oct 22, 2024
1 parent 91d34ab commit 471ef16
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 26 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

### Added

- managed load balancer: `http_status`, `request_header`, and `response_header` rule matchers
- managed load balancer: `set_request_header`, and `set_response_header` rule actions

## [8.10.0]

### Added
Expand Down
68 changes: 42 additions & 26 deletions upcloud/load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,21 @@ const (
LoadBalancerCertificateBundleOperationalStateSetupChallenge LoadBalancerCertificateBundleOperationalState = "setup-challenge"
LoadBalancerCertificateBundleOperationalStateCompleteChallenge LoadBalancerCertificateBundleOperationalState = "complete-challenge"

LoadBalancerMatcherTypeSrcIP LoadBalancerMatcherType = "src_ip"
LoadBalancerMatcherTypeSrcPort LoadBalancerMatcherType = "src_port"
LoadBalancerMatcherTypeBodySize LoadBalancerMatcherType = "body_size"
LoadBalancerMatcherTypePath LoadBalancerMatcherType = "path"
LoadBalancerMatcherTypeURL LoadBalancerMatcherType = "url"
LoadBalancerMatcherTypeURLQuery LoadBalancerMatcherType = "url_query"
LoadBalancerMatcherTypeHost LoadBalancerMatcherType = "host"
LoadBalancerMatcherTypeHTTPMethod LoadBalancerMatcherType = "http_method"
LoadBalancerMatcherTypeCookie LoadBalancerMatcherType = "cookie"
LoadBalancerMatcherTypeHeader LoadBalancerMatcherType = "header"
LoadBalancerMatcherTypeURLParam LoadBalancerMatcherType = "url_param"
LoadBalancerMatcherTypeNumMembersUp LoadBalancerMatcherType = "num_members_up"
LoadBalancerMatcherTypeSrcIP LoadBalancerMatcherType = "src_ip"
LoadBalancerMatcherTypeSrcPort LoadBalancerMatcherType = "src_port"
LoadBalancerMatcherTypeBodySize LoadBalancerMatcherType = "body_size"
LoadBalancerMatcherTypePath LoadBalancerMatcherType = "path"
LoadBalancerMatcherTypeURL LoadBalancerMatcherType = "url"
LoadBalancerMatcherTypeURLQuery LoadBalancerMatcherType = "url_query"
LoadBalancerMatcherTypeHost LoadBalancerMatcherType = "host"
LoadBalancerMatcherTypeHTTPMethod LoadBalancerMatcherType = "http_method"
LoadBalancerMatcherTypeHTTPStatus LoadBalancerMatcherType = "http_status"
LoadBalancerMatcherTypeCookie LoadBalancerMatcherType = "cookie"
LoadBalancerMatcherTypeHeader LoadBalancerMatcherType = "header"
LoadBalancerMatcherTypeRequestHeader LoadBalancerMatcherType = "request_header"
LoadBalancerMatcherTypeResponseHeader LoadBalancerMatcherType = "response_header"
LoadBalancerMatcherTypeURLParam LoadBalancerMatcherType = "url_param"
LoadBalancerMatcherTypeNumMembersUp LoadBalancerMatcherType = "num_members_up"

LoadBalancerMatchingConditionAnd LoadBalancerMatchingCondition = "and"
LoadBalancerMatchingConditionOr LoadBalancerMatchingCondition = "or"
Expand All @@ -79,6 +82,8 @@ const (
LoadBalancerActionTypeHTTPReturn LoadBalancerActionType = "http_return"
LoadBalancerActionTypeHTTPRedirect LoadBalancerActionType = "http_redirect"
LoadBalancerActionTypeSetForwardedHeaders LoadBalancerActionType = "set_forwarded_headers"
LoadBalancerActionTypeSetRequestHeader LoadBalancerActionType = "set_request_header"
LoadBalancerActionTypeSetResponseHeader LoadBalancerActionType = "set_response_header"

LoadBalancerActionHTTPRedirectSchemeHTTP LoadBalancerActionHTTPRedirectScheme = "http"
LoadBalancerActionHTTPRedirectSchemeHTTPS LoadBalancerActionHTTPRedirectScheme = "https"
Expand Down Expand Up @@ -275,20 +280,23 @@ type LoadBalancer struct {

// LoadBalancerMatcher represents rule matcher
type LoadBalancerMatcher struct {
Type LoadBalancerMatcherType `json:"type,omitempty"`
SrcIP *LoadBalancerMatcherSourceIP `json:"match_src_ip,omitempty"`
SrcPort *LoadBalancerMatcherInteger `json:"match_src_port,omitempty"`
BodySize *LoadBalancerMatcherInteger `json:"match_body_size,omitempty"`
Path *LoadBalancerMatcherString `json:"match_path,omitempty"`
URL *LoadBalancerMatcherString `json:"match_url,omitempty"`
URLQuery *LoadBalancerMatcherString `json:"match_url_query,omitempty"`
Host *LoadBalancerMatcherHost `json:"match_host,omitempty"`
HTTPMethod *LoadBalancerMatcherHTTPMethod `json:"match_http_method,omitempty"`
Cookie *LoadBalancerMatcherStringWithArgument `json:"match_cookie,omitempty"`
Header *LoadBalancerMatcherStringWithArgument `json:"match_header,omitempty"`
URLParam *LoadBalancerMatcherStringWithArgument `json:"match_url_param,omitempty"`
NumMembersUp *LoadBalancerMatcherNumMembersUp `json:"match_num_members_up,omitempty"`
Inverse *bool `json:"inverse,omitempty"`
Type LoadBalancerMatcherType `json:"type,omitempty"`
SrcIP *LoadBalancerMatcherSourceIP `json:"match_src_ip,omitempty"`
SrcPort *LoadBalancerMatcherInteger `json:"match_src_port,omitempty"`
BodySize *LoadBalancerMatcherInteger `json:"match_body_size,omitempty"`
Path *LoadBalancerMatcherString `json:"match_path,omitempty"`
RequestHeader *LoadBalancerMatcherStringWithArgument `json:"match_request_header,omitempty"`
ResponseHeader *LoadBalancerMatcherStringWithArgument `json:"match_response_header,omitempty"`
URL *LoadBalancerMatcherString `json:"match_url,omitempty"`
URLQuery *LoadBalancerMatcherString `json:"match_url_query,omitempty"`
Host *LoadBalancerMatcherHost `json:"match_host,omitempty"`
HTTPMethod *LoadBalancerMatcherHTTPMethod `json:"match_http_method,omitempty"`
HTTPStatus *LoadBalancerMatcherInteger `json:"match_http_status,omitempty"`
Cookie *LoadBalancerMatcherStringWithArgument `json:"match_cookie,omitempty"`
Header *LoadBalancerMatcherStringWithArgument `json:"match_header,omitempty"` // Deprecated: use RequestHeader instead
URLParam *LoadBalancerMatcherStringWithArgument `json:"match_url_param,omitempty"`
NumMembersUp *LoadBalancerMatcherNumMembersUp `json:"match_num_members_up,omitempty"`
Inverse *bool `json:"inverse,omitempty"`
}

// LoadBalancerMatcherStringWithArgument represents 'string with argument' matcher
Expand Down Expand Up @@ -344,6 +352,8 @@ type LoadBalancerAction struct {
HTTPReturn *LoadBalancerActionHTTPReturn `json:"action_http_return,omitempty"`
HTTPRedirect *LoadBalancerActionHTTPRedirect `json:"action_http_redirect,omitempty"`
SetForwardedHeaders *LoadBalancerActionSetForwardedHeaders `json:"action_set_forwarded_headers,omitempty"`
SetRequestHeader *LoadBalancerActionSetHeader `json:"action_set_request_header,omitempty"`
SetResponseHeader *LoadBalancerActionSetHeader `json:"action_set_response_header,omitempty"`
}

// LoadBalancerActionUseBackend represents 'use_backend' action
Expand All @@ -370,6 +380,12 @@ type LoadBalancerActionHTTPRedirect struct {
// LoadBalancerActionSetForwardedHeaders represents 'set_forwarded_headers' action
type LoadBalancerActionSetForwardedHeaders struct{}

// LoadBalancerActionSetHeader represents 'set_request_header' and 'set_response_header' actions
type LoadBalancerActionSetHeader struct {
Header string `json:"header,omitempty"`
Value string `json:"value,omitempty"`
}

// LoadBalancerCertificateBundle represents certificate bundle
type LoadBalancerCertificateBundle struct {
UUID string `json:"uuid,omitempty"`
Expand Down
46 changes: 46 additions & 0 deletions upcloud/load_balancer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,29 @@ func TestLoadBalancerRule(t *testing.T) {
Type: LoadBalancerActionTypeSetForwardedHeaders,
SetForwardedHeaders: &LoadBalancerActionSetForwardedHeaders{},
},
{
Type: LoadBalancerActionTypeSetRequestHeader,
SetRequestHeader: &LoadBalancerActionSetHeader{
Header: "Test-Type",
Value: "Unit",
},
},
{
Type: LoadBalancerActionTypeSetResponseHeader,
SetResponseHeader: &LoadBalancerActionSetHeader{
Header: "Test-Type",
Value: "Unit",
},
},
},
Matchers: []LoadBalancerMatcher{
{
Type: LoadBalancerMatcherTypeHTTPStatus,
HTTPStatus: &LoadBalancerMatcherInteger{
Method: LoadBalancerIntegerMatcherMethodEqual,
Value: 200,
},
},
},
CreatedAt: timeParse("2021-12-07T13:58:30.817272Z"),
UpdatedAt: timeParse("2022-02-11T17:33:08.490581Z"),
Expand Down Expand Up @@ -489,6 +512,29 @@ func TestLoadBalancerRule(t *testing.T) {
{
"type": "set_forwarded_headers",
"action_set_forwarded_headers": {}
},
{
"type": "set_request_header",
"action_set_request_header": {
"header": "Test-Type",
"value": "Unit"
}
},
{
"type": "set_response_header",
"action_set_response_header": {
"header": "Test-Type",
"value": "Unit"
}
}
],
"matchers": [
{
"type": "http_status",
"match_http_status": {
"method": "equal",
"value": 200
}
}
]
}
Expand Down
66 changes: 66 additions & 0 deletions upcloud/request/load_balancer_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ func NewLoadBalancerSetForwardedHeadersAction() upcloud.LoadBalancerAction {
}
}

func NewLoadBalancerSetRequestHeaderAction(header, value string) upcloud.LoadBalancerAction {
return upcloud.LoadBalancerAction{
Type: upcloud.LoadBalancerActionTypeSetRequestHeader,
SetRequestHeader: &upcloud.LoadBalancerActionSetHeader{
Header: header,
Value: value,
},
}
}

func NewLoadBalancerSetResponseHeaderAction(header, value string) upcloud.LoadBalancerAction {
return upcloud.LoadBalancerAction{
Type: upcloud.LoadBalancerActionTypeSetResponseHeader,
SetResponseHeader: &upcloud.LoadBalancerActionSetHeader{
Header: header,
Value: value,
},
}
}

func NewLoadBalancerNumMembersUpMatcher(m upcloud.LoadBalancerIntegerMatcherMethod, count int, backend string) upcloud.LoadBalancerMatcher {
return upcloud.LoadBalancerMatcher{
Type: upcloud.LoadBalancerMatcherTypeNumMembersUp,
Expand All @@ -79,6 +99,7 @@ func NewLoadBalancerURLParamMatcher(m upcloud.LoadBalancerStringMatcherMethod, n
}
}

// Deprecated: Use NewLoadBalancerRequestHeaderMatcher instead
func NewLoadBalancerHeaderMatcher(m upcloud.LoadBalancerStringMatcherMethod, name, value string, ignoreCase *bool) upcloud.LoadBalancerMatcher {
return upcloud.LoadBalancerMatcher{
Type: upcloud.LoadBalancerMatcherTypeHeader,
Expand All @@ -91,6 +112,30 @@ func NewLoadBalancerHeaderMatcher(m upcloud.LoadBalancerStringMatcherMethod, nam
}
}

func NewLoadBalancerRequestHeaderMatcher(m upcloud.LoadBalancerStringMatcherMethod, name, value string, ignoreCase *bool) upcloud.LoadBalancerMatcher {
return upcloud.LoadBalancerMatcher{
Type: upcloud.LoadBalancerMatcherTypeRequestHeader,
RequestHeader: &upcloud.LoadBalancerMatcherStringWithArgument{
Method: m,
Name: name,
Value: value,
IgnoreCase: ignoreCase,
},
}
}

func NewLoadBalancerResponseHeaderMatcher(m upcloud.LoadBalancerStringMatcherMethod, name, value string, ignoreCase *bool) upcloud.LoadBalancerMatcher {
return upcloud.LoadBalancerMatcher{
Type: upcloud.LoadBalancerMatcherTypeResponseHeader,
ResponseHeader: &upcloud.LoadBalancerMatcherStringWithArgument{
Method: m,
Name: name,
Value: value,
IgnoreCase: ignoreCase,
},
}
}

func NewLoadBalancerCookieMatcher(m upcloud.LoadBalancerStringMatcherMethod, name, value string, ignoreCase *bool) upcloud.LoadBalancerMatcher {
return upcloud.LoadBalancerMatcher{
Type: upcloud.LoadBalancerMatcherTypeCookie,
Expand All @@ -112,6 +157,27 @@ func NewLoadBalancerHTTPMethodMatcher(method upcloud.LoadBalancerHTTPMatcherMeth
}
}

func NewLoadBalancerHTTPStatusMatcher(m upcloud.LoadBalancerIntegerMatcherMethod, status int) upcloud.LoadBalancerMatcher {
return upcloud.LoadBalancerMatcher{
Type: upcloud.LoadBalancerMatcherTypeHTTPStatus,
HTTPStatus: &upcloud.LoadBalancerMatcherInteger{
Method: m,
Value: status,
},
}
}

func NewLoadBalancerHTTPStatusRangeMatcher(start, end int) upcloud.LoadBalancerMatcher {
return upcloud.LoadBalancerMatcher{
Type: upcloud.LoadBalancerMatcherTypeHTTPStatus,
HTTPStatus: &upcloud.LoadBalancerMatcherInteger{
Method: upcloud.LoadBalancerIntegerMatcherMethodRange,
RangeStart: start,
RangeEnd: end,
},
}
}

func NewLoadBalancerHostMatcher(host string) upcloud.LoadBalancerMatcher {
return upcloud.LoadBalancerMatcher{
Type: upcloud.LoadBalancerMatcherTypeHost,
Expand Down

0 comments on commit 471ef16

Please sign in to comment.