update-json-file: add role to combine values into a .json

Ansible doens't really have a great built-in way to modify a json file
(unlike ini files).  The extant docker role does what seems to be the
usual standard, which is slurp in the file, parse it and then write it
back out.

In a follow-on change (I338616c41a65b007d56648fdab6da2a6a6b909f4) we
need to set some more values in the docker configuration .json file,
which made me think it's generic enough that we can have a role to
basically run read the file, |combine and write it back out.

This adds such a role with various options, and converts the existing
json configuration update in ensure-docker to use it.

Change-Id: I155a409945e0175249cf2dc630b839c7a97fb452
This commit is contained in:
Ian Wienand 2020-08-19 15:26:58 +10:00
parent a086fb4333
commit 0b9fad9583
7 changed files with 146 additions and 26 deletions

View File

@ -45,6 +45,7 @@ General Purpose Roles
.. zuul:autorole:: start-zuul-console .. zuul:autorole:: start-zuul-console
.. zuul:autorole:: test-setup .. zuul:autorole:: test-setup
.. zuul:autorole:: trigger-readthedocs .. zuul:autorole:: trigger-readthedocs
.. zuul:autorole:: update-json-file
.. zuul:autorole:: upload-artifactory .. zuul:autorole:: upload-artifactory
.. zuul:autorole:: upload-git-mirror .. zuul:autorole:: upload-git-mirror
.. zuul:autorole:: validate-dco-license .. zuul:autorole:: validate-dco-license

View File

@ -15,34 +15,14 @@
- name: Update docker daemon configuration - name: Update docker daemon configuration
when: docker_userland_proxy is defined when: docker_userland_proxy is defined
block: block:
- name: Check if docker daemon configuration exists - name: Add proxy config
stat: include_role:
path: /etc/docker/daemon.json name: update-json-file
register: docker_config_stat
- name: Load docker daemon configuration
when: docker_config_stat.stat.exists
slurp:
path: /etc/docker/daemon.json
register: docker_config
- name: Parse docker daemon configuration
when: docker_config_stat.stat.exists
set_fact:
docker_config: "{{ docker_config.content | b64decode | from_json }}"
- name: Set default docker daemon configuration
when: not docker_config_stat.stat.exists
set_fact:
docker_config: {}
- name: Add registry to docker daemon configuration
vars: vars:
new_config: update_json_file_name: /etc/docker/daemon.json
update_json_file_combine:
userland-proxy: "{{ docker_userland_proxy }}" userland-proxy: "{{ docker_userland_proxy }}"
set_fact: update_json_file_become: true
docker_config: "{{ docker_config | combine(new_config) }}"
- name: Save docker daemon configuration
copy:
content: "{{ docker_config | to_nice_json }}"
dest: /etc/docker/daemon.json
become: true
- name: Reset ssh connection to pick up docker group - name: Reset ssh connection to pick up docker group
meta: reset_connection meta: reset_connection

View File

@ -0,0 +1,48 @@
Update JSON file
This role reads a JSON file, merges it with supplied values using
Ansible's ``combine`` filter and writes it back out. It is useful for
updating configuration files. Note this role is not currently
idempotent and will write the file each time.
**Role Variables**
.. zuul:rolevar:: update_json_file_name
:type: path
The path to the file to edit.
.. zuul:rolevar:: update_json_file_combine
:type: object
The data to be combined with the existing file data. This uses the
Jinja ``combine`` filter.
.. zuul:rolevar:: update_json_file_debug
:default: false
:type: bool
If enabled, output the combined result in a debug task.
.. zuul:rolevar:: update_json_file_default
:default: {}
The default value if the given file does not exist.
.. zuul:rolevar:: update_json_file_become
:type: bool
:default: false
The ``become:`` status when writing out the new file.
.. zuul:rolevar:: update_json_file_mode
The mode for the combined file.
.. zuul:rolevar:: update_json_file_user
The user for the combined file.
.. zuul:rolevar:: update_json_file_group
The group for the combined file.

View File

@ -0,0 +1,3 @@
update_json_file_debug: false
update_json_file_become: false
update_json_file_default: {}

View File

@ -0,0 +1,38 @@
- name: Check if file exists
stat:
path: '{{ update_json_file_name }}'
register: _stat
- name: Load existing file
when: _stat.stat.exists
slurp:
path: '{{ update_json_file_name }}'
register: _file
- name: Parse exisiting file
when: _stat.stat.exists
set_fact:
_config: "{{ _file.content | b64decode | from_json }}"
- name: Set default for non existing file
when: not _stat.stat.exists
set_fact:
_config: '{{ update_json_file_default }}'
- name: Combine new configuration
set_fact:
_config: "{{ _config | combine(update_json_file_combine) }}"
- name: Debug _config variable
debug:
var: _config
when: update_json_file_debug
- name: Save new file
copy:
content: "{{ _config | to_nice_json }}"
dest: '{{ update_json_file_name }}'
mode: '{{ update_json_file_mode | default(omit) }}'
owner: '{{ update_json_file_owner | default(omit) }}'
group: '{{ update_json_file_group | default(omit) }}'
become: '{{ update_json_file_become }}'

View File

@ -0,0 +1,40 @@
- hosts: all
tasks:
- include_role:
name: update-json-file
vars:
update_json_file_name: test.json
update_json_file_default:
foo: bar
update_json_file_combine:
moo: boo
update_json_file_debug: true
- include_role:
name: update-json-file
vars:
update_json_file_name: test.json
update_json_file_combine:
new: content
a:
- list
- of
- items
update_json_file_debug: true
- name: Load resulting merged file
slurp:
path: 'test.json'
register: _file
- name: Parse merged file
set_fact:
_config: "{{ _file.content | b64decode | from_json }}"
- assert:
that:
- _config['foo'] == 'bar'
- _config['moo'] == 'boo'
- _config['new'] == 'content'
- _config['a'] == ['list', 'of', 'items']

View File

@ -642,6 +642,14 @@
- name: fedora-32 - name: fedora-32
label: fedora-32 label: fedora-32
- job:
name: zuul-jobs-test-update-json-file
description: Test the json edit role
run: test-playbooks/update-json-file.yaml
files:
- test-playbooks/update-json-file.yaml
- roles/update-json-file/.*
# -* AUTOGENERATED *- # -* AUTOGENERATED *-
# The following project section is autogenerated by # The following project section is autogenerated by
# tox -e update-test-platforms # tox -e update-test-platforms
@ -692,6 +700,7 @@
- zuul-jobs-test-upload-git-mirror - zuul-jobs-test-upload-git-mirror
- zuul-jobs-test-shake-build - zuul-jobs-test-shake-build
- zuul-jobs-test-ensure-zookeeper - zuul-jobs-test-ensure-zookeeper
- zuul-jobs-test-update-json-file
gate: gate:
jobs: &id001 jobs: &id001
- zuul-jobs-test-add-authorized-keys - zuul-jobs-test-add-authorized-keys
@ -732,5 +741,6 @@
- zuul-jobs-test-upload-git-mirror - zuul-jobs-test-upload-git-mirror
- zuul-jobs-test-shake-build - zuul-jobs-test-shake-build
- zuul-jobs-test-ensure-zookeeper - zuul-jobs-test-ensure-zookeeper
- zuul-jobs-test-update-json-file
periodic-weekly: periodic-weekly:
jobs: *id001 jobs: *id001