Vamos falar sobre arquivos de configuração. Existem três formatos populares que vem sendo utilizados para este propósito, YAML, JSON e o caçula TOML.

O YAML e o JSON podem ser usados como arquivos de configuração, mas na realidade ambos são linguagens de serialização de dados. Eita, agora complicou. Não, nada disso, fiquem tranquilos, é só um nome complicado para um conceito bem simples.

Já o TOML como o próprio website deles especifica é na verdade um arquivo de configuração puro e simples.

Requisitos

Vamos estabelecer requisitos simples e básicos para escolhermos a linguagem do nosso arquivo de configuração.

  1. Simples de escrever
  2. Fácil de entender
  3. Amplamente utilizado

O requisito número 3 garante que não vamos perder tempo aprendendo uma linguagem que só vai ser utilizada em nosso programa. Queremos sempre otimizar nosso cérebro, não dá para saber tudo, portanto vale focar sempre naquela tecnologia que iremos reutilizar muitas e muitas vezes. Eu já selecionei três formatos que são amplamente utilizados em diversos sistemas, porém vale o requisito, pois ele pode servir como critério de desempate.

Com os requisitos estabelecidos vamos entender as especificações de cada linguagem e a partir daí vamos julgar cada uma delas.

Cada requisito vai ter uma pontuação de 0 até 5. Vamos à análise.

TOML

Vamos começar analisando a linguagem TOML, afinal ela foi criada exatamente para ser uma linguagem de configuração.

O TOML pretende ser um formato de arquivo de configuração mínimo, fácil de ler devido à semântica óbvia. TOML é projetado para mapear inequivocamente para uma tabela hash. O TOML deve ser fácil de analisar em estruturas de dados em uma ampla variedade de linguagens.

Veja que interessante, segundo seu criador, o TOML é projetado para ser um arquivo de configuração mínimo. Esta é uma característica muito importante, já que faz correspondência com um dos nossos requisitos: Simples de Escrever.

Aqueles que já possuem experiência com linguagens de programação ou administração de sistemas irão perceber que o arquivo TOML lembra bastante arquivos de configuração do tipo INI. Ou seja, cada seção do arquivo é separada utilizando um nome entre colchetes "[" e "]".

Vamos à um exemplo.

# This is a TOML document.

title = "TOML Example"

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates

[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

[servers]

  # Indentation (tabs and/or spaces) is allowed but not required
  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

[clients]
data = [ ["gamma", "delta"], [1, 2] ]

# Line breaks are OK when inside arrays
hosts = [
  "alpha",
  "omega"
]

Comentários

O arquivo de configuração do tipo TOML permite comentários e eles são escritos da mesma forma que na linguagem Python, utilizando a hashtag "#".

# isto é um comentário em arquivos TOML

Strings

Existem quatro maneiras de expressar strings na linguagem TOML: básico, básico com várias linhas, literal e literal com várias linhas. Todas as strings devem conter apenas caracteres UTF-8 válidos.

Strings básicas são colocadas entre aspas ("). Qualquer caractere Unicode pode ser usado, exceto aqueles que devem ser escapados: aspas por exemplo.

# String na linguagem TOML
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
str6 = """Aqui estão 15 aspas duplas: ""\"""\"""\"""\"""\"."""

Strings de Múltiplas Linhas

As strings literais de várias linhas são circundadas por três aspas simples em cada lado e permitem novas linhas. Como strings literais, não há escape de qualquer espécie. Uma nova linha imediatamente após o delimitador de abertura será cortada. Todos os outros conteúdos entre os delimitadores são interpretados como estão, sem modificação.

regex2 = '''I [dw]on't need \d{2} apples'''
lines  = '''
The first newline is
trimmed in raw strings.
   All other whitespace
   is preserved.
'''
quot15 = '''Aqui estão 15 aspas duplas: """""""""""""""'''

Números

Quando falamos de números, basicamente temos inteiros e números flutuantes. O TOML lida com números flutuantes seguindo uma especificação do IEEE, a IEEE 754. Ao implementar esta especificação, o TOML traz bastante vantagem, pois usa um padrão já utilizado em diversos outros contextos e também no meio científico.

Como exemplo, é muito comum a necessidade de tratar números exponenciais, muitas outras linguagens, como o YAML que veremos, não possui uma definição muito clara de como tratar esses números podendo causar diversas interpretações possíveis. Portanto, o tratamento de números pelo TOML é uma vantagem inerente desta linguagem.

[integer]
int1 = 100

[hexadecimal]
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef

[binary]
bin1 = 0b11010110

[octal]
oct1 = 0o01234567

[fractional]
flt1 = +1.0
flt2 = 3.1415
flt3 = -0.01

[exponent]
flt4 = 5e+22
flt5 = 1e06
flt6 = -2E-2
flt7 = 6.626e-34

Listas e Dicionários (Hash Tables)

Listas são colchetes com valores dentro. O espaço em branco é ignorado. Os elementos são separados por vírgulas. Os arrays podem conter valores dos mesmos tipos de dados permitidos nos pares chave / valor. Valores de diferentes tipos podem ser misturados.

integers = [ 1, 2, 3 ]
colors = [ "red", "yellow", "green" ]
nested_array_of_int = [ [ 1, 2 ], [3, 4, 5, "a"] ]
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c", 5] ]
string_array = [ "all", 'strings', """are the same""", '''type''' ]

Dicionários são coleções de pares de chave / valor. Eles aparecem entre colchetes em uma linha. Você pode diferenciá-los dos arrays porque os arrays são sempre valores.

[table-1]
key1 = "some string"
key2 = 123

[table-2]
key1 = "another string"
key2 = 456

[nested.dict]
key1 = "Sou uma chave que pertence a um dicionário chamado dict, aninhado em outro dicionário chamado nested."

O TOML usa chaves separadas por ponto (.) para declarar uma sequência de chaves vazias ou "unidas" por um ponto. Isso permite agrupar propriedades semelhantes:

physical.color = "orange"
physical.shape = "round"

Na minha opinião é nesta parte de dicionários que a linguagem TOML deixa a desejar. Entendo ser um pouco confuso olhar para um documento TOML e entender exatamente como isso vai ser mapeado em um dicionário Python ou um objeto em Javascript.

Popularidade

A linguagem TOML tem se tornado bastante popular, eu sinceramente não conhecia essa linguagem antes de começar a minha pesquisa para escrever este artigo. Porém TOML vs YAML têm causado boas discussões na comunidade dev.

Alguns casos de sucesso para o TOML é seu uso como arquivo de configuração adotado pela linguagem Rust, pela base de dados InfluxDB e mais recentemente pelo Python na PEP 518.

Avaliação Final

  1. Simples de Escrever

    Acredito que nesse quesito, o TOML fica com nota 4.5. O TOML é bastante simples de escrever, embora eu ainda tenha alguma dificuldade em me adaptar à escrever dicionários em TOML, razão pela nota não ser 5.

  2. Fácil de Entender

    Nesse quesito, entendo que a linguagem perde um pouco mais de ponto, de novo pela questão dos dicionários aninhados, que ao meu ver são mais complicados de entendermos com a sintaxe utilizada pelo TOML, por isso eu dou nota 4.

  3. Amplamente Utilizado

    Como vimos, o TOML vem ganhando tração em algumas linguagens populares como Python e Rust, mas ainda não tem uma popularidade muito grande. Conseguimos contar nos dedos (pés e mãos, mas ainda sim..) a quantidade de projetos que estão usando essa linguagem. Por esta razão, nota 3.

Quesito Nota
Simples de Escrever 4.5
Fácil de Entender 4
Amplamente Utilizado 3
Total 11.5

JSON

Vamos agora, analisar a linguagem JSON, a mais antiga dentre as três analisadas aqui.

JSON (JavaScript Object Notation - Notação de Objetos JavaScript) é uma formatação leve de troca de dados. Para seres humanos, é fácil de ler e escrever. Para máquinas, é fácil de interpretar e gerar.

Segundo a apresentação do time que mantém o JSON, está é uma linguagem simples de ler e escrever, bom eu tenho algumas ressalvas quanto à isso. O JSON depende de chaves "{" e "}" para delimitar objetos, objetos são sempre uma coleção de pares nome/valor onde o nome no JSON precisa estar sempre entre aspas duplas (").

Aqueles que já possuem experiência com Javascript vão ter bastante facilidade à se adaptar ao JSON, afinal o mesmo foi baseado no Javascript.

Vamos à um exemplo.

{
  "title": "JSON Example",
  "owner": {
    "name": "Douglas Crockford",
    "dob": "1979-05-27T15:32:00.000Z"
  },
  "database": {
    "server": "192.168.1.1",
    "ports": [
      8001,
      8001,
      8002
    ],
    "connection_max": 5000,
    "enabled": true
  },
  "servers": {
    "alpha": {
      "ip": "10.0.0.1",
      "dc": "eqdc10"
    },
    "beta": {
      "ip": "10.0.0.2",
      "dc": "eqdc10"
    }
  },
  "clients": {
    "data": [
      [
        "gamma",
        "delta"
      ],
      [
        1,
        2
      ]
    ],
    "hosts": [
      "alpha",
      "omega"
    ]
  }
}

Comentários

Infelizmente, os arquivos do tipo JSON não permitem comentários.

Talvez aqui seja um bom lugar para discutirmos e entendermos por que comentários são importantes.

Vamos escrever um arquivo de configuração e tentar deixá-lo o mais simples possível, porém as idéias e razões para escolhermos um esquema deste arquivo nunca estará 100% clara para pessoas que não sejam nós mesmas. Existem duas maneiras de esclarecer nossas decisões.

  1. Comentários no arquivo de configuração
  2. Documentação sobre o arquivo de configuração

Eu não sei vocês, mas eu não gostaria de escrever ainda outro documento apenas para explicar nosso arquivo de configuração. É muito mais fácil poder apenas adicionar comentários próximos aos parâmetros que definirmos, além do que esses comentários podem estar presentes apenas no arquivo de template.

O JSON sai perdendo neste quesito e isso tira ponto no critério 2, fácil de entender, pois sem comentários, pode ser difícil entender as razões por trás de um certo parâmetro ou até mesmo como ele vai ser utilizado.

Strings

Existe apenas uma maneira de expressar strings na linguagem JSON: básico.

Strings básicas são colocadas entre aspas ("). Qualquer caractere Unicode pode ser usado, exceto aqueles que devem ser escapados: aspas por exemplo.

{
  "str2": "I'm a string and I can be \"quoted\". Você pode acentuar, normalmente, é permitido.",
  "str3": "Aqui estão 5 aspas duplas: \"\"\"\"\".",
  "str": "Eu também sou uma string."
}

Strings de Múltiplas Linhas

As strings de várias linhas não existem no JSON. Para imitar o comportamento do TOML é preciso usar as quebras de linhas explicitamente utilizando (\n).

{
  "lines": "Este conjunto de caracteres\nvai aparecer exatamente\nneste formato\ncom quebra de linhas.\n",
  "one-liner": "Essa linha, apesar de estar quebrada em várias linhas, vai ser transformada em uma só linha."
}

Números

Quando falamos de números, basicamente temos inteiros e números flutuantes. O JSON lida com ambos e também suporta números exponenciais. A única observação que eu tenho é que o JSON não aceita que escrevamos um número em formato de string, por exemplo, o conteúdo JSON abaixo seria inválido.

{
    "invalid-number": "42",
    "valid-number": 42
}

Para números exponenciais, o JSON segue a mesma linha do TOML, permitindo uma descrição exatamente igual.

Abaixo vemos uma representação JSON do mesmo arquivo TOML que vimos anteriormente.

{
    "integer": {"int1": 100},
    "hexadecimal": {"hex1": "0xDEADBEEF",
                    "hex2": "0xdeadbeef"},
    "binary": {"bin1": "0b11010110"},
    "octal": {"oct1": "0o01234567"},
    "fractional": {
        "flt1": 1.0,
        "flt2": 3.1415,
        "flt3": -0.01
    },
    "exponent": {"flt4": 5e+22,
        "flt5": 1e06,
        "flt6": -2E-2,
        "flt7": 6.626e-34
    }
}

Listas e Dicionários (Hash Tables)

Listas são colchetes com valores dentro. O espaço em branco é ignorado. Os elementos são separados por vírgulas. Os arrays podem conter valores dos mesmos tipos de dados permitidos nos pares chave / valor. Valores de diferentes tipos podem ser misturados.

{
  "integers": [
    1,
    2,
    3
  ],
  "colors": [
    "red",
    "yellow",
    "green"
  ],
  "nested_array_of_int": [
    [
      1,
      2
    ],
    [
      3,
      4,
      5,
      "a"
    ]
  ],
  "nested_mixed_array": [
    [
      1,
      2
    ],
    [
      "a",
      "b",
      "c",
      5
    ]
  ],
  "string_array": [
    "all",
    "strings",
    "",
    "are the same",
    "",
    "",
    "type",
    ""
  ]
}

Dicionários são coleções de pares de chave / valor. Eles aparecem entre chaves "{" e "}". Eles podem ser aninhados em outros dicionários ou mesmo listas.

{
  "table-1": {
    "key1": "some string",
    "key2": 123
  },
  "table-2": {
    "key1": "another string",
    "key2": 456
  },
  "nested": {
    "dict": {
      "key1": "Sou uma chave que pertence a um dicionário chamado dict, aninhado em outro dicionário chamado nested."
    }
  }
}

Bem diferente do TOML, o JSON é mais verbose ou seja, precisamos gastar mais dedos no teclado para alcançar os mesmos objetivos.

Popularidade

A linguagem JSON é muito popular, utilizada por todas as APIs que utilizam o protocolo HTTP, e ainda mais popular com a vasta adoção do Javascript como linguagem de front-end e back-end (Node.js).

Sempre que buscar na Internet algum conversor de formato, tenha certeza que será possível converter pra JSON, pois é um formato tão comum que é implementado e serve de referência para tudo.

Avaliação Final

  1. Simples de Escrever

    Acredito que nesse quesito, o JSON fica com nota 3. O JSON não é de nenhum jeito simples de escrever, embora as regras sejam mínimas, escrever JSON requer um pouco de atenção com as chaves, mesmo utilizando uma IDE como VS Code. E bem, chaves podem se tornar complicadas.

  2. Fácil de Entender

    Nesse quesito, entendo que a linguagem é a pior entre as três. Novamente pela questão da sintaxe usando chaves para delimitar objetos e sem qualquer regra que defina um padrão visual, ao meu ver o JSON perde muito. Nota 2.

  3. Amplamente Utilizado

    Como vimos, o JSON é extremamente utilizado. Para onde olhamos, vemos JSON, até mesmo em plataformar como Kubernetes onde se escreve YAML para enviar as configurações para o sistema, primeiro o arquivo YAML é convertido para JSON. Portanto, sem sombra de dúvida, nota 5.

Só para provar meu ponto sobre as chaves, abaixo um arquivo JSON válido:

{"a": {"b": {"a": {"onde-estamos?": {"dificil-saber": true}}}}}
Quesito Nota
Simples de Escrever 3
Fácil de Entender 2
Amplamente Utilizado 5
Total 10

YAML

A linguagem YAML significa YAML Ain't Markup Language.

YAML é uma linguagem de serialização de dados amigável e padrão para todas as linguagens de programação.

Veja que interessante, diferente da linguagem TOML a linguagem YAML é projetada para ser uma linguagem de serialização, porém assim como no JSON isso não nos impede de a usarmos como uma linguagem de configuração também.

O YAML, tecnicamente é um superset do JSON, e isso significa que podemos sempre converter arquivos YAML para arquivos JSON e isso pode ser interessante se quisermos uma maneira melhor de escrever um arquivo de configuração antes de enviá-lo via rede, por exemplo.

Neste exemplo simples, escreveríamos nossa configuração em YAML e antes de enviar essa configuração via rede, usando HTTP por exemplo, poderíamos converter o arquivo para formato JSON que vai ter menos overhead, ou seja, economizará dados.

Aqueles que já possuem experiência com Kubernetes, Docker e até ANSIBLE já estarão mais do que acostumados a escreverem arquivos do tipo YAML.

Vamos à um exemplo.

# This is a YAML document.
title: YAML Example
owner:
    name:  Clark Evans
    dob: 1979-05-27T07:32:00-08:00 # First class dates
database:
    server: 192.168.1.1
    ports:
        - 8001
        - 8001
        - 8002
    connection_max: 5000
    enabled: true
servers:
    alpha:
        ip: 10.0.0.1
        dc: eqdc10
    beta:
        ip: 10.0.0.2
        dc: eqdc10
clients:
    data: [ ["gamma", "delta"], [1, 2] ]
    hosts:
        - alpha
        - omega

Comentários

O arquivo de configuração do tipo YAML permite comentários e eles são escritos da mesma forma que na linguagem Python, utilizando a hashtag "#".

# isto é um comentário em arquivos YAML

Aqui, assim como foi o caso da linguagem TOML é possível utilizar comentários no próprio arquivo YAML. Isto não só é recomendável, como também muito importante para que os usuários da nossa ferramenta possam entendê-la de maneira fácil e rápida sem precisar consultar uma documentação extra.

Strings

As strings YAML são Unicode. Na maioria das situações, você não precisa especificá-las entre aspas. Porém isso também é permitido. A string pode ser especificada tanto com aspas duplas (") quanto com aspas simples (').

# String na linguagem YAML
str2: I'm a string and I can be "quoted". Você pode acentuar, normalmente, é permitido.
str3: 'Aqui estão 5 aspas duplas: """"".'
str: "Eu também sou uma string."

Strings de Múltiplas Linhas

As strings de várias linhas são especificadas utilizando um caractere especial (|), também chamado de delimitador. Uma nova linha imediatamente após o delimitador de abertura será cortada. Todos os outros conteúdos entre os delimitadores são interpretados como estão, sem modificação.

Também é possível, como maneira de melhorar a leitura do arquivo YAML quebrar a string em várias linhas, mas ter a mesma, serializada como uma string de uma só linha. Para isso, basta usar o delimitador (>).

lines: |
    Este conjunto de caracteres
    vai aparecer exatamente
    neste formato
    com quebra de linhas.
one-liner: >
    Essa linha, apesar de estar
    quebrada em várias linhas,
    vai ser transformada em uma só
    linha.

Números

O YAML lida com os números inteiros, flutuantes e exponenciais, assim como o TOML e o JSON, porém a especificação para números exponenciais não é tão boa quanto à do TOML por exemplo. No exemplo abaixo, apesar do intuito ser tratar ambos os números como flutuantes, o YAML irá tratar o primeiro como string.

"exp-number-treated-as-string": -2E-2,
"exp-number": -2.0e-2

Abaixo vemos uma representação YAML do mesmo arquivo TOML e JSON que vimos anteriormente.

integer:
  int1: 100
hexadecimal:
  hex1: 0xDEADBEEF
  hex2: 0xdeadbeef
binary:
  bin1: 0b11010110
octal:
  oct1: 0o01234567
fractional:
  flt1: 1
  flt2: 3.1415
  flt3: -0.01
exponent:
  flt4: 5.0e+22
  flt5: 1.0e+6
  flt6: -2.0e-2
  flt7: 6.626e-34

Listas e Dicionários (Hash Tables)

Listas são colchetes com valores dentro. O espaço em branco é ignorado. Os elementos são separados por vírgulas. Os arrays podem conter valores dos mesmos tipos de dados permitidos nos pares chave / valor. Valores de diferentes tipos podem ser misturados.

Uma outra maneira de escrever listas em YAML é utilizando o delimitador (-).

integers:
- 1
- 2
- 3
colors:
- red
- yellow
- green
nested_array_of_int:
- - 1
  - 2
- - 3
  - 4
  - 5
  - a
nested_mixed_array:
- - 1
  - 2
- [a, b, c, 5]
string_array:
- all
- strings
- ''
- are the same
- ''
- ''
- type
- ''
normal_array: [1,2,3]

Dicionários são coleções de pares de chave / valor. Eles aparecem entre chaves "{" e "}". Eles podem ser aninhados em outros dicionários ou mesmo listas.

table-1:
  key1: some string
  key2: 123
table-2:
  key1: another string
  key2: 456
nested:
  dict:
    key1: Sou uma chave que pertence a um dicionário chamado dict, aninhado em outro
      dicionário chamado nested.
other_rep: {dict: "quando escrito assim, toda string precisa estar entre aspas"}

Bem diferente do TOML e do JSON, o YAML trabalha com o conceito de identação obrigatória, inspirado principalmente pela linguagem Python. Pode ser um pouco ruim para escrever, mas qualquer IDE suporta identação automática do YAML. A vantagem é que ler um arquivo YAML fica mais simples, pois é possível reconhecer esse padrão visual causado pelo aninhamento de valores.

Popularidade

A linguagem YAML é muito popular, utilizada em diversas ferramentas, tal como ANSIBLE, Kubernetes, Docker.

Se o uso de YAML no Kubernetes não te convenceu, eu não sei o que mais te convenceria. YAML com certeza já é tão popular quanto o JSON.

Avaliação Final

  1. Simples de Escrever

    Acredito que nesse quesito, o YAML fica com nota 4. O YAML é bem simples de escrever, embora as regras desta linguagem sejam extensas. Para efeito de comparação, a especificação YAML possui mais de 23 mil palavras, enquanto a do TOML possui pouco mais de 3 mil. De qualquer maneira, o YAML pode ser simples de escrever, pois dificilmente vamos utilizar todas as funcionalidades que a linguagem nos proporciona.

  2. Fácil de Entender

    Nesse quesito, entendo que a linguagem é a melhor entre as três. Novamente pela questão da identação. Nós, seres humanos, procuramos padrões visuais em tudo e identação é um forte padrão visual, facilmente identificável por nós. Por esta razão, dou nota 5 ao YAML. Pode me chamar de enviesado por gostar de Python, mas identação por padrão é o melhor jeito de formatar qualquer arquivo texto.

  3. Amplamente Utilizado

    Como vimos, o YAML é extremamente utilizado. Para onde olhamos, vemos YAML, o destaque, claro, vai para seu uso nas plataformas como Kubernetes e Docker. Portanto, sem sombra de dúvida, nota 5.

Quesito Nota
Simples de Escrever 4
Fácil de Entender 5
Amplamente Utilizado 5
Total 14

O Veredito

Como vimos, o YAML na minha opinião é a melhor linguagem para escrevemos nossas configurações. Bom, não exatamente nossa configuração, mas os parâmetros que vamos passar para o programa (que ainda vamos desenvolver) escrever a configuração.

O único quesito onde o YAML perdeu ponto foi no "Simples de Escrever", isso se deve ao fato de sua documentação ser extensa e possuir diversas funcionalidades como aliases que não vou nem começar a explicar.

O JSON é muito famoso, mas extremamente difícil de entender por falta de padrão visual. O TOML é muito promissor, gostaria que houvesse um jeito melhor de escrever dicionários no TOML, talvez isso alinhado à um pouco mais de popularidade fizesse essa linguagem se tornar vencedora.

Talvez você discorde e prefira outra linguagem que eu nem mencionei. Tudo bem, como provocação, abaixo seguem lado a lado, a mesma configuração em JSON, TOML e YAML.

Corre lá no twitter e me conta qual você prefere!

@castromonteiro

JSON TOML YAML

{
  "owner": {
    "name": "Leonardo Monteiro",
    "dob": "25-09-2020"
  },
  "database": {
    "server": "192.168.1.1",
    "ports": [
      8001,
      8001,
      8002
    ],
    "connection_max": 5000,
    "enabled": true
  },
  "servers": {
    "alpha": {
      "ip": "10.0.0.1",
      "dc": "eqdc10"
    },
    "beta": {
      "ip": "10.0.0.2",
      "dc": "eqdc10"
    }
  },
  "clients": {
    "data": [
      [
        "gamma",
        "delta"
      ],
      [
        1,
        2
      ]
    ],
    "hosts": [
      "alpha",
      "omega"
    ]
  }
}
[owner]
name = "Leonardo Monteiro"
dob = "25-09-2020"

[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

[servers]

[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"

[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"

[clients]

data = [ ["gamma", "delta"], [1, 2] ]
hosts = [
  "alpha",
  "omega"
]
owner:
  name: Leonardo Monteiro
  date: '25-09-2020'
database:
  server: 192.168.1.1
  ports:
  - 8001
  - 8001
  - 8002
  connection_max: 5000
  enabled: true
servers:
  alpha:
    ip: 10.0.0.1
    dc: eqdc10
  beta:
    ip: 10.0.0.2
    dc: eqdc10
clients:
  data:
  - - gamma
    - delta
  - - 1
    - 2
  hosts:
  - alpha
  - omega