1
0
Fork 0
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) (#1836)

* 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”>
(cherry picked from commit 6dd4cd0eb7)

Co-authored-by: Frank Dornheim <524257+conloos@users.noreply.github.com>
This commit is contained in:
patchback[bot] 2021-02-16 10:58:34 +01:00 committed by GitHub
parent 0d0884b069
commit 7d400663b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 121 additions and 5 deletions

View 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).

View file

@ -2,12 +2,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright: (c) 2016, Hiroaki Nakamura <hnakamur@gmail.com> # 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) # 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 from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = '''
--- ---
module: lxd_profile module: lxd_profile
@ -52,6 +52,14 @@ options:
See U(https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-11) See U(https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-11)
required: false required: false
type: str 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: state:
choices: choices:
- present - present
@ -142,6 +150,23 @@ EXAMPLES = '''
parent: br0 parent: br0
type: nic 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 # An example for deleting a profile
- hosts: localhost - hosts: localhost
connection: local connection: local
@ -181,7 +206,6 @@ actions:
''' '''
import os import os
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException
@ -266,7 +290,7 @@ class LXDProfileManagement(object):
self._create_profile() self._create_profile()
else: else:
self.module.fail_json( 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) changed=False)
else: else:
if self.new_name is not None and self.new_name != self.name: 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') self._needs_to_change_profile_config('devices')
) )
def _apply_profile_configs(self): def _merge_dicts(self, source, destination):
config = self.old_profile_json.copy() """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(): for k, v in self.config.items():
config[k] = v 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.client.do('PUT', '/1.0/profiles/{0}'.format(self.name), config)
self.actions.append('apply_profile_configs') self.actions.append('apply_profile_configs')
@ -371,6 +481,10 @@ def main():
devices=dict( devices=dict(
type='dict', type='dict',
), ),
merge_profile=dict(
type='bool',
default=False
),
state=dict( state=dict(
choices=PROFILES_STATES, choices=PROFILES_STATES,
default='present' default='present'