
    Vh                        d dl mZ dZd dl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 dlmZ 	 d dlmZmZ d	Z e       Z G d de      Zy# e$ r d
ZY w xY w)    )annotationsa  
author: Unknown (!UNKNOWN)
name: redis
short_description: Use Redis DB for cache
description:
  - This cache uses JSON formatted, per host records saved in Redis.
requirements:
  - redis>=2.4.5 (python lib)
options:
  _uri:
    description:
      - A colon separated string of connection information for Redis.
      - The format is V(host:port:db:password), for example V(localhost:6379:0:changeme).
      - To use encryption in transit, prefix the connection with V(tls://), as in V(tls://localhost:6379:0:changeme).
      - To use redis sentinel, use separator V(;), for example V(localhost:26379;localhost:26379;0:changeme). Requires redis>=2.9.0.
    type: string
    required: true
    env:
      - name: ANSIBLE_CACHE_PLUGIN_CONNECTION
    ini:
      - key: fact_caching_connection
        section: defaults
  _prefix:
    description: User defined prefix to use when creating the DB entries.
    type: string
    default: ansible_facts
    env:
      - name: ANSIBLE_CACHE_PLUGIN_PREFIX
    ini:
      - key: fact_caching_prefix
        section: defaults
  _keyset_name:
    description: User defined name for cache keyset name.
    type: string
    default: ansible_cache_keys
    env:
      - name: ANSIBLE_CACHE_REDIS_KEYSET_NAME
    ini:
      - key: fact_caching_redis_keyset_name
        section: defaults
    version_added: 1.3.0
  _sentinel_service_name:
    description: The redis sentinel service name (or referenced as cluster name).
    type: string
    env:
      - name: ANSIBLE_CACHE_REDIS_SENTINEL
    ini:
      - key: fact_caching_redis_sentinel
        section: defaults
    version_added: 1.3.0
  _timeout:
    default: 86400
    type: integer
        # TODO: determine whether it is OK to change to: type: float
    description: Expiration timeout in seconds for the cache plugin data. Set to 0 to never expire.
    env:
      - name: ANSIBLE_CACHE_PLUGIN_TIMEOUT
    ini:
      - key: fact_caching_timeout
        section: defaults
N)AnsibleError)AnsibleJSONEncoderAnsibleJSONDecoder)BaseCacheModule)Display)StrictRedisVERSIONTFc                       e Zd ZdZdZ ej                  d      Z ej                  d      Z fdZ	e
d        Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Z xZS )CacheModulea  
    A caching module backed by redis.

    Keys are maintained in a zset with their score being the timestamp
    when they are inserted. This allows for the usage of 'zremrangebyscore'
    to expire keys. This mechanism is used or a pattern matched 'scan' for
    performance.
    Nz)^([^:]+|\[[^]]+\]):(\d+):(\d+)(?::(.*))?$z^(.*):(\d+)$c                   d}t        t        | 
  |i | | j                  d      r| j                  d      }t	        | j                  d            | _        | j                  d      | _        | j                  d      | _        | j                  d      | _        t        st        d      i | _        i }d}|j                  |      rd	|d
<   |t        |      d  }| j                  r| j                  ||      | _        n,| j!                  | j"                  |      }t%        |i || _        t&        j)                  d| j                          y )N _uri_timeout_prefix_keyset_name_sentinel_service_namezlThe 'redis' python module (version 2.4.5 or newer) is required for the redis fact cache, 'pip install redis'ztls://TsslzRedis connection: )superr   __init__
get_optionfloatr   r   	_keys_setr   	HAS_REDISr   _cache
startswithlen_get_sentinel_connection_db_parse_connectionre_url_connr	   displayvv)selfargskwargsurikw	tlsprefix
connection	__class__s          i/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/cache/redis.pyr   zCacheModule.__init__e   s/   k4)4:6:??6"//&)Cdooj9:y18&*oo6N&O#   N  O  O 	>>)$BuIc)no&C &&44S"=DH //0@0@#FJ"J5"5DH

'z23    c                ^    | j                  |      }|st        d      |j                         S )Nz!Unable to parse connection string)matchr   groups)re_pattr'   r/   s      r,   r    zCacheModule._parse_connection   s+    c"BCC||~r-   c                h   	 ddl m} d|vrt        d      |j	                  d      }|j                  d      }t        |      dkD  r:|j	                  d      }|j                  d      |d<   	 |j                  d      |d	<   |D cg c]  }| j                  | j                  |        }}t        j                  d
|         ||fi |}	 |j                  | j                  d      S # t        $ r t        d      w xY w# t        $ r Y w xY wc c}w # t        $ r}	t        d|	       d}	~	ww xY w)z;
        get sentinel connection details from _uri
        r   )SentinelzUThe 'redis' python module (version 2.9.0 or newer) is required to use redis sentinel.;z#_uri does not have sentinel syntax.:dbpasswordz
Using redis sentinels: g?)socket_timeoutz%Could not connect to redis sentinel: N)redis.sentinelr3   ImportErrorr   splitpopr   
IndexErrorr    re_sent_connr"   r#   
master_forr   	Exception)
r$   r'   r(   r3   connectionsconnection_argsshost	sentinelssconexcs
             r,   r   z$CacheModule._get_sentinel_connection   sQ   	x/ c>DEE iin%//"-!#-33C8O&**1-BtH!0!4!4Q!7: T__%T++D,=,=uE_	_

.yk:;	(R(	N??4#>#>s?SS+  	xvww	x   `
  	N!FseLMM	Ns;   C) -D #DD )C>	DD	D1D,,D1c                     | j                   |z   S N)r   r$   keys     r,   	_make_keyzCacheModule._make_key   s    ||c!!r-   c                *   || j                   vrk| j                  j                  | j                  |            }|| j	                  |       t
        t        j                  |t              | j                   |<   | j                   j                  |      S )N)cls)	r   r   getrL   deleteKeyErrorjsonloadsr   )r$   rK   values      r,   rO   zCacheModule.get   sn    dkk!HHLL!45E }C #zz%5GHDKK{{s##r-   c                P   t        j                  |t        dd      }| j                  dkD  r@| j                  j                  | j                  |      t        | j                        |       n+| j                  j                  | j                  |      |       t        d   dk(  r:| j                  j                  | j                  t        j                         |       n:| j                  j                  | j                  |t        j                         i       || j                  |<   y )NT   )rN   	sort_keysindentr      )rR   dumpsr   r   r   setexrL   intsetr
   zaddr   timer   )r$   rK   rT   value2s       r,   r]   zCacheModule.set   s    E'9TRST==1HHNN4>>#.DMM0BFKHHLL,f51:?HHMM$..$))+s;HHMM$..3		*<= Cr-   c                    | j                   dkD  rIt        j                         | j                   z
  }| j                  j                  | j                  d|       y y )Nr   )r   r_   r   zremrangebyscorer   )r$   
expiry_ages     r,   _expire_keyszCacheModule._expire_keys   sA    ==1t}}4JHH%%dnnaD r-   c                p    | j                          | j                  j                  | j                  dd      S )Nr   r5   )rd   r   zranger   r$   s    r,   keyszCacheModule.keys   s)    xxt~~q"55r-   c                r    | j                          | j                  j                  | j                  |      d uS rI   )rd   r   zrankr   rJ   s     r,   containszCacheModule.contains   s,    t~~s34?@r-   c                    || j                   v r| j                   |= | j                  j                  | j                  |             | j                  j	                  | j
                  |       y rI   )r   r   rP   rL   zremr   rJ   s     r,   rP   zCacheModule.delete   sI    $++C s+,dnnc*r-   c                b    t        | j                               D ]  }| j                  |        y rI   )listrh   rP   rJ   s     r,   flushzCacheModule.flush   s(    		$ 	CKK	r-   c                j    | j                         D ci c]  }|| j                  |       }}|S c c}w rI   )rh   rO   )r$   krets      r,   copyzCacheModule.copy   s1    '+yy{3!q$((1+~33
 4s   0c                    t               S rI   )dictrg   s    r,   __getstate__zCacheModule.__getstate__   s	    vr-   c                $    | j                          y rI   )r   )r$   datas     r,   __setstate__zCacheModule.__setstate__   s    r-   )__name__
__module____qualname____doc__r   recompiler!   r?   r   staticmethodr    r   rL   rO   r]   rd   rh   rk   rP   rp   rt   rw   rz   __classcell__)r+   s   @r,   r   r   X   s     ""**IJK2::o.L4B  N>"$!E
6A+
r-   r   )
__future__r   DOCUMENTATIONr   r_   rR   ansible.errorsr   ansible.parsing.ajsonr   r   ansible.plugins.cacher   ansible.utils.displayr   redisr	   r
   r   r;   r"   r    r-   r,   <module>r      sc    #<| 
   ' H 1 )*I )S/ S  Is   
A AA