mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
* add project support for lxd modules
* fix lxd_container yaml format error
* add changelog fragement add version_add entry
* fix LXD spelling
* complete lxd_profile example
(cherry picked from commit 552db0d353
)
Co-authored-by: Raymond Chang <xrayjemmy@gmail.com>
This commit is contained in:
parent
bdc4ee496f
commit
aeece5a107
3 changed files with 108 additions and 23 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
minor_changes:
|
||||||
|
- lxd_container - adds ``project`` option to allow selecting project for LXD instance (https://github.com/ansible-collections/community.general/pull/4479).
|
||||||
|
- lxd_profile - adds ``project`` option to allow selecting project for LXD profile (https://github.com/ansible-collections/community.general/pull/4479).
|
|
@ -21,6 +21,13 @@ options:
|
||||||
- Name of an instance.
|
- Name of an instance.
|
||||||
type: str
|
type: str
|
||||||
required: true
|
required: true
|
||||||
|
project:
|
||||||
|
description:
|
||||||
|
- 'Project of an instance.
|
||||||
|
See U(https://github.com/lxc/lxd/blob/master/doc/projects.md).'
|
||||||
|
required: false
|
||||||
|
type: str
|
||||||
|
version_added: 4.8.0
|
||||||
architecture:
|
architecture:
|
||||||
description:
|
description:
|
||||||
- 'The architecture for the instance (for example C(x86_64) or C(i686)).
|
- 'The architecture for the instance (for example C(x86_64) or C(i686)).
|
||||||
|
@ -248,6 +255,26 @@ EXAMPLES = '''
|
||||||
wait_for_ipv4_addresses: true
|
wait_for_ipv4_addresses: true
|
||||||
timeout: 600
|
timeout: 600
|
||||||
|
|
||||||
|
# An example for creating container in project other than default
|
||||||
|
- hosts: localhost
|
||||||
|
connection: local
|
||||||
|
tasks:
|
||||||
|
- name: Create a started container in project mytestproject
|
||||||
|
community.general.lxd_container:
|
||||||
|
name: mycontainer
|
||||||
|
project: mytestproject
|
||||||
|
ignore_volatile_options: true
|
||||||
|
state: started
|
||||||
|
source:
|
||||||
|
protocol: simplestreams
|
||||||
|
type: image
|
||||||
|
mode: pull
|
||||||
|
server: https://images.linuxcontainers.org
|
||||||
|
alias: ubuntu/20.04/cloud
|
||||||
|
profiles: ["default"]
|
||||||
|
wait_for_ipv4_addresses: true
|
||||||
|
timeout: 600
|
||||||
|
|
||||||
# An example for deleting a container
|
# An example for deleting a container
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
connection: local
|
connection: local
|
||||||
|
@ -412,6 +439,7 @@ class LXDContainerManagement(object):
|
||||||
"""
|
"""
|
||||||
self.module = module
|
self.module = module
|
||||||
self.name = self.module.params['name']
|
self.name = self.module.params['name']
|
||||||
|
self.project = self.module.params['project']
|
||||||
self._build_config()
|
self._build_config()
|
||||||
|
|
||||||
self.state = self.module.params['state']
|
self.state = self.module.params['state']
|
||||||
|
@ -468,16 +496,16 @@ class LXDContainerManagement(object):
|
||||||
self.config[attr] = param_val
|
self.config[attr] = param_val
|
||||||
|
|
||||||
def _get_instance_json(self):
|
def _get_instance_json(self):
|
||||||
return self.client.do(
|
url = '{0}/{1}'.format(self.api_endpoint, self.name)
|
||||||
'GET', '{0}/{1}'.format(self.api_endpoint, self.name),
|
if self.project:
|
||||||
ok_error_codes=[404]
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
)
|
return self.client.do('GET', url, ok_error_codes=[404])
|
||||||
|
|
||||||
def _get_instance_state_json(self):
|
def _get_instance_state_json(self):
|
||||||
return self.client.do(
|
url = '{0}/{1}/state'.format(self.api_endpoint, self.name)
|
||||||
'GET', '{0}/{1}/state'.format(self.api_endpoint, self.name),
|
if self.project:
|
||||||
ok_error_codes=[404]
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
)
|
return self.client.do('GET', url, ok_error_codes=[404])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _instance_json_to_module_state(resp_json):
|
def _instance_json_to_module_state(resp_json):
|
||||||
|
@ -486,18 +514,26 @@ class LXDContainerManagement(object):
|
||||||
return ANSIBLE_LXD_STATES[resp_json['metadata']['status']]
|
return ANSIBLE_LXD_STATES[resp_json['metadata']['status']]
|
||||||
|
|
||||||
def _change_state(self, action, force_stop=False):
|
def _change_state(self, action, force_stop=False):
|
||||||
|
url = '{0}/{1}/state'.format(self.api_endpoint, self.name)
|
||||||
|
if self.project:
|
||||||
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
body_json = {'action': action, 'timeout': self.timeout}
|
body_json = {'action': action, 'timeout': self.timeout}
|
||||||
if force_stop:
|
if force_stop:
|
||||||
body_json['force'] = True
|
body_json['force'] = True
|
||||||
return self.client.do('PUT', '{0}/{1}/state'.format(self.api_endpoint, self.name), body_json=body_json)
|
return self.client.do('PUT', url, body_json=body_json)
|
||||||
|
|
||||||
def _create_instance(self):
|
def _create_instance(self):
|
||||||
|
url = self.api_endpoint
|
||||||
|
url_params = dict()
|
||||||
|
if self.target:
|
||||||
|
url_params['target'] = self.target
|
||||||
|
if self.project:
|
||||||
|
url_params['project'] = self.project
|
||||||
|
if url_params:
|
||||||
|
url = '{0}?{1}'.format(url, urlencode(url_params))
|
||||||
config = self.config.copy()
|
config = self.config.copy()
|
||||||
config['name'] = self.name
|
config['name'] = self.name
|
||||||
if self.target:
|
self.client.do('POST', url, config, wait_for_container=self.wait_for_container)
|
||||||
self.client.do('POST', '{0}?{1}'.format(self.api_endpoint, urlencode(dict(target=self.target))), config, wait_for_container=self.wait_for_container)
|
|
||||||
else:
|
|
||||||
self.client.do('POST', self.api_endpoint, config, wait_for_container=self.wait_for_container)
|
|
||||||
self.actions.append('create')
|
self.actions.append('create')
|
||||||
|
|
||||||
def _start_instance(self):
|
def _start_instance(self):
|
||||||
|
@ -513,7 +549,10 @@ class LXDContainerManagement(object):
|
||||||
self.actions.append('restart')
|
self.actions.append('restart')
|
||||||
|
|
||||||
def _delete_instance(self):
|
def _delete_instance(self):
|
||||||
self.client.do('DELETE', '{0}/{1}'.format(self.api_endpoint, self.name))
|
url = '{0}/{1}'.format(self.api_endpoint, self.name)
|
||||||
|
if self.project:
|
||||||
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
|
self.client.do('DELETE', url)
|
||||||
self.actions.append('delete')
|
self.actions.append('delete')
|
||||||
|
|
||||||
def _freeze_instance(self):
|
def _freeze_instance(self):
|
||||||
|
@ -666,7 +705,10 @@ class LXDContainerManagement(object):
|
||||||
if self._needs_to_change_instance_config('profiles'):
|
if self._needs_to_change_instance_config('profiles'):
|
||||||
body_json['profiles'] = self.config['profiles']
|
body_json['profiles'] = self.config['profiles']
|
||||||
|
|
||||||
self.client.do('PUT', '{0}/{1}'.format(self.api_endpoint, self.name), body_json=body_json)
|
url = '{0}/{1}'.format(self.api_endpoint, self.name)
|
||||||
|
if self.project:
|
||||||
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
|
self.client.do('PUT', url, body_json=body_json)
|
||||||
self.actions.append('apply_instance_configs')
|
self.actions.append('apply_instance_configs')
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -715,6 +757,9 @@ def main():
|
||||||
type='str',
|
type='str',
|
||||||
required=True
|
required=True
|
||||||
),
|
),
|
||||||
|
project=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
architecture=dict(
|
architecture=dict(
|
||||||
type='str',
|
type='str',
|
||||||
),
|
),
|
||||||
|
|
|
@ -21,6 +21,13 @@ options:
|
||||||
- Name of a profile.
|
- Name of a profile.
|
||||||
required: true
|
required: true
|
||||||
type: str
|
type: str
|
||||||
|
project:
|
||||||
|
description:
|
||||||
|
- 'Project of a profile.
|
||||||
|
See U(https://github.com/lxc/lxd/blob/master/doc/projects.md).'
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
version_added: 4.8.0
|
||||||
description:
|
description:
|
||||||
description:
|
description:
|
||||||
- Description of the profile.
|
- Description of the profile.
|
||||||
|
@ -129,6 +136,19 @@ EXAMPLES = '''
|
||||||
parent: br0
|
parent: br0
|
||||||
type: nic
|
type: nic
|
||||||
|
|
||||||
|
# An example for creating a profile in project mytestproject
|
||||||
|
- hosts: localhost
|
||||||
|
connection: local
|
||||||
|
tasks:
|
||||||
|
- name: Create a profile
|
||||||
|
community.general.lxd_profile:
|
||||||
|
name: testprofile
|
||||||
|
project: mytestproject
|
||||||
|
state: present
|
||||||
|
config: {}
|
||||||
|
description: test profile in project mytestproject
|
||||||
|
devices: {}
|
||||||
|
|
||||||
# An example for creating a profile via http connection
|
# An example for creating a profile via http connection
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
connection: local
|
connection: local
|
||||||
|
@ -208,6 +228,7 @@ 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
|
||||||
|
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||||
|
|
||||||
# ANSIBLE_LXD_DEFAULT_URL is a default value of the lxd endpoint
|
# ANSIBLE_LXD_DEFAULT_URL is a default value of the lxd endpoint
|
||||||
ANSIBLE_LXD_DEFAULT_URL = 'unix:/var/lib/lxd/unix.socket'
|
ANSIBLE_LXD_DEFAULT_URL = 'unix:/var/lib/lxd/unix.socket'
|
||||||
|
@ -232,6 +253,7 @@ class LXDProfileManagement(object):
|
||||||
"""
|
"""
|
||||||
self.module = module
|
self.module = module
|
||||||
self.name = self.module.params['name']
|
self.name = self.module.params['name']
|
||||||
|
self.project = self.module.params['project']
|
||||||
self._build_config()
|
self._build_config()
|
||||||
self.state = self.module.params['state']
|
self.state = self.module.params['state']
|
||||||
self.new_name = self.module.params.get('new_name', None)
|
self.new_name = self.module.params.get('new_name', None)
|
||||||
|
@ -272,10 +294,10 @@ class LXDProfileManagement(object):
|
||||||
self.config[attr] = param_val
|
self.config[attr] = param_val
|
||||||
|
|
||||||
def _get_profile_json(self):
|
def _get_profile_json(self):
|
||||||
return self.client.do(
|
url = '/1.0/profiles/{0}'.format(self.name)
|
||||||
'GET', '/1.0/profiles/{0}'.format(self.name),
|
if self.project:
|
||||||
ok_error_codes=[404]
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
)
|
return self.client.do('GET', url, ok_error_codes=[404])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _profile_json_to_module_state(resp_json):
|
def _profile_json_to_module_state(resp_json):
|
||||||
|
@ -307,14 +329,20 @@ class LXDProfileManagement(object):
|
||||||
changed=False)
|
changed=False)
|
||||||
|
|
||||||
def _create_profile(self):
|
def _create_profile(self):
|
||||||
|
url = '/1.0/profiles'
|
||||||
|
if self.project:
|
||||||
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
config = self.config.copy()
|
config = self.config.copy()
|
||||||
config['name'] = self.name
|
config['name'] = self.name
|
||||||
self.client.do('POST', '/1.0/profiles', config)
|
self.client.do('POST', url, config)
|
||||||
self.actions.append('create')
|
self.actions.append('create')
|
||||||
|
|
||||||
def _rename_profile(self):
|
def _rename_profile(self):
|
||||||
|
url = '/1.0/profiles/{0}'.format(self.name)
|
||||||
|
if self.project:
|
||||||
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
config = {'name': self.new_name}
|
config = {'name': self.new_name}
|
||||||
self.client.do('POST', '/1.0/profiles/{0}'.format(self.name), config)
|
self.client.do('POST', url, config)
|
||||||
self.actions.append('rename')
|
self.actions.append('rename')
|
||||||
self.name = self.new_name
|
self.name = self.new_name
|
||||||
|
|
||||||
|
@ -421,11 +449,17 @@ class LXDProfileManagement(object):
|
||||||
config = self._generate_new_config(config)
|
config = self._generate_new_config(config)
|
||||||
|
|
||||||
# upload config to lxd
|
# upload config to lxd
|
||||||
self.client.do('PUT', '/1.0/profiles/{0}'.format(self.name), config)
|
url = '/1.0/profiles/{0}'.format(self.name)
|
||||||
|
if self.project:
|
||||||
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
|
self.client.do('PUT', url, config)
|
||||||
self.actions.append('apply_profile_configs')
|
self.actions.append('apply_profile_configs')
|
||||||
|
|
||||||
def _delete_profile(self):
|
def _delete_profile(self):
|
||||||
self.client.do('DELETE', '/1.0/profiles/{0}'.format(self.name))
|
url = '/1.0/profiles/{0}'.format(self.name)
|
||||||
|
if self.project:
|
||||||
|
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
|
||||||
|
self.client.do('DELETE', url)
|
||||||
self.actions.append('delete')
|
self.actions.append('delete')
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -469,6 +503,9 @@ def main():
|
||||||
type='str',
|
type='str',
|
||||||
required=True
|
required=True
|
||||||
),
|
),
|
||||||
|
project=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
new_name=dict(
|
new_name=dict(
|
||||||
type='str',
|
type='str',
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue