---
#
# Configure Server Profiles and Policies
#
# The hosts group used is provided by the group variable or defaulted to 'Intersight_Servers'.
# You can specify a specific host (or host group) on the command line:
#   ansible-playbook ... -e group=<your host group>
#   e.g., ansible-playbook server_profiles.yml -e group=TME_Demo
#
- hosts: "{{ group | default('Intersight_Servers') }}"
  connection: local
  collections:
    - cisco.intersight
  gather_facts: false
  vars:
    # Create an anchor for api_info that can be used throughout the file
    api_info: &api_info
      api_private_key: "{{ api_private_key }}"
      api_key_id: "{{ api_key_id }}"
      api_uri: "{{ api_uri | default(omit) }}"
      validate_certs: "{{ validate_certs | default(omit) }}"
      state: "{{ state | default(omit) }}"
    # Server Profile name default
    profile_name: "SP-{{ inventory_hostname }}"
    # Organization name
    org_name: DevNet
  tasks:
    # Get the Organization Moid used by all profiles and policies
    - name: "Get Organization {{ org_name }} Moid"
      intersight_rest_api:
        <<: *api_info
        resource_path: /organization/Organizations
        query_params:
          $filter: "Name eq '{{ org_name }}'"
      register: org_resp
      delegate_to: localhost
      tags: always
    #
    # Configure profiles specific to server (run for each server in the inventory)
    # Server Profiles role will register a profile_resp and profile_resp list (from all hosts) can be used by policy tasks
    #
    - name: "Configure {{ profile_name }} Server Profile"
      intersight_rest_api:
        <<: *api_info
        resource_path: /server/Profiles
        query_params:
          $filter: "Name eq '{{ profile_name }}'"
        api_body: {
          "Name": "{{ profile_name }}",
          "AssignedServer": {
            "Moid": "{{ server_moid }}",
            "ObjectType": "compute.RackUnit"
          },
          "Organization": {
            "Moid": "{{ org_resp.api_response.Moid }}"
          }
        }
      register: profile_resp
      when: server_moid is defined
      delegate_to: localhost
      tags: server_profiles
    #
    # Enclose policy tasks in a block that runs once
    # Policy API body is specified in a role specific vars section for each role import
    # See https://intersight.com/apidocs/ or https://intersight.com/mobrowser/ for information on setting resource_path and api_body
    #
    - block:
        # Boot Order policy
        - import_role:
            name: policies/server_policies
          vars:
            resource_path: /boot/PrecisionPolicies
            api_body: {
              "Name": "COS-Boot",
              "ConfiguredBootMode": "Legacy",
              "BootDevices": [
                {
                  "ObjectType": "boot.LocalDisk",
                  "Enabled": true,
                  "Name": "Disk",
                  "Slot": "MRAID"
                },
                {
                  "ObjectType": "boot.VirtualMedia",
                  "Enabled": true,
                  "Name": "VM",
                  "Subtype": "cimc-mapped-dvd"
                }
              ],
              "Organization": {
                "Moid": "{{ org_resp.api_response.Moid }}"
              }
            }
          tags: boot_order
        # Adapter Configuration policy
        - import_role:
            name: policies/server_policies
          vars:
            resource_path: /adapter/ConfigPolicies
            api_body: {
              "Name":"COS-Adapter",
              "Settings":[
                {
                  "SlotId":"MLOM",
                  "EthSettings":{
                    "LldpEnabled":true
                  },
                  "FcSettings":{
                    "FipEnabled":false
                  }
                }
              ],
              "Organization": {
                "Moid": "{{ org_resp.api_response.Moid }}"
              }
            }
          tags: adapter_configuration
        # LAN Connectivity and related policies
        - block:
            # Ethernet Adapter
            - name: "Configure Ethernet Adapter Policy"
              intersight_rest_api:
                <<: *api_info
                resource_path: /vnic/EthAdapterPolicies
                query_params:
                  $filter: "Name eq 'COS-EthernetAdapter'"
                api_body: {
                  "Name": "COS-EthernetAdapter",
                  "InterruptSettings": {
                    "Count": 32,
                    "Mode": "MSIx",
                    "CoalescingTime": 125,
                    "CoalescingType": "MIN"
                  },
                  "RxQueueSettings": {
                    "Count": 8,
                    "RingSize": 4096
                  },
                  "TxQueueSettings": {
                    "Count": 8,
                    "RingSize": 4096
                  },
                  "CompletionQueueSettings": {
                    "Count": 16
                  },
                  "Organization": {
                    "Moid": "{{ org_resp.api_response.Moid }}"
                  }
                }
              register: eth_adapter_resp
            # Ethernet Network
            - name: "Configure Ethernet Network Policy"
              intersight_rest_api:
                <<: *api_info
                resource_path: /vnic/EthNetworkPolicies
                query_params:
                  $filter: "Name eq 'COS-EthernetNetwork'"
                api_body: {
                  "Name": "COS-EthernetNetwork",
                  "VlanSettings": {
                    "Mode": "TRUNK",
                    "DefaultVlan": 10
                  },
                  "Organization": {
                    "Moid": "{{ org_resp.api_response.Moid }}"
                  }
                }
              register: eth_network_resp
            # Ethernet QoS
            - name: "Configure Ethernet QoS Policy"
              intersight_rest_api:
                <<: *api_info
                resource_path: /vnic/EthQosPolicies
                query_params:
                  $filter: "Name eq 'COS-QoS'"
                api_body: {
                  "Name": "COS-QoS",
                  "Mtu": 9000,
                  "Organization": {
                    "Moid": "{{ org_resp.api_response.Moid }}"
                  }
                }
              register: eth_qos_resp
            # Import role for LAN Connectivity will register a policy_resp
            - import_role:
                name: policies/server_policies
              vars:
                resource_path: /vnic/LanConnectivityPolicies
                api_body: {
                  "Name": "COS-LAN",
                  "Organization": {
                    "Moid": "{{ org_resp.api_response.Moid }}"
                  }
                }
            # vNIC configuration
            # Ideally this would be in a loop, but Uplink is converted to a string (instead of the required int) when in a loop
            - name: "Configure eth0"
              intersight_rest_api:
                <<: *api_info
                resource_path: /vnic/EthIfs
                query_params:
                  $filter: "LanConnectivityPolicy.Moid eq '{{ policy_resp.api_response.Moid }}' and Name eq 'eth0'"
                api_body: {
                  "Name": "eth0",
                  "Placement": {
                    "Id": "MLOM",
                    "Uplink": 0
                  },
                  "Order": 0,
                  "EthAdapterPolicy": {
                    "Moid": "{{ eth_adapter_resp.api_response.Moid }}"
                  },
                  "EthNetworkPolicy": {
                    "Moid": "{{ eth_network_resp.api_response.Moid }}"
                  },
                  "EthQosPolicy": {
                    "Moid": "{{ eth_qos_resp.api_response.Moid }}"
                  },
                  "LanConnectivityPolicy": {
                    "Moid": "{{ policy_resp.api_response.Moid }}"
                  },
                  "Organization": {
                    "Moid": "{{ org_resp.api_response.Moid }}"
                  }
                }
            - name: "Configure eth1"
              intersight_rest_api:
                <<: *api_info
                resource_path: /vnic/EthIfs
                query_params:
                  $filter: "LanConnectivityPolicy.Moid eq '{{ policy_resp.api_response.Moid }}' and Name eq 'eth1'"
                api_body: {
                  "Name": "eth1",
                  "Placement": {
                    "Id": "MLOM",
                    "Uplink": 1
                  },
                  "Order": 1,
                  "EthAdapterPolicy": {
                    "Moid": "{{ eth_adapter_resp.api_response.Moid }}"
                  },
                  "EthNetworkPolicy": {
                    "Moid": "{{ eth_network_resp.api_response.Moid }}"
                  },
                  "EthQosPolicy": {
                    "Moid": "{{ eth_qos_resp.api_response.Moid }}"
                  },
                  "LanConnectivityPolicy": {
                    "Moid": "{{ policy_resp.api_response.Moid }}"
                  },
                  "Organization": {
                    "Moid": "{{ org_resp.api_response.Moid }}"
                  }
                }
          tags: lan_connectivity
        # NTP policy config
        - import_role:
            name: policies/server_policies
          vars:
            resource_path: /ntp/Policies
            api_body: {
              "Name": "COS-NTP",
              "Enabled": true,
              "NtpServers": [
                "173.38.201.115"
              ],
              "Organization": {
                "Moid": "{{ org_resp.api_response.Moid }}"
              }
            }
          tags: ntp
        # Storage and related policies
        - block:
            # Disk Group policy
            - name: "Configure Disk Group Policy"
              intersight_rest_api:
                <<: *api_info
                resource_path: /storage/DiskGroupPolicies
                query_params:
                  $filter: "Name eq 'COS-Disk'"
                api_body: {
                  "Name":"COS-Disk",
                  "RaidLevel":"Raid1",
                  "SpanGroups":[
                    {
                      "Disks":[
                        {
                          "SlotNumber":13
                        },
                        {
                          "SlotNumber":14
                        }
                      ]
                    }
                  ],
                  "UseJbods":true,
                  "Organization": {
                    "Moid": "{{ org_resp.api_response.Moid }}"
                  }
                }
              register: disk_group_resp
            # Storage policy
            - import_role:
                name: policies/server_policies
              vars:
                resource_path: /storage/StoragePolicies
                api_body: {
                  "Name": "COS-Storage",
                  "RetainPolicyVirtualDrives": true,
                  "UnusedDisksState": "Jbod",
                  "VirtualDrives": [
                    {
                      "Name": "Boot",
                      "DiskGroupPolicy": "{{ disk_group_resp.api_response.Moid }}",
                      "AccessPolicy": "ReadWrite",
                      "ReadPolicy": "Default",
                      "WritePolicy": "WriteBackGoodBbu",
                      "IoPolicy": "Default",
                      "DriveCache": "Default",
                      "ExpandToAvailable": true,
                      "BootDrive": true
                    }
                  ],
                  "Organization": {
                    "Moid": "{{ org_resp.api_response.Moid }}"
                  }
                }
          tags: storage
        # Virtual Media policy config
        - import_role:
            name: policies/server_policies
          vars:
            resource_path: /vmedia/Policies
            api_body: {
              "Name": "COS-VM",
              "Mappings": [
                {
                  "MountProtocol": "http",
                  "VolumeName": "COS.3.13.6",
                  "DeviceType": "cdd",
                  "HostName": "sjc02dmz-rhel.sjc02dmz.net",
                  "RemotePath": "ibm",
                  "RemoteFile": "clevos-3.13.6.33-allinone-usbiso.iso"
                }
              ],
              "Organization": {
                "Moid": "{{ org_resp.api_response.Moid }}"
              }
            }
          tags: virtual_media
      # Policies are common, so only run this block once and not for every host
      run_once: true
      delegate_to: localhost
