What is indexed array in YAML? - yaml

In my yaml spring-boot application config I have
additional-properties[auto.register.schemas]: false
additional-properties[use.latest.version]: true
and it works! I haven't found this syntax in the YAML specification. What does it mean? How can it be re-written using standard YAML? Is this the same as
additional-properties:
- auto.register.schemas: false
- use.latest.version: true
?

AFAIK:
Every element (separated by a dot) has to be on its own line and tabed accordingly.
foo:
bar:
name: value
name2: value2
fez: value
So your example would be:
additional-properties:
auto:
register:
schemas: false

After experimenting and after finding this answer, I conclude that (at least in Spring application.yaml):
camel.component.kafka:
additional-properties[auto.register.schemas]: false
additional-properties[use.latest.version]: true
is equivalent to
camel.component.kafka.additional-properties:
"[auto.register.schemas]": false
"[use.latest.version]": true
and this is equivalent to
camel:
component:
kafka:
additional-properties:
"[auto.register.schemas]": false
"[use.latest.version]": true

Related

Rundeck parse option based on another option value

I need rundeck to parse an option based on the value selected in another option. I have an option ${option.env} and other options like ${option.id_dev}, ${option.id_qa}
I want to achieve something like below for extra-vars, so that "env" option value determines which id(dev or qa) to read.
ansible-playbook /build.yml -e id=${option.id_${option.env.value}}
Is this possible or Could I pass extra-vars like a conditional case based on env value ?. I'm using rundeck 3.0.X
Update :
To give clear info, If I select 'dev' for the option 'env', I need to use its value like ${option.id_${option.env.value}} , so it translates to ${option.id_dev} to get other option in the command line
You can use cascade remote options in a tricky way. The explanation is at the end of this answer.
I made a little example to see how to achieve this:
The branches.json file (referenced on the job options as "branches"):
[
{"name":"branch1", "value":"branch1.json"},
{"name":"branch2", "value":"branch2.json"},
{"name":"branch3", "value":"branch3.json"}
]
The branch1.json is the first tentative value of the branches option:
[
{"name":"v1", "value":"1"},
{"name":"v2", "value":"2"},
{"name":"v3", "value":"3"}
]
The branch2.json is the second tentative value of the branches option:
[
{"name":"v4", "value":"4"},
{"name":"v5", "value":"5"},
{"name":"v6", "value":"6"}
]
The branch3.json is the third tentative value of the branches option:
[
{"name":"v7", "value":"7"},
{"name":"v8", "value":"8"},
{"name":"v9", "value":"9"}
]
Full job definition to test:
- defaultTab: summary
description: ''
executionEnabled: true
id: ed0d84fe-135b-41ee-95b6-6daeaa94894b
loglevel: INFO
name: CascadeTEST
nodeFilterEditable: false
options:
- enforced: true
name: branches
valuesUrl: file:/Users/myuser/branches.json
- enforced: true
name: level2
valuesUrl: file:/Users/myuser/${option.branches.value}
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- fileExtension: .sh
interpreterArgsQuoted: false
script: |+
#!/bin/sh
# getting the options
first=#option.branches#
second=#option.level2#
# this just an example
echo "this an example: ${first%%.*}.$second"
scriptInterpreter: /bin/bash
keepgoing: false
strategy: node-first
uuid: ed0d84fe-135b-41ee-95b6-6daeaa94894b
Explanation
As you see, the value of the first option is always a file name, if you take the value directly you always obtain an "option1.json" like string, so, the trick here is to cut the file extension and take only the name as the value, for that, I used this approach.
So, with the first selection value and the second one, you can do anything later in a script, for example, launch the ansible-playbook command in the inline script.
Check the example result.
UPDATED ANSWER:
The closest way is just using two options and concatenating them in the command step but isn't possible to get the option value inside the other one as you say.
Just like this:
- defaultTab: nodes
description: ''
executionEnabled: true
id: 4e8df698-c7ca-4a10-9f70-bc68c1007a10
loglevel: INFO
name: NewJob
nodeFilterEditable: false
options:
- enforced: true
name: env
value: qa
values:
- qa
- prod
- stage
valuesListDelimiter: ','
- enforced: true
name: id_dev
value: '1'
values:
- '1'
- '2'
- '3'
valuesListDelimiter: ','
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- exec: echo ${option.env}_${option.id_dev}
keepgoing: false
strategy: node-first
uuid: 4e8df698-c7ca-4a10-9f70-bc68c1007a10
Result.
(the cascade option is another approach)

Yaml - how to write mapping(s) in single line

I have the following yaml.
version: "0.1"
services:
svc:
image: test
networks:
- test_net_1
- test_net_2
- test_net_3
networkMapping:
test_net_1:
external: true
test_net_2:
external: true
test_net_3:
external: true
I would like to rewrite the networkMapping in a single line like the following
version: "0.2"
services:
svc:
image: test
networks: ['test_net_1', 'test_net_2', 'test_net_3']
networkMapping: {{'test_net_1': {'external': true}}, {'test_net_2': {'external': true}}, {'test_net_3': {'external': true}}}
but when on lint/parse it returns like this
version: "0.2"
services:
svc:
image: test
networks:
- test_net_1
- test_net_2
- test_net_3
networkMapping:
?
test_net_1':
external: true
: ~
?
test_net_2:
external: true
: ~
?
test_net_3:
external: true
: ~
and it cause error in app 'invalid map key: map[interface {}]interface {}{"test_net_1":map[interface {}]interface {}{"external":true}}'.
I checked with double instead of single quotes and without quotes too. But no luck :(.
We can change to to associate array by replacing first and last {} with [] but the app need it as mapping rather than associate array.
Just wondering if anyone had similar problem and any solution?
many thanks in advance.
You use too many {}. This is how you should write it:
networkMapping: {'test_net_1': {'external': true}, 'test_net_2': {'external': true}, 'test_net_3': {'external': true}}

how to take duplicate configurations out in filebeat.yaml

I have a list of inputs in filebeat, for example
- path: /xxx/xx.log
enabled: true
type: log
fields:
topic: topic_1
- path: /xxx/ss.log
enabled: true
type: log
fields:
topic: topic_2
so can I take the duplicate configs out as a reference variable? for example
- path: /xxx/xx.log
${vars}
fields:
topic: topic_1
- path: /xxx/ss.log
${vars}
fields:
topic: topic_2
You can use YAML's inheritance : your first input is used as a model, and the others can override parameters.
- &default-log
path: /xxx/xx.log
enabled: true
type: log
fields:
topic: topic_1
- <<: *default-log
path: /xxx/ss.log
fields:
topic: topic_2
AFAIK there is no way to define an "abstract" default, meaning your &default-log should be one of your inputs (not just an abstract model).
(YAML syntax verified with YAMLlint)

How to generate configuration for combination of multiple environments and mutations

I'm trying to use gomplate as a generator of configuration. The problem I'm facing now is having multiple mutations and environments where the application needs to be configured in a different way. I'd like to achieve some user-friendly and readable way with the least possible repetitions in the template and source data.
The motivation behind this is to have generated source data app_config which can be used in a following gomplate as following:
feature_a={{ index (datasource "app_config").features.feature_a .Env.APP_MUTATION .Env.ENV_NAME | required }}
feature_b={{ index (datasource "app_config").features.feature_b .Env.APP_MUTATION .Env.ENV_NAME | required }}
Basically I'd like to have this source data
features:
feature_a:
~: true
feature_b:
mut_a:
~: false
dev: true
test: true
mut_b:
~: true
converted into this result (used as app_config gomplate datasource)
features:
feature_a:
mut_a:
dev: true
test: true
load: true
staging: true
prod: true
mut_b:
dev: true
test: true
load: true
staging: true
prod: true
feature_b:
mut_a:
dev: true
test: true
load: false
staging: false
prod: false
mut_b:
dev: true
test: true
load: true
staging: true
prod: true
given that datasource platform is defined as
mutations:
- mut_a
- mut_b
environments:
- dev
- test
- load
- staging
- prod
I chose to use the ~ to state that every environment or mutation that is not defined will get the value behind ~.
This should work under assumption that the lowest level is environment and the level before the lowest is mutation. Unless environments are not defined, in that case mutation level is lowest and applies for all mutations and environments. However I know this brings extra complexity, so I'm wiling to use simplified variant where mutations are always defined:
features:
feature_a:
mut_a: true
mut_b: true
feature_b:
mut_a:
~: false
dev: true
test: true
mut_b:
~: true
However, since I'm fairly new to gomplate, I'm not sure whether it is the right tool for the job.
I welcome every feedback.
After further investigation I decided that this issue will be better solved with separate tool.

Duplicate key in YAML configuaration file

I have the following in YAML:
key1
key2: "value"
key1
key2
key3: "value2"
Get exception duplicate key key1.
Caused by: org.yaml.snakeyaml.parser.ParserException: while parsing MappingNode
Tried various combinations but was unable to parse it correctly.
Your YAML is syntactically invalid, but I am assuming it actually looks like this:
key1:
key2: "value"
key1:
key2:
key3: "value2"
Your error is that key1 is used two times as mapping key in the root node. This is illegal as per YAML spec:
The content of a mapping node is an unordered set of key: value node pairs, with the restriction that each of the keys is unique.
The solution is to make all keys of the same mapping unique:
key11:
key2: "value"
key12:
key2:
key3: "value2"
I too faced the same issue. Then it struck on me! The answer is simple.
From
mapping:
refresh:
schedule:
frequency:
milli: 86400000
mapping:
refresh:
schedule:
initial:
delay:
ms: 30000
to
mapping:
refresh:
schedule:
frequency:
milli: 86400000
initial:
delay:
ms: 30000
so below simple solution worked for me.
Basically, in the first scenario 'server' keyword came as a separate structure
in the 2d scenario 'server' keyword came as child structure.
I simply did a small indentation and it worked.
Before :->
server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false
server :
waitTimeInMsWhenSyncEmpty: false
After :->
server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false
server :
waitTimeInMsWhenSyncEmpty: false
You may fix it like this:
key1
key2: "value"
key2.key3: "value2"

Resources