Skip to content

Commit a6f2394

Browse files
authored
Merge pull request #5 from stackhpc/os-deploy-templates
Add os_deploy_templates role
2 parents 8fc544c + 54190ad commit a6f2394

File tree

8 files changed

+348
-1
lines changed

8 files changed

+348
-1
lines changed

.ansible-lint

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ exclude_paths:
33
- .cache/
44
- .github/
55
skip_list:
6+
- meta-no-info
67
- meta-runtime[unsupported-version]
78
- yaml[line-length]
89
use_default_rules: true

galaxy.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ license:
1111
tags:
1212
- cloud
1313
- openstack
14-
dependencies: {}
14+
dependencies:
15+
"openstack.cloud": "*"
1516
repository: https://github.com/stackhpc/ansible-collection-openstack
1617
documentation: https://github.com/stackhpc/ansible-collection-openstack/branch/main/README.md
1718
homepage: https://github.com/stackhpc/ansible-collection-openstack
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
4+
# Copyright (c) 2023 StackHPC Ltd.
5+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6+
7+
# This module has been proposed to the OpenStack collection:
8+
# https://review.opendev.org/c/openstack/ansible-collections-openstack/+/874755
9+
# Keep a copy here until it merges.
10+
# It requires OpenStack SDK 0.53.0.
11+
12+
from __future__ import (absolute_import, division, print_function)
13+
__metaclass__ = type
14+
15+
DOCUMENTATION = r'''
16+
module: baremetal_deploy_template
17+
short_description: Create/Delete Bare Metal deploy template Resources from OpenStack
18+
author: OpenStack Ansible SIG
19+
description:
20+
- Create, Update and Remove ironic deploy templates from OpenStack.
21+
options:
22+
extra:
23+
description:
24+
- A set of one or more arbitrary metadata key and value pairs.
25+
type: dict
26+
id:
27+
description:
28+
- ID of the deploy template.
29+
- Will be auto-generated if not specified.
30+
type: str
31+
aliases: ['uuid']
32+
name:
33+
description:
34+
- Name of the deploy template.
35+
- Must be formatted as a trait name (see API reference).
36+
- Required when the deploy template is created, after which the
37+
name or ID may be used.
38+
type: str
39+
steps:
40+
description:
41+
- List of deploy steps to apply.
42+
- Required when the deploy template is created.
43+
type: list
44+
elements: dict
45+
state:
46+
description:
47+
- Indicates desired state of the resource
48+
choices: ['present', 'absent']
49+
default: present
50+
type: str
51+
extends_documentation_fragment:
52+
- openstack.cloud.openstack
53+
'''
54+
55+
EXAMPLES = r'''
56+
- name: Create Bare Metal deploy template
57+
openstack.cloud.baremetal_deploy_template:
58+
cloud: devstack
59+
state: present
60+
name: CUSTOM_FOO
61+
steps:
62+
- interface: bios
63+
step: apply_configuration
64+
args:
65+
settings:
66+
- name: LogicalProc
67+
value: Enabled
68+
priority: 110
69+
extra:
70+
something: extra
71+
register: result
72+
73+
- name: Delete Bare Metal deploy template
74+
openstack.cloud.baremetal_deploy_template:
75+
cloud: devstack
76+
state: absent
77+
id: 1a85ebca-22bf-42eb-ad9e-f640789b8098
78+
register: result
79+
80+
- name: Update Bare Metal deploy template
81+
openstack.cloud.baremetal_deploy_template:
82+
cloud: devstack
83+
state: present
84+
id: 1a85ebca-22bf-42eb-ad9e-f640789b8098
85+
extra:
86+
something: new
87+
'''
88+
89+
RETURN = r'''
90+
template:
91+
description: A deploy template dictionary, subset of the dictionary keys
92+
listed below may be returned, depending on your cloud
93+
provider.
94+
returned: success
95+
type: dict
96+
contains:
97+
created_at:
98+
description: Bare Metal deploy template created at timestamp.
99+
returned: success
100+
type: str
101+
extra:
102+
description: A set of one or more arbitrary metadata key and value
103+
pairs.
104+
returned: success
105+
type: dict
106+
id:
107+
description: The UUID for the Baremetal Deploy Template resource.
108+
returned: success
109+
type: str
110+
links:
111+
description: A list of relative links, including the self and
112+
bookmark links.
113+
returned: success
114+
type: list
115+
location:
116+
description: Cloud location of this resource (cloud, project,
117+
region, zone)
118+
returned: success
119+
type: dict
120+
name:
121+
description: Bare Metal deploy template name.
122+
returned: success
123+
type: str
124+
steps:
125+
description: A list of deploy steps.
126+
returned: success
127+
type: list
128+
elements: dict
129+
updated_at:
130+
description: Bare Metal deploy template updated at timestamp.
131+
returned: success
132+
type: str
133+
'''
134+
135+
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
136+
OpenStackModule
137+
)
138+
139+
140+
class BaremetalDeployTemplateModule(OpenStackModule):
141+
argument_spec = dict(
142+
extra=dict(type='dict'),
143+
id=dict(aliases=['uuid']),
144+
name=dict(),
145+
steps=dict(type='list', elements='dict'),
146+
state=dict(default='present', choices=['present', 'absent']),
147+
)
148+
149+
module_kwargs = dict(
150+
required_one_of=[
151+
('id', 'name'),
152+
],
153+
)
154+
155+
def run(self):
156+
template = self._find_deploy_template()
157+
state = self.params['state']
158+
if state == 'present':
159+
# create or update deploy template
160+
161+
kwargs = {}
162+
for k in ['extra', 'id', 'name', 'steps']:
163+
if self.params[k] is not None:
164+
kwargs[k] = self.params[k]
165+
166+
changed = True
167+
if not template:
168+
# create deploy template
169+
template = self.conn.baremetal.create_deploy_template(**kwargs)
170+
else:
171+
# update deploy template
172+
updates = dict((k, v)
173+
for k, v in kwargs.items()
174+
if v != template[k])
175+
176+
if updates:
177+
template = \
178+
self.conn.baremetal.update_deploy_template(template['id'], **updates)
179+
else:
180+
changed = False
181+
182+
self.exit_json(changed=changed, template=template.to_dict(computed=False))
183+
184+
if state == 'absent':
185+
# remove deploy template
186+
if not template:
187+
self.exit_json(changed=False)
188+
189+
template = self.conn.baremetal.delete_deploy_template(template['id'])
190+
self.exit_json(changed=True)
191+
192+
def _find_deploy_template(self):
193+
id_or_name = self.params['id'] if self.params['id'] else self.params['name']
194+
try:
195+
return self.conn.baremetal.get_deploy_template(id_or_name)
196+
except self.sdk.exceptions.ResourceNotFound:
197+
return None
198+
199+
200+
def main():
201+
module = BaremetalDeployTemplateModule()
202+
module()
203+
204+
205+
if __name__ == "__main__":
206+
main()
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
OpenStack Ironic deploy templates
2+
=================================
3+
4+
This role can be used to register deploy templates in OpenStack ironic.
5+
6+
What are deploy templates? Read the
7+
[docs](https://docs.openstack.org/ironic/latest/admin/node-deployment.html) or
8+
watch the [video](https://www.youtube.com/watch?v=DrQcTljx_eM) to find out!
9+
10+
Requirements
11+
------------
12+
13+
The OpenStack Ironic API should be accessible from the target host.
14+
15+
Role Variables
16+
--------------
17+
18+
`os_deploy_templates_venv` is a path to a directory in which to create a
19+
virtualenv.
20+
21+
`os_deploy_templates_upper_constraints_file` is a file or URL containing Python
22+
upper constraints.
23+
24+
`os_deploy_templates_auth_type` is an authentication type compatible with
25+
the `auth_type` argument of `openstack.cloud` Ansible modules.
26+
27+
`os_deploy_templates_auth` is a dict containing authentication information
28+
compatible with the `auth` argument of `openstack.cloud` Ansible modules.
29+
30+
`os_deploy_templates_cacert` is an optional path to a CA certificate bundle.
31+
32+
`os_deploy_templates_interface` is the endpoint URL type to fetch from the service
33+
catalog. Maybe be one of `public`, `admin`, or `internal`.
34+
35+
`os_deploy_templates` is a list of Ironic deploy templates to register. Each
36+
item should be a dict containing following items:
37+
* `name`: Name of the deploy template.
38+
* `steps`: List of deploy steps.
39+
* `extra`: Dict of metadata, optional.
40+
* `uuid`: UUID, optional.
41+
* `state`: State, optional.
42+
43+
Dependencies
44+
------------
45+
46+
This role depends on the `stackhpc.openstack.os_openstacksdk` role.
47+
48+
Example Playbook
49+
----------------
50+
51+
The following playbook registers an Ironic deploy template.
52+
53+
```
54+
---
55+
- name: Ensure Ironic deploy templates are registered
56+
hosts: os-clients
57+
tasks:
58+
- import_role:
59+
name: stackhpc.openstack.os_deploy_templates
60+
vars:
61+
os_deploy_templates_venv: "~/os-deploy_templates-venv"
62+
os_deploy_templates_auth_type: "password"
63+
os_deploy_templates_auth:
64+
project_name: <keystone project>
65+
username: <keystone user>
66+
password: <keystone password>
67+
auth_url: <keystone auth URL>
68+
os_deploy_templates:
69+
- name: CUSTOM_HYPERTHREADING_ENABLED
70+
steps:
71+
- interface: bios
72+
step: apply_configuration
73+
args:
74+
settings:
75+
- name: LogicalProc
76+
value: Enabled
77+
priority: 110
78+
```
79+
80+
Author Information
81+
------------------
82+
83+
- Mark Goddard (<[email protected]>)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
# Path to a directory in which to create a virtualenv.
3+
os_deploy_templates_venv:
4+
5+
# Upper constraints file for installation of python dependencies.
6+
#
7+
# Use Yoga upper constraints, to avoid incompatibility with openstacksdk
8+
# 0.99.0 and include support for deploy templates (included since openstacksdk
9+
# 0.53).
10+
os_deploy_templates_upper_constraints_file: https://releases.openstack.org/constraints/upper/yoga
11+
12+
# Authentication type.
13+
os_deploy_templates_auth_type:
14+
15+
# Authentication information.
16+
os_deploy_templates_auth: {}
17+
18+
# Endpoint URL type to fetch from the service catalog. Maybe be one of:
19+
# public, admin, or internal.
20+
os_deploy_templates_interface:
21+
22+
# List of Ironic deploy templates to register. Each item should be a dict
23+
# containing the following items:
24+
# - 'name': Name of the deploy template.
25+
# - 'steps': List of deploy steps.
26+
# - 'extra': Dict of metadata, optional.
27+
# - 'uuid': UUID, optional.
28+
# - 'state': State, optional.
29+
os_deploy_templates: [] # noqa var-naming[no-role-prefix]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
dependencies:
3+
- role: stackhpc.openstack.os_openstacksdk
4+
os_openstacksdk_venv: "{{ os_deploy_templates_venv }}"
5+
os_openstacksdk_upper_constraints_file: "{{ os_deploy_templates_upper_constraints_file }}"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
- name: Ensure Ironic deploy templates exist
3+
stackhpc.openstack.baremetal_deploy_template:
4+
auth_type: "{{ os_deploy_templates_auth_type }}"
5+
auth: "{{ os_deploy_templates_auth }}"
6+
cacert: "{{ os_deploy_templates_cacert | default(omit) }}"
7+
interface: "{{ os_deploy_templates_interface | default(omit, true) }}"
8+
name: "{{ item.name }}"
9+
steps: "{{ item.steps }}"
10+
uuid: "{{ item.uuid | default(omit) }}"
11+
extra: "{{ item.extra | default(omit) }}"
12+
state: "{{ item.state | default(omit) }}"
13+
loop: "{{ os_deploy_templates }}"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
- name: Set a fact about the Ansible python interpreter
3+
ansible.builtin.set_fact:
4+
old_ansible_python_interpreter: "{{ ansible_python_interpreter | default('/usr/bin/python3') }}"
5+
6+
- name: Import deploy_templates.yml
7+
ansible.builtin.import_tasks: deploy_templates.yml
8+
vars:
9+
ansible_python_interpreter: "{{ os_deploy_templates_venv ~ '/bin/python' if os_deploy_templates_venv != None else old_ansible_python_interpreter }}"

0 commit comments

Comments
 (0)