mirror of
https://github.com/alibaba/higress.git
synced 2026-06-09 20:57:32 +08:00
upgrade to istio 1.19 (#1211)
Co-authored-by: CH3CHO <ch3cho@qq.com> Co-authored-by: rinfx <893383980@qq.com>
This commit is contained in:
197
pkg/ingress/kube/gateway/controller.go
Normal file
197
pkg/ingress/kube/gateway/controller.go
Normal file
@@ -0,0 +1,197 @@
|
||||
// Copyright (c) 2023 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 gateway
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"istio.io/istio/pilot/pkg/config/kube/crdclient"
|
||||
"istio.io/istio/pilot/pkg/credentials"
|
||||
kubecredentials "istio.io/istio/pilot/pkg/credentials/kube"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
kubecontroller "istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/collection"
|
||||
"istio.io/istio/pkg/config/schema/collections"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/config/schema/resource"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/multicluster"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
higressconfig "github.com/alibaba/higress/pkg/config"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
istiogateway "github.com/alibaba/higress/pkg/ingress/kube/gateway/istio"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||
)
|
||||
|
||||
type gatewayController struct {
|
||||
virtualServiceHandlers []model.EventHandler
|
||||
gatewayHandlers []model.EventHandler
|
||||
destinationRuleHandlers []model.EventHandler
|
||||
envoyFilterHandlers []model.EventHandler
|
||||
|
||||
store model.ConfigStoreController
|
||||
credsController credentials.MulticlusterController
|
||||
istioController *istiogateway.Controller
|
||||
|
||||
resourceUpToDate atomic.Bool
|
||||
}
|
||||
|
||||
func NewController(client kube.Client, options common.Options) common.GatewayController {
|
||||
domainSuffix := util.GetDomainSuffix()
|
||||
opts := crdclient.Option{
|
||||
Revision: higressconfig.Revision,
|
||||
DomainSuffix: domainSuffix,
|
||||
Identifier: "gateway-controller",
|
||||
}
|
||||
schemasBuilder := collection.NewSchemasBuilder()
|
||||
collections.PilotGatewayAPI().ForEach(func(schema resource.Schema) bool {
|
||||
if schema.Group() == collections.GatewayClass.Group() {
|
||||
schemasBuilder.MustAdd(schema)
|
||||
}
|
||||
return false
|
||||
})
|
||||
store := crdclient.NewForSchemas(client, opts, schemasBuilder.Build())
|
||||
|
||||
clusterId := options.ClusterId
|
||||
credsController := kubecredentials.NewMulticluster(clusterId)
|
||||
credsController.ClusterAdded(&multicluster.Cluster{ID: clusterId, Client: client}, nil)
|
||||
istioController := istiogateway.NewController(client, store, client.CrdWatcher().WaitForCRD, credsController, kubecontroller.Options{DomainSuffix: domainSuffix})
|
||||
if options.GatewaySelectorKey != "" {
|
||||
istioController.DefaultGatewaySelector = map[string]string{options.GatewaySelectorKey: options.GatewaySelectorValue}
|
||||
}
|
||||
|
||||
if options.EnableStatus {
|
||||
// TODO: Add status sync support
|
||||
//istioController.SetStatusWrite(true,)
|
||||
} else {
|
||||
IngressLog.Infof("Disable status update for cluster %s", clusterId)
|
||||
}
|
||||
|
||||
return &gatewayController{
|
||||
store: store,
|
||||
credsController: credsController,
|
||||
istioController: istioController,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *gatewayController) Schemas() collection.Schemas {
|
||||
return g.istioController.Schemas()
|
||||
}
|
||||
|
||||
func (g *gatewayController) Get(typ config.GroupVersionKind, name, namespace string) *config.Config {
|
||||
return g.istioController.Get(typ, name, namespace)
|
||||
}
|
||||
|
||||
func (g *gatewayController) List(typ config.GroupVersionKind, namespace string) []config.Config {
|
||||
if g.resourceUpToDate.CompareAndSwap(false, true) {
|
||||
err := g.istioController.Reconcile(model.NewPushContext())
|
||||
if err != nil {
|
||||
IngressLog.Errorf("failed to recompute Gateway API resources: %v", err)
|
||||
}
|
||||
}
|
||||
return g.istioController.List(typ, namespace)
|
||||
}
|
||||
|
||||
func (g *gatewayController) Create(config config.Config) (revision string, err error) {
|
||||
return g.istioController.Create(config)
|
||||
}
|
||||
|
||||
func (g *gatewayController) Update(config config.Config) (newRevision string, err error) {
|
||||
return g.istioController.Update(config)
|
||||
}
|
||||
|
||||
func (g *gatewayController) UpdateStatus(config config.Config) (newRevision string, err error) {
|
||||
return g.istioController.UpdateStatus(config)
|
||||
}
|
||||
|
||||
func (g *gatewayController) Patch(orig config.Config, patchFn config.PatchFunc) (string, error) {
|
||||
return g.istioController.Patch(orig, patchFn)
|
||||
}
|
||||
|
||||
func (g *gatewayController) Delete(typ config.GroupVersionKind, name, namespace string, resourceVersion *string) error {
|
||||
return g.istioController.Delete(typ, name, namespace, resourceVersion)
|
||||
}
|
||||
|
||||
func (g *gatewayController) RegisterEventHandler(kind config.GroupVersionKind, f model.EventHandler) {
|
||||
switch kind {
|
||||
case gvk.VirtualService:
|
||||
g.virtualServiceHandlers = append(g.virtualServiceHandlers, f)
|
||||
case gvk.Gateway:
|
||||
g.gatewayHandlers = append(g.gatewayHandlers, f)
|
||||
case gvk.DestinationRule:
|
||||
g.destinationRuleHandlers = append(g.destinationRuleHandlers, f)
|
||||
case gvk.EnvoyFilter:
|
||||
g.envoyFilterHandlers = append(g.envoyFilterHandlers, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *gatewayController) Run(stop <-chan struct{}) {
|
||||
g.store.Schemas().ForEach(func(schema resource.Schema) bool {
|
||||
g.store.RegisterEventHandler(schema.GroupVersionKind(), g.onEvent)
|
||||
return false
|
||||
})
|
||||
go g.store.Run(stop)
|
||||
go g.istioController.Run(stop)
|
||||
}
|
||||
|
||||
func (g *gatewayController) SetWatchErrorHandler(f func(r *cache.Reflector, err error)) error {
|
||||
// TODO: implement
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *gatewayController) HasSynced() bool {
|
||||
ret := g.istioController.HasSynced()
|
||||
if ret {
|
||||
err := g.istioController.Reconcile(model.NewPushContext())
|
||||
if err != nil {
|
||||
IngressLog.Errorf("failed to recompute Gateway API resources: %v", err)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (g *gatewayController) onEvent(prev config.Config, curr config.Config, event model.Event) {
|
||||
g.resourceUpToDate.Store(false)
|
||||
|
||||
name := "gateway-api"
|
||||
namespace := curr.Namespace
|
||||
|
||||
vsMetadata := config.Meta{
|
||||
Name: name + "-" + "virtualservice",
|
||||
Namespace: namespace,
|
||||
GroupVersionKind: gvk.VirtualService,
|
||||
// Set this label so that we do not compare configs and just push.
|
||||
Labels: map[string]string{constants.AlwaysPushLabel: "true"},
|
||||
}
|
||||
gatewayMetadata := config.Meta{
|
||||
Name: name + "-" + "gateway",
|
||||
Namespace: namespace,
|
||||
GroupVersionKind: gvk.Gateway,
|
||||
// Set this label so that we do not compare configs and just push.
|
||||
Labels: map[string]string{constants.AlwaysPushLabel: "true"},
|
||||
}
|
||||
|
||||
for _, f := range g.virtualServiceHandlers {
|
||||
f(config.Config{Meta: vsMetadata}, config.Config{Meta: vsMetadata}, event)
|
||||
}
|
||||
|
||||
for _, f := range g.gatewayHandlers {
|
||||
f(config.Config{Meta: gatewayMetadata}, config.Config{Meta: gatewayMetadata}, event)
|
||||
}
|
||||
}
|
||||
362
pkg/ingress/kube/gateway/istio/conditions.go
Normal file
362
pkg/ingress/kube/gateway/istio/conditions.go
Normal file
@@ -0,0 +1,362 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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 istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"istio.io/istio/pilot/pkg/model/kstatus"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/maps"
|
||||
"istio.io/istio/pkg/ptr"
|
||||
"istio.io/istio/pkg/slices"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
k8sbeta "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/pkg/config/constants"
|
||||
)
|
||||
|
||||
// RouteParentResult holds the result of a route for a specific parent
|
||||
type RouteParentResult struct {
|
||||
// OriginalReference contains the original reference
|
||||
OriginalReference k8s.ParentReference
|
||||
// DeniedReason, if present, indicates why the reference was not valid
|
||||
DeniedReason *ParentError
|
||||
// RouteError, if present, indicates why the reference was not valid
|
||||
RouteError *ConfigError
|
||||
}
|
||||
|
||||
func createRouteStatus(parentResults []RouteParentResult, obj config.Config, currentParents []k8s.RouteParentStatus) []k8s.RouteParentStatus {
|
||||
parents := make([]k8s.RouteParentStatus, 0, len(parentResults))
|
||||
// Fill in all the gateways that are already present but not owned by us. This is non-trivial as there may be multiple
|
||||
// gateway controllers that are exposing their status on the same route. We need to attempt to manage ours properly (including
|
||||
// removing gateway references when they are removed), without mangling other Controller's status.
|
||||
for _, r := range currentParents {
|
||||
if r.ControllerName != constants.ManagedGatewayController {
|
||||
// We don't own this status, so keep it around
|
||||
parents = append(parents, r)
|
||||
}
|
||||
}
|
||||
// Collect all of our unique parent references. There may be multiple when we have a route without section name,
|
||||
// but reference a parent with multiple sections.
|
||||
// While we process these internally for-each sectionName, in the status we are just supposed to report one merged entry
|
||||
seen := map[k8s.ParentReference][]RouteParentResult{}
|
||||
seenReasons := sets.New[ParentErrorReason]()
|
||||
successCount := map[k8s.ParentReference]int{}
|
||||
for _, incoming := range parentResults {
|
||||
// We will append it if it is our first occurrence, or the existing one has an error. This means
|
||||
// if *any* section has no errors, we will declare Admitted
|
||||
if incoming.DeniedReason == nil {
|
||||
successCount[incoming.OriginalReference]++
|
||||
}
|
||||
seen[incoming.OriginalReference] = append(seen[incoming.OriginalReference], incoming)
|
||||
if incoming.DeniedReason != nil {
|
||||
seenReasons.Insert(incoming.DeniedReason.Reason)
|
||||
} else {
|
||||
seenReasons.Insert(ParentNoError)
|
||||
}
|
||||
}
|
||||
reasonRanking := []ParentErrorReason{
|
||||
// No errors is preferred
|
||||
ParentNoError,
|
||||
// All route level errors
|
||||
ParentErrorNotAllowed,
|
||||
ParentErrorNoHostname,
|
||||
ParentErrorParentRefConflict,
|
||||
// Failures to match the Port or SectionName. These are last so that if we bind to 1 listener we
|
||||
// just report errors for that 1 listener instead of for all sections we didn't bind to
|
||||
ParentErrorNotAccepted,
|
||||
}
|
||||
// Next we want to collapse these. We need to report 1 type of error, or none.
|
||||
report := map[k8s.ParentReference]RouteParentResult{}
|
||||
for _, wantReason := range reasonRanking {
|
||||
if !seenReasons.Contains(wantReason) {
|
||||
continue
|
||||
}
|
||||
// We found our highest priority ranking, now we need to collapse this into a single message
|
||||
for k, refs := range seen {
|
||||
for _, ref := range refs {
|
||||
reason := ParentNoError
|
||||
if ref.DeniedReason != nil {
|
||||
reason = ref.DeniedReason.Reason
|
||||
}
|
||||
if wantReason != reason {
|
||||
// Skip this one, it is for a less relevant reason
|
||||
continue
|
||||
}
|
||||
exist, f := report[k]
|
||||
if f {
|
||||
if ref.DeniedReason != nil {
|
||||
if exist.DeniedReason != nil {
|
||||
// join the error
|
||||
exist.DeniedReason.Message += "; " + ref.DeniedReason.Message
|
||||
} else {
|
||||
exist.DeniedReason = ref.DeniedReason
|
||||
}
|
||||
}
|
||||
} else {
|
||||
exist = ref
|
||||
}
|
||||
report[k] = exist
|
||||
}
|
||||
}
|
||||
// Once we find the best reason, do not consider any others
|
||||
break
|
||||
}
|
||||
|
||||
// Now we fill in all the parents we do own
|
||||
for k, gw := range report {
|
||||
msg := "Route was valid"
|
||||
if successCount[k] > 1 {
|
||||
msg = fmt.Sprintf("Route was valid, bound to %d parents", successCount[k])
|
||||
}
|
||||
conds := map[string]*condition{
|
||||
string(k8s.RouteConditionAccepted): {
|
||||
reason: string(k8s.RouteReasonAccepted),
|
||||
message: msg,
|
||||
},
|
||||
string(k8s.RouteConditionResolvedRefs): {
|
||||
reason: string(k8s.RouteReasonResolvedRefs),
|
||||
message: "All references resolved",
|
||||
},
|
||||
}
|
||||
if gw.RouteError != nil {
|
||||
// Currently, the spec is not clear on where errors should be reported. The provided resources are:
|
||||
// * Accepted - used to describe errors binding to parents
|
||||
// * ResolvedRefs - used to describe errors about binding to objects
|
||||
// But no general errors
|
||||
// For now, we will treat all general route errors as "Ref" errors.
|
||||
conds[string(k8s.RouteConditionResolvedRefs)].error = gw.RouteError
|
||||
}
|
||||
if gw.DeniedReason != nil {
|
||||
conds[string(k8s.RouteConditionAccepted)].error = &ConfigError{
|
||||
Reason: ConfigErrorReason(gw.DeniedReason.Reason),
|
||||
Message: gw.DeniedReason.Message,
|
||||
}
|
||||
}
|
||||
|
||||
var currentConditions []metav1.Condition
|
||||
currentStatus := slices.FindFunc(currentParents, func(s k8sbeta.RouteParentStatus) bool {
|
||||
return parentRefString(s.ParentRef) == parentRefString(gw.OriginalReference)
|
||||
})
|
||||
if currentStatus != nil {
|
||||
currentConditions = currentStatus.Conditions
|
||||
}
|
||||
parents = append(parents, k8s.RouteParentStatus{
|
||||
ParentRef: gw.OriginalReference,
|
||||
ControllerName: constants.ManagedGatewayController,
|
||||
Conditions: setConditions(obj.Generation, currentConditions, conds),
|
||||
})
|
||||
}
|
||||
// Ensure output is deterministic.
|
||||
// TODO: will we fight over other controllers doing similar (but not identical) ordering?
|
||||
sort.SliceStable(parents, func(i, j int) bool {
|
||||
return parentRefString(parents[i].ParentRef) > parentRefString(parents[j].ParentRef)
|
||||
})
|
||||
return parents
|
||||
}
|
||||
|
||||
type ParentErrorReason string
|
||||
|
||||
const (
|
||||
ParentErrorNotAccepted = ParentErrorReason(k8sbeta.RouteReasonNoMatchingParent)
|
||||
ParentErrorNotAllowed = ParentErrorReason(k8s.RouteReasonNotAllowedByListeners)
|
||||
ParentErrorNoHostname = ParentErrorReason(k8s.RouteReasonNoMatchingListenerHostname)
|
||||
ParentErrorParentRefConflict = ParentErrorReason("ParentRefConflict")
|
||||
ParentNoError = ParentErrorReason("")
|
||||
)
|
||||
|
||||
type ConfigErrorReason = string
|
||||
|
||||
const (
|
||||
// InvalidRefNotPermitted indicates a route was not permitted
|
||||
InvalidRefNotPermitted ConfigErrorReason = ConfigErrorReason(k8s.RouteReasonRefNotPermitted)
|
||||
// InvalidDestination indicates an issue with the destination
|
||||
InvalidDestination ConfigErrorReason = "InvalidDestination"
|
||||
InvalidAddress ConfigErrorReason = ConfigErrorReason(k8sbeta.GatewayReasonUnsupportedAddress)
|
||||
// InvalidDestinationPermit indicates a destination was not permitted
|
||||
InvalidDestinationPermit ConfigErrorReason = ConfigErrorReason(k8s.RouteReasonRefNotPermitted)
|
||||
// InvalidDestinationKind indicates an issue with the destination kind
|
||||
InvalidDestinationKind ConfigErrorReason = ConfigErrorReason(k8s.RouteReasonInvalidKind)
|
||||
// InvalidDestinationNotFound indicates a destination does not exist
|
||||
InvalidDestinationNotFound ConfigErrorReason = ConfigErrorReason(k8s.RouteReasonBackendNotFound)
|
||||
// InvalidParentRef indicates we could not refer to the parent we request
|
||||
InvalidParentRef ConfigErrorReason = "InvalidParentReference"
|
||||
// InvalidFilter indicates an issue with the filters
|
||||
InvalidFilter ConfigErrorReason = "InvalidFilter"
|
||||
// InvalidTLS indicates an issue with TLS settings
|
||||
InvalidTLS ConfigErrorReason = ConfigErrorReason(k8sbeta.ListenerReasonInvalidCertificateRef)
|
||||
// InvalidListenerRefNotPermitted indicates a listener reference was not permitted
|
||||
InvalidListenerRefNotPermitted ConfigErrorReason = ConfigErrorReason(k8sbeta.ListenerReasonRefNotPermitted)
|
||||
// InvalidConfiguration indicates a generic error for all other invalid configurations
|
||||
InvalidConfiguration ConfigErrorReason = "InvalidConfiguration"
|
||||
InvalidResources ConfigErrorReason = ConfigErrorReason(k8sbeta.GatewayReasonNoResources)
|
||||
DeprecateFieldUsage = "DeprecatedField"
|
||||
)
|
||||
|
||||
// ParentError represents that a parent could not be referenced
|
||||
type ParentError struct {
|
||||
Reason ParentErrorReason
|
||||
Message string
|
||||
}
|
||||
|
||||
// ConfigError represents an invalid configuration that will be reported back to the user.
|
||||
type ConfigError struct {
|
||||
Reason ConfigErrorReason
|
||||
Message string
|
||||
}
|
||||
|
||||
type condition struct {
|
||||
// reason defines the reason to report on success. Ignored if error is set
|
||||
reason string
|
||||
// message defines the message to report on success. Ignored if error is set
|
||||
message string
|
||||
// status defines the status to report on success. The inverse will be set if error is set
|
||||
// If not set, will default to StatusTrue
|
||||
status metav1.ConditionStatus
|
||||
// error defines an error state; the reason and message will be replaced with that of the error and
|
||||
// the status inverted
|
||||
error *ConfigError
|
||||
// setOnce, if enabled, will only set the condition if it is not yet present or set to this reason
|
||||
setOnce string
|
||||
}
|
||||
|
||||
// setConditions sets the existingConditions with the new conditions
|
||||
func setConditions(generation int64, existingConditions []metav1.Condition, conditions map[string]*condition) []metav1.Condition {
|
||||
// Sort keys for deterministic ordering
|
||||
for _, k := range slices.Sort(maps.Keys(conditions)) {
|
||||
cond := conditions[k]
|
||||
setter := kstatus.UpdateConditionIfChanged
|
||||
if cond.setOnce != "" {
|
||||
setter = func(conditions []metav1.Condition, condition metav1.Condition) []metav1.Condition {
|
||||
return kstatus.CreateCondition(conditions, condition, cond.setOnce)
|
||||
}
|
||||
}
|
||||
// A condition can be "negative polarity" (ex: ListenerInvalid) or "positive polarity" (ex:
|
||||
// ListenerValid), so in order to determine the status we should set each `condition` defines its
|
||||
// default positive status. When there is an error, we will invert that. Example: If we have
|
||||
// condition ListenerInvalid, the status will be set to StatusFalse. If an error is reported, it
|
||||
// will be inverted to StatusTrue to indicate listeners are invalid. See
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
|
||||
// for more information
|
||||
if cond.error != nil {
|
||||
existingConditions = setter(existingConditions, metav1.Condition{
|
||||
Type: k,
|
||||
Status: kstatus.InvertStatus(cond.status),
|
||||
ObservedGeneration: generation,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: cond.error.Reason,
|
||||
Message: cond.error.Message,
|
||||
})
|
||||
} else {
|
||||
status := cond.status
|
||||
if status == "" {
|
||||
status = kstatus.StatusTrue
|
||||
}
|
||||
existingConditions = setter(existingConditions, metav1.Condition{
|
||||
Type: k,
|
||||
Status: status,
|
||||
ObservedGeneration: generation,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: cond.reason,
|
||||
Message: cond.message,
|
||||
})
|
||||
}
|
||||
}
|
||||
return existingConditions
|
||||
}
|
||||
|
||||
func reportListenerAttachedRoutes(index int, obj config.Config, i int32) {
|
||||
obj.Status.(*kstatus.WrappedStatus).Mutate(func(s config.Status) config.Status {
|
||||
gs := s.(*k8s.GatewayStatus)
|
||||
for index >= len(gs.Listeners) {
|
||||
gs.Listeners = append(gs.Listeners, k8s.ListenerStatus{})
|
||||
}
|
||||
status := gs.Listeners[index]
|
||||
status.AttachedRoutes = i
|
||||
gs.Listeners[index] = status
|
||||
return gs
|
||||
})
|
||||
}
|
||||
|
||||
func reportListenerCondition(index int, l k8s.Listener, obj config.Config, conditions map[string]*condition) {
|
||||
obj.Status.(*kstatus.WrappedStatus).Mutate(func(s config.Status) config.Status {
|
||||
gs := s.(*k8s.GatewayStatus)
|
||||
for index >= len(gs.Listeners) {
|
||||
gs.Listeners = append(gs.Listeners, k8s.ListenerStatus{})
|
||||
}
|
||||
cond := gs.Listeners[index].Conditions
|
||||
supported, valid := generateSupportedKinds(l)
|
||||
if !valid {
|
||||
conditions[string(k8sbeta.ListenerConditionResolvedRefs)] = &condition{
|
||||
reason: string(k8sbeta.ListenerReasonInvalidRouteKinds),
|
||||
status: metav1.ConditionFalse,
|
||||
message: "Invalid route kinds",
|
||||
}
|
||||
}
|
||||
gs.Listeners[index] = k8s.ListenerStatus{
|
||||
Name: l.Name,
|
||||
AttachedRoutes: 0, // this will be reported later
|
||||
SupportedKinds: supported,
|
||||
Conditions: setConditions(obj.Generation, cond, conditions),
|
||||
}
|
||||
return gs
|
||||
})
|
||||
}
|
||||
|
||||
func generateSupportedKinds(l k8s.Listener) ([]k8s.RouteGroupKind, bool) {
|
||||
supported := []k8s.RouteGroupKind{}
|
||||
switch l.Protocol {
|
||||
case k8sbeta.HTTPProtocolType, k8sbeta.HTTPSProtocolType:
|
||||
// Only terminate allowed, so its always HTTP
|
||||
supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.HTTPRoute.Group)), Kind: k8s.Kind(gvk.HTTPRoute.Kind)}}
|
||||
case k8sbeta.TCPProtocolType:
|
||||
supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.TCPRoute.Group)), Kind: k8s.Kind(gvk.TCPRoute.Kind)}}
|
||||
case k8sbeta.TLSProtocolType:
|
||||
if l.TLS != nil && l.TLS.Mode != nil && *l.TLS.Mode == k8sbeta.TLSModePassthrough {
|
||||
supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.TLSRoute.Group)), Kind: k8s.Kind(gvk.TLSRoute.Kind)}}
|
||||
} else {
|
||||
supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.TCPRoute.Group)), Kind: k8s.Kind(gvk.TCPRoute.Kind)}}
|
||||
}
|
||||
// UDP route note support
|
||||
}
|
||||
if l.AllowedRoutes != nil && len(l.AllowedRoutes.Kinds) > 0 {
|
||||
// We need to filter down to only ones we actually support
|
||||
intersection := []k8s.RouteGroupKind{}
|
||||
for _, s := range supported {
|
||||
for _, kind := range l.AllowedRoutes.Kinds {
|
||||
if routeGroupKindEqual(s, kind) {
|
||||
intersection = append(intersection, s)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return intersection, len(intersection) == len(l.AllowedRoutes.Kinds)
|
||||
}
|
||||
return supported, true
|
||||
}
|
||||
|
||||
// This and the following function really belongs in some gateway-api lib
|
||||
func routeGroupKindEqual(rgk1, rgk2 k8s.RouteGroupKind) bool {
|
||||
return rgk1.Kind == rgk2.Kind && getGroup(rgk1) == getGroup(rgk2)
|
||||
}
|
||||
|
||||
func getGroup(rgk k8s.RouteGroupKind) k8s.Group {
|
||||
return ptr.OrDefault(rgk.Group, k8s.Group(gvk.KubernetesGateway.Group))
|
||||
}
|
||||
110
pkg/ingress/kube/gateway/istio/conditions_test.go
Normal file
110
pkg/ingress/kube/gateway/istio/conditions_test.go
Normal file
@@ -0,0 +1,110 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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 istio
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/pkg/config/constants"
|
||||
)
|
||||
|
||||
func TestCreateRouteStatus(t *testing.T) {
|
||||
lastTransitionTime := metav1.Now()
|
||||
parentRef := httpRouteSpec.ParentRefs[0]
|
||||
parentStatus := []k8s.RouteParentStatus{
|
||||
{
|
||||
ParentRef: parentRef,
|
||||
ControllerName: constants.ManagedGatewayController,
|
||||
Conditions: []metav1.Condition{
|
||||
{
|
||||
Type: string(k8s.RouteReasonAccepted),
|
||||
Status: metav1.ConditionTrue,
|
||||
ObservedGeneration: 1,
|
||||
LastTransitionTime: lastTransitionTime,
|
||||
Message: "Route was valid",
|
||||
},
|
||||
{
|
||||
Type: string(k8s.RouteConditionResolvedRefs),
|
||||
Status: metav1.ConditionTrue,
|
||||
ObservedGeneration: 1,
|
||||
LastTransitionTime: lastTransitionTime,
|
||||
Message: "All references resolved",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
httpRoute := config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.HTTPRoute,
|
||||
Namespace: "foo",
|
||||
Name: "bar",
|
||||
Generation: 1,
|
||||
},
|
||||
Spec: &httpRouteSpec,
|
||||
Status: &k8s.HTTPRouteStatus{
|
||||
RouteStatus: k8s.RouteStatus{
|
||||
Parents: parentStatus,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type args struct {
|
||||
gateways []RouteParentResult
|
||||
obj config.Config
|
||||
current []k8s.RouteParentStatus
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantEqual bool
|
||||
}{
|
||||
{
|
||||
name: "no error",
|
||||
args: args{
|
||||
gateways: []RouteParentResult{{OriginalReference: parentRef}},
|
||||
obj: httpRoute,
|
||||
current: parentStatus,
|
||||
},
|
||||
wantEqual: true,
|
||||
},
|
||||
{
|
||||
name: "route status error",
|
||||
args: args{
|
||||
gateways: []RouteParentResult{{OriginalReference: parentRef, RouteError: &ConfigError{
|
||||
Reason: ConfigErrorReason(k8s.RouteReasonRefNotPermitted),
|
||||
}}},
|
||||
obj: httpRoute,
|
||||
current: parentStatus,
|
||||
},
|
||||
wantEqual: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := createRouteStatus(tt.args.gateways, tt.args.obj, tt.args.current)
|
||||
equal := reflect.DeepEqual(got, tt.args.current)
|
||||
if equal != tt.wantEqual {
|
||||
t.Errorf("route status: old: %+v, new: %+v", tt.args.current, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
133
pkg/ingress/kube/gateway/istio/context.go
Normal file
133
pkg/ingress/kube/gateway/istio/context.go
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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 istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pkg/cluster"
|
||||
"istio.io/istio/pkg/config/host"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// GatewayContext contains a minimal subset of push context functionality to be exposed to GatewayAPIControllers
|
||||
type GatewayContext struct {
|
||||
ps *model.PushContext
|
||||
}
|
||||
|
||||
func NewGatewayContext(ps *model.PushContext) GatewayContext {
|
||||
return GatewayContext{ps}
|
||||
}
|
||||
|
||||
// ResolveGatewayInstances attempts to resolve all instances that a gateway will be exposed on.
|
||||
// Note: this function considers *all* instances of the service; its possible those instances will not actually be properly functioning
|
||||
// gateways, so this is not 100% accurate, but sufficient to expose intent to users.
|
||||
// The actual configuration generation is done on a per-workload basis and will get the exact set of matched instances for that workload.
|
||||
// Four sets are exposed:
|
||||
// * Internal addresses (eg istio-ingressgateway.istio-system.svc.cluster.local:80).
|
||||
// * External addresses (eg 1.2.3.4), this comes from LoadBalancer services. There may be multiple in some cases (especially multi cluster).
|
||||
// * Pending addresses (eg istio-ingressgateway.istio-system.svc), are LoadBalancer-type services with pending external addresses.
|
||||
// * Warnings for references that could not be resolved. These are intended to be user facing.
|
||||
func (gc GatewayContext) ResolveGatewayInstances(
|
||||
namespace string,
|
||||
gwsvcs []string,
|
||||
servers []*networking.Server,
|
||||
) (internal, external, pending, warns []string) {
|
||||
ports := map[int]struct{}{}
|
||||
for _, s := range servers {
|
||||
ports[int(s.Port.Number)] = struct{}{}
|
||||
}
|
||||
foundInternal := sets.New[string]()
|
||||
foundExternal := sets.New[string]()
|
||||
foundPending := sets.New[string]()
|
||||
warnings := []string{}
|
||||
for _, g := range gwsvcs {
|
||||
svc, f := gc.ps.ServiceIndex.HostnameAndNamespace[host.Name(g)][namespace]
|
||||
if !f {
|
||||
otherNamespaces := []string{}
|
||||
for ns := range gc.ps.ServiceIndex.HostnameAndNamespace[host.Name(g)] {
|
||||
otherNamespaces = append(otherNamespaces, `"`+ns+`"`) // Wrap in quotes for output
|
||||
}
|
||||
if len(otherNamespaces) > 0 {
|
||||
sort.Strings(otherNamespaces)
|
||||
warnings = append(warnings, fmt.Sprintf("hostname %q not found in namespace %q, but it was found in namespace(s) %v",
|
||||
g, namespace, strings.Join(otherNamespaces, ", ")))
|
||||
} else {
|
||||
warnings = append(warnings, fmt.Sprintf("hostname %q not found", g))
|
||||
}
|
||||
continue
|
||||
}
|
||||
svcKey := svc.Key()
|
||||
for port := range ports {
|
||||
instances := gc.ps.ServiceInstancesByPort(svc, port, nil)
|
||||
if len(instances) > 0 {
|
||||
foundInternal.Insert(fmt.Sprintf("%s:%d", g, port))
|
||||
if svc.Attributes.ClusterExternalAddresses.Len() > 0 {
|
||||
// Fetch external IPs from all clusters
|
||||
svc.Attributes.ClusterExternalAddresses.ForEach(func(c cluster.ID, externalIPs []string) {
|
||||
foundExternal.InsertAll(externalIPs...)
|
||||
})
|
||||
} else if corev1.ServiceType(svc.Attributes.Type) == corev1.ServiceTypeLoadBalancer {
|
||||
if !foundPending.Contains(g) {
|
||||
warnings = append(warnings, fmt.Sprintf("address pending for hostname %q", g))
|
||||
foundPending.Insert(g)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
instancesByPort := gc.ps.ServiceInstances(svcKey)
|
||||
if instancesEmpty(instancesByPort) {
|
||||
warnings = append(warnings, fmt.Sprintf("no instances found for hostname %q", g))
|
||||
} else {
|
||||
hintPort := sets.New[string]()
|
||||
for _, instances := range instancesByPort {
|
||||
for _, i := range instances {
|
||||
if i.Endpoint.EndpointPort == uint32(port) {
|
||||
hintPort.Insert(strconv.Itoa(i.ServicePort.Port))
|
||||
}
|
||||
}
|
||||
}
|
||||
if hintPort.Len() > 0 {
|
||||
warnings = append(warnings, fmt.Sprintf(
|
||||
"port %d not found for hostname %q (hint: the service port should be specified, not the workload port. Did you mean one of these ports: %v?)",
|
||||
port, g, sets.SortedList(hintPort)))
|
||||
} else {
|
||||
warnings = append(warnings, fmt.Sprintf("port %d not found for hostname %q", port, g))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(warnings)
|
||||
return sets.SortedList(foundInternal), sets.SortedList(foundExternal), sets.SortedList(foundPending), warnings
|
||||
}
|
||||
|
||||
func (gc GatewayContext) GetService(hostname, namespace string) *model.Service {
|
||||
return gc.ps.ServiceIndex.HostnameAndNamespace[host.Name(hostname)][namespace]
|
||||
}
|
||||
|
||||
func instancesEmpty(m map[int][]*model.ServiceInstance) bool {
|
||||
for _, instances := range m {
|
||||
if len(instances) > 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
403
pkg/ingress/kube/gateway/istio/controller.go
Normal file
403
pkg/ingress/kube/gateway/istio/controller.go
Normal file
@@ -0,0 +1,403 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
"istio.io/istio/pilot/pkg/credentials"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pilot/pkg/model/kstatus"
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pilot/pkg/status"
|
||||
"istio.io/istio/pkg/cluster"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/labels"
|
||||
"istio.io/istio/pkg/config/schema/collection"
|
||||
"istio.io/istio/pkg/config/schema/collections"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/config/schema/gvr"
|
||||
"istio.io/istio/pkg/config/schema/kind"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/controllers"
|
||||
"istio.io/istio/pkg/kube/kclient"
|
||||
istiolog "istio.io/istio/pkg/log"
|
||||
"istio.io/istio/pkg/maps"
|
||||
"istio.io/istio/pkg/slices"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
klabels "k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var log = istiolog.RegisterScope("gateway", "gateway-api controller")
|
||||
|
||||
var errUnsupportedOp = fmt.Errorf("unsupported operation: the gateway config store is a read-only view")
|
||||
|
||||
// Controller defines the controller for the gateway-api. The controller acts a bit different from most.
|
||||
// Rather than watching the CRs directly, we depend on the existing model.ConfigStoreController which
|
||||
// already watches all CRs. When there are updates, a new PushContext will be computed, which will eventually
|
||||
// call Controller.Reconcile(). Once this happens, we will inspect the current state of the world, and transform
|
||||
// gateway-api types into Istio types (Gateway/VirtualService). Future calls to Get/List will return these
|
||||
// Istio types. These are not stored in the cluster at all, and are purely internal; they can be seen on /debug/configz.
|
||||
// During Reconcile(), the status on all gateway-api types is also tracked. Once completed, if the status
|
||||
// has changed at all, it is queued to asynchronously update the status of the object in Kubernetes.
|
||||
type Controller struct {
|
||||
// client for accessing Kubernetes
|
||||
client kube.Client
|
||||
// cache provides access to the underlying gateway-configs
|
||||
cache model.ConfigStoreController
|
||||
|
||||
// Gateway-api types reference namespace labels directly, so we need access to these
|
||||
namespaces kclient.Client[*corev1.Namespace]
|
||||
namespaceHandler model.EventHandler
|
||||
|
||||
// Gateway-api types reference secrets directly, so we need access to these
|
||||
credentialsController credentials.MulticlusterController
|
||||
secretHandler model.EventHandler
|
||||
|
||||
// the cluster where the gateway-api controller runs
|
||||
cluster cluster.ID
|
||||
// domain stores the cluster domain, typically cluster.local
|
||||
domain string
|
||||
|
||||
// state is our computed Istio resources. Access is guarded by stateMu. This is updated from Reconcile().
|
||||
state IstioResources
|
||||
stateMu sync.RWMutex
|
||||
|
||||
// statusController controls the status working queue. Status will only be written if statusEnabled is true, which
|
||||
// is only the case when we are the leader.
|
||||
statusController *status.Controller
|
||||
statusEnabled *atomic.Bool
|
||||
|
||||
// Start - Added by Higress
|
||||
DefaultGatewaySelector map[string]string
|
||||
// End - Added by Higress
|
||||
|
||||
waitForCRD func(class schema.GroupVersionResource, stop <-chan struct{}) bool
|
||||
}
|
||||
|
||||
var _ model.GatewayController = &Controller{}
|
||||
|
||||
func NewController(
|
||||
kc kube.Client,
|
||||
c model.ConfigStoreController,
|
||||
waitForCRD func(class schema.GroupVersionResource, stop <-chan struct{}) bool,
|
||||
credsController credentials.MulticlusterController,
|
||||
options controller.Options,
|
||||
) *Controller {
|
||||
var ctl *status.Controller
|
||||
|
||||
namespaces := kclient.New[*corev1.Namespace](kc)
|
||||
gatewayController := &Controller{
|
||||
client: kc,
|
||||
cache: c,
|
||||
namespaces: namespaces,
|
||||
credentialsController: credsController,
|
||||
cluster: options.ClusterID,
|
||||
domain: options.DomainSuffix,
|
||||
statusController: ctl,
|
||||
// Disabled by default, we will enable only if we win the leader election
|
||||
statusEnabled: atomic.NewBool(false),
|
||||
waitForCRD: waitForCRD,
|
||||
}
|
||||
|
||||
namespaces.AddEventHandler(controllers.EventHandler[*corev1.Namespace]{
|
||||
UpdateFunc: func(oldNs, newNs *corev1.Namespace) {
|
||||
if options.DiscoveryNamespacesFilter != nil && !options.DiscoveryNamespacesFilter.Filter(newNs) {
|
||||
return
|
||||
}
|
||||
if !labels.Instance(oldNs.Labels).Equals(newNs.Labels) {
|
||||
gatewayController.namespaceEvent(oldNs, newNs)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if credsController != nil {
|
||||
credsController.AddSecretHandler(gatewayController.secretEvent)
|
||||
}
|
||||
|
||||
return gatewayController
|
||||
}
|
||||
|
||||
func (c *Controller) Schemas() collection.Schemas {
|
||||
return collection.SchemasFor(
|
||||
collections.VirtualService,
|
||||
collections.Gateway,
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Controller) Get(typ config.GroupVersionKind, name, namespace string) *config.Config {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) List(typ config.GroupVersionKind, namespace string) []config.Config {
|
||||
if typ != gvk.Gateway && typ != gvk.VirtualService {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.stateMu.RLock()
|
||||
defer c.stateMu.RUnlock()
|
||||
switch typ {
|
||||
case gvk.Gateway:
|
||||
return filterNamespace(c.state.Gateway, namespace)
|
||||
case gvk.VirtualService:
|
||||
return filterNamespace(c.state.VirtualService, namespace)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) SetStatusWrite(enabled bool, statusManager *status.Manager) {
|
||||
c.statusEnabled.Store(enabled)
|
||||
if enabled && features.EnableGatewayAPIStatus && statusManager != nil {
|
||||
c.statusController = statusManager.CreateGenericController(func(status any, context any) status.GenerationProvider {
|
||||
return &gatewayGeneration{context}
|
||||
})
|
||||
} else {
|
||||
c.statusController = nil
|
||||
}
|
||||
}
|
||||
|
||||
// Reconcile takes in a current snapshot of the gateway-api configs, and regenerates our internal state.
|
||||
// Any status updates required will be enqueued as well.
|
||||
func (c *Controller) Reconcile(ps *model.PushContext) error {
|
||||
t0 := time.Now()
|
||||
defer func() {
|
||||
log.Debugf("reconcile complete in %v", time.Since(t0))
|
||||
}()
|
||||
gatewayClass := c.cache.List(gvk.GatewayClass, metav1.NamespaceAll)
|
||||
gateway := c.cache.List(gvk.KubernetesGateway, metav1.NamespaceAll)
|
||||
httpRoute := c.cache.List(gvk.HTTPRoute, metav1.NamespaceAll)
|
||||
tcpRoute := c.cache.List(gvk.TCPRoute, metav1.NamespaceAll)
|
||||
tlsRoute := c.cache.List(gvk.TLSRoute, metav1.NamespaceAll)
|
||||
referenceGrant := c.cache.List(gvk.ReferenceGrant, metav1.NamespaceAll)
|
||||
|
||||
input := GatewayResources{
|
||||
GatewayClass: deepCopyStatus(gatewayClass),
|
||||
Gateway: deepCopyStatus(gateway),
|
||||
HTTPRoute: deepCopyStatus(httpRoute),
|
||||
TCPRoute: deepCopyStatus(tcpRoute),
|
||||
TLSRoute: deepCopyStatus(tlsRoute),
|
||||
ReferenceGrant: referenceGrant,
|
||||
DefaultGatewaySelector: c.DefaultGatewaySelector,
|
||||
Domain: c.domain,
|
||||
Context: NewGatewayContext(ps),
|
||||
}
|
||||
|
||||
if !input.hasResources() {
|
||||
// Early exit for common case of no gateway-api used.
|
||||
c.stateMu.Lock()
|
||||
defer c.stateMu.Unlock()
|
||||
// make sure we clear out the state, to handle the last gateway-api resource being removed
|
||||
c.state = IstioResources{}
|
||||
return nil
|
||||
}
|
||||
|
||||
nsl := c.namespaces.List("", klabels.Everything())
|
||||
namespaces := make(map[string]*corev1.Namespace, len(nsl))
|
||||
for _, ns := range nsl {
|
||||
namespaces[ns.Name] = ns
|
||||
}
|
||||
input.Namespaces = namespaces
|
||||
|
||||
if c.credentialsController != nil {
|
||||
credentials, err := c.credentialsController.ForCluster(c.cluster)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get credentials: %v", err)
|
||||
}
|
||||
input.Credentials = credentials
|
||||
}
|
||||
|
||||
output := convertResources(input)
|
||||
|
||||
// Handle all status updates
|
||||
c.QueueStatusUpdates(input)
|
||||
|
||||
c.stateMu.Lock()
|
||||
defer c.stateMu.Unlock()
|
||||
c.state = output
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) QueueStatusUpdates(r GatewayResources) {
|
||||
c.handleStatusUpdates(r.GatewayClass)
|
||||
c.handleStatusUpdates(r.Gateway)
|
||||
c.handleStatusUpdates(r.HTTPRoute)
|
||||
c.handleStatusUpdates(r.TCPRoute)
|
||||
c.handleStatusUpdates(r.TLSRoute)
|
||||
}
|
||||
|
||||
func (c *Controller) handleStatusUpdates(configs []config.Config) {
|
||||
if c.statusController == nil || !c.statusEnabled.Load() {
|
||||
return
|
||||
}
|
||||
for _, cfg := range configs {
|
||||
ws := cfg.Status.(*kstatus.WrappedStatus)
|
||||
if ws.Dirty {
|
||||
res := status.ResourceFromModelConfig(cfg)
|
||||
c.statusController.EnqueueStatusUpdateResource(ws.Unwrap(), res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) Create(config config.Config) (revision string, err error) {
|
||||
return "", errUnsupportedOp
|
||||
}
|
||||
|
||||
func (c *Controller) Update(config config.Config) (newRevision string, err error) {
|
||||
return "", errUnsupportedOp
|
||||
}
|
||||
|
||||
func (c *Controller) UpdateStatus(config config.Config) (newRevision string, err error) {
|
||||
return "", errUnsupportedOp
|
||||
}
|
||||
|
||||
func (c *Controller) Patch(orig config.Config, patchFn config.PatchFunc) (string, error) {
|
||||
return "", errUnsupportedOp
|
||||
}
|
||||
|
||||
func (c *Controller) Delete(typ config.GroupVersionKind, name, namespace string, _ *string) error {
|
||||
return errUnsupportedOp
|
||||
}
|
||||
|
||||
func (c *Controller) RegisterEventHandler(typ config.GroupVersionKind, handler model.EventHandler) {
|
||||
switch typ {
|
||||
case gvk.Namespace:
|
||||
c.namespaceHandler = handler
|
||||
case gvk.Secret:
|
||||
c.secretHandler = handler
|
||||
}
|
||||
// For all other types, do nothing as c.cache has been registered
|
||||
}
|
||||
|
||||
func (c *Controller) Run(stop <-chan struct{}) {
|
||||
go func() {
|
||||
if c.waitForCRD(gvr.GatewayClass, stop) {
|
||||
gcc := NewClassController(c.client)
|
||||
c.client.RunAndWait(stop)
|
||||
gcc.Run(stop)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (c *Controller) HasSynced() bool {
|
||||
return c.cache.HasSynced() && c.namespaces.HasSynced()
|
||||
}
|
||||
|
||||
func (c *Controller) SecretAllowed(resourceName string, namespace string) bool {
|
||||
c.stateMu.RLock()
|
||||
defer c.stateMu.RUnlock()
|
||||
return c.state.AllowedReferences.SecretAllowed(resourceName, namespace)
|
||||
}
|
||||
|
||||
// namespaceEvent handles a namespace add/update. Gateway's can select routes by label, so we need to handle
|
||||
// when the labels change.
|
||||
// Note: we don't handle delete as a delete would also clean up any relevant gateway-api types which will
|
||||
// trigger its own event.
|
||||
func (c *Controller) namespaceEvent(oldNs, newNs *corev1.Namespace) {
|
||||
// First, find all the label keys on the old/new namespace. We include NamespaceNameLabel
|
||||
// since we have special logic to always allow this on namespace.
|
||||
touchedNamespaceLabels := sets.New(NamespaceNameLabel)
|
||||
touchedNamespaceLabels.InsertAll(getLabelKeys(oldNs)...)
|
||||
touchedNamespaceLabels.InsertAll(getLabelKeys(newNs)...)
|
||||
|
||||
// Next, we find all keys our Gateways actually reference.
|
||||
c.stateMu.RLock()
|
||||
intersection := touchedNamespaceLabels.Intersection(c.state.ReferencedNamespaceKeys)
|
||||
c.stateMu.RUnlock()
|
||||
|
||||
// If there was any overlap, then a relevant namespace label may have changed, and we trigger a
|
||||
// push. A more exact check could actually determine if the label selection result actually changed.
|
||||
// However, this is a much simpler approach that is likely to scale well enough for now.
|
||||
if !intersection.IsEmpty() && c.namespaceHandler != nil {
|
||||
log.Debugf("namespace labels changed, triggering namespace handler: %v", intersection.UnsortedList())
|
||||
c.namespaceHandler(config.Config{}, config.Config{}, model.EventUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
// getLabelKeys extracts all label keys from a namespace object.
|
||||
func getLabelKeys(ns *corev1.Namespace) []string {
|
||||
if ns == nil {
|
||||
return nil
|
||||
}
|
||||
return maps.Keys(ns.Labels)
|
||||
}
|
||||
|
||||
func (c *Controller) secretEvent(name, namespace string) {
|
||||
var impactedConfigs []model.ConfigKey
|
||||
c.stateMu.RLock()
|
||||
impactedConfigs = c.state.ResourceReferences[model.ConfigKey{
|
||||
Kind: kind.Secret,
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}]
|
||||
c.stateMu.RUnlock()
|
||||
if len(impactedConfigs) > 0 {
|
||||
log.Debugf("secret %s/%s changed, triggering secret handler", namespace, name)
|
||||
for _, cfg := range impactedConfigs {
|
||||
gw := config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.KubernetesGateway,
|
||||
Namespace: cfg.Namespace,
|
||||
Name: cfg.Name,
|
||||
},
|
||||
}
|
||||
c.secretHandler(gw, gw, model.EventUpdate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// deepCopyStatus creates a copy of all configs, with a copy of the status field that we can mutate.
|
||||
// This allows our functions to call Status.Mutate, and then we can later persist all changes into the
|
||||
// API server.
|
||||
func deepCopyStatus(configs []config.Config) []config.Config {
|
||||
return slices.Map(configs, func(c config.Config) config.Config {
|
||||
return config.Config{
|
||||
Meta: c.Meta,
|
||||
Spec: c.Spec,
|
||||
Status: kstatus.Wrap(c.Status),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// filterNamespace allows filtering out configs to only a specific namespace. This allows implementing the
|
||||
// List call which can specify a specific namespace.
|
||||
func filterNamespace(cfgs []config.Config, namespace string) []config.Config {
|
||||
if namespace == metav1.NamespaceAll {
|
||||
return cfgs
|
||||
}
|
||||
return slices.Filter(cfgs, func(c config.Config) bool {
|
||||
return c.Namespace == namespace
|
||||
})
|
||||
}
|
||||
|
||||
// hasResources determines if there are any gateway-api resources created at all.
|
||||
// If not, we can short circuit all processing to avoid excessive work.
|
||||
func (kr GatewayResources) hasResources() bool {
|
||||
return len(kr.GatewayClass) > 0 ||
|
||||
len(kr.Gateway) > 0 ||
|
||||
len(kr.HTTPRoute) > 0 ||
|
||||
len(kr.TCPRoute) > 0 ||
|
||||
len(kr.TLSRoute) > 0 ||
|
||||
len(kr.ReferenceGrant) > 0
|
||||
}
|
||||
205
pkg/ingress/kube/gateway/istio/controller_test.go
Normal file
205
pkg/ingress/kube/gateway/istio/controller_test.go
Normal file
@@ -0,0 +1,205 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/config/memory"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pilot/pkg/networking/core/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/util/xdsfake"
|
||||
"istio.io/istio/pkg/config"
|
||||
istioconst "istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/collections"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/kclient/clienttest"
|
||||
"istio.io/istio/pkg/test"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
k8sbeta "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/pkg/config/constants"
|
||||
)
|
||||
|
||||
var (
|
||||
gatewayClassSpec = &k8s.GatewayClassSpec{
|
||||
ControllerName: constants.ManagedGatewayController,
|
||||
}
|
||||
gatewaySpec = &k8s.GatewaySpec{
|
||||
GatewayClassName: "gwclass",
|
||||
Listeners: []k8s.Listener{
|
||||
{
|
||||
Name: "default",
|
||||
Port: 9009,
|
||||
Protocol: "HTTP",
|
||||
AllowedRoutes: &k8s.AllowedRoutes{Namespaces: &k8s.RouteNamespaces{From: func() *k8s.FromNamespaces { x := k8sbeta.NamespacesFromAll; return &x }()}},
|
||||
},
|
||||
},
|
||||
}
|
||||
httpRouteSpec = &k8s.HTTPRouteSpec{
|
||||
CommonRouteSpec: k8s.CommonRouteSpec{ParentRefs: []k8s.ParentReference{{
|
||||
Name: "gwspec",
|
||||
}}},
|
||||
Hostnames: []k8s.Hostname{"test.cluster.local"},
|
||||
}
|
||||
|
||||
expectedgw = &networking.Gateway{
|
||||
Servers: []*networking.Server{
|
||||
{
|
||||
Port: &networking.Port{
|
||||
Number: 9009,
|
||||
Name: "default",
|
||||
Protocol: "HTTP",
|
||||
},
|
||||
Hosts: []string{"*/*"},
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
var AlwaysReady = func(class schema.GroupVersionResource, stop <-chan struct{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestListInvalidGroupVersionKind(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
clientSet := kube.NewFakeClient()
|
||||
store := memory.NewController(memory.Make(collections.All))
|
||||
controller := NewController(clientSet, store, AlwaysReady, nil, controller.Options{})
|
||||
|
||||
typ := config.GroupVersionKind{Kind: "wrong-kind"}
|
||||
c := controller.List(typ, "ns1")
|
||||
g.Expect(c).To(HaveLen(0))
|
||||
}
|
||||
|
||||
func TestListGatewayResourceType(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
clientSet := kube.NewFakeClient()
|
||||
store := memory.NewController(memory.Make(collections.All))
|
||||
controller := NewController(clientSet, store, AlwaysReady, nil, controller.Options{})
|
||||
|
||||
store.Create(config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.GatewayClass,
|
||||
Name: "gwclass",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: gatewayClassSpec,
|
||||
})
|
||||
if _, err := store.Create(config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.KubernetesGateway,
|
||||
Name: "gwspec",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: gatewaySpec,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
store.Create(config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.HTTPRoute,
|
||||
Name: "http-route",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: httpRouteSpec,
|
||||
})
|
||||
|
||||
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{})
|
||||
g.Expect(controller.Reconcile(cg.PushContext())).ToNot(HaveOccurred())
|
||||
cfg := controller.List(gvk.Gateway, "ns1")
|
||||
g.Expect(cfg).To(HaveLen(1))
|
||||
for _, c := range cfg {
|
||||
g.Expect(c.GroupVersionKind).To(Equal(gvk.Gateway))
|
||||
g.Expect(c.Name).To(Equal("gwspec" + "-" + istioconst.KubernetesGatewayName + "-default"))
|
||||
g.Expect(c.Namespace).To(Equal("ns1"))
|
||||
g.Expect(c.Spec).To(Equal(expectedgw))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamespaceEvent(t *testing.T) {
|
||||
clientSet := kube.NewFakeClient()
|
||||
store := memory.NewController(memory.Make(collections.All))
|
||||
c := NewController(clientSet, store, AlwaysReady, nil, controller.Options{})
|
||||
s := xdsfake.NewFakeXDS()
|
||||
|
||||
c.RegisterEventHandler(gvk.Namespace, func(_, cfg config.Config, _ model.Event) {
|
||||
s.ConfigUpdate(&model.PushRequest{
|
||||
Full: true,
|
||||
Reason: model.NewReasonStats(model.NamespaceUpdate),
|
||||
})
|
||||
})
|
||||
|
||||
stop := test.NewStop(t)
|
||||
c.Run(stop)
|
||||
kube.WaitForCacheSync("test", stop, c.HasSynced)
|
||||
c.state.ReferencedNamespaceKeys = sets.String{"allowed": struct{}{}}
|
||||
|
||||
ns1 := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns1",
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
}}
|
||||
ns2 := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns2",
|
||||
Labels: map[string]string{
|
||||
"allowed": "true",
|
||||
},
|
||||
}}
|
||||
ns := clienttest.Wrap(t, c.namespaces)
|
||||
|
||||
ns.Create(ns1)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns.Create(ns2)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns1.Annotations = map[string]string{"foo": "bar"}
|
||||
ns.Update(ns1)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns2.Annotations = map[string]string{"foo": "bar"}
|
||||
ns.Update(ns2)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns1.Labels["bar"] = "foo"
|
||||
ns.Update(ns1)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns2.Labels["foo"] = "bar"
|
||||
ns.Update(ns2)
|
||||
s.WaitOrFail(t, "xds full")
|
||||
|
||||
ns1.Labels["allowed"] = "true"
|
||||
ns.Update(ns1)
|
||||
s.WaitOrFail(t, "xds full")
|
||||
|
||||
ns2.Labels["allowed"] = "false"
|
||||
ns.Update(ns2)
|
||||
s.WaitOrFail(t, "xds full")
|
||||
}
|
||||
2221
pkg/ingress/kube/gateway/istio/conversion.go
Normal file
2221
pkg/ingress/kube/gateway/istio/conversion.go
Normal file
File diff suppressed because it is too large
Load Diff
994
pkg/ingress/kube/gateway/istio/conversion_test.go
Normal file
994
pkg/ingress/kube/gateway/istio/conversion_test.go
Normal file
@@ -0,0 +1,994 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"istio.io/istio/pilot/pkg/config/kube/crd"
|
||||
credentials "istio.io/istio/pilot/pkg/credentials/kube"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pilot/pkg/model/kstatus"
|
||||
"istio.io/istio/pilot/pkg/networking/core/v1alpha3"
|
||||
"istio.io/istio/pilot/test/util"
|
||||
"istio.io/istio/pkg/cluster"
|
||||
"istio.io/istio/pkg/config"
|
||||
crdvalidation "istio.io/istio/pkg/config/crd"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/test"
|
||||
"istio.io/istio/pkg/test/util/assert"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var ports = []*model.Port{
|
||||
{
|
||||
Name: "http",
|
||||
Port: 80,
|
||||
Protocol: "HTTP",
|
||||
},
|
||||
{
|
||||
Name: "tcp",
|
||||
Port: 34000,
|
||||
Protocol: "TCP",
|
||||
},
|
||||
}
|
||||
|
||||
var defaultGatewaySelector = map[string]string{
|
||||
"higress": "higress-system-higress-gateway",
|
||||
}
|
||||
|
||||
var services = []*model.Service{
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Name: "higress-gateway",
|
||||
Namespace: "higress-system",
|
||||
ClusterExternalAddresses: &model.AddressMap{
|
||||
Addresses: map[cluster.ID][]string{
|
||||
"Kubernetes": {"1.2.3.4"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "higress-gateway.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "example.com",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "apple",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-apple.apple.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "banana",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-banana.banana.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-second.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-wildcard.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "foo-svc.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-other.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "example.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "echo.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "echo.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "cert",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.cert.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "service",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "my-svc.service.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "google.com",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "allowed-1",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc2.allowed-1.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "allowed-2",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc2.allowed-2.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "allowed-1",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc1.allowed-1.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "allowed-2",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc3.allowed-2.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc4.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "group-namespace1",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.group-namespace1.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "group-namespace2",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.group-namespace2.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-zero.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-mirror.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-foo.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-alt.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "higress-controller.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "higress-controller.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "echo.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-bad.default.svc.domain.suffix",
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
// https://github.com/kubernetes/kubernetes/blob/v1.25.4/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_tls_test.go#L31
|
||||
rsaCertPEM = `-----BEGIN CERTIFICATE-----
|
||||
MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
|
||||
hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
|
||||
rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
|
||||
zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
|
||||
MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
|
||||
r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
rsaKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
|
||||
k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
|
||||
6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
|
||||
MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
|
||||
SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
|
||||
xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
|
||||
D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`
|
||||
|
||||
secrets = []runtime.Object{
|
||||
&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-cert-http",
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"tls.crt": []byte(rsaCertPEM),
|
||||
"tls.key": []byte(rsaKeyPEM),
|
||||
},
|
||||
},
|
||||
&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cert",
|
||||
Namespace: "cert",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"tls.crt": []byte(rsaCertPEM),
|
||||
"tls.key": []byte(rsaKeyPEM),
|
||||
},
|
||||
},
|
||||
&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "malformed",
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
// nolint: lll
|
||||
// https://github.com/kubernetes-sigs/gateway-api/blob/d7f71d6b7df7e929ae299948973a693980afc183/conformance/tests/gateway-invalid-tls-certificateref.yaml#L87-L90
|
||||
// this certificate is invalid because contains an invalid pem (base64 of "Hello world"),
|
||||
// and the certificate and the key are identical
|
||||
"tls.crt": []byte("SGVsbG8gd29ybGQK"),
|
||||
"tls.key": []byte("SGVsbG8gd29ybGQK"),
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
features.EnableAlphaGatewayAPI = true
|
||||
features.EnableAmbientControllers = true
|
||||
// Recompute with ambient enabled
|
||||
classInfos = getClassInfos()
|
||||
builtinClasses = getBuiltinClasses()
|
||||
}
|
||||
|
||||
func TestConvertResources(t *testing.T) {
|
||||
validator := crdvalidation.NewIstioValidator(t)
|
||||
cases := []struct {
|
||||
name string
|
||||
}{
|
||||
{"http"},
|
||||
{"tcp"},
|
||||
{"tls"},
|
||||
{"mismatch"},
|
||||
{"weighted"},
|
||||
{"zero"},
|
||||
{"invalid"},
|
||||
{"multi-gateway"},
|
||||
{"delegated"},
|
||||
{"route-binding"},
|
||||
{"reference-policy-tls"},
|
||||
{"reference-policy-service"},
|
||||
{"serviceentry"},
|
||||
{"alias"},
|
||||
{"mcs"},
|
||||
{"route-precedence"},
|
||||
}
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
input := readConfig(t, fmt.Sprintf("testdata/%s.yaml", tt.name), validator)
|
||||
// Setup a few preconfigured services
|
||||
instances := []*model.ServiceInstance{}
|
||||
for _, svc := range services {
|
||||
instances = append(instances, &model.ServiceInstance{
|
||||
Service: svc,
|
||||
ServicePort: ports[0],
|
||||
Endpoint: &model.IstioEndpoint{EndpointPort: 8080},
|
||||
}, &model.ServiceInstance{
|
||||
Service: svc,
|
||||
ServicePort: ports[1],
|
||||
Endpoint: &model.IstioEndpoint{},
|
||||
})
|
||||
}
|
||||
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{
|
||||
Services: services,
|
||||
Instances: instances,
|
||||
})
|
||||
kr := splitInput(t, input)
|
||||
kr.Context = NewGatewayContext(cg.PushContext())
|
||||
output := convertResources(kr)
|
||||
output.AllowedReferences = AllowedReferences{} // Not tested here
|
||||
output.ReferencedNamespaceKeys = nil // Not tested here
|
||||
output.ResourceReferences = nil // Not tested here
|
||||
|
||||
// sort virtual services to make the order deterministic
|
||||
sort.Slice(output.VirtualService, func(i, j int) bool {
|
||||
return output.VirtualService[i].Namespace+"/"+output.VirtualService[i].Name < output.VirtualService[j].Namespace+"/"+output.VirtualService[j].Name
|
||||
})
|
||||
goldenFile := fmt.Sprintf("testdata/%s.yaml.golden", tt.name)
|
||||
res := append(output.Gateway, output.VirtualService...)
|
||||
util.CompareContent(t, marshalYaml(t, res), goldenFile)
|
||||
golden := splitOutput(readConfig(t, goldenFile, validator))
|
||||
|
||||
// sort virtual services to make the order deterministic
|
||||
sort.Slice(golden.VirtualService, func(i, j int) bool {
|
||||
return golden.VirtualService[i].Namespace+"/"+golden.VirtualService[i].Name < golden.VirtualService[j].Namespace+"/"+golden.VirtualService[j].Name
|
||||
})
|
||||
|
||||
assert.Equal(t, golden, output)
|
||||
|
||||
//outputStatus := getStatus(t, kr.GatewayClass, kr.Gateway, kr.HTTPRoute, kr.TLSRoute, kr.TCPRoute)
|
||||
//goldenStatusFile := fmt.Sprintf("testdata/%s.status.yaml.golden", tt.name)
|
||||
//if util.Refresh() {
|
||||
// if err := os.WriteFile(goldenStatusFile, outputStatus, 0o644); err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
//}
|
||||
//goldenStatus, err := os.ReadFile(goldenStatusFile)
|
||||
//if err != nil {
|
||||
// t.Fatal(err)
|
||||
//}
|
||||
//if diff := cmp.Diff(string(goldenStatus), string(outputStatus)); diff != "" {
|
||||
// t.Fatalf("Diff:\n%s", diff)
|
||||
//}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReferencePolicy(t *testing.T) {
|
||||
validator := crdvalidation.NewIstioValidator(t)
|
||||
type res struct {
|
||||
name, namespace string
|
||||
allowed bool
|
||||
}
|
||||
cases := []struct {
|
||||
name string
|
||||
config string
|
||||
expectations []res
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
config: `apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
name: allow-gateways-to-ref-secrets
|
||||
namespace: default
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
namespace: higress-system
|
||||
to:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
`,
|
||||
expectations: []res{
|
||||
// allow cross namespace
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "higress-system", true},
|
||||
// denied same namespace. We do not implicitly allow (in this code - higher level code does)
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "default", false},
|
||||
// denied namespace
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "bad", false},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple in one",
|
||||
config: `apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
name: allow-gateways-to-ref-secrets
|
||||
namespace: default
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
namespace: ns-1
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
namespace: ns-2
|
||||
to:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
`,
|
||||
expectations: []res{
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "ns-1", true},
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "ns-2", true},
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "bad", false},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple",
|
||||
config: `apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
name: ns1
|
||||
namespace: default
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
namespace: ns-1
|
||||
to:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
name: ns2
|
||||
namespace: default
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
namespace: ns-2
|
||||
to:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
`,
|
||||
expectations: []res{
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "ns-1", true},
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "ns-2", true},
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "bad", false},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "same namespace",
|
||||
config: `apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
name: allow-gateways-to-ref-secrets
|
||||
namespace: default
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
namespace: default
|
||||
to:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
`,
|
||||
expectations: []res{
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "higress-system", false},
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "default", true},
|
||||
{"kubernetes-gateway://default/wildcard-example-com-cert", "bad", false},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "same name",
|
||||
config: `apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
name: allow-gateways-to-ref-secrets
|
||||
namespace: default
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
namespace: default
|
||||
to:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
name: public
|
||||
`,
|
||||
expectations: []res{
|
||||
{"kubernetes-gateway://default/public", "higress-system", false},
|
||||
{"kubernetes-gateway://default/public", "default", true},
|
||||
{"kubernetes-gateway://default/private", "default", false},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
input := readConfigString(t, tt.config, validator)
|
||||
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{})
|
||||
kr := splitInput(t, input)
|
||||
kr.Context = NewGatewayContext(cg.PushContext())
|
||||
output := convertResources(kr)
|
||||
c := &Controller{
|
||||
state: output,
|
||||
}
|
||||
for _, sc := range tt.expectations {
|
||||
t.Run(fmt.Sprintf("%v/%v", sc.name, sc.namespace), func(t *testing.T) {
|
||||
got := c.SecretAllowed(sc.name, sc.namespace)
|
||||
if got != sc.allowed {
|
||||
t.Fatalf("expected allowed=%v, got allowed=%v", sc.allowed, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getStatus(t test.Failer, acfgs ...[]config.Config) []byte {
|
||||
cfgs := []config.Config{}
|
||||
for _, cl := range acfgs {
|
||||
cfgs = append(cfgs, cl...)
|
||||
}
|
||||
for i, c := range cfgs {
|
||||
c = c.DeepCopy()
|
||||
c.Spec = nil
|
||||
c.Labels = nil
|
||||
c.Annotations = nil
|
||||
if c.Status.(*kstatus.WrappedStatus) != nil {
|
||||
c.Status = c.Status.(*kstatus.WrappedStatus).Status
|
||||
}
|
||||
cfgs[i] = c
|
||||
}
|
||||
return timestampRegex.ReplaceAll(marshalYaml(t, cfgs), []byte("lastTransitionTime: fake"))
|
||||
}
|
||||
|
||||
var timestampRegex = regexp.MustCompile(`lastTransitionTime:.*`)
|
||||
|
||||
func splitOutput(configs []config.Config) IstioResources {
|
||||
out := IstioResources{
|
||||
Gateway: []config.Config{},
|
||||
VirtualService: []config.Config{},
|
||||
}
|
||||
for _, c := range configs {
|
||||
c.Domain = "domain.suffix"
|
||||
switch c.GroupVersionKind {
|
||||
case gvk.Gateway:
|
||||
out.Gateway = append(out.Gateway, c)
|
||||
case gvk.VirtualService:
|
||||
out.VirtualService = append(out.VirtualService, c)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func splitInput(t test.Failer, configs []config.Config) GatewayResources {
|
||||
out := GatewayResources{DefaultGatewaySelector: defaultGatewaySelector}
|
||||
namespaces := sets.New[string]()
|
||||
for _, c := range configs {
|
||||
namespaces.Insert(c.Namespace)
|
||||
switch c.GroupVersionKind {
|
||||
case gvk.GatewayClass:
|
||||
out.GatewayClass = append(out.GatewayClass, c)
|
||||
case gvk.KubernetesGateway:
|
||||
out.Gateway = append(out.Gateway, c)
|
||||
case gvk.HTTPRoute:
|
||||
out.HTTPRoute = append(out.HTTPRoute, c)
|
||||
case gvk.TCPRoute:
|
||||
out.TCPRoute = append(out.TCPRoute, c)
|
||||
case gvk.TLSRoute:
|
||||
out.TLSRoute = append(out.TLSRoute, c)
|
||||
case gvk.ReferenceGrant:
|
||||
out.ReferenceGrant = append(out.ReferenceGrant, c)
|
||||
}
|
||||
}
|
||||
out.Namespaces = map[string]*corev1.Namespace{}
|
||||
for ns := range namespaces {
|
||||
out.Namespaces[ns] = &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: ns,
|
||||
Labels: map[string]string{
|
||||
"istio.io/test-name-part": strings.Split(ns, "-")[0],
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
client := kube.NewFakeClient(secrets...)
|
||||
out.Credentials = credentials.NewCredentialsController(client)
|
||||
client.RunAndWait(test.NewStop(t))
|
||||
|
||||
out.Domain = "domain.suffix"
|
||||
return out
|
||||
}
|
||||
|
||||
func readConfig(t testing.TB, filename string, validator *crdvalidation.Validator) []config.Config {
|
||||
t.Helper()
|
||||
|
||||
data, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read input yaml file: %v", err)
|
||||
}
|
||||
return readConfigString(t, string(data), validator)
|
||||
}
|
||||
|
||||
func readConfigString(t testing.TB, data string, validator *crdvalidation.Validator) []config.Config {
|
||||
if err := validator.ValidateCustomResourceYAML(data); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
c, _, err := crd.ParseInputs(data)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse CRD: %v", err)
|
||||
}
|
||||
return insertDefaults(c)
|
||||
}
|
||||
|
||||
// insertDefaults sets default values that would be present when reading from Kubernetes but not from
|
||||
// files
|
||||
func insertDefaults(cfgs []config.Config) []config.Config {
|
||||
res := make([]config.Config, 0, len(cfgs))
|
||||
for _, c := range cfgs {
|
||||
switch c.GroupVersionKind {
|
||||
case gvk.GatewayClass:
|
||||
c.Status = kstatus.Wrap(&k8s.GatewayClassStatus{})
|
||||
case gvk.KubernetesGateway:
|
||||
c.Status = kstatus.Wrap(&k8s.GatewayStatus{})
|
||||
case gvk.HTTPRoute:
|
||||
c.Status = kstatus.Wrap(&k8s.HTTPRouteStatus{})
|
||||
case gvk.TCPRoute:
|
||||
c.Status = kstatus.Wrap(&k8s.TCPRouteStatus{})
|
||||
case gvk.TLSRoute:
|
||||
c.Status = kstatus.Wrap(&k8s.TLSRouteStatus{})
|
||||
}
|
||||
res = append(res, c)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Print as YAML
|
||||
func marshalYaml(t test.Failer, cl []config.Config) []byte {
|
||||
t.Helper()
|
||||
result := []byte{}
|
||||
separator := []byte("---\n")
|
||||
for _, config := range cl {
|
||||
obj, err := crd.ConvertConfig(config)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not decode %v: %v", config.Name, err)
|
||||
}
|
||||
bytes, err := yaml.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not convert %v to YAML: %v", config, err)
|
||||
}
|
||||
result = append(result, bytes...)
|
||||
result = append(result, separator...)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func TestHumanReadableJoin(t *testing.T) {
|
||||
tests := []struct {
|
||||
input []string
|
||||
want string
|
||||
}{
|
||||
{[]string{"a"}, "a"},
|
||||
{[]string{"a", "b"}, "a and b"},
|
||||
{[]string{"a", "b", "c"}, "a, b, and c"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(strings.Join(tt.input, "_"), func(t *testing.T) {
|
||||
if got := humanReadableJoin(tt.input); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("got %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBuildHTTPVirtualServices(b *testing.B) {
|
||||
ports := []*model.Port{
|
||||
{
|
||||
Name: "http",
|
||||
Port: 80,
|
||||
Protocol: "HTTP",
|
||||
},
|
||||
{
|
||||
Name: "tcp",
|
||||
Port: 34000,
|
||||
Protocol: "TCP",
|
||||
},
|
||||
}
|
||||
ingressSvc := &model.Service{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Name: "higress-gateway",
|
||||
Namespace: "higress-system",
|
||||
ClusterExternalAddresses: &model.AddressMap{
|
||||
Addresses: map[cluster.ID][]string{
|
||||
"Kubernetes": {"1.2.3.4"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "higress-gateway.higress-system.svc.domain.suffix",
|
||||
}
|
||||
altIngressSvc := &model.Service{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "example.com",
|
||||
}
|
||||
cg := v1alpha3.NewConfigGenTest(b, v1alpha3.TestOptions{
|
||||
Services: []*model.Service{ingressSvc, altIngressSvc},
|
||||
Instances: []*model.ServiceInstance{
|
||||
{Service: ingressSvc, ServicePort: ingressSvc.Ports[0], Endpoint: &model.IstioEndpoint{EndpointPort: 8080}},
|
||||
{Service: ingressSvc, ServicePort: ingressSvc.Ports[1], Endpoint: &model.IstioEndpoint{}},
|
||||
{Service: altIngressSvc, ServicePort: altIngressSvc.Ports[0], Endpoint: &model.IstioEndpoint{}},
|
||||
{Service: altIngressSvc, ServicePort: altIngressSvc.Ports[1], Endpoint: &model.IstioEndpoint{}},
|
||||
},
|
||||
})
|
||||
|
||||
validator := crdvalidation.NewIstioValidator(b)
|
||||
input := readConfig(b, "testdata/benchmark-httproute.yaml", validator)
|
||||
kr := splitInput(b, input)
|
||||
kr.Context = NewGatewayContext(cg.PushContext())
|
||||
ctx := configContext{
|
||||
GatewayResources: kr,
|
||||
AllowedReferences: convertReferencePolicies(kr),
|
||||
}
|
||||
_, gwMap, _ := convertGateways(ctx)
|
||||
ctx.GatewayReferences = gwMap
|
||||
|
||||
b.ResetTimer()
|
||||
for n := 0; n < b.N; n++ {
|
||||
// for gateway routes, build one VS per gateway+host
|
||||
gatewayRoutes := make(map[string]map[string]*config.Config)
|
||||
// for mesh routes, build one VS per namespace+host
|
||||
meshRoutes := make(map[string]map[string]*config.Config)
|
||||
for _, obj := range kr.HTTPRoute {
|
||||
buildHTTPVirtualServices(ctx, obj, gatewayRoutes, meshRoutes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start - Updated by Higress
|
||||
func TestExtractGatewayServices(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
r GatewayResources
|
||||
kgw *k8s.GatewaySpec
|
||||
obj config.Config
|
||||
gatewayServices []string
|
||||
useDefaultService bool
|
||||
err *ConfigError
|
||||
}{
|
||||
{
|
||||
name: "default gateway",
|
||||
r: GatewayResources{Domain: "cluster.local", DefaultGatewaySelector: defaultGatewaySelector},
|
||||
kgw: &k8s.GatewaySpec{
|
||||
GatewayClassName: "higress",
|
||||
},
|
||||
obj: config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
gatewayServices: []string{},
|
||||
useDefaultService: true,
|
||||
},
|
||||
{
|
||||
name: "default gateway with name overridden",
|
||||
r: GatewayResources{Domain: "cluster.local", DefaultGatewaySelector: defaultGatewaySelector},
|
||||
kgw: &k8s.GatewaySpec{
|
||||
GatewayClassName: "higress",
|
||||
},
|
||||
obj: config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
gatewayNameOverride: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
gatewayServices: []string{"bar.default.svc.cluster.local"},
|
||||
},
|
||||
{
|
||||
name: "unmanaged gateway with only hostname address",
|
||||
r: GatewayResources{Domain: "domain", DefaultGatewaySelector: defaultGatewaySelector},
|
||||
kgw: &k8s.GatewaySpec{
|
||||
GatewayClassName: "higress",
|
||||
Addresses: []k8s.GatewayAddress{
|
||||
{
|
||||
Type: func() *k8s.AddressType {
|
||||
t := k8s.HostnameAddressType
|
||||
return &t
|
||||
}(),
|
||||
Value: "example.com",
|
||||
},
|
||||
},
|
||||
},
|
||||
obj: config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
gatewayServices: []string{"example.com"},
|
||||
},
|
||||
{
|
||||
name: "unmanaged gateway with other address types",
|
||||
r: GatewayResources{Domain: "domain", DefaultGatewaySelector: defaultGatewaySelector},
|
||||
kgw: &k8s.GatewaySpec{
|
||||
GatewayClassName: "higress",
|
||||
Addresses: []k8s.GatewayAddress{
|
||||
{
|
||||
Value: "abc",
|
||||
},
|
||||
{
|
||||
Type: func() *k8s.AddressType {
|
||||
t := k8s.HostnameAddressType
|
||||
return &t
|
||||
}(),
|
||||
Value: "example.com",
|
||||
},
|
||||
{
|
||||
Type: func() *k8s.AddressType {
|
||||
t := k8s.IPAddressType
|
||||
return &t
|
||||
}(),
|
||||
Value: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
},
|
||||
obj: config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
gatewayServices: []string{"abc.default.svc.domain", "example.com"},
|
||||
err: &ConfigError{
|
||||
Reason: InvalidAddress,
|
||||
Message: "only Hostname is supported, ignoring [1.2.3.4]",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "unmanaged gateway with empty type address",
|
||||
r: GatewayResources{Domain: "domain", DefaultGatewaySelector: defaultGatewaySelector},
|
||||
kgw: &k8s.GatewaySpec{
|
||||
GatewayClassName: "higress",
|
||||
Addresses: []k8s.GatewayAddress{
|
||||
{
|
||||
Value: "abc",
|
||||
},
|
||||
},
|
||||
},
|
||||
obj: config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
gatewayServices: []string{"abc.default.svc.domain"},
|
||||
},
|
||||
{
|
||||
name: "unmanaged gateway with no hostname address",
|
||||
r: GatewayResources{Domain: "domain", DefaultGatewaySelector: defaultGatewaySelector},
|
||||
kgw: &k8s.GatewaySpec{
|
||||
GatewayClassName: "higress",
|
||||
Addresses: []k8s.GatewayAddress{
|
||||
{
|
||||
Type: func() *k8s.AddressType {
|
||||
t := k8s.IPAddressType
|
||||
return &t
|
||||
}(),
|
||||
Value: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
},
|
||||
obj: config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
gatewayServices: []string{},
|
||||
useDefaultService: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gatewayServices, useDefaultService, err := extractGatewayServices(tt.r, tt.kgw, tt.obj)
|
||||
assert.Equal(t, gatewayServices, tt.gatewayServices)
|
||||
assert.Equal(t, useDefaultService, tt.useDefaultService)
|
||||
assert.Equal(t, err, tt.err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// End - Updated by Higress
|
||||
90
pkg/ingress/kube/gateway/istio/deploymentcontroller.go
Normal file
90
pkg/ingress/kube/gateway/istio/deploymentcontroller.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/pkg/config/constants"
|
||||
)
|
||||
|
||||
// classInfo holds information about a gateway class
|
||||
type classInfo struct {
|
||||
// controller name for this class
|
||||
controller string
|
||||
// description for this class
|
||||
description string
|
||||
// The key in the templates to use for this class
|
||||
templates string
|
||||
|
||||
// defaultServiceType sets the default service type if one is not explicit set
|
||||
defaultServiceType corev1.ServiceType
|
||||
|
||||
// disableRouteGeneration, if set, will make it so the controller ignores this class.
|
||||
disableRouteGeneration bool
|
||||
}
|
||||
|
||||
var classInfos = getClassInfos()
|
||||
|
||||
var builtinClasses = getBuiltinClasses()
|
||||
|
||||
func getBuiltinClasses() map[gateway.ObjectName]gateway.GatewayController {
|
||||
res := map[gateway.ObjectName]gateway.GatewayController{
|
||||
defaultClassName: constants.ManagedGatewayController,
|
||||
// Start - Commented by Higress
|
||||
//constants.RemoteGatewayClassName: constants.UnmanagedGatewayController,
|
||||
// End - Commented by Higress
|
||||
}
|
||||
// Start - Commented by Higress
|
||||
//if features.EnableAmbientControllers {
|
||||
// res[constants.WaypointGatewayClassName] = constants.ManagedGatewayMeshController
|
||||
//}
|
||||
// End - Commented by Higress
|
||||
return res
|
||||
}
|
||||
|
||||
func getClassInfos() map[gateway.GatewayController]classInfo {
|
||||
// Start - Updated by Higress
|
||||
m := map[gateway.GatewayController]classInfo{
|
||||
constants.ManagedGatewayController: {
|
||||
controller: constants.ManagedGatewayController,
|
||||
description: "The default Higress GatewayClass",
|
||||
templates: "kube-gateway",
|
||||
defaultServiceType: corev1.ServiceTypeLoadBalancer,
|
||||
},
|
||||
//UnmanagedGatewayController: {
|
||||
// // This represents a gateway that our control plane cannot discover directly via the API server.
|
||||
// // We shouldn't generate Istio resources for it. We aren't programming this gateway.
|
||||
// controller: UnmanagedGatewayController,
|
||||
// description: "Remote to this cluster. Does not deploy or affect configuration.",
|
||||
// disableRouteGeneration: true,
|
||||
//},
|
||||
}
|
||||
//if features.EnableAmbientControllers {
|
||||
// m[constants.ManagedGatewayMeshController] = classInfo{
|
||||
// controller: constants.ManagedGatewayMeshController,
|
||||
// description: "The default Istio waypoint GatewayClass",
|
||||
// templates: "waypoint",
|
||||
// defaultServiceType: corev1.ServiceTypeClusterIP,
|
||||
// }
|
||||
//}
|
||||
// End - Updated by Higress
|
||||
return m
|
||||
}
|
||||
|
||||
// DeploymentController is removed by Higress
|
||||
28
pkg/ingress/kube/gateway/istio/fuzz_test.go
Normal file
28
pkg/ingress/kube/gateway/istio/fuzz_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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 istio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"istio.io/istio/pkg/fuzz"
|
||||
)
|
||||
|
||||
func FuzzConvertResources(f *testing.F) {
|
||||
fuzz.Fuzz(f, func(fg fuzz.Helper) {
|
||||
r := fuzz.Struct[GatewayResources](fg)
|
||||
convertResources(r)
|
||||
})
|
||||
}
|
||||
121
pkg/ingress/kube/gateway/istio/gatewayclass.go
Normal file
121
pkg/ingress/kube/gateway/istio/gatewayclass.go
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"istio.io/istio/pilot/pkg/model/kstatus"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/controllers"
|
||||
"istio.io/istio/pkg/kube/kclient"
|
||||
"istio.io/istio/pkg/util/istiomultierror"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
)
|
||||
|
||||
// ClassController is a controller that creates the default Istio GatewayClass(s). This will not
|
||||
// continually reconcile the full state of the GatewayClass object, and instead only create the class
|
||||
// if it doesn't exist. This allows users to manage it through other means or modify it as they wish.
|
||||
// If it is deleted, however, it will be added back.
|
||||
// This controller intentionally does not do leader election for simplicity. Because we only create
|
||||
// and not update there is no need; the first controller to create the GatewayClass wins.
|
||||
type ClassController struct {
|
||||
queue controllers.Queue
|
||||
classes kclient.Client[*gateway.GatewayClass]
|
||||
}
|
||||
|
||||
func NewClassController(kc kube.Client) *ClassController {
|
||||
gc := &ClassController{}
|
||||
gc.queue = controllers.NewQueue("gateway class",
|
||||
controllers.WithReconciler(gc.Reconcile),
|
||||
controllers.WithMaxAttempts(25))
|
||||
|
||||
gc.classes = kclient.New[*gateway.GatewayClass](kc)
|
||||
gc.classes.AddEventHandler(controllers.FilteredObjectHandler(gc.queue.AddObject, func(o controllers.Object) bool {
|
||||
_, f := builtinClasses[gateway.ObjectName(o.GetName())]
|
||||
return f
|
||||
}))
|
||||
return gc
|
||||
}
|
||||
|
||||
func (c *ClassController) Run(stop <-chan struct{}) {
|
||||
// Ensure we initially reconcile the current state
|
||||
c.queue.Add(types.NamespacedName{})
|
||||
c.queue.Run(stop)
|
||||
}
|
||||
|
||||
func (c *ClassController) Reconcile(types.NamespacedName) error {
|
||||
err := istiomultierror.New()
|
||||
for class := range builtinClasses {
|
||||
err = multierror.Append(err, c.reconcileClass(class))
|
||||
}
|
||||
return err.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (c *ClassController) reconcileClass(class gateway.ObjectName) error {
|
||||
if c.classes.Get(string(class), "") != nil {
|
||||
log.Debugf("GatewayClass/%v already exists, no action", class)
|
||||
return nil
|
||||
}
|
||||
controller := builtinClasses[class]
|
||||
classInfo, f := classInfos[controller]
|
||||
if !f {
|
||||
// Should only happen when ambient is disabled; otherwise builtinClasses and classInfos should be consistent
|
||||
return nil
|
||||
}
|
||||
gc := &gateway.GatewayClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: string(class),
|
||||
},
|
||||
Spec: gateway.GatewayClassSpec{
|
||||
ControllerName: gateway.GatewayController(classInfo.controller),
|
||||
Description: &classInfo.description,
|
||||
},
|
||||
}
|
||||
_, err := c.classes.Create(gc)
|
||||
if err != nil && !kerrors.IsConflict(err) {
|
||||
return err
|
||||
} else if err != nil && kerrors.IsConflict(err) {
|
||||
// This is not really an error, just a race condition
|
||||
log.Infof("Attempted to create GatewayClass/%v, but it was already created", class)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetClassStatus(existing *k8s.GatewayClassStatus, gen int64) k8s.GatewayClassStatus {
|
||||
if existing == nil {
|
||||
existing = &k8s.GatewayClassStatus{}
|
||||
}
|
||||
existing.Conditions = kstatus.UpdateConditionIfChanged(existing.Conditions, metav1.Condition{
|
||||
Type: string(gateway.GatewayClassConditionStatusAccepted),
|
||||
Status: kstatus.StatusTrue,
|
||||
ObservedGeneration: gen,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: string(gateway.GatewayClassConditionStatusAccepted),
|
||||
// Start - Updated by Higress
|
||||
Message: "Handled by Higress controller",
|
||||
// End - Updated by Higress
|
||||
})
|
||||
return *existing
|
||||
}
|
||||
93
pkg/ingress/kube/gateway/istio/gatewayclass_test.go
Normal file
93
pkg/ingress/kube/gateway/istio/gatewayclass_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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 istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/kclient/clienttest"
|
||||
"istio.io/istio/pkg/test"
|
||||
"istio.io/istio/pkg/test/util/retry"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/pkg/config/constants"
|
||||
)
|
||||
|
||||
func TestClassController(t *testing.T) {
|
||||
client := kube.NewFakeClient()
|
||||
cc := NewClassController(client)
|
||||
classes := clienttest.Wrap(t, cc.classes)
|
||||
stop := test.NewStop(t)
|
||||
client.RunAndWait(stop)
|
||||
go cc.Run(stop)
|
||||
createClass := func(name, controller string) {
|
||||
gc := &gateway.GatewayClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
Spec: gateway.GatewayClassSpec{
|
||||
ControllerName: gateway.GatewayController(controller),
|
||||
},
|
||||
}
|
||||
classes.CreateOrUpdate(gc)
|
||||
}
|
||||
deleteClass := func(name string) {
|
||||
classes.Delete(name, "")
|
||||
}
|
||||
expectClass := func(name, controller string) {
|
||||
t.Helper()
|
||||
retry.UntilSuccessOrFail(t, func() error {
|
||||
gc := classes.Get(name, "")
|
||||
if controller == "" {
|
||||
if gc == nil { // Expect none, got none
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("expected no class, got %v", gc.Spec.ControllerName)
|
||||
}
|
||||
if gc == nil {
|
||||
return fmt.Errorf("expected class %v, got none", controller)
|
||||
}
|
||||
if gateway.GatewayController(controller) != gc.Spec.ControllerName {
|
||||
return fmt.Errorf("expected class %v, got %v", controller, gc.Spec.ControllerName)
|
||||
}
|
||||
return nil
|
||||
}, retry.Timeout(time.Second*3))
|
||||
}
|
||||
|
||||
// Class should be created initially
|
||||
expectClass(defaultClassName, constants.ManagedGatewayController)
|
||||
|
||||
// Once we delete it, it should be added back
|
||||
deleteClass(defaultClassName)
|
||||
expectClass(defaultClassName, constants.ManagedGatewayController)
|
||||
|
||||
// Overwrite the class, controller should not reconcile it back
|
||||
createClass(defaultClassName, "different-controller")
|
||||
expectClass(defaultClassName, "different-controller")
|
||||
|
||||
// Once we delete it, it should be added back
|
||||
deleteClass(defaultClassName)
|
||||
expectClass(defaultClassName, constants.ManagedGatewayController)
|
||||
|
||||
// Create an unrelated GatewayClass, we should not do anything to it
|
||||
createClass("something-else", "different-controller")
|
||||
expectClass("something-else", "different-controller")
|
||||
deleteClass("something-else")
|
||||
expectClass("something-else", "")
|
||||
}
|
||||
32
pkg/ingress/kube/gateway/istio/generation_adapter.go
Normal file
32
pkg/ingress/kube/gateway/istio/generation_adapter.go
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright Istio Authors
|
||||
|
||||
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 istio
|
||||
|
||||
type gatewayGeneration struct {
|
||||
inner any
|
||||
}
|
||||
|
||||
func (g *gatewayGeneration) SetObservedGeneration(i int64) {
|
||||
// Intentionally blank. The observed generation of a gateway
|
||||
// status type is contained in the individual conditions
|
||||
// not at the top level, and is the responsibility
|
||||
// of the condition functions to update.
|
||||
}
|
||||
|
||||
func (g *gatewayGeneration) Unwrap() any {
|
||||
return g.inner
|
||||
}
|
||||
26
pkg/ingress/kube/gateway/istio/leak_test.go
Normal file
26
pkg/ingress/kube/gateway/istio/leak_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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 istio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"istio.io/istio/tests/util/leak"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// CheckMain asserts that no goroutines are leaked after a test package exits.
|
||||
leak.CheckMain(m)
|
||||
}
|
||||
122
pkg/ingress/kube/gateway/istio/model.go
Normal file
122
pkg/ingress/kube/gateway/istio/model.go
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"istio.io/istio/pilot/pkg/credentials"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
creds "istio.io/istio/pilot/pkg/model/credentials"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
|
||||
"github.com/alibaba/higress/pkg/config/constants"
|
||||
)
|
||||
|
||||
const (
|
||||
// Start - Updated by Higress
|
||||
defaultClassName = constants.DefaultGatewayClass
|
||||
gatewayAliasForAnnotationKey = "gateway.higress.io/alias-for"
|
||||
gatewayTLSTerminateModeKey = "gateway.higress.io/tls-terminate-mode"
|
||||
gatewayNameOverride = "gateway.higress.io/name-override"
|
||||
gatewaySAOverride = "gateway.higress.io/service-account"
|
||||
serviceTypeOverride = "networking.higress.io/service-type"
|
||||
// End - Updated by Higress
|
||||
)
|
||||
|
||||
// GatewayResources stores all gateway resources used for our conversion.
|
||||
type GatewayResources struct {
|
||||
GatewayClass []config.Config
|
||||
Gateway []config.Config
|
||||
HTTPRoute []config.Config
|
||||
TCPRoute []config.Config
|
||||
TLSRoute []config.Config
|
||||
ReferenceGrant []config.Config
|
||||
// Namespaces stores all namespace in the cluster, keyed by name
|
||||
Namespaces map[string]*corev1.Namespace
|
||||
// Credentials stores all credentials in the cluster
|
||||
Credentials credentials.Controller
|
||||
|
||||
// Start - Added by Higress
|
||||
DefaultGatewaySelector map[string]string
|
||||
// End - Added by Higress
|
||||
|
||||
// Domain for the cluster. Typically, cluster.local
|
||||
Domain string
|
||||
Context GatewayContext
|
||||
}
|
||||
|
||||
type Grants struct {
|
||||
AllowAll bool
|
||||
AllowedNames sets.String
|
||||
}
|
||||
|
||||
type AllowedReferences map[Reference]map[Reference]*Grants
|
||||
|
||||
func (refs AllowedReferences) SecretAllowed(resourceName string, namespace string) bool {
|
||||
p, err := creds.ParseResourceName(resourceName, "", "", "")
|
||||
if err != nil {
|
||||
log.Warnf("failed to parse resource name %q: %v", resourceName, err)
|
||||
return false
|
||||
}
|
||||
from := Reference{Kind: gvk.KubernetesGateway, Namespace: k8s.Namespace(namespace)}
|
||||
to := Reference{Kind: gvk.Secret, Namespace: k8s.Namespace(p.Namespace)}
|
||||
allow := refs[from][to]
|
||||
if allow == nil {
|
||||
return false
|
||||
}
|
||||
return allow.AllowAll || allow.AllowedNames.Contains(p.Name)
|
||||
}
|
||||
|
||||
func (refs AllowedReferences) BackendAllowed(
|
||||
k config.GroupVersionKind,
|
||||
backendName k8s.ObjectName,
|
||||
backendNamespace k8s.Namespace,
|
||||
routeNamespace string,
|
||||
) bool {
|
||||
from := Reference{Kind: k, Namespace: k8s.Namespace(routeNamespace)}
|
||||
to := Reference{Kind: gvk.Service, Namespace: backendNamespace}
|
||||
allow := refs[from][to]
|
||||
if allow == nil {
|
||||
return false
|
||||
}
|
||||
return allow.AllowAll || allow.AllowedNames.Contains(string(backendName))
|
||||
}
|
||||
|
||||
// IstioResources stores all outputs of our conversion
|
||||
type IstioResources struct {
|
||||
Gateway []config.Config
|
||||
VirtualService []config.Config
|
||||
// AllowedReferences stores all allowed references, from Reference -> to Reference(s)
|
||||
AllowedReferences AllowedReferences
|
||||
// ReferencedNamespaceKeys stores the label key of all namespace selections. This allows us to quickly
|
||||
// determine if a namespace update could have impacted any Gateways. See namespaceEvent.
|
||||
ReferencedNamespaceKeys sets.String
|
||||
|
||||
// ResourceReferences stores all resources referenced by gateway-api resources. This allows us to quickly
|
||||
// determine if a resource update could have impacted any Gateways.
|
||||
// key: referenced resources(e.g. secrets), value: gateway-api resources(e.g. gateways)
|
||||
ResourceReferences map[model.ConfigKey][]model.ConfigKey
|
||||
}
|
||||
|
||||
// Reference stores a reference to a namespaced GVK, as used by ReferencePolicy
|
||||
type Reference struct {
|
||||
Kind config.GroupVersionKind
|
||||
Namespace k8s.Namespace
|
||||
}
|
||||
98
pkg/ingress/kube/gateway/istio/testdata/alias.status.yaml.golden
vendored
Normal file
98
pkg/ingress/kube/gateway/istio/testdata/alias.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: third-party-gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: third-party-gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
65
pkg/ingress/kube/gateway/istio/testdata/alias.yaml
vendored
Normal file
65
pkg/ingress/kube/gateway/istio/testdata/alias.yaml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: third-party-gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: third-party-gatewayclass
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
annotations:
|
||||
gateway.higress.io/alias-for: third-party-gateway
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: third-party-gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["first.domain.example", "another.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
68
pkg/ingress/kube/gateway/istio/testdata/alias.yaml.golden
vendored
Normal file
68
pkg/ingress/kube/gateway/istio/testdata/alias.yaml.golden
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- first.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /
|
||||
name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-1-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- another.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /
|
||||
name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
131
pkg/ingress/kube/gateway/istio/testdata/benchmark-httproute.yaml
vendored
Normal file
131
pkg/ingress/kube/gateway/istio/testdata/benchmark-httproute.yaml
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
# the same as pilot/pkg/config/kube/gateway/testdata/route-precedence.yaml
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Selector
|
||||
selector:
|
||||
matchLabels:
|
||||
istio.io/test-name-part: allowed
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: allowed-1
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
- kind: Mesh
|
||||
name: istio
|
||||
hostnames: ["a.domain.example", "b.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /foo
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
backendRefs:
|
||||
- name: svc1
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: RegularExpression
|
||||
value: /foo((\/).*)?
|
||||
backendRefs:
|
||||
- name: svc2
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: allowed-2
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
- kind: Mesh
|
||||
name: istio
|
||||
hostnames: ["a.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /foo/bar
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /bar
|
||||
backendRefs:
|
||||
- name: svc2
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: Exact
|
||||
value: /baz
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
queryParams:
|
||||
- name: my-param
|
||||
value: some-value
|
||||
type: RegularExpression
|
||||
backendRefs:
|
||||
- name: svc2
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: svc3
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["a.domain.example", "b.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /abc
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
backendRefs:
|
||||
- name: svc4
|
||||
port: 80
|
||||
---
|
||||
141
pkg/ingress/kube/gateway/istio/testdata/delegated.status.yaml.golden
vendored
Normal file
141
pkg/ingress/kube/gateway/istio/testdata/delegated.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: apple
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: banana
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: apple
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: banana
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
67
pkg/ingress/kube/gateway/istio/testdata/delegated.yaml
vendored
Normal file
67
pkg/ingress/kube/gateway/istio/testdata/delegated.yaml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: apple
|
||||
hostname: "apple.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Selector
|
||||
selector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: apple
|
||||
- name: banana
|
||||
hostname: "banana.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Selector
|
||||
selector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: banana
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: apple
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin-apple
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: banana
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin-banana
|
||||
port: 80
|
||||
---
|
||||
80
pkg/ingress/kube/gateway/istio/testdata/delegated.yaml.golden
vendored
Normal file
80
pkg/ingress/kube/gateway/istio/testdata/delegated.yaml.golden
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/apple.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-apple
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- apple/apple.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/banana.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-banana
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- banana/banana.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.apple
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: apple
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-apple
|
||||
hosts:
|
||||
- '*'
|
||||
http:
|
||||
- name: apple/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin-apple.apple.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.banana
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: banana
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-banana
|
||||
hosts:
|
||||
- '*'
|
||||
http:
|
||||
- name: banana/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin-banana.banana.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
240
pkg/ingress/kube/gateway/istio/testdata/http.status.yaml.golden
vendored
Normal file
240
pkg/ingress/kube/gateway/istio/testdata/http.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 6
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http-not-selected
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: no hostnames matched parent hostname "*.domain.example"
|
||||
reason: NoMatchingListenerHostname
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http2
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: mirror
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: redirect
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: redirect-prefix-replace
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: rewrite
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
212
pkg/ingress/kube/gateway/istio/testdata/http.yaml
vendored
Normal file
212
pkg/ingress/kube/gateway/istio/testdata/http.yaml
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["first.domain.example", "another.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /get
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
filters:
|
||||
- type: RequestHeaderModifier
|
||||
requestHeaderModifier:
|
||||
add:
|
||||
- name: my-added-header
|
||||
value: added-value
|
||||
remove: [my-removed-header]
|
||||
- type: ResponseHeaderModifier
|
||||
responseHeaderModifier:
|
||||
add:
|
||||
- name: my-added-resp-header
|
||||
value: added-resp-value
|
||||
remove: [my-removed-header]
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http2
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["second.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /second
|
||||
backendRefs:
|
||||
- name: httpbin-second
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: httpbin-wildcard
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: redirect
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- filters:
|
||||
- type: RequestRedirect
|
||||
requestRedirect:
|
||||
port: 8080
|
||||
statusCode: 302
|
||||
scheme: https
|
||||
path:
|
||||
type: ReplaceFullPath
|
||||
replaceFullPath: /replace-full
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: redirect-prefix-replace
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["redirect.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /original
|
||||
filters:
|
||||
- type: RequestRedirect
|
||||
requestRedirect:
|
||||
port: 8080
|
||||
statusCode: 302
|
||||
scheme: https
|
||||
path:
|
||||
type: ReplacePrefixMatch
|
||||
replacePrefixMatch: /replacement
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: rewrite
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /prefix-original
|
||||
name: prefix-path-rewrite
|
||||
filters:
|
||||
- type: URLRewrite
|
||||
urlRewrite:
|
||||
hostname: "new.example.com"
|
||||
path:
|
||||
type: ReplacePrefixMatch
|
||||
replacePrefixMatch: "/replacement"
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /full-original
|
||||
name: full-path-rewrite
|
||||
filters:
|
||||
- type: URLRewrite
|
||||
urlRewrite:
|
||||
hostname: "new.example.com"
|
||||
path:
|
||||
type: ReplaceFullPath
|
||||
replaceFullPath: "/replacement"
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: mirror
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- filters:
|
||||
- type: RequestMirror
|
||||
requestMirror:
|
||||
backendRef:
|
||||
name: httpbin-mirror
|
||||
port: 80
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http-not-selected
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["should.not.select"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /get
|
||||
backendRefs:
|
||||
- name: httpbin-bad
|
||||
port: 80
|
||||
213
pkg/ingress/kube/gateway/istio/testdata/http.yaml.golden
vendored
Normal file
213
pkg/ingress/kube/gateway/istio/testdata/http.yaml.golden
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- first.domain.example
|
||||
http:
|
||||
- headers:
|
||||
request:
|
||||
add:
|
||||
my-added-header: added-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
response:
|
||||
add:
|
||||
my-added-resp-header: added-resp-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /get
|
||||
name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-1-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- another.domain.example
|
||||
http:
|
||||
- headers:
|
||||
request:
|
||||
add:
|
||||
my-added-header: added-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
response:
|
||||
add:
|
||||
my-added-resp-header: added-resp-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /get
|
||||
name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http2.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http2-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- second.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /second
|
||||
name: default/http2
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin-second.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /
|
||||
name: default/http2
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin-wildcard.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/mirror.default,HTTPRoute/redirect.default,HTTPRoute/rewrite.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: mirror-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- '*'
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /prefix-original
|
||||
name: default/rewrite
|
||||
rewrite:
|
||||
authority: new.example.com
|
||||
uri: /replacement
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /full-original
|
||||
name: default/rewrite
|
||||
rewrite:
|
||||
authority: new.example.com
|
||||
uriRegexRewrite:
|
||||
match: /.*
|
||||
rewrite: /replacement
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- mirror:
|
||||
host: httpbin-mirror.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
name: default/mirror
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- name: default/redirect
|
||||
redirect:
|
||||
port: 8080
|
||||
redirectCode: 302
|
||||
scheme: https
|
||||
uri: /replace-full
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/redirect-prefix-replace.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: redirect-prefix-replace-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- redirect.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /original
|
||||
name: default/redirect-prefix-replace
|
||||
redirect:
|
||||
port: 8080
|
||||
redirectCode: 302
|
||||
scheme: https
|
||||
uri: '%PREFIX()%/replacement'
|
||||
---
|
||||
480
pkg/ingress/kube/gateway/istio/testdata/invalid.status.yaml.golden
vendored
Normal file
480
pkg/ingress/kube/gateway/istio/testdata/invalid.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,480 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-service
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: hostname "fake-service.com"
|
||||
not found'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: target-port-reference
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: port 8080 not found for
|
||||
hostname "higress-gateway.higress-system.svc.domain.suffix" (hint: the service
|
||||
port should be specified, not the workload port. Did you mean one of these ports:
|
||||
[80]?)'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-gateway-address
|
||||
namespace: invalid-gateway-address
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: only Hostname is supported, ignoring [1.2.3.4]
|
||||
reason: UnsupportedAddress
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Failed to assign to any requested addresses
|
||||
reason: UnsupportedAddress
|
||||
status: "False"
|
||||
type: Programmed
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-cert-kind
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: invalid certificate reference core/unknown/my-cert-http., only secret
|
||||
is allowed
|
||||
reason: InvalidCertificateRef
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-cert-notfound
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: invalid certificate reference /Secret/nonexistent., secret higress-system/nonexistent
|
||||
not found
|
||||
reason: InvalidCertificateRef
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-cert-malformed
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: 'invalid certificate reference /Secret/malformed., the certificate
|
||||
is malformed: tls: failed to find any PEM data in certificate input'
|
||||
reason: InvalidCertificateRef
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-backendRef-kind
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'referencing unsupported backendRef: group "" kind "GcsBucket"'
|
||||
reason: InvalidKind
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-backendRef-mixed
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'referencing unsupported backendRef: group "" kind "GcsBucket"'
|
||||
reason: InvalidKind
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-backendRef-notfound
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: backend(nonexistent.default.svc.domain.suffix) not found
|
||||
reason: BackendNotFound
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-mirror
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'referencing unsupported backendRef: group "" kind "no-support"'
|
||||
reason: InvalidKind
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-parentRef-port
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: port 1234 not found
|
||||
reason: NoMatchingParent
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
port: 1234
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-sectionname-port
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: sectionName "fake" not found
|
||||
reason: NoMatchingParent
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: fake
|
||||
---
|
||||
|
||||
262
pkg/ingress/kube/gateway/istio/testdata/invalid.yaml
vendored
Normal file
262
pkg/ingress/kube/gateway/istio/testdata/invalid.yaml
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: invalid-service
|
||||
namespace: higress-system
|
||||
spec:
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
addresses:
|
||||
- value: fake-service.com
|
||||
type: Hostname
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: target-port-reference
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.example"
|
||||
port: 8080 # Test service has port 80 with targetPort 8080
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: invalid-gateway-address
|
||||
namespace: invalid-gateway-address
|
||||
spec:
|
||||
gatewayClassName: higress
|
||||
addresses:
|
||||
- value: 1.2.3.4
|
||||
type: istio.io/FakeType
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: invalid-cert-kind
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "domain.example"
|
||||
port: 34000
|
||||
protocol: HTTPS
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- name: my-cert-http
|
||||
group: core
|
||||
kind: unknown
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: invalid-cert-notfound
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "domain.example"
|
||||
port: 34001
|
||||
protocol: HTTPS
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- name: nonexistent
|
||||
kind: Secret
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: invalid-cert-malformed
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "domain.example"
|
||||
port: 34002
|
||||
protocol: HTTPS
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- name: malformed
|
||||
kind: Secret
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: invalid-backendRef-kind
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["first.domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
kind: GcsBucket
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: invalid-backendRef-notfound
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["second.domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: nonexistent
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: invalid-backendRef-mixed
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["third.domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: nonexistent
|
||||
port: 80
|
||||
weight: 1
|
||||
- name: httpbin
|
||||
port: 80
|
||||
weight: 1
|
||||
- name: httpbin
|
||||
kind: GcsBucket
|
||||
weight: 1
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: invalid-mirror
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- filters:
|
||||
- type: RequestMirror
|
||||
requestMirror:
|
||||
backendRef:
|
||||
kind: no-support
|
||||
name: httpbin-mirror
|
||||
port: 80
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: no-backend
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: httpbin
|
||||
rules:
|
||||
- filters:
|
||||
- type: RequestMirror
|
||||
requestMirror:
|
||||
backendRef:
|
||||
name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: invalid-parentRef-port
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
port: 1234
|
||||
hostnames: ["first.domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
weight: 1
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: invalid-sectionname-port
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: fake
|
||||
hostnames: ["first.domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
weight: 1
|
||||
167
pkg/ingress/kube/gateway/istio/testdata/invalid.yaml.golden
vendored
Normal file
167
pkg/ingress/kube/gateway/istio/testdata/invalid.yaml.golden
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: fake-service.com
|
||||
internal.istio.io/parents: Gateway/invalid-service/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: invalid-service-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- higress-system/*.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/target-port-reference/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: target-port-reference-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- higress-system/*.example
|
||||
port:
|
||||
name: default
|
||||
number: 8080
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: Gateway/invalid-gateway-address/default.invalid-gateway-address
|
||||
creationTimestamp: null
|
||||
name: invalid-gateway-address-istio-autogenerated-k8s-gateway-default
|
||||
namespace: invalid-gateway-address
|
||||
spec:
|
||||
selector:
|
||||
higress: higress-system-higress-gateway
|
||||
servers:
|
||||
- hosts:
|
||||
- invalid-gateway-address/*.domain.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/invalid-backendRef-kind.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: invalid-backendRef-kind-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- first.domain.example
|
||||
http:
|
||||
- name: default/invalid-backendRef-kind
|
||||
route:
|
||||
- destination: {}
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/invalid-backendRef-mixed.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: invalid-backendRef-mixed-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- third.domain.example
|
||||
http:
|
||||
- name: default/invalid-backendRef-mixed
|
||||
route:
|
||||
- destination:
|
||||
host: nonexistent.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
weight: 1
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
weight: 1
|
||||
- destination: {}
|
||||
weight: 1
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/invalid-backendRef-notfound.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: invalid-backendRef-notfound-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- second.domain.example
|
||||
http:
|
||||
- name: default/invalid-backendRef-notfound
|
||||
route:
|
||||
- destination:
|
||||
host: nonexistent.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/no-backend.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: no-backend-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- mesh
|
||||
hosts:
|
||||
- httpbin.default.svc.domain.suffix
|
||||
http:
|
||||
- directResponse:
|
||||
status: 500
|
||||
mirror:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
name: default/no-backend
|
||||
---
|
||||
75
pkg/ingress/kube/gateway/istio/testdata/mcs.status.yaml.golden
vendored
Normal file
75
pkg/ingress/kube/gateway/istio/testdata/mcs.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:34000
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TCPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tcp
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
30
pkg/ingress/kube/gateway/istio/testdata/mcs.yaml
vendored
Normal file
30
pkg/ingress/kube/gateway/istio/testdata/mcs.yaml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
port: 34000
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
name: tcp
|
||||
namespace: higress-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- group: multicluster.x-k8s.io
|
||||
kind: ServiceImport
|
||||
name: echo
|
||||
port: 80
|
||||
39
pkg/ingress/kube/gateway/istio/testdata/mcs.yaml.golden
vendored
Normal file
39
pkg/ingress/kube/gateway/istio/testdata/mcs.yaml.golden
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- higress-system/*
|
||||
port:
|
||||
name: default
|
||||
number: 34000
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TCPRoute/tcp.higress-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: tcp-tcp-istio-autogenerated-k8s-gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- '*'
|
||||
tcp:
|
||||
- route:
|
||||
- destination:
|
||||
host: echo.higress-system.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
23
pkg/ingress/kube/gateway/istio/testdata/mismatch.status.yaml.golden
vendored
Normal file
23
pkg/ingress/kube/gateway/istio/testdata/mismatch.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
---
|
||||
22
pkg/ingress/kube/gateway/istio/testdata/mismatch.yaml
vendored
Normal file
22
pkg/ingress/kube/gateway/istio/testdata/mismatch.yaml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Mismatch shows that we don't generate config for Gateways that do not match the GatewayClass
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: something-else
|
||||
listeners:
|
||||
- name: default
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
0
pkg/ingress/kube/gateway/istio/testdata/mismatch.yaml.golden
vendored
Normal file
0
pkg/ingress/kube/gateway/istio/testdata/mismatch.yaml.golden
vendored
Normal file
94
pkg/ingress/kube/gateway/istio/testdata/multi-gateway.status.yaml.golden
vendored
Normal file
94
pkg/ingress/kube/gateway/istio/testdata/multi-gateway.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Assigned to service(s) example.com:34000, example.com:80, higress-gateway.higress-system.svc.domain.suffix:34000,
|
||||
and higress-gateway.higress-system.svc.domain.suffix:80, but failed to assign
|
||||
to all requested addresses: hostname "higress-gateway.not-default.svc.domain.suffix"
|
||||
not found'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: http
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: tcp
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TCPRoute
|
||||
---
|
||||
32
pkg/ingress/kube/gateway/istio/testdata/multi-gateway.yaml
vendored
Normal file
32
pkg/ingress/kube/gateway/istio/testdata/multi-gateway.yaml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
gatewayClassName: higress
|
||||
addresses:
|
||||
- type: Hostname
|
||||
value: higress-gateway
|
||||
- type: Hostname
|
||||
value: higress-gateway.not-default.svc.domain.suffix
|
||||
- type: Hostname
|
||||
value: example.com
|
||||
listeners:
|
||||
- name: http
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
- name: tcp
|
||||
port: 34000
|
||||
protocol: TCP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
36
pkg/ingress/kube/gateway/istio/testdata/multi-gateway.yaml.golden
vendored
Normal file
36
pkg/ingress/kube/gateway/istio/testdata/multi-gateway.yaml.golden
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix,higress-gateway.not-default.svc.domain.suffix,example.com
|
||||
internal.istio.io/parents: Gateway/gateway/http.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-http
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- higress-system/*.domain.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix,higress-gateway.not-default.svc.domain.suffix,example.com
|
||||
internal.istio.io/parents: Gateway/gateway/tcp.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-tcp
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*'
|
||||
port:
|
||||
name: default
|
||||
number: 34000
|
||||
protocol: TCP
|
||||
---
|
||||
101
pkg/ingress/kube/gateway/istio/testdata/reference-policy-service.status.yaml.golden
vendored
Normal file
101
pkg/ingress/kube/gateway/istio/testdata/reference-policy-service.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 2
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: simple
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: backend-not-allowed
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: backendRef httpbin/default not accessible to a route in namespace "higress-system"
|
||||
(missing a ReferenceGrant?)
|
||||
reason: RefNotPermitted
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
70
pkg/ingress/kube/gateway/istio/testdata/reference-policy-service.yaml
vendored
Normal file
70
pkg/ingress/kube/gateway/istio/testdata/reference-policy-service.yaml
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: simple
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
name: allow-service
|
||||
namespace: service
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
namespace: higress-system
|
||||
to:
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: my-svc
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: higress-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["simple.domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: my-svc
|
||||
namespace: service
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: backend-not-allowed
|
||||
namespace: higress-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["simple2.domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: my-svc
|
||||
namespace: service
|
||||
port: 80
|
||||
weight: 1
|
||||
- name: httpbin
|
||||
namespace: default
|
||||
port: 80
|
||||
weight: 1
|
||||
65
pkg/ingress/kube/gateway/istio/testdata/reference-policy-service.yaml.golden
vendored
Normal file
65
pkg/ingress/kube/gateway/istio/testdata/reference-policy-service.yaml.golden
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/simple.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-simple
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/backend-not-allowed.higress-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: backend-not-allowed-0-istio-autogenerated-k8s-gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-simple
|
||||
hosts:
|
||||
- simple2.domain.example
|
||||
http:
|
||||
- name: backend-not-allowed
|
||||
route:
|
||||
- destination:
|
||||
host: my-svc.service.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
weight: 1
|
||||
- destination: {}
|
||||
weight: 1
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.higress-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-simple
|
||||
hosts:
|
||||
- simple.domain.example
|
||||
http:
|
||||
- name: http
|
||||
route:
|
||||
- destination:
|
||||
host: my-svc.service.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
88
pkg/ingress/kube/gateway/istio/testdata/reference-policy-tls.status.yaml.golden
vendored
Normal file
88
pkg/ingress/kube/gateway/istio/testdata/reference-policy-tls.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: port 443 not found for
|
||||
hostname "higress-gateway.higress-system.svc.domain.suffix"'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: cross
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: cert
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
62
pkg/ingress/kube/gateway/istio/testdata/reference-policy-tls.yaml
vendored
Normal file
62
pkg/ingress/kube/gateway/istio/testdata/reference-policy-tls.yaml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: cross
|
||||
hostname: "cert1.domain.example"
|
||||
port: 443
|
||||
protocol: HTTPS
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Selector
|
||||
selector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: "cert"
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- name: cert
|
||||
namespace: cert
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
name: allow-cert
|
||||
namespace: cert
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
namespace: higress-system
|
||||
to:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: cert
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["cert1.domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
43
pkg/ingress/kube/gateway/istio/testdata/reference-policy-tls.yaml.golden
vendored
Normal file
43
pkg/ingress/kube/gateway/istio/testdata/reference-policy-tls.yaml.golden
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/cross.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-cross
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- cert/cert1.domain.example
|
||||
port:
|
||||
name: default
|
||||
number: 443
|
||||
protocol: HTTPS
|
||||
tls:
|
||||
credentialName: kubernetes-gateway://cert/cert
|
||||
mode: SIMPLE
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.cert
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: cert
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-cross
|
||||
hosts:
|
||||
- cert1.domain.example
|
||||
http:
|
||||
- name: cert/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.cert.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
418
pkg/ingress/kube/gateway/istio/testdata/route-binding.status.yaml.golden
vendored
Normal file
418
pkg/ingress/kube/gateway/istio/testdata/route-binding.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- attachedRoutes: 3
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: foobar
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: same-namespace
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: Invalid route kinds
|
||||
reason: InvalidRouteKinds
|
||||
status: "False"
|
||||
type: ResolvedRefs
|
||||
name: scope-route
|
||||
supportedKinds: []
|
||||
- attachedRoutes: 2
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: namespace-selector
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: bind-all
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid, bound to 2 parents
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: host-mismatch
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: no hostnames matched parent hostname "*.foobar.example"
|
||||
reason: NoMatchingListenerHostname
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: foobar
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-bind-cross-namespace
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: hostnames matched parent hostname "*.namespace-selector.example", but
|
||||
namespace "default" is not allowed by the parent
|
||||
reason: NotAllowedByListeners
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: namespace-selector
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: same-namespace-invalid
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: no hostnames matched parent hostname "*.same-namespace.example"
|
||||
reason: NoMatchingListenerHostname
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
kind: Gateway
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: same-namespace
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: section-name-cross-namespace
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: foobar
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: bind-cross-namespace
|
||||
namespace: group-namespace1
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: namespace-selector
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: bind-cross-namespace
|
||||
namespace: group-namespace2
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: namespace-selector
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: same-namespace-valid
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: same-namespace
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: foobar
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: wrong-protocol
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: kind gateway.networking.k8s.io/v1alpha2/TCPRoute is not allowed
|
||||
reason: NotAllowedByListeners
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: foobar
|
||||
---
|
||||
200
pkg/ingress/kube/gateway/istio/testdata/route-binding.yaml
vendored
Normal file
200
pkg/ingress/kube/gateway/istio/testdata/route-binding.yaml
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
- name: foobar
|
||||
hostname: "*.foobar.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
kinds:
|
||||
- kind: HTTPRoute
|
||||
- name: same-namespace
|
||||
hostname: "*.same-namespace.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
- name: scope-route
|
||||
hostname: "*.scope-route.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
kinds:
|
||||
- kind: TCPRoute
|
||||
- name: namespace-selector
|
||||
hostname: "*.namespace-selector.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Selector
|
||||
selector:
|
||||
matchLabels:
|
||||
istio.io/test-name-part: group
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: section-name-cross-namespace
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: foobar
|
||||
hostnames: ["alpha.foobar.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: same-namespace-valid
|
||||
namespace: higress-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: foobar
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: same-namespace
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 81
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: same-namespace-invalid
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- kind: Gateway
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: same-namespace
|
||||
hostnames: ["foo.same.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: echo
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
# Should not generate anything, the protocol is HTTP
|
||||
name: wrong-protocol
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: foobar
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 82
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: host-mismatch
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: foobar
|
||||
hostnames: ["no.match.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 84
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: bind-all
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 85
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: bind-cross-namespace
|
||||
namespace: group-namespace1
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: namespace-selector
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 86
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: bind-cross-namespace
|
||||
namespace: group-namespace2
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: namespace-selector
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 87
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: invalid-bind-cross-namespace
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
sectionName: namespace-selector
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 87
|
||||
|
||||
213
pkg/ingress/kube/gateway/istio/testdata/route-binding.yaml.golden
vendored
Normal file
213
pkg/ingress/kube/gateway/istio/testdata/route-binding.yaml.golden
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/foobar.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-foobar
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.foobar.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/same-namespace.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-same-namespace
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- higress-system/*.same-namespace.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/scope-route.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-scope-route
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.scope-route.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/namespace-selector.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-namespace-selector
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- group-namespace1/*.namespace-selector.example
|
||||
- group-namespace2/*.namespace-selector.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/bind-all.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: bind-all-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- '*'
|
||||
http:
|
||||
- name: default/bind-all
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 85
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/bind-all.default,HTTPRoute/same-namespace-valid.higress-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: bind-all-1-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-foobar
|
||||
hosts:
|
||||
- '*'
|
||||
http:
|
||||
- name: default/bind-all
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 85
|
||||
- name: same-namespace-valid
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.higress-system.svc.domain.suffix
|
||||
port:
|
||||
number: 81
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/section-name-cross-namespace.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: section-name-cross-namespace-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-foobar
|
||||
hosts:
|
||||
- alpha.foobar.example
|
||||
http:
|
||||
- name: default/section-name-cross-namespace
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/bind-cross-namespace.group-namespace1,HTTPRoute/bind-cross-namespace.group-namespace2
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: bind-cross-namespace-0-istio-autogenerated-k8s-gateway
|
||||
namespace: group-namespace1
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-namespace-selector
|
||||
hosts:
|
||||
- '*'
|
||||
http:
|
||||
- name: group-namespace1/bind-cross-namespace
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.group-namespace1.svc.domain.suffix
|
||||
port:
|
||||
number: 86
|
||||
- name: group-namespace2/bind-cross-namespace
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.group-namespace2.svc.domain.suffix
|
||||
port:
|
||||
number: 87
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/same-namespace-valid.higress-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: same-namespace-valid-0-istio-autogenerated-k8s-gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-same-namespace
|
||||
hosts:
|
||||
- '*'
|
||||
http:
|
||||
- name: same-namespace-valid
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.higress-system.svc.domain.suffix
|
||||
port:
|
||||
number: 81
|
||||
---
|
||||
189
pkg/ingress/kube/gateway/istio/testdata/route-precedence.status.yaml.golden
vendored
Normal file
189
pkg/ingress/kube/gateway/istio/testdata/route-precedence.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 2
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: allowed-1
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: b-example
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: a-example
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: allowed-2
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: a-example
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: hostnames matched parent hostname "*.domain.example", but namespace
|
||||
"default" is not allowed by the parent
|
||||
reason: NotAllowedByListeners
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
143
pkg/ingress/kube/gateway/istio/testdata/route-precedence.yaml
vendored
Normal file
143
pkg/ingress/kube/gateway/istio/testdata/route-precedence.yaml
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Selector
|
||||
selector:
|
||||
matchLabels:
|
||||
istio.io/test-name-part: allowed
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: allowed-1
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: a-example
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: b-example
|
||||
hostnames: ["a.domain.example", "b.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /foo
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
backendRefs:
|
||||
- name: svc1
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: RegularExpression
|
||||
value: /foo((\/).*)?
|
||||
backendRefs:
|
||||
- name: svc2
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: allowed-2
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: a-example
|
||||
hostnames: ["a.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /foo/bar
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /bar
|
||||
backendRefs:
|
||||
- name: svc2
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: Exact
|
||||
value: /baz
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
queryParams:
|
||||
- name: my-param
|
||||
value: some-value
|
||||
type: RegularExpression
|
||||
backendRefs:
|
||||
- name: svc2
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: svc3
|
||||
port: 80
|
||||
- matches:
|
||||
- method: PATCH
|
||||
path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: svc2
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["a.domain.example", "b.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /abc
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
backendRefs:
|
||||
- name: svc4
|
||||
port: 80
|
||||
---
|
||||
289
pkg/ingress/kube/gateway/istio/testdata/route-precedence.yaml.golden
vendored
Normal file
289
pkg/ingress/kube/gateway/istio/testdata/route-precedence.yaml.golden
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- allowed-1/*.domain.example
|
||||
- allowed-2/*.domain.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.allowed-1,HTTPRoute/http.allowed-2
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: allowed-1
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- a.domain.example
|
||||
http:
|
||||
- match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
queryParams:
|
||||
my-param:
|
||||
regex: some-value
|
||||
uri:
|
||||
exact: /baz
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /foo/bar
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /foo
|
||||
name: allowed-1/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc1.allowed-1.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /bar
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- method:
|
||||
exact: PATCH
|
||||
uri:
|
||||
prefix: /
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
regex: /foo((\/).*)?
|
||||
name: allowed-1/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-1.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc3.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.allowed-1
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-1-istio-autogenerated-k8s-gateway
|
||||
namespace: allowed-1
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- b.domain.example
|
||||
http:
|
||||
- match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /foo
|
||||
name: allowed-1/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc1.allowed-1.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
regex: /foo((\/).*)?
|
||||
name: allowed-1/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-1.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.allowed-1
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-2-istio-autogenerated-k8s-gateway
|
||||
namespace: allowed-1
|
||||
spec:
|
||||
gateways:
|
||||
- mesh
|
||||
hosts:
|
||||
- a-example.allowed-1.svc.domain.suffix
|
||||
http:
|
||||
- match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /foo
|
||||
name: allowed-1/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc1.allowed-1.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
regex: /foo((\/).*)?
|
||||
name: allowed-1/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-1.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.allowed-1
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-3-istio-autogenerated-k8s-gateway
|
||||
namespace: allowed-1
|
||||
spec:
|
||||
gateways:
|
||||
- mesh
|
||||
hosts:
|
||||
- b-example.allowed-1.svc.domain.suffix
|
||||
http:
|
||||
- match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /foo
|
||||
name: allowed-1/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc1.allowed-1.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
regex: /foo((\/).*)?
|
||||
name: allowed-1/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-1.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.allowed-2
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: allowed-2
|
||||
spec:
|
||||
gateways:
|
||||
- mesh
|
||||
hosts:
|
||||
- a-example.allowed-2.svc.domain.suffix
|
||||
http:
|
||||
- match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
queryParams:
|
||||
my-param:
|
||||
regex: some-value
|
||||
uri:
|
||||
exact: /baz
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /foo/bar
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /bar
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- method:
|
||||
exact: PATCH
|
||||
uri:
|
||||
prefix: /
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc2.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /
|
||||
name: allowed-2/http
|
||||
route:
|
||||
- destination:
|
||||
host: svc3.allowed-2.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
73
pkg/ingress/kube/gateway/istio/testdata/serviceentry.status.yaml.golden
vendored
Normal file
73
pkg/ingress/kube/gateway/istio/testdata/serviceentry.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: hostname "gateway-higress.higress-system.svc.domain.suffix"
|
||||
not found'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
32
pkg/ingress/kube/gateway/istio/testdata/serviceentry.yaml
vendored
Normal file
32
pkg/ingress/kube/gateway/istio/testdata/serviceentry.yaml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
-
|
||||
backendRefs:
|
||||
- kind: Hostname
|
||||
group: networking.istio.io
|
||||
name: google.com
|
||||
port: 80
|
||||
---
|
||||
41
pkg/ingress/kube/gateway/istio/testdata/serviceentry.yaml.golden
vendored
Normal file
41
pkg/ingress/kube/gateway/istio/testdata/serviceentry.yaml.golden
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
selector:
|
||||
higress: higress-system-higress-gateway
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- '*'
|
||||
http:
|
||||
- name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: google.com
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
90
pkg/ingress/kube/gateway/istio/testdata/tcp.status.yaml.golden
vendored
Normal file
90
pkg/ingress/kube/gateway/istio/testdata/tcp.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:34000
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TCPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tcp
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
38
pkg/ingress/kube/gateway/istio/testdata/tcp.yaml
vendored
Normal file
38
pkg/ingress/kube/gateway/istio/testdata/tcp.yaml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
port: 34000
|
||||
protocol: TCP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
name: tcp
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 9090
|
||||
39
pkg/ingress/kube/gateway/istio/testdata/tcp.yaml.golden
vendored
Normal file
39
pkg/ingress/kube/gateway/istio/testdata/tcp.yaml.golden
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*'
|
||||
port:
|
||||
name: default
|
||||
number: 34000
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TCPRoute/tcp.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: tcp-tcp-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- '*'
|
||||
tcp:
|
||||
- route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 9090
|
||||
---
|
||||
192
pkg/ingress/kube/gateway/istio/testdata/tls.status.yaml.golden
vendored
Normal file
192
pkg/ingress/kube/gateway/istio/testdata/tls.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:34000
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 2
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: passthrough
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: terminate
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: terminate-mtls
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tls
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tls-match
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
95
pkg/ingress/kube/gateway/istio/testdata/tls.yaml
vendored
Normal file
95
pkg/ingress/kube/gateway/istio/testdata/tls.yaml
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: passthrough
|
||||
port: 34000
|
||||
protocol: TLS
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
tls:
|
||||
mode: Passthrough
|
||||
- name: terminate
|
||||
hostname: "domain.example"
|
||||
port: 34000
|
||||
protocol: HTTPS
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- name: my-cert-http
|
||||
- name: terminate-mtls
|
||||
hostname: "other.example"
|
||||
port: 34000
|
||||
protocol: HTTPS
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- name: my-cert-http
|
||||
options:
|
||||
gateway.higress.io/tls-terminate-mode: MUTUAL
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: tls
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 443
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: tls-match
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames:
|
||||
- "foo.com"
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin-foo
|
||||
port: 443
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["domain.example"]
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
131
pkg/ingress/kube/gateway/istio/testdata/tls.yaml.golden
vendored
Normal file
131
pkg/ingress/kube/gateway/istio/testdata/tls.yaml.golden
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/passthrough.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-passthrough
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*'
|
||||
port:
|
||||
name: default
|
||||
number: 34000
|
||||
protocol: TLS
|
||||
tls: {}
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/terminate.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-terminate
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 34000
|
||||
protocol: HTTPS
|
||||
tls:
|
||||
credentialName: kubernetes-gateway://higress-system/my-cert-http
|
||||
mode: SIMPLE
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/terminate-mtls.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-terminate-mtls
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/other.example'
|
||||
port:
|
||||
name: default
|
||||
number: 34000
|
||||
protocol: HTTPS
|
||||
tls:
|
||||
credentialName: kubernetes-gateway://higress-system/my-cert-http
|
||||
mode: MUTUAL
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-terminate
|
||||
hosts:
|
||||
- domain.example
|
||||
http:
|
||||
- name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TLSRoute/tls-match.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: tls-match-tls-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-passthrough
|
||||
hosts:
|
||||
- foo.com
|
||||
tls:
|
||||
- match:
|
||||
- sniHosts:
|
||||
- foo.com
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin-foo.default.svc.domain.suffix
|
||||
port:
|
||||
number: 443
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TLSRoute/tls.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: tls-tls-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-passthrough
|
||||
hosts:
|
||||
- '*'
|
||||
tls:
|
||||
- match:
|
||||
- sniHosts:
|
||||
- '*'
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 443
|
||||
---
|
||||
142
pkg/ingress/kube/gateway/istio/testdata/weighted.status.yaml.golden
vendored
Normal file
142
pkg/ingress/kube/gateway/istio/testdata/weighted.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:34000
|
||||
and higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: http
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: tcp
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TCPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tcp
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
94
pkg/ingress/kube/gateway/istio/testdata/weighted.yaml
vendored
Normal file
94
pkg/ingress/kube/gateway/istio/testdata/weighted.yaml
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: http
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
- name: tcp
|
||||
port: 34000
|
||||
protocol: TCP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["first.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /get
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
weight: 2
|
||||
- name: httpbin-other
|
||||
port: 8080
|
||||
weight: 3
|
||||
- name: httpbin-zero
|
||||
port: 8080
|
||||
weight: 0
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /weighted-100
|
||||
backendRefs:
|
||||
- filters:
|
||||
- requestHeaderModifier:
|
||||
add:
|
||||
- name: foo
|
||||
value: bar
|
||||
type: RequestHeaderModifier
|
||||
- responseHeaderModifier:
|
||||
add:
|
||||
- name: response
|
||||
value: header
|
||||
type: ResponseHeaderModifier
|
||||
port: 8000
|
||||
name: foo-svc
|
||||
weight: 100
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
name: tcp
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin
|
||||
port: 9090
|
||||
weight: 1
|
||||
- name: httpbin-alt
|
||||
port: 9090
|
||||
weight: 2
|
||||
110
pkg/ingress/kube/gateway/istio/testdata/weighted.yaml.golden
vendored
Normal file
110
pkg/ingress/kube/gateway/istio/testdata/weighted.yaml.golden
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/http.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-http
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/tcp.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-tcp
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*'
|
||||
port:
|
||||
name: default
|
||||
number: 34000
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-http
|
||||
hosts:
|
||||
- first.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /weighted-100
|
||||
name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: foo-svc.default.svc.domain.suffix
|
||||
port:
|
||||
number: 8000
|
||||
headers:
|
||||
request:
|
||||
add:
|
||||
foo: bar
|
||||
response:
|
||||
add:
|
||||
response: header
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /get
|
||||
name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
weight: 2
|
||||
- destination:
|
||||
host: httpbin-other.default.svc.domain.suffix
|
||||
port:
|
||||
number: 8080
|
||||
weight: 3
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TCPRoute/tcp.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: tcp-tcp-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-tcp
|
||||
hosts:
|
||||
- '*'
|
||||
tcp:
|
||||
- route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 9090
|
||||
weight: 1
|
||||
- destination:
|
||||
host: httpbin-alt.default.svc.domain.suffix
|
||||
port:
|
||||
number: 9090
|
||||
weight: 2
|
||||
---
|
||||
142
pkg/ingress/kube/gateway/istio/testdata/zero.status.yaml.golden
vendored
Normal file
142
pkg/ingress/kube/gateway/istio/testdata/zero.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Handled by Higress controller
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:34000
|
||||
and higress-gateway.higress-system.svc.domain.suffix:80
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: tcp
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TCPRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tcp
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
80
pkg/ingress/kube/gateway/istio/testdata/zero.yaml
vendored
Normal file
80
pkg/ingress/kube/gateway/istio/testdata/zero.yaml
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
- name: tcp
|
||||
port: 34000
|
||||
protocol: TCP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["first.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /get
|
||||
backendRefs:
|
||||
- name: httpbin-zero
|
||||
port: 8080
|
||||
weight: 0
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /weighted-100
|
||||
backendRefs:
|
||||
- filters:
|
||||
- requestHeaderModifier:
|
||||
add:
|
||||
- name: foo
|
||||
value: bar
|
||||
type: RequestHeaderModifier
|
||||
port: 8000
|
||||
name: foo-svc
|
||||
weight: 100
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TCPRoute
|
||||
metadata:
|
||||
name: tcp
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: httpbin-zero
|
||||
port: 8080
|
||||
weight: 0
|
||||
93
pkg/ingress/kube/gateway/istio/testdata/zero.yaml.golden
vendored
Normal file
93
pkg/ingress/kube/gateway/istio/testdata/zero.yaml.golden
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/tcp.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-tcp
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*'
|
||||
port:
|
||||
name: default
|
||||
number: 34000
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- first.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /weighted-100
|
||||
name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: foo-svc.default.svc.domain.suffix
|
||||
port:
|
||||
number: 8000
|
||||
headers:
|
||||
request:
|
||||
add:
|
||||
foo: bar
|
||||
- directResponse:
|
||||
status: 500
|
||||
match:
|
||||
- uri:
|
||||
prefix: /get
|
||||
name: default/http
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TCPRoute/tcp.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: tcp-tcp-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-tcp
|
||||
hosts:
|
||||
- '*'
|
||||
tcp:
|
||||
- route:
|
||||
- destination:
|
||||
host: internal.cluster.local
|
||||
port:
|
||||
number: 65535
|
||||
subset: zero-weight
|
||||
---
|
||||
Reference in New Issue
Block a user