%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /lib/python2.7/site-packages/salt/pillar/
Upload File :
Create Path :
Current File : //lib/python2.7/site-packages/salt/pillar/sql_base.pyc

�
���^c@@s�dZddlmZmZmZddlZddlZddlmZddl	m
Z
ddlmZej
e�Zd�Zdejeje�fd	��YZdS(
u>
Retrieve Pillar data by doing a SQL query

This module is not meant to be used directly as an ext_pillar.
It is a place to put code common to PEP 249 compliant SQL database adapters.
It exposes a python ABC that can be subclassed for new database providers.

:maturity: new
:platform: all

Theory of sql_base ext_pillar
=============================

Ok, here's the theory for how this works...

- First, any non-keyword args are processed in order.
- Then, remaining keywords are processed.

We do this so that it's backward compatible with older configs.
Keyword arguments are sorted before being appended, so that they're predictable,
but they will always be applied last so overall it's moot.

For each of those items we process, it depends on the object type:

- Strings are executed as is and the pillar depth is determined by the number
  of fields returned.
- A list has the first entry used as the query, the second as the pillar depth.
- A mapping uses the keys "query" and "depth" as the tuple

You can retrieve as many fields as you like, how they get used depends on the
exact settings.

Configuring a sql_base ext_pillar
=================================

The sql_base ext_pillar cannot be used directly, but shares query configuration
with its implementations. These examples use a fake 'sql_base' adapter, which
should be replaced with the name of the adapter you are using.

A list of queries can be passed in

.. code-block:: yaml

  ext_pillar:
    - sql_base:
        - "SELECT pillar,value FROM pillars WHERE minion_id = %s"
        - "SELECT pillar,value FROM more_pillars WHERE minion_id = %s"

Or you can pass in a mapping

.. code-block:: yaml

  ext_pillar:
    - sql_base:
        main: "SELECT pillar,value FROM pillars WHERE minion_id = %s"
        extras: "SELECT pillar,value FROM more_pillars WHERE minion_id = %s"

The query can be provided as a string as we have just shown, but they can be
provided as lists

.. code-block:: yaml

  ext_pillar:
    - sql_base:
        - "SELECT pillar,value FROM pillars WHERE minion_id = %s"
          2

Or as a mapping

.. code-block:: yaml

  ext_pillar:
    - sql_base:
        - query: "SELECT pillar,value FROM pillars WHERE minion_id = %s"
          depth: 2

The depth defines how the dicts are constructed.
Essentially if you query for fields a,b,c,d for each row you'll get:

- With depth 1: {a: {"b": b, "c": c, "d": d}}
- With depth 2: {a: {b: {"c": c, "d": d}}}
- With depth 3: {a: {b: {c: d}}}

Depth greater than 3 wouldn't be different from 3 itself.
Depth of 0 translates to the largest depth needed, so 3 in this case.
(max depth == key count - 1)

Then they are merged in a similar way to plain pillar data, in the order
returned by the SQL database.

Thus subsequent results overwrite previous ones when they collide.

The ignore_null option can be used to change the overwrite behavior so that
only non-NULL values in subsequent results will overwrite.  This can be used
to selectively overwrite default values.

.. code-block:: yaml

  ext_pillar:
    - sql_base:
        - query: "SELECT pillar,value FROM pillars WHERE minion_id = 'default' and minion_id != %s"
          depth: 2
        - query: "SELECT pillar,value FROM pillars WHERE minion_id = %s"
          depth: 2
          ignore_null: True

If you specify `as_list: True` in the mapping expression it will convert
collisions to lists.

If you specify `with_lists: '...'` in the mapping expression it will
convert the specified depths to list.  The string provided is a sequence
numbers that are comma separated.  The string '1,3' will result in::

    a,b,c,d,e,1  # field 1 same, field 3 differs
    a,b,c,f,g,2  # ^^^^
    a,z,h,y,j,3  # field 1 same, field 3 same
    a,z,h,y,k,4  # ^^^^
      ^   ^

These columns define list grouping

.. code-block:: python

    {a: [
          {c: [
              {e: 1},
              {g: 2}
              ]
          },
          {h: [
              {j: 3, k: 4 }
              ]
          }
    ]}

The range for with_lists is 1 to number_of_fields, inclusive.
Numbers outside this range are ignored.

Finally, if you pass the queries in via a mapping, the key will be the
first level name where as passing them in as a list will place them in the
root.  This isolates the query results into their own subtrees.
This may be a help or hindrance to your aims and can be used as such.

You can basically use any SELECT query that gets you the information, you
could even do joins or subqueries in case your minion_id is stored elsewhere.
It is capable of handling single rows or multiple rows per minion.

Configuration of the connection depends on the adapter in use.

More complete example for MySQL (to also show configuration)
============================================================

.. code-block:: yaml

    mysql:
      user: 'salt'
      pass: 'super_secret_password'
      db: 'salt_db'

    ext_pillar:
      - mysql:
          fromdb:
            query: 'SELECT col1,col2,col3,col4,col5,col6,col7
                      FROM some_random_table
                     WHERE minion_pattern LIKE %s'
            depth: 5
            as_list: True
            with_lists: [1,3]
i(tabsolute_importtprint_functiontunicode_literalsN(tOrderedDict(trange(tsixcC@stS(N(tFalse(((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pyt__virtual__�stSqlBaseExtPillarcB@s�eZdZd
Zd
Zd
ZdZdZe	Z
d
Ze	Zd�Z
eejd���Zejd��Zd�Zd�Zd�Zd�Zd	�ZRS(u]
    This class receives and processes the database rows in a database
    agnostic way.
    icC@si|_|_dS(N(tresulttfocus(tself((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pyt__init__�scC@sdS(ut
        Return a friendly name for the database, e.g. 'MySQL' or 'SQLite'.
        Used in logging output.
        N((tcls((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pyt_db_name�scC@sdS(uH
        Yield a PEP 249 compliant Cursor as a context manager.
        N((R((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pyt_get_cursor�scC@sQg}|jg|D]}d
|g^q�t|j��}|j�|jg|D]}|||g^qU�g|D]�}t|dtj�r�t|d�st|dtt	f�r�t|d�dkr�|ddst|dt
�ryd|dkryt|dd�ry|^qy}x%|D]}idd6dd6td6d
d6td6}	t|dtj�r�|d|	d<n�t|dtt	f�r�|dd|	d<t|d�dkr?|dd|	d<q?nd|	j|d�|	dr?t|	dtj�r?g|	dj
d	�D]}
t|
�^q |	d<n|	|d<q,W|S(u�
        This function normalizes the config block into a set of queries we
        can use.  The return is a list of consistently laid out dicts.
        iiuqueryuudepthuas_listu
with_listsuignore_nullu,N(textendtNonetlisttkeystsortt
isinstanceRtstring_typestlenttupletdictRtupdatetsplittint(Rtargstkwargstqbuffertstklisttktxtqbtdefaultsti((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pytextract_queries�s4&
*
&=C


 3cC@s-|ri|j|<|_n|j|_dS(u2
        Set self.focus for kwarg queries
        N(R	R
(Rtroot((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pyt
enter_rootscC@sS||_t|�|_|dks3||jkrF|jd|_n	||_dS(u�
        The primary purpose of this function is to store the sql field list
        and the depth to which we process.
        iiN(tfield_namesRt
num_fieldstdepth(RR*R,((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pytprocess_fields(s
	c
C@s_t�}t�}x�|D]�}|j}x�td|jd�D]i}|d|jkr�t|�|kr�g|t|�<||t|�<n|||t|�kr�|t|�j||�q�n|||kr�i|||<|||}q?t|||�}|tkr;i}|||j|�|}q?|t	k	r�|j
r{i}||||g|||<|}q�i|||<|||}q?|||}q?W|j|jdkr�|jd}	|j
r�||	|ks�|	d|jkrr||	|krAt|||	t�sO|||	g|||	<qOng|||	<|||	j||jd�q�|j
s�||jddk	r�||jd|||	<q�q||jd|kr�i|||jd<n|j|jkrqt|�|kr(g|t|�<||t|�<n||jd|t|�krq|t|�j||jd�qqn|||jd}x+t|j|j�D]}|j|}	|d|jkr*t|�|kr�g|t|�<||t|�<n|	|t|�kr*|t|�j|	�q*n|j
r�|	|kr�t||	t�rj||	j||�q�||	||g||	<q�|j
s�||dk	r�||||	<q�q�WqWt|j��}
|
j�x�|
D]|}||}xi||D]]}t||t	�r,t||j��||<q�t||t�r�||g||<q�q�Wq�WdS(uz
        This function takes a list of database results and iterates over,
        merging them into a dict form.
        iiiN(RR
RR,t
with_liststidtappendttypeRRtas_listR+Rtignore_nullRR*Rtreversetvalues(
Rtrowstlistifyt
listify_dictstrettcrdR&ttyttemptnktkstdR"((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pytprocess_results7s�		
	!			
#!!(



c
O@s|j�}tjd||�|j||�}|j���}x�|D]�\}}	|j|	d|f�|jg|jD]}
|
d^qz|	d�|j|�|	d|_	|	dr�|	d|_
n	g|_
|	d|_|j|j
��tjd||�qGWWd	QX|jS(
u>
        Execute queries, merge and return as a dict.
        u"Querying %s for information for %suqueryiudepthuas_listu
with_listsuignore_nulluext_pillar %s: Return data: %sN(RtlogtinfoR'RtexecuteR-tdescriptionR)R2R.R3R@tfetchalltdebugR	(Rt	minion_idtpillarRRtdb_nameRtcursorR(tdetailstrow((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pytfetch�s .


	
N(t__name__t
__module__t__doc__RR	R
R*R+R,RR2R.R3RtclassmethodtabctabstractmethodRRR'R)R-R@RM(((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pyR�s$		8	
		k(RPt
__future__RRRtloggingRRtsalt.utils.odictRtsalt.ext.six.movesRtsalt.extRt	getLoggerRNRARtwith_metaclasstABCMetatobjectR(((s8/usr/lib/python2.7/site-packages/salt/pillar/sql_base.pyt<module>�s	

Zerion Mini Shell 1.0