1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- """Ansible action plugin to decode ignition payloads"""
- import base64
- import os
- import six
- from six.moves import urllib
- from ansible.plugins.action import ActionBase
- # pylint: disable=too-many-function-args
- def get_file_data(encoded_contents):
- """Decode data URLs as specified in RFC 2397"""
- # The following source is adapted from Python3 source
- # License: https://github.com/python/cpython/blob/3.7/LICENSE
- # retrieved from: https://github.com/python/cpython/blob/3.7/Lib/urllib/request.py
- _, data = encoded_contents.split(":", 1)
- mediatype, data = data.split(",", 1)
- # even base64 encoded data URLs might be quoted so unquote in any case:
- data = urllib.parse.unquote(data)
- if mediatype.endswith(";base64"):
- data = base64.b64decode(data).decode('utf-8')
- mediatype = mediatype[:-7]
- # End PSF software
- return data
- # pylint: disable=too-many-function-args
- def get_files(files_dict, systemd_dict, dir_list, data):
- """parse data to populate file_dict"""
- files = data.get('storage', []).get('files', [])
- for item in files:
- path = item["path"]
- dir_list.add(os.path.dirname(path))
- # remove prefix "data:,"
- encoded_contents = item['contents']['source']
- contents = get_file_data(encoded_contents)
- # convert from int to octal, padding at least to 4 places.
- # eg, 420 becomes '0644'
- mode = str(format(int(item["mode"]), '04o'))
- inode = {"contents": contents, "mode": mode}
- files_dict[path] = inode
- # get the systemd units files we're here
- systemd_units = data.get('systemd', []).get('units', [])
- for item in systemd_units:
- contents = item['contents']
- if six.PY2:
- # pylint: disable=redefined-variable-type
- contents = contents.decode('unicode-escape')
- mode = "0644"
- inode = {"contents": contents, "mode": mode}
- name = item['name']
- path = '/etc/systemd/system/' + name
- dir_list.add(os.path.dirname(path))
- files_dict[path] = inode
- enabled = item.get('enabled') or True
- systemd_dict[name] = enabled
- # pylint: disable=too-few-public-methods
- class ActionModule(ActionBase):
- """ActionModule for parse_ignition.py"""
- def run(self, tmp=None, task_vars=None):
- """Run parse_ignition action plugin"""
- result = super(ActionModule, self).run(tmp, task_vars)
- result["changed"] = False
- result["failed"] = False
- result["msg"] = "Parsed successfully"
- files_dict = {}
- systemd_dict = {}
- dir_list = set()
- result["files_dict"] = files_dict
- result["systemd_dict"] = systemd_dict
- # self.task_vars holds all in-scope variables.
- # Ignore settting self.task_vars outside of init.
- # pylint: disable=W0201
- self.task_vars = task_vars or {}
- ign_file_contents = self._task.args.get('ign_file_contents')
- get_files(files_dict, systemd_dict, dir_list, ign_file_contents)
- result["dir_list"] = list(dir_list)
- return result
|