Skip to content

Commit 277ca6e

Browse files
committed
Initial commit
0 parents  commit 277ca6e

File tree

63 files changed

+1779
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1779
-0
lines changed

AUTHORS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Original Contribution:
2+
3+
* Jose Delarosa - Dell Inc.
4+
* Bill Dodd - Majec Systems

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Change Log
2+
3+
## [1.0.0] - 2019-10-18
4+
- Initial public release

LICENSE.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
The Distributed Management Task Force (DMTF) grants rights under copyright in
2+
this software on the terms of the BSD 3-Clause License as set forth below; no
3+
other rights are granted by DMTF. This software might be subject to other rights
4+
(such as patent rights) of other parties.
5+
6+
7+
### Copyrights.
8+
9+
Copyright (c) 2019, Contributing Member(s) of Distributed Management Task Force,
10+
Inc.. All rights reserved.
11+
12+
Redistribution and use in source and binary forms, with or without modification,
13+
are permitted provided that the following conditions are met:
14+
15+
* Redistributions of source code must retain the above copyright notice, this
16+
list of conditions and the following disclaimer.
17+
* Redistributions in binary form must reproduce the above copyright notice, this
18+
list of conditions and the following disclaimer in the documentation and/or
19+
other materials provided with the distribution.
20+
* Neither the name of the Distributed Management Task Force (DMTF) nor the names
21+
of its contributors may be used to endorse or promote products derived from this
22+
software without specific prior written permission.
23+
24+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34+
35+
36+
### Patents.
37+
38+
This software may be subject to third party patent rights, including provisional
39+
patent rights ("patent rights"). DMTF makes no representations to users of the
40+
standard as to the existence of such rights, and is not responsible to
41+
recognize, disclose, or identify any or all such third party patent right,
42+
owners or claimants, nor for any incomplete or inaccurate identification or
43+
disclosure of such rights, owners or claimants. DMTF shall have no liability to
44+
any party, in any manner or circumstance, under any legal theory whatsoever, for
45+
failure to recognize, disclose, or identify any such third party patent rights,
46+
or for such party's reliance on the software or incorporation thereof in its
47+
product, protocols or testing procedures. DMTF shall have no liability to any
48+
party using such software, whether such use is foreseeable or not, nor to any
49+
patent owner or claimant, and shall have no liability or responsibility for
50+
costs or losses incurred if software is withdrawn or modified after publication,
51+
and shall be indemnified and held harmless by any party using the software from
52+
any and all claims of infringement by a patent owner for such use.
53+
54+
DMTF Members that contributed to this software source code might have made
55+
patent licensing commitments in connection with their participation in the DMTF.
56+
For details, see http://dmtf.org/sites/default/files/patent-10-18-01.pdf and
57+
http://www.dmtf.org/about/policies/disclosures.

OEM_EXTENSIONS.md

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
Copyright 2019 DMTF. All rights reserved.
2+
3+
# Redfish Ansible OEM Extensions
4+
5+
## About
6+
7+
This document describes an approach for extending the standard Redfish Ansible modules in order to support OEM extensions used by various vendors.
8+
9+
## The Approach
10+
11+
With the current Redfish Ansible support, there are three main modules (`redfish_command.py`, `redfish_config.py` and `redfish_info.py`). These three modules are relatively thin modules that establish the commands and their parameters and then call out to a utility module, `redfish_utils.py`, that has the bulk of the logic to interact with the Redfish services.
12+
13+
The `redfish_utils.py` module implements a `RedfishUtils` class that has many methods to perform the various Redfish operations. With this architecture, a new vendor module that needs to add a specific Oem feature can create a new class (e.g. `ContosoRedfishUtils`) that extends the existing `RedfishUtils`. New method(s) can be added to that class (or existing methods overridden) while still being able to leverage all the existing standard methods in the parent class. Then a new vendor module (e.g. `contoso_redfish_command.py`) can be written that is basically a sparse version of `redfish_command.py` that only needs to handle the new or changed vendor commands.
14+
15+
Here is an example module that does what is described above. This example provides a non-standard `CreateBiosConfigJob` command. Here is the code:
16+
17+
```
18+
DOCUMENTATION = '''
19+
---
20+
module: contoso_redfish_command
21+
version_added: "2.7"
22+
short_description: Manages Out-Of-Band controllers using Contoso Oem Redfish APIs
23+
description:
24+
- Builds Redfish URIs locally and sends them to remote OOB controllers to
25+
perform an action.
26+
- For use with operations that require Contoso Oem extensions
27+
options:
28+
category:
29+
required: true
30+
description:
31+
- Category to execute on OOB controller
32+
command:
33+
required: true
34+
description:
35+
- List of commands to execute on OOB controller
36+
baseuri:
37+
required: true
38+
description:
39+
- Base URI of OOB controller
40+
user:
41+
required: true
42+
description:
43+
- User for authentication with OOB controller
44+
password:
45+
required: true
46+
description:
47+
- Password for authentication with OOB controller
48+
49+
author: ""
50+
'''
51+
52+
EXAMPLES = '''
53+
- name: Create BIOS config job
54+
contoso_redfish_command:
55+
category: Systems
56+
command: CreateBiosConfigJob
57+
baseuri: "{{ baseuri }}"
58+
user: "{{ user }}"
59+
password: "{{ password }}"
60+
'''
61+
62+
RETURN = '''
63+
msg:
64+
description: Message with action result or error description
65+
returned: always
66+
type: string
67+
sample: "Action was successful"
68+
'''
69+
70+
import re
71+
from ansible.module_utils.basic import AnsibleModule
72+
from ansible.module_utils.redfish_utils import RedfishUtils, HEADERS
73+
from ansible.module_utils._text import to_native
74+
75+
class ContosoRedfishUtils(RedfishUtils):
76+
77+
def create_bios_config_job(self):
78+
result = {}
79+
key = "Bios"
80+
jobs = "Jobs"
81+
82+
# Search for 'key' entry and extract URI from it
83+
response = self.get_request(self.root_uri + self.systems_uri)
84+
if response['ret'] is False:
85+
return response
86+
result['ret'] = True
87+
data = response['data']
88+
89+
if key not in data:
90+
return {'ret': False, 'msg': "Key %s not found" % key}
91+
92+
bios_uri = data[key]["@odata.id"]
93+
94+
# Extract proper URI
95+
response = self.get_request(self.root_uri + bios_uri)
96+
if response['ret'] is False:
97+
return response
98+
result['ret'] = True
99+
data = response['data']
100+
set_bios_attr_uri = data["@Redfish.Settings"]["SettingsObject"][
101+
"@odata.id"]
102+
103+
payload = {"TargetSettingsURI": set_bios_attr_uri}
104+
response = self.post_request(
105+
self.root_uri + self.manager_uri + "/" + jobs,
106+
payload, HEADERS)
107+
if response['ret'] is False:
108+
return response
109+
110+
response_output = response['resp'].__dict__
111+
job_id = response_output["headers"]["Location"]
112+
job_id = re.search("JID_.+", job_id).group()
113+
# Currently not passing job_id back to user but patch is coming
114+
return {'ret': True, 'msg': "Config job %s created" % job_id}
115+
116+
117+
CATEGORY_COMMANDS_ALL = {
118+
"Systems": ["CreateBiosConfigJob"],
119+
"Accounts": [],
120+
"Manager": []
121+
}
122+
123+
124+
def main():
125+
result = {}
126+
module = AnsibleModule(
127+
argument_spec=dict(
128+
category=dict(required=True),
129+
command=dict(required=True, type='list'),
130+
baseuri=dict(required=True),
131+
user=dict(required=True),
132+
password=dict(required=True, no_log=True)
133+
),
134+
supports_check_mode=False
135+
)
136+
137+
category = module.params['category']
138+
command_list = module.params['command']
139+
140+
# admin credentials used for authentication
141+
creds = {'user': module.params['user'],
142+
'pswd': module.params['password']}
143+
144+
# Build root URI
145+
root_uri = "https://" + module.params['baseuri']
146+
rf_uri = "/redfish/v1/"
147+
rf_utils = ContosoRedfishUtils(creds, root_uri)
148+
149+
# Check that Category is valid
150+
if category not in CATEGORY_COMMANDS_ALL:
151+
module.fail_json(msg=to_native("Invalid Category '%s'. Valid Categories = %s" % (category, CATEGORY_COMMANDS_ALL.keys())))
152+
153+
# Check that all commands are valid
154+
for cmd in command_list:
155+
# Fail if even one command given is invalid
156+
if cmd not in CATEGORY_COMMANDS_ALL[category]:
157+
module.fail_json(msg=to_native("Invalid Command '%s'. Valid Commands = %s" % (cmd, CATEGORY_COMMANDS_ALL[category])))
158+
159+
# Organize by Categories / Commands
160+
161+
if category == "Systems":
162+
# execute only if we find a System resource
163+
result = rf_utils._find_systems_resource(rf_uri)
164+
if result['ret'] is False:
165+
module.fail_json(msg=to_native(result['msg']))
166+
167+
for command in command_list:
168+
if command == "CreateBiosConfigJob":
169+
# execute only if we find a Managers resource
170+
result = rf_utils._find_managers_resource(rf_uri)
171+
if result['ret'] is False:
172+
module.fail_json(msg=to_native(result['msg']))
173+
result = rf_utils.create_bios_config_job()
174+
175+
# Return data back or fail with proper message
176+
if result['ret'] is True:
177+
del result['ret']
178+
module.exit_json(changed=True, msg='Action was successful')
179+
else:
180+
module.fail_json(msg=to_native(result['msg']))
181+
182+
183+
if __name__ == '__main__':
184+
main()
185+
```
186+
187+
Given this new vendor module, playbooks like this can be written that call a mix of tasks using standard and vendor modules. For example, here is a playbook that sets some BIOS attributes using a standard module and then applies the attributes using a vendor module:
188+
189+
```
190+
---
191+
- hosts: myhosts
192+
connection: local
193+
name: Set BIOS attribute - choose below
194+
gather_facts: False
195+
196+
# Updating BIOS settings requires creating a configuration job to implement,
197+
# which then reboots the system.
198+
199+
# BIOS attributes that have been tested
200+
#
201+
# Name Value
202+
# --------------------------------------------------
203+
# OsWatchdogTimer Disabled / Enabled
204+
# ProcVirtualization Disabled / Enabled
205+
# MemTest Disabled / Enabled
206+
# SriovGlobalEnable Disabled / Enabled
207+
208+
vars:
209+
- attribute_name1: SriovGlobalEnable
210+
- attribute_value1: Disabled
211+
- attribute_name2: ProcVirtualization
212+
- attribute_value2: Enabled
213+
214+
tasks:
215+
216+
- name: Set BIOS attribute {{ attribute_name1 }} to {{ attribute_value1 }}
217+
redfish_config:
218+
category: Systems
219+
command: SetBiosAttributes
220+
bios_attr_name: "{{ attribute_name1 }}"
221+
bios_attr_value: "{{ attribute_value1 }}"
222+
baseuri: "{{ baseuri }}"
223+
user: "{{ user }}"
224+
password: "{{ password }}"
225+
226+
- name: Set BIOS attribute {{ attribute_name2 }} to {{ attribute_value2 }}
227+
redfish_config:
228+
category: Systems
229+
command: SetBiosAttributes
230+
bios_attr_name: "{{ attribute_name2 }}"
231+
bios_attr_value: "{{ attribute_value2 }}"
232+
baseuri: "{{ baseuri }}"
233+
user: "{{ user }}"
234+
password: "{{ password }}"
235+
236+
- name: Schedule Config Job - Reboot
237+
contoso_redfish_command:
238+
category: Systems
239+
command: CreateBiosConfigJob
240+
baseuri: "{{ baseuri }}"
241+
user: "{{ user }}"
242+
password: "{{ password }}"
243+
```
244+
245+
Note that the first 2 tasks use a standard module (`redfish_config`) and the last task uses a vendor module (`contoso_redfish_command`).
246+
247+
And here is an example playbook to set the BIOS attributes using all standard modules:
248+
249+
```
250+
---
251+
- hosts: myhosts
252+
connection: local
253+
name: Set BIOS attribute - choose below
254+
gather_facts: False
255+
256+
# Updating BIOS settings requires creating a configuration job to implement,
257+
# which then reboots the system.
258+
259+
# BIOS attributes that have been tested
260+
#
261+
# Name Value
262+
# --------------------------------------------------
263+
# OsWatchdogTimer Disabled / Enabled
264+
# ProcVirtualization Disabled / Enabled
265+
# MemTest Disabled / Enabled
266+
# SriovGlobalEnable Disabled / Enabled
267+
268+
vars:
269+
- attribute_name1: SriovGlobalEnable
270+
- attribute_value1: Disabled
271+
- attribute_name2: ProcVirtualization
272+
- attribute_value2: Enabled
273+
274+
tasks:
275+
276+
- name: Set BIOS attribute {{ attribute_name1 }} to {{ attribute_value1 }}
277+
redfish_config:
278+
category: Systems
279+
command: SetBiosAttributes
280+
bios_attr_name: "{{ attribute_name1 }}"
281+
bios_attr_value: "{{ attribute_value1 }}"
282+
baseuri: "{{ baseuri }}"
283+
user: "{{ user }}"
284+
password: "{{ password }}"
285+
286+
- name: Set BIOS attribute {{ attribute_name2 }} to {{ attribute_value2 }}
287+
redfish_config:
288+
category: Systems
289+
command: SetBiosAttributes
290+
bios_attr_name: "{{ attribute_name2 }}"
291+
bios_attr_value: "{{ attribute_value2 }}"
292+
baseuri: "{{ baseuri }}"
293+
user: "{{ user }}"
294+
password: "{{ password }}"
295+
296+
- name: Reboot
297+
redfish_command:
298+
category: Systems
299+
command: PowerReboot
300+
baseuri: "{{ baseuri }}"
301+
user: "{{ user }}"
302+
password: "{{ password }}"
303+
```

0 commit comments

Comments
 (0)