#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Dell EMC OpenManage Ansible Modules
# Version 4.4.0
# Copyright (C) 2019-2021 Dell Inc. or its subsidiaries. All Rights Reserved.
# 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
DOCUMENTATION = r'''
---
module: ome_template
short_description: Create, modify, deploy, delete, export, import and clone a template on OpenManage Enterprise
version_added: "2.0.0"
description: "This module creates, modifies, deploys, deletes, exports, imports and clones a template on
OpenManage Enterprise."
extends_documentation_fragment:
- dellemc.openmanage.ome_auth_options
options:
command:
description:
- C(create) creates a new template.
- C(modify) modifies an existing template.
- C(deploy) creates a template-deployment job.
- C(delete) deletes an existing template.
- C(export) exports an existing template.
- C(import) creates a template from a specified configuration text in SCP XML format.
- C(clone) creates a clone of a existing template.
choices: [create, modify, deploy, delete, export, import, clone]
default: create
aliases: ['state']
type: str
template_id:
description:
- ID of the existing template.
- This option is applicable when I(command) is C(modify), C(deploy), C(delete) and C(export).
- This option is mutually exclusive with I(template_name).
type: int
template_name:
description:
- Name of the existing template.
- This option is applicable when I(command) is C(modify), C(deploy), C(delete) and C(export).
- This option is mutually exclusive with I(template_id).
type: str
device_id:
description:
- >-
Specify the list of targeted device ID(s) when I(command) is C(deploy). When I (command) is C(create),
specify the ID of a single device.
- Either I(device_id) or I(device_service_tag) is mandatory or both can be applicable.
type: list
elements: int
default: []
device_service_tag:
description:
- >-
Specify the list of targeted device service tags when I (command) is C(deploy). When I(command) is C(create),
specify the service tag of a single device.
- Either I(device_id) or I(device_service_tag) is mandatory or both can be applicable.
type: list
elements: str
default: []
device_group_names:
description:
- Specify the list of groups when I (command) is C(deploy).
- Provide at least one of the mandatory options I(device_id), I(device_service_tag), or I(device_group_names).
type: list
elements: str
default: []
template_view_type:
description:
- Select the type of view of the OME template.
- This is applicable when I(command) is C(create),C(clone) and C(import).
choices: [Deployment, Compliance, Inventory, Sample, None]
type: str
default: Deployment
attributes:
type: dict
description:
- >-
Payload data for the template operations. All the variables in this option are added as payload for C(create),
C(modify), C(deploy), C(import), and C(clone) operations. It takes the following attributes.
- >-
Attributes: List of dictionaries of attributes (if any) to be modified in the deployment template. This is
applicable when I(command) is C(deploy) and C(modify).
- >-
Name: Name of the template. This is mandatory when I(command) is C(create), C(import), C(clone), and
optional when I(command) is C(modify).
- >-
Description: Description for the template. This is applicable when I(command) is C(create) or C(modify).
- >-
Fqdds: This allows to create a template using components from a specified reference server. One or more, of the
following values must be specified in a comma-separated string: iDRAC, System, BIOS, NIC, LifeCycleController,
RAID, and EventFilters. If none of the values are specified, the default value 'All' is selected.
This is applicable when I (command) is C(create).
- >-
Options: Options to control device shutdown or end power state post template deployment. This is applicable
for C(deploy) operation.
- >-
Schedule: Provides options to schedule the deployment task immediately, or at a specified time. This is
applicable when I(command) is C(deploy).
- >-
NetworkBootIsoModel: Payload to specify the ISO deployment details. This is applicable when I(command) is
C(deploy).
- >-
Content: The XML content of template. This is applicable when I(command) is C(import).
- >-
Type: Template type ID, indicating the type of device for which configuration is supported, such as chassis
and servers. This is applicable when I(command) is C(import).
- >-
TypeId: Template type ID, indicating the type of device for which configuration is supported, such as chassis
and servers. This is applicable when I(command) is C(create).
- >-
Refer OpenManage Enterprise API Reference Guide for more details.
requirements:
- "python >= 2.7.5"
author: "Jagadeesh N V (@jagadeeshnv)"
notes:
- Run this module from a system that has direct access to DellEMC OpenManage Enterprise.
- This module does not support C(check_mode).
'''
EXAMPLES = r'''
---
- name: Create a template from a reference device
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
device_id: 25123
attributes:
Name: "New Template"
Description: "New Template description"
- name: Modify template name, description, and attribute value
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "modify"
template_id: 12
attributes:
Name: "New Custom Template"
Description: "Custom Template Description"
# Attributes to be modified in the template.
# For information on any attribute id, use API /TemplateService/Templates(Id)/Views(Id)/AttributeViewDetails
# This section is optional
Attributes:
- Id: 1234
Value: "Test Attribute"
IsIgnored: false
- name: Deploy template on multiple devices
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "deploy"
template_id: 12
device_id:
- 12765
- 10173
device_service_tag:
- 'SVTG123'
- 'SVTG456'
- name: Deploy template on groups
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "deploy"
template_id: 12
device_group_names:
- server_group_1
- server_group_2
- name: Deploy template on multiple devices along with the attributes values to be modified on the target devices
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "deploy"
template_id: 12
device_id:
- 12765
- 10173
device_service_tag:
- 'SVTG123'
attributes:
# Device specific attributes to be modified during deployment.
# For information on any attribute id, use API /TemplateService/Templates(Id)/Views(Id)/AttributeViewDetails
# This section is optional
Attributes:
# specific device where attribute to be modified at deployment run-time.
# The DeviceId should be mentioned above in the 'device_id' section.
# Service tags not allowed.
- DeviceId: 12765
Attributes:
- Id : 15645
Value : "0.0.0.0"
IsIgnored : false
- DeviceId: 10173
Attributes:
- Id : 18968,
Value : "hostname-1"
IsIgnored : false
- name: Deploy template and Operating System (OS) on multiple devices
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "deploy"
template_id: 12
device_id:
- 12765
device_service_tag:
- 'SVTG123'
attributes:
# Include this to install OS on the devices.
# This section is optional
NetworkBootIsoModel:
BootToNetwork: true
ShareType: "NFS"
IsoTimeout: 1 # allowable values(1,2,4,8,16) in hours
IsoPath: "/home/iso_path/filename.iso"
ShareDetail:
IpAddress: "192.168.0.2"
ShareName: "sharename"
User: "share_user"
Password: "share_password"
Options:
EndHostPowerState: 1
ShutdownType: 0
TimeToWaitBeforeShutdown: 300
Schedule:
RunLater: true
RunNow: false
- name: "Deploy template on multiple devices and changes the device-level attributes. After the template is deployed,
install OS using its image"
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "deploy"
template_id: 12
device_id:
- 12765
- 10173
device_service_tag:
- 'SVTG123'
- 'SVTG456'
attributes:
Attributes:
- DeviceId: 12765
Attributes:
- Id : 15645
Value : "0.0.0.0"
IsIgnored : false
- DeviceId: 10173
Attributes:
- Id : 18968,
Value : "hostname-1"
IsIgnored : false
NetworkBootIsoModel:
BootToNetwork: true
ShareType: "NFS"
IsoTimeout: 1 # allowable values(1,2,4,8,16) in hours
IsoPath: "/home/iso_path/filename.iso"
ShareDetail:
IpAddress: "192.168.0.2"
ShareName: "sharename"
User: "share_user"
Password: "share_password"
Options:
EndHostPowerState: 1
ShutdownType: 0
TimeToWaitBeforeShutdown: 300
Schedule:
RunLater: true
RunNow: false
- name: Delete template
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "delete"
template_id: 12
- name: Export a template
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "export"
template_id: 12
# Start of example to export template to a local xml file
- name: Export template to a local xml file
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "export"
template_name: "my_template"
register: result
- name: Save template into a file
ansible.builtin.copy:
content: "{{ result.Content}}"
dest: "/path/to/exported_template.xml"
# End of example to export template to a local xml file
- name: Clone a template
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "clone"
template_id: 12
attributes:
Name: "New Cloned Template Name"
- name: Import template from XML content
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "import"
attributes:
Name: "Imported Template Name"
# Template Type from TemplateService/TemplateTypes
Type: 2
# xml string content
Content: "\n\nTrue\nClear\n
\n\nReady
\nNo\n\n
\nReady\n
No\n\n\n"
- name: Import template from local XML file
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "import"
attributes:
Name: "Imported Template Name"
Type: 2
Content: "{{ lookup('ansible.builtin.file.', '/path/to/xmlfile') }}"
- name: "Deploy template and Operating System (OS) on multiple devices."
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "deploy"
template_id: 12
device_id:
- 12765
device_service_tag:
- 'SVTG123'
attributes:
# Include this to install OS on the devices.
# This section is optional
NetworkBootIsoModel:
BootToNetwork: true
ShareType: "CIFS"
IsoTimeout: 1 # allowable values(1,2,4,8,16) in hours
IsoPath: "/home/iso_path/filename.iso"
ShareDetail:
IpAddress: "192.168.0.2"
ShareName: "sharename"
User: "share_user"
Password: "share_password"
Options:
EndHostPowerState: 1
ShutdownType: 0
TimeToWaitBeforeShutdown: 300
Schedule:
RunLater: true
RunNow: false
- name: Create a compliance template from reference device
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "create"
device_service_tag:
- "SVTG123"
template_view_type: "Compliance"
attributes:
Name: "Configuration Compliance"
Description: "Configuration Compliance Template"
Fqdds: "BIOS"
- name: Import a compliance template from XML file
dellemc.openmanage.ome_template:
hostname: "192.168.0.1"
username: "username"
password: "password"
command: "import"
template_view_type: "Compliance"
attributes:
Name: "Configuration Compliance"
Content: "{{ lookup('ansible.builtin.file', './test.xml') }}"
Type: 2
'''
RETURN = r'''
---
msg:
description: Overall status of the template operation.
returned: always
type: str
sample: "Successfully created a template with ID 23"
return_id:
description: ID of the template for C(create), C(modify), C(import) and C(clone) or task created in case of C(deploy).
returned: success, when I(command) is C(create), C(modify), C(import), C(clone) and C(deploy)
type: int
sample: 12
TemplateId:
description: ID of the template for C(export).
returned: success, when I(command) is C(export)
type: int
sample: 13
Content:
description: XML content of the exported template. This content can be written to a xml file.
returned: success, when I(command) is C(export)
type: str
sample: "\n\nTrue\nClear\n\n\n
Ready\nNo\n
\n\nReady
\nNo\n\n\n"
error_info:
description: Details of the HTTP Error.
returned: on HTTP error
type: dict
sample: {
"error": {
"code": "Base.1.0.GeneralError",
"message": "A general error has occurred. See ExtendedInfo for more information.",
"@Message.ExtendedInfo": [
{
"MessageId": "GEN1234",
"RelatedProperties": [],
"Message": "Unable to process the request because an error occurred.",
"MessageArgs": [],
"Severity": "Critical",
"Resolution": "Retry the operation. If the issue persists, contact your system administrator."
}
]
}
}
'''
import json
from ssl import SSLError
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.dellemc.openmanage.plugins.module_utils.ome import RestOME
from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
from ansible.module_utils.urls import ConnectionError, SSLValidationError
TEMPLATES_URI = "TemplateService/Templates"
TEMPLATE_PATH = "TemplateService/Templates({template_id})"
TEMPALTE_ACTION = "TemplateService/Actions/TemplateService.{op}"
DEVICE_URI = "DeviceService/Devices"
GROUP_URI = "GroupService/Groups"
def get_group_devices_all(rest_obj, uri):
total_items = []
next_link = uri
while next_link:
resp = rest_obj.invoke_request('GET', next_link)
data = resp.json_data
total_items.extend(data.get("value", []))
next_link_list = str(data.get('@odata.nextLink', '')).split('/api')
next_link = next_link_list[-1]
return total_items
def get_group(rest_obj, module, group_name):
query_param = {"$filter": "Name eq '{0}'".format(group_name)}
group_req = rest_obj.invoke_request("GET", GROUP_URI, query_param=query_param)
for grp in group_req.json_data.get('value'):
if grp['Name'] == group_name:
return grp
module.fail_json(msg="Group name '{0}' is invalid. Please provide a valid group name.".format(group_name))
def get_group_details(rest_obj, module):
group_name_list = module.params.get('device_group_names')
device_ids = []
for group_name in group_name_list:
group = get_group(rest_obj, module, group_name)
group_uri = GROUP_URI + "({0})/Devices".format(group['Id'])
group_device_list = get_group_devices_all(rest_obj, group_uri)
device_ids.extend([dev['Id'] for dev in group_device_list])
return device_ids
def get_device_ids(module, rest_obj):
"""Getting the list of device ids filtered from the device inventory."""
target_ids = []
if module.params.get('device_service_tag') or module.params.get('device_id'):
# device_list = get_group_devices_all(rest_obj, DEVICE_URI)
device_list = rest_obj.get_all_report_details(DEVICE_URI)['report_list']
device_tag_id_map = dict([(device.get('DeviceServiceTag'), device.get('Id')) for device in device_list])
device_id = module.params.get('device_id')
invalid_ids = set(device_id) - set(device_tag_id_map.values())
if invalid_ids:
fail_module(module, msg="Unable to complete the operation because the entered target device"
" id(s) '{0}' are invalid.".format(",".join(list(map(str, set(invalid_ids))))))
target_ids.extend(device_id)
service_tags = module.params.get('device_service_tag')
invalid_tags = set(service_tags) - set(device_tag_id_map.keys())
if invalid_tags:
fail_module(module, msg="Unable to complete the operation because the entered target service"
" tag(s) '{0}' are invalid.".format(",".join(set(invalid_tags))))
for tag in service_tags: # append ids for service tags
target_ids.append(device_tag_id_map.get(tag))
if module.params.get('device_group_names'):
target_ids.extend(get_group_details(rest_obj, module))
return list(set(target_ids)) # set to eliminate duplicates
def get_view_id(rest_obj, viewstr):
resp = rest_obj.invoke_request('GET', "TemplateService/TemplateViewTypes")
if resp.success and resp.json_data.get('value'):
tlist = resp.json_data.get('value', [])
for xtype in tlist:
if xtype.get('Description', "") == viewstr:
return xtype.get('Id')
viewmap = {"Deployment": 2, "Compliance": 1, "Inventory": 3, "Sample": 4, "None": 0}
return viewmap.get(viewstr)
def get_type_id_valid(rest_obj, typeid):
resp = rest_obj.invoke_request('GET', "TemplateService/TemplateTypes")
if resp.success and resp.json_data.get('value'):
tlist = resp.json_data.get('value', [])
for xtype in tlist:
if xtype.get('Id') == typeid: # use Name if str is passed
return True
return False
def get_create_payload(module_params, deviceid, view_id):
create_payload = {"Fqdds": "All",
"ViewTypeId": view_id}
if isinstance(module_params.get("attributes"), dict):
attrib_dict = module_params.get("attributes").copy()
typeid = attrib_dict.get("Type") and attrib_dict.get("Type") or attrib_dict.get("TypeId")
if typeid:
create_payload["TypeId"] = typeid
attrib_dict.pop("Type", None) # remove if exists as it is not required for create payload
create_payload.update(attrib_dict)
create_payload["SourceDeviceId"] = int(deviceid)
return create_payload
def get_modify_payload(module_params, template_id, template_dict):
modify_payload = {}
if isinstance(module_params.get("attributes"), dict):
modify_payload.update(module_params.get("attributes"))
modify_payload['Id'] = template_id
# Update with old template values
if not modify_payload.get("Name"):
modify_payload["Name"] = template_dict["Name"]
if not modify_payload.get("Description"):
modify_payload["Description"] = template_dict["Description"]
return modify_payload
def get_deploy_payload(module_params, deviceidlist, template_id):
deploy_payload = {}
if isinstance(module_params.get("attributes"), dict):
deploy_payload.update(module_params.get("attributes"))
deploy_payload["Id"] = template_id
deploy_payload["TargetIds"] = deviceidlist
return deploy_payload
def get_import_payload(module, rest_obj, view_id):
attrib_dict = module.params.get("attributes").copy()
import_payload = {}
import_payload["Name"] = attrib_dict.pop("Name")
import_payload["ViewTypeId"] = view_id
import_payload["Type"] = 2
typeid = attrib_dict.get("Type") and attrib_dict.get("Type") or attrib_dict.get("TypeId")
if typeid:
if get_type_id_valid(rest_obj, typeid):
import_payload["Type"] = typeid # Type is mandatory for import
else:
fail_module(module, msg="Type provided for 'import' operation is invalid")
import_payload["Content"] = attrib_dict.pop("Content")
if isinstance(attrib_dict, dict):
attrib_dict.pop("TypeId", None) # remove if exists as it is not required for import payload
import_payload.update(attrib_dict)
return import_payload
def get_clone_payload(module_params, template_id, view_id):
attrib_dict = module_params.get("attributes").copy()
clone_payload = {}
clone_payload["SourceTemplateId"] = template_id
clone_payload["NewTemplateName"] = attrib_dict.pop("Name")
clone_payload["ViewTypeId"] = view_id
if isinstance(attrib_dict, dict):
clone_payload.update(attrib_dict)
return clone_payload
def get_template_by_id(module, rest_obj, template_id):
path = TEMPLATE_PATH.format(template_id=template_id)
template_req = rest_obj.invoke_request("GET", path)
if template_req.success:
return template_req.json_data
else:
fail_module(module, msg="Unable to complete the operation because the"
" requested template is not present.")
def get_template_by_name(template_name, module, rest_obj):
"""Filter out specific template based on name, and it returns template_id.
:param template_name: string
:param module: dictionary
:param rest_obj: object
:return: template_id: integer
"""
template_id = None
template = None
template_path = TEMPLATES_URI
query_param = {"$filter": "Name eq '{0}'".format(template_name)}
template_req = rest_obj.invoke_request("GET", template_path, query_param=query_param)
for each in template_req.json_data.get('value'):
if each['Name'] == template_name:
template_id = each['Id']
template = each
break
else:
fail_module(module, msg="Unable to complete the operation because the"
" requested template with name {0} is not present.".format(template_name))
return template, template_id
def _get_resource_parameters(module, rest_obj):
command = module.params.get("command")
rest_method = 'POST'
payload = {}
template_id = module.params.get("template_id")
template_name = module.params.get("template_name")
if template_name:
template, template_id = get_template_by_name(template_name, module, rest_obj)
if command not in ["import", "create"] and template_id is None:
fail_module(module, msg="Enter a valid template_name or template_id")
if command == "create":
devid_list = get_device_ids(module, rest_obj)
if len(devid_list) != 1:
fail_module(module, msg="Create template requires only one reference device")
view_id = get_view_id(rest_obj, module.params['template_view_type'])
payload = get_create_payload(module.params, devid_list[0], view_id)
path = TEMPLATES_URI
elif command == "modify":
path = TEMPLATE_PATH.format(template_id=template_id)
template_dict = get_template_by_id(module, rest_obj, template_id)
payload = get_modify_payload(module.params, template_id, template_dict)
rest_method = 'PUT'
elif command == "delete":
path = TEMPLATE_PATH.format(template_id=template_id)
rest_method = 'DELETE'
elif command == "export":
path = TEMPALTE_ACTION.format(op="Export")
payload = {'TemplateId': template_id}
elif command == "deploy":
devid_list = get_device_ids(module, rest_obj)
if not devid_list:
fail_module(module, msg="There are no devices provided for deploy operation")
path = TEMPALTE_ACTION.format(op="Deploy")
payload = get_deploy_payload(module.params, devid_list, template_id)
elif command == "clone":
view_id = get_view_id(rest_obj, module.params['template_view_type'])
path = TEMPALTE_ACTION.format(op="Clone")
payload = get_clone_payload(module.params, template_id, view_id)
else:
view_id = get_view_id(rest_obj, module.params['template_view_type'])
path = TEMPALTE_ACTION.format(op="Import")
payload = get_import_payload(module, rest_obj, view_id)
return path, payload, rest_method
def _validate_inputs(module):
"""validates input parameters"""
command = module.params.get("command")
if command in ["create", "deploy"]:
dev_id = module.params["device_id"]
dev_st = module.params["device_service_tag"]
if None in dev_id or None in dev_st:
fail_module(module, msg="Argument device_id or device_service_tag has null values")
attrib_dict = {}
if module.params.get("attributes"):
attrib_dict = module.params.get("attributes")
if command in ["import", "clone", "create"]:
if not attrib_dict.get("Name"):
fail_module(module, msg="Argument 'Name' required in attributes for {0} operation".format(command))
if command == "import":
if not attrib_dict.get("Content"):
fail_module(module, msg="Argument 'Content' required in attributes for {0} operation".format(command))
def password_no_log(attributes):
if isinstance(attributes, dict):
netdict = attributes.get("NetworkBootIsoModel")
if isinstance(netdict, dict):
sharedet = netdict.get("ShareDetail")
if isinstance(sharedet, dict) and 'Password' in sharedet:
sharedet['Password'] = "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
def fail_module(module, **failmsg):
password_no_log(module.params.get("attributes"))
module.fail_json(**failmsg)
def exit_module(module, response):
password_no_log(module.params.get("attributes"))
resp = None
my_change = True
command = module.params.get('command')
result = {}
if command in ["create", "modify", "deploy", "import", "clone"]:
result["return_id"] = response.json_data
resp = result["return_id"]
if command == 'deploy' and result["return_id"] == 0:
result["failed"] = True
command = 'deploy_fail'
my_change = False
if command == 'export':
my_change = False
result = response.json_data
msg_dict = {'create': "Successfully created a template with ID {0}".format(resp),
'modify': "Successfully modified the template with ID {0}".format(resp),
'deploy': "Successfully created the template-deployment job with ID {0}".format(resp),
'deploy_fail': 'Failed to deploy template.',
'delete': "Deleted successfully",
'export': "Exported successfully",
'import': "Imported successfully",
'clone': "Cloned successfully"}
module.exit_json(msg=msg_dict.get(command), changed=my_change, **result)
def main():
module = AnsibleModule(
argument_spec={
"hostname": {"required": True, "type": 'str'},
"username": {"required": True, "type": 'str'},
"password": {"required": True, "type": 'str', "no_log": True},
"port": {"required": False, "default": 443, "type": 'int'},
"command": {"required": False, "default": "create", "aliases": ['state'],
"choices": ['create', 'modify', 'deploy', 'delete', 'export', 'import', 'clone']},
"template_id": {"required": False, "type": 'int'},
"template_name": {"required": False, "type": 'str'},
"template_view_type": {"required": False, "default": 'Deployment',
"choices": ['Deployment', 'Compliance', 'Inventory', 'Sample', 'None']},
"device_id": {"required": False, "type": 'list', "default": [], "elements": 'int'},
"device_service_tag": {"required": False, "type": 'list', "default": [], "elements": 'str'},
"device_group_names": {"required": False, "type": 'list', "default": [], "elements": 'str'},
"attributes": {"required": False, "type": 'dict'},
},
required_if=[
['command', 'create', ['attributes']],
['command', 'modify', ['attributes']],
['command', 'import', ['attributes']],
['command', 'modify', ['template_id', 'template_name'], True],
['command', 'delete', ['template_id', 'template_name'], True],
['command', 'export', ['template_id', 'template_name'], True],
['command', 'clone', ['template_id', 'template_name'], True],
['command', 'deploy', ['template_id', 'template_name'], True],
['command', 'deploy', ['device_id', 'device_service_tag', 'device_group_names'], True],
],
mutually_exclusive=[["template_id", "template_name"]],
supports_check_mode=False)
try:
_validate_inputs(module)
with RestOME(module.params, req_session=True) as rest_obj:
path, payload, rest_method = _get_resource_parameters(module, rest_obj)
resp = rest_obj.invoke_request(rest_method, path, data=payload)
if resp.success:
exit_module(module, resp)
except HTTPError as err:
fail_module(module, msg=str(err), error_info=json.load(err))
except URLError as err:
password_no_log(module.params.get("attributes"))
module.exit_json(msg=str(err), unreachable=True)
except (IOError, SSLError, SSLValidationError, ConnectionError, TypeError, ValueError, KeyError) as err:
fail_module(module, msg=str(err))
if __name__ == '__main__':
main()