I use vscode as an editor and have several yaml files in the project where parameter replacement occurs. However, it re-formats only one file with extra spaces between brackets, a file named service.yaml used by helm in our ci/cd pipeline. See below for before and after.
and after
I was wondering if the name of the file has particular significance for vscode or any other extensions... Thanks.
Uncheck Bracket Spacing in Extensions/YAML.
Edit: There is a caveat. This will format {{ foo }} or { { foo } } to {{foo}}, which is not necessarily syntactically correct in terms of Jinja templating.
One of the way how to resolve this issue - wrap values into the quotes.
Like this:
app: "{{ .Values.name }}"
Probably not the best solution, but it works for me.
I have the following chart:
deployment:
envVars:
- name: FIRST
value: first
- name: SECOND
value: second
I would like to append an extra name/value pair to the chart via the --set command in Helm.
The documentation at https://github.com/helm/helm/blob/master/docs/using_helm.md#the-format-and-limitations-of---set doesn't seem to help me.
I've tried to pass --set deployment.envVars[0].name=APPEND,deployment.envVars[0].value=yes but it says no matches found.
Using Helm 2.10.
Any suggestion?
Try escape square brackets [] with backslash \ in your command, like this --set deployment.envVars\[0\].name=APPEND,deployment.envVars\[0\].value=yes.
In ZSH, this should do it:
helm [...] --set 'ingress.annotations.nginx\.ingress\.kubernetes\.io\/proxy-body-size'=8m
Make sure to properly escape all slashes and dots which aren't object nesting level delimiters in the actual keys of the map, to avoid improper rendering.
Let's say there is a config.xml file outside the chart directory. Can this file be copied to a directory inside the container?
If its inside the chart directory, its pretty easy to use configMap as in
{{ (tpl (.Files.Glob "myconf/*").AsConfig . ) | indent 2 }}
Since the file is outside chart directory its not supported in helm2(although there is some talk of supporting in helm3).
Thought of putting as in
key: |
<tag>abc</tag>
Then read in the configMap and put as file.
Is there any elgant way to do it?
Yes. All examples I see until now use this way.
I have YAML find and replace value with correct YAML format (with space and quote). Below Sample YAML, I am able to replace jdbcUrl value using below Sed command. But, need help how to prefix a space and quote of the value using Sed.
Below Sed will find and replace a required jdbcUrl. But, it won't prefix a space (YAML standard) and add quote of the value.
Script for find and replace URL:
DB_URL='jdbc:mysql://localhost:3306/sd?autoReconnect=true'
sed -i -e 's, MYDATABASE,'$DB_URL',g' input.yaml
Sample Input Yaml:
- name: AP_DB
description: "datasource"
jndiConfig:
name: jdbc/AP_DB
definition:
type: RDBMS
configuration:
jdbcUrl: MYDATABASE
username: username
password: password
driverClassName: com.mysql.jdbc.Driver
Required Output Yaml:
- name: AP_DB
description: "datasource"
jndiConfig:
name: jdbc/AP_DB
definition:
type: RDBMS
configuration:
jdbcUrl: 'jdbc:mysql://localhost:3306/sd?autoReconnect=true'
username: username
password: password
driverClassName: com.mysql.jdbc.Driver
You seem to have few misconceptions that seem to hinder you from solving this:
Your input file is invalid YAML and the replacement of MYDATABASE is not going to fix that. You cannot have a scalar value for name and a mapping (starting with key description) at the same time. I assume that your file would need to look like:
- name: AP_DB
description: "datasource"
jndiConfig:
name: jdbc/AP_DB
definition:
type: RDBMS
configuration:
jdbcUrl: MYDATABASE
username: username
password: password
driverClassName: com.mysql.jdbc.Driver
Adding quotes to the value assigned to DB_URL in the shell doesn't make a difference
you are not using the shell, but sed to make the changes. Your shell is just used to invoke sed
You invoke sed with -i which overwrites your input.yaml, that makes it difficult to see if the output is correct, and you need to roll-back your changes
The space is not a prefix, it is the whitespace that normally needs to followi YAML's value indicator (:)
You match that space in your matching pattern, but you don't have it in your substitution pattern, nor are there any quotes in the substitution pattern. You probably think there are surrounding $DB_URL, but of course they are not.
The quotes around the URL in your output are superfluous
If you really want the output as you indicate there are several options. First of all you could just change the relevant line in your YAML to include the quotes
jdbcUrl: 'MYDATABASE'
and slightly change your sed command:
sed -e 's,MYDATABASE,'$DB_URL',g' < input.yaml
If you cannot change the input.yaml, you can just add the quotes (and the space) to the sed substitution:
sed -e 's, MYDATABASE, "'$DB_URL'",g' < input.yaml
Or not use the single quotes, and concacatenate a prefix and postfix to $DB_URL but use double quotes, which do allow $DB_URL to be expanded:
sed -e "s, MYDATABASE, '$DB_URL',g" < input.yaml
Once you verify that any of these solutions work you can re-add the inplace replacment option -i to sed.
sed is not the right kind of tool for this, especially not because you seem unfamiliar with it and with YAML. Use a proper YAML parser to do these kind of things. They tend to keep working when simple pattern matching no longer gets the job done. And the parser's dumping mechanism knows when to insert quotes instead of dumbly inserting them when they are not needed. A parser would also indicate that your input is invalid YAML right from the start.
It is bit more code to do this e.g. in Python, but at least it only matches mapping values that are exactly your substitution string, and doesn't try to do substitutions on keys, sequence items, within YAML comments, or on mapping values like ORIG_MYDATABASE, if these happen to be in the file. Preventing that from happening using sed can be quite a challenge.
Such a Python program could look like subst.py:
import sys
from pathlib import Path
from ruamel.yaml import YAML
val = sys.argv[1]
subst = sys.argv[2]
file_name = Path(sys.argv[3])
def update(d, val, sub):
if isinstance(d, dict):
for k in d:
v = d[k]
if v == val:
d[k] = sub
else:
update(v, val, sub)
elif isinstance(d, list):
for item in d:
update(item, val, sub)
yaml = YAML()
yaml.preserve_quotes = True # to preserve superfluous quotes in the input
data = yaml.load(file_name)
update(data, val, subst)
yaml.dump(data, file_name)
and be invoked from the shell, just like sed would have to be, by using:
python subst.py MYDATABASE $DB_URL input.yaml
Of course there will be no quotes in the output around the URL, as they are superfluous and not in the input file, but the superfluous quotes around datasource are preserved.
Here's a more automated way to change a "key : new value", in your yaml file:
yaml_file="input.yaml"
key="jdbcUrl"
new_value="'jdbc:mysql://localhost:3306/sd?autoReconnect=true'"
sed -r "s/^(\s*${key}\s*:\s*).*/\1${new_value}/" -i "$yaml_file"
I've got problem with one of ansible playbooks (enrise.postgresql).
It accepts variable postgresql_listen_addresses (list of values to listen_addresses in /etc/postgresql/9.3/main/postgresql.conf).
I want to use value ansible_default_ipv4.address, but ansible provide it without quotes, and postgress wants it with single quotes (like '192.168.0.1').
I have variable like this:
postgresql_listen_addresses: '{{ [ ansible_default_ipv4.address ] }}'
When address is without quotes, postgress complains about unquoted IP address (syntax error).
How can I add quotes around value of ansible_default_ipv4.address?
Thanks.
UPD:
I was able to solve it with this ugly code. If someone can better, please help.
print_quotes: "'%s'"
postgresql_listen_addresses: [ "{{print_quotes|format(ansible_default_ipv4.address) }}"
You can also use the quote filter:
postgresql_listen_addresses: "{{ ansible_default_ipv4.address | quote }}"
See Playbooks Filters.
Did you already try this?
postgresql_listen_addresses: "[ '{{ansible_default_ipv4.address}}' ]"
or this if postgress expects double quotes instead of single.
postgresql_listen_addresses: '[ "{{ansible_default_ipv4.address}}" ]'
I have no simple way of testing so I only have hope to support the theory... :-)