
    Vh"                         d dl mZmZmZ eZdZdZdZdZ	d dl
mZ d dlmZmZmZ  G d d	e      Zd
 Zedk(  r e        yy)    )absolute_importdivisionprint_functionz:Abinash Mishra, Madhan Sankaranarayanan, Rishita Chowdharya  
---
module: pnp_intent
short_description: Resource module for Site and PnP related functions
description:
  - Manage operations add device, claim device and unclaim device of Onboarding Configuration(PnP)
    resource
  - API to add device to pnp inventory and claim it to a site.
  - API to delete device from the pnp inventory.
  - API to reset the device from errored state.
version_added: 6.6.0
extends_documentation_fragment:
  - cisco.dnac.intent_params
author: Abinash Mishra (@abimishr) Madhan Sankaranarayanan (@madhansansel) Rishita
  Chowdhary (@rishitachowdhary)
options:
  config_verify:
    description: Set to True to verify the Cisco Catalyst Center config after applying
      the playbook config.
    type: bool
    default: false
  state:
    description: The state of Cisco Catalyst Center after module completion.
    type: str
    choices:
      - merged
      - deleted
    default: merged
  config:
    description:
      - List of details of device being managed.
    type: list
    elements: dict
    required: true
    suboptions:
      device_info:
        description:
          - Provides the device-specific information required for adding devices to
            the PnP database that are not already present.
          - For adding a single device, the list should contain exactly one set of
            device information. If a site name is also provided, the device can be
            claimed immediately after being added.
          - For bulk import, the list must contain information for more than one device.
            Bulk import is intended solely for adding devices; claiming must be performed
            with separate tasks or configurations.
        type: list
        required: true
        elements: dict
        suboptions:
          hostname:
            description:
              - Defines the desired hostname for the PnP device after it has been
                claimed.
              - The hostname can only be assigned or changed during the claim process,
                not during bulk or single device additions.
            type: str
          state:
            description:
              - Represents the onboarding state of the PnP device.
              - Possible values are 'Unclaimed', 'Claimed', or 'Provisioned'.
            type: str
          pid:
            description: Pnp Device's pid.
            type: str
          serial_number:
            description: Pnp Device's serial_number.
            type: str
          is_sudi_required:
            description: Sudi Authentication requiremnet's flag.
            type: bool
      site_name:
        description: Name of the site for which device will be claimed.
        type: str
      project_name:
        description: Name of the project under which the template is present
        type: str
        default: Onboarding Configuration
      template_name:
        description:
          - Name of template to be configured on the device.
          - Supported for EWLC from Cisco Catalyst Center release version 2.3.7.x
            onwards.
        type: str
      template_params:
        description:
          - Parameter values for the parameterised templates.
          - Each varibale has a value that needs to be passed as key-value pair in
            the dictionary. We can pass values as variable_name:variable_value.
          - Supported for EWLC from Cisco Catalyst Center release version 2.3.7.x
            onwards.
        type: dict
      image_name:
        description: Name of image to be configured on the device
        type: str
      golden_image:
        description: Is the image to be condifgured tagged as golden image
        type: bool
      pnp_type:
        description: Specifies the device type for the Plug and Play (PnP) device.
          - Options include 'Default', 'CatalystWLC', 'AccessPoint', or 'StackSwitch'.
          - 'Default' is applicable to switches and routers. - 'CatalystWLC' should
          be selected for 9800 series wireless controllers. - 'AccessPoint' is used
          when claiming an access point. - 'StackSwitch' should be chosen for a group
          of switches that operate as a single switch, typically used in the access
          layer.
        type: str
        choices:
          - Default
          - CatalystWLC
          - AccessPoint
          - StackSwitch
        default: Default
      static_ip:
        description: Management IP address of the Wireless Controller
        type: str
      subnet_mask:
        description: Subnet Mask of the Management IP address of the Wireless Controller
        type: str
      gateway:
        description: Gateway IP address of the Wireless Controller for getting pinged
        type: str
      vlan_id:
        description: Vlan Id allocated for claimimg of Wireless Controller
        type: str
      ip_interface_name:
        description: Specifies the interface name utilized for Plug and Play (PnP)
          by the Wireless Controller. Ensure this interface is pre-configured on the
          Controller prior to device claiming.
        type: str
      rf_profile:
        description:
          - Radio Frequecy (RF) profile of the AP being claimed.
          - RF Profiles allow you to tune groups of APs that share a common coverage
            zone together.
          - They selectively change how Radio Resource Management will operate the
            APs within that coverage zone.
          - HIGH RF profile allows you to use more power and allows to join AP with
            the client in an easier fashion.
          - TYPICAL RF profile is a blend of moderate power and moderate visibility
            to the client.
          - LOW RF profile allows you to consume lesser power and has least visibility
            to the client.
        type: str
        choices:
          - HIGH
          - LOW
          - TYPICAL
requirements:
  - dnacentersdk == 2.6.10
  - python >= 3.9
notes:
  - SDK Method used are device_onboarding_pnp.DeviceOnboardingPnp.add_device, device_onboarding_pnp.DeviceOnboardingPnp.get_device_list,
    device_onboarding_pnp.DeviceOnboardingPnp.claim_a_device_to_a_site, device_onboarding_pnp.DeviceOnboardingPnp.delete_device_by_id_from_pnp,
    device_onboarding_pnp.DeviceOnboardingPnp.get_device_count, device_onboarding_pnp.DeviceOnboardingPnp.get_device_by_id,
    device_onboarding_pnp.DeviceOnboardingPnp.update_device, sites.Sites.get_site,
    software_image_management_swim.SoftwareImageManagementSwim.get_software_image_details,
    configuration_templates.ConfigurationTemplates.gets_the_templates_available
  - Paths used are post /dna/intent/api/v1/onboarding/pnp-device post /dna/intent/api/v1/onboarding/pnp-device/site-claim
    post /dna/intent/api/v1/onboarding/pnp-device/{id} get /dna/intent/api/v1/onboarding/pnp-device/count
    get /dna/intent/api/v1/onboarding/pnp-device put /onboarding/pnp-device/${id}
    get /dna/intent/api/v1/site get /dna/intent/api/v1/image/importation get /dna/intent/api/v1/template-programmer/template
aW  
- name: Import multiple switches in bulk only
  cisco.dnac.pnp_intent:
    dnac_host: "{{dnac_host}}"
    dnac_username: "{{dnac_username}}"
    dnac_password: "{{dnac_password}}"
    dnac_verify: "{{dnac_verify}}"
    dnac_port: "{{dnac_port}}"
    dnac_version: "{{dnac_version}}"
    dnac_debug: "{{dnac_debug}}"
    dnac_log_level: "{{dnac_log_level}}"
    dnac_log: true
    state: merged
    config_verify: true
    config:
      - device_info:
          - serial_number: QD2425L8M7
            state: Unclaimed
            pid: c9300-24P
            is_sudi_required: false
          - serial_number: QTC2320E0H9
            state: Unclaimed
            pid: c9300-24P
            hostname: Test-123
          - serial_number: ETC2320E0HB
            state: Unclaimed
            pid: c9300-24P
- name: Add a new EWLC and claim it
  cisco.dnac.pnp_intent:
    dnac_host: "{{dnac_host}}"
    dnac_username: "{{dnac_username}}"
    dnac_password: "{{dnac_password}}"
    dnac_verify: "{{dnac_verify}}"
    dnac_port: "{{dnac_port}}"
    dnac_version: "{{dnac_version}}"
    dnac_debug: "{{dnac_debug}}"
    dnac_log_level: "{{dnac_log_level}}"
    dnac_log: true
    state: merged
    config_verify: true
    config:
      - device_info:
          - serial_number: FOX2639PAY7
            hostname: New_WLC
            state: Unclaimed
            pid: C9800-CL-K9
        site_name: Global/USA/San Francisco/BGL_18
        template_name: Ansible_PNP_WLC
        template_params:
          hostname: IAC-EWLC-Claimed
        project_name: Onboarding Configuration
        image_name: C9800-40-universalk9_wlc.17.12.01.SPA.bin
        golden_image: true
        pnp_type: CatalystWLC
        static_ip: 204.192.101.10
        subnet_mask: 255.255.255.0
        gateway: 204.192.101.1
        vlan_id: 1101
        ip_interface_name: TenGigabitEthernet0/0/0
- name: Claim a pre-added switch, apply a template, and perform an image upgrade
    for a specific site
  cisco.dnac.pnp_intent:
    dnac_host: "{{dnac_host}}"
    dnac_username: "{{dnac_username}}"
    dnac_password: "{{dnac_password}}"
    dnac_verify: "{{dnac_verify}}"
    dnac_port: "{{dnac_port}}"
    dnac_version: "{{dnac_version}}"
    dnac_debug: "{{dnac_debug}}"
    dnac_log_level: "{{dnac_log_level}}"
    dnac_log: true
    state: merged
    config_verify: true
    config:
      - device_info:
          - serial_number: FJC271924EQ
            hostname: Switch
            state: Unclaimed
            pid: C9300-48UXM
        site_name: Global/USA/San Francisco/BGL_18
        template_name: "Ansible_PNP_Switch"
        image_name: cat9k_iosxe_npe.17.03.07.SPA.bin
        project_name: Onboarding Configuration
        template_params:
          hostname: SJC-Switch-1
          interface: TwoGigabitEthernet1/0/2
- name: Remove multiple devices from the PnP dashboard safely (ignores non-existent
    devices)
  cisco.dnac.pnp_intent:
    dnac_host: "{{dnac_host}}"
    dnac_username: "{{dnac_username}}"
    dnac_password: "{{dnac_password}}"
    dnac_verify: "{{dnac_verify}}"
    dnac_port: "{{dnac_port}}"
    dnac_version: "{{dnac_version}}"
    dnac_debug: "{{dnac_debug}}"
    dnac_log_level: "{{dnac_log_level}}"
    dnac_log: true
    state: deleted
    config_verify: true
    config:
      - device_info:
          - serial_number: QD2425L8M7
          - serial_number: FTC2320E0HA
          - serial_number: FKC2310E0HB
ah  
#Case_1: When the device is claimed successfully.
response_1:
  description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK
  returned: always
  type: dict
  sample: >
    {
      "response":
        {
          "response": String,
          "version": String
        },
      "msg": String
    }
#Case_2: Given site/image/template/project not found or Device is not found for deletion
response_2:
  description: A list with the response returned by the Cisco Catalyst Center Python SDK
  returned: always
  type: list
  sample: >
    {
      "response": [],
      "msg": String
    }
#Case_3: Error while deleting/claiming a device
response_3:
  description: A string with the response returned by the Cisco Catalyst Center Python SDK
  returned: always
  type: dict
  sample: >
    {
      "response": String,
      "msg": String
    }
)AnsibleModule)DnacBasevalidate_list_of_dictsget_dict_resultc                   t     e Zd Z fdZd Zd Zd Zd Zd ZddZ	d Z
d	 Zd
 Zd Zd Zd Zd Zd Z xZS )PnPc                 $    t         |   |       y N)super__init__)selfmodule	__class__s     i/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/cisco/dnac/plugins/modules/pnp_intent.pyr   zPnP.__init__A  s         c                 B   | j                   sd| _        d| _        | S ddddddddddddddddd	ddd
ddddddddddddddddddddddddddddd}t        | j                   |      \  }}|rSdj	                  dj                  |            | _        | j                  t        | j                        d       d| _        | S || _        dj	                  t        |            | _        | j                  t        | j                        d       d| _        | S )ag  
        Validate the fields provided in the playbook.  Checks the
        configuration provided in the playbook against a predefined
        specification to ensure it adheres to the expected structure
        and data types.

        Parameters:
          - self: The instance of the class containing the 'config' attribute
                  to be validated.
        Returns:
          The method returns an instance of the class with updated attributes:
          - self.msg: A message describing the validation result.
          - self.status: The status of the validation (either 'success' or 'failed').
          - self.validated_config: If successful, a validated version of the
                                   'config' parameter.
        Example:
          To use this method, create an instance of the class and call
          'validate_input' on it.If the validation succeeds, 'self.status'
          will be 'success'and 'self.validated_config' will contain the
          validated configuration. If it fails, 'self.status' will be
          'failed', and 'self.msg' will describe the validation issues.
        z/config not available in playbook for validationsuccessstrF)typerequireddictzOnboarding Configuration)r   r   defaultboollistT)r   r   elementsDefault)template_nametemplate_paramsproject_name	site_name
image_namegolden_imagedevice_infopnp_type
rf_profile	static_ipsubnet_maskgatewayvlan_idip_interface_namesensorProfilez#Invalid parameters in playbook: {0}
ERRORfailedz2Successfully validated playbook config params: {0}INFO)	configmsgstatusr   formatjoinlogr   validated_config)r   pnp_spec	valid_pnpinvalid_paramss       r   validate_inputzPnP.validate_inputD  sL   0 {{HDH#DKK ',?(.EB%*(BD"'U;#(e<%+?$*(.0!&EiP#(e<"'U;$)u= %59 %59*/U!C&+?#
* %;KK%
!	> <CC		.)+DHHHS]G,"DKK )GNNsS\~^TXX'r   c                    d}d}d}	  | j                   d   ddd| j                  j                  d      id	      }|r| j	                  dj                  | j                  j                  d      t        |            d       |j                  d      }t        |      dk(  rQ|d   j                  d      }d}| j	                  dj                  || j                  j                  d            d       ||fS # t        $ r[ | j	                  d
j                  | j                  j                  d            d       | j                  j                  dg        Y w xY w)ab  
        Check whether the site exists or not, along with side id

        Parameters:
          - self: The instance of the class containing the 'config'
                  attribute to be validated.
        Returns:
          The method returns an instance of the class with updated attributes:
          - site_exits: A boolean value indicating the existence of the site.
          - site_id: The Id of the site i.e. required to claim device to site.
        Example:
          Post creation of the validated input, we this method gets the
          site_id and checks whether the site exists or not
        FNexecsitesget_sitenamer#   Tfamilyfunctionparamsop_modifiesz>Exception occurred as site                 '{0}' was not foundCRITICALSite not foundr4   responsez4Received site details                 for '{0}': {1}DEBUGrK      r   idzSite Name: {1}, Site ID: {0}r2   )

dnac_applywantget	Exceptionr8   r6   r   	fail_jsonr   len)r   site_existssite_idrK   sites        r   get_site_detailszPnP.get_site_details  s?     
	E.tv.#		k :; 	H HH   &tyy}}['A3x= QSZ\<<
+D4yA~q'++d+"7>>w		VaHbceklW%%  	EHH %%+VDIIMM+,F%GUKK!!&6!D	Es   4C6 6A EEc           	         	  | j                   d   ddd| j                  j                  d      id      }r| j	                  dj                  | j                  j                  d      t        |            d       |j                  d      }|d   j                  d      }|D ]f  }|d   dk(  s|j                  d      j                  d      }| j	                  dj                  || j                  j                  d            d       h S # t        $ r[ | j	                  dj                  | j                  j                  d            d	       | j                  j                  d
g        Y ;w xY w)a  
        Fetches the type of site

        Parameters:
          - self: The instance of the class containing the 'config' attribute
                  to be validated.
        Returns:
          The method returns an instance of the class with updated attributes:
          - site_type: A string indicating the type of the
                       site (area/building/floor).
        Example:
          Post creation of the validated input, we this method gets the
          type of the site.
        r?   r@   rA   rB   r#   TrC   z>Exception occurred as                 site '{0}' was not foundrH   rI   rJ   z3Received site details                for '{0}': {1}rL   rK   r   additionalInfo	nameSpaceLocation
attributesr   z#Site type for site name '{1}' : {0}r2   )	rO   rP   rQ   rR   r8   r6   r   rS   r   )r   rK   rW   site_additional_infoitem	site_types         r   get_site_typezPnP.get_site_type  sY    
	E.tv.#		k :; 	H HH   &tyy}}['A3x= QSZ\<<
+D#'7;;/?#@ , z$
2 $ 6 : :6 BIHHBII)UYU^U^UbUbcnUoprxyz
   	EHH **0&{1K*LjZKK!!&6!D	Es   4D A E21E2c                     |d   }g }|D ]F  }i }|j                  d      |d<   d|v r|j                  d      |d<   ||d<   |j                  |       H | j                  dj                  t	        |            d       |S )	a  
        Store pnp parameters from the playbook for pnp processing in Cisco Catalyst Center.

        Parameters:
          - self: The instance of the class containing the 'config'
                  attribute to be validated.
          - params: The validated params passed from the playbook.
        Returns:
          The method returns an instance of the class with updated attributes:
          - pnp_params: A dictionary containing all the values indicating
                        the type of the site (area/building/floor).
        Example:
          Post creation of the validated input, it fetches the required paramters
          and stores it for further processing and calling the parameters in
          other APIs.
        r&   serial_numberserialNumberis_sudi_requiredisSudiRequired
deviceInfozPnP paramters passed are {0}r2   )popappendr8   r6   r   )r   rF   params_listdevice_info_listparamdevice_dicts         r   get_pnp_paramszPnP.get_pnp_params  s    $ ]+  	1EK$)IIo$>E.!!U**/))4F*G&'(-K%##K0	1 	/66s;7GH&Qr   c                     |j                  d      |j                  d      d}| j                  dj                  t        |            d       |S )a  
        Get image name and the confirmation whether it's tagged golden or not

        Parameters:
          - self: The instance of the class containing the 'config' attribute
                  to be validated.
          - params: The validated params passed from the playbook.
        Returns:
          The method returns an instance of the class with updated attributes:
          - image_params: A dictionary containing all the values indicating
                          name of the image and its golden image status.
        Example:
          Post creation of the validated input, it fetches the required
          paramters and stores it for further processing and calling the
          parameters in other APIs.
        r$   r%   )r$   is_tagged_goldenzImage details are {0}r2   )rQ   r8   r6   r   )r   rF   image_paramss      r   get_image_paramszPnP.get_image_params  sJ    & !**\2 &

> :

 	(//L0ABFKr   c                 `    | j                  |d       | j                  j                  |       y)z|
        Method for failing discovery if there is any discrepancy in the PnP credentials
        passed by the user
        rH   r4   N)r8   r   rS   )r   r4   s     r   pnp_cred_failurezPnP.pnp_cred_failure  s'     	j!#&r   c                 \   d| j                   j                  d      i}| j                  d   j                  d      }| j                   j                  d      dddgd}|j                  d	      rV|rTt        |t              rDt        |      dkD  r6g |d
<   |j                         D ]  \  }}||d}|d
   j                  |         | j                   j                  d      | j                   j                  d      | j                  j                  d      | j                  j                  d      ||d}|d   dk(  rx| j                  d   j                  d      sd}| j                  |       | j                  d   j                  d      sd}| j                  |       | j                  d   j                  d      sd}| j                  |       | j                  d   j                  d      sd}| j                  |       | j                  d   j                  d      sd}| j                  |       | j                  d   d   |d<   | j                  d   d   |d<   | j                  d   d   |d<   t        | j                  d   j                  d            |d<   | j                  d   d   |d <   |d   d!k(  rG| j                  d   j                  d"      sd#}| j                  |       | j                  d   d"   |d$<   | j                  d%j                  t        |            d&       |S )'a,  
        Get the paramters needed for claiming the device to site.
        Parameters:
          - self: The instance of the class containing the 'config'
                  attribute to be validated.
        Returns:
          The method returns an instance of the class with updated attributes:
          - claim_params: A dictionary needed for calling the POST call
                          for claim a device to a site API.
        Example:
          The stored dictionary can be used to call the API claim a device
          to a site via SDK
        imageIdimage_idr   r!   template_id keyvalueconfigIdconfigParametersr   r   	device_idrV   r'   hostname)deviceIdsiteIdr   r   	imageInfo
configInfor   CatalystWLCr)   zSA static IP address is required to claim a wireless controller. Please provide one.rt   r*   zqPlease provide a subnet mask to claim a wireless controller. This information is mandatory for the configuration.r+   zUA gateway IP is required to claim a wireless controller. Please ensure to provide it.r-   a   Please provide the Interface Name to claim a wireless controller. This information is necessary for making it a logical interface post claiming which can used to help manage the Wireless SSIDs broadcasted by the access points, manage the controller, access point and user data, plus more.r,   zPlease provide the Vlan ID to claim a wireless controller. This is a required field for the process to create and set the specified port as trunk during PnP.staticIP
subnetMaskvlanIdipInterfaceNameAccessPointr(   z0The RF Profile for claiming an AP must be passed	rfProfilez$Parameters used for claiming are {0}r2   )haverQ   r9   
isinstancer   rT   itemsri   rP   ru   r   r8   r6   )	r   	imageinfor!   
configinfor|   r}   config_dictclaim_paramsr4   s	            r   get_claim_paramszPnP.get_claim_params  s7     tyy}}Z0
	 //2667HI		m4 !

 >>*%//40'!+57J12&5&;&;&= K
U#&%*' ##56==kJK 		k2iimmI.IIMM*-		j1"$
 =0))!,00=k%%#%.))!,00?K%%#%.))!,00;m%%#%.))!,001DEv %%#%.))!,00;Q%%#%.'+'<'<Q'?'LL$)-)>)>q)A-)PL&&*&;&;A&>y&IL#%()>)>q)A)E)Ei)P%QL".2.C.CA.FGZ.[L*+=0))!,00>H%%#%.(,(=(=a(@(NL%7>>s<?PQSYZr   c                     d| j                   j                  d      dddgdg| j                   j                  d      ddddgi}| j                  dj                  t	        |            d	       |S )
a   
        Get the paramters needed for resetting the device in an errored state.
        Parameters:
          - self: The instance of the class containing the 'config'
                  attribute to be validated.
        Returns:
          The method returns an instance of the class with updated attributes:
          - reset_params: A dictionary needed for calling the PUT call
                          for update device details API.
        Example:
          The stored dictionary can be used to call the API update device details
        deviceResetListry   rz   r{   r~   r   )
configListr   licenseLevellicenseTypetopOfStackSerialNumberz3Paramters used for resetting from errored state:{0}r2   )r   rQ   r8   r6   r   )r   reset_paramss     r   get_reset_paramszPnP.get_reset_paramso  s      )-		m(D ,.-/!"1
# !%		k :$&#%.0 
, 	FMMcR^N_`bhir   c           	         i }t        | j                  j                  d            dk(  ru | j                  d   ddd| j                  j                  d      id      }| j	                  d	j                  | j                  j                  d      t        |            d
       |rt        |      dk(  sV| j	                  dj                  | j                  j                  d            d       d| _        d| _        || _	        d|d<   | S d|d<   |d   j                  d      |d<   | j	                  dt        |d         z          | j                  j                  d      dk(  r< | j                  d   dd| j                  j                  d      d      }|j                  d      }| j	                  dj                  t        |            d
        | j                  d   ddd| j                  j                  d      id      }| j	                  d j                  | j                  j                  d      t        |            d
        | j                  d   dd!d|d   j                  d      id      }| j	                  d"j                  t        |            d
       |j                  d#      j                  d$      }| j	                  d%j                  | j                  j                  d      |      d&       d}t        | j                  j                  d'      t              sb| j                  j                  d      d   j                  d#      s5d(| _        | j	                  t        | j                        d)       d*| _        | S | j                  j                  d'      }	| j                         \  }}
|r|
|d+<   | j	                  d,j                  ||	|
      d&       | j                  j                  d-      d.k(  re| j                         d/k7  rRd0j                  | j                               | _        | j	                  t        | j                        d)       d*| _        | S t        |      dk(  rWd1j                  | j                  d   j                  d2            | _        | j	                  | j                  d3       d*| _        | S t        |      dk(  r|d4k7  rDd5j                  |      | _        | j	                  t        | j                        d3       d*| _        | S |d   j                  d6      |d7<   | j	                  d8j                  | j                  j                  d      j                  d2      t        |d7               d&       | j                  j                  d9      }|r|rt        |t              s,d:| _        | j	                  | j                  d3       d*| _        | S t!        |d;|      }|r|j                  d<      |d=<   nd>j                  |      | _        | j	                  | j                  d3       d*| _        | S | j                  j                  d      d   j                  d#      s,d?| _        | j	                  | j                  d)       d*| _        | S d@| _        | j	                  | j                  d&       d| _        || _	        | S )Aa  
        Get the current image, template and site details from the Cisco Catalyst Center.

        Parameters:
          - self: The instance of the class containing the 'config' attribute
                  to be validated.
        Returns:
          The method returns an instance of the class with updated attributes:
          - self.image_response: A list of image passed by the user
          - self.template_list: A list of template under project
          - self.device_response: Gets the device_id and stores it
        Example:
          Stored paramters are used to call the APIs to get the current image,
          template and site details to call the API for various types of devices
        
pnp_paramsrM   r?   device_onboarding_pnpget_device_listrc   TrC   zKDevice details for the device with serial                 number '{0}': {1}rL   z;Device with serial number {0} is not found in the inventoryWARNINGzAdding the device to databaser   Fdevice_foundr   rN   r   zDevice Id: statemergedsoftware_image_management_swimget_software_image_detailsrq   rK   zEImage details obtained from the API 'get_software_image_details': {0}configuration_templatesgets_the_templates_availableproject_namesr"   z.List of templates under the project '{0}': {1}get_device_by_idzFDevice details retrieved after calling the 'get_device_by_id' API: {0}rg   modez=Installation mode of the device with the serial no. '{0}':{1}r2   r#   zThe site name must be a stringr0   r1   rV   z,Site Exists: {0}
Site Name: {1}
Site ID: {2}r'   r   floorzPlease ensure that the site type is specified as 'floor' when claiming an AP. The site type is given as '{0}'. Please change the 'site_type' into 'floor' to proceed.zThe image '{0}' is either not present or not tagged as 'Golden' in the Cisco Catalyst Center. Please verify its existence and its tag status.r$   rH   INSTALLz}The system must be in INSTALL mode to upgrade the image. The current mode is '{0}'. Please switch to INSTALL mode to proceed.	imageUuidrx   z!Image ID for the image '{0}': {1}r    z(Either project not found or it is Empty.rB   
templateIdry   zTemplate '{0}' is not found.z1Either Site Name or Device details must be added.zxSuccessfully collected all project and template                     parameters from Cisco Catalyst Center for comparison)rT   rP   rQ   rO   r8   r6   r   r4   r5   r   rF   r   rX   ra   r9   r   r	   )r   r   device_responseimage_response
image_listtemplate_listdev_details_responseinstall_moderU   r#   rV   r    template_detailss                r   get_havezPnP.get_have  s_      tyy}}\*+q05doof5.*')GH 	O HH ##)6$))--*H#oJ^#_ahj $_)=)BV]]^b^g^g^k^kl{^|}  @I  J:' 	',^$#'D  / 2 6 6t <DHH]Sk):%;;<{{w'83!8!8;999==8 $	" ,//
;
`gghklzh{|  F  G !8 74;+TYY]]>-JK $	! IPPQUQZQZQ^Q^_mQnps  uB  qC  D  FM  N'>tv'>2/ /!"4"8"8">? $	($ ahhil  nB  jC  D  FM  N377EII&QX__`d`i`i`m`mn}`~  AM  N  PV  W $!$))--"<cB IIMM,7:>>|L?DHHHS]G4"*DKK IIMM+6	)-)>)>)@&g&-DOHHMTTU`bkmtuw}~yy}}Z0MA--/7:(++16$2D2D2F+G !H !HHS]G<*2DK#'K:!+$OOUvVZVkVklmVnVrVrs  WA  PB :6&.#:!+'94(MMSVT`Ma !H HHS]J?*2DK#'K+5a=+<+<[+IZ(!D!K!KDIIMMZhLiLmLmnzL{  ~A  BF  GQ  BR  ~S  "T  V\  ]$(IIMM/$BM$ -*]D2Q(3DH HHTXXz:*2DK#'K+:=&R_+`(+2B2F2F|2TD/'E'L'L]'[DH HHTXXz:*2DK#'K  99==6q9==lK#V73&.#J6"	r   c                    | j                  |      | j                  |      |j                  d      |j                  d      |j                  d      |j                  d      d| _        t	        | j                  j                  d            dk(  rb| j                  d   d   d	   j                  d
      | j                  d<   | j                  d   d   d	   j                  d      | j                  d<   | j                  d   dk(  r|j                  d      | j                  d<   |j                  d      | j                  d<   |j                  d      | j                  d<   |j                  d      | j                  d<   |j                  d      | j                  d<   n0| j                  d   dk(  r|j                  d      | j                  d<   d| _        | j                  | j
                  d       d| _        | S )a3  
        Get all the image, template and site and pnp related
        information from playbook that is needed to be created in Cisco Catalyst Center.

        Parameters:
          - self: The instance of the class containing the 'config'
                  attribute to be validated.
          - config: validated config passed from the playbook
        Returns:
          The method returns an instance of the class with updated attributes:
          - self.want: A dictionary of paramters obtained from the playbook.
          - self.msg: A message indicating all the paramters from the playbook
                      are collected.
          - self.status: Success.
        Example:
            It stores all the paramters passed from the playbook for further
            processing before calling the APIs
        r'   r#   r"   r    )rq   r   r'   r#   r"   r    r   rM   r   rg   rd   rc   r   r   r)   r*   r+   r,   r-   r   r(   zBSuccessfully collected all parameters from playbook for comparisonr2   r   )rr   rn   rQ   rP   rT   r4   r8   r5   )r   r3   s     r   get_wantzPnP.get_want(  s   * !11&9--f5

:.K0"JJ~6#ZZ8
	 tyy}}\*+q0		,'*<8N# IIo&
 		,'*<8J IIj!
 99Z M1%+ZZ%<DIIk"'-zz-'@DIIm$#)::i#8DIIi #)::i#8DIIi -3ZZ8K-LDII)*YYz"m3&,jj&>DIIl#6"r   c           	         t        | j                  j                  d      t              s,d| _        | j                  | j                  d       d| _        | S t        | j                  j                  d            dkD  rrg }| j                  j                  d      D ]  } | j                  d   ddd	|d
   d   id      }| j                  dj                  |d
   d   t        |            d       |sXt        |      dk(  sg|j                  |       | j                  dj                  t        |            d        t        | j                  j                  d            t        |      z
  dk(  r?g | j                  d<   d| j                  d<   | j                  | j                  d   d       | S | j                  j                  d      D cg c]  }||vr|
 }} | j                  d   ddd|id      }| j                  dj                  |      d       t        |j                  d            dkD  rdj                  t        |j                  d                  | j                  d<   | j                  | j                  d   d       || j                  d<   | j                  | j                  d<   d| j                  d<   | S d| _        | j                  | j                  d       d| _        | S | j                  j                  d	      d d!}| j                  j                  d	      d"d!}| j                  j                  d#      sK| j                  d   s,d$| _        | j                  | j                  d       d| _        | S | j                  d%   s4| j                  d&d        | j                  d   dd'| j                  j                  d      d   d      }|j                  d
      | j                  d
<   | j                  d(j                  t        |            d       | j                  d
   rgd)| j                  d<   | j                  | j                  d   d       || j                  d<   | j                  | j                  d<   d| j                  d<   | S d*| _        | j                  | j                  d   d       d| _        | S | j                  d&        | j                  d   dd'| j                  j                  d      d   d      }| j                         j!                          |j                  d
      | j                  d
<   | j                  d+j                  t        |            d       | j#                         }	|j                  d,      |	d-<    | j                  d   dd.d|	/      }
| j                  d0j                  t        |            d       |
j                  d      d1k(  rv| j                  d
   rgd2| j                  d<   | j                  | j                  d   d       |
| j                  d<   | j                  | j                  d<   d| j                  d<   | S d3| _        | j                  | j                  d   d       d| _        | S  | j                  d   dd4d|/      }| j                  d5j                  t        |            d        | j                  d   dd4d|/      }| j                  d6j                  t        |            d        | j                  d   dd7d,| j                  d8   id      }| j                  d9j                  t        |            d       d:}|j                  d
      j                  d;      r |j                  d
      j                  d;      }|j                  d
      j                  d<      }| j                  d=j                  |      d       | j                  d%   sX| j                  j                  d#      | j                  d<   d>| j                  d<   | j                  | j                  d   d       | S d
| j                  j                  d      d   j                  d
      i}||d
   d;<   | j                  d?j                  |      d        | j                  d   dd@| j                  d8   |dAd      }| j                  dBj                  t        |            d       |dCk(  r| j%                         } | j                  d   ddDd|id      }| j                  dEj                  t        |            d       dF| j                  d<   | j                  | j                  d   d       || j                  d<   | j                  | j                  d<   d| j                  d<   | S |j                  d      dk(  r|j                  d      dk(  r|dGk(  sx| j                  j                  d#      | j                  d<   dH| j                  d<   | j                  | j                  d   d       |j                  d
      rd| j                  d<   | S | j#                         }	| j                  dIj                  t        |	            d        | j                  d   dd.d|	/      }
| j                  dJj                  t        |
            d       |
j                  d      d1k(  redK| j                  d<   | j                  | j                  d   d       |
| j                  d<   | j                  | j                  d<   d| j                  d<   | S c c}w )La  
        If given device doesnot exist
        then add it to pnp database and get the device id
        Args:
            self: An instance of a class used for interacting with Cisco Catalyst Center.
        Returns:
            object: An instance of the class with updated results and status
            based on the processing of differences. Based on the length of devices passed
            it adds/claims or does both.
        Description:
            The function processes the differences and, depending on the
            changes required, it may add, update,or resynchronize devices in
            Cisco Catalyst Center. The updated results and status are stored in the
            class instance for further use.
        r   z$Device Info must be passed as a listr0   r1   rM   r?   r   r   rc   rg   rd   TrC   ziDevice details for serial number {0}                         obtained from the API 'get_device_list': {1}rL   zDetails of the added device:{0}r2   r   rK   zDevices are already addedr4   r   import_devices_in_bulkpayloadzDResponse from API 'import_devices_in_bulk' for imported devices: {0}successListz#{0} device(s) imported successfullydiffchangedzBulk import failedrH   Provisioned)rc   r   Plannedr   z@Device needs to be added before claiming. Please add device_infor#   zAdding device to pnp database
add_devicez@Response from API 'add device' for a single device addition: {0}zOnly Device Added SuccessfullyzDevice Addition Failedz>Response from API 'add device' for single device addition: {0}rN   r   claim_a_device_to_a_siterD   rE   rG   rF   zGResponse from API 'claim a device to a site' for a single claiming: {0}zDevice Claimedz%Device Added and Claimed SuccessfullyzDevice Claim Failedget_device_countzAResponse from 'get device count' API for provisioned devices: {0}zFResponse from 'get_device_count' API for devices in planned state: {0}r   r   z<Response from 'get_device_by_id' API for device details: {0}Fstackr   zPnP state of the device: {0}zDevice is already addedzHThe request sent for 'update_device' API for device's config update: {0}update_device)rN   r   zAResponse from 'update_device' API for device's config update: {0}Errorreset_devicezCResponse from 'update_device' API for errored state resolution: {0}zDevice reset done Successfully	UnclaimedzDevice is already claimedz'Parameters for claiming the device: {0}z>Response from 'claim_a_device_to_a_site' API for claiming: {0}z Only Device Claimed Successfully)r   rP   rQ   r   r4   r8   r5   rT   rO   r6   r   ri   resultr9   r   r   check_return_statusr   r   )r   devices_addeddevicemulti_device_response	bulk_listbulk_paramsprovisioned_count_paramsplanned_count_paramsdev_add_responser   claim_responseprov_dev_responseplan_dev_responser   is_stack	pnp_stateupdate_payloadupdate_responsereset_paramtersreset_responses                       r   get_diff_mergedzPnP.get_diff_merged^  s
   " $))--5t<=DHHHTXXw'"DKKtyy}}\*+a/M))--5 \(?(?2.+VL-A.-QR $	)%  FFLfVT`MabpMqsv  xM  tN  GO  QXY)s3H/IQ/N!((0HH>EEc&kRTZ[\ DIIMM,/03}3EE!K*,J'%@E"U+Y7 #iimmL9. I 
 2$//&1.1!9- 	K HH[bbcnoqxy;??=12Q6%J%Q%Q67&9E"U+V4*5J'&*&;&;F#)-I&+DHHHTXXz*"DKK "YY]]?;"$
  "YY]]?; 

 yy}}^,99\*]7+&99[)8&A#:4??6#:2)99==6q9 $	$  +;*>*>|*L		,'[bbcfgwcxy  |C  D99\*)IDKK&HHT[[/8.>DKK
+*.*?*?DKK'-1DKK	* 	  8DHHHT[[/<"*DK 89#:4??6#:2)99==6q9 $	$  335*:*>*>|*L		,'Y``adeuavw  zA  B#446+;+?+?+EZ(!8!827 $'	" biijmn~j  A  CJ  K!%%j15EE$))T`Ja)PDKK&HHT[[/8.<DKK
+*.*?*?DKK'-1DKK	* 	  5DHHHT[[/<"*DK3DOOF3*'+	
 	T[[\_`q\rsu|}3DOOF3*''	
 	Y``adevawx  {B  	C6tv6*'$))K01	 
 	OVVWZ[oWpqsz{##L155g>+//=AA'JH(,,\:>>wG	/66yA6Jyy%&*iimmN&CDKK
#!:DKKHHT[['3K&		l(CA(F(J(J<(XY08|$W-[bbcqrt{|1$//&1*$))K0-/
 	T[[\_`o\pqsz{"335O4T__V4.'!?3 	N HHZaabeftbuvx  A!ADKKHHT[['0&4DKK
#"&"7"7DKK%)DKK	"K !!*-2!!*-2$&*iimmN&CDKK
#!<DKKHHT[['3""<0)-I&,,.:AA#lBSTV]^00*/	
 	QXXY\]kYlmovwj)-==!CDKKHHT[['0&4DKK
#"&"7"7DKK%)DKK	"Ms   mc           	         g }| j                   j                  d      dd }|D ]d  } | j                  d   ddd|d   d   id	
      }| j                  dj	                  t        |            d       |sRt        |      dk(  sa|d   j                  d      } | j                  d   ddd	d|i      }| j                  dj	                  |d   d   t        |            d       |j                  di       j                  d      dk(  rC|j                  |d   d          | j                   j                  d      j                  |       (|| j                  d<   d| j                  d<   | j                  | j                  d   d       g t        |      dkD  rd	| j                  d<   || j                  d<   | j                   j                  d      | j                  d<   dj	                  t        |            | j                  d<   | j                  | j                  d   d       | S d| j                  d<   | j                  | j                  d   d       || j                  d<   | S )a  
        If the given device is added to pnp database
        and is in unclaimed or failed state delete the
        given device
        Args:
            self: An instance of a class used for interacting with Cisco Catalyst Center.
            Here we pass a list of device info to be deleted
        Returns:
            self: An instance of the class with updated results and status based on
            the deletion operation. It tells us the number of devices deleted if any of the devices
            get deleted
        Description:
            This function is responsible for removing devices from the Cisco Catalyst Center PnP GUI and
            pass new changes if devices are already deleted.
        r   Nr?   r   r   rc   rg   rd   TrC   z5Response from 'get_device_list' API for claiming: {0}rL   rM   r   rN   delete_device_by_id_from_pnpr   z[Device details for the deleted device with                         serial number '{0}': {1}r   DeletedrK   zError while deleting the devicer4   rH   r   r   z"{0} Device(s) Deleted Successfullyr2   zDevice(s) Not Foundr   )
rP   rQ   rO   r8   r6   r   rT   ri   remover   )r   devices_deleteddevices_to_deleter   r   r   rK   s          r   get_diff_deletedzPnP.get_diff_deletedQ  sE      IIMM,7:' 	=F$;DOOF$;.*')=n)MN 	%! HHLSSTWXmTnoqxy$-B)Cq)H1!488>	24??622; $ ),	  228&9Mn9]_bck_l2movx<<b155g>)K#**6,+?+OPIIMM,/66v>.6DKK
+)JDKK&HHT[[/<3	=6 !#%)DKK	"&5DKK
#"&))--"=DKK!E!L!LSQ`Ma!bDKKHHT[['0 	 "7DKKHHT[['3&5DKK
#r   c                    | j                  dj                  t        | j                              d       | j                  dj                  t        |            d       | j                  j                  d      D ]  } | j                  d   ddd|d	   d
   id      }|r8t        |      dk(  r*dj                  |d	   d
         }| j                  |d       ^dj                  |d	   d
         }| j                  |d        d| _        | S )a  
        Verify the merged status(Creation/Updation) of PnP configuration in Cisco Catalyst Center.
        Args:
            - self (object): An instance of a class used for interacting with Cisco Catalyst Center.
            - config (dict): The configuration details to be verified.
        Return:
            - self (object): An instance of a class used for interacting with Cisco Catalyst Center.
        Description:
            This method checks the merged status of a configuration in Cisco Catalyst Center by
            retrieving the current state (have) and desired state (want) of the configuration,
            logs the states, and validates whether the specified device(s) exists in the DNA
            Center configuration's PnP Database.
        Current State (have): {0}r2   Desired State (want): {0}r   r?   r   r   rc   rg   rd   TrC   rM   z_Requested Device with Serial No. {0} is present in Cisco Catalyst Center and addition verified.zRRequested Device with Serial No. {0} is not present in Cisco Catalyst CenterCenterr   r   	r8   r6   r   r   rP   rQ   rO   rT   r5   r   r3   r   r   r4   s        r   verify_diff_mergedzPnP.verify_diff_merged  s    	,33C		NCVL,33CK@&IiimmL1 	)F5doof5.*')=n)MN 	O  S%9Q%>**0&1En1U*V  f%#VF<$8$HI  i('	)*  r   c                    | j                  dj                  t        | j                              d       | j                  dj                  t        |            d       | j                  j                  d      D ]  } | j                  d   ddd|d	   d
   id      }|rt        |      dk(  s*dj                  |d	   d
         }| j                  |d       ^dj                  |d	   d
         }| j                  |d        d| _        | S )a  
        Verify the deletion status of PnP configuration in Cisco Catalyst Center.
        Args:
            - self (object): An instance of a class used for interacting with Cisco Catalyst Center.
            - config (dict): The configuration details to be verified.
        Return:
            - self (object): An instance of a class used for interacting with Cisco Catalyst Center.
        Description:
            This method checks the deletion status of a configuration in Cisco Catalyst Center.
            It validates whether the specified device(s) exists in the Cisco Catalyst Center configuration's
            PnP Database.
        r   r2   r   r   r?   r   r   rc   rg   rd   TrC   rM   zKRequested Device with Serial No. {0} is not present in the Cisco DNACenter.zHRequested Device with Serial No. {0} is present in Cisco Catalyst Centerr   r   r   r   s        r   verify_diff_deletedzPnP.verify_diff_deleted  s    	,33C		NCVL,33CK@&IiimmL1 	)F5doof5.*')=n)MN 	O $_)=)B$fVL%9.%IJ  f%77=vf\>RSa>b7c  i(%	)(  r   r   )__name__
__module____qualname__r   r=   rX   ra   rn   rr   ru   r   r   r   r   r   r   r   r   __classcell__)r   s   @r   r   r   @  s\    !@D)&V&P >4'Rh%NPd4lqf8t(T&r   r   c                     i ddddddddddd	d
gdddddddddddddddddddddddddddddddddddddddddddddd dd!dd"dd#d$d%d&d'd'd(gd)} t        | d*      }t        |      }|j                  j                  d&      }||j                  vr-d+|_        d,j                  |      |_        |j                          |j                         j                          |j                  j                  d      }|j                  D ]  }|j                          |j                  |      j                          |j                         j                           |j                  |          j                          |su |j                  |   |      j                            |j                   d.i |j"                   y-)/z/
    main entry point for module execution
    	dnac_hostTr   )r   r   	dnac_port443)r   r   dnac_usernameadminuser)r   r   aliasesdnac_password)r   no_logdnac_verifyr   Truednac_versionz2.2.3.3
dnac_debugFdnac_logdnac_log_levelr   dnac_log_file_pathzdnac.logdnac_log_appendvalidate_response_schemaconfig_verifydnac_api_task_timeoutinti  dnac_task_poll_interval   r3   r   r   )r   r   r   r   r   deleted)r   choices)argument_specsupports_check_modeinvalidzState {0} is invalidN )r   r   rF   rQ   supported_statesr5   r6   r4   r   r=   r9   reset_valuesr   r   get_diff_state_applyverify_diff_state_apply	exit_jsonr   )element_specr   ccc_pnpr   r  r3   s         r   mainr    s_   
KdE!B %E!B#eU[T\%] $et%D "Fv#F	
 #Uy$I !6e"D E B %u&K )5Z*P &4'H /D0Q $f%G ,e-M .!/L 4VT  x>ST!L& /46F&kGNNw'EG,,,",33E:##%002NN&&7M** Q 446..0+$$U+-AAC2G++E26:NNPQ F&w~~&r   __main__N)
__future__r   r   r   r   __metaclass__
__author__DOCUMENTATIONEXAMPLESRETURNansible.module_utils.basicr   8ansible_collections.cisco.dnac.plugins.module_utils.dnacr   r   r	   r   r  r   r  r   r   <module>r"     sj   
 A @J
aDiT#
H 5 [( [|-'` zF r   