diff --git a/docs/content/getting-started/configuration-overview.md b/docs/content/getting-started/configuration-overview.md index 864b5dc2c..2a8861488 100644 --- a/docs/content/getting-started/configuration-overview.md +++ b/docs/content/getting-started/configuration-overview.md @@ -49,7 +49,12 @@ Once positioned, this option sets (and resets) all the default values of the sub ### Configuration File -At startup, Traefik searches for a file named `traefik.toml` in `/etc/traefik/`, `$XDG_CONFIG_HOME/`, `$HOME/.config/`, and `.` (_the working directory_). +At startup, Traefik searches for a file named `traefik.toml` (or `traefik.yml` or `traefik.yaml`) in: + +- `/etc/traefik/` +- `$XDG_CONFIG_HOME/` +- `$HOME/.config/` +- `.` (_the working directory_). You can override this using the `configFile` argument. diff --git a/docs/content/providers/file.md b/docs/content/providers/file.md index 3740f5ba6..8c2033568 100644 --- a/docs/content/providers/file.md +++ b/docs/content/providers/file.md @@ -3,10 +3,10 @@ Good Old Configuration File {: .subtitle } -The file provider lets you define the [dynamic configuration](./overview.md) in a `toml` file. +The file provider lets you define the [dynamic configuration](./overview.md) in a TOML or YAML file. You can write these configuration elements: -* At the end of the main Traefik configuration file (by default: `traefik.toml`). +* At the end of the main Traefik configuration file (by default: `traefik.toml`/`traefik.yml`/`traefik.yaml`). * In [a dedicated file](#filename) * In [several dedicated files](#directory) @@ -20,10 +20,20 @@ You can write these configuration elements: ??? example "Declaring Routers, Middlewares & Services" - ``` toml - # Enabling the file provider - [providers.file] + Enabling the file provider: + ```toml tab="TOML" + [providers.file] + ``` + + ```yaml tab="YAML" + providers: + file: {} + ``` + + Declaring Routers, Middlewares & Services: + + ```toml tab="TOML" [http] # Add the router [http.routers] @@ -49,6 +59,32 @@ You can write these configuration elements: [[http.services.service-foo.LoadBalancer.Servers]] url = "http://bar/" ``` + + ```yaml tab="YAML" + http: + routers: + router0: + entrypoints: + - web + middlewares: + - my-basic-auth + service: service-foo + rule: Path(`foo`) + middlewares: + my-basic-auth: + basicAuth: + users: + - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ + - test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0 + usersfile: etc/traefik/.htpasswd + headerfield: "" + services: + service-foo: + loadbalancer: + servers: + - url: http://foo/ + - url: http://bar/ + ``` ## Provider Configuration Options @@ -61,24 +97,36 @@ _Optional_ Defines the path of the configuration file. -```toml +```toml tab="TOML" [providers] [providers.file] filename = "rules.toml" ``` +```yaml tab="YAML" +providers: + file: + filename: rules.yaml +``` + ### `directory` _Optional_ Defines the directory that contains the configuration files. -```toml +```toml tab="TOML" [providers] [providers.file] directory = "/path/to/config" ``` +```yaml tab="YAML" +providers: + file: + directory: /path/to/config +``` + ### `watch` _Optional_ @@ -86,24 +134,32 @@ _Optional_ Set the `watch` option to `true` to allow Traefik to automatically watch for file changes. It works with both the `filename` and the `directory` options. -```toml +```toml tab="TOML" [providers] [providers.file] filename = "rules.toml" watch = true ``` -### TOML Templating +```yaml tab="YAML" +providers: + file: + filename: rules.yml + watch: true +``` + +### Go Templating !!! warning - TOML templating only works along with dedicated configuration files. Templating does not work in the Traefik main configuration file. + Go Templating only works along with dedicated configuration files. + Templating does not work in the Traefik main configuration file. -Traefik allows using TOML templating. +Traefik allows using Go templating. Thus, it's possible to define easily lot of routers, services and TLS certificates as described in the file `template-rules.toml` : ??? example "Configuring Using Templating" - - ```toml + + ```toml tab="TOML" # template-rules.toml [http] @@ -149,3 +205,43 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat # ... {{ end }} ``` + + ```yaml tab="YAML" + http: + + {{range $i, $e := until 100 }} + routers: + router{{ $e }: + # ... + {{end}} + + {{range $i, $e := until 100 }} + services: + application{{ $e }}: + # ... + {{end}} + + tcp: + + {{range $i, $e := until 100 }} + routers: + router{{ $e }: + # ... + {{end}} + + {{range $i, $e := until 100 }} + services: + service{{ $e }}: + # ... + {{end}} + + {{ range $i, $e := until 10 }} + tls: + store: + - "my-store-foo-{{ $e }}" + - "my-store-bar-{{ $e }}" + certificate: + certfile: "/etc/traefik/cert-{{ $e }}.pem" + keyfile: "/etc/traefik/cert-{{ $e }}.key" + {{end}} + ``` diff --git a/docs/content/reference/dynamic-configuration/file.md b/docs/content/reference/dynamic-configuration/file.md index 8afa5796e..754e6d35d 100644 --- a/docs/content/reference/dynamic-configuration/file.md +++ b/docs/content/reference/dynamic-configuration/file.md @@ -1,8 +1,12 @@ # File Configuration Reference -Dynamic configuration with toml files +Dynamic configuration with files {: .subtitle } -```toml +```toml tab="TOML" --8<-- "content/reference/dynamic-configuration/file.toml" ``` + +```yml tab="YAML" +--8<-- "content/reference/dynamic-configuration/file.yaml" +``` diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml new file mode 100644 index 000000000..0587df582 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -0,0 +1,294 @@ +http: + routers: + Router0: + entrypoints: + - foobar + - foobar + middlewares: + - foobar + - foobar + service: foobar + rule: foobar + priority: 42 + tls: + options: TLS0 + middlewares: + Middleware0: + addPrefix: + prefix: foobar + Middleware1: + stripPrefix: + prefixes: + - foobar + - foobar + Middleware2: + stripPrefixRegex: + regex: + - foobar + - foobar + Middleware3: + replacePath: + path: foobar + Middleware4: + replacePathRegex: + regex: foobar + replacement: foobar + Middleware5: + chain: + middlewares: + - foobar + - foobar + Middleware6: + ipWhiteList: + sourcerange: + - foobar + - foobar + ipstrategy: null + Middleware7: + ipWhiteList: + sourcerange: [] + ipstrategy: + depth: 42 + excludedips: + - foobar + - foobar + Middleware8: + headers: + customrequestheaders: + name0: foobar + name1: foobar + customresponseheaders: + name0: foobar + name1: foobar + accesscontrolallowcredentials: true + accesscontrolallowheaders: + - foobar + - foobar + accesscontrolallowmethods: + - foobar + - foobar + accesscontrolalloworigin: foobar + accesscontrolexposeheaders: + - foobar + - foobar + accesscontrolmaxage: 42 + addvaryheader: true + allowedhosts: + - foobar + - foobar + hostsproxyheaders: + - foobar + - foobar + sslredirect: true + ssltemporaryredirect: true + sslhost: foobar + sslproxyheaders: + name0: foobar + name1: foobar + sslforcehost: true + stsseconds: 42 + stsincludesubdomains: true + stspreload: true + forcestsheader: true + framedeny: true + customframeoptionsvalue: foobar + contenttypenosniff: true + browserxssfilter: true + custombrowserxssvalue: foobar + contentsecuritypolicy: foobar + publickey: foobar + referrerpolicy: foobar + isdevelopment: true + Middleware9: + errors: + status: + - foobar + - foobar + service: foobar + query: foobar + Middleware10: + rateLimit: + rateset: + Rate0: + period: 42000000000 + average: 42 + burst: 42 + Rate1: + period: 42000000000 + average: 42 + burst: 42 + extractorfunc: foobar + Middleware11: + redirectRegex: + regex: foobar + replacement: foobar + permanent: true + Middleware12: + redirectScheme: + scheme: foobar + port: foobar + permanent: true + Middleware13: + basicAuth: + users: + - foobar + - foobar + usersfile: foobar + realm: foobar + removeheader: true + headerfield: foobar + Middleware14: + digestAuth: + users: + - foobar + - foobar + usersfile: foobar + removeheader: true + realm: foobar + headerfield: foobar + Middleware15: + forwardAuth: + address: foobar + tls: + ca: foobar + caoptional: true + cert: foobar + key: foobar + insecureskipverify: true + trustforwardheader: true + authresponseheaders: + - foobar + - foobar + Middleware16: + maxConn: + amount: 42 + extractorfunc: foobar + Middleware17: + buffering: + maxrequestbodybytes: 42 + memrequestbodybytes: 42 + maxresponsebodybytes: 42 + memresponsebodybytes: 42 + retryexpression: foobar + Middleware18: + circuitBreaker: + expression: foobar + Middleware19: + compress: {} + Middleware20: + passTLSClientCert: + pem: true + info: + notafter: true + notbefore: true + sans: true + subject: + country: true + province: true + locality: true + organization: true + commonname: true + serialnumber: true + domaincomponent: true + issuer: + country: true + province: true + locality: true + organization: true + commonname: true + serialnumber: true + domaincomponent: true + Middleware21: + retry: + attempts: 42 + services: + Service0: + loadbalancer: + stickiness: + cookiename: foobar + securecookie: false + httponlycookie: false + servers: + - url: foobar + scheme: "" + port: "" + - url: foobar + scheme: "" + port: "" + healthcheck: + scheme: foobar + path: foobar + port: 42 + interval: foobar + timeout: foobar + hostname: foobar + headers: + name0: foobar + name1: foobar + passhostheader: true + responseforwarding: + flushinterval: foobar +tcp: + routers: + TCPRouter0: + entrypoints: + - foobar + - foobar + service: foobar + rule: foobar + tls: + passthrough: true + options: TLS1 + services: + TCPService0: + loadbalancer: + servers: + - address: foobar + port: "" + - address: foobar + port: "" +tls: + - stores: + - foobar + - foobar + certificate: + certfile: foobar + keyfile: foobar + - stores: + - foobar + - foobar + certificate: + certfile: foobar + keyfile: foobar +tlsoptions: + TLS0: + minversion: foobar + ciphersuites: + - foobar + - foobar + clientca: + files: + - foobar + - foobar + optional: true + snistrict: true + TLS1: + minversion: foobar + ciphersuites: + - foobar + - foobar + clientca: + files: + - foobar + - foobar + optional: true + snistrict: true +tlsstores: + Store0: + defaultcertificate: + certfile: foobar + keyfile: foobar + Store1: + defaultcertificate: + certfile: foobar + keyfile: foobar diff --git a/docs/content/reference/static-configuration/file.md b/docs/content/reference/static-configuration/file.md index c103de7f7..6fa3daf4f 100644 --- a/docs/content/reference/static-configuration/file.md +++ b/docs/content/reference/static-configuration/file.md @@ -1,7 +1,9 @@ # Static Configuration: File -## TOML - -```toml +```toml tab="TOML" --8<-- "content/reference/static-configuration/file.toml" ``` + +```yml tab="YAML" +--8<-- "content/reference/static-configuration/file.yaml" +``` diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index da26229c5..b0ec36369 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -133,16 +133,16 @@ [Metrics.Datadog] Address = "foobar" - PushInterval = "foobar" + PushInterval = "10s" [Metrics.StatsD] Address = "foobar" - PushInterval = "foobar" + PushInterval = "10s" [Metrics.InfluxDB] Address = "foobar" Protocol = "foobar" - PushInterval = "foobar" + PushInterval = "10s" Database = "foobar" RetentionPolicy = "foobar" Username = "foobar" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml new file mode 100644 index 000000000..b616be96a --- /dev/null +++ b/docs/content/reference/static-configuration/file.yaml @@ -0,0 +1,240 @@ +global: + checknewversion: true + sendanonymoususage: true +serverstransport: + insecureskipverify: true + rootcas: + - foobar + - foobar + maxidleconnsperhost: 42 + forwardingtimeouts: + dialtimeout: 42000000000 + responseheadertimeout: 42000000000 +entrypoints: + EntryPoint0: + address: foobar + transport: + lifecycle: + requestacceptgracetimeout: 42000000000 + gracetimeout: 42000000000 + respondingtimeouts: + readtimeout: 42000000000 + writetimeout: 42000000000 + idletimeout: 42000000000 + proxyprotocol: + insecure: true + trustedips: + - foobar + - foobar + forwardedheaders: + insecure: true + trustedips: + - foobar + - foobar +providers: + providersthrottleduration: 42000000000 + docker: + constraints: foobar + watch: true + endpoint: foobar + defaultrule: foobar + tls: + ca: foobar + caoptional: true + cert: foobar + key: foobar + insecureskipverify: true + exposedbydefault: true + usebindportip: true + swarmmode: true + network: foobar + swarmmoderefreshseconds: 42000000000 + file: + directory: foobar + watch: true + filename: foobar + debugloggeneratedtemplate: true + traefikfile: foobar + marathon: + constraints: foobar + trace: true + watch: true + endpoint: foobar + defaultrule: foobar + exposedbydefault: true + dcostoken: foobar + tls: + ca: foobar + caoptional: true + cert: foobar + key: foobar + insecureskipverify: true + dialertimeout: 42000000000 + responseheadertimeout: 42000000000 + tlshandshaketimeout: 42000000000 + keepalive: 42000000000 + forcetaskhostname: true + basic: + httpbasicauthuser: foobar + httpbasicpassword: foobar + respectreadinesschecks: true + kubernetes: + endpoint: foobar + token: foobar + certauthfilepath: foobar + disablepasshostheaders: true + namespaces: + - foobar + - foobar + labelselector: foobar + ingressclass: foobar + ingressendpoint: + ip: foobar + hostname: foobar + publishedservice: foobar + kubernetescrd: + endpoint: foobar + token: foobar + certauthfilepath: foobar + disablepasshostheaders: true + namespaces: + - foobar + - foobar + labelselector: foobar + ingressclass: foobar + rest: + entrypoint: foobar + rancher: + constraints: foobar + watch: true + defaultrule: foobar + exposedbydefault: true + enableservicehealthfilter: true + refreshseconds: 42 + intervalpoll: true + prefix: foobar +api: + entrypoint: foobar + dashboard: true + debug: false + statistics: + recenterrors: 42 + middlewares: + - foobar + - foobar + dashboardassets: null +metrics: + prometheus: + buckets: + - 42 + - 42 + entrypoint: foobar + middlewares: + - foobar + - foobar + datadog: + address: foobar + pushinterval: 10000000000 + statsd: + address: foobar + pushinterval: 10000000000 + influxdb: + address: foobar + protocol: foobar + pushinterval: 10000000000 + database: foobar + retentionpolicy: foobar + username: foobar + password: foobar +ping: + entrypoint: foobar + middlewares: + - foobar + - foobar +log: + level: foobar + filepath: foobar + format: foobar +accesslog: + filepath: foobar + format: foobar + filters: + statuscodes: + - foobar + - foobar + retryattempts: true + minduration: 42000000000 + fields: + defaultmode: foobar + names: + name0: foobar + name1: foobar + headers: + defaultmode: foobar + names: + name0: foobar + name1: foobar + bufferingsize: 42 +tracing: + backend: foobar + servicename: foobar + spannamelimit: 42 + jaeger: + samplingserverurl: foobar + samplingtype: foobar + samplingparam: 42 + localagenthostport: foobar + gen128bit: true + propagation: foobar + tracecontextheadername: foobar + zipkin: + httpendpoint: foobar + samespan: true + id128bit: true + debug: true + samplerate: 42 + datadog: + localagenthostport: foobar + globaltag: foobar + debug: true + prioritysampling: true + traceidheadername: foobar + parentidheadername: foobar + samplingpriorityheadername: foobar + bagageprefixheadername: foobar + instana: + localagenthost: foobar + localagentport: 42 + loglevel: foobar + haystack: null +hostresolver: + cnameflattening: true + resolvconfig: foobar + resolvdepth: 42 +acme: + email: foobar + acmelogging: true + caserver: foobar + storage: foobar + entrypoint: foobar + keytype: foobar + onhostrule: true + dnschallenge: + provider: foobar + delaybeforecheck: 42000000000 + resolvers: + - foobar + - foobar + disablepropagationcheck: true + httpchallenge: + entrypoint: foobar + tlschallenge: {} + domains: + - main: foobar + sans: + - foobar + - foobar + - main: foobar + sans: + - foobar + - foobar diff --git a/docs/content/routing/overview.md b/docs/content/routing/overview.md index 8fbb01242..072b93f01 100644 --- a/docs/content/routing/overview.md +++ b/docs/content/routing/overview.md @@ -24,29 +24,79 @@ If they do, the router might transform the request using pieces of [middleware]( Below is an example of a full configuration file for the [file provider](../providers/file.md) that forwards `http://domain/whoami/` requests to a service reachable on `http://private/whoami-service/`. In the process, Traefik will make sure that the user is authenticated (using the [BasicAuth middleware](../middlewares/basicauth.md)). -```toml +Static configuration: + +```toml tab="TOML" [entryPoints] - [entryPoints.web] - address = ":8081" # Listen on port 8081 for incoming requests + [entryPoints.web] + # Listen on port 8081 for incoming requests + address = ":8081" [providers] - [providers.file] # Enable the file provider to define routers / middlewares / services in a file + # Enable the file provider to define routers / middlewares / services in a file + [providers.file] +``` -[http] # http routing section - [http.routers] - [http.routers.to-whoami] # Define a connection between requests and services - rule = "Host(domain) && PathPrefix(/whoami/)" - middlewares = ["test-user"] # If the rule matches, applies the middleware - service = "whoami" # If the rule matches, forward to the whoami service (declared below) +```yaml tab="YAML" +entrypoints: + web: + # Listen on port 8081 for incoming requests + address: :8081 +providers: + # Enable the file provider to define routers / middlewares / services in a file + file: {} +``` - [http.middlewares] - [http.middlewares.test-user.basicauth] # Define an authentication mechanism - users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] +Dynamic configuration: - [http.services] - [http.services.whoami.loadbalancer] # Define how to reach an existing service on our infrastructure - [[http.services.whoami.loadbalancer.servers]] - url = "http://private/whoami-service" +```toml tab="TOML" +# http routing section +[http] + [http.routers] + # Define a connection between requests and services + [http.routers.to-whoami] + rule = "Host(`domain`) && PathPrefix(`/whoami/`)" + # If the rule matches, applies the middleware + middlewares = ["test-user"] + # If the rule matches, forward to the whoami service (declared below) + service = "whoami" + + [http.middlewares] + # Define an authentication mechanism + [http.middlewares.test-user.basicauth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] + + [http.services] + # Define how to reach an existing service on our infrastructure + [http.services.whoami.loadbalancer] + [[http.services.whoami.loadbalancer.servers]] + url = "http://private/whoami-service" +``` + +```yaml tab="YAML" +# http routing section +http: + routers: + # Define a connection between requests and services + to-whoami: + rule: "Host(`domain`) && PathPrefix(`/whoami/`)" + # If the rule matches, applies the middleware + middlewares: + - test-user + # If the rule matches, forward to the whoami service (declared below) + service: whoami + middlewares: + # Define an authentication mechanism + test-user: + basicAuth: + users: + - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ + services: + # Define how to reach an existing service on our infrastructure + whoami: + loadbalancer: + servers: + - url: http://private/whoami-service ``` !!! note "The File Provider" @@ -61,27 +111,51 @@ In the process, Traefik will make sure that the user is authenticated (using the ??? example "Adding a TCP route for TLS requests on whoami.traefik.io" - ```toml + Static configuration: + + ```toml tab="TOML" [entryPoints] [entryPoints.web] - address = ":8081" # Listen on port 8081 for incoming requests + # Listen on port 8081 for incoming requests + address = ":8081" [providers] - [providers.file] # Enable the file provider to define routers / middlewares / services in a file + # Enable the file provider to define routers / middlewares / services in a file + [providers.file] + ``` + + ```yaml tab="YAML" + entrypoints: + web: + # Listen on port 8081 for incoming requests + address: :8081 + providers: + # Enable the file provider to define routers / middlewares / services in a file + file: {} + ``` + + Dynamic configuration: - [http] # http routing section + ```toml tab="TOML" + # http routing section + [http] [http.routers] - [http.routers.to-whoami] # Define a connection between requests and services - rule = "Host(`domain`) && PathPrefix(/whoami/)" - middlewares = ["test-user"] # If the rule matches, applies the middleware - service = "whoami" # If the rule matches, forward to the whoami service (declared below) + # Define a connection between requests and services + [http.routers.to-whoami] + rule = "Host(`domain`) && PathPrefix(`/whoami/`)" + # If the rule matches, applies the middleware + middlewares = ["test-user"] + # If the rule matches, forward to the whoami service (declared below) + service = "whoami" [http.middlewares] - [http.middlewares.test-user.basicauth] # Define an authentication mechanism + # Define an authentication mechanism + [http.middlewares.test-user.basicauth] users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] [http.services] - [http.services.whoami.loadbalancer] # Define how to reach an existing service on our infrastructure + # Define how to reach an existing service on our infrastructure + [http.services.whoami.loadbalancer] [[http.services.whoami.loadbalancer.servers]] url = "http://private/whoami-service" @@ -97,3 +171,39 @@ In the process, Traefik will make sure that the user is authenticated (using the [[tcp.services.whoami-tcp.loadbalancer.servers]] address = "xx.xx.xx.xx:xx" ``` + + ```yaml tab="YAML" + # http routing section + http: + routers: + # Define a connection between requests and services + to-whoami: + rule: Host(`domain`) && PathPrefix(`/whoami/`) + # If the rule matches, applies the middleware + middlewares: + - test-user + # If the rule matches, forward to the whoami service (declared below) + service: whoami + middlewares: + # Define an authentication mechanism + test-user: + basicAuth: + users: + - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ + services: + # Define how to reach an existing service on our infrastructure + whoami: + loadbalancer: + servers: + - url: http://private/whoami-service + tcp: + routers: + to-whoami-tcp: + service: whoami-tcp + rule: HostSNI(`whoami-tcp.traefik.io`) + services: + whoami-tcp: + loadbalancer: + servers: + - address: xx.xx.xx.xx:xx + ``` diff --git a/pkg/config/dyn_config.go b/pkg/config/dyn_config.go index b08ebd227..6b7577945 100644 --- a/pkg/config/dyn_config.go +++ b/pkg/config/dyn_config.go @@ -215,7 +215,7 @@ type Message struct { type Configuration struct { HTTP *HTTPConfiguration TCP *TCPConfiguration - TLS []*traefiktls.Configuration `json:"-" label:"-"` + TLS []*traefiktls.Configuration `json:"-" label:"-" yaml:"tls"` TLSOptions map[string]traefiktls.TLS TLSStores map[string]traefiktls.Store } diff --git a/pkg/config/file/file_node.go b/pkg/config/file/file_node.go index 33534d922..0c64f6e35 100644 --- a/pkg/config/file/file_node.go +++ b/pkg/config/file/file_node.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "path/filepath" "reflect" + "strings" "github.com/BurntSushi/toml" "github.com/containous/traefik/pkg/config/parser" @@ -22,7 +23,7 @@ func decodeFileToNode(filePath string, filters ...string) (*parser.Node, error) data := make(map[string]interface{}) - switch filepath.Ext(filePath) { + switch strings.ToLower(filepath.Ext(filePath)) { case ".toml": err = toml.Unmarshal(content, &data) if err != nil { @@ -30,14 +31,11 @@ func decodeFileToNode(filePath string, filters ...string) (*parser.Node, error) } case ".yml", ".yaml": - var err error err = yaml.Unmarshal(content, data) if err != nil { return nil, err } - return decodeRawToNode(data, parser.DefaultRootName, filters...) - default: return nil, fmt.Errorf("unsupported file extension: %s", filePath) } diff --git a/pkg/config/middlewares.go b/pkg/config/middlewares.go index 2caa868bb..05c36513a 100644 --- a/pkg/config/middlewares.go +++ b/pkg/config/middlewares.go @@ -9,27 +9,27 @@ import ( // Middleware holds the Middleware configuration. type Middleware struct { - AddPrefix *AddPrefix `json:"addPrefix,omitempty"` - StripPrefix *StripPrefix `json:"stripPrefix,omitempty"` - StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty"` - ReplacePath *ReplacePath `json:"replacePath,omitempty"` - ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty"` - Chain *Chain `json:"chain,omitempty"` - IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty"` - Headers *Headers `json:"headers,omitempty"` - Errors *ErrorPage `json:"errors,omitempty"` - RateLimit *RateLimit `json:"rateLimit,omitempty"` - RedirectRegex *RedirectRegex `json:"redirectRegex,omitempty"` - RedirectScheme *RedirectScheme `json:"redirectScheme,omitempty"` - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - DigestAuth *DigestAuth `json:"digestAuth,omitempty"` - ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty"` - MaxConn *MaxConn `json:"maxConn,omitempty"` - Buffering *Buffering `json:"buffering,omitempty"` - CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty"` - Compress *Compress `json:"compress,omitempty" label:"allowEmpty"` - PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty"` - Retry *Retry `json:"retry,omitempty"` + AddPrefix *AddPrefix `json:"addPrefix,omitempty" yaml:"addPrefix,omitempty"` + StripPrefix *StripPrefix `json:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty"` + StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty"` + ReplacePath *ReplacePath `json:"replacePath,omitempty" yaml:"replacePath,omitempty"` + ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty"` + Chain *Chain `json:"chain,omitempty" yaml:"chain,omitempty"` + IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty"` + Headers *Headers `json:"headers,omitempty" yaml:"headers,omitempty"` + Errors *ErrorPage `json:"errors,omitempty" yaml:"errors,omitempty"` + RateLimit *RateLimit `json:"rateLimit,omitempty" yaml:"rateLimit,omitempty"` + RedirectRegex *RedirectRegex `json:"redirectRegex,omitempty" yaml:"redirectRegex,omitempty"` + RedirectScheme *RedirectScheme `json:"redirectScheme,omitempty" yaml:"redirectScheme,omitempty"` + BasicAuth *BasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth,omitempty"` + DigestAuth *DigestAuth `json:"digestAuth,omitempty" yaml:"digestAuth,omitempty"` + ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty" yaml:"forwardAuth,omitempty"` + MaxConn *MaxConn `json:"maxConn,omitempty" yaml:"maxConn,omitempty"` + Buffering *Buffering `json:"buffering,omitempty" yaml:"buffering,omitempty"` + CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty" yaml:"circuitBreaker,omitempty"` + Compress *Compress `json:"compress,omitempty" label:"allowEmpty" yaml:"compress,omitempty" label:"allowEmpty"` + PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty"` + Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/file/file.go b/pkg/provider/file/file.go index 48c525032..57903ec3d 100644 --- a/pkg/provider/file/file.go +++ b/pkg/provider/file/file.go @@ -7,7 +7,6 @@ import ( "fmt" "io/ioutil" "os" - "path" "path/filepath" "strings" "text/template" @@ -20,6 +19,7 @@ import ( "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/tls" "gopkg.in/fsnotify.v1" + "gopkg.in/yaml.v2" ) const providerName = "file" @@ -170,28 +170,13 @@ func sendConfigToChannel(configurationChan chan<- config.Message, configuration } } -func readFile(filename string) (string, error) { - if len(filename) > 0 { - buf, err := ioutil.ReadFile(filename) - if err != nil { - return "", err - } - return string(buf), nil - } - return "", fmt.Errorf("invalid filename: %s", filename) -} - func (p *Provider) loadFileConfig(filename string, parseTemplate bool) (*config.Configuration, error) { - fileContent, err := readFile(filename) - if err != nil { - return nil, fmt.Errorf("error reading configuration file: %s - %s", filename, err) - } - + var err error var configuration *config.Configuration if parseTemplate { - configuration, err = p.CreateConfiguration(fileContent, template.FuncMap{}, false) + configuration, err = p.CreateConfiguration(filename, template.FuncMap{}, false) } else { - configuration, err = p.DecodeConfiguration(fileContent) + configuration, err = p.DecodeConfiguration(filename) } if err != nil { return nil, err @@ -223,7 +208,6 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st logger := log.FromContext(ctx) fileList, err := ioutil.ReadDir(directory) - if err != nil { return configuration, fmt.Errorf("unable to read directory %s: %v", directory, err) } @@ -243,6 +227,7 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st } configTLSMaps := make(map[*tls.Configuration]struct{}) + for _, item := range fileList { if item.IsDir() { @@ -251,13 +236,17 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st return configuration, fmt.Errorf("unable to load content configuration from subdirectory %s: %v", item, err) } continue - } else if !strings.HasSuffix(item.Name(), ".toml") && !strings.HasSuffix(item.Name(), ".tmpl") { + } + + switch strings.ToLower(filepath.Ext(item.Name())) { + case ".toml", ".yaml", ".yml": + // noop + default: continue } var c *config.Configuration - c, err = p.loadFileConfig(path.Join(directory, item.Name()), true) - + c, err = p.loadFileConfig(filepath.Join(directory, item.Name()), true) if err != nil { return configuration, err } @@ -318,7 +307,12 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st } // CreateConfiguration creates a provider configuration from content using templating. -func (p *Provider) CreateConfiguration(tmplContent string, funcMap template.FuncMap, templateObjects interface{}) (*config.Configuration, error) { +func (p *Provider) CreateConfiguration(filename string, funcMap template.FuncMap, templateObjects interface{}) (*config.Configuration, error) { + tmplContent, err := readFile(filename) + if err != nil { + return nil, fmt.Errorf("error reading configuration file: %s - %s", filename, err) + } + var defaultFuncMap = sprig.TxtFuncMap() defaultFuncMap["normalize"] = provider.Normalize defaultFuncMap["split"] = strings.Split @@ -328,7 +322,7 @@ func (p *Provider) CreateConfiguration(tmplContent string, funcMap template.Func tmpl := template.New(p.Filename).Funcs(defaultFuncMap) - _, err := tmpl.Parse(tmplContent) + _, err = tmpl.Parse(tmplContent) if err != nil { return nil, err } @@ -341,14 +335,25 @@ func (p *Provider) CreateConfiguration(tmplContent string, funcMap template.Func var renderedTemplate = buffer.String() if p.DebugLogGeneratedTemplate { - log.Debugf("Template content: %s", tmplContent) - log.Debugf("Rendering results: %s", renderedTemplate) + logger := log.WithoutContext().WithField(log.ProviderName, providerName) + logger.Debugf("Template content: %s", tmplContent) + logger.Debugf("Rendering results: %s", renderedTemplate) } - return p.DecodeConfiguration(renderedTemplate) + + return p.decodeConfiguration(filename, renderedTemplate) } // DecodeConfiguration Decodes a *types.Configuration from a content. -func (p *Provider) DecodeConfiguration(content string) (*config.Configuration, error) { +func (p *Provider) DecodeConfiguration(filename string) (*config.Configuration, error) { + content, err := readFile(filename) + if err != nil { + return nil, fmt.Errorf("error reading configuration file: %s - %s", filename, err) + } + + return p.decodeConfiguration(filename, content) +} + +func (p *Provider) decodeConfiguration(filePath string, content string) (*config.Configuration, error) { configuration := &config.Configuration{ HTTP: &config.HTTPConfiguration{ Routers: make(map[string]*config.Router), @@ -363,8 +368,35 @@ func (p *Provider) DecodeConfiguration(content string) (*config.Configuration, e TLSStores: make(map[string]tls.Store), TLSOptions: make(map[string]tls.TLS), } - if _, err := toml.Decode(content, configuration); err != nil { - return nil, err + + switch strings.ToLower(filepath.Ext(filePath)) { + case ".toml": + _, err := toml.Decode(content, configuration) + if err != nil { + return nil, err + } + + case ".yml", ".yaml": + var err error + err = yaml.Unmarshal([]byte(content), configuration) + if err != nil { + return nil, err + } + + default: + return nil, fmt.Errorf("unsupported file extension: %s", filePath) } + return configuration, nil } + +func readFile(filename string) (string, error) { + if len(filename) > 0 { + buf, err := ioutil.ReadFile(filename) + if err != nil { + return "", err + } + return string(buf), nil + } + return "", fmt.Errorf("invalid filename: %s", filename) +} diff --git a/pkg/provider/file/file_test.go b/pkg/provider/file/file_test.go index 95bbb26eb..46f28354b 100644 --- a/pkg/provider/file/file_test.go +++ b/pkg/provider/file/file_test.go @@ -2,10 +2,11 @@ package file import ( "context" - "fmt" + "io" "io/ioutil" "os" - "path" + "path/filepath" + "strconv" "testing" "time" @@ -17,14 +18,62 @@ import ( type ProvideTestCase struct { desc string - directoryContent []string - fileContent string - traefikFileContent string + directoryPaths []string + filePath string + traefikFilePath string expectedNumRouter int expectedNumService int expectedNumTLSConf int } +func TestTLSContent(t *testing.T) { + tempDir := createTempDir(t, "testdir") + defer os.RemoveAll(tempDir) + + fileTLS, err := createTempFile("./fixtures/toml/tls_file.cert", tempDir) + require.NoError(t, err) + + fileConfig, err := ioutil.TempFile(tempDir, "temp*.toml") + require.NoError(t, err) + + content := ` +[[tls]] + [tls.certificate] + certFile = "` + fileTLS.Name() + `" + keyFile = "` + fileTLS.Name() + `" +` + + _, err = fileConfig.Write([]byte(content)) + require.NoError(t, err) + + provider := &Provider{} + configuration, err := provider.loadFileConfig(fileConfig.Name(), true) + require.NoError(t, err) + + require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.CertFile.String()) + require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.KeyFile.String()) +} + +func TestErrorWhenEmptyConfig(t *testing.T) { + provider := &Provider{} + configChan := make(chan config.Message) + errorChan := make(chan struct{}) + go func() { + err := provider.Provide(configChan, safe.NewPool(context.Background())) + assert.Error(t, err) + close(errorChan) + }() + + timeout := time.After(time.Second) + select { + case <-configChan: + t.Fatal("We should not receive config message") + case <-timeout: + t.Fatal("timeout while waiting for config") + case <-errorChan: + } +} + func TestProvideWithoutWatch(t *testing.T) { for _, test := range getTestCases() { t.Run(test.desc+" without watch", func(t *testing.T) { @@ -74,21 +123,20 @@ func TestProvideWithWatch(t *testing.T) { t.Errorf("timeout while waiting for config") } - if len(test.fileContent) > 0 { - if err := ioutil.WriteFile(provider.Filename, []byte(test.fileContent), 0755); err != nil { - t.Error(err) - } + if len(test.filePath) > 0 { + err := copyFile(test.filePath, provider.Filename) + require.NoError(t, err) } - if len(test.traefikFileContent) > 0 { - if err := ioutil.WriteFile(provider.TraefikFile, []byte(test.traefikFileContent), 0755); err != nil { - t.Error(err) - } + if len(test.traefikFilePath) > 0 { + err := copyFile(test.traefikFilePath, provider.TraefikFile) + require.NoError(t, err) } - if len(test.directoryContent) > 0 { - for _, fileContent := range test.directoryContent { - createRandomFile(t, provider.Directory, fileContent) + if len(test.directoryPaths) > 0 { + for i, filePath := range test.directoryPaths { + err := copyFile(filePath, filepath.Join(provider.Directory, strconv.Itoa(i)+filepath.Ext(filePath))) + require.NoError(t, err) } } @@ -114,62 +162,86 @@ func TestProvideWithWatch(t *testing.T) { } } -func TestErrorWhenEmptyConfig(t *testing.T) { - provider := &Provider{} - configChan := make(chan config.Message) - errorChan := make(chan struct{}) - go func() { - err := provider.Provide(configChan, safe.NewPool(context.Background())) - assert.Error(t, err) - close(errorChan) - }() - - timeout := time.After(time.Second) - select { - case <-configChan: - t.Fatal("We should not receive config message") - case <-timeout: - t.Fatal("timeout while waiting for config") - case <-errorChan: - } -} - func getTestCases() []ProvideTestCase { return []ProvideTestCase{ { desc: "simple file", - fileContent: createRoutersConfiguration(3) + createServicesConfiguration(6) + createTLS(5), + filePath: "./fixtures/toml/simple_file_01.toml", expectedNumRouter: 3, expectedNumService: 6, expectedNumTLSConf: 5, }, { - desc: "simple file and a traefik file", - fileContent: createRoutersConfiguration(4) + createServicesConfiguration(8) + createTLS(4), - traefikFileContent: ` - debug=true -`, + desc: "simple file yaml", + filePath: "./fixtures/yaml/simple_file_01.yml", + expectedNumRouter: 3, + expectedNumService: 6, + expectedNumTLSConf: 5, + }, + { + desc: "simple file and a traefik file", + filePath: "./fixtures/toml/simple_file_02.toml", + traefikFilePath: "./fixtures/toml/simple_traefik_file_01.toml", expectedNumRouter: 4, expectedNumService: 8, expectedNumTLSConf: 4, }, { - desc: "template file", - fileContent: ` -[http.routers] -{{ range $i, $e := until 20 }} - [http.routers.router{{ $e }}] - service = "application" -{{ end }} -`, + desc: "simple file and a traefik file yaml", + filePath: "./fixtures/yaml/simple_file_02.yml", + traefikFilePath: "./fixtures/yaml/simple_traefik_file_01.yml", + expectedNumRouter: 4, + expectedNumService: 8, + expectedNumTLSConf: 4, + }, + { + desc: "simple traefik file", + traefikFilePath: "./fixtures/toml/simple_traefik_file_02.toml", + expectedNumRouter: 2, + expectedNumService: 3, + expectedNumTLSConf: 4, + }, + { + desc: "simple traefik file yaml", + traefikFilePath: "./fixtures/yaml/simple_traefik_file_02.yml", + expectedNumRouter: 2, + expectedNumService: 3, + expectedNumTLSConf: 4, + }, + { + desc: "template file", + filePath: "./fixtures/toml/template_file.toml", expectedNumRouter: 20, }, + { + desc: "template file yaml", + filePath: "./fixtures/yaml/template_file.yml", + expectedNumRouter: 20, + }, + { + desc: "simple traefik file with templating", + traefikFilePath: "./fixtures/toml/simple_traefik_file_with_templating.toml", + expectedNumRouter: 2, + expectedNumService: 3, + expectedNumTLSConf: 4, + }, { desc: "simple directory", - directoryContent: []string{ - createRoutersConfiguration(2), - createServicesConfiguration(3), - createTLS(4), + directoryPaths: []string{ + "./fixtures/toml/dir01_file01.toml", + "./fixtures/toml/dir01_file02.toml", + "./fixtures/toml/dir01_file03.toml", + }, + expectedNumRouter: 2, + expectedNumService: 3, + expectedNumTLSConf: 4, + }, + { + desc: "simple directory yaml", + directoryPaths: []string{ + "./fixtures/yaml/dir01_file01.yml", + "./fixtures/yaml/dir01_file02.yml", + "./fixtures/yaml/dir01_file03.yml", }, expectedNumRouter: 2, expectedNumService: 3, @@ -177,45 +249,21 @@ func getTestCases() []ProvideTestCase { }, { desc: "template in directory", - directoryContent: []string{ - ` -[http.routers] -{{ range $i, $e := until 20 }} - [http.routers.router{{ $e }}] - service = "application" -{{ end }} -`, - ` -[http.services] -{{ range $i, $e := until 20 }} - [http.services.application-{{ $e }}] - [[http.services.application-{{ $e }}.servers]] - url="http://127.0.0.1" -{{ end }} -`, + directoryPaths: []string{ + "./fixtures/toml/template_in_directory_file01.toml", + "./fixtures/toml/template_in_directory_file02.toml", }, expectedNumRouter: 20, expectedNumService: 20, }, { - desc: "simple traefik file", - traefikFileContent: ` - debug=true - [providers.file] - ` + createRoutersConfiguration(2) + createServicesConfiguration(3) + createTLS(4), - expectedNumRouter: 2, - expectedNumService: 3, - expectedNumTLSConf: 4, - }, - { - desc: "simple traefik file with templating", - traefikFileContent: ` - temp="{{ getTag \"test\" }}" - [providers.file] - ` + createRoutersConfiguration(2) + createServicesConfiguration(3) + createTLS(4), - expectedNumRouter: 2, - expectedNumService: 3, - expectedNumTLSConf: 4, + desc: "template in directory yaml", + directoryPaths: []string{ + "./fixtures/yaml/template_in_directory_file01.yml", + "./fixtures/yaml/template_in_directory_file02.yml", + }, + expectedNumRouter: 20, + expectedNumService: 20, }, } } @@ -226,30 +274,46 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) (*Provider, provider := &Provider{} provider.Watch = true - if len(test.directoryContent) > 0 { + if len(test.directoryPaths) > 0 { if !watch { - for _, fileContent := range test.directoryContent { - createRandomFile(t, tempDir, fileContent) + for _, filePath := range test.directoryPaths { + var err error + _, err = createTempFile(filePath, tempDir) + require.NoError(t, err) } } provider.Directory = tempDir } - if len(test.fileContent) > 0 { - if watch { - test.fileContent = "" - } - filename := createRandomFile(t, tempDir, test.fileContent) - provider.Filename = filename.Name() + if len(test.filePath) > 0 { + var file *os.File + if watch { + var err error + file, err = ioutil.TempFile(tempDir, "temp*"+filepath.Ext(test.filePath)) + require.NoError(t, err) + } else { + var err error + file, err = createTempFile(test.filePath, tempDir) + require.NoError(t, err) + } + + provider.Filename = file.Name() } - if len(test.traefikFileContent) > 0 { + if len(test.traefikFilePath) > 0 { + var file *os.File if watch { - test.traefikFileContent = "" + var err error + file, err = ioutil.TempFile(tempDir, "temp*"+filepath.Ext(test.traefikFilePath)) + require.NoError(t, err) + } else { + var err error + file, err = createTempFile(test.traefikFilePath, tempDir) + require.NoError(t, err) } - filename := createRandomFile(t, tempDir, test.traefikFileContent) - provider.TraefikFile = filename.Name() + + provider.TraefikFile = file.Name() } return provider, func() { @@ -257,39 +321,10 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) (*Provider, } } -// createRandomFile Helper -func createRandomFile(t *testing.T, tempDir string, contents ...string) *os.File { - return createFile(t, tempDir, fmt.Sprintf("temp%d.toml", time.Now().UnixNano()), contents...) -} - -// createFile Helper -func createFile(t *testing.T, tempDir string, name string, contents ...string) *os.File { - t.Helper() - fileName := path.Join(tempDir, name) - - tempFile, err := os.Create(fileName) - if err != nil { - t.Fatal(err) - } - - for _, content := range contents { - _, err = tempFile.WriteString(content) - if err != nil { - t.Fatal(err) - } - } - - err = tempFile.Close() - if err != nil { - t.Fatal(err) - } - - return tempFile -} - // createTempDir Helper func createTempDir(t *testing.T, dir string) string { t.Helper() + d, err := ioutil.TempDir("", dir) if err != nil { t.Fatal(err) @@ -297,62 +332,36 @@ func createTempDir(t *testing.T, dir string) string { return d } -// createRoutersConfiguration Helper -func createRoutersConfiguration(n int) string { - conf := "[http.routers]\n" - for i := 1; i <= n; i++ { - conf += fmt.Sprintf(` -[http.routers."router%[1]d"] - service = "application-%[1]d" -`, i) +func copyFile(srcPath, dstPath string) error { + dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + return err } - return conf -} + defer dst.Close() -// createServicesConfiguration Helper -func createServicesConfiguration(n int) string { - conf := "[http.services]\n" - for i := 1; i <= n; i++ { - conf += fmt.Sprintf(` -[http.services.application-%[1]d.loadbalancer] - [[http.services.application-%[1]d.loadbalancer.servers]] - url = "http://172.17.0.%[1]d:80" -`, i) + src, err := os.Open(srcPath) + if err != nil { + return err } - return conf + defer src.Close() + + _, err = io.Copy(dst, src) + return err } -// createTLS Helper -func createTLS(n int) string { - var conf string - for i := 1; i <= n; i++ { - conf += fmt.Sprintf(`[[TLS]] - EntryPoints = ["https"] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest%[1]d.com.cert" - KeyFile = "integration/fixtures/https/snitest%[1]d.com.key" -`, i) +func createTempFile(srcPath, tempDir string) (*os.File, error) { + file, err := ioutil.TempFile(tempDir, "temp*"+filepath.Ext(srcPath)) + if err != nil { + return nil, err } - return conf -} - -func TestTLSContent(t *testing.T) { - tempDir := createTempDir(t, "testdir") - defer os.RemoveAll(tempDir) - - fileTLS := createRandomFile(t, tempDir, "CONTENT") - fileConfig := createRandomFile(t, tempDir, ` -[[tls]] -entryPoints = ["https"] - [tls.certificate] - certFile = "`+fileTLS.Name()+`" - keyFile = "`+fileTLS.Name()+`" -`) - - provider := &Provider{} - configuration, err := provider.loadFileConfig(fileConfig.Name(), true) - require.NoError(t, err) - - require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.CertFile.String()) - require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.KeyFile.String()) + defer file.Close() + + src, err := os.Open(srcPath) + if err != nil { + return nil, err + } + defer src.Close() + + _, err = io.Copy(file, src) + return file, err } diff --git a/pkg/provider/file/fixtures/toml/dir01_file01.toml b/pkg/provider/file/fixtures/toml/dir01_file01.toml new file mode 100644 index 000000000..64f84722a --- /dev/null +++ b/pkg/provider/file/fixtures/toml/dir01_file01.toml @@ -0,0 +1,7 @@ +[http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" diff --git a/pkg/provider/file/fixtures/toml/dir01_file02.toml b/pkg/provider/file/fixtures/toml/dir01_file02.toml new file mode 100644 index 000000000..6eb6d31d5 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/dir01_file02.toml @@ -0,0 +1,13 @@ +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" diff --git a/pkg/provider/file/fixtures/toml/dir01_file03.toml b/pkg/provider/file/fixtures/toml/dir01_file03.toml new file mode 100644 index 000000000..498a19b91 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/dir01_file03.toml @@ -0,0 +1,16 @@ +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_file_01.toml b/pkg/provider/file/fixtures/toml/simple_file_01.toml new file mode 100644 index 000000000..e3af6f686 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_file_01.toml @@ -0,0 +1,55 @@ +[http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" + +[http.routers."router3"] + service = "application-3" +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" + +[http.services.application-4.loadbalancer] + [[http.services.application-4.loadbalancer.servers]] + url = "http://172.17.0.4:80" + +[http.services.application-5.loadbalancer] + [[http.services.application-5.loadbalancer.servers]] + url = "http://172.17.0.5:80" + +[http.services.application-6.loadbalancer] + [[http.services.application-6.loadbalancer.servers]] + url = "http://172.17.0.6:80" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest5.com.cert" + KeyFile = "integration/fixtures/https/snitest5.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_file_02.toml b/pkg/provider/file/fixtures/toml/simple_file_02.toml new file mode 100644 index 000000000..e614160d3 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_file_02.toml @@ -0,0 +1,62 @@ +[http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" + +[http.routers."router3"] + service = "application-3" + +[http.routers."router4"] + service = "application-4" +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" + +[http.services.application-4.loadbalancer] + [[http.services.application-4.loadbalancer.servers]] + url = "http://172.17.0.4:80" + +[http.services.application-5.loadbalancer] + [[http.services.application-5.loadbalancer.servers]] + url = "http://172.17.0.5:80" + +[http.services.application-6.loadbalancer] + [[http.services.application-6.loadbalancer.servers]] + url = "http://172.17.0.6:80" + +[http.services.application-7.loadbalancer] + [[http.services.application-7.loadbalancer.servers]] + url = "http://172.17.0.7:80" + +[http.services.application-8.loadbalancer] + [[http.services.application-8.loadbalancer.servers]] + url = "http://172.17.0.8:80" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml new file mode 100644 index 000000000..2aa73ad54 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml @@ -0,0 +1,3 @@ + +[log] + level = "DEBUG" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml new file mode 100644 index 000000000..4d9e472f5 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml @@ -0,0 +1,38 @@ +[providers.file] + +[http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml new file mode 100644 index 000000000..99bb1bc14 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml @@ -0,0 +1,39 @@ + + temp="{{ getTag \"test\" }}" + [providers.file] + [http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/template_file.toml b/pkg/provider/file/fixtures/toml/template_file.toml new file mode 100644 index 000000000..1958d6387 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/template_file.toml @@ -0,0 +1,6 @@ + +[http.routers] +{{ range $i, $e := until 20 }} + [http.routers.router{{ $e }}] + service = "application" +{{ end }} diff --git a/pkg/provider/file/fixtures/toml/template_in_directory_file01.toml b/pkg/provider/file/fixtures/toml/template_in_directory_file01.toml new file mode 100644 index 000000000..3eccb8862 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/template_in_directory_file01.toml @@ -0,0 +1,5 @@ +[http.routers] +{{ range $i, $e := until 20 }} + [http.routers.router{{ $e }}] + service = "application" +{{ end }} \ No newline at end of file diff --git a/pkg/provider/file/fixtures/toml/template_in_directory_file02.toml b/pkg/provider/file/fixtures/toml/template_in_directory_file02.toml new file mode 100644 index 000000000..35c2d25f3 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/template_in_directory_file02.toml @@ -0,0 +1,6 @@ +[http.services] +{{ range $i, $e := until 20 }} + [http.services.application-{{ $e }}] + [[http.services.application-{{ $e }}.servers]] + url="http://127.0.0.1" +{{ end }} \ No newline at end of file diff --git a/pkg/provider/file/fixtures/toml/tls_file.cert b/pkg/provider/file/fixtures/toml/tls_file.cert new file mode 100644 index 000000000..33840068c --- /dev/null +++ b/pkg/provider/file/fixtures/toml/tls_file.cert @@ -0,0 +1 @@ +CONTENT \ No newline at end of file diff --git a/pkg/provider/file/fixtures/yaml/dir01_file01.yml b/pkg/provider/file/fixtures/yaml/dir01_file01.yml new file mode 100644 index 000000000..621580524 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/dir01_file01.yml @@ -0,0 +1,6 @@ +http: + routers: + router1: + service: application-1 + router2: + service: application-2 diff --git a/pkg/provider/file/fixtures/yaml/dir01_file02.yml b/pkg/provider/file/fixtures/yaml/dir01_file02.yml new file mode 100644 index 000000000..65f706ff0 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/dir01_file02.yml @@ -0,0 +1,14 @@ +http: + services: + application-1: + loadbalancer: + servers: + - url: 'http://172.17.0.1:80' + application-2: + loadbalancer: + servers: + - url: 'http://172.17.0.2:80' + application-3: + loadbalancer: + servers: + - url: 'http://172.17.0.3:80' diff --git a/pkg/provider/file/fixtures/yaml/dir01_file03.yml b/pkg/provider/file/fixtures/yaml/dir01_file03.yml new file mode 100644 index 000000000..e243d4fa8 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/dir01_file03.yml @@ -0,0 +1,13 @@ +tls: + - certificate: + certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certificate: + certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certificate: + certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certificate: + certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_file_01.yml b/pkg/provider/file/fixtures/yaml/simple_file_01.yml new file mode 100644 index 000000000..b2fc6e191 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/simple_file_01.yml @@ -0,0 +1,50 @@ +http: + routers: + router1: + service: application-1 + router2: + service: application-2 + router3: + service: application-3 + services: + application-1: + loadbalancer: + servers: + - url: 'http://172.17.0.1:80' + application-2: + loadbalancer: + servers: + - url: 'http://172.17.0.2:80' + application-3: + loadbalancer: + servers: + - url: 'http://172.17.0.3:80' + application-4: + loadbalancer: + servers: + - url: 'http://172.17.0.4:80' + application-5: + loadbalancer: + servers: + - url: 'http://172.17.0.5:80' + application-6: + loadbalancer: + servers: + - url: 'http://172.17.0.6:80' + +tls: + - certificate: + certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certificate: + certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certificate: + certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certificate: + certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key + - certificate: + certfile: integration/fixtures/https/snitest5.com.cert + keyfile: integration/fixtures/https/snitest5.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_file_02.yml b/pkg/provider/file/fixtures/yaml/simple_file_02.yml new file mode 100644 index 000000000..ae40b8789 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/simple_file_02.yml @@ -0,0 +1,58 @@ +http: + routers: + router1: + service: application-1 + router2: + service: application-2 + router3: + service: application-3 + router4: + service: application-4 + services: + application-1: + loadbalancer: + servers: + - url: 'http://172.17.0.1:80' + application-2: + loadbalancer: + servers: + - url: 'http://172.17.0.2:80' + application-3: + loadbalancer: + servers: + - url: 'http://172.17.0.3:80' + application-4: + loadbalancer: + servers: + - url: 'http://172.17.0.4:80' + application-5: + loadbalancer: + servers: + - url: 'http://172.17.0.5:80' + application-6: + loadbalancer: + servers: + - url: 'http://172.17.0.6:80' + application-7: + loadbalancer: + servers: + - url: 'http://172.17.0.7:80' + application-8: + loadbalancer: + servers: + - url: 'http://172.17.0.8:80' + +tls: + - certificate: + certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certificate: + certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certificate: + certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certificate: + certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key + diff --git a/pkg/provider/file/fixtures/yaml/simple_traefik_file_01.yml b/pkg/provider/file/fixtures/yaml/simple_traefik_file_01.yml new file mode 100644 index 000000000..b0e9cab54 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/simple_traefik_file_01.yml @@ -0,0 +1,2 @@ +log: + level: DEBUG diff --git a/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml b/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml new file mode 100644 index 000000000..f8733b514 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml @@ -0,0 +1,35 @@ +providers: + file: {} +http: + routers: + router1: + service: application-1 + router2: + service: application-2 + services: + application-1: + loadbalancer: + servers: + - url: 'http://172.17.0.1:80' + application-2: + loadbalancer: + servers: + - url: 'http://172.17.0.2:80' + application-3: + loadbalancer: + servers: + - url: 'http://172.17.0.3:80' + +tls: + - certificate: + certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certificate: + certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certificate: + certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certificate: + certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key diff --git a/pkg/provider/file/fixtures/yaml/template_file.yml b/pkg/provider/file/fixtures/yaml/template_file.yml new file mode 100644 index 000000000..66903fbc8 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/template_file.yml @@ -0,0 +1,6 @@ +http: +{{ range $i, $e := until 20 }} + routers: + router{{ $e }}: + service: application-1 +{{ end }} \ No newline at end of file diff --git a/pkg/provider/file/fixtures/yaml/template_in_directory_file01.yml b/pkg/provider/file/fixtures/yaml/template_in_directory_file01.yml new file mode 100644 index 000000000..908eed00c --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/template_in_directory_file01.yml @@ -0,0 +1,6 @@ +http: +{{ range $i, $e := until 20 }} + routers: + router{{ $e }}: + service: application-1 +{{ end }} diff --git a/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml b/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml new file mode 100644 index 000000000..8c2d94c03 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml @@ -0,0 +1,8 @@ +http: + services: +{{ range $i, $e := until 20 }} + application-{{ $e }}: + loadbalancer: + servers: + - url: 'http://127.0.0.1' +{{ end }} diff --git a/pkg/provider/file/fixtures/yaml/tls_file.cert b/pkg/provider/file/fixtures/yaml/tls_file.cert new file mode 100644 index 000000000..33840068c --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/tls_file.cert @@ -0,0 +1 @@ +CONTENT \ No newline at end of file