Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to use YAML instead of TOML for configuration #2999

Closed
gaui opened this issue Mar 11, 2018 · 20 comments
Closed

Option to use YAML instead of TOML for configuration #2999

gaui opened this issue Mar 11, 2018 · 20 comments
Labels
kind/proposal a proposal that needs to be discussed. status/5-frozen-due-to-age
Projects
Milestone

Comments

@gaui
Copy link

gaui commented Mar 11, 2018

Do you want to request a feature or report a bug?

feature

Description

YAML is becoming the industry standard configuration format. Docker uses it for Compose/Stack, Kubernetes, GitLab CI, Travis CI, Drone CI, Google App Engine, etc. Wouldn't it be ok to support both configuration formats, for those who prefer YAML instead of TOML.

Let's take the following example, a configuration in both TOML and YAML from here. In my opinion YAML is more readable, better structured (with indent as context) and with less noise (less repetitions of parent elements).

TOML

[entryPoints]
  [entryPoints.http]
    address = ":80"
    whitelistSourceRange = ["10.42.0.0/16", "152.89.1.33/32", "afed:be44::/16"]
    compress = true

    [entryPoints.http.tls]
      minVersion = "VersionTLS12"
      cipherSuites = [
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_RSA_WITH_AES_256_GCM_SHA384"
       ]
      [[entryPoints.http.tls.certificates]]
        certFile = "path/to/my.cert"
        keyFile = "path/to/my.key"
      [[entryPoints.http.tls.certificates]]
        certFile = "path/to/other.cert"
        keyFile = "path/to/other.key"
      # ...
      [entryPoints.http.tls.clientCA]
        files = ["path/to/ca1.crt", "path/to/ca2.crt"]
        optional = false

    [entryPoints.http.redirect]
      entryPoint = "https"
      regex = "^http://localhost/(.*)"
      replacement = "http://mydomain/$1"

    [entryPoints.http.auth]
      headerField = "X-WebAuth-User"
      [entryPoints.http.auth.basic]
        users = [
          "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
          "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
        ]
        usersFile = "/path/to/.htpasswd"
      [entryPoints.http.auth.digest]
        users = [
          "test:traefik:a2688e031edb4be6a3797f3882655c05",
          "test2:traefik:518845800f9e2bfb1f1f740ec24f074e",
        ]
        usersFile = "/path/to/.htdigest"
      [entryPoints.http.auth.forward]
        address = "https://authserver.com/auth"
        trustForwardHeader = true
        [entryPoints.http.auth.forward.tls]
          ca =  [ "path/to/local.crt"]
          caOptional = true
          cert = "path/to/foo.cert"
          key = "path/to/foo.key"
          insecureSkipVerify = true

    [entryPoints.http.proxyProtocol]
      insecure = true
      trustedIPs = ["10.10.10.1", "10.10.10.2"]

    [entryPoints.http.forwardedHeaders]
      trustedIPs = ["10.10.10.1", "10.10.10.2"]

YAML

entryPoints:
  http:
    address: ':80'
    whitelistSourceRange:
      - 10.42.0.0/16
      - 152.89.1.33/32
      - 'afed:be44::/16'
    compress: true
    tls:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_RSA_WITH_AES_256_GCM_SHA384
      certificates:
        - certFile: path/to/my.cert
          keyFile: path/to/my.key
        - certFile: path/to/other.cert
          keyFile: path/to/other.key
      clientCA:
        files:
          - path/to/ca1.crt
          - path/to/ca2.crt
        optional: false
    redirect:
      entryPoint: https
      regex: '^http://localhost/(.*)'
      replacement: 'http://mydomain/$1'
    auth:
      headerField: X-WebAuth-User
      basic:
        users:
          - 'test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/'
          - 'test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0'
        usersFile: /path/to/.htpasswd
      digest:
        users:
          - 'test:traefik:a2688e031edb4be6a3797f3882655c05'
          - 'test2:traefik:518845800f9e2bfb1f1f740ec24f074e'
        usersFile: /path/to/.htdigest
      forward:
        address: 'https://authserver.com/auth'
        trustForwardHeader: true
        tls:
          ca:
            - path/to/local.crt
          caOptional: true
          cert: path/to/foo.cert
          key: path/to/foo.key
          insecureSkipVerify: true
    proxyProtocol:
      insecure: true
      trustedIPs:
        - 10.10.10.1
        - 10.10.10.2
    forwardedHeaders:
      trustedIPs:
        - 10.10.10.1
        - 10.10.10.2

Output of traefik version: (What version of Traefik are you using?)

Version:      v1.5.3
Codename:     cancoillotte
Go version:   go1.9.4
Built:        2018-02-27_02:47:04PM
OS/Arch:      linux/amd64
@ldez ldez added status/0-needs-triage kind/proposal a proposal that needs to be discussed. and removed status/0-needs-triage labels Mar 11, 2018
@kinghuang
Copy link

Switching to YAML would also help reduce repetition when creating multiple frontends to handle differing routes (#3026). There's no equivalent to YAML anchors in TOML, which leads to a lot of repeated configuration.

@timoreimann
Copy link
Contributor

I see two general issues with YAML:

  1. For anything but simple (read: not deeply nested) configurations, it's very hard to maintain as a human due to its heavy reliance on indentation. Everyone who has worked with Kubernetes manifests knows this pain first hand. TOML traded in indentation for ordering needs, which to me makes it easier to manage.
  2. The format is pretty complex. TOML, on the other hand, only knows a handful of types.

In a nutshell: YAML is nicer to read, but TOML is easier to write.

From a technical perspective, I guess I'm okay with considering support if it's cheap to maintain. (That is, we can automatically and easily transform between the formats.)

From a end-user support perspective, I am somewhat concerned that YAML will open up a whole new dimension of headaches ("why is my configuration not working?" -- "you are missing an indent in line 43").

@kinghuang
Copy link

While TOML doesn't require indentation, I find a lot of TOML is indented anyways, because it can be hard to comprehend without it. All of Traefik's documentation shows indented TOML, for example.

Personally, I find TOML harder to write than YAML. YAML is definitely easier to read.

@gaui
Copy link
Author

gaui commented Mar 16, 2018

This is debatable, but the industry seems to have adopted it - so why shouldn't it be supported in Træfik?

@timoreimann Actually, I am a dev and I personally find it easier to read and write. I use an IDE with great YAML support. But I get your concern for the indentation problems on user-end but I think you should validate the config before using it - whether it's YAML or TOML.

@timoreimann
Copy link
Contributor

timoreimann commented Mar 18, 2018

@kinghuang

While TOML doesn't require indentation, I find a lot of TOML is indented anyways, because it can be hard to comprehend without it. All of Traefik's documentation shows indented TOML, for example.

Sure, we do that to improve readability, which indentation definitely helps with. Unlike YAML, however, I find that TOML makes it fairly easy to indent correctly as the explicitly required table specifiers provide the necessary scaffolding (at the price of added verbosity, no question). Furthermore, the cost of misaligning is just a minor cosmetic issue in TOML, whereas in YAML such a mistake can turn into an wrong configuration.

@gaui

Actually, I am a dev and I personally find it easier to read and write. I use an IDE with great YAML support. But I get your concern for the indentation problems on user-end but I think you should validate the config before using it - whether it's YAML or TOML.

I also use a plugin to assist with writing YAML. In fact, it's the only way for me to effectively write complex YAML files. I consider that to be a sign that the syntax and format is too complicated to be handled with simple editors. With TOML, I don't feel that pain.

Validating configurations in-code is a non-trivial problem. Strictly speaking, you'd have to treat every unknown configuration option as an error and report it to the user. Traefik doesn't do this at the moment -- instead, it tries hard to bootstrap into a somehow working mode. Whether that's desirable or not is debatable. But even if we had some kind of strict mode, I believe a broken YAML configuration is still harder to debug and get right, again based on my experience with working on Kubernetes manifests.

That said, I do understand the value for supporting a well-known format like YAML: a larger group is familiar with it, lots of tools exist, etc. TOML certainly isn't free of issues either -- the fact that any non-table option must go before the first table option has been a continuous source of end-user support questions ever since. So I'm not super opposed to the idea, I just think that it comes with a price we shouldn't underestimate when we make a decision.

@Johannestegner
Copy link

Maybe abstract the settings loader in a way that we could use either (or other types) through adapters? YAML, Toml, json and XML are all quite easy to convert to the same data output (not sure about toml, due to not being that used to it yet), and it's often more of a question of taste.
This would also make it easier for the devs to just implement the loader for toml and let us create our own loaders to plug in to the engine! ;)

@gaui
Copy link
Author

gaui commented Mar 22, 2018

One awesome pro with YAML: It has so called anchors which makes your config DRY.

@ldez
Copy link
Contributor

ldez commented Mar 22, 2018

Have the ability to repeat something can be useful for the dynamic configuration but it's not really useful for the static configuration.

With this PR #2991 (v1.6) you will be able to use Go Template syntax (functions, loops, variables, ...) in the TOML configuration (for the dynamic configuration).

@trondhindenes
Copy link

So much this. I don't understand how TOML has become as popular as it has. I'd love to see Traefik support both toml and yaml, these "dsl language arguments" never go anywhere constructive, there's always pros and cons.
For us as an Ansible/Kubernetes shop, we live in yaml. We have linters so we can test yaml configuration in CI for instance. But most importantly, we simply like and prefer yaml over toml.

@timoreimann
Copy link
Contributor

timoreimann commented Mar 30, 2018

@containous/traefik thoughts?

At least by looking at the number of thumbs up on the issue description, there seems to be a desire to support YAML.

@mrmachine
Copy link

I was excited to find out about traefik as a replacement for the deprecated dockercloud-haproxy, but the config examples in TOML immediately put me off big time. I personally find YAML is infinitely easier to read and write, even without any special linters. Although I'm a Python developer, so I'm used to indentation being important (and I think that's a good thing). And yes, everything is YAML these days. There's little to be gained by going against the grain on this one.

@slayer
Copy link

slayer commented Aug 23, 2018

Obviously TOML is harder to read and understand. [] and [[ ]] adds pits and mounds for eyes.

@DanielJoyce
Copy link

DanielJoyce commented Nov 7, 2018

go templates are overkill for something that yaml anchors fix trivially. Its an even more complicated solution than the yaml one. It's also not trivial to merge/compose some configuration in it. Those templates are even uglier and harder to use than yaml.

Traefik config is repetitive and ugly. Toml is intended for simple configurations like old school windows ini files, not emulating tree structures with dot seperated names. Also [[]] is ugly to look at and comprehend.

@DanielJoyce
Copy link

Put your confid in yaml, then convert with remarshal, a python util...

@ndeloof
Copy link

ndeloof commented Nov 30, 2018

relying on https://github.com/spf13/viper would allow to support both toml and yaml, + json, hcl, and even java properties (!)

@thewilli
Copy link

Any update on this? I hoped to find some additional labels / milestones associated with this issue when YAML support was mentioned in the v2 blog post:

grafik

@ldez ldez added this to To do in v2 via automation Mar 25, 2019
@olekukonko

This comment has been minimized.

@bbinet
Copy link
Contributor

bbinet commented Jun 20, 2019

Can we close this issue now that #4935 is merged?

@gaui gaui closed this as completed Jun 22, 2019
v2 automation moved this from To do to Done Jun 22, 2019
@ldez
Copy link
Contributor

ldez commented Jun 22, 2019

In fact Traefik don't really support YAML: current (alpha7) we only added YAML support for the static configuration, the dynamic configuration still use TOML only.

This is why we have not communicated on this subject, nor added documentation, nor closed the issue.

@ldez ldez reopened this Jun 22, 2019
v2 automation moved this from Done to To do Jun 22, 2019
@traefiker
Copy link
Contributor

Closed by #5024.

@traefiker traefiker added this to the 2.0 milestone Jun 26, 2019
v2 automation moved this from To do to Done Jun 26, 2019
@traefik traefik locked and limited conversation to collaborators Sep 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
kind/proposal a proposal that needs to be discussed. status/5-frozen-due-to-age
Projects
No open projects
v2
Done
Development

No branches or pull requests