pkg/providers/apisix/translation/apisix_plugin.go (277 lines of code) (raw):
// 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 (
"errors"
"strconv"
configv2 "github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2"
"github.com/apache/apisix-ingress-controller/pkg/providers/translation"
apisixv1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
)
var (
_errKeyNotFoundOrInvalid = errors.New("key \"key\" not found or invalid in secret")
_errUsernameNotFoundOrInvalid = errors.New("key \"username\" not found or invalid in secret")
_errPasswordNotFoundOrInvalid = errors.New("key \"password\" not found or invalid in secret")
_jwtAuthExpDefaultValue = int64(868400)
_hmacAuthAlgorithmDefaultValue = "hmac-sha256"
_hmacAuthClockSkewDefaultValue = int64(0)
_hmacAuthKeepHeadersDefaultValue = false
_hmacAuthEncodeURIParamsDefaultValue = true
_hmacAuthValidateRequestBodyDefaultValue = false
_hmacAuthMaxReqBodyDefaultValue = int64(524288)
)
func (t *translator) translateTrafficSplitPlugin(ctx *translation.TranslateContext, ns string, defaultBackendWeight int,
backends []configv2.ApisixRouteHTTPBackend) (*apisixv1.TrafficSplitConfig, error) {
var (
wups []apisixv1.TrafficSplitConfigRuleWeightedUpstream
)
for _, backend := range backends {
svcClusterIP, svcPort, err := t.GetServiceClusterIPAndPort(&backend, ns)
if err != nil {
return nil, err
}
ups, err := t.translateService(ns, backend.ServiceName, backend.Subset, backend.ResolveGranularity, svcClusterIP, svcPort)
if err != nil {
return nil, err
}
ctx.AddUpstream(ups)
weight := translation.DefaultWeight
if backend.Weight != nil {
weight = *backend.Weight
}
wups = append(wups, apisixv1.TrafficSplitConfigRuleWeightedUpstream{
UpstreamID: ups.ID,
Weight: weight,
})
}
// append the default upstream in the route.
wups = append(wups, apisixv1.TrafficSplitConfigRuleWeightedUpstream{
Weight: defaultBackendWeight,
})
tsCfg := &apisixv1.TrafficSplitConfig{
Rules: []apisixv1.TrafficSplitConfigRule{
{
WeightedUpstreams: wups,
},
},
}
return tsCfg, nil
}
func (t *translator) translateConsumerKeyAuthPluginV2(consumerNamespace string, cfg *configv2.ApisixConsumerKeyAuth) (*apisixv1.KeyAuthConsumerConfig, error) {
if cfg.Value != nil {
return &apisixv1.KeyAuthConsumerConfig{Key: cfg.Value.Key}, nil
}
sec, err := t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
if err != nil {
return nil, err
}
raw, ok := sec.Data["key"]
if !ok || len(raw) == 0 {
return nil, _errKeyNotFoundOrInvalid
}
return &apisixv1.KeyAuthConsumerConfig{Key: string(raw)}, nil
}
func (t *translator) translateConsumerBasicAuthPluginV2(consumerNamespace string, cfg *configv2.ApisixConsumerBasicAuth) (*apisixv1.BasicAuthConsumerConfig, error) {
if cfg.Value != nil {
return &apisixv1.BasicAuthConsumerConfig{
Username: cfg.Value.Username,
Password: cfg.Value.Password,
}, nil
}
sec, err := t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
if err != nil {
return nil, err
}
raw1, ok := sec.Data["username"]
if !ok || len(raw1) == 0 {
return nil, _errUsernameNotFoundOrInvalid
}
raw2, ok := sec.Data["password"]
if !ok || len(raw2) == 0 {
return nil, _errPasswordNotFoundOrInvalid
}
return &apisixv1.BasicAuthConsumerConfig{
Username: string(raw1),
Password: string(raw2),
}, nil
}
func (t *translator) translateConsumerWolfRBACPluginV2(consumerNamespace string, cfg *configv2.ApisixConsumerWolfRBAC) (*apisixv1.WolfRBACConsumerConfig, error) {
if cfg.Value != nil {
return &apisixv1.WolfRBACConsumerConfig{
Server: cfg.Value.Server,
Appid: cfg.Value.Appid,
HeaderPrefix: cfg.Value.HeaderPrefix,
}, nil
}
sec, err := t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
if err != nil {
return nil, err
}
raw1 := sec.Data["server"]
raw2 := sec.Data["appid"]
raw3 := sec.Data["header_prefix"]
return &apisixv1.WolfRBACConsumerConfig{
Server: string(raw1),
Appid: string(raw2),
HeaderPrefix: string(raw3),
}, nil
}
func (t *translator) translateConsumerJwtAuthPluginV2(consumerNamespace string, cfg *configv2.ApisixConsumerJwtAuth) (*apisixv1.JwtAuthConsumerConfig, error) {
if cfg.Value != nil {
// The field exp must be a positive integer, default value 86400.
if cfg.Value.Exp < 1 {
cfg.Value.Exp = _jwtAuthExpDefaultValue
}
return &apisixv1.JwtAuthConsumerConfig{
Key: cfg.Value.Key,
Secret: cfg.Value.Secret,
PublicKey: cfg.Value.PublicKey,
PrivateKey: cfg.Value.PrivateKey,
Algorithm: cfg.Value.Algorithm,
Exp: cfg.Value.Exp,
Base64Secret: cfg.Value.Base64Secret,
LifetimeGracePeriod: cfg.Value.LifetimeGracePeriod,
}, nil
}
sec, err := t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
if err != nil {
return nil, err
}
keyRaw, ok := sec.Data["key"]
if !ok || len(keyRaw) == 0 {
return nil, _errKeyNotFoundOrInvalid
}
base64SecretRaw := sec.Data["base64_secret"]
var base64Secret bool
if string(base64SecretRaw) == "true" {
base64Secret = true
}
expRaw := sec.Data["exp"]
exp, _ := strconv.ParseInt(string(expRaw), 10, 64)
// The field exp must be a positive integer, default value 86400.
if exp < 1 {
exp = _jwtAuthExpDefaultValue
}
lifetimeGracePeriodRaw := sec.Data["lifetime_grace_period"]
lifetimeGracePeriod, _ := strconv.ParseInt(string(lifetimeGracePeriodRaw), 10, 64)
secretRaw := sec.Data["secret"]
publicKeyRaw := sec.Data["public_key"]
privateKeyRaw := sec.Data["private_key"]
algorithmRaw := sec.Data["algorithm"]
return &apisixv1.JwtAuthConsumerConfig{
Key: string(keyRaw),
Secret: string(secretRaw),
PublicKey: string(publicKeyRaw),
PrivateKey: string(privateKeyRaw),
Algorithm: string(algorithmRaw),
Exp: exp,
Base64Secret: base64Secret,
LifetimeGracePeriod: lifetimeGracePeriod,
}, nil
}
func (t *translator) translateConsumerHMACAuthPluginV2(consumerNamespace string, cfg *configv2.ApisixConsumerHMACAuth) (*apisixv1.HMACAuthConsumerConfig, error) {
if cfg.Value != nil {
return &apisixv1.HMACAuthConsumerConfig{
AccessKey: cfg.Value.AccessKey,
SecretKey: cfg.Value.SecretKey,
Algorithm: cfg.Value.Algorithm,
ClockSkew: cfg.Value.ClockSkew,
SignedHeaders: cfg.Value.SignedHeaders,
KeepHeaders: cfg.Value.KeepHeaders,
EncodeURIParams: cfg.Value.EncodeURIParams,
ValidateRequestBody: cfg.Value.ValidateRequestBody,
MaxReqBody: cfg.Value.MaxReqBody,
}, nil
}
sec, err := t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
if err != nil {
return nil, err
}
accessKeyRaw, ok := sec.Data["access_key"]
if !ok || len(accessKeyRaw) == 0 {
return nil, _errKeyNotFoundOrInvalid
}
secretKeyRaw, ok := sec.Data["secret_key"]
if !ok || len(secretKeyRaw) == 0 {
return nil, _errKeyNotFoundOrInvalid
}
algorithmRaw, ok := sec.Data["algorithm"]
var algorithm string
if !ok {
algorithm = _hmacAuthAlgorithmDefaultValue
} else {
algorithm = string(algorithmRaw)
}
clockSkewRaw := sec.Data["clock_skew"]
clockSkew, _ := strconv.ParseInt(string(clockSkewRaw), 10, 64)
if clockSkew < 0 {
clockSkew = _hmacAuthClockSkewDefaultValue
}
var signedHeaders []string
signedHeadersRaw := sec.Data["signed_headers"]
for _, b := range signedHeadersRaw {
signedHeaders = append(signedHeaders, string(b))
}
var keepHeader bool
keepHeaderRaw, ok := sec.Data["keep_headers"]
if !ok {
keepHeader = _hmacAuthKeepHeadersDefaultValue
} else {
if string(keepHeaderRaw) == "true" {
keepHeader = true
} else {
keepHeader = false
}
}
var encodeURIParams bool
encodeURIParamsRaw, ok := sec.Data["encode_uri_params"]
if !ok {
encodeURIParams = _hmacAuthEncodeURIParamsDefaultValue
} else {
if string(encodeURIParamsRaw) == "true" {
encodeURIParams = true
} else {
encodeURIParams = false
}
}
var validateRequestBody bool
validateRequestBodyRaw, ok := sec.Data["validate_request_body"]
if !ok {
validateRequestBody = _hmacAuthValidateRequestBodyDefaultValue
} else {
if string(validateRequestBodyRaw) == "true" {
validateRequestBody = true
} else {
validateRequestBody = false
}
}
maxReqBodyRaw := sec.Data["max_req_body"]
maxReqBody, _ := strconv.ParseInt(string(maxReqBodyRaw), 10, 64)
if maxReqBody < 0 {
maxReqBody = _hmacAuthMaxReqBodyDefaultValue
}
return &apisixv1.HMACAuthConsumerConfig{
AccessKey: string(accessKeyRaw),
SecretKey: string(secretKeyRaw),
Algorithm: algorithm,
ClockSkew: clockSkew,
SignedHeaders: signedHeaders,
KeepHeaders: keepHeader,
EncodeURIParams: encodeURIParams,
ValidateRequestBody: validateRequestBody,
MaxReqBody: maxReqBody,
}, nil
}
func (t *translator) translateConsumerLDAPAuthPluginV2(consumerNamespace string, cfg *configv2.ApisixConsumerLDAPAuth) (*apisixv1.LDAPAuthConsumerConfig, error) {
if cfg.Value != nil {
return &apisixv1.LDAPAuthConsumerConfig{
UserDN: cfg.Value.UserDN,
}, nil
}
sec, err := t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
if err != nil {
return nil, err
}
userDNRaw, ok := sec.Data["user_dn"]
if !ok || len(userDNRaw) == 0 {
return nil, _errKeyNotFoundOrInvalid
}
return &apisixv1.LDAPAuthConsumerConfig{
UserDN: string(userDNRaw),
}, nil
}