1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Add project support for lxd_container and lxd_profile module (#4479)

* 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
This commit is contained in:
Raymond Chang 2022-04-23 04:32:32 +08:00 committed by GitHub
parent 0620cd2e74
commit 552db0d353
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 108 additions and 23 deletions

View file

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

View file

@ -21,6 +21,13 @@ options:
- Name of an instance.
type: str
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:
description:
- 'The architecture for the instance (for example C(x86_64) or C(i686)).
@ -248,6 +255,26 @@ EXAMPLES = '''
wait_for_ipv4_addresses: true
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
- hosts: localhost
connection: local
@ -412,6 +439,7 @@ class LXDContainerManagement(object):
"""
self.module = module
self.name = self.module.params['name']
self.project = self.module.params['project']
self._build_config()
self.state = self.module.params['state']
@ -468,16 +496,16 @@ class LXDContainerManagement(object):
self.config[attr] = param_val
def _get_instance_json(self):
return self.client.do(
'GET', '{0}/{1}'.format(self.api_endpoint, self.name),
ok_error_codes=[404]
)
url = '{0}/{1}'.format(self.api_endpoint, self.name)
if self.project:
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):
return self.client.do(
'GET', '{0}/{1}/state'.format(self.api_endpoint, self.name),
ok_error_codes=[404]
)
url = '{0}/{1}/state'.format(self.api_endpoint, self.name)
if self.project:
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
return self.client.do('GET', url, ok_error_codes=[404])
@staticmethod
def _instance_json_to_module_state(resp_json):
@ -486,18 +514,26 @@ class LXDContainerManagement(object):
return ANSIBLE_LXD_STATES[resp_json['metadata']['status']]
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}
if force_stop:
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):
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['name'] = self.name
if self.target:
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.client.do('POST', url, config, wait_for_container=self.wait_for_container)
self.actions.append('create')
def _start_instance(self):
@ -513,7 +549,10 @@ class LXDContainerManagement(object):
self.actions.append('restart')
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')
def _freeze_instance(self):
@ -666,7 +705,10 @@ class LXDContainerManagement(object):
if self._needs_to_change_instance_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')
def run(self):
@ -715,6 +757,9 @@ def main():
type='str',
required=True
),
project=dict(
type='str',
),
architecture=dict(
type='str',
),

View file

@ -21,6 +21,13 @@ options:
- Name of a profile.
required: true
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 of the profile.
@ -129,6 +136,19 @@ EXAMPLES = '''
parent: br0
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
- hosts: localhost
connection: local
@ -208,6 +228,7 @@ actions:
import os
from ansible.module_utils.basic import AnsibleModule
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 = 'unix:/var/lib/lxd/unix.socket'
@ -232,6 +253,7 @@ class LXDProfileManagement(object):
"""
self.module = module
self.name = self.module.params['name']
self.project = self.module.params['project']
self._build_config()
self.state = self.module.params['state']
self.new_name = self.module.params.get('new_name', None)
@ -272,10 +294,10 @@ class LXDProfileManagement(object):
self.config[attr] = param_val
def _get_profile_json(self):
return self.client.do(
'GET', '/1.0/profiles/{0}'.format(self.name),
ok_error_codes=[404]
)
url = '/1.0/profiles/{0}'.format(self.name)
if self.project:
url = '{0}?{1}'.format(url, urlencode(dict(project=self.project)))
return self.client.do('GET', url, ok_error_codes=[404])
@staticmethod
def _profile_json_to_module_state(resp_json):
@ -307,14 +329,20 @@ class LXDProfileManagement(object):
changed=False)
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['name'] = self.name
self.client.do('POST', '/1.0/profiles', config)
self.client.do('POST', url, config)
self.actions.append('create')
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}
self.client.do('POST', '/1.0/profiles/{0}'.format(self.name), config)
self.client.do('POST', url, config)
self.actions.append('rename')
self.name = self.new_name
@ -421,11 +449,17 @@ class LXDProfileManagement(object):
config = self._generate_new_config(config)
# 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')
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')
def run(self):
@ -469,6 +503,9 @@ def main():
type='str',
required=True
),
project=dict(
type='str',
),
new_name=dict(
type='str',
),