mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Previously LXD profiles were overwritten, now these are merged. (#1813)
* added ``merge_profile`` parameter to merge configurations from the play to an existing profile * add fragment * cosmetic changes Co-authored-by: Frank Dornheim <“dornheim@posteo.de@users.noreply.github.com”>
This commit is contained in:
parent
03fd6bd008
commit
6dd4cd0eb7
2 changed files with 121 additions and 5 deletions
2
changelogs/fragments/1813-lxd_profile-merge-profiles.yml
Normal file
2
changelogs/fragments/1813-lxd_profile-merge-profiles.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- lxd_profile - added ``merge_profile`` parameter to merge configurations from the play to an existing profile (https://github.com/ansible-collections/community.general/pull/1813).
|
|
@ -2,12 +2,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2016, Hiroaki Nakamura <hnakamur@gmail.com>
|
||||
# Copyright: (c) 2020, Frank Dornheim <dornheim@posteo.de>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: lxd_profile
|
||||
|
@ -52,6 +52,14 @@ options:
|
|||
See U(https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-11)
|
||||
required: false
|
||||
type: str
|
||||
merge_profile:
|
||||
description:
|
||||
- Merge the configuration of the present profile with the new desired configuration,
|
||||
instead of replacing it.
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
version_added: 2.1.0
|
||||
state:
|
||||
choices:
|
||||
- present
|
||||
|
@ -142,6 +150,23 @@ EXAMPLES = '''
|
|||
parent: br0
|
||||
type: nic
|
||||
|
||||
# An example for modify/merge a profile
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
tasks:
|
||||
- name: Merge a profile
|
||||
community.general.lxd_profile:
|
||||
merge_profile: true
|
||||
name: macvlan
|
||||
state: present
|
||||
config: {}
|
||||
description: my macvlan profile
|
||||
devices:
|
||||
eth0:
|
||||
nictype: macvlan
|
||||
parent: br0
|
||||
type: nic
|
||||
|
||||
# An example for deleting a profile
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
|
@ -181,7 +206,6 @@ actions:
|
|||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException
|
||||
|
||||
|
@ -266,7 +290,7 @@ class LXDProfileManagement(object):
|
|||
self._create_profile()
|
||||
else:
|
||||
self.module.fail_json(
|
||||
msg='new_name must not be set when the profile does not exist and the specified state is present',
|
||||
msg='new_name must not be set when the profile does not exist and the state is present',
|
||||
changed=False)
|
||||
else:
|
||||
if self.new_name is not None and self.new_name != self.name:
|
||||
|
@ -307,10 +331,96 @@ class LXDProfileManagement(object):
|
|||
self._needs_to_change_profile_config('devices')
|
||||
)
|
||||
|
||||
def _apply_profile_configs(self):
|
||||
config = self.old_profile_json.copy()
|
||||
def _merge_dicts(self, source, destination):
|
||||
"""Merge Dictionarys
|
||||
|
||||
Get a list of filehandle numbers from logger to be handed to
|
||||
DaemonContext.files_preserve
|
||||
|
||||
Args:
|
||||
dict(source): source dict
|
||||
dict(destination): destination dict
|
||||
Kwargs:
|
||||
None
|
||||
Raises:
|
||||
None
|
||||
Returns:
|
||||
dict(destination): merged dict"""
|
||||
for key, value in source.items():
|
||||
if isinstance(value, dict):
|
||||
# get node or create one
|
||||
node = destination.setdefault(key, {})
|
||||
self._merge_dicts(value, node)
|
||||
else:
|
||||
destination[key] = value
|
||||
return destination
|
||||
|
||||
def _merge_config(self, config):
|
||||
""" merge profile
|
||||
|
||||
Merge Configuration of the present profile and the new desired configitems
|
||||
|
||||
Args:
|
||||
dict(config): Dict with the old config in 'metadata' and new config in 'config'
|
||||
Kwargs:
|
||||
None
|
||||
Raises:
|
||||
None
|
||||
Returns:
|
||||
dict(config): new config"""
|
||||
# merge or copy the sections from the existing profile to 'config'
|
||||
for item in ['config', 'description', 'devices', 'name', 'used_by']:
|
||||
if item in config:
|
||||
config[item] = self._merge_dicts(config['metadata'][item], config[item])
|
||||
else:
|
||||
config[item] = config['metadata'][item]
|
||||
# merge or copy the sections from the ansible-task to 'config'
|
||||
return self._merge_dicts(self.config, config)
|
||||
|
||||
def _generate_new_config(self, config):
|
||||
""" rebuild profile
|
||||
|
||||
Rebuild the Profile by the configuration provided in the play.
|
||||
Existing configurations are discarded.
|
||||
|
||||
This ist the default behavior.
|
||||
|
||||
Args:
|
||||
dict(config): Dict with the old config in 'metadata' and new config in 'config'
|
||||
Kwargs:
|
||||
None
|
||||
Raises:
|
||||
None
|
||||
Returns:
|
||||
dict(config): new config"""
|
||||
for k, v in self.config.items():
|
||||
config[k] = v
|
||||
return config
|
||||
|
||||
def _apply_profile_configs(self):
|
||||
""" Selection of the procedure: rebuild or merge
|
||||
|
||||
The standard behavior is that all information not contained
|
||||
in the play is discarded.
|
||||
|
||||
If "merge_profile" is provides in the play and "True", then existing
|
||||
configurations from the profile and new ones defined are merged.
|
||||
|
||||
Args:
|
||||
None
|
||||
Kwargs:
|
||||
None
|
||||
Raises:
|
||||
None
|
||||
Returns:
|
||||
None"""
|
||||
config = self.old_profile_json.copy()
|
||||
if self.module.params['merge_profile']:
|
||||
config = self._merge_config(config)
|
||||
else:
|
||||
config = self._generate_new_config(config)
|
||||
|
||||
# upload config to lxd
|
||||
self.client.do('PUT', '/1.0/profiles/{0}'.format(self.name), config)
|
||||
self.actions.append('apply_profile_configs')
|
||||
|
||||
|
@ -371,6 +481,10 @@ def main():
|
|||
devices=dict(
|
||||
type='dict',
|
||||
),
|
||||
merge_profile=dict(
|
||||
type='bool',
|
||||
default=False
|
||||
),
|
||||
state=dict(
|
||||
choices=PROFILES_STATES,
|
||||
default='present'
|
||||
|
|
Loading…
Reference in a new issue