blob: f9ce8432121b56e083fb676693d29cc0792a3dd5 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 translation
import (
configv1 "github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v1"
apisixv1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
)
func (t *translator) translateUpstreamRetriesAndTimeout(retries int, timeout *configv1.UpstreamTimeout, ups *apisixv1.Upstream) error {
if retries < 0 {
return &translateError{
field: "retries",
reason: "invalid value",
}
}
ups.Retries = retries
if timeout == nil {
return nil
}
// Since the schema of timeout doesn't allow only configuring
// one or two items. Here we assign the default value first.
connTimeout := apisixv1.DefaultUpstreamTimeout
readTimeout := apisixv1.DefaultUpstreamTimeout
sendTimeout := apisixv1.DefaultUpstreamTimeout
if timeout.Connect.Duration < 0 {
return &translateError{
field: "timeout.connect",
reason: "invalid value",
}
} else if timeout.Connect.Duration > 0 {
connTimeout = int(timeout.Connect.Seconds())
}
if timeout.Read.Duration < 0 {
return &translateError{
field: "timeout.read",
reason: "invalid value",
}
} else if timeout.Read.Duration > 0 {
readTimeout = int(timeout.Read.Seconds())
}
if timeout.Send.Duration < 0 {
return &translateError{
field: "timeout.send",
reason: "invalid value",
}
} else if timeout.Send.Duration > 0 {
sendTimeout = int(timeout.Send.Seconds())
}
ups.Timeout = &apisixv1.UpstreamTimeout{
Connect: connTimeout,
Send: sendTimeout,
Read: readTimeout,
}
return nil
}
func (t *translator) translateUpstreamScheme(scheme string, ups *apisixv1.Upstream) error {
if scheme == "" {
ups.Scheme = apisixv1.SchemeHTTP
return nil
}
switch scheme {
case apisixv1.SchemeHTTP, apisixv1.SchemeGRPC:
ups.Scheme = scheme
return nil
default:
return &translateError{field: "scheme", reason: "invalid value"}
}
}
func (t *translator) translateUpstreamLoadBalancer(lb *configv1.LoadBalancer, ups *apisixv1.Upstream) error {
if lb == nil || lb.Type == "" {
ups.Type = apisixv1.LbRoundRobin
return nil
}
switch lb.Type {
case apisixv1.LbRoundRobin, apisixv1.LbLeastConn, apisixv1.LbEwma:
ups.Type = lb.Type
case apisixv1.LbConsistentHash:
ups.Type = lb.Type
ups.Key = lb.Key
switch lb.HashOn {
case apisixv1.HashOnVars:
fallthrough
case apisixv1.HashOnHeader:
fallthrough
case apisixv1.HashOnCookie:
fallthrough
case apisixv1.HashOnConsumer:
fallthrough
case apisixv1.HashOnVarsCombination:
ups.HashOn = lb.HashOn
default:
return &translateError{field: "loadbalancer.hashOn", reason: "invalid value"}
}
default:
return &translateError{
field: "loadbalancer.type",
reason: "invalid value",
}
}
return nil
}
func (t *translator) translateUpstreamHealthCheck(config *configv1.HealthCheck, ups *apisixv1.Upstream) error {
if config == nil || (config.Passive == nil && config.Active == nil) {
return nil
}
var hc apisixv1.UpstreamHealthCheck
if config.Passive != nil {
passive, err := t.translateUpstreamPassiveHealthCheck(config.Passive)
if err != nil {
return err
}
hc.Passive = passive
}
if config.Active != nil {
active, err := t.translateUpstreamActiveHealthCheck(config.Active)
if err != nil {
return err
}
hc.Active = active
} else {
return &translateError{
field: "healthCheck.active",
reason: "not exist",
}
}
ups.Checks = &hc
return nil
}
func (t *translator) translateUpstreamActiveHealthCheck(config *configv1.ActiveHealthCheck) (*apisixv1.UpstreamActiveHealthCheck, error) {
var active apisixv1.UpstreamActiveHealthCheck
switch config.Type {
case apisixv1.HealthCheckHTTP, apisixv1.HealthCheckHTTPS, apisixv1.HealthCheckTCP:
active.Type = config.Type
case "":
active.Type = apisixv1.HealthCheckHTTP
default:
return nil, &translateError{
field: "healthCheck.active.Type",
reason: "invalid value",
}
}
active.Timeout = int(config.Timeout.Seconds())
if config.Port < 0 || config.Port > 65535 {
return nil, &translateError{
field: "healthCheck.active.port",
reason: "invalid value",
}
} else {
active.Port = config.Port
}
if config.Concurrency < 0 {
return nil, &translateError{
field: "healthCheck.active.concurrency",
reason: "invalid value",
}
} else {
active.Concurrency = config.Concurrency
}
active.Host = config.Host
active.HTTPPath = config.HTTPPath
active.HTTPRequestHeaders = config.RequestHeaders
if config.StrictTLS == nil || *config.StrictTLS {
active.HTTPSVerifyCert = true
}
if config.Healthy != nil {
if config.Healthy.Successes < 0 || config.Healthy.Successes > apisixv1.HealthCheckMaxConsecutiveNumber {
return nil, &translateError{
field: "healthCheck.active.healthy.successes",
reason: "invalid value",
}
}
active.Healthy.Successes = config.Healthy.Successes
if config.Healthy.HTTPCodes != nil && len(config.Healthy.HTTPCodes) < 1 {
return nil, &translateError{
field: "healthCheck.active.healthy.httpCodes",
reason: "empty",
}
}
active.Healthy.HTTPStatuses = config.Healthy.HTTPCodes
if config.Healthy.Interval.Duration < apisixv1.ActiveHealthCheckMinInterval {
return nil, &translateError{
field: "healthCheck.active.healthy.interval",
reason: "invalid value",
}
}
active.Healthy.Interval = int(config.Healthy.Interval.Seconds())
}
if config.Unhealthy != nil {
if config.Unhealthy.HTTPFailures < 0 || config.Unhealthy.HTTPFailures > apisixv1.HealthCheckMaxConsecutiveNumber {
return nil, &translateError{
field: "healthCheck.active.unhealthy.httpFailures",
reason: "invalid value",
}
}
active.Unhealthy.HTTPFailures = config.Unhealthy.HTTPFailures
if config.Unhealthy.TCPFailures < 0 || config.Unhealthy.TCPFailures > apisixv1.HealthCheckMaxConsecutiveNumber {
return nil, &translateError{
field: "healthCheck.active.unhealthy.tcpFailures",
reason: "invalid value",
}
}
active.Unhealthy.TCPFailures = config.Unhealthy.TCPFailures
active.Unhealthy.Timeouts = config.Unhealthy.Timeout.Seconds()
if config.Unhealthy.HTTPCodes != nil && len(config.Unhealthy.HTTPCodes) < 1 {
return nil, &translateError{
field: "healthCheck.active.unhealthy.httpCodes",
reason: "empty",
}
}
active.Unhealthy.HTTPStatuses = config.Unhealthy.HTTPCodes
if config.Unhealthy.Interval.Duration < apisixv1.ActiveHealthCheckMinInterval {
return nil, &translateError{
field: "healthCheck.active.unhealthy.interval",
reason: "invalid value",
}
}
active.Unhealthy.Interval = int(config.Unhealthy.Interval.Seconds())
}
return &active, nil
}
func (t *translator) translateUpstreamPassiveHealthCheck(config *configv1.PassiveHealthCheck) (*apisixv1.UpstreamPassiveHealthCheck, error) {
var passive apisixv1.UpstreamPassiveHealthCheck
switch config.Type {
case apisixv1.HealthCheckHTTP, apisixv1.HealthCheckHTTPS, apisixv1.HealthCheckTCP:
passive.Type = config.Type
case "":
passive.Type = apisixv1.HealthCheckHTTP
default:
return nil, &translateError{
field: "healthCheck.passive.Type",
reason: "invalid value",
}
}
if config.Healthy != nil {
// zero means use the default value.
if config.Healthy.Successes < 0 || config.Healthy.Successes > apisixv1.HealthCheckMaxConsecutiveNumber {
return nil, &translateError{
field: "healthCheck.passive.healthy.successes",
reason: "invalid value",
}
}
passive.Healthy.Successes = config.Healthy.Successes
if config.Healthy.HTTPCodes != nil && len(config.Healthy.HTTPCodes) < 1 {
return nil, &translateError{
field: "healthCheck.passive.healthy.httpCodes",
reason: "empty",
}
}
passive.Healthy.HTTPStatuses = config.Healthy.HTTPCodes
}
if config.Unhealthy != nil {
if config.Unhealthy.HTTPFailures < 0 || config.Unhealthy.HTTPFailures > apisixv1.HealthCheckMaxConsecutiveNumber {
return nil, &translateError{
field: "healthCheck.passive.unhealthy.httpFailures",
reason: "invalid value",
}
}
passive.Unhealthy.HTTPFailures = config.Unhealthy.HTTPFailures
if config.Unhealthy.TCPFailures < 0 || config.Unhealthy.TCPFailures > apisixv1.HealthCheckMaxConsecutiveNumber {
return nil, &translateError{
field: "healthCheck.passive.unhealthy.tcpFailures",
reason: "invalid value",
}
}
passive.Unhealthy.TCPFailures = config.Unhealthy.TCPFailures
passive.Unhealthy.Timeouts = config.Unhealthy.Timeout.Seconds()
if config.Unhealthy.HTTPCodes != nil && len(config.Unhealthy.HTTPCodes) < 1 {
return nil, &translateError{
field: "healthCheck.passive.unhealthy.httpCodes",
reason: "empty",
}
}
passive.Unhealthy.HTTPStatuses = config.Unhealthy.HTTPCodes
}
return &passive, nil
}