I have a YAML file with the content below:
job_name: "node"
scrape_interval: "15s"
static_configs:
- targets: ['10.10.10.11:8080']
now if I execute my python script it should append target line in YAML file using given arguments
i.e script.py -ip 10.10.20.30 -p 8181
file should look like this
job_name: "node"
scrape_interval: "15s"
static_configs:
- targets: ['10.10.10.11:8080', '10.10.20.30:8181']
for this I am using the python script below, but it's giving errors:
#!/usr/bin/python
import os
import yaml
with open('test.yaml', 'ra') as f:
lines = f.readlines()
for i, line in enumerate(lines):
if line.startswith('targets:'):
line[i] = line[i].strip() + 'arg1,arg2\n'
f.seek(0)
for line in lines:
f.write(line)
How can I fix this?
You are importing os, yaml (i.e. PyYAML) but you are not using those packages.
You also try to "edit" the YAML file as if it is unstructured text, and you should not. Instead you should load the YAML file, then extend the data structure that you get and then dump the data structure back to the YAML file, but not with PyYAML as that doesn't support this kind of round-tripping without losing information.
Instead use ruamel.yaml (disclaimer: I am the author of that package):
from ruamel.yaml import YAML
yaml = YAML()
yaml.preserve_quotes = True
yaml.indent = 5
yaml.block_seq_indent = 2
ip = '10.10.20.30' # sys.argv[2]
port = 8181 # sys.argv[4]
with open('test.yaml') as f:
data = yaml.load(f)
targets = data['static_configs'][0]['targets']
targets.append(type(targets[0])(str(ip) + ':' + str(port)))
with open('test.yaml', 'w') as fo:
yaml.dump(data, fo)
Which will write:
job_name: "node"
scrape_interval: "15s"
static_configs:
- targets: ['10.10.10.11:8080', '10.10.20.30:8181']
Setting attributes preserve_quotes, indent, block_seq_indent is only needed to get the output to match your input. So is the copying of the type
of the first targets element. Actually none of the quotes in your file are needed.
If a more default YAML output file, which will load to the same data, is ok with you can do:
from ruamel.yaml import YAML
yaml = YAML()
ip = '10.10.20.30' # sys.argv[2]
port = 8181 # sys.argv[4]
with open('test.yaml') as f:
data = yaml.load(f)
data['static_configs'][0]['targets'].append(str(ip) + ':' + str(port))
with open('test.yaml', 'w') as fo:
yaml.dump(data, fo)
Please note that both the key order in multiple entry mappings, as well as any comments in your YAML file would be preserved by the above round-tripping.
You would of course still have to get the IP and port from the commandline, and concatenate the values instead of hard coding the ip and port values. I suggest using the standard python module argparse for that, but beware that most applications only take long options with double dashes (--ip instead of -ip)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With