
    Vhb                        d Z ddlmZmZmZ eZdZdZdZ	ddl
mZ ddlmZ ddlZddlZ ej                   d	      Z G d
 d      Z G d d      Z G d d      Z G d d      Z G d d      Zd Zd Zedk(  r e        yy)z] Ansible module for managing resource group deployments on Dell Technologies (Dell) PowerFlex    )absolute_importdivisionprint_functiona  
module: resource_group
version_added: '2.3.0'
short_description: Manage resource group deployments on Dell PowerFlex.
description:
- Managing resource group deployments on PowerFlex storage system includes deploying,
  editing, adding nodes and deleting a resource group deployment.
author:
- Jennifer John (@johnj9) <ansible.team@dell.com>
- Trisha Datta (@trisha-dell) <ansible.team@dell.com>
extends_documentation_fragment:
  - dellemc.powerflex.powerflex
options:
  resource_group_name:
    description:
    - The name of the resource group.
    - This is a required field to deploy a resource group.
    - Either I(resource_group_id) or I(resource_group_name) must be specified to perform resource group operations.
    - Mutually exclusive with I(resource_group_id).
    type: str
  resource_group_id:
    description:
    - The ID of the resource group.
    - Either I(resource_group_id) or I(resource_group_name) must be specified to perform resource group operations.
    - Mutually exclusive with I(resource_group_name).
    type: str
  template_name:
    description:
    - The name of the published template.
    - Either I(template_id) or I(template_name) must be specified to deploy a resource group.
    - Mutually exclusive with I(template_id).
    type: str
  template_id:
    description:
    - The ID of the published template.
    - Either I(template_id) or I(template_name) must be specified to deploy a resource group.
    - Mutually exclusive with I(template_name).
    type: str
  firmware_repository_id:
    description:
    - The ID of the firmware repository if not using the appliance default catalog.
    - Mutually exclusive with I(firmware_repository_name).
    type: str
  firmware_repository_name:
    description:
    - The name of the firmware repository if not using the appliance default catalog.
    - Mutually exclusive with I(firmware_repository_id).
    type: str
  new_resource_group_name:
    description:
    - New name of the resource group to rename to.
    type: str
  description:
    description:
    - The description of the resource group.
    type: str
  scaleup:
    description:
    - Whether to scale up the resource group. Specify as true to add nodes to the resource group.
    type: bool
    default: false
  clone_node:
    description:
    - Resource to duplicate during scaleup, if more than one nodes are available in the resource group.
    type: str
  node_count:
    description:
    - Number of nodes to clone during scaleup.
    type: int
    default: 1
  validate:
    description:
    - Specify as true to validate the deployment of resource group.
    type: bool
    default: false
  schedule_date:
    description:
    - Scheduled date for the resource group deployment.
    - Specify in YYYY-MM-DD HH:MM:SS.sss or YYYY-MM-DD format.
    type: str
  state:
    description:
    - The state of the resource group.
    type: str
    choices: ['absent', 'present']
    default: 'present'
notes:
- The I(check_mode) is supported.
- Resource group scale up can be done only when deployment is complete.
aJ  
- name: Validate deployment of a resource group
  dellemc.powerflex.resource_group:
    hostname: "{{ hostname }}"
    username: "{{ username }}"
    password: "{{ password }}"
    validate_certs: "{{ validate_certs }}"
    port: "{{ port }}"
    resource_group_name: "{{ resource_group_name_1 }}"
    description: ans_rg
    template_id: c65d0172-8666-48ab-935e-9a0bf69ed66d
    firmware_repository_id: 8aaa80788b5755d1018b576126d51ba3
    validate: true

- name: Deploy a resource group
  dellemc.powerflex.resource_group:
    hostname: "{{ hostname }}"
    username: "{{ username }}"
    password: "{{ password }}"
    validate_certs: "{{ validate_certs }}"
    port: "{{ port }}"
    resource_group_name: "{{ resource_group_name_1 }}"
    description: ans_rg
    template_id: c65d0172-8666-48ab-935e-9a0bf69ed66d
    firmware_repository_id: 8aaa80788b5755d1018b576126d51ba3

- name: Add a node to a resource group
  dellemc.powerflex.resource_group:
    hostname: "{{ hostname }}"
    username: "{{ username }}"
    password: "{{ password }}"
    validate_certs: "{{ validate_certs }}"
    resource_group_name: "{{ resource_group_name_1 }}"
    scaleup: true
    clone_node: "{{ node_1 }}"
    node_count: "{{ node_count }}"

- name: Modify a resource group
  dellemc.powerflex.resource_group:
    hostname: "{{ hostname }}"
    username: "{{ username }}"
    password: "{{ password }}"
    validate_certs: "{{ validate_certs }}"
    resource_group_name: "{{ resource_group_name_1 }}"
    new_resource_group_name: "{{ new_resource_group_name }}"
    description: "description new"

- name: Delete a resource group
  dellemc.powerflex.resource_group:
    hostname: "{{ hostname }}"
    username: "{{ username }}"
    password: "{{ password }}"
    validate_certs: "{{ validate_certs }}"
    port: "{{ port }}"
    resource_group_name: ans_rg
    state: "absent"
a  
changed:
    description: Whether or not the resource has changed.
    returned: always
    type: bool
    sample: 'false'
resource_group_details:
    description: Details of the resource group deployment.
    returned: When resource group exists.
    type: dict
    contains:
        id:
            description: The ID of the deployed resource group.
            type: str
        deploymentName:
            description: The name of the resource group deployment.
            type: str
        deploymentDescription:
            description: The description of the resource group deployment.
            type: str
        serviceTemplate:
            description: The service template of the resource group.
            type: dict
            contains:
                id:
                    description: The ID of the service template.
                    type: str
                templateName:
                    description: The name of the service template.
                    type: str
        status:
            description: The status of the deployment of the resource group.
            type: str
        firmwareRepositoryId:
            description: The ID of the firmware repository of the resource group.
            type: str
    sample: {
        "id": "8aaa03a88de961fa018de96a88d80008",
        "deploymentName": "dep-ans-test-rg1",
        "deploymentDescription": "ans test rg",
        "retry": true,
        "teardown": false,
        "serviceTemplate": {
            "id": "8aaa03a88de961fa018de96a88d80008",
            "templateName": "update-template (8aaa03a88de961fa018de96a88d80008)"
        },
        "scheduleDate": null,
        "status": "error",
        "compliant": true,
        "deploymentDevice": [
            {
                "refId": "scaleio-block-legacy-gateway",
                "refType": "SCALEIO",
                "deviceHealth": "GREEN",
                "compliantState": "COMPLIANT",
                "deviceType": "scaleio",
                "currentIpAddress": "1.3.9.2",
                "componentId": "910bf934-d45a-4fe3-8ea2-dc481e063a81",
                "statusMessage": "The processing of PowerFlex is unsuccessful.",
                "model": "PowerFlex Gateway",
                "brownfield": false
            }
          ],
          "updateServerFirmware": true,
          "useDefaultCatalog": true,
          "firmwareRepository": {
              "id": "8aaa80788b5755d1018b576126d51ba3",
              "name": "PowerFlex 4.5.0.0",
              "rcmapproved": false
          },
          "firmwareRepositoryId": "8aaa80788b5755d1018b576126d51ba3",
          "deploymentHealthStatusType": "red",
          "allUsersAllowed": false,
          "owner": "admin",
          "numberOfDeployments": 0,
          "lifecycleMode": false,
          "vds": false,
          "scaleUp": false,
          "brownfield": false,
          "templateValid": true,
          "configurationChange": false
      }
)AnsibleModule)utilsNresource_groupc                   Z    e Zd Zd ZddZddZd Zd Zd Zd Z	d	 Z
d
 ZddZd Zd Zy)PowerFlexResourceGroupc                 P   t        j                         | _        | j                  j                  t	                      ddgddgddgg}ddgg}t        | j                  ||d      | _        t        j                  | j                         	 t        j                  | j                  j                        | _
        t        j                  d	       y# t        $ rM}t        j                  t        |             | j                  j!                  t        |      
       Y d}~yd}~ww xY w)z. Define all parameters required by this moduleresource_group_nameresource_group_idtemplate_nametemplate_idfirmware_repository_idfirmware_repository_nameT)argument_specmutually_exclusiverequired_one_ofsupports_check_modez3Got the PowerFlex system connection object instancemsgN)r   %get_powerflex_gateway_host_parametersmodule_paramsupdate'get_powerflex_resource_group_parametersr   moduleensure_required_libs%get_powerflex_gateway_host_connectionparamspowerflex_connLOGinfo	Exceptionerrorstr	fail_json)selfmut_ex_argsrequired_one_of_argses       t/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/dellemc/powerflex/plugins/modules/resource_group.py__init__zPowerFlexResourceGroup.__init__   s    "HHJ!!"I"KL-/BC'702LMO "78K LM $,,*0 $	& 	""4;;/	."'"M"M""#$DHHJK 	.IIc!fKK!!c!f!--	.s   AC 	D%AD  D%Nc                 j   |s|s| j                   j                  d       |r`t        j                  |      }| j                  j
                  j                  |g      }|s"d| d}| j                   j                  |       |xs d   d   }| j                  j
                  j                  ||      S )a,  
        Retrieves a service template based on the provided parameters.

        Args:
            template_id (str, optional): The ID of the service template. Defaults to None.
            template_name (str, optional): The name of the service template. Defaults to None.
            for_deployment (bool, optional): Indicates whether the template is for deployment. Defaults to True.

        Returns:
            ServiceTemplate: The retrieved service template.

        Raises:
            AnsibleFailJson: If either `template_id` or `template_name` is not specified for resource group deployment.
            AnsibleFailJson: If the service template with the specified `template_name` is not found.
            AnsibleFailJson: If the service template with the specified `template_id` is not found.
        zSEither template_id or template_name must be specified for resource group deploymentr   filterszService template  is not foundr   id)r   r&   r   
get_filterr    service_templateget	get_by_id)r'   r   r   for_deploymentfilter_querytemplate	error_msgs          r+   get_service_templatez+PowerFlexResourceGroup.get_service_template  s    " }KK!!&{!| ++M:L**;;???WH/mL	%%)%4!6Xa[%6""33==k>ZZ    c                     | j                   j                  j                         }rt        fd|D        d      }nt        fd|D        d      }|s$| j                  j                  dxs  d       |d   S )a  
        Retrieves the firmware repository ID based on the provided firmware repository name or ID.

        Args:
            firmware_repo_id (str, optional): The ID of the firmware repository. Defaults to None.
            firmware_repo_name (str, optional): The name of the firmware repository. Defaults to None.

        Returns:
            str: The ID of the firmware repository.

        Raises:
            ValueError: If the firmware repository is not found.
        c              3   L   K   | ]  }|j                  d       k(  s|  yw)r1   Nr4   ).0repofirmware_repo_ids     r+   	<genexpr>z;PowerFlexResourceGroup.get_firmware_repo.<locals>.<genexpr>G  s!     !h4TXXd^WgEg$!h   $$Nc              3   L   K   | ]  }|j                  d       k(  s|  yw)nameNr>   )r?   r@   firmware_repo_names     r+   rB   z;PowerFlexResourceGroup.get_firmware_repo.<locals>.<genexpr>I  s"     !l4TXXfEUYkEk$!lrC   zFirmware repository r0   r   r1   )r    firmware_repositoryr4   nextr   r&   )r'   rA   rF   firmware_reposfirmware_repos    ``  r+   get_firmware_repoz(PowerFlexResourceGroup.get_firmware_repo7  s~     ,,@@DDF !h>!hjnoM !l>!lnrsMKK!!(<=M=cQc<ddq&r!sT""r;   c                 t    | j                   j                  d   }|s| j                   j                  d       |S )z+ Retrieves the name of the resource group. r   z:Specify resource_group_name for resource group deployment.r   )r   r   r&   )r'   r   s     r+   get_resource_group_namez.PowerFlexResourceGroup.get_resource_group_nameN  s7    "kk001FG"KK!!&b!c""r;   c                 (   d}| j                   j                  d   !|d   | j                   j                  d   k7  rd}| j                   j                  d   !|d   | j                   j                  d   k7  rd}| j                   j                  d   rd}|S )NFnew_resource_group_namedeploymentNameTdescriptiondeploymentDescriptionscaleup)r   r   )r'   deployment_datamodify_dicts      r+   is_modify_neededz'PowerFlexResourceGroup.is_modify_neededU  s    ;;78D 01T[[5G5GHa5bbK;;m,8 78DKK<N<N}<]]K;;i(Kr;   c                     d }d}g }t        t        |d   d               D ]6  }|d   d   |   d   dk(  s|dz   }|j                  |d   d   |   d          8 t        t        |d   d               D ]  }| j                  j                  d   H|dk(  r |d   d   |   d   |d   k(  r|d   d   |   }A|dk7  sG| j                  j                  d	
       d|d   d   |   d   | j                  j                  d   k(  s|d   d   |   } |S )Nr   serviceTemplate
componentstypeSERVER   rE   
clone_nodez<More than 1 server components exist. Provide the clone_node.r   )rangelenappendr   r   r&   )r'   deploy_datanew_componentcount_serverserver_name	components         r+   clone_componentz&PowerFlexResourceGroup.clone_componentc  sp   s;/@#A,#OPQ 	dI,-l;IFvNRZZ+a/"";/@#A,#OPY#Z[a#bc	d s;/@#A,#OPQ 	\I{{!!,/71$5F)G)UV_)`ag)hlwxylz)z$/0A$B<$PQZ$[M!Q&KK)).l)m01,?	J6RVZVaVaVhVhiuVvv$/0A$B<$PQZ$[M	\ r;   c                    | j                  |      }|t        j                         }|j                  d d d d d d||d       g d}t	        t        |d               D ]i  }|d   |   d   dk(  st	        t        |d   |   d               D ]8  }|d   |   d   |   d   |vsd |d   |   d   |   d	<   d |d   |   d   |   d
<   : k |S )Nra   F)
identifierasmGUIDpuppetCertNameosPuppetCertNamemanagementIpAddress
brownfieldr1   rE   )razor_imagescaleio_enabledscaleio_rolecompression_enabledreplication_enabled	resourcesr1   zasm::server
parametersguidvalue)rf   r   random_uuid_generationr   r^   r_   )r'   ra   rb   uuidresource_paramsresourceparams          r+   prepare_add_node_payloadz/PowerFlexResourceGroup.prepare_add_node_payloadw  s+   ,,,E$//1D  ""&$('+#" MO "#mK&@"AB f -h7=N!&s=+Eh+OP\+]'^!_ f(5h?MeTUYZ'67`dM+6x@NuUV\]aeM+6x@NuUV]^	ff r;   c                 r   t        j                  |      }| j                  j                  d   r| j                  j                  d   |d<   | j                  j                  d   r| j                  j                  d   |d<   | j                  j                  d   rd|d<   d|d<   d}|| j                  j                  d	   k  rbt        j                  |      }| j	                  |
      }|r|d   d   j                  |       |dz   }|| j                  j                  d	   k  rb	 | j                  j                  s+| j                  j                  j                  |d   |       y y # t        $ rG}dt        j                  t        |             }| j                  j                  |       Y d }~y d }~ww xY w)NrO   rP   rQ   rR   rS   Tretryr   
node_countrh   rX   rY   r\   r1   )deployment_idrg_dataz8Modifying a resource group deployment failed with error r   )copydeepcopyr   r   r}   r`   
check_moder    
deploymenteditr#   r   get_display_messager%   r&   )r'   rT   new_deployment_datanodenew_deployment_data1rb   r*   errmsgs           r+   modify_resource_group_detailsz4PowerFlexResourceGroup.modify_resource_group_details  s   "mmO< ;;7848KK4F4FG`4a 01;;m,;?;;;M;Mm;\ 78 ;;i(-1	*+/(D++L99'+}}_'E$ $ = =J^ = _ '(9:<HOOP]^ax ++L99	.;;))##..33/RVBW<O 4 Q *  	.OPUPiPijmnojpPqOrsFKK!!f!--	.s   $A E& &	F6/=F11F6c                 `   | j                   j                  d   }| j                   j                  d   }| j                         }| j                   j                  d   }| j                   j                  d   }| j                   j                  d   }| j                   j                  d   }| j                  ||d      }|||ddd	}	|s|r| j	                  ||      }
|
|	d
<   d|	d<   |r6t        j                  |      s| j                   j                  d       ||	d<   t        j                  |	      S )z
        Retrieves deployment data based on the provided parameters.

        :return: A JSON string representing the deployment data.
        r   r   rQ   r   r   schedule_dateT)r6   )rP   rR   rX   updateServerFirmwareuseDefaultCatalogfirmwareRepositoryIdFr   zVInvalid schedule_date format. Specify the date in the format 'YYYY-MM-DDTHH:MM:SS.sss'r   scheduleDate)
r   r   rM   r:   rK   r   validate_dater&   jsondumps)r'   r   r   r   rQ   rA   rF   r   r3   rT   r   s              r+   get_deployment_dataz*PowerFlexResourceGroup.get_deployment_data  s7    kk((7**?;"::<kk((7;;--.FG![[//0JK**?;44[-`d4e1%0/$(!%
 1%)%;%;<LN`%a"6LO2338O/0&&}5%%  +C%  D.;ON+zz/**r;   c                    	 |rTt        j                  |      }| j                  j                  j	                  |g      }t        |      dkD  r	|d   d   }ny| j                  j                  j                  |      S # t        $ rk}t        |d      rt        |j                        dk(  rY d}~y| j                  j                  t        j                  t        |                   Y d}~yd}~ww xY w)a  
        Retrieves deployment details based on the provided deployment name or deployment ID.

        Args:
            deployment_name (str, optional): The name of the deployment. Defaults to None.
            deployment_id (str, optional): The ID of the deployment. Defaults to None.

        Returns:
            list: A list of deployment details if the deployment name is provided and a matching deployment is found.
            None: if the deployment ID is provided and no deployment is found with that ID.
        r.   r   r1   Nstatus404r   )r   r2   r    r   r4   r_   r5   r#   hasattrr%   r   r   r&   r   )r'   deployment_namer   r7   respr*   s         r+   get_deployment_detailsz-PowerFlexResourceGroup.get_deployment_details  s    	M$//@**5599<.9Qt9q=$(GDMM&&11;;MJJ 	Mq(#AHH(>%%%*C*CCF*K%LL		Ms$   AA= $A= =	C1$C,/8C,,C1c           	      X   | j                   st        t        t        t        d}n+t        t        t        t        t        t        t        t        d}| j
                  j                  d   }| j
                  j                  d   }| j
                  j                  }|j                  |||f      S )z
        Get the operation mapping based on the deployment details and module parameters.

        :return: The operation mapping for the given state, validate, and check_mode.
        )presentTTr   TFr   FTr   FF))absentTT)r   TF)r   FT)r   FFr   r   r   r   statevalidate)	deployment_detailsValidateDeployDeployDeleteDeployModifyResourceGroupr   r   r   r4   )r'   operation_mappingr   r   r   s        r+   get_operation_mappingz,PowerFlexResourceGroup.get_operation_mapping  s     &&)7*8*8+1	! )5)5)5*6)<*=*=+>	! ""7+;;%%j1[[++
 $$eXz%BCCr;   c                 B   t        dg       }| j                  | j                  j                  d   | j                  j                  d         | _        | j                         }|r|j                  |       \  }}||d<   ||d<    | j                  j                  d	i | y)
z}
        Perform the module operation.

        :return: A dictionary containing the result of the module operation.
        F)changedresource_group_detailsr   r   )r   r   r   r   N )dictr   r   r   r   r   execute	exit_json)r'   resultresource_group_operationr   r   s        r+   perform_module_operationz/PowerFlexResourceGroup.perform_module_operation  s     #%

 #'"="= KK../DE++,,-@A #> #C $(#=#=#? #.F.N.Nt.T+G+/EF+, 'F9''r;   )NNT)NN)__name__
__module____qualname__r,   r:   rK   rM   rV   rf   r}   r   r   r   r   r   r   r;   r+   r
   r
      sC    .6[:#.#(4.@+BM8D>(r;   r
   c                       e Zd Zd Zy)r   c                    	 | j                         }| j                  j                  j                  |      }d|fS # t        $ rG}dt        j                  t        |             }| j                  j                  |       Y d }~y d }~ww xY w)NTz-Deploying a resource group failed with error r   )
r   r    r   creater#   r   r   r%   r   r&   r'   r   responser*   r   s        r+   r   zDeploy.execute%  s    	...0G**55<<WEH>! 	.DUE^E^_bcd_eEfDghFKK!!f!--	.   8; 	B=BBNr   r   r   r   r   r;   r+   r   r   $      .r;   r   c                       e Zd Zd Zy)r   c                    	 | j                         }| j                  j                  j                  |      }d|fS # t        $ rG}dt        j                  t        |             }| j                  j                  |       Y d }~y d }~ww xY w)NFz9Validating a resource group deployment failed with error r   )
r   r    r   r   r#   r   r   r%   r   r&   r   s        r+   r   zValidateDeploy.execute0  s    	...0G**55>>wGH(?" 	.PQVQjQjknopkqQrPstFKK!!f!--	.r   Nr   r   r;   r+   r   r   /  r   r;   r   c                       e Zd Zd Zy)r   c                 D   	 d}| j                   }| j                  |      r| j                  |       d}| j                  |d         }||fS # t        $ rG}dt        j                  t        |             }| j                  j                  |       Y d }~y d }~ww xY w)NF)rT   Tr1   )r   z+Editing a resource group failed with error r   )
r   rV   r   r   r#   r   r   r%   r   r&   )r'   r   r   r   r*   r   s         r+   r   zModifyResourceGroup.execute;  s    	.G--G$$W$=2272K222OHH$$ 	.B5C\C\]`ab]cCdBefFKK!!f!--	.s   AA 	B=BBNr   r   r;   r+   r   r   :      .r;   r   c                       e Zd Zd Zy)r   c                    	 d}| j                   rn| j                  j                  sV| j                  j                  j                  | j                   d          | j                  | j                   d         | _         d}|| j                   fS # t        $ rG}dt        j                  t        |             }| j                  j                  |       Y d }~y d }~ww xY w)NFr1   rP   )r   Tz7Deleting a resource group deployment failed with error r   )r   r   r   r    r   deleter   r#   r   r   r%   r&   )r'   r   r*   r   s       r+   r   zDeleteDeploy.executeK  s    	.G&&{{--''2299$:Q:QRV:WX33DD[D[\lDm3n +D3333 	.NuOhOhilmnioOpNqrFKK!!f!--	.s   B	B 	C=CCNr   r   r;   r+   r   r   J  r   r;   r   c                  8    t               } | j                          y)zk Create PowerFlex resource group object and perform actions on it
        based on user input from playbookN)r
   r   )objs    r+   mainr   Z  s     !
"C  "r;   c                  0   t        t               t               t               t               t               t               t               t               t        dd      t               t        dd      t        dd      t               t        ddgd      	      S )
zWThis method provides parameters required for the resource group
    module on PowerFlexboolF)rZ   defaultintr\   r   r   )choicesr   )r   r   r   r   r   r   rO   rQ   rS   r]   r   r   r   r   )r   r   r;   r+   r   r   a  sp      F&fF#v!% $F&%06UA.651fIx0)D r;   __main__)__doc__
__future__r   r   r   rZ   __metaclass__DOCUMENTATIONEXAMPLESRETURNansible.module_utils.basicr   Gansible_collections.dellemc.powerflex.plugins.module_utils.storage.dellr   r   r   
get_loggerr!   r
   r   r   r   r   r   r   r   r   r;   r+   <module>r      s    d B BYv8tR
j 5  e'(c( c(L	. .. .. . . . #* zF r;   