
    Vh]                        d dl mZmZmZ eZdZdZdZd dl	Z	d dl
Z
	 d dlmZ d dlmZmZ d dlmZ d	Zd dlmZ d dlmZ d Zd Zd Zd Zd Zd Zd Z d Z!d Z"e#dk(  r e"        yy# e$ r d
ZdZdZdZdZdZdZdZdZY Nw xY w)    )absolute_importdivisionprint_functiona  
module: pubnub_blocks
short_description: PubNub blocks management module
description:
  - 'This module allows Ansible to interface with the PubNub BLOCKS infrastructure by providing the following operations:
    create / remove, start / stop and rename for blocks and create / modify / remove for event handlers.'
author:
  - PubNub <support@pubnub.com> (@pubnub)
  - Sergey Mamontov <sergey@pubnub.com> (@parfeon)
requirements:
  - "pubnub_blocks_client >= 1.0"
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  email:
    description:
      - Email from account for which new session should be started.
      - Not required if O(cache) contains result of previous module call (in same play).
    required: false
    type: str
    default: ''
  password:
    description:
      - Password which match to account to which specified O(email) belong.
      - Not required if O(cache) contains result of previous module call (in same play).
    required: false
    type: str
    default: ''
  cache:
    description: >-
      In case if single play use blocks management module few times it is preferred to enabled 'caching' by making previous
      module to share gathered artifacts and pass them to this parameter.
    required: false
    type: dict
    default: {}
  account:
    description:
      - Name of PubNub account for from which O(application) will be used to manage blocks.
      - User's account will be used if value not set or empty.
    type: str
    default: ''
  application:
    description:
      - Name of target PubNub application for which blocks configuration on specific O(keyset) will be done.
    type: str
    required: true
  keyset:
    description:
      - Name of application's keys set which is bound to managed blocks.
    type: str
    required: true
  state:
    description:
      - Intended block state after event handlers creation / update process will be completed.
    required: false
    default: 'present'
    choices: ['started', 'stopped', 'present', 'absent']
    type: str
  name:
    description:
      - Name of managed block which will be later visible on admin.pubnub.com.
    required: true
    type: str
  description:
    description:
      - Short block description which will be later visible on U(https://admin.pubnub.com).
      - Used only if block does not exists and does not change description for existing block.
    required: false
    type: str
  event_handlers:
    description:
      - List of event handlers which should be updated for specified block O(name).
      - 'Each entry for new event handler should contain: V(name), V(src), V(channels), V(event). V(name) used as event handler
        name which can be used later to make changes to it.'
      - C(src) is full path to file with event handler code.
      - V(channels) is name of channel from which event handler is waiting for events.
      - 'V(event) is type of event which is able to trigger event handler: V(js-before-publish), V(js-after-publish), V(js-after-presence).'
      - Each entry for existing handlers should contain C(name) (so target handler can be identified). Rest parameters (C(src),
        C(channels) and C(event)) can be added if changes required for them.
      - It is possible to rename event handler by adding C(changes) key to event handler payload and pass dictionary, which
        will contain single key C(name), where new name should be passed.
      - To remove particular event handler it is possible to set C(state) for it to C(absent) and it will be removed.
    required: false
    default: []
    type: list
    elements: dict
  changes:
    description:
      - List of fields which should be changed by block itself (does not affect any event handlers).
      - 'Possible options for change is: O(name).'
    required: false
    default: {}
    type: dict
  validate_certs:
    description:
      - This key allow to try skip certificates check when performing REST API calls. Sometimes host may have issues with
        certificates on it and this will cause problems to call PubNub REST API.
      - If check should be ignored V(false) should be passed to this parameter.
    required: false
    default: true
    type: bool
a	  
# Event handler create example.
- name: Create single event handler
  community.general.pubnub_blocks:
    email: '{{ email }}'
    password: '{{ password }}'
    application: '{{ app_name }}'
    keyset: '{{ keyset_name }}'
    name: '{{ block_name }}'
    event_handlers:
      - src: '{{ path_to_handler_source }}'
        name: '{{ handler_name }}'
        event: 'js-before-publish'
        channels: '{{ handler_channel }}'

# Change event handler trigger event type.
- name: Change event handler 'event'
  community.general.pubnub_blocks:
    email: '{{ email }}'
    password: '{{ password }}'
    application: '{{ app_name }}'
    keyset: '{{ keyset_name }}'
    name: '{{ block_name }}'
    event_handlers:
      - name: '{{ handler_name }}'
        event: 'js-after-publish'

# Stop block and event handlers.
- name: Stopping block
  community.general.pubnub_blocks:
    email: '{{ email }}'
    password: '{{ password }}'
    application: '{{ app_name }}'
    keyset: '{{ keyset_name }}'
    name: '{{ block_name }}'
    state: stop

# Multiple module calls with cached result passing
- name: Create '{{ block_name }}' block
  register: module_cache
  community.general.pubnub_blocks:
    email: '{{ email }}'
    password: '{{ password }}'
    application: '{{ app_name }}'
    keyset: '{{ keyset_name }}'
    name: '{{ block_name }}'
    state: present
- name: Add '{{ event_handler_1_name }}' handler to '{{ block_name }}'
  register: module_cache
  community.general.pubnub_blocks:
    cache: '{{ module_cache }}'
    application: '{{ app_name }}'
    keyset: '{{ keyset_name }}'
    name: '{{ block_name }}'
    state: present
    event_handlers:
      - src: '{{ path_to_handler_1_source }}'
        name: '{{ event_handler_1_name }}'
        channels: '{{ event_handler_1_channel }}'
        event: 'js-before-publish'
- name: Add '{{ event_handler_2_name }}' handler to '{{ block_name }}'
  register: module_cache
  community.general.pubnub_blocks:
    cache: '{{ module_cache }}'
    application: '{{ app_name }}'
    keyset: '{{ keyset_name }}'
    name: '{{ block_name }}'
    state: present
    event_handlers:
      - src: '{{ path_to_handler_2_source }}'
        name: '{{ event_handler_2_name }}'
        channels: '{{ event_handler_2_channel }}'
        event: 'js-before-publish'
- name: Start '{{ block_name }}' block
  register: module_cache
  community.general.pubnub_blocks:
    cache: '{{ module_cache }}'
    application: '{{ app_name }}'
    keyset: '{{ keyset_name }}'
    name: '{{ block_name }}'
    state: started
z
module_cache:
  description:
    - Cached account information. In case if with single play module used few times it is better to pass cached data to next
      module calls to speed up process.
  type: dict
  returned: always
N)User)BlockEventHandler)
exceptionsTF)AnsibleModule)to_textc                    d}| j                   }|j                  d      rP|d   j                  d      r<|d   d   }t               }|j                  t	        j
                  |d                |S |j                  d      r>|j                  d      r-t        |j                  d      |j                  d            }|S d	}| j                  d
|d       |S )a{  Create and configure user model if it possible.

    :type module:  AnsibleModule
    :param module: Reference on module which contain module launch
                   information and status report methods.

    :rtype:  User
    :return: Reference on initialized and ready to use user or 'None' in
             case if not all required information has been passed to block.
    Ncachemodule_cachepnm_user)r   emailpassword)r   r   zsIt looks like not account credentials has been passed or 'cache' field doesn't have result of previous module call.zMissing account credentials.Fmsgdescriptionchanged)paramsgetr   restorecopydeepcopy	fail_json)moduleuserr   r   err_msgs        s/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/pubnub_blocks.pypubnub_userr       s     D]]Fzz'vg22>Bw/v4==z):;< K 
G	J!7&**W-

:8NO K 	;%,e 	 	= K    c                    | j                   }|j                  d      r[|j                  d      }|j                  |j                  d            }|%d}| j                  d|j	                  |      d       |S |j                         d   }|S )a&  Create and configure account if it is possible.

    :type module:  AnsibleModule
    :param module: Reference on module which contain module launch
                   information and status report methods.
    :type user:    User
    :param user:   Reference on authorized user for which one of accounts
                   should be used during manipulations with block.

    :rtype:  Account
    :return: Reference on initialized and ready to use account or 'None' in
             case if not all required information has been passed to block.
    account)namezIt looks like there is no '{0}' account for authorized user. Please make sure what correct name has been passed during module configuration.zMissing account.Fr   r   )r   r   r#   r   formataccounts)r   r   r   account_namer#   err_frmts         r   pubnub_accountr)     s     ]]Fzz)zz),,,FJJy$9,:?KH !3)1)F%*  , N --/!$Nr!   c           	         d}| j                   }	 |j                  |d         }|Rd}|j                  j                  }| j                  |j                  |d   |      |j                  t        |             |S # t        j                  t        j                  f$ rd}t        |      }t        |d      r|j                  n|j                  d   }| j                  |||j                  t        |             Y d}~d}~ww xY w)aj  Retrieve reference on target application from account model.

    NOTE: In case if account authorization will fail or there is no
    application with specified name, module will exit with error.
    :type module:   AnsibleModule
    :param module:  Reference on module which contain module launch
                    information and status report methods.
    :type account:  Account
    :param account: Reference on PubNub account model from which reference
                    on application should be fetched.

    :rtype:  Application
    :return: Reference on initialized and ready to use application model.
    Napplicationmessager   r   r   r   r   zThere is no '{0}' application for {1}. Make sure what correct application name has been passed. If application doesn't exist you can create it on admin.pubnub.com.r   r   r   )r   r+   r	   AccountErrorGeneralPubNubError_failure_title_from_exceptionhasattrr,   argsr   r   dictownerr   r%   )	r   r#   r+   r   excexc_msg	exc_descrerr_fmtr   s	            r   pubnub_applicationr:   -  s     K]]F5))&*?@ J ##W^^F=,A5I!(tG} 	 	N  ##Z%B%BC 5/4#*3	#:CKK	W)!(&*7m 	 	5 	55s   A: :#DAC<<Dc                     | j                   }|j                  |d         }|Fd}| j                  |j                  |d   |j                        |j
                  t        |             |S )a  Retrieve reference on target keyset from application model.

    NOTE: In case if there is no keyset with specified name, module will
    exit with error.
    :type module:       AnsibleModule
    :param module:      Reference on module which contain module launch
                        information and status report methods.
    :type account:      Account
    :param account:     Reference on PubNub account model which will be
                        used in case of error to export cached data.
    :type application:  Application
    :param application: Reference on PubNub application model from which
                        reference on keyset should be fetched.

    :rtype:  Keyset
    :return: Reference on initialized and ready to use keyset model.
    keysetzThere is no '{0}' keyset for '{1}' application. Make sure what correct keyset name has been passed. If keyset doesn't exist you can create it on admin.pubnub.com.r.   )r   r<   r   r%   r$   r   r4   )r   r#   r+   r   r<   r9   s         r   pubnub_keysetr=   R  st    $ ]]Fx 01F~J 	W^^F8,<,7,<,<>!(tG} 	 	N Mr!   c           	      D   d}| j                   }	 |j                  |d         }|N|d   dv rG|j                  d      }| j                  dj                  |      |j                  t        |      	       |D|d   d
k(  r<t        |j                  d      |j                  d            }|j                  |       |rY|j                  d      r!|d   j                  d      r|d   d   |_        |j                  d      r|j                  d      |_        |S # t        j                  t        j                  f$ re}t        |      }t        |d      r|j                  n|j                  d   }| j                  |||j                  t        |             Y d}~vd}~ww xY w)a  Retrieve reference on target keyset from application model.

    NOTE: In case if there is no block with specified name and module
    configured to start/stop it, module will exit with error.
    :type module:   AnsibleModule
    :param module:  Reference on module which contain module launch
                    information and status report methods.
    :type account:  Account
    :param account: Reference on PubNub account model which will be used in
                    case of error to export cached data.
    :type keyset:   Keyset
    :param keyset:  Reference on keyset model from which reference on block
                    should be fetched.

    :rtype:  Block
    :return: Reference on initialized and ready to use keyset model.
    Nr$   r,   r   r-   state)startedstoppedz'{0}' block doesn't exists.r.   presentr   )r$   r   changes)r   blockr	   KeysetErrorr0   r1   r2   r,   r3   r   r   r4   r   r%   r   	add_blockr$   r   )	r   r#   r<   rD   r   r6   r7   r8   
block_names	            r   pubnub_blockrH   q  s   $ E]]FNVF^, },BBZZ'
:AA*M!(tG} 	 	N }I56::f-"(**]";=::i VI%6%:%:6%B	*62EJ::m$ &

= 9EL3 ""J$A$AB N/4#*3	#:CKK	W)!(tG} 	 	N 	NNs   D #F:AFFc                    | j                  |d         }d|v r |j                  d      j                  d      nd}|j                  d      xs |}|j                  d      }|j                  d      }t        |j                  d            }|j                  d      xs d}|%|dk(  r t	        ||||	      }| j                  |       |)|dk(  r$|||_        |||_        |||_        |||_	        |S )
aj  Retrieve reference on target event handler from application model.

    :type block:  Block
    :param block: Reference on block model from which reference on event
                  handlers should be fetched.
    :type data:   dict
    :param data:  Reference on dictionary which contain information about
                  event handler and whether it should be created or not.

    :rtype:  EventHandler
    :return: Reference on initialized and ready to use event handler model.
             'None' will be returned in case if there is no handler with
             specified name and no request to create it.
    r$   rC   Nchannelseventsrcr?   rB   )r$   rJ   rK   code)
event_handlerpopr   _content_of_file_at_pathr   add_event_handlerr$   rJ   rK   rM   )	rD   datarN   changed_namer$   rJ   rK   rM   r?   s	            r   pubnub_event_handlerrT     s    ''V5M !D( HHY'++F3.2 88F+|Dxx
#HHHWE#DHHUO4DHHW*E )!3$$*.0.  Ui%7!%M%-M""'M!%Mr!   c                    d}| j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j
                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd	}|S | j                   t        j                  k(  rd
}|S | j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j                  k(  rd}|S | j                   t        j                   k(  rd}|S )a  Compose human-readable title for module error title.

    Title will be based on status codes if they has been provided.
    :type exception:  exceptions.GeneralPubNubError
    :param exception: Reference on exception for which title should be
                      composed.

    :rtype:  str
    :return: Reference on error tile which should be shown on module
             failure.
    zGeneral REST API access error.z)Authorization error: missing credentials.z'Authorization error: wrong credentials.z-API access error: insufficient access rights.z%API access error: time token expired.z<Block create did fail: block with same name already exists).z'Unable fetch list of blocks for keyset.zBlock creation did fail.zBlock update did fail.zBlock removal did fail.zBlock start/stop did fail.z0Event handler creation did fail: missing fields.z Event handler creation did fail.zEvent handler update did fail.zEvent handler removal did fail.)rM   r	   $PN_AUTHORIZATION_MISSING_CREDENTIALS"PN_AUTHORIZATION_WRONG_CREDENTIALSPN_USER_INSUFFICIENT_RIGHTSPN_API_ACCESS_TOKEN_EXPIREDPN_KEYSET_BLOCK_EXISTSPN_KEYSET_BLOCKS_FETCH_DID_FAILPN_BLOCK_CREATE_DID_FAILPN_BLOCK_UPDATE_DID_FAILPN_BLOCK_REMOVE_DID_FAILPN_BLOCK_START_STOP_DID_FAILPN_EVENT_HANDLER_MISSING_FIELDSPN_BLOCK_EVENT_HANDLER_EXISTS PN_EVENT_HANDLER_CREATE_DID_FAIL PN_EVENT_HANDLER_UPDATE_DID_FAIL PN_EVENT_HANDLER_REMOVE_DID_FAIL)	exceptiontitles     r   r1   r1     s    -E~~HHH;< L; 
:HH	H98 L7 
:AA	A?4 L3 
:AA	A70 L/ 
:<<	<N, L+ 
:EE	E9( L' 
:>>	>*$ L# 
:>>	>(  L 
:>>	>) L 
:BB	B, L 
:EE	EB L 
:CC	CB L 
:FF	F2 L 
:FF	F0 L 
:FF	F1Lr!   c                     d}| rUt         j                  j                  |       r6t        | d      5 }|j	                         }	 t        |d      }ddd       |S |S # t        $ r Y w xY w# 1 sw Y   |S xY w)zRead file content.

    Try read content of file at specified path.
    :type path:  str
    :param path: Full path to location of file which should be read'ed.
    :rtype:  content
    :return: File content or 'None'
    Nrt)modesurrogate_or_strict)errors)ospathexistsopenreadr   UnicodeError)rm   contentopened_file	b_contents       r   rP   rP      s}     Gt$$T" 	k#((*I!)4IJ	 N7N   		 Ns)   A+A	A(%A+'A((A++A5c                     t        t        ddd      t        dddd      t        ddd      t        dd      t        ddd      t        d	dg d
      t        dd      t        d      t        t               dd      t        t               d      t        t               d      t        dd            } t        | d      }t        s|j	                  d       |j
                  }t        |      }t        ||      }t        ||      }t        |||      }t        |||      }|d uxr |j                  dk(  }||d   dk(  r|j                  |       d }||j                  d      r!|d   j                  d      r|d   d   |_        |j                  d      xs
 t               D ]>  }	|	j                  d      xs d	}
t        |	|       }|
dk(  s+|s.|j!                  |       @ |r3|s1|d   d!k(  r|j#                          n|d   d"k(  r|j%                          |j&                  s	 |j)                          t        |      }|j7                  t        t        |      #             |j@                  xs |jB                  }|jE                  ||'       y # t*        j,                  t*        j.                  t*        j0                  t*        j2                  t*        j4                  f$ r}t        |      }|j7                  t        t        |      #             t9        |      }t;        |d$      r|j<                  n|j>                  d%   }|j	                  |||j@                  |&       Y d }~3d }~ww xY w)(N Fstr)defaultrequiredtypeT)rx   ry   rz   no_log)ry   rz   )ry   rz   r{   rB   )r@   rA   rB   absent)rx   rz   choices)rz   listr4   )rx   rz   elements)rx   rz   bool)r   r   r#   r+   r<   r?   r$   r   event_handlersrC   r   validate_certs)argument_specsupports_check_modez.pubnub_blocks_client required for this module.)r   )r   )r#   )r#   r+   )r#   r<   r?   r|   rC   r$   r   )rR   rD   r@   rA   )r   r,   r   r-   )r   r   )#r4   r~   r
   HAS_PUBNUB_BLOCKS_CLIENTr   r   r    r)   r:   r=   rH   uidremove_blockr   r$   rT   delete_event_handlerstartstop
check_modesaver	   APIAccessErrorrE   
BlockErrorEventHandlerErrorr0   updater1   r2   r,   r3   r   will_change	exit_json)fieldsr   r   r   r#   r+   r<   rD   is_new_blockevent_handler_datar?   rN   r6   r   r7   r8   changed_will_changes                    r   mainr     s   2E:b5uTJR%e<$U3Te<95FH4e,$E:JDF&ITV&146/Dv68F TJF#MN]]F vDV$/G$VW=K67LF@E$8bL VG_8E"::i VI%6%:%:6%B	*62EJ #)**-=">"H$& 	:&**73@yE06H7<>M ]**=9	: \'?i'KKMG_	)JJL 	8LLN =Ld4j12!//@W-@-@
0|L )):+A+A%%z'C'C--/ 		8  =Ld4j 9:3C8G'.sI'>CHHQKIi%,__*6  8 8		8s   4J! !AM<1B M77M<__main__)$
__future__r   r   r   rz   __metaclass__DOCUMENTATIONEXAMPLESRETURNr   rl   pubnub_blocks_clientr   r   r   r	   r   ImportErrorAccountOwnerApplicationKeysetansible.module_utils.basicr
   +ansible.module_utils.common.text.convertersr   r    r)   r:   r=   rH   rT   r1   rP   r   __name__ r!   r   <module>r      s    A @jXQf
  	)8/# 5 ?<>"J>/d+\,^*MM` zF I  	$DGEKFELJ	s   A' 'B B