Add scheme to IngressRoute.

This commit is contained in:
Ludovic Fernandez 2019-07-05 17:24:04 +02:00 committed by Traefiker Bot
parent 39aae4167e
commit c39aa5e857
38 changed files with 220 additions and 120 deletions

View file

@ -97,6 +97,12 @@ spec:
middlewares: middlewares:
- name: stripprefix - name: stripprefix
- name: addprefix - name: addprefix
- match: PathPrefix(`/misc`)
services:
- name: s3
port: 8443
# scheme allow to override the scheme for the service. (ex: https or h2c)
scheme: https
# use an empty tls object for TLS with Let's Encrypt # use an empty tls object for TLS with Let's Encrypt
tls: tls:
secretName: supersecret secretName: supersecret

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -13,7 +13,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test2.crd name: test2.route
namespace: default namespace: default
spec: spec:

View file

@ -1,24 +1,24 @@
{ {
"routers": { "routers": {
"default/test.crd-6b204d94623b3df4370c@kubernetescrd": { "default/test.route-6b204d94623b3df4370c@kubernetescrd": {
"entryPoints": [ "entryPoints": [
"web" "web"
], ],
"service": "default/test.crd-6b204d94623b3df4370c", "service": "default/test.route-6b204d94623b3df4370c",
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/bar`)", "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/bar`)",
"priority": 12, "priority": 12,
"tls": { "tls": {
"options": "default/mytlsoption" "options": "default/mytlsoption"
} }
}, },
"default/test2.crd-23c7f4c450289ee29016@kubernetescrd": { "default/test2.route-23c7f4c450289ee29016@kubernetescrd": {
"entryPoints": [ "entryPoints": [
"web" "web"
], ],
"middlewares": [ "middlewares": [
"default/stripprefix" "default/stripprefix"
], ],
"service": "default/test2.crd-23c7f4c450289ee29016", "service": "default/test2.route-23c7f4c450289ee29016",
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/tobestripped`)" "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/tobestripped`)"
} }
}, },
@ -30,12 +30,12 @@
] ]
}, },
"usedBy": [ "usedBy": [
"default/test2.crd-23c7f4c450289ee29016@kubernetescrd" "default/test2.route-23c7f4c450289ee29016@kubernetescrd"
] ]
} }
}, },
"services": { "services": {
"default/test.crd-6b204d94623b3df4370c@kubernetescrd": { "default/test.route-6b204d94623b3df4370c@kubernetescrd": {
"loadBalancer": { "loadBalancer": {
"servers": [ "servers": [
{ {
@ -48,14 +48,14 @@
"passHostHeader": true "passHostHeader": true
}, },
"usedBy": [ "usedBy": [
"default/test.crd-6b204d94623b3df4370c@kubernetescrd" "default/test.route-6b204d94623b3df4370c@kubernetescrd"
], ],
"serverStatus": { "serverStatus": {
"http://10.42.0.3:80": "UP", "http://10.42.0.3:80": "UP",
"http://10.42.0.5:80": "UP" "http://10.42.0.5:80": "UP"
} }
}, },
"default/test2.crd-23c7f4c450289ee29016@kubernetescrd": { "default/test2.route-23c7f4c450289ee29016@kubernetescrd": {
"loadBalancer": { "loadBalancer": {
"servers": [ "servers": [
{ {
@ -68,7 +68,7 @@
"passHostHeader": true "passHostHeader": true
}, },
"usedBy": [ "usedBy": [
"default/test2.crd-23c7f4c450289ee29016@kubernetescrd" "default/test2.route-23c7f4c450289ee29016@kubernetescrd"
], ],
"serverStatus": { "serverStatus": {
"http://10.42.0.3:80": "UP", "http://10.42.0.3:80": "UP",

View file

@ -86,3 +86,34 @@ subsets:
ports: ports:
- name: web-secure - name: web-secure
port: 443 port: 443
---
apiVersion: v1
kind: Service
metadata:
name: whoami3
namespace: default
spec:
ports:
- name: web-secure2
port: 8443
scheme: https
selector:
app: containous
task: whoami3
---
kind: Endpoints
apiVersion: v1
metadata:
name: whoami3
namespace: default
subsets:
- addresses:
- ip: 10.10.0.7
- ip: 10.10.0.8
ports:
- name: web-secure2
port: 8443

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -52,7 +52,7 @@ data:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -12,7 +12,7 @@ data:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -51,7 +51,7 @@ data:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -51,7 +51,7 @@ data:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -12,7 +12,7 @@ data:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -12,7 +12,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -12,7 +12,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP kind: IngressRouteTCP
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -41,7 +41,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -0,0 +1,18 @@
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`foo.com`) && PathPrefix(`/bar`)
kind: Rule
priority: 12
services:
- name: whoami3
port: 8443
scheme: https

View file

@ -24,7 +24,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test2.crd name: test2.route
namespace: default namespace: default
spec: spec:

View file

@ -24,7 +24,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test2.crd name: test2.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -12,7 +12,7 @@ data:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -40,7 +40,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -40,7 +40,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -11,7 +11,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -11,7 +11,7 @@ spec:
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -1,7 +1,7 @@
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: test.crd name: test.route
namespace: default namespace: default
spec: spec:

View file

@ -278,8 +278,15 @@ func loadServers(client Client, namespace string, svc v1alpha1.Service) ([]confi
} }
protocol := "http" protocol := "http"
if port == 443 || strings.HasPrefix(portSpec.Name, "https") { switch svc.Scheme {
protocol = "https" case "http", "https", "h2c":
protocol = svc.Scheme
case "":
if port == 443 || strings.HasPrefix(portSpec.Name, "https") {
protocol = "https"
}
default:
return nil, fmt.Errorf("invalid scheme %q specified", svc.Scheme)
} }
for _, addr := range subset.Addresses { for _, addr := range subset.Addresses {

View file

@ -45,14 +45,14 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -77,19 +77,19 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
expected: &config.Configuration{ expected: &config.Configuration{
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
}, },
"default/test.crd-f44ce589164e656d231c": { "default/test.route-f44ce589164e656d231c": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-f44ce589164e656d231c", Service: "default/test.route-f44ce589164e656d231c",
Rule: "HostSNI(`bar.com`)", Rule: "HostSNI(`bar.com`)",
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -103,7 +103,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
}, },
}, },
"default/test.crd-f44ce589164e656d231c": { "default/test.route-f44ce589164e656d231c": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -133,14 +133,14 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
expected: &config.Configuration{ expected: &config.Configuration{
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -236,15 +236,15 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
TLS: &config.RouterTCPTLSConfig{}, TLS: &config.RouterTCPTLSConfig{},
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -273,9 +273,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
expected: &config.Configuration{ expected: &config.Configuration{
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
TLS: &config.RouterTCPTLSConfig{ TLS: &config.RouterTCPTLSConfig{
Passthrough: true, Passthrough: true,
@ -283,7 +283,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -332,9 +332,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
TLS: &config.RouterTCPTLSConfig{ TLS: &config.RouterTCPTLSConfig{
Options: "default/foo", Options: "default/foo",
@ -342,7 +342,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -390,9 +390,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
TLS: &config.RouterTCPTLSConfig{ TLS: &config.RouterTCPTLSConfig{
Options: "myns/foo", Options: "myns/foo",
@ -400,7 +400,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -447,9 +447,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
TLS: &config.RouterTCPTLSConfig{ TLS: &config.RouterTCPTLSConfig{
Options: "default/foo", Options: "default/foo",
@ -457,7 +457,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -493,9 +493,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
TLS: &config.RouterTCPTLSConfig{ TLS: &config.RouterTCPTLSConfig{
Options: "default/unknown", Options: "default/unknown",
@ -503,7 +503,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -539,9 +539,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
TLS: &config.RouterTCPTLSConfig{ TLS: &config.RouterTCPTLSConfig{
Options: "unknown/foo", Options: "unknown/foo",
@ -549,7 +549,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -578,15 +578,15 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
expected: &config.Configuration{ expected: &config.Configuration{
TCP: &config.TCPConfiguration{ TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{ Routers: map[string]*config.TCPRouter{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-fdd3e9338e47a45efefc", Service: "default/test.route-fdd3e9338e47a45efefc",
Rule: "HostSNI(`foo.com`)", Rule: "HostSNI(`foo.com`)",
TLS: &config.RouterTCPTLSConfig{}, TLS: &config.RouterTCPTLSConfig{},
}, },
}, },
Services: map[string]*config.TCPService{ Services: map[string]*config.TCPService{
"default/test.crd-fdd3e9338e47a45efefc": { "default/test.route-fdd3e9338e47a45efefc": {
LoadBalancer: &config.TCPLoadBalancerService{ LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{ Servers: []config.TCPServer{
{ {
@ -661,16 +661,16 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
}, },
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -698,9 +698,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test2.crd-23c7f4c450289ee29016": { "default/test2.route-23c7f4c450289ee29016": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test2.crd-23c7f4c450289ee29016", Service: "default/test2.route-23c7f4c450289ee29016",
Rule: "Host(`foo.com`) && PathPrefix(`/tobestripped`)", Rule: "Host(`foo.com`) && PathPrefix(`/tobestripped`)",
Priority: 12, Priority: 12,
Middlewares: []string{"default/stripprefix", "foo/addprefix"}, Middlewares: []string{"default/stripprefix", "foo/addprefix"},
@ -719,7 +719,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
}, },
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test2.crd-23c7f4c450289ee29016": { "default/test2.route-23c7f4c450289ee29016": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -748,9 +748,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test2.crd-23c7f4c450289ee29016": { "default/test2.route-23c7f4c450289ee29016": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test2.crd-23c7f4c450289ee29016", Service: "default/test2.route-23c7f4c450289ee29016",
Rule: "Host(`foo.com`) && PathPrefix(`/tobestripped`)", Rule: "Host(`foo.com`) && PathPrefix(`/tobestripped`)",
Priority: 12, Priority: 12,
Middlewares: []string{"default/stripprefix", "foo/addprefix", "basicauth@file", "redirect@file"}, Middlewares: []string{"default/stripprefix", "foo/addprefix", "basicauth@file", "redirect@file"},
@ -769,7 +769,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
}, },
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test2.crd-23c7f4c450289ee29016": { "default/test2.route-23c7f4c450289ee29016": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -796,22 +796,22 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Priority: 14, Priority: 14,
}, },
"default/test.crd-77c62dfe9517144aeeaa": { "default/test.route-77c62dfe9517144aeeaa": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-77c62dfe9517144aeeaa", Service: "default/test.route-77c62dfe9517144aeeaa",
Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", Rule: "Host(`foo.com`) && PathPrefix(`/foo`)",
Priority: 12, Priority: 12,
}, },
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -824,7 +824,7 @@ func TestLoadIngressRoutes(t *testing.T) {
PassHostHeader: true, PassHostHeader: true,
}, },
}, },
"default/test.crd-77c62dfe9517144aeeaa": { "default/test.route-77c62dfe9517144aeeaa": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -853,16 +853,16 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-77c62dfe9517144aeeaa": { "default/test.route-77c62dfe9517144aeeaa": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-77c62dfe9517144aeeaa", Service: "default/test.route-77c62dfe9517144aeeaa",
Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", Rule: "Host(`foo.com`) && PathPrefix(`/foo`)",
Priority: 12, Priority: 12,
}, },
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-77c62dfe9517144aeeaa": { "default/test.route-77c62dfe9517144aeeaa": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -970,9 +970,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
TLS: &config.RouterTLSConfig{}, TLS: &config.RouterTLSConfig{},
@ -980,7 +980,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -1026,9 +1026,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
TLS: &config.RouterTLSConfig{ TLS: &config.RouterTLSConfig{
@ -1038,7 +1038,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -1084,9 +1084,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
TLS: &config.RouterTLSConfig{ TLS: &config.RouterTLSConfig{
@ -1096,7 +1096,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -1141,9 +1141,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
TLS: &config.RouterTLSConfig{ TLS: &config.RouterTLSConfig{
@ -1153,7 +1153,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -1187,9 +1187,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
TLS: &config.RouterTLSConfig{ TLS: &config.RouterTLSConfig{
@ -1199,7 +1199,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -1233,9 +1233,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
TLS: &config.RouterTLSConfig{ TLS: &config.RouterTLSConfig{
@ -1245,7 +1245,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -1273,9 +1273,9 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"}, EntryPoints: []string{"web"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
TLS: &config.RouterTLSConfig{}, TLS: &config.RouterTLSConfig{},
@ -1283,7 +1283,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -1311,16 +1311,16 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
HTTP: &config.HTTPConfiguration{ HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{ Routers: map[string]*config.Router{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"foo"}, EntryPoints: []string{"foo"},
Service: "default/test.crd-6b204d94623b3df4370c", Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12, Priority: 12,
}, },
}, },
Middlewares: map[string]*config.Middleware{}, Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{ Services: map[string]*config.Service{
"default/test.crd-6b204d94623b3df4370c": { "default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{ LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{ Servers: []config.Server{
{ {
@ -1337,6 +1337,43 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
}, },
}, },
{
desc: "Simple Ingress Route, explicit https scheme",
paths: []string{"services.yml", "with_https_scheme.yml"},
expected: &config.Configuration{
TLS: &config.TLSConfiguration{},
TCP: &config.TCPConfiguration{
Routers: map[string]*config.TCPRouter{},
Services: map[string]*config.TCPService{},
},
HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"default/test.route-6b204d94623b3df4370c": {
EntryPoints: []string{"foo"},
Service: "default/test.route-6b204d94623b3df4370c",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12,
},
},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
"default/test.route-6b204d94623b3df4370c": {
LoadBalancer: &config.LoadBalancerService{
Servers: []config.Server{
{
URL: "https://10.10.0.7:8443",
},
{
URL: "https://10.10.0.8:8443",
},
},
PassHostHeader: true,
},
},
},
},
},
},
{ {
desc: "port selected by name (TODO)", desc: "port selected by name (TODO)",
}, },

View file

@ -45,6 +45,7 @@ type TLSOptionRef struct {
type Service struct { type Service struct {
Name string `json:"name"` Name string `json:"name"`
Port int32 `json:"port"` Port int32 `json:"port"`
Scheme string `json:"scheme,omitempty"`
HealthCheck *HealthCheck `json:"healthCheck,omitempty"` HealthCheck *HealthCheck `json:"healthCheck,omitempty"`
Strategy string `json:"strategy,omitempty"` Strategy string `json:"strategy,omitempty"`
} }