mirror of
https://github.com/alibaba/higress.git
synced 2026-02-24 20:50:51 +08:00
236 lines
5.2 KiB
Go
236 lines
5.2 KiB
Go
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
|
//
|
|
// 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 annotations
|
|
|
|
import (
|
|
"strings"
|
|
|
|
networking "istio.io/api/networking/v1alpha3"
|
|
"istio.io/istio/pkg/cluster"
|
|
"istio.io/istio/pkg/util/sets"
|
|
listersv1 "k8s.io/client-go/listers/core/v1"
|
|
|
|
"github.com/alibaba/higress/pkg/ingress/kube/mcpserver"
|
|
)
|
|
|
|
type GlobalContext struct {
|
|
// secret key is cluster/namespace/name
|
|
WatchedSecrets sets.Set[string]
|
|
|
|
ClusterSecretLister map[cluster.ID]listersv1.SecretLister
|
|
|
|
ClusterServiceList map[cluster.ID]listersv1.ServiceLister
|
|
|
|
McpServers []*mcpserver.McpServer
|
|
}
|
|
|
|
type Meta struct {
|
|
Namespace string
|
|
Name string
|
|
RawClusterId string
|
|
ClusterId cluster.ID
|
|
}
|
|
|
|
// Ingress defines the valid annotations present in one NGINX Ingress.
|
|
type Ingress struct {
|
|
Meta
|
|
|
|
Cors *CorsConfig
|
|
|
|
Rewrite *RewriteConfig
|
|
|
|
Redirect *RedirectConfig
|
|
|
|
UpstreamTLS *UpstreamTLSConfig
|
|
|
|
DownstreamTLS *DownstreamTLSConfig
|
|
|
|
Canary *CanaryConfig
|
|
|
|
IPAccessControl *IPAccessControlConfig
|
|
|
|
Timeout *TimeoutConfig
|
|
|
|
Retry *RetryConfig
|
|
|
|
LoadBalance *LoadBalanceConfig
|
|
|
|
localRateLimit *localRateLimitConfig
|
|
|
|
Fallback *FallbackConfig
|
|
|
|
Auth *AuthConfig
|
|
|
|
Mirror *MirrorConfig
|
|
|
|
Destination *DestinationConfig
|
|
|
|
IgnoreCase *IgnoreCaseConfig
|
|
|
|
Match *MatchConfig
|
|
|
|
HeaderControl *HeaderControlConfig
|
|
|
|
Http2Rpc *Http2RpcConfig
|
|
}
|
|
|
|
func (i *Ingress) NeedRegexMatch(path string) bool {
|
|
if i.Rewrite == nil {
|
|
return false
|
|
}
|
|
if i.Rewrite.RewriteTarget != "" && strings.ContainsAny(path, `\.+*?()|[]{}^$`) {
|
|
return true
|
|
}
|
|
if strings.ContainsAny(i.Rewrite.RewriteTarget, `$\`) {
|
|
return true
|
|
}
|
|
return i.IsPrefixRegexMatch() || i.IsFullPathRegexMatch()
|
|
}
|
|
|
|
func (i *Ingress) IsPrefixRegexMatch() bool {
|
|
return i.Rewrite.UseRegex
|
|
}
|
|
|
|
func (i *Ingress) IsFullPathRegexMatch() bool {
|
|
return i.Rewrite.FullPathRegex
|
|
}
|
|
|
|
func (i *Ingress) IsCanary() bool {
|
|
if i.Canary == nil {
|
|
return false
|
|
}
|
|
|
|
return i.Canary.Enabled
|
|
}
|
|
|
|
// CanaryKind return byHeader, byWeight
|
|
func (i *Ingress) CanaryKind() (bool, bool) {
|
|
if !i.IsCanary() {
|
|
return false, false
|
|
}
|
|
|
|
// first header, cookie
|
|
if i.Canary.Header != "" || i.Canary.Cookie != "" {
|
|
return true, false
|
|
}
|
|
|
|
// then weight
|
|
return false, true
|
|
}
|
|
|
|
func (i *Ingress) NeedTrafficPolicy() bool {
|
|
return i.UpstreamTLS != nil ||
|
|
i.LoadBalance != nil
|
|
}
|
|
|
|
type AnnotationHandler interface {
|
|
Parser
|
|
GatewayHandler
|
|
VirtualServiceHandler
|
|
RouteHandler
|
|
TrafficPolicyHandler
|
|
}
|
|
|
|
type AnnotationHandlerManager struct {
|
|
parsers []Parser
|
|
gatewayHandlers []GatewayHandler
|
|
virtualServiceHandlers []VirtualServiceHandler
|
|
routeHandlers []RouteHandler
|
|
trafficPolicyHandlers []TrafficPolicyHandler
|
|
}
|
|
|
|
func NewAnnotationHandlerManager() AnnotationHandler {
|
|
return &AnnotationHandlerManager{
|
|
parsers: []Parser{
|
|
canary{},
|
|
cors{},
|
|
downstreamTLS{},
|
|
redirect{},
|
|
rewrite{},
|
|
upstreamTLS{},
|
|
ipAccessControl{},
|
|
timeout{},
|
|
retry{},
|
|
loadBalance{},
|
|
localRateLimit{},
|
|
fallback{},
|
|
auth{},
|
|
mirror{},
|
|
destination{},
|
|
ignoreCaseMatching{},
|
|
match{},
|
|
headerControl{},
|
|
http2rpc{},
|
|
mcpServer{},
|
|
},
|
|
gatewayHandlers: []GatewayHandler{
|
|
downstreamTLS{},
|
|
},
|
|
virtualServiceHandlers: []VirtualServiceHandler{
|
|
ipAccessControl{},
|
|
},
|
|
routeHandlers: []RouteHandler{
|
|
cors{},
|
|
redirect{},
|
|
rewrite{},
|
|
ipAccessControl{},
|
|
timeout{},
|
|
retry{},
|
|
localRateLimit{},
|
|
fallback{},
|
|
mirror{},
|
|
ignoreCaseMatching{},
|
|
match{},
|
|
headerControl{},
|
|
},
|
|
trafficPolicyHandlers: []TrafficPolicyHandler{
|
|
upstreamTLS{},
|
|
loadBalance{},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (h *AnnotationHandlerManager) Parse(annotations Annotations, config *Ingress, globalContext *GlobalContext) error {
|
|
for _, parser := range h.parsers {
|
|
_ = parser.Parse(annotations, config, globalContext)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (h *AnnotationHandlerManager) ApplyGateway(gateway *networking.Gateway, config *Ingress) {
|
|
for _, handler := range h.gatewayHandlers {
|
|
handler.ApplyGateway(gateway, config)
|
|
}
|
|
}
|
|
|
|
func (h *AnnotationHandlerManager) ApplyVirtualServiceHandler(virtualService *networking.VirtualService, config *Ingress) {
|
|
for _, handler := range h.virtualServiceHandlers {
|
|
handler.ApplyVirtualServiceHandler(virtualService, config)
|
|
}
|
|
}
|
|
|
|
func (h *AnnotationHandlerManager) ApplyRoute(route *networking.HTTPRoute, config *Ingress) {
|
|
for _, handler := range h.routeHandlers {
|
|
handler.ApplyRoute(route, config)
|
|
}
|
|
}
|
|
|
|
func (h *AnnotationHandlerManager) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy, portTrafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress) {
|
|
for _, handler := range h.trafficPolicyHandlers {
|
|
handler.ApplyTrafficPolicy(trafficPolicy, portTrafficPolicy, config)
|
|
}
|
|
}
|