1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3 4# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 6from __future__ import absolute_import, division, print_function 7__metaclass__ = type 8 9ANSIBLE_METADATA = {'metadata_version': '1.1', 10 'status': ['preview'], 11 'supported_by': 'community'} 12 13DOCUMENTATION = r''' 14--- 15module: intersight_boot_order_policy 16short_description: Boot Order policy configuration for Cisco Intersight 17description: 18 - Boot Order policy configuration for Cisco Intersight. 19 - Used to configure Boot Order servers and timezone settings on Cisco Intersight managed devices. 20 - For more information see L(Cisco Intersight,https://intersight.com/apidocs). 21extends_documentation_fragment: intersight 22options: 23 state: 24 description: 25 - If C(present), will verify the resource is present and will create if needed. 26 - If C(absent), will verify the resource is absent and will delete if needed. 27 choices: [present, absent] 28 default: present 29 organization: 30 description: 31 - The name of the Organization this resource is assigned to. 32 - Profiles and Policies that are created within a Custom Organization are applicable only to devices in the same Organization. 33 default: default 34 name: 35 description: 36 - The name assigned to the Boot Order policy. 37 - The name must be between 1 and 62 alphanumeric characters, allowing special characters :-_. 38 required: true 39 tags: 40 description: 41 - List of tags in Key:<user-defined key> Value:<user-defined value> format. 42 type: list 43 description: 44 description: 45 - The user-defined description of the Boot Order policy. 46 - Description can contain letters(a-z, A-Z), numbers(0-9), hyphen(-), period(.), colon(:), or an underscore(_). 47 aliases: [descr] 48 configured_boot_mode: 49 description: 50 - Sets the BIOS boot mode. 51 - UEFI uses the GUID Partition Table (GPT) whereas Legacy mode uses the Master Boot Record (MBR) partitioning scheme. 52 choices: [Legacy, Uefi] 53 default: Legacy 54 uefi_enable_secure_boot: 55 description: 56 - Secure boot enforces that device boots using only software that is trusted by the Original Equipment Manufacturer (OEM). 57 - Option is only used if configured_boot_mode is set to Uefi. 58 type: bool 59 default: false 60 boot_devices: 61 description: 62 - List of Boot Devices configured on the endpoint. 63 type: list 64 suboptions: 65 enabled: 66 description: 67 - Specifies if the boot device is enabled or disabled. 68 type: bool 69 default: true 70 device_type: 71 description: 72 - Device type used with this boot option. 73 - Choices are based on each device title in the API schema. 74 choices: [iSCSI, Local CDD, Local Disk, NVMe, PCH Storage, PXE, SAN, SD Card, UEFI Shell, USB, Virtual Media] 75 required: true 76 device_name: 77 description: 78 - A name that helps identify a boot device. 79 - It can be any string that adheres to the following constraints. 80 - It should start and end with an alphanumeric character. 81 - It can have underscores and hyphens. 82 - It cannot be more than 30 characters. 83 required: true 84 network_slot: 85 description: 86 - The slot id of the controller for the iscsi and pxe device. 87 - Option is used when device_type is iscsi and pxe. 88 choices: [1 - 255, MLOM, L, L1, L2, OCP] 89 port: 90 description: 91 - The port id of the controller for the iscsi and pxe device. 92 - Option is used when device_type is iscsi and pxe. 93 - The port id need to be an integer from 0 to 255. 94 controller_slot: 95 description: 96 - The slot id of the controller for the local disk device. 97 - Option is used when device_type is local_disk. 98 choices: [1-255, M, HBA, SAS, RAID, MRAID, MSTOR-RAID] 99 bootloader_name: 100 description: 101 - Details of the bootloader to be used during boot from local disk. 102 - Option is used when device_type is local_disk and configured_boot_mode is Uefi. 103 bootloader_description: 104 description: 105 - Details of the bootloader to be used during boot from local disk. 106 - Option is used when device_type is local_disk and configured_boot_mode is Uefi. 107 bootloader_path: 108 description: 109 - Details of the bootloader to be used during boot from local disk. 110 - Option is used when device_type is local_disk and configured_boot_mode is Uefi. 111 ip_type: 112 description: 113 - The IP Address family type to use during the PXE Boot process. 114 - Option is used when device_type is pxe. 115 chocies: [None, IPv4, IPv6] 116 default: None 117 interface_source: 118 description: 119 - Lists the supported Interface Source for PXE device. 120 - Option is used when device_type is pxe. 121 choices: [name, mac, port] 122 default: name 123 intefrace_name: 124 description: 125 - The name of the underlying virtual ethernet interface used by the PXE boot device. 126 - Option is used when device_type is pxe and interface_source is name. 127 mac_address: 128 description: 129 - The MAC Address of the underlying virtual ethernet interface used by the PXE boot device. 130 - Option is used when device_type is pxe and interface_source is mac. 131 sd_card_subtype: 132 description: 133 - The subtype for the selected device type. 134 - Option is used when device_type is sd_card. 135 choices: [None, flex-util, flex-flash, SDCARD] 136 default: None 137 lun: 138 description: 139 - The Logical Unit Number (LUN) of the device. 140 - Option is used when device_type is pch, san and sd_card. 141 - The LUN need to be an integer from 0 to 255. 142 usb_subtype: 143 description: 144 - The subtype for the selected device type. 145 - Option is used when device_type is usb. 146 choices: [None, usb-cd, usb-fdd, usb-hdd] 147 default: None 148 virtual_media_subtype: 149 description: 150 - The subtype for the selected device type. 151 - Option is used when device_type is virtual_media. 152 choices: [None, cimc-mapped-dvd, cimc-mapped-hdd, kvm-mapped-dvd, kvm-mapped-hdd, kvm-mapped-fdd] 153 default: None 154author: 155 - Tse Kai "Kevin" Chan (@BrightScale) 156version_added: '2.10' 157''' 158 159EXAMPLES = r''' 160- name: Configure Boot Order Policy 161 cisco.intersight.intersight_boot_order_policy: 162 api_private_key: "{{ api_private_key }}" 163 api_key_id: "{{ api_key_id }}" 164 organization: DevNet 165 name: COS-Boot 166 description: Boot Order policy for COS 167 tags: 168 - Key: Site 169 Value: RCDN 170 configured_boot_mode: legacy 171 boot_devices: 172 - device_type: Local Disk 173 device_name: Boot-Lun 174 controller_slot: MRAID 175 176- name: Delete Boot Order Policy 177 cisco.intersight.intersight_boot_policy: 178 api_private_key: "{{ api_private_key }}" 179 api_key_id: "{{ api_key_id }}" 180 organization: DevNet 181 name: COS-Boot 182 state: absent 183''' 184 185RETURN = r''' 186api_repsonse: 187 description: The API response output returned by the specified resource. 188 returned: always 189 type: dict 190 sample: 191 "api_response": { 192 "Name": "COS-Boot", 193 "ObjectType": "boot.Policy", 194 "Tags": [ 195 { 196 "Key": "Site", 197 "Value": "RCDN" 198 } 199 ] 200 } 201''' 202 203 204from ansible.module_utils.basic import AnsibleModule 205from ansible_collections.cisco.intersight.plugins.module_utils.intersight import IntersightModule, intersight_argument_spec 206 207 208def main(): 209 boot_device = dict( 210 enabled=dict(type='bool', default=True), 211 device_type=dict( 212 type='str', 213 choices=[ 214 'iSCSI', 215 'Local CDD', 216 'Local Disk', 217 'NVMe', 218 'PCH Storage', 219 'PXE', 220 'SAN', 221 'SD Card', 222 'UEFI Shell', 223 'USB', 224 'Virtual Media', 225 ], 226 required=True, 227 ), 228 device_name=dict(type='str', required=True), 229 # iscsi and pxe options 230 network_slot=dict(type='str', default=''), 231 port=dict(type='int', default=0), 232 # local disk options 233 controller_slot=dict(type='str', default=''), 234 # bootloader options 235 bootloader_name=dict(type='str', default=''), 236 bootloader_description=dict(type='str', default=''), 237 bootloader_path=dict(type='str', default=''), 238 # pxe only options 239 ip_type=dict( 240 type='str', 241 choices=[ 242 'None', 243 'IPv4', 244 'IPv6' 245 ], 246 default='None' 247 ), 248 interface_source=dict( 249 type='str', 250 choices=[ 251 'name', 252 'mac', 253 'port' 254 ], 255 default='name' 256 ), 257 interface_name=dict(type='str', default=''), 258 mac_address=dict(type='str', defualt=''), 259 # sd card options 260 sd_card_subtype=dict( 261 type='str', 262 choices=[ 263 'None', 264 'flex-util', 265 'flex-flash', 266 'SDCARD' 267 ], 268 default='None', 269 ), 270 # lun for pch, san, sd_card 271 lun=dict(type='int', default=0), 272 # usb options 273 usb_subtype=dict( 274 type='str', 275 choices=[ 276 'None', 277 'usb-cd', 278 'usb-fdd', 279 'usb-hdd' 280 ], 281 default='None', 282 ), 283 # virtual media options 284 virtual_media_subtype=dict( 285 type='str', 286 choices=[ 287 'None', 288 'cimc-mapped-dvd', 289 'cimc-mapped-hdd', 290 'kvm-mapped-dvd', 291 'kvm-mapped-hdd', 292 'kvm-mapped-fdd' 293 ], 294 default='None', 295 ), 296 ) 297 argument_spec = intersight_argument_spec 298 argument_spec.update( 299 state=dict(type='str', choices=['present', 'absent'], default='present'), 300 organization=dict(type='str', default='default'), 301 name=dict(type='str', required=True), 302 description=dict(type='str', aliases=['descr'], default=''), 303 tags=dict(type='list', default=[]), 304 configured_boot_mode=dict(type='str', choices=['Legacy', 'Uefi'], default='Legacy'), 305 uefi_enable_secure_boot=dict(type='bool', default=False), 306 boot_devices=dict(type='list', elements='dict', options=boot_device), 307 ) 308 309 module = AnsibleModule( 310 argument_spec, 311 supports_check_mode=True, 312 ) 313 314 intersight = IntersightModule(module) 315 intersight.result['api_response'] = {} 316 intersight.result['trace_id'] = '' 317 # 318 # Argument spec above, resource path, and API body should be the only code changed in each policy module 319 # 320 # Resource path used to configure policy 321 resource_path = '/boot/PrecisionPolicies' 322 # Define API body used in compares or create 323 intersight.api_body = { 324 'Organization': { 325 'Name': intersight.module.params['organization'], 326 }, 327 'Name': intersight.module.params['name'], 328 'Tags': intersight.module.params['tags'], 329 'Description': intersight.module.params['description'], 330 'ConfiguredBootMode': intersight.module.params['configured_boot_mode'], 331 "EnforceUefiSecureBoot": intersight.module.params['uefi_enable_secure_boot'], 332 'BootDevices': [], 333 } 334 if intersight.module.params.get('boot_devices'): 335 for device in intersight.module.params['boot_devices']: 336 if device['device_type'] == 'iSCSI': 337 intersight.api_body['BootDevices'].append( 338 { 339 "ClassId": "boot.Iscsi", 340 "ObjectType": "boot.Iscsi", 341 "Enabled": device['enabled'], 342 "Name": device['device_name'], 343 "Slot": device['network_slot'], 344 "Port": device['port'], 345 } 346 ) 347 elif device['device_type'] == 'Local CDD': 348 intersight.api_body['BootDevices'].append( 349 { 350 "ClassId": "boot.LocalCDD", 351 "ObjectType": "boot.LocalCDD", 352 "Enabled": device['enabled'], 353 "Name": device['device_name'], 354 } 355 ) 356 elif device['device_type'] == 'Local Disk': 357 intersight.api_body['BootDevices'].append( 358 { 359 "ClassId": "boot.LocalDisk", 360 "ObjectType": "boot.LocalDisk", 361 "Enabled": device['enabled'], 362 "Name": device['device_name'], 363 "Slot": device['controller_slot'], 364 "Bootloader": { 365 "ClassId": "boot.Bootloader", 366 "ObjectType": "boot.Bootloader", 367 "Description": device['bootloader_description'], 368 "Name": device['bootloader_name'], 369 "Path": device['bootloader_path'], 370 }, 371 } 372 ) 373 elif device['device_type'] == 'NVMe': 374 intersight.api_body['BootDevices'].append( 375 { 376 "ClassId": "boot.NVMe", 377 "ObjectType": "boot.NVMe", 378 "Enabled": device['enabled'], 379 "Name": device['device_name'], 380 "Bootloader": { 381 "ClassId": "boot.Bootloader", 382 "ObjectType": "boot.Bootloader", 383 "Description": device['bootloader_description'], 384 "Name": device['bootloader_name'], 385 "Path": device['bootloader_path'], 386 }, 387 } 388 ) 389 elif device['device_type'] == 'PCH Storage': 390 intersight.api_body['BootDevices'].append( 391 { 392 "ClassId": "boot.PchStorage", 393 "ObjectType": "boot.PchStorage", 394 "Enabled": device['enabled'], 395 "Name": device['device_name'], 396 "Bootloader": { 397 "ClassId": "boot.Bootloader", 398 "ObjectType": "boot.Bootloader", 399 "Description": device['bootloader_description'], 400 "Name": device['bootloader_name'], 401 "Path": device['bootloader_path'], 402 }, 403 "Lun": device['lun'], 404 } 405 ) 406 elif device['device_type'] == 'PXE': 407 intersight.api_body['BootDevices'].append( 408 { 409 "ClassId": "boot.Pxe", 410 "ObjectType": "boot.Pxe", 411 "Enabled": device['enabled'], 412 "Name": device['device_name'], 413 "IpType": device['ip_type'], 414 "InterfaceSource": device['interface_source'], 415 "Slot": device['network_slot'], 416 "InterfaceName": device['interface_name'], 417 "Port": device['port'], 418 "MacAddress": device['mac_address'], 419 } 420 ) 421 elif device['device_type'] == 'SAN': 422 intersight.api_body['BootDevices'].append( 423 { 424 "ClassId": "boot.San", 425 "ObjectType": "boot.San", 426 "Enabled": device['enabled'], 427 "Name": device['device_name'], 428 "Lun": device['lun'], 429 "Slot": device['network_slot'], 430 "Bootloader": { 431 "ClassId": "boot.Bootloader", 432 "ObjectType": "boot.Bootloader", 433 "Description": device['bootloader_description'], 434 "Name": device['bootloader_name'], 435 "Path": device['bootloader_path'], 436 }, 437 } 438 ) 439 elif device['device_type'] == 'SD Card': 440 intersight.api_body['BootDevices'].append( 441 { 442 "ClassId": "boot.SdCard", 443 "ObjectType": "boot.SdCard", 444 "Enabled": device['enabled'], 445 "Name": device['device_name'], 446 "Lun": device['lun'], 447 "SubType": device['sd_card_subtype'], 448 "Bootloader": { 449 "ClassId": "boot.Bootloader", 450 "ObjectType": "boot.Bootloader", 451 "Description": device['bootloader_description'], 452 "Name": device['bootloader_name'], 453 "Path": device['bootloader_path'], 454 }, 455 } 456 ) 457 elif device['device_type'] == 'UEFI Shell': 458 intersight.api_body['BootDevices'].append( 459 { 460 "ClassId": "boot.UefiShell", 461 "ObjectType": "boot.UefiShell", 462 "Enabled": device['enabled'], 463 "Name": device['device_name'], 464 } 465 ) 466 elif device['device_type'] == 'USB': 467 intersight.api_body['BootDevices'].append( 468 { 469 "ClassId": "boot.Usb", 470 "ObjectType": "boot.Usb", 471 "Enabled": device['enabled'], 472 "Name": device['device_name'], 473 "SubType": device['usb_subtype'], 474 } 475 ) 476 elif device['device_type'] == 'Virtual Media': 477 intersight.api_body['BootDevices'].append( 478 { 479 "ClassId": "boot.VirtualMedia", 480 "ObjectType": "boot.VirtualMedia", 481 "Enabled": device['enabled'], 482 "Name": device['device_name'], 483 "SubType": device['virtual_media_subtype'], 484 } 485 ) 486 # 487 # Code below should be common across all policy modules 488 # 489 intersight.configure_policy_or_profile(resource_path=resource_path) 490 491 module.exit_json(**intersight.result) 492 493 494if __name__ == '__main__': 495 main() 496