Skip to content

Commit

Permalink
1.6.0 collection with server maintenance policy and HFP example
Browse files Browse the repository at this point in the history
  • Loading branch information
“dsoper2” committed Nov 2, 2020
1 parent dd5133b commit acf9eab
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 3 deletions.
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace: cisco
name: ucs

# The version of the collection. Must be compatible with semantic versioning
version: 1.5.0
version: 1.6.0

# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md
Expand Down
83 changes: 83 additions & 0 deletions playbooks/fw_download_config_hfp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
#
# Download firmware to the FI and configure Host Firmware Packages (HFP).
# Uses remote fileshare and scp for FW download (server, remote_path, etc. provided through variables):
# Example vars:
# [ucs:vars]
# remote_ip_address=172.28.224.77
# remote_fw_path=/mnt/SHARE/ISOS/UCS_Code/4.1
# remote_username=...
#
# The fw_bundles variable is a list that can be passed on the command line.
# Example:
# ansible-playbook ... -e '{"fw_bundles": ["ucs-k9-bundle-b-series.4.1.2b.B.bin"]}'
#
- hosts: ucs
connection: local
gather_facts: false
vars:
login_info: &login_info
hostname: "{{ inventory_hostname }}"
username: "{{ username | default(omit) }}"
password: "{{ password }}"
tasks:
- name: Download FW to FI
ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.firmware.FirmwareCatalogue
class: FirmwareCatalogue
properties:
parent_mo_or_dn: sys
children:
- module: ucsmsdk.mometa.firmware.FirmwareDownloader
class: FirmwareDownloader
properties:
protocol: scp
server: "{{ remote_ip_address }}"
remote_path: "{{ remote_fw_path }}"
file_name: "{{ item }}"
user: "{{ remote_username }}"
pwd: "{{ remote_password }}"
loop: "{{ fw_bundles }}"
delegate_to: localhost
register: download_result
- name: Query and wait for download if needed
cisco.ucs.ucs_query:
<<: *login_info
distinguished_names: "{{ fw_download_dn }}"
loop: "{{ fw_bundles }}"
vars:
fw_download_dn: "sys/fw-catalogue/dnld-{{ item }}"
delegate_to: localhost
register: query_response
# works with warnings:
# until: query_response['objects']["{{ fw_download_dn }}"]['transfer_state'] == 'downloaded'
until: query_response.objects is search('downloaded')
# retry every 60 seconds for 20 minutes
delay: 60
retries: 20
# regular escapes in a set variable
- set_fact:
match_str: 'ucs-.*?\.(?P<rel>\d\.\d)\.(?P<patch>.*)\.'
# escape the escapes when used directly in strings
- set_fact:
blade_version: "{{ item | regex_replace(match_str + 'B\\.bin', '\\g<rel>(\\g<patch>)B') }}"
loop: "{{ fw_bundles }}"
when: item | regex_search(match_str + 'B\\.bin')
- set_fact:
rack_version: "{{ item | regex_replace(match_str + 'C\\.bin', '\\g<rel>(\\g<patch>)C') }}"
loop: "{{ fw_bundles }}"
when: item | regex_search(match_str + 'C\\.bin')
- name: Config Host FW Package
ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.firmware.FirmwareComputeHostPack
class: FirmwareComputeHostPack
properties:
parent_mo_or_dn: org-root
name: ansible-latest
blade_bundle_version: "{{ blade_version | default(omit) }}"
rack_bundle_version: "{{ rack_version | default(omit) }}"
delegate_to: localhost
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
cisco.ucs.ucs_service_profile_template:
<<: *login_info
name: "{{ template_name }}"
template_type: updating-template
template_type: "{{ template_type }}"
host_firmware_package: "{{ host_firmware_package }}"
server_pool: default
vmedia_policy: "{{ vmedia_policy }}"
boot_policy: vmedia-local
maintenance_policy: "{{ maintenance_policy }}"
2 changes: 1 addition & 1 deletion playbooks/roles/servers/service_profiles/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
<<: *login_info
name: "{{ profile_name }}-{{ '%d' | format(item) }}"
source_template: "{{ template_name }}"
loop: "{{ range(1, num_profiles + 1) | list }}"
loop: "{{ range(1, num_profiles|int + 1) | list }}"
3 changes: 3 additions & 0 deletions playbooks/server_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
hostname: "{{ inventory_hostname }}"
# Names for Service Profiles, Policies, and number of Profiles
template_name: auto-template
template_type: updating-template
host_firmware_package: ansible-latest
maintenance_policy: user-ack
vmedia_policy: cdd-nfs
profile_name: auto-profile
num_profiles: 2
Expand Down
43 changes: 43 additions & 0 deletions playbooks/ucs_server_maintenance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
# Example Playbook: cisco.ucs.ucs_server_maintenance
- hosts: ucs
connection: local
gather_facts: false

tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"

- name: Add Server Maintenance Policy (check_mode)
cisco.ucs.ucs_server_maintenance:
<<: *login_info
name: user-ack
uptime_disr: user-ack
trigger_config: on-next-boot
delegate_to: localhost
check_mode: true

- name: Add Server Maintenance Policy
cisco.ucs.ucs_server_maintenance:
<<: *login_info
name: user-ack
uptime_disr: user-ack
trigger_config: on-next-boot
delegate_to: localhost

- name: Idempotent Add Server Maintenance Policy
cisco.ucs.ucs_server_maintenance:
<<: *login_info
name: user-ack
uptime_disr: user-ack
trigger_config: on-next-boot
delegate_to: localhost
158 changes: 158 additions & 0 deletions plugins/modules/ucs_server_maintenance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# 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

__metaclass__ = type

ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}

DOCUMENTATION = r'''
---
module: ucs_server_maintenance
short_description: Creates Server Maintenance Policy on Cisco UCS Manager
version_added: 2.10
description:
- Configures Server Maintenance Policy on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify Server Maintenance Policy is present and will create if needed.
- If C(absent), will verify Server Maintenance Policy is absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name assigned to the Server Maintenance Policy.
- The Server Maintenance Policy name is case sensitive.
- This name can be between 1 and 16 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- You cannot change this name after the Server Maintenance Policy is created.
required: yes
description:
description:
- A description of the Server Maintenance Package Policy.
- Cisco recommends including information about where and when to use the policy.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
trigger_config:
description:
- This option is used in combination with either User Ack (user-ack) or Timer Automatic (timer-automatic).
- When the On Next Boot option is enabled, the host OS reboot, shutdown, or server reset also triggers the associated FSM to apply the changes.
- Note that de-selecting the On Next Boot option disables the Maintenance Policy on the BMC.
choices: [on-next-boot]
uptime_disr:
description:
- When a Server profile is associated with a Server, or when changes are made to a Server profile that is already associated with a Server, you must reboot the Server to complete the process.
- The Reboot Policy field determines when the reboot occurs for Server associated with any Server profiles that include this maintenance policy.
choices: [immediate, timer-automatic, user-ack]
required: true
requirements:
- ucsmsdk
author:
- Brett Johnson (@brettjohnson008)
'''

EXAMPLES = r'''
- name: Add Server Maintenance Policy
cisco.ucs.ucs_server_maintenance:
hostname: 172.16.143.150
username: admin
password: password
name: user-ack
uptime_disr: user-ack
trigger_config: on-next-boot
'''

RETURN = r'''
#
'''

from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec


def main():
argument_spec = ucs_argument_spec
argument_spec.update(
name=dict(type='str', required=True),
description=dict(type='str', default=''),
trigger_config=dict(type='str', default='', choices=['on-next-boot']),
uptime_disr=dict(type='str', required=True, choices=['immediate', 'timer-automatic', 'user-ack']),
state=dict(type='str', default='present', choices=['present', 'absent']),
)

module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)

ucs = UCSModule(module)

err = False

# UCSModule creation above verifies ucsmsdk is present and exits on failure, so additional imports are done below.
from ucsmsdk.mometa.lsmaint.LsmaintMaintPolicy import LsmaintMaintPolicy

changed = False
try:
mo_exists = False
props_match = False
dn_base = 'org-root'
dn = dn_base + '/maint-' + module.params['name']

mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True

if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
changed = True
else:
if mo_exists:
# check top-level mo props
kwargs = dict(name=module.params['name'])
kwargs['descr'] = module.params['description']
kwargs['trigger_config'] = module.params['trigger_config']
kwargs['uptime_disr'] = module.params['uptime_disr']
if mo.check_prop_match(**kwargs):
props_match = True

if not props_match:
if not module.check_mode:
# create if mo does not already exist
mo = LsmaintMaintPolicy(
parent_mo_or_dn=dn_base,
name=module.params['name'],
descr=module.params['description'],
trigger_config=module.params['trigger_config'],
uptime_disr=module.params['uptime_disr'],
)

ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True

except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)

ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)


if __name__ == '__main__':
main()
Binary file added releases/cisco-ucs-1.6.0.tar.gz
Binary file not shown.

0 comments on commit acf9eab

Please sign in to comment.