%PDF- %PDF-
Mini Shell

Mini Shell

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

�
���^c@@s0dZddlmZmZmZddlZddlZddlZddl	Zddl
jjZ
ddlZdZeje�ZdZdeZedZd�Zd	�Zd
�Zd�Zd�Zdd
d�Zd�Zd�Zddd�Zd�Z d�Z!d�Z"e#d�Z$d�Z%dS(u�
This module renders highstate configuration into a more human readable format.

How it works:

 `highstate or lowstate` data is parsed with a `proccesser` this defaults to `highstate_doc.proccesser_markdown`.
 The proccessed data is passed to a `jinja` template that builds up the document content.


configuration: Pillar

.. code-block:: yaml

    # the following defaults can be overrided
    highstate_doc.config:

        # list of regex of state names to ignore in `highstate_doc.proccess_lowstates`
        filter_id_regex:
            - '.*!doc_skip$'

        # list of regex of state functions to ignore in `highstate_doc.proccess_lowstates`
        filter_state_function_regex:
            - 'file.accumulated'

        # dict of regex to replace text after `highstate_doc.render`. (remove passwords)
        text_replace_regex:
            'password:.*^': '[PASSWORD]'

        # limit size of files that can be included in doc (10000 bytes)
        max_render_file_size: 10000

        # advanced option to set a custom lowstate proccesser
        proccesser: highstate_doc.proccesser_markdown


State example

.. code-block:: yaml

    {{sls}} note:
        highstate_doc.note:
            - name: example
            - order: 0
            - contents: |
                example `highstate_doc.note`
                ------------------
                This state does not do anything to the system! It is only used by a `proccesser`
                you can use `requisites` and `order` to move your docs around the rendered file.

    {{sls}} a file we dont want in the doc !doc_skip:
        file.managed:
            - name: /root/passwords
            - contents: 'password: sadefgq34y45h56q'
            # also could use `highstate_doc.config: text_replace_regex` to replace
            # password string. `password:.*^': '[PASSWORD]`


To create the help document build a State that uses `highstate_doc.render`.
For preformance it's advised to not included this state in your `top.sls` file.

.. code-block:: yaml

    # example `salt://makereadme.sls`
    make helpfile:
        file.managed:
            - name: /root/README.md
            - contents: {{salt.highstate_doc.render()|json}}
            - show_diff: {{opts['test']}}
            - mode: '0640'
            - order: last

Run our `makereadme.sls` state to create `/root/README.md`.

.. code-block:: bash

    # first ensure `highstate` return without errors or changes
    salt-call state.highstate
    salt-call state.apply makereadme
    # or if you dont want the extra `make helpfile` state
    salt-call --out=newline_values_only salt.highstate_doc.render > /root/README.md ; chmod 0600 /root/README.md


Creating a document collection
------------------------------

From the master we can run the following script to
creates a collection of all your minion documents.

.. code-block:: bash

    salt '*' state.apply makereadme

.. code-block:: python

    #!/bin/python
    import os
    import salt.client
    s = salt.client.LocalClient()
    # NOTE: because of issues with `cp.push` use `highstate_doc.read_file`
    o = s.cmd('*', 'highstate_doc.read_file', ['/root/README.md'])
    for m in o:
        d = o.get(m)
        if d and not d.endswith('is not available.'):
            # mkdir m
            #directory = os.path.dirname(file_path)
            if not os.path.exists(m):
                os.makedirs(m)
            with open(m + '/README.md','wb') as f:
                f.write(d)
            print('ADDED: ' + m + '/README.md')


Once the master has a collection of all the README files.
You can use pandoc to create HTML versions of the markdown.

.. code-block:: bash

    # proccess all the readme.md files to readme.html
    if which pandoc; then echo "Found pandoc"; else echo "** Missing pandoc"; exit 1; fi
    if which gs; then echo "Found gs"; else echo "** Missing gs(ghostscript)"; exit 1; fi
    readme_files=$(find $dest -type f -path "*/README.md" -print)
    for f in $readme_files ; do
        ff=${f#$dest/}
        minion=${ff%%/*}
        echo "proccess: $dest/${minion}/$(basename $f)"
        cat $dest/${minion}/$(basename $f) |             pandoc --standalone --from markdown_github --to html             --include-in-header $dest/style.html             > $dest/${minion}/$(basename $f).html
    done

It is also nice to put the help files in source control.

    # git init
    git add -A
    git commit -am 'updated docs'
    git push -f


Other hints
-----------

If you wish to customize the document format:

.. code-block:: yaml

    # you could also create a new `proccesser` for perhaps reStructuredText
    # highstate_doc.config:
    #     proccesser: doc_custom.proccesser_rst

    # example `salt://makereadme.jinja`
    """
    {{opts['id']}}
    ==========================================

    {# lowstates is set from highstate_doc.render() #}
    {# if lowstates is missing use salt.highstate_doc.proccess_lowstates() #}
    {% for s in lowstates %}
    {{s.id}}
    -----------------------------------------------------------------
    {{s.function}}

    {{s.markdown.requisite}}
    {{s.markdown.details}}

    {%- endfor %}
    """

    # example `salt://makereadme.sls`
    {% import_text "makereadme.jinja" as makereadme %}
    {{sls}} or:
        file.managed:
            - name: /root/README_other.md
            - contents: {{salt.highstate_doc.render(jinja_template_text=makereadme)|json}}
            - mode: '0640'


Some `replace_text_regex` values that might be helpful.

    ## CERTS
    '-----BEGIN RSA PRIVATE KEY-----[
	\S]{0,2200}': 'XXXXXXX'
    '-----BEGIN CERTIFICATE-----[
	\S]{0,2200}': 'XXXXXXX'
    '-----BEGIN DH PARAMETERS-----[
	\S]{0,2200}': 'XXXXXXX'
    '-----BEGIN PRIVATE KEY-----[
	\S]{0,2200}': 'XXXXXXX'
    '-----BEGIN OPENSSH PRIVATE KEY-----[
	\S]{0,2200}': 'XXXXXXX'
    'ssh-rsa .* ': 'ssh-rsa XXXXXXX '
    'ssh-dss .* ': 'ssh-dss XXXXXXX '
    ## DB
    'DB_PASS.*': 'DB_PASS = XXXXXXX'
    '5432:*:*:.*': '5432:*:XXXXXXX'
    "'PASSWORD': .*": "'PASSWORD': 'XXXXXXX',"
    " PASSWORD '.*'": " PASSWORD 'XXXXXXX'"
    'PGPASSWORD=.* ': 'PGPASSWORD=XXXXXXX'
    "_replication password '.*'":  "_replication password 'XXXXXXX'"
    ## OTHER
    'EMAIL_HOST_PASSWORD =.*': 'EMAIL_HOST_PASSWORD =XXXXXXX'
    "net ads join -U '.*@MFCFADS.MATH.EXAMPLE.CA.* ": "net ads join -U '.*@MFCFADS.MATH.EXAMPLE.CA%XXXXXXX "
    "net ads join -U '.*@NEXUS.EXAMPLE.CA.* ": "net ads join -U '.*@NEXUS.EXAMPLE.CA%XXXXXXX "
    'install-uptrack .* --autoinstall': 'install-uptrack XXXXXXX --autoinstall'
    'accesskey = .*': 'accesskey = XXXXXXX'
    'auth_pass .*': 'auth_pass XXXXXXX'
    'PSK "0x.*': 'PSK "0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
    'SECRET_KEY.*': 'SECRET_KEY = XXXXXXX'
    "password=.*": "password=XXXXXXX"
    '<password>.*</password>': '<password>XXXXXXX</password>'
    '<salt>.*</salt>': '<salt>XXXXXXX</salt>'
    'application.secret = ".*"': 'application.secret = "XXXXXXX"'
    'url = "postgres://.*"': 'url = "postgres://XXXXXXX"'
    'PASS_.*_PASS': 'PASS_XXXXXXX_PASS'
    ## HTACCESS
    ':{PLAIN}.*': ':{PLAIN}XXXXXXX'

i(tabsolute_importtprint_functiontunicode_literalsNu
highstate_docu�
{% for s in lowstates %}
`{{s.id_full}}`
-----------------------------------------------------------------
 * state: {{s.state_function}}
 * name: `{{s.name}}`

{{s.markdown.requisites}}
{{s.markdown.details}}

{%- endfor %}
u�
Configuration Managment
===============================================================================

```
####################################################
fqdn: {{grains.get('fqdn')}}
os: {{grains.get('os')}}
osfinger: {{grains.get('osfinger')}}
mem_total: {{grains.get('mem_total')}}MB
num_cpus: {{grains.get('num_cpus')}}
ipv4: {{grains.get('ipv4')}}
master: {{opts.get('master')}}
####################################################
```

This system is fully or partly managed using Salt.

The following sections are a rendered view of what the configuration management system
controlled on this system. Each item is handled in order from top to bottom unless some
requisites like `require` force other ordering.

u�

{% if vars.get('doc_other', True) -%}
Other information
=====================================================================================

```

salt grain: ip_interfaces
-----------------------------------------------------------------
{{grains['ip_interfaces']|dictsort}}


salt grain: hwaddr_interfaces
-----------------------------------------------------------------
{{grains['hwaddr_interfaces']|dictsort}}

{% if not grains['os'] == 'Windows' %}

{% if salt['cmd.has_exec']('ip') -%}
# ip address show
-----------------------------------------------------------------
{{salt['cmd.run']('ip address show | sed "/valid_lft/d"')}}


# ip route list table all
-----------------------------------------------------------------
{{salt['cmd.run']('ip route list table all')}}
{% endif %}

{% if salt['cmd.has_exec']('iptables') %}
{%- if salt['cmd.has_exec']('iptables-save') -%}
# iptables-save
-----------------------------------------------------------------
{{salt['cmd.run']("iptables --list > /dev/null; iptables-save | \grep -v -F '#' | sed '/^:/s@\[[0-9]\{1,\}:[0-9]\{1,\}\]@[0:0]@g'")}}


# ip6tables-save
-----------------------------------------------------------------
{{salt['cmd.run']("ip6tables --list > /dev/null; ip6tables-save | \grep -v -F '#' | sed '/^:/s@\[[0-9]\{1,\}:[0-9]\{1,\}\]@[0:0]@g'")}}
{%- else -%}
# iptables --list-rules
-----------------------------------------------------------------
{{salt['cmd.run']('iptables --list-rules')}}


# ip6tables --list-rules
-----------------------------------------------------------------
{{salt['cmd.run']('ip6tables --list-rules')}}
{% endif %}
{% endif %}

{% if salt['cmd.has_exec']('firewall-cmd') -%}
# firewall-cmd --list-all
-----------------------------------------------------------------
{{salt['cmd.run']('firewall-cmd --list-all')}}
{% endif %}

# mount
-----------------------------------------------------------------
{{salt['cmd.run']('mount')}}

{% endif %}
cK@stS(u�
    Return text for a simple markdown jinja template

    This function can be used from the `highstate_doc.render` modules `jinja_template_function` option.
    (t!markdown_basic_jinja_template_txt(tkwargs((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pytmarkdown_basic_jinja_templateRscK@stS(u�
    Return text for a markdown jinja template that included a header

    This function can be used from the `highstate_doc.render` modules `jinja_template_function` option.
    (t#markdown_default_jinja_template_txt(R((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pytmarkdown_default_jinja_template[scK@stS(u�
    Return text for an advanced markdown jinja template

    This function can be used from the `highstate_doc.render` modules `jinja_template_function` option.
    (t$markdown_advanced_jinja_template_txt(R((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pytmarkdown_full_jinja_templatedscK@s�idgd6gd6id6dd6dd6d
d	6}d
t�krndjt�}|jtd|i��nx8t|j��t|j��@D]}||||<q�W|S(u
    Return configuration
    u.*!doc_skipufilter_id_regexufilter_function_regexureplace_text_regexu!highstate_doc.proccesser_markdownu
proccesseri'umax_render_file_sizeunoteu__salt__u
{0}.configu
config.getN(tNonetglobalstformatt__virtualname__tupdatet__salt__tsettkeys(Rtconfigt
config_keytk((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt_get_configms

)cC@snd}y@tjjj|d��"}tjjj|j��}WdQXWn!tk
ri}tj	|�dSX|S(ue
    output the contents of a file:

    this is a workaround if the cp.push module does not work.
    https://github.com/saltstack/salt/issues/37133

    help the master output the contents of a document
    that might be saved on the minions filesystem.

    .. code-block:: python

        #!/bin/python
        import os
        import salt.client
        s = salt.client.LocalClient()
        o = s.cmd('*', 'highstate_doc.read_file', ['/root/README.md'])
        for m in o:
            d = o.get(m)
            if d and not d.endswith('is not available.'):
                # mkdir m
                #directory = os.path.dirname(file_path)
                if not os.path.exists(m):
                    os.makedirs(m)
                with open(m + '/README.md','wb') as fin:
                    fin.write(d)
                print('ADDED: ' + m + '/README.md')
    uurN(tsalttutilstfilestfopentstringutilst
to_unicodetreadt	ExceptiontlogterrorR
(tnametouttftex((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt	read_file�s%
u-highstate_doc.markdown_default_jinja_templatec
K@s�t|�}t|�}idd6|d6|d6td6td6td6td6|d6}|}|dkr�|r�t||�}n|dkr�td	��ntj	||d
d�}|j
d�}x'|D]}	tj|	||	|�}q�W|S(
u�
    Render highstate to a text format (default Markdown)

    if `jinja_template_text` is not set, `jinja_template_function` is used.

    jinja_template_text: jinja text that the render uses to create the document.
    jinja_template_function: a salt module call that returns template text.
        options:
            highstate_doc.markdown_basic_jinja_template
            highstate_doc.markdown_default_jinja_template
            highstate_doc.markdown_full_jinja_template
    usaltenvuconfigu	lowstatesusaltupillarugrainsuoptsukwargsuNo jinja template textttmplpathureplace_text_regexN(
Rtproccess_lowstatesR
Rt
__pillar__t
__grains__t__opts__Rttpltrender_jinja_tmpltgettretsub(
tjinja_template_texttjinja_template_functionRRt	lowstatestcontextt
template_textttxttrttr((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pytrender�s*


cC@s�|d}|d}dj|d|d�}x(|dD]}tj||�r9tSq9Wx,|dD] }tj||d�rdtSqdWtS(Nustateufunu{0}.{1}ufilter_function_regexufilter_id_regexu__id__(RR-tmatchtTruetFalse(tsRtsstsftstate_functiontb((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt_blacklist_filter�s

cK@s�g}t|�}|jd�}td�}t|t�sLtd��n7t|�dkr�t|dt�s�td��q�nxF|D]>}t||�r�q�nt||||�}|j	|�q�W|S(u�
    return proccessed lowstate data that was not blacklisted

    render_module_function is used to provide your own.
    defaults to from_lowstate
    u
proccesserustate.show_lowstateuLERROR: to see details run: [salt-call state.show_lowstate] <-----***-SEE-***i(
RR,Rt
isinstancetlistRtlentdictR@tappend(RtstatesRt
proccessertlsR;tdoc((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyR&�s

cC@s�i}|dkr?ddddddddd	d
ddg}nt|j��}|rj|t|�8}n|r�|t|�M}nx|D]}||||<q�Wt|�d
kr�dStjjj|dt�S(u3
    return a data dict in yaml string format.
    u__env__u__id__u__sls__ufununameucontextuorderustateurequireu
require_inuwatchuwatch_initdefault_flow_styleN(	R
RRRCRRtyamlt	safe_dumpR:(tdatat	whitelistt	blacklisttytksetR((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt_state_data_to_yaml_string�s-
cC@s|jdd�S(uM
    sanitize text data that is to be displayed in a markdown code block
    u```u``[`][markdown parse fix](treplace(ttext((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt_md_fixsc	C@smd}td|�}t|ddddddd	g�}|rY|d
j||�7}n|jd	�}||jd�krAt}y2tdd
j|��}d|kr�t}nWntk
r�}t}nX|r�d}	n<tjj	j
|d��"}
tjjj|
j
��}	WdQXt|	�}	|dj|	|�7}n(|djdjdjt�|��7}|S(Nuu
file.statsRNuuserugroupumodeuuidugidusizeufile stat {1}
```
{0}```
umax_render_file_sizeu	cmd.shellu\file -i '{0}'ucharset=binaryu[[skipped binary data]]urufile data {1}
```
{0}
```
u```
{0}
```
uASKIPPED LARGE FILE!
Set {0}:max_render_file_size > {1} to render.u
{0}.config(RRRRR,R9R:RRRRRRRRRUR
(tfilenameRtrett
file_statsRPt	file_sizet	is_binaryt	file_typeR#t	file_dataR"((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt_format_markdown_system_files,$

	!(cC@sE|}d}x |D]}|j|d�}qW|jdd�}|S(Nu~`!@#$%^&*()+={}[]:;"<>,.?/|'\uu u-(RS(R tlinktsymbalsR;((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt_format_markdown_link0s
cC@s?dj||�}|r.dj|t|��Sdj|�SdS(u4
    format requisite as a link users can click
    u{0}: {1}u * [{0}](#{1})
u	 * `{0}`
N(RR`(tstatetstateidtmakelinktfmt_id((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt_format_markdown_requisite9scK@s4|}dj|d|d�}dj|d|d�}d}|jd�r�|d7}xI|jdg�D]5}|t|j�d	d	|j�d	d
�7}qlW|d7}n|jd�r$|d
7}xI|jdg�D]5}|t|j�d	d	|j�d	d
�7}q�W|d7}n|jd�r�t|jd��d	kr�|d7}xI|jdg�D]5}|t|j�d	d	|j�d	d
�7}qkW|d7}n|jd�r#|d7}xI|jdg�D]5}|t|j�d	d	|j�d	d
�7}q�W|d7}nd}|dkr�d|kr[|dj|d�7}nd|kr�td|d�}	|	r�|dj|	�7}q�|djdj|d��7}q�n|dkr�|jd|jd��}
|dj|
�7}n|dkr�|d7}t|�}|r8|dj|�7}nd|kr�td d!|jd�d"d#�}t|�d$ks�d%|kr�x8|D]}
|t|
|�7}q�Wq�|d&7}|d'7}q�|d(7}|d)7}|d*7}n|d+kr_|jd,�r|d-jt|d,��7}n|jd�r_d.|jd�}	|d-jt|	��7}q_n|d/kr�|t|d|�7}nt|�d	kr�t|�}|r�|d0j|�7}q�ni|d16|dd6|dd6|dd26|dd36|d46|d56i|j	d6�d76|j	d6�d86d96}|S(:uw
    Takes low state data and returns a dict of proccessed data
    that is by default used in a jinja template when rendering a markdown highstate_doc.

    This `lowstate_item_markdown` given a lowstate item, returns a dict like:

    .. code-block:: yaml

        vars:       # the raw lowstate_item that was proccessed
        id:         # the 'id' of the state.
        id_full:    # combo of the state type and id "state: id"
        state:      # name of the salt state module
        function:   # name of the state function
        name:       # value of 'name:' passed to the salt state module
        state_function:    # the state name and function name
        markdown:          # text data to describe a state
            requisites:    # requisite like [watch_in, require_in]
            details:       # state name, parameters and other details like file contents

    u{0}.{1}ustateufunu{0}: {1}u__id__uuwatchu run or update after changes in:
iiu
uwatch_inuafter changes, run or update:
urequireu	require:
u
require_inu
required in:
uhighstate_doc.noteucontentsu
{0}
usourceucp.get_file_struERROR: opening {0}u
pkg.installedupkgsunameu
```
install: {0}
```
ufile.recurseurecurse copy of files
u```
{0}
```
u!doc_recurseu	file.findtpathttypeufi
u!doc_recurse_forceu3 > Skipping because more than 10 files to display.
u: > HINT: to force include !doc_recurse_force in state id.
u7 > For more details review logs and Salt state files.

u^ > HINT: for improved docs use multiple file.managed states or file.archive, git.latest. etc.
uC > HINT: to force doc to show all files in path add !doc_recurse .
ufile.blockreplaceucontentu/ensure block of content is in file
```
{0}
```
u** source: ufile.managedu```
{0}```
uvarsufunctionuiduid_fullustate_functionuutf-8u
requisitesudetailsumarkdown(
RR,RetitemsRCRRRR]RUtdecode(t
lowstate_itemRRR;R>tid_fullt
requisitestwtdetailsRTtpkgsRPt	findfilesR"R6((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pytproccesser_markdownDs�
3

3
*
3

3
&
"





 (&t__doc__t
__future__RRRR-tloggingtsalt.utils.filesRtsalt.utils.stringutilstsalt.utils.templatesRt	templatesR*tsalt.utils.yamlR
t	getLoggert__name__RRRRRRR	RR$R
R7R@R&RRRUR]R`R9ReRq(((s>/usr/lib/python2.7/site-packages/salt/modules/highstate_doc.pyt<module>�s6
?								&(	
					

Zerion Mini Shell 1.0