diff --git a/pkg/apigee/v1/apiproxymodel_test.go b/pkg/apigee/v1/apiproxymodel_test.go index e3f4a84..4eecf4a 100644 --- a/pkg/apigee/v1/apiproxymodel_test.go +++ b/pkg/apigee/v1/apiproxymodel_test.go @@ -44,6 +44,9 @@ func TestNewAPIProxyModel(t *testing.T) { { "health-monitor-tcp", }, + { + "lb-server-unhealthy", + }, } for _, tt := range tests { ttDir := filepath.Join("testdata", "yaml-first", tt.name) diff --git a/pkg/apigee/v1/loadbalancer.go b/pkg/apigee/v1/loadbalancer.go index fafff9d..322cfb1 100644 --- a/pkg/apigee/v1/loadbalancer.go +++ b/pkg/apigee/v1/loadbalancer.go @@ -17,8 +17,11 @@ package v1 import "fmt" type LoadBalancer struct { - Algorithm string `xml:"Algorithm,omitempty"` - Servers *ServerList `xml:"Server,omitempty"` + Algorithm string `xml:"Algorithm,omitempty"` + Servers *ServerList `xml:"Server,omitempty"` + ServerUnhealthyResponse *ServerUnhealthyResponse `xml:"ServerUnhealthyResponse,omitempty"` + MaxFailures int `xml:"MaxFailures,omitempty"` + RetryEnabled bool `xml:"RetryEnabled,omitempty"` UnknownNode AnyList `xml:",any"` } @@ -35,6 +38,7 @@ func ValidateLoadBalancer(v *LoadBalancer, path string) []error { var subErrors []error subErrors = append(subErrors, ValidateServers(v.Servers, subPath)...) + subErrors = append(subErrors, ValidateServerUnhealthyResponse(v.ServerUnhealthyResponse, subPath)...) return subErrors } diff --git a/pkg/apigee/v1/serverunhealthyresponse.go b/pkg/apigee/v1/serverunhealthyresponse.go new file mode 100644 index 0000000..a8e0240 --- /dev/null +++ b/pkg/apigee/v1/serverunhealthyresponse.go @@ -0,0 +1,38 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import "fmt" + +type ServerUnhealthyResponse struct { + ResponseCodes ResponseCodeList `xml:"ResponseCode,omitempty"` + UnknownNode AnyList `xml:",any"` +} + +func ValidateServerUnhealthyResponse(v *ServerUnhealthyResponse, path string) []error { + if v == nil { + return nil + } + + subPath := fmt.Sprintf("%s.ServerUnhealthyResponse", path) + if len(v.UnknownNode) > 0 { + return []error{&UnknownNodeError{subPath, v.UnknownNode[0]}} + } + + var subErrors []error + subErrors = append(subErrors, ValidateResponseCodes(&v.ResponseCodes, subPath)...) + + return subErrors +} diff --git a/pkg/apigee/v1/testdata/yaml-first/lb-server-unhealthy/apiproxy.yaml b/pkg/apigee/v1/testdata/yaml-first/lb-server-unhealthy/apiproxy.yaml new file mode 100644 index 0000000..831d340 --- /dev/null +++ b/pkg/apigee/v1/testdata/yaml-first/lb-server-unhealthy/apiproxy.yaml @@ -0,0 +1,42 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +APIProxy: + .revision: 1 + .name: httpbin +Policies: [] +ProxyEndpoints: + - ProxyEndpoint: + .name: default + Flows: [] + HTTPProxyConnection: + BasePath: /httpbin + RouteRule: + .name: default + TargetEndpoint: default +TargetEndpoints: + - TargetEndpoint: + .name: default + HTTPTargetConnection: + Path: /test + LoadBalancer: + - Algorithm: RoundRobin + - Server: + .name: target1 + - Server: + .name: target2 + - RetryEnabled: true + - MaxFailures: 3 + - ServerUnhealthyResponse: + - ResponseCode: 400 + - ResponseCode: 500 \ No newline at end of file