%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /usr/lib/python2.7/site-packages/salt/cache/
Upload File :
Create Path :
Current File : //usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyo

�
���^c@@s�dZddlmZmZmZddlZy6ddlZddlmZ	ddlm
ZeZ
Wnek
r}eZ
nXyddlmZeZWnek
r�eZnXddlmZddlmZd	Zid
d6Zeje�ZdZd
ZdZdZda!d�Z"d�Z#d�Z$dd�Z%d�Z&d�Z'd�Z(d�Z)d�Z*dd�Z+d�Z,d�Z-dd�Z.d�Z/d�Z0dS( uZ
Redis
=====

Redis plugin for the Salt caching subsystem.

.. versionadded:: 2017.7.0

As Redis provides a simple mechanism for very fast key-value store, in order to
privde the necessary features for the Salt caching subsystem, the following
conventions are used:

- A Redis key consists of the bank name and the cache key separated by ``/``, e.g.:
  ``$KEY_minions/alpha/stuff`` where ``minions/alpha`` is the bank name
  and ``stuff`` is the key name.
- As the caching subsystem is organised as a tree, we need to store the caching
  path and identify the bank and its offspring.  At the same time, Redis is
  linear and we need to avoid doing ``keys <pattern>`` which is very
  inefficient as it goes through all the keys on the remote Redis server.
  Instead, each bank hierarchy has a Redis SET associated which stores the list
  of sub-banks. By default, these keys begin with ``$BANK_``.
- In addition, each key name is stored in a separate SET of all the keys within
  a bank. By default, these SETs begin with ``$BANKEYS_``.

For example, to store the key ``my-key`` under the bank ``root-bank/sub-bank/leaf-bank``,
the following hierarchy will be built:

.. code-block:: text

    127.0.0.1:6379> SMEMBERS $BANK_root-bank
    1) "sub-bank"
    127.0.0.1:6379> SMEMBERS $BANK_root-bank/sub-bank
    1) "leaf-bank"
    127.0.0.1:6379> SMEMBERS $BANKEYS_root-bank/sub-bank/leaf-bank
    1) "my-key"
    127.0.0.1:6379> GET $KEY_root-bank/sub-bank/leaf-bank/my-key
    "my-value"

There are three types of keys stored:

- ``$BANK_*`` is a Redis SET containing the list of banks under the current bank
- ``$BANKEYS_*`` is a Redis SET containing the list of keys under the current bank
- ``$KEY_*`` keeps the value of the key

These prefixes and the separator can be adjusted using the configuration options:

bank_prefix: ``$BANK``
    The prefix used for the name of the Redis key storing the list of sub-banks.

bank_keys_prefix: ``$BANKEYS``
    The prefix used for the name of the Redis keyt storing the list of keys under a certain bank.

key_prefix: ``$KEY``
    The prefix of the Redis keys having the value of the keys to be cached under
    a certain bank.

separator: ``_``
    The separator between the prefix and the key body.

The connection details can be specified using:

host: ``localhost``
    The hostname of the Redis server.

port: ``6379``
    The Redis server port.

cluster_mode: ``False``
    Whether cluster_mode is enabled or not

cluster.startup_nodes:
    A list of host, port dictionaries pointing to cluster members. At least one is required
    but multiple nodes are better

    .. code-block:: yaml

        cache.redis.cluster.startup_nodes
          - host: redis-member-1
            port: 6379
          - host: redis-member-2
            port: 6379

cluster.skip_full_coverage_check: ``False``
    Some cluster providers restrict certain redis commands such as CONFIG for enhanced security.
    Set this option to true to skip checks that required advanced privileges.

    .. note::

        Most cloud hosted redis clusters will require this to be set to ``True``

db: ``'0'``
    The database index.

    .. note::
        The database index must be specified as string not as integer value!

password:
    Redis connection password.

unix_socket_path:

    .. versionadded:: 2018.3.1

    Path to a UNIX socket for access. Overrides `host` / `port`.

Configuration Example:

.. code-block:: yaml

    cache.redis.host: localhost
    cache.redis.port: 6379
    cache.redis.db: '0'
    cache.redis.password: my pass
    cache.redis.bank_prefix: #BANK
    cache.redis.bank_keys_prefix: #BANKEYS
    cache.redis.key_prefix: #KEY
    cache.redis.separator: '@'

Cluster Configuration Example:

.. code-block:: yaml

    cache.redis.cluster_mode: true
    cache.redis.cluster.skip_full_coverage_check: true
    cache.redis.cluster.startup_nodes:
      - host: redis-member-1
        port: 6379
      - host: redis-member-2
        port: 6379
    cache.redis.db: '0'
    cache.redis.password: my pass
    cache.redis.bank_prefix: #BANK
    cache.redis.bank_keys_prefix: #BANKEYS
    cache.redis.key_prefix: #KEY
    cache.redis.separator: '@'
i(tabsolute_importtprint_functiontunicode_literalsN(tConnectionError(t
ResponseError(tStrictRedisCluster(trange(tSaltCacheErroruredisulistulist_u$BANKu$KEYu$BANKEYSu_cC@s2tstdfStr.t�dr.tdfStS(u�
    The redis library must be installed for this module to work.

    The redis redis cluster library must be installed if cluster_mode is True
    u(Please install the python-redis package.ucluster_modeu,Please install the redis-py-cluster package.(t	HAS_REDIStFalsetHAS_REDIS_CLUSTERt_get_redis_cache_optst__virtualname__(((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyt__virtual__�s


cC@siS(N((tkwargs((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pytinit_kwargs�scC@s�itjdd�d6tjdd�d6tjdd�d6tjd	d
�d6tjdd
�d6tjdt�d6tjdi�d6tjdt�d6S(uG
    Return the Redis server connection details from the __opts__.
    ucache.redis.hostu	localhostuhostucache.redis.porti�uportucache.redis.unix_socket_pathuunix_socket_pathucache.redis.dbu0udbucache.redis.passworduupassworducache.redis.cluster_modeucluster_modeu!cache.redis.cluster.startup_nodesu
startup_nodesu,cache.redis.cluster.skip_full_coverage_checkuskip_full_coverage_checkN(t__opts__tgettNoneR	(((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyR�sc
C@s�tr
tS|st�}n|drFtd|dd|d�an8tj|d|dd|d	d
|dd|d
�atS(uL
    Return the Redis server instance.
    Caching the object instance.
    ucluster_modet
startup_nodesu
startup_nodestskip_full_coverage_checkuskip_full_coverage_checkuhostuporttunix_socket_pathuunix_socket_pathtdbudbtpasswordupassword(tREDIS_SERVERRRtredistStrictRedis(topts((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyt_get_redis_server�s





cC@sPitjdt�d6tjdt�d6tjdt�d6tjdt�d6S(	u7
    Build the key opts based on the user options.
    ucache.redis.bank_prefixubank_prefixucache.redis.bank_keys_prefixubank_keys_prefixucache.redis.key_prefixu
key_prefixucache.redis.separatoru	separator(RRt_BANK_PREFIXt_BANK_KEYS_PREFIXt_KEY_PREFIXt
_SEPARATOR(((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyt_get_redis_keys_opts�s
cC@s-t�}djd|dd|dd|�S(u;
    Return the Redis key for the bank given the name.
    u{prefix}{separator}{bank}tprefixubank_prefixt	separatoru	separatortbank(R!tformat(R$R((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyt_get_bank_redis_keys
		

c	C@s3t�}djd|dd|dd|d|�S(uD
    Return the Redis key given the bank name and the key name.
    u{prefix}{separator}{bank}/{key}R"u
key_prefixR#u	separatorR$tkey(R!R%(R$R'R((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyt_get_key_redis_keys		

cC@s-t�}djd|dd|dd|�S(u]
    Return the Redis key for the SET of keys under a certain bank, given the bank name.
    u{prefix}{separator}{bank}R"ubank_keys_prefixR#u	separatorR$(R!R%(R$R((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyt_get_bank_keys_redis_keys
		

cC@sy|jd�}|d}xY|dD]M}t|�}|j||�tjd||�djd|d|�}q$WtS(u�
    Build the bank hierarchy from the root of the tree.
    If already exists, it won't rewrite.
    It's using the Redis pipeline,
    so there will be only one interaction with the remote server.
    u/iiuAdding %s to %su{curr_path}/{bank_name}t	curr_patht	bank_name(tsplitR&tsaddtlogtdebugR%tTrue(R$t
redis_pipet	bank_listtparent_bank_pathR+tprev_bank_redis_key((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyt_build_bank_hier%s
	
ucC@s�|s|ndjd|d|�}|g}t|�}|j|�}|sR|Sx*|D]"}|jt||d|��qYW|S(u�
    A simple tree tarversal algorithm that builds the list of banks to remove,
    starting from an arbitrary node in the tree.
    u
{path}/{bank}tpathR$(R%R&tsmemberstextendt_get_banks_to_remove(tredis_serverR$R6tcurrent_pathtbank_paths_to_removetbank_keytchild_bankst
child_bank((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyR99s$	
 c
C@s�t�}|j�}t||�}t|�}ywt||�tdj|�}|j||�tj	d|||�|j
||�tj	d||�|j�WnJtt
fk
r�}djd|d|�}	tj|	�t|	��nXdS(u(
    Store the data in a Redis key.
    userialu&Setting the value for %s under %s (%s)uAdding %s to %su-Cannot set the Redis cache key {rkey}: {rerr}trkeytrerrN(RtpipelineR(R)R5t__context__tdumpstsetR.R/R-texecutetRedisConnectionErrortRedisResponseErrorR%terrorR(
R$R'tdataR:R1t	redis_keytredis_bank_keystvalueRAtmesg((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pytstoreQs"	
	
cC@s�t�}t||�}d}y|j|�}WnJttfk
r}}djd|d|�}tj|�t	|��nX|dkr�iSt
dj|�S(u*
    Fetch data from the Redis cache.
    u/Cannot fetch the Redis cache key {rkey}: {rerr}R@RAuserialN(RR(RRRGRHR%R.RIRRCtloads(R$R'R:RKtredis_valueRARN((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pytfetchhs		
cC@sxt�}|j�}|d
kr�t||�}x:|D]2}t|�}|j|�tjd||�q7Wytjd�|j�}WnSt	t
fk
r�}djddj|�d|�}	tj
|	�t|	��nXt|�}
x*t|
�D]�}||}||}
x@|D]8}t|
|�}|j|�tjd||
|�qWt|
�}|j|�tjd|
|�t|
�}|j|�tjd	|
|�q�Wndt||�}|j|�tjd|||�t|�}|j||�tjd
|||�y|j�WnJt	t
fk
rs}djd|d|�}	tj
|	�t|	��nXtS(ud
    Remove the key from the cache bank with all the key content. If no key is specified, remove
    the entire bank with all keys and sub-banks inside.
    This function is using the Redis pipelining for best performance.
    However, when removing a whole bank,
    in order to re-create the tree, there are a couple of requests made. In total:

    - one for node in the hierarchy sub-tree, starting from the bank node
    - one pipelined request to get the keys under all banks in the sub-tree
    - one pipeline request to remove the corresponding keys

    This is not quite optimal, as if we need to flush a bank having
    a very long list of sub-banks, the number of requests to build the sub-tree may grow quite big.

    An improvement for this would be loading a custom Lua script in the Redis instance of the user
    (using the ``register_script`` feature) and call it whenever we flush.
    This script would only need to build this sub-tree causing problems. It can be added later and the behaviour
    should not change as the user needs to explicitly allow Salt inject scripts in their Redis instance.
    u%Fetching the keys of the %s bank (%s)uExecuting the pipe...uBCannot retrieve the keys under these cache banks: {rbanks}: {rerr}trbanksu, RAu*Removing the key %s under the %s bank (%s)u/Removing the bank-keys key for the %s bank (%s)uRemoving the %s bank (%s)u@De-referencing the key %s from the bank-keys of the %s bank (%s)u1Cannot flush the Redis cache bank {rbank}: {rerr}trbankN(RRBRR9R)R7R.R/RFRGRHR%tjoinRIRtlenRR(tdeleteR&tsremR0(R$R'R:R1R<tbank_to_removetbank_keys_redis_keytsubtree_keysRARNttotal_bankstindext	bank_keyst	bank_pathRKR=((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pytflush{sn	


		










	
cC@s�t�}t|�}y|j|�}WnJttfk
rt}djd|d|�}tj|�t|��nX|sgSt	|�S(u5
    Lists entries stored in the specified bank.
    u.Cannot list the Redis cache key {rkey}: {rerr}R@RA(
RR&R7RGRHR%R.RIRtlist(R$R:tbank_redis_keytbanksRARN((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pytlist_�s		
cC@szt�}t|�}y|j||�SWnJttfk
ru}djd|d|�}tj|�t|��nXdS(uB
    Checks if the specified bank contains the specified key.
    u2Cannot retrieve the Redis cache key {rkey}: {rerr}R@RAN(	RR&t	sismemberRGRHR%R.RIR(R$R'R:RbRARN((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pytcontains�s		
(1t__doc__t
__future__RRRtloggingRtredis.exceptionsRRGRRHR0RtImportErrorR	tredisclusterRR
tsalt.ext.six.movesRtsalt.exceptionsRRt__func_alias__t	getLoggert__file__R.RRRR RRR
RRRR!R&R(R)R5R9RORRR`RdRf(((s:/usr/lib/python2.7/site-packages/salt/cache/redis_cache.pyt<module>�sN






						
				_	

Zerion Mini Shell 1.0