blob: 668ee2066dcdabf9a9728ad5d7fb941b513c2e4c [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 envoy
import (
"context"
"fmt"
"sort"
)
import (
envoy_types "github.com/envoyproxy/go-control-plane/pkg/cache/types"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
)
import (
core_xds "github.com/apache/dubbo-kubernetes/pkg/core/xds"
"github.com/apache/dubbo-kubernetes/pkg/xds/envoy/tags"
)
type Cluster interface {
Service() string
Name() string
Mesh() string
Tags() tags.Tags
Hash() string
IsExternalService() bool
}
type Split interface {
ClusterName() string
Weight() uint32
LBMetadata() tags.Tags
HasExternalService() bool
}
// Deprecated: for new policies use pkg/plugins/policies/xds/cluster.go
type ClusterImpl struct {
service string
name string
weight uint32
tags tags.Tags
mesh string
isExternalService bool
}
func (c *ClusterImpl) Service() string { return c.service }
func (c *ClusterImpl) Name() string { return c.name }
func (c *ClusterImpl) Weight() uint32 { return c.weight }
func (c *ClusterImpl) Tags() tags.Tags { return c.tags }
// Mesh returns a non-empty string only if the cluster is in a different mesh
// from the context.
func (c *ClusterImpl) Mesh() string { return c.mesh }
func (c *ClusterImpl) IsExternalService() bool { return c.isExternalService }
func (c *ClusterImpl) Hash() string { return fmt.Sprintf("%s-%s", c.name, c.tags.String()) }
func (c *ClusterImpl) SetName(name string) {
c.name = name
}
func (c *ClusterImpl) SetMesh(mesh string) {
c.mesh = mesh
}
type NewClusterOpt interface {
apply(cluster *ClusterImpl)
}
type newClusterOptFunc func(cluster *ClusterImpl)
func (f newClusterOptFunc) apply(cluster *ClusterImpl) {
f(cluster)
}
// Deprecated: for new policies use pkg/plugins/policies/xds/cluster.go
func NewCluster(opts ...NewClusterOpt) *ClusterImpl {
c := &ClusterImpl{}
for _, opt := range opts {
opt.apply(c)
}
if err := c.validate(); err != nil {
panic(err)
}
return c
}
func (c *ClusterImpl) validate() error {
if c.service == "" || c.name == "" {
return errors.New("either WithService() or WithName() should be called")
}
return nil
}
func WithService(service string) NewClusterOpt {
return newClusterOptFunc(func(cluster *ClusterImpl) {
cluster.service = service
if len(cluster.name) == 0 {
cluster.name = service
}
})
}
func WithName(name string) NewClusterOpt {
return newClusterOptFunc(func(cluster *ClusterImpl) {
cluster.name = name
if len(cluster.service) == 0 {
cluster.service = name
}
})
}
func WithWeight(weight uint32) NewClusterOpt {
return newClusterOptFunc(func(cluster *ClusterImpl) {
cluster.weight = weight
})
}
func WithTags(tags tags.Tags) NewClusterOpt {
return newClusterOptFunc(func(cluster *ClusterImpl) {
cluster.tags = tags
})
}
func WithExternalService(isExternalService bool) NewClusterOpt {
return newClusterOptFunc(func(cluster *ClusterImpl) {
cluster.isExternalService = isExternalService
})
}
type Service struct {
name string
clusters []Cluster
hasExternalService bool
tlsReady bool
}
func (c *Service) Add(cluster Cluster) {
c.clusters = append(c.clusters, cluster)
if cluster.IsExternalService() {
c.hasExternalService = true
}
}
func (c *Service) Tags() []tags.Tags {
var result []tags.Tags
for _, cluster := range c.clusters {
result = append(result, cluster.Tags())
}
return result
}
func (c *Service) HasExternalService() bool {
return c.hasExternalService
}
func (c *Service) Clusters() []Cluster {
return c.clusters
}
func (c *Service) TLSReady() bool {
return c.tlsReady
}
type Services map[string]*Service
func (c Services) Sorted() []string {
var keys []string
for key := range c {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}
type ServicesAccumulator struct {
tlsReadiness map[string]bool
services map[string]*Service
}
func NewServicesAccumulator(tlsReadiness map[string]bool) ServicesAccumulator {
return ServicesAccumulator{
tlsReadiness: tlsReadiness,
services: map[string]*Service{},
}
}
func (sa ServicesAccumulator) Services() Services {
return sa.services
}
func (sa ServicesAccumulator) Add(clusters ...Cluster) {
for _, c := range clusters {
if sa.services[c.Service()] == nil {
sa.services[c.Service()] = &Service{
tlsReady: sa.tlsReadiness[c.Service()],
name: c.Service(),
}
}
sa.services[c.Service()].Add(c)
}
}
type CLACache interface {
GetCLA(ctx context.Context, meshName, meshHash string, cluster Cluster, apiVersion core_xds.APIVersion, endpointMap core_xds.EndpointMap) (proto.Message, error)
}
type NamedResource interface {
envoy_types.Resource
GetName() string
}
type TrafficDirection string
const (
TrafficDirectionOutbound TrafficDirection = "OUTBOUND"
TrafficDirectionInbound TrafficDirection = "INBOUND"
TrafficDirectionUnspecified TrafficDirection = "UNSPECIFIED"
)
type StaticEndpointPath struct {
Path string
ClusterName string
RewritePath string
Header string
HeaderExactMatch string
}