gateway api: support RouteNamespaces
Co-authored-by: Jean-Baptiste Doumenjou <925513+jbdoumenjou@users.noreply.github.com>
This commit is contained in:
parent
9ef3fc84f9
commit
969dd088a2
24 changed files with 2629 additions and 95 deletions
|
@ -424,3 +424,9 @@ Traefik v2.6 introduces the `AdvertisedPort` option,
|
||||||
which allows advertising, in the `Alt-Svc` header, a UDP port different from the one on which Traefik is actually listening (the EntryPoint's port).
|
which allows advertising, in the `Alt-Svc` header, a UDP port different from the one on which Traefik is actually listening (the EntryPoint's port).
|
||||||
By doing so, it introduces a new configuration structure `http3`, which replaces the `enableHTTP3` option (which therefore doesn't exist anymore).
|
By doing so, it introduces a new configuration structure `http3`, which replaces the `enableHTTP3` option (which therefore doesn't exist anymore).
|
||||||
To enable HTTP3 on an EntryPoint, please check out the [HTTP3 configuration](../routing/entrypoints.md#http3) documentation.
|
To enable HTTP3 on an EntryPoint, please check out the [HTTP3 configuration](../routing/entrypoints.md#http3) documentation.
|
||||||
|
|
||||||
|
### Kubernetes Gateway provider
|
||||||
|
|
||||||
|
In `v2.6`, the [Kubernetes Gateway provider](../providers/kubernetes-gateway.md) now supports [route namespaces](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.RouteNamespaces) selectors,
|
||||||
|
which requires Traefik to fetch and watch the cluster namespaces.
|
||||||
|
Therefore, the RBAC definitions must be updated, please check out the [RBAC configuration reference](../reference/dynamic-configuration/kubernetes-gateway.md#rbac).
|
||||||
|
|
|
@ -4,6 +4,13 @@ kind: ClusterRole
|
||||||
metadata:
|
metadata:
|
||||||
name: gateway-role
|
name: gateway-role
|
||||||
rules:
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- namespaces
|
||||||
|
verbs:
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
|
|
|
@ -97,8 +97,13 @@ Depending on the Listener Protocol, different modes and Route types are supporte
|
||||||
port: 80 # [4]
|
port: 80 # [4]
|
||||||
routes: # [8]
|
routes: # [8]
|
||||||
kind: HTTPRoute # [9]
|
kind: HTTPRoute # [9]
|
||||||
selector: # [10]
|
namespaces:
|
||||||
matchLabels: # [11]
|
from: Selector # [10]
|
||||||
|
selector: # [11]
|
||||||
|
matchLabels:
|
||||||
|
app: foo
|
||||||
|
selector: # [12]
|
||||||
|
matchLabels:
|
||||||
app: foo
|
app: foo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -120,8 +125,13 @@ Depending on the Listener Protocol, different modes and Route types are supporte
|
||||||
name: "mysecret"
|
name: "mysecret"
|
||||||
routes: # [8]
|
routes: # [8]
|
||||||
kind: HTTPRoute # [9]
|
kind: HTTPRoute # [9]
|
||||||
selector: # [10]
|
namespaces:
|
||||||
matchLabels: # [11]
|
from: Selector # [10]
|
||||||
|
selector: # [11]
|
||||||
|
matchLabels:
|
||||||
|
app: foo
|
||||||
|
selector: # [12]
|
||||||
|
matchLabels:
|
||||||
app: foo
|
app: foo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -138,8 +148,13 @@ Depending on the Listener Protocol, different modes and Route types are supporte
|
||||||
port: 8000 # [4]
|
port: 8000 # [4]
|
||||||
routes: # [8]
|
routes: # [8]
|
||||||
kind: TCPRoute # [9]
|
kind: TCPRoute # [9]
|
||||||
selector: # [10]
|
namespaces:
|
||||||
matchLabels: # [11]
|
from: Selector # [10]
|
||||||
|
selector: # [11]
|
||||||
|
matchLabels:
|
||||||
|
app: footcp
|
||||||
|
selector: # [12]
|
||||||
|
matchLabels:
|
||||||
app: footcp
|
app: footcp
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -162,13 +177,18 @@ Depending on the Listener Protocol, different modes and Route types are supporte
|
||||||
name: "mysecret"
|
name: "mysecret"
|
||||||
routes: # [8]
|
routes: # [8]
|
||||||
kind: TLSRoute # [9]
|
kind: TLSRoute # [9]
|
||||||
selector: # [10]
|
namespaces:
|
||||||
matchLabels: # [11]
|
from: Selector # [10]
|
||||||
|
selector: # [11]
|
||||||
|
matchLabels:
|
||||||
|
app: footcp
|
||||||
|
selector: # [12]
|
||||||
|
matchLabels:
|
||||||
app: footcp
|
app: footcp
|
||||||
```
|
```
|
||||||
|
|
||||||
| Ref | Attribute | Description |
|
| Ref | Attribute | Description |
|
||||||
|------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|------|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [1] | `gatewayClassName` | GatewayClassName used for this Gateway. This is the name of a GatewayClass resource. |
|
| [1] | `gatewayClassName` | GatewayClassName used for this Gateway. This is the name of a GatewayClass resource. |
|
||||||
| [2] | `listeners` | Logical endpoints that are bound on this Gateway's addresses. At least one Listener MUST be specified. |
|
| [2] | `listeners` | Logical endpoints that are bound on this Gateway's addresses. At least one Listener MUST be specified. |
|
||||||
| [3] | `protocol` | The network protocol this listener expects to receive (only HTTP and HTTPS are implemented). |
|
| [3] | `protocol` | The network protocol this listener expects to receive (only HTTP and HTTPS are implemented). |
|
||||||
|
@ -178,8 +198,9 @@ Depending on the Listener Protocol, different modes and Route types are supporte
|
||||||
| [7] | `certificateRef` | The reference to Kubernetes object that contains a TLS certificate and private key. |
|
| [7] | `certificateRef` | The reference to Kubernetes object that contains a TLS certificate and private key. |
|
||||||
| [8] | `routes` | A schema for associating routes with the Listener using selectors. |
|
| [8] | `routes` | A schema for associating routes with the Listener using selectors. |
|
||||||
| [9] | `kind` | The kind of the referent. |
|
| [9] | `kind` | The kind of the referent. |
|
||||||
| [10] | `selector` | Routes in namespaces selected by the selector may be used by this Gateway routes to associate with the Gateway. |
|
| [10] | `from` | From indicates in which namespaces the Routes will be selected for this Gateway. Possible values are `All`, `Same` and `Selector` (Defaults to `Same`). |
|
||||||
| [11] | `matchLabels` | A set of route labels used for selecting routes to associate with the Gateway. |
|
| [11] | `selector` | Selector must be specified when From is set to `Selector`. In that case, only Routes in Namespaces matching this Selector will be selected by this Gateway. |
|
||||||
|
| [12] | `selector` | Selector specifies a set of route labels used for selecting routes to associate with the Gateway. An empty Selector matches all routes. |
|
||||||
|
|
||||||
### Kind: `HTTPRoute`
|
### Kind: `HTTPRoute`
|
||||||
|
|
||||||
|
|
|
@ -55,19 +55,21 @@ type Client interface {
|
||||||
UpdateGatewayStatus(gateway *v1alpha1.Gateway, gatewayStatus v1alpha1.GatewayStatus) error
|
UpdateGatewayStatus(gateway *v1alpha1.Gateway, gatewayStatus v1alpha1.GatewayStatus) error
|
||||||
UpdateGatewayClassStatus(gatewayClass *v1alpha1.GatewayClass, condition metav1.Condition) error
|
UpdateGatewayClassStatus(gatewayClass *v1alpha1.GatewayClass, condition metav1.Condition) error
|
||||||
GetGateways() []*v1alpha1.Gateway
|
GetGateways() []*v1alpha1.Gateway
|
||||||
GetHTTPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error)
|
GetHTTPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error)
|
||||||
GetTCPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error)
|
GetTCPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error)
|
||||||
GetTLSRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error)
|
GetTLSRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error)
|
||||||
|
|
||||||
GetService(namespace, name string) (*corev1.Service, bool, error)
|
GetService(namespace, name string) (*corev1.Service, bool, error)
|
||||||
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
|
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
|
||||||
GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error)
|
GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error)
|
||||||
|
GetNamespaces(selector labels.Selector) ([]string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type clientWrapper struct {
|
type clientWrapper struct {
|
||||||
csGateway versioned.Interface
|
csGateway versioned.Interface
|
||||||
csKube kubernetes.Interface
|
csKube kubernetes.Interface
|
||||||
|
|
||||||
|
factoryNamespace informers.SharedInformerFactory
|
||||||
factoryGatewayClass externalversions.SharedInformerFactory
|
factoryGatewayClass externalversions.SharedInformerFactory
|
||||||
factoriesGateway map[string]externalversions.SharedInformerFactory
|
factoriesGateway map[string]externalversions.SharedInformerFactory
|
||||||
factoriesKube map[string]informers.SharedInformerFactory
|
factoriesKube map[string]informers.SharedInformerFactory
|
||||||
|
@ -171,6 +173,9 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
|
||||||
options.LabelSelector = c.labelSelector
|
options.LabelSelector = c.labelSelector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.factoryNamespace = informers.NewSharedInformerFactory(c.csKube, resyncPeriod)
|
||||||
|
c.factoryNamespace.Core().V1().Namespaces().Informer().AddEventHandler(eventHandler)
|
||||||
|
|
||||||
c.factoryGatewayClass = externalversions.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, externalversions.WithTweakListOptions(labelSelectorOptions))
|
c.factoryGatewayClass = externalversions.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, externalversions.WithTweakListOptions(labelSelectorOptions))
|
||||||
c.factoryGatewayClass.Networking().V1alpha1().GatewayClasses().Informer().AddEventHandler(eventHandler)
|
c.factoryGatewayClass.Networking().V1alpha1().GatewayClasses().Informer().AddEventHandler(eventHandler)
|
||||||
|
|
||||||
|
@ -193,6 +198,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
|
||||||
c.factoriesSecret[ns] = factorySecret
|
c.factoriesSecret[ns] = factorySecret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.factoryNamespace.Start(stopCh)
|
||||||
c.factoryGatewayClass.Start(stopCh)
|
c.factoryGatewayClass.Start(stopCh)
|
||||||
|
|
||||||
for _, ns := range namespaces {
|
for _, ns := range namespaces {
|
||||||
|
@ -201,6 +207,12 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
|
||||||
c.factoriesSecret[ns].Start(stopCh)
|
c.factoriesSecret[ns].Start(stopCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for t, ok := range c.factoryNamespace.WaitForCacheSync(stopCh) {
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("timed out waiting for controller caches to sync %s", t.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for t, ok := range c.factoryGatewayClass.WaitForCacheSync(stopCh) {
|
for t, ok := range c.factoryGatewayClass.WaitForCacheSync(stopCh) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("timed out waiting for controller caches to sync %s", t.String())
|
return nil, fmt.Errorf("timed out waiting for controller caches to sync %s", t.String())
|
||||||
|
@ -230,53 +242,90 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
|
||||||
return eventCh, nil
|
return eventCh, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientWrapper) GetHTTPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error) {
|
func (c *clientWrapper) GetNamespaces(selector labels.Selector) ([]string, error) {
|
||||||
if !c.isWatchedNamespace(namespace) {
|
ns, err := c.factoryNamespace.Core().V1().Namespaces().Lister().List(selector)
|
||||||
return nil, fmt.Errorf("failed to get HTTPRoutes %s with labels selector %s: namespace is not within watched namespaces", namespace, selector)
|
|
||||||
}
|
|
||||||
httpRoutes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().HTTPRoutes().Lister().HTTPRoutes(namespace).List(selector)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(httpRoutes) == 0 {
|
var namespaces []string
|
||||||
|
for _, namespace := range ns {
|
||||||
|
if !c.isWatchedNamespace(namespace.Name) {
|
||||||
|
log.WithoutContext().Warnf("Namespace %q is not within watched namespaces", selector, namespace)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
namespaces = append(namespaces, namespace.Name)
|
||||||
|
}
|
||||||
|
return namespaces, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *clientWrapper) GetHTTPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error) {
|
||||||
|
var httpRoutes []*v1alpha1.HTTPRoute
|
||||||
|
for _, namespace := range namespaces {
|
||||||
|
if !c.isWatchedNamespace(namespace) {
|
||||||
|
log.WithoutContext().Warnf("Failed to get HTTPRoutes with labels selector %s: %q is not within watched namespaces", selector, namespace)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
routes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().HTTPRoutes().Lister().HTTPRoutes(namespace).List(selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(routes) == 0 {
|
||||||
log.WithoutContext().Debugf("No HTTPRoutes found in %q namespace with labels selector %s", namespace, selector)
|
log.WithoutContext().Debugf("No HTTPRoutes found in %q namespace with labels selector %s", namespace, selector)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRoutes = append(httpRoutes, routes...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return httpRoutes, nil
|
return httpRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientWrapper) GetTCPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error) {
|
func (c *clientWrapper) GetTCPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error) {
|
||||||
|
var tcpRoutes []*v1alpha1.TCPRoute
|
||||||
|
for _, namespace := range namespaces {
|
||||||
if !c.isWatchedNamespace(namespace) {
|
if !c.isWatchedNamespace(namespace) {
|
||||||
return nil, fmt.Errorf("failed to get TCPRoutes %s with labels selector %s: namespace is not within watched namespaces", namespace, selector)
|
log.WithoutContext().Warnf("Failed to get TCPRoutes with labels selector %s: %q is not within watched namespaces", selector, namespace)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpRoutes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().TCPRoutes().Lister().TCPRoutes(namespace).List(selector)
|
routes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().TCPRoutes().Lister().TCPRoutes(namespace).List(selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tcpRoutes) == 0 {
|
if len(routes) == 0 {
|
||||||
log.WithoutContext().Debugf("No TCPRoutes found in %q namespace with labels selector %s", namespace, selector)
|
log.WithoutContext().Debugf("No TCPRoutes found in %q namespace with labels selector %s", namespace, selector)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tcpRoutes = append(tcpRoutes, routes...)
|
||||||
|
}
|
||||||
return tcpRoutes, nil
|
return tcpRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientWrapper) GetTLSRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error) {
|
func (c *clientWrapper) GetTLSRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error) {
|
||||||
|
var tlsRoutes []*v1alpha1.TLSRoute
|
||||||
|
for _, namespace := range namespaces {
|
||||||
if !c.isWatchedNamespace(namespace) {
|
if !c.isWatchedNamespace(namespace) {
|
||||||
return nil, fmt.Errorf("failed to get TLSRoutes %s with labels selector %s: namespace is not within watched namespaces", namespace, selector)
|
log.WithoutContext().Warnf("Failed to get TLSRoutes with labels selector %s: %q is not within watched namespaces", selector, namespace)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsRoutes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().TLSRoutes().Lister().TLSRoutes(namespace).List(selector)
|
routes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().TLSRoutes().Lister().TLSRoutes(namespace).List(selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tlsRoutes) == 0 {
|
if len(routes) == 0 {
|
||||||
log.WithoutContext().Debugf("No TLSRoutes found in %q namespace with labels selector %s", namespace, selector)
|
log.WithoutContext().Debugf("No TLSRoutes found in %q namespace with labels selector %s", namespace, selector)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlsRoutes = append(tlsRoutes, routes...)
|
||||||
|
}
|
||||||
return tlsRoutes, nil
|
return tlsRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ type clientMock struct {
|
||||||
services []*corev1.Service
|
services []*corev1.Service
|
||||||
secrets []*corev1.Secret
|
secrets []*corev1.Secret
|
||||||
endpoints []*corev1.Endpoints
|
endpoints []*corev1.Endpoints
|
||||||
|
namespaces []*corev1.Namespace
|
||||||
|
|
||||||
apiServiceError error
|
apiServiceError error
|
||||||
apiSecretError error
|
apiSecretError error
|
||||||
|
@ -57,6 +58,8 @@ func newClientMock(paths ...string) clientMock {
|
||||||
c.services = append(c.services, o)
|
c.services = append(c.services, o)
|
||||||
case *corev1.Secret:
|
case *corev1.Secret:
|
||||||
c.secrets = append(c.secrets, o)
|
c.secrets = append(c.secrets, o)
|
||||||
|
case *corev1.Namespace:
|
||||||
|
c.namespaces = append(c.namespaces, o)
|
||||||
case *corev1.Endpoints:
|
case *corev1.Endpoints:
|
||||||
c.endpoints = append(c.endpoints, o)
|
c.endpoints = append(c.endpoints, o)
|
||||||
case *v1alpha1.GatewayClass:
|
case *v1alpha1.GatewayClass:
|
||||||
|
@ -131,36 +134,53 @@ func (c clientMock) GetGateways() []*v1alpha1.Gateway {
|
||||||
return c.gateways
|
return c.gateways
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c clientMock) GetHTTPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error) {
|
func inNamespace(m metav1.ObjectMeta, s string) bool {
|
||||||
var httpRoutes []*v1alpha1.HTTPRoute
|
return s == metav1.NamespaceAll || m.Namespace == s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c clientMock) GetNamespaces(selector labels.Selector) ([]string, error) {
|
||||||
|
var ns []string
|
||||||
|
for _, namespace := range c.namespaces {
|
||||||
|
if selector.Matches(labels.Set(namespace.Labels)) {
|
||||||
|
ns = append(ns, namespace.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ns, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c clientMock) GetHTTPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error) {
|
||||||
|
var httpRoutes []*v1alpha1.HTTPRoute
|
||||||
|
for _, namespace := range namespaces {
|
||||||
for _, httpRoute := range c.httpRoutes {
|
for _, httpRoute := range c.httpRoutes {
|
||||||
if httpRoute.Namespace == namespace && selector.Matches(labels.Set(httpRoute.Labels)) {
|
if inNamespace(httpRoute.ObjectMeta, namespace) && selector.Matches(labels.Set(httpRoute.Labels)) {
|
||||||
httpRoutes = append(httpRoutes, httpRoute)
|
httpRoutes = append(httpRoutes, httpRoute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return httpRoutes, nil
|
return httpRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c clientMock) GetTCPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error) {
|
func (c clientMock) GetTCPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error) {
|
||||||
var tcpRoutes []*v1alpha1.TCPRoute
|
var tcpRoutes []*v1alpha1.TCPRoute
|
||||||
|
for _, namespace := range namespaces {
|
||||||
for _, tcpRoute := range c.tcpRoutes {
|
for _, tcpRoute := range c.tcpRoutes {
|
||||||
if tcpRoute.Namespace == namespace && selector.Matches(labels.Set(tcpRoute.Labels)) {
|
if inNamespace(tcpRoute.ObjectMeta, namespace) && selector.Matches(labels.Set(tcpRoute.Labels)) {
|
||||||
tcpRoutes = append(tcpRoutes, tcpRoute)
|
tcpRoutes = append(tcpRoutes, tcpRoute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return tcpRoutes, nil
|
return tcpRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c clientMock) GetTLSRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error) {
|
func (c clientMock) GetTLSRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error) {
|
||||||
var tlsRoutes []*v1alpha1.TLSRoute
|
var tlsRoutes []*v1alpha1.TLSRoute
|
||||||
|
for _, namespace := range namespaces {
|
||||||
for _, tlsRoute := range c.tlsRoutes {
|
for _, tlsRoute := range c.tlsRoutes {
|
||||||
if tlsRoute.Namespace == namespace && selector.Matches(labels.Set(tlsRoute.Labels)) {
|
if inNamespace(tlsRoute.ObjectMeta, namespace) && selector.Matches(labels.Set(tlsRoute.Labels)) {
|
||||||
tlsRoutes = append(tlsRoutes, tlsRoute)
|
tlsRoutes = append(tlsRoutes, tlsRoute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return tlsRoutes, nil
|
return tlsRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +190,7 @@ func (c clientMock) GetService(namespace, name string) (*corev1.Service, bool, e
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, service := range c.services {
|
for _, service := range c.services {
|
||||||
if service.Namespace == namespace && service.Name == name {
|
if inNamespace(service.ObjectMeta, namespace) && service.Name == name {
|
||||||
return service, true, nil
|
return service, true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,7 +203,7 @@ func (c clientMock) GetEndpoints(namespace, name string) (*corev1.Endpoints, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, endpoints := range c.endpoints {
|
for _, endpoints := range c.endpoints {
|
||||||
if endpoints.Namespace == namespace && endpoints.Name == name {
|
if inNamespace(endpoints.ObjectMeta, namespace) && endpoints.Name == name {
|
||||||
return endpoints, true, nil
|
return endpoints, true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +217,7 @@ func (c clientMock) GetSecret(namespace, name string) (*corev1.Secret, bool, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, secret := range c.secrets {
|
for _, secret := range c.secrets {
|
||||||
if secret.Namespace == namespace && secret.Name == name {
|
if inNamespace(secret.ObjectMeta, namespace) && secret.Name == name {
|
||||||
return secret, true, nil
|
return secret, true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: HTTP
|
||||||
|
port: 80
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: All
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: foo
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: foo
|
||||||
|
spec:
|
||||||
|
hostnames:
|
||||||
|
- "foo.com"
|
||||||
|
rules:
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: Exact
|
||||||
|
value: /foo
|
||||||
|
forwardTo:
|
||||||
|
- serviceName: whoami
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: foo
|
||||||
|
spec:
|
||||||
|
hostnames:
|
||||||
|
- "bar.com"
|
||||||
|
rules:
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: Exact
|
||||||
|
value: /bar
|
||||||
|
forwardTo:
|
||||||
|
- serviceName: whoami-bar
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
|
@ -0,0 +1,68 @@
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: HTTP
|
||||||
|
port: 80
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: foo
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: foo
|
||||||
|
spec:
|
||||||
|
hostnames:
|
||||||
|
- "foo.com"
|
||||||
|
rules:
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: Exact
|
||||||
|
value: /foo
|
||||||
|
forwardTo:
|
||||||
|
- serviceName: whoami
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: foo
|
||||||
|
spec:
|
||||||
|
hostnames:
|
||||||
|
- "bar.com"
|
||||||
|
rules:
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: Exact
|
||||||
|
value: /bar
|
||||||
|
forwardTo:
|
||||||
|
- serviceName: whoami-bar
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
|
@ -0,0 +1,79 @@
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: bar
|
||||||
|
labels:
|
||||||
|
foo: bar
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: HTTP
|
||||||
|
port: 80
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Selector
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
foo: bar
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: foo
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: foo
|
||||||
|
spec:
|
||||||
|
hostnames:
|
||||||
|
- "foo.com"
|
||||||
|
rules:
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: Exact
|
||||||
|
value: /foo
|
||||||
|
forwardTo:
|
||||||
|
- serviceName: whoami
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: foo
|
||||||
|
spec:
|
||||||
|
hostnames:
|
||||||
|
- "bar.com"
|
||||||
|
rules:
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: Exact
|
||||||
|
value: /bar
|
||||||
|
forwardTo:
|
||||||
|
- serviceName: whoami-bar
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
|
@ -100,6 +100,7 @@ spec:
|
||||||
- serviceName: whoami
|
- serviceName: whoami
|
||||||
port: 80
|
port: 80
|
||||||
weight: 1
|
weight: 1
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: TCPRoute
|
kind: TCPRoute
|
||||||
apiVersion: networking.x-k8s.io/v1alpha1
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
|
|
@ -93,6 +93,7 @@ spec:
|
||||||
- serviceName: whoami
|
- serviceName: whoami
|
||||||
port: 80
|
port: 80
|
||||||
weight: 1
|
weight: 1
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: HTTPRoute
|
kind: HTTPRoute
|
||||||
apiVersion: networking.x-k8s.io/v1alpha1
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: supersecret
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||||
|
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: HTTP
|
||||||
|
port: 9080
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: All
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: http-app
|
||||||
|
- protocol: HTTPS
|
||||||
|
port: 9443
|
||||||
|
tls:
|
||||||
|
certificateRef:
|
||||||
|
kind: Secret
|
||||||
|
name: supersecret
|
||||||
|
group: core
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: All
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: http-app
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: All
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tcp-app
|
||||||
|
- protocol: TLS
|
||||||
|
port: 10000
|
||||||
|
hostname: tls.foo.example.com
|
||||||
|
tls:
|
||||||
|
certificateRef:
|
||||||
|
kind: Secret
|
||||||
|
name: supersecret
|
||||||
|
group: core
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: All
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tcp-app
|
||||||
|
- protocol: TLS
|
||||||
|
port: 11000
|
||||||
|
hostname: pass.tls.foo.example.com
|
||||||
|
tls:
|
||||||
|
mode: Passthrough
|
||||||
|
routes:
|
||||||
|
kind: TLSRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tls-app
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: http-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoami
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tcp-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: http-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoami-bar
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tcp-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
|
@ -0,0 +1,177 @@
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: supersecret
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||||
|
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: HTTP
|
||||||
|
port: 9080
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: http-app
|
||||||
|
- protocol: HTTPS
|
||||||
|
port: 9443
|
||||||
|
tls:
|
||||||
|
certificateRef:
|
||||||
|
kind: Secret
|
||||||
|
name: supersecret
|
||||||
|
group: core
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: http-app
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tcp-app
|
||||||
|
- protocol: TLS
|
||||||
|
port: 10000
|
||||||
|
hostname: tls.foo.example.com
|
||||||
|
tls:
|
||||||
|
certificateRef:
|
||||||
|
kind: Secret
|
||||||
|
name: supersecret
|
||||||
|
group: core
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tcp-app
|
||||||
|
- protocol: TLS
|
||||||
|
port: 11000
|
||||||
|
hostname: pass.tls.foo.example.com
|
||||||
|
tls:
|
||||||
|
mode: Passthrough
|
||||||
|
routes:
|
||||||
|
kind: TLSRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tls-app
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: http-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoami
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tcp-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: http-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoami-bar
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tcp-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
|
@ -0,0 +1,201 @@
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: bar
|
||||||
|
labels:
|
||||||
|
foo: bar
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: supersecret
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||||
|
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: HTTP
|
||||||
|
port: 9080
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Selector
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
foo: bar
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: http-app
|
||||||
|
- protocol: HTTPS
|
||||||
|
port: 9443
|
||||||
|
tls:
|
||||||
|
certificateRef:
|
||||||
|
kind: Secret
|
||||||
|
name: supersecret
|
||||||
|
group: core
|
||||||
|
routes:
|
||||||
|
kind: HTTPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Selector
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
foo: bar
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: http-app
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Selector
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
foo: bar
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tcp-app
|
||||||
|
- protocol: TLS
|
||||||
|
port: 10000
|
||||||
|
hostname: tls.foo.example.com
|
||||||
|
tls:
|
||||||
|
certificateRef:
|
||||||
|
kind: Secret
|
||||||
|
name: supersecret
|
||||||
|
group: core
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Selector
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
foo: bar
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tcp-app
|
||||||
|
- protocol: TLS
|
||||||
|
port: 11000
|
||||||
|
hostname: pass.tls.foo.example.com
|
||||||
|
tls:
|
||||||
|
mode: Passthrough
|
||||||
|
routes:
|
||||||
|
kind: TLSRoute
|
||||||
|
namespaces:
|
||||||
|
from: Selector
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
foo: bar
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tls-app
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: http-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoami
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tcp-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: HTTPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: http-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: http-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoami-bar
|
||||||
|
port: 80
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tcp-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
|
@ -33,6 +33,42 @@ subsets:
|
||||||
- name: web2
|
- name: web2
|
||||||
port: 8000
|
port: 8000
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: whoami-bar
|
||||||
|
namespace: bar
|
||||||
|
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- name: web2
|
||||||
|
port: 8000
|
||||||
|
targetPort: web2
|
||||||
|
- name: web
|
||||||
|
port: 80
|
||||||
|
targetPort: web
|
||||||
|
selector:
|
||||||
|
app: containous
|
||||||
|
task: whoami
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Endpoints
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: whoami-bar
|
||||||
|
namespace: bar
|
||||||
|
|
||||||
|
subsets:
|
||||||
|
- addresses:
|
||||||
|
- ip: 10.10.0.11
|
||||||
|
- ip: 10.10.0.12
|
||||||
|
ports:
|
||||||
|
- name: web
|
||||||
|
port: 80
|
||||||
|
- name: web2
|
||||||
|
port: 8000
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -164,7 +200,6 @@ spec:
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
port: 443
|
port: 443
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: Endpoints
|
kind: Endpoints
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -199,3 +234,38 @@ spec:
|
||||||
- protocol: TCP
|
- protocol: TCP
|
||||||
port: 10000
|
port: 10000
|
||||||
name: tcp-2
|
name: tcp-2
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Endpoints
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: whoamitcp-bar
|
||||||
|
namespace: bar
|
||||||
|
|
||||||
|
subsets:
|
||||||
|
- addresses:
|
||||||
|
- ip: 10.10.0.13
|
||||||
|
- ip: 10.10.0.14
|
||||||
|
ports:
|
||||||
|
- name: tcp-1
|
||||||
|
protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
- name: tcp-2
|
||||||
|
protocol: TCP
|
||||||
|
port: 10000
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: whoamitcp-bar
|
||||||
|
namespace: bar
|
||||||
|
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
name: tcp-1
|
||||||
|
- protocol: TCP
|
||||||
|
port: 10000
|
||||||
|
name: tcp-2
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-tcp-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: All
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: whoamitcp
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: whoamitcp
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: whoamitcp
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
|
@ -0,0 +1,57 @@
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-tcp-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: whoamitcp
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: whoamitcp
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: whoamitcp
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
|
@ -0,0 +1,68 @@
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: bar
|
||||||
|
labels:
|
||||||
|
foo: bar
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-tcp-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
routes:
|
||||||
|
kind: TCPRoute
|
||||||
|
namespaces:
|
||||||
|
from: Selector
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
foo: bar
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: whoamitcp
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: whoamitcp
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TCPRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tcp-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: whoamitcp
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
|
@ -50,7 +50,6 @@ spec:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: label-tls-app-1
|
app: label-tls-app-1
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: TCPRoute
|
kind: TCPRoute
|
||||||
apiVersion: networking.x-k8s.io/v1alpha1
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: TLS
|
||||||
|
port: 9001
|
||||||
|
hostname: foo.example.com
|
||||||
|
tls:
|
||||||
|
mode: Passthrough
|
||||||
|
routes:
|
||||||
|
kind: TLSRoute
|
||||||
|
namespaces:
|
||||||
|
from: All
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tls-app
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
matches:
|
||||||
|
- snis:
|
||||||
|
- foo.default
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
matches:
|
||||||
|
- snis:
|
||||||
|
- foo.bar
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: TLS
|
||||||
|
port: 9001
|
||||||
|
hostname: foo.example.com
|
||||||
|
tls:
|
||||||
|
mode: Passthrough
|
||||||
|
routes:
|
||||||
|
kind: TLSRoute
|
||||||
|
namespaces:
|
||||||
|
from: Same
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tls-app
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
matches:
|
||||||
|
- snis:
|
||||||
|
- foo.default
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
matches:
|
||||||
|
- snis:
|
||||||
|
- foo.bar
|
|
@ -0,0 +1,76 @@
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: bar
|
||||||
|
labels:
|
||||||
|
foo: bar
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: GatewayClass
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway-class
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/gateway-controller
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Gateway
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: my-gateway
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
gatewayClassName: my-gateway-class
|
||||||
|
listeners: # Use GatewayClass defaults for listener definition.
|
||||||
|
- protocol: TLS
|
||||||
|
port: 9001
|
||||||
|
hostname: foo.example.com
|
||||||
|
tls:
|
||||||
|
mode: Passthrough
|
||||||
|
routes:
|
||||||
|
kind: TLSRoute
|
||||||
|
namespaces:
|
||||||
|
from: Selector
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
foo: bar
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: tls-app
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-default
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
matches:
|
||||||
|
- snis:
|
||||||
|
- foo.default
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: TLSRoute
|
||||||
|
apiVersion: networking.x-k8s.io/v1alpha1
|
||||||
|
metadata:
|
||||||
|
name: tls-app-bar
|
||||||
|
namespace: bar
|
||||||
|
labels:
|
||||||
|
app: tls-app
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- forwardTo:
|
||||||
|
- serviceName: whoamitcp-bar
|
||||||
|
port: 9000
|
||||||
|
weight: 1
|
||||||
|
matches:
|
||||||
|
- snis:
|
||||||
|
- foo.bar
|
|
@ -492,13 +492,23 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway *
|
||||||
}
|
}
|
||||||
|
|
||||||
func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha1.Listener, gateway *v1alpha1.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition {
|
func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha1.Listener, gateway *v1alpha1.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition {
|
||||||
// TODO: support RouteNamespaces
|
|
||||||
selector := labels.Everything()
|
selector := labels.Everything()
|
||||||
|
|
||||||
if listener.Routes.Selector != nil {
|
if listener.Routes.Selector != nil {
|
||||||
selector = labels.SelectorFromSet(listener.Routes.Selector.MatchLabels)
|
var err error
|
||||||
|
selector, err = metav1.LabelSelectorAsSelector(listener.Routes.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return []metav1.Condition{{
|
||||||
|
Type: string(v1alpha1.ListenerConditionResolvedRefs),
|
||||||
|
Status: metav1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
|
Message: fmt.Sprintf("Invalid routes selector: %v", err),
|
||||||
|
}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
httpRoutes, err := client.GetHTTPRoutes(gateway.Namespace, selector)
|
namespaces, err := getRouteBindingSelectorNamespace(client, gateway.Namespace, listener.Routes.Namespaces)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
||||||
return []metav1.Condition{{
|
return []metav1.Condition{{
|
||||||
|
@ -506,7 +516,19 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha
|
||||||
Status: metav1.ConditionFalse,
|
Status: metav1.ConditionFalse,
|
||||||
LastTransitionTime: metav1.Now(),
|
LastTransitionTime: metav1.Now(),
|
||||||
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
Message: fmt.Sprintf("Cannot fetch %ss for namespace %q and matchLabels %v", listener.Routes.Kind, gateway.Namespace, listener.Routes.Selector.MatchLabels),
|
Message: fmt.Sprintf("Invalid route namespaces selector: %v", err),
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRoutes, err := client.GetHTTPRoutes(namespaces, selector)
|
||||||
|
if err != nil {
|
||||||
|
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
||||||
|
return []metav1.Condition{{
|
||||||
|
Type: string(v1alpha1.ListenerConditionResolvedRefs),
|
||||||
|
Status: metav1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
|
Message: fmt.Sprintf("Cannot fetch %ss: %v", listener.Routes.Kind, err),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +599,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha
|
||||||
if len(routeRule.ForwardTo) == 1 && isInternalService(routeRule.ForwardTo[0]) {
|
if len(routeRule.ForwardTo) == 1 && isInternalService(routeRule.ForwardTo[0]) {
|
||||||
router.Service = routeRule.ForwardTo[0].BackendRef.Name
|
router.Service = routeRule.ForwardTo[0].BackendRef.Name
|
||||||
} else {
|
} else {
|
||||||
wrrService, subServices, err := loadServices(client, gateway.Namespace, routeRule.ForwardTo)
|
wrrService, subServices, err := loadServices(client, httpRoute.Namespace, routeRule.ForwardTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// update "ResolvedRefs" status true with "DroppedRoutes" reason
|
// update "ResolvedRefs" status true with "DroppedRoutes" reason
|
||||||
conditions = append(conditions, metav1.Condition{
|
conditions = append(conditions, metav1.Condition{
|
||||||
|
@ -585,7 +607,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha
|
||||||
Status: metav1.ConditionFalse,
|
Status: metav1.ConditionFalse,
|
||||||
LastTransitionTime: metav1.Now(),
|
LastTransitionTime: metav1.Now(),
|
||||||
Reason: string(v1alpha1.ListenerReasonDegradedRoutes),
|
Reason: string(v1alpha1.ListenerReasonDegradedRoutes),
|
||||||
Message: fmt.Sprintf("Cannot load service from %s %s/%s : %v", listener.Routes.Kind, gateway.Namespace, httpRoute.Name, err),
|
Message: fmt.Sprintf("Cannot load service from %s %s/%s: %v", listener.Routes.Kind, httpRoute.Namespace, httpRoute.Name, err),
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO update the RouteStatus condition / deduplicate conditions on listener
|
// TODO update the RouteStatus condition / deduplicate conditions on listener
|
||||||
|
@ -611,13 +633,23 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha
|
||||||
}
|
}
|
||||||
|
|
||||||
func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.Listener, gateway *v1alpha1.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition {
|
func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.Listener, gateway *v1alpha1.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition {
|
||||||
// TODO: support RouteNamespaces
|
|
||||||
selector := labels.Everything()
|
selector := labels.Everything()
|
||||||
|
|
||||||
if listener.Routes.Selector != nil {
|
if listener.Routes.Selector != nil {
|
||||||
selector = labels.SelectorFromSet(listener.Routes.Selector.MatchLabels)
|
var err error
|
||||||
|
selector, err = metav1.LabelSelectorAsSelector(listener.Routes.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return []metav1.Condition{{
|
||||||
|
Type: string(v1alpha1.ListenerConditionResolvedRefs),
|
||||||
|
Status: metav1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
|
Message: fmt.Sprintf("Invalid routes selector: %v", err),
|
||||||
|
}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpRoutes, err := client.GetTCPRoutes(gateway.Namespace, selector)
|
namespaces, err := getRouteBindingSelectorNamespace(client, gateway.Namespace, listener.Routes.Namespaces)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
||||||
return []metav1.Condition{{
|
return []metav1.Condition{{
|
||||||
|
@ -625,7 +657,19 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.
|
||||||
Status: metav1.ConditionFalse,
|
Status: metav1.ConditionFalse,
|
||||||
LastTransitionTime: metav1.Now(),
|
LastTransitionTime: metav1.Now(),
|
||||||
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
Message: fmt.Sprintf("Cannot fetch %ss for namespace %q and matchLabels %v", listener.Routes.Kind, gateway.Namespace, listener.Routes.Selector.MatchLabels),
|
Message: fmt.Sprintf("Invalid route namespaces selector: %v", err),
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
tcpRoutes, err := client.GetTCPRoutes(namespaces, selector)
|
||||||
|
if err != nil {
|
||||||
|
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
||||||
|
return []metav1.Condition{{
|
||||||
|
Type: string(v1alpha1.ListenerConditionResolvedRefs),
|
||||||
|
Status: metav1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
|
Message: fmt.Sprintf("Cannot fetch %ss: %v", listener.Routes.Kind, err),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,7 +725,7 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
wrrService, subServices, err := loadTCPServices(client, gateway.Namespace, routeRule.ForwardTo)
|
wrrService, subServices, err := loadTCPServices(client, tcpRoute.Namespace, routeRule.ForwardTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// update "ResolvedRefs" status true with "DroppedRoutes" reason
|
// update "ResolvedRefs" status true with "DroppedRoutes" reason
|
||||||
conditions = append(conditions, metav1.Condition{
|
conditions = append(conditions, metav1.Condition{
|
||||||
|
@ -689,7 +733,7 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.
|
||||||
Status: metav1.ConditionFalse,
|
Status: metav1.ConditionFalse,
|
||||||
LastTransitionTime: metav1.Now(),
|
LastTransitionTime: metav1.Now(),
|
||||||
Reason: string(v1alpha1.ListenerReasonDegradedRoutes),
|
Reason: string(v1alpha1.ListenerReasonDegradedRoutes),
|
||||||
Message: fmt.Sprintf("Cannot load service from %s %s/%s : %v", listener.Routes.Kind, gateway.Namespace, tcpRoute.Name, err),
|
Message: fmt.Sprintf("Cannot load service from %s %s/%s: %v", listener.Routes.Kind, tcpRoute.Namespace, tcpRoute.Name, err),
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO update the RouteStatus condition / deduplicate conditions on listener
|
// TODO update the RouteStatus condition / deduplicate conditions on listener
|
||||||
|
@ -714,13 +758,23 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.
|
||||||
}
|
}
|
||||||
|
|
||||||
func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.Listener, gateway *v1alpha1.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition {
|
func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.Listener, gateway *v1alpha1.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition {
|
||||||
// TODO: support RouteNamespaces
|
|
||||||
selector := labels.Everything()
|
selector := labels.Everything()
|
||||||
|
|
||||||
if listener.Routes.Selector != nil {
|
if listener.Routes.Selector != nil {
|
||||||
selector = labels.SelectorFromSet(listener.Routes.Selector.MatchLabels)
|
var err error
|
||||||
|
selector, err = metav1.LabelSelectorAsSelector(listener.Routes.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return []metav1.Condition{{
|
||||||
|
Type: string(v1alpha1.ListenerConditionResolvedRefs),
|
||||||
|
Status: metav1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
|
Message: fmt.Sprintf("Invalid routes selector: %v", err),
|
||||||
|
}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsRoutes, err := client.GetTLSRoutes(gateway.Namespace, selector)
|
namespaces, err := getRouteBindingSelectorNamespace(client, gateway.Namespace, listener.Routes.Namespaces)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
||||||
return []metav1.Condition{{
|
return []metav1.Condition{{
|
||||||
|
@ -728,7 +782,19 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.
|
||||||
Status: metav1.ConditionFalse,
|
Status: metav1.ConditionFalse,
|
||||||
LastTransitionTime: metav1.Now(),
|
LastTransitionTime: metav1.Now(),
|
||||||
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
Message: fmt.Sprintf("Cannot fetch %ss for namespace %q and matchLabels %v", listener.Routes.Kind, gateway.Namespace, listener.Routes.Selector.MatchLabels),
|
Message: fmt.Sprintf("Invalid route namespaces selector: %v", err),
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsRoutes, err := client.GetTLSRoutes(namespaces, selector)
|
||||||
|
if err != nil {
|
||||||
|
// update "ResolvedRefs" status true with "InvalidRoutesRef" reason
|
||||||
|
return []metav1.Condition{{
|
||||||
|
Type: string(v1alpha1.ListenerConditionResolvedRefs),
|
||||||
|
Status: metav1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: string(v1alpha1.ListenerReasonInvalidRoutesRef),
|
||||||
|
Message: fmt.Sprintf("Cannot fetch %ss: %v", listener.Routes.Kind, err),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,7 +852,7 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
wrrService, subServices, err := loadTCPServices(client, gateway.Namespace, routeRule.ForwardTo)
|
wrrService, subServices, err := loadTCPServices(client, tlsRoute.Namespace, routeRule.ForwardTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// update "ResolvedRefs" status true with "DroppedRoutes" reason
|
// update "ResolvedRefs" status true with "DroppedRoutes" reason
|
||||||
conditions = append(conditions, metav1.Condition{
|
conditions = append(conditions, metav1.Condition{
|
||||||
|
@ -794,7 +860,7 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.
|
||||||
Status: metav1.ConditionFalse,
|
Status: metav1.ConditionFalse,
|
||||||
LastTransitionTime: metav1.Now(),
|
LastTransitionTime: metav1.Now(),
|
||||||
Reason: string(v1alpha1.ListenerReasonDegradedRoutes),
|
Reason: string(v1alpha1.ListenerReasonDegradedRoutes),
|
||||||
Message: fmt.Sprintf("Cannot load service from %s %s/%s : %v", listener.Routes.Kind, gateway.Namespace, tlsRoute.Name, err),
|
Message: fmt.Sprintf("Cannot load service from %s %s/%s: %v", listener.Routes.Kind, tlsRoute.Namespace, tlsRoute.Name, err),
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO update the RouteStatus condition / deduplicate conditions on listener
|
// TODO update the RouteStatus condition / deduplicate conditions on listener
|
||||||
|
@ -818,6 +884,30 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha1.
|
||||||
return conditions
|
return conditions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRouteBindingSelectorNamespace(client Client, gatewayNamespace string, routeNamespaces *v1alpha1.RouteNamespaces) ([]string, error) {
|
||||||
|
if routeNamespaces == nil || routeNamespaces.From == nil {
|
||||||
|
return []string{gatewayNamespace}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch *routeNamespaces.From {
|
||||||
|
case v1alpha1.RouteSelectAll:
|
||||||
|
return []string{metav1.NamespaceAll}, nil
|
||||||
|
|
||||||
|
case v1alpha1.RouteSelectSame:
|
||||||
|
return []string{gatewayNamespace}, nil
|
||||||
|
|
||||||
|
case v1alpha1.RouteSelectSelector:
|
||||||
|
selector, err := metav1.LabelSelectorAsSelector(routeNamespaces.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("malformed selector: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.GetNamespaces(selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("unsupported RouteSelectType: %q", *routeNamespaces.From)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha1.ListenerStatus) (v1alpha1.GatewayStatus, error) {
|
func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha1.ListenerStatus) (v1alpha1.GatewayStatus, error) {
|
||||||
// As Status.Addresses are not implemented yet, we initialize an empty array to follow the API expectations.
|
// As Status.Addresses are not implemented yet, we initialize an empty array to follow the API expectations.
|
||||||
gatewayStatus := v1alpha1.GatewayStatus{
|
gatewayStatus := v1alpha1.GatewayStatus{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
// MustParseYaml parses a YAML to objects.
|
// MustParseYaml parses a YAML to objects.
|
||||||
func MustParseYaml(content []byte) []runtime.Object {
|
func MustParseYaml(content []byte) []runtime.Object {
|
||||||
acceptedK8sTypes := regexp.MustCompile(`^(Deployment|Endpoints|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|GatewayClass|Gateway|HTTPRoute|TCPRoute|TLSRoute)$`)
|
acceptedK8sTypes := regexp.MustCompile(`^(Namespace|Deployment|Endpoints|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|GatewayClass|Gateway|HTTPRoute|TCPRoute|TLSRoute)$`)
|
||||||
|
|
||||||
files := strings.Split(string(content), "---")
|
files := strings.Split(string(content), "---")
|
||||||
retVal := make([]runtime.Object, 0, len(files))
|
retVal := make([]runtime.Object, 0, len(files))
|
||||||
|
|
Loading…
Reference in a new issue