Say, I want to dynamically edit a Kubernetes deployment file that looks like this using Python:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 4
selector:
matchLabels:
app: guestbook
tier: frontend
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- env:
- name: GET_HOSTS_FROM
value: dns
image: gcr.io/google-samples/gb-frontend:v4
name: php-redis
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 100Mi
I have a code that opens this yaml file where I want to change the content of spec.replicas branch from 2 to 4:
with open(deployment_yaml_full_path, "r") as stream:
try:
deployment = yaml.safe_load(stream)
if value_to_change[0] == 'spec.replicas':
deployment['spec']['replicas'] = value_to_change[1]
except yaml.YAMLError as exc:
logger.error('There was a problem opening a deployment file in path: ',
deployment_yaml_full_path=deployment_yaml_full_path, exc=exc)
I would like to know if there’s a way to avoid the hardcoded part here to something more dynamic:
if value_to_change[0] == 'spec.replicas':
deployment['spec']['replicas'] = value_to_change[1]
Is there a way?
4
Answers
If the paths can be longer:
I believe you want to change the YAML to JSON/dictionary using
PyYaml
After that you would like to use:
Usage Example:
The last phase will be to change the value by string path:
I think the correct way to do what you want is to study json path, there is an easy example here and this stupid answer of mine could help you create the actual json path expressions!
Well, this is the one-liner you should NOT use to achieve what you want in the most dynamic way possible:
We create a list from the
value_to_change[0]
value splitting by dot.We get each
val
in this list end we enclose it in "dictionary" syntax (hashtags.. well they can be anything you want, but f-strings do not support backslashes, hence I replace hashtags with the quotes after)We
join
the vals in astring
andreplace
the hashtags and add thedeployment
stringThe result will be this string… (what you would normally write to change that value):
We perform actual monstrosity executing the string.
In my example
value_to_change[1]
is50
Have FUN!
The json path solution is like this
You just need
parse
function fromjsonpath_ng
library (pip install jsonpath_ng)When you check with find you will see a lot of output, just focus on the first part:
As you can see the expression is really easy:
"$.path.to.value.you.want"
If you wonder how to manage
list
inside, the syntax is the same as python[]
, with inside the index, or*
to say all the items in the list (and this is priceless!!)This is a very good place to learn everything you need!