Use of Ansible custom Filter_plugins

Source: Internet
Author: User
Tags base64 glob iterable json md5 rand readable ansible playbook

Ansible Playbook A very powerful function is to allow us to customize Filter_plugins, what is this filter_plugin?

Is what we usually see.

{{Item|max}}}

In fact, the back of this max is a function, we can define our own functions, such as:


|--Filter_plugins
| |--zhiming_filter.py
| '--ZHIMING_FILTER.PYC
'--main.yml
The directory structure is that we create the Filter_plugins folder under our playbook, then write a python file that defines some methods:

For example, my:


#!/usr/bin/env python
# Coding=utf-8
'''
Created on APR 13, 2016

@author: Zhizhang
'''
Import re


Class Filtermodule (object):
@staticmethod
def get_ebs_id (data):
Patten = Re.compile (R ' xiaoming-[a-za-z0-9]{8} ')
If Patten.search (data):
return Patten.search (data). Group ()
Return None
def filters (self):
"' Returns a mapping of filters to methods '
return {
"get_ebs_id": self.get_ebs_id,
}

function of this function, for example we have a string of strings

Xiaoming-s7d7f7s7-we32sdfa-asdfasdf

We just want to take xiaoming-s7d7f7s7.

We can use my method directly in playbook, for example

–debug:msg= "The ID infof is {abc|get_ebs_id}}"

And then it's okay.

example, Ilter_plugins plugin implements JINJA2 template filter filter

Ansible supports the default built-in filter usage in JINJA2, which is part of the! Each of the specific features I do not say in detail, we will know the use of the test.

ABS (number)
Absolute

attr (obj, name)
Property


{{My_variable|default (' my_variable is not Defined ')}}
If there are no values, you can define the default

{% for item in mydict|dictsort%}
Sort the dict by key, case insensitive

{% for item in Mydict|dictsort (TRUE)%}
Sort the dict by key, case sensitive

{% for item in Mydict|dictsort (False, ' value ')%}
Sort the dict by key, case insensitive, sorted
Normally and ordered by value.
Escape (s)
Secure Code Patterns


A (SEQ)
First one

Float (value, default=0.0)
Floating-point type

Forceescape (value)
Force HTML Escape


Indent (S, width=4, Indentfirst=false)


{{Mytext|indent (2, True)}}


{{[1, 2, 3]|join (' | ')}}
-> 1|2|3

{{[1, 2, 3]|join}}}
-> 123


{{Users|join (', ', attribute= ' username ')}}


Last (SEQ)
Return to the last item of a sequence.

Length (object)
Return the number of items of a sequence or mapping.


Lower (s)
Convert a value to lowercase.

Random (seq)
Return a random item from the sequence.

Reject ()
Filters a sequence of objects by appying a test to the object and rejecting the ones with the test succeeding.

Example usage:

{{Numbers|reject (' odd ')}}
New in version 2.7.

Rejectattr ()
Filters a sequence of objects by appying A of "an" of "an", "an" and "rejecting" with The test succeeding.

{{users|rejectattr (' is_active ')}}
{users|rejectattr ("email", "None")}}
New in version 2.7.

Replace (s, old, new, Count=none)


{{"Hello World" |replace ("Hello", "Goodbye")}}
-> Goodbye World

{{"Aaaaargh" |replace ("a", "D ' Oh,", 2)}}
-> d ' Oh, d ' Oh, Aaargh

Round (value, precision=0, method= ' common ')


{{42.55|round}}}
-> 43.0
{{42.55|round (1, ' Floor ')}}
-> 42.5
Note this even if rounded to 0 precision, the a float is returned. If you are need a real integer, pipe it through int:

{{42.55|round|int}}}
-> 43
Safe (value)
Mark the value as safe which means the environment with automatic escaping enabled this variable won't be escape D.

Select ()
Filters a sequence of objects by appying a test to the object and only selecting the ones with the test succeeding.

Example usage:

{{Numbers|select (' odd ')}}
{{Numbers|select (' odd ')}}
New in version 2.7.

Selectattr ()


Example usage:

{{users|selectattr (' is_active ')}}
{users|selectattr ("email", "None")}}

{% for item in iterable|sort%}
...
{% ENDFOR%}
It is also possible to sort by (for example to sort by the date of object) by specifying the attribute par Ameter:

{% for item in Iterable|sort (attribute= ' date ')%}
...
{% ENDFOR%}
Changed in version 2.6:the attribute parameter is added.

String (object)
Make a string Unicode if it isn ' t already. That way a markup string isn't converted back to Unicode.


Upper (s)
Convert a value to uppercase.

UrlEncode (value)
Escape strings for use in URLs (uses UTF-8 encoding). It accepts both dictionaries and regular strings as as. pairwise iterables.

WordCount (s)
Number
Here is the code that implements the custom JINJA2 filter. Inside has already implemented the call Ansible's template, may use the filter filter.


#111cn. Net

Import Base64
Import JSON
Import Os.path
Import Yaml
Import types
Import Pipes
Import Glob
Import re
Import operator as Py_operator
From ansible Import Errors
From ansible.utils import md5s
From distutils.version import looseversion, strictversion
From random import Systemrandom
From jinja2.filters import Environmentfilter

def to_nice_yaml (*a, **kw):
' Make verbose, human readable yaml '
Return Yaml.safe_dump (*a, indent=4, Allow_unicode=true, Default_flow_style=false, **kw)

Def To_json (A, *args, **kw):
"Convert the value to JSON" "
Return Json.dumps (A, *args, **kw)

Def To_nice_json (A, *args, **kw):
' Make verbose, human readable JSON '
Return Json.dumps (A, indent=4, Sort_keys=true, *args, **kw)

Def failed (*a, **kw):
' Test If task result yields failed '
item = a[0]
If Type (item)!= dict:
Raise errors. Ansiblefiltererror ("|failed expects a dictionary")
rc = item.get (' RC ', 0)
Failed = Item.get (' failed ', False)
If RC!= 0 or failed:
Return True
Else
Return False

def success (*a, **kw):
' Test If task result yields success '
Return not failed (*a, **kw)

Def changed (*a, **kw):
  ' Test If task result yields changed ' '
  item = a[0]
  if Type ( Item)!= dict:
    raise errors. Ansiblefiltererror ("|changed expects a dictionary")
  if not ' changed ' in item:
    changed = False
    if (' Results ' in item # some modules return a ' results ' key
         and type (item[' results ']) = = List
        and type (item[' Results '][0] = = = Dict):
      for result in item[' results ']:
         changed = changed or Result.get (' changed ', False)
  Else:
    changed = Ite M.get (' changed ', False)
  return changed

def skipped (*a, **kw):
' Test If task result yields skipped '
item = a[0]
If Type (item)!= dict:
Raise errors. Ansiblefiltererror ("|skipped expects a dictionary")
skipped = Item.get (' skipped ', False)
Return skipped

def mandatory (a):
' Make a variable mandatory '
Try
A
Except Nameerror:
Raise errors. Ansiblefiltererror (' mandatory variable not defined. ')
Else
Return a

def bool (a):
' Return a bool to the ARG '
If a is None or type (a) = = bool:
Return a
If type (a) in types. Stringtypes:
A = A.lower ()
If a in [' Yes ', ' on ', ' 1 ', ' true ', 1]:
Return True
Else
Return False

DEF quote (a):
"' return it argument quoted for shell usage '"
Return Pipes.quote (a)

def fileglob (pathname):
' Return list of matched files for Glob '
return Glob.glob (pathname)

def regex (value= ', pattern= ', Ignorecase=false, match_type= ' search '):
' Expose ' re ' as a Boolean filter using the ' Search ' method by default.
This is likely only useful for ' search ' and ' match ' which already
have their own filters.
'''
If ignorecase:
Flags = Re. I
Else
Flags = 0
_re = Re.compile (pattern, flags=flags)
_bool = __builtins__.get (' bool ')
Return _bool (GetAttr (_re, Match_type, ' Search ') (value)

Def match (value, pattern= ', ignorecase=false):
' Perform a ' re.match ' returning a Boolean '
return Regex (value, pattern, ignorecase, ' match ')

def search (value, pattern= ', ignorecase=false):
' Perform a ' re.search ' returning a Boolean '
return Regex (value, pattern, ignorecase, ' search ')

def regex_replace (value= ', pattern= ', replacement= ', ignorecase=false):
' Perform a ' re.sub ' returning a string '

If not isinstance (value, basestring):
Value = str (value)

If ignorecase:
Flags = Re. I
Else
Flags = 0
_re = Re.compile (pattern, flags=flags)
Return _re.sub (replacement, value)

def unique (a):
return set (a)

def intersect (A, B):
return set (a). Intersection (b)

def difference (A, B):
return set (a). Difference (b)

Def symmetric_difference (A, B):
return set (a). Symmetric_difference (b)

Def union (A, B):
return set (a). Union (b)

def version_compare (value, version, operator= ' eq ', strict=false):
"' Perform a version comparison on a value '"
Op_map = {
' = = ': ' eq ', ' = ': ' eq ', ' welfare ': ' eq ',
' < ': ' lt ', ' lt ': ' Lt ',
' <= ': ' Le ', ' le ': ' Le ',
' > ': ' GT ', ' GT ': ' GT ',
' >= ': ' ge ', ' ge ': ' ge ',
'!= ': ' ne ', ' <> ': ' ne ', ' ne ': ' ne '
}

If strict:
Version = Strictversion
Else
Version = Looseversion

If operator in Op_map:
operator = Op_map[operator]
Else
Raise errors. Ansiblefiltererror (' Invalid operator type ')

Try
method = GetAttr (Py_operator, operator)
Return method (Version (str (value)), Version (str (version))
Except Exception, E:
Raise errors. Ansiblefiltererror (' Version comparison:%s '% e)

@environmentfilter
def rand (Environment, end, Start=none, Step=none):
R = Systemrandom ()
If Isinstance (end, (int, long)):
If not start:
Start = 0
If not step:
Step = 1
Return R.randrange (Start, end, step)
Elif hasattr (end, ' __iter__ '):
If Start or step:
Raise errors. Ansiblefiltererror (' Start and step can ' is used with integer values ')
return R.choice (end)
Else
Raise errors. Ansiblefiltererror (' Random can is used on sequences and integers ')

Class Filtermodule (object):
"' Ansible core jinja2 filters '"

def filters (self):
return {
# Base 64
' B64decode ': Base64.b64decode,
' B64encode ': Base64.b64encode,

# JSON
' To_json ': To_json,
' To_nice_json ': To_nice_json,
' From_json ': json.loads,

# YAML
' To_yaml ': Yaml.safe_dump,
' To_nice_yaml ': To_nice_yaml,
' From_yaml ': yaml.safe_load,

# path
' basename ': Os.path.basename,
' DirName ': Os.path.dirname,
' Expanduser ': Os.path.expanduser,
' Realpath ': Os.path.realpath,
' RelPath ': Os.path.relpath,

# Failure Testing
' Failed ': failed,
' Success ': Success,

# changed testing
' Changed ': Changed,

# Skip Testing
' Skipped ': Skipped,

# variable existence
' Mandatory ': mandatory,

# Value As Boolean
' BOOL ': bool,

# Quote string for Shell usage
' Quote ': quote,

# MD5 Hex Digest of string
' MD5 ': md5s,

# file Glob
' Fileglob ': Fileglob,

# regex
' Match ': match,
' Search ': Search,
' Regex ': Regex,
' Regex_replace ': regex_replace,

# list
' Unique ': unique,
' intersect ': intersect,
' Difference ': difference,
' Symmetric_difference ': symmetric_difference,
' Union ': union,

# version Comparison
' Version_compare ': Version_compare,

# random Numbers
' Random ': Rand,
}

The code for the template, this is just a test. The variables inside the template are not introduced from the outside, they are the variables I set myself.

This is Ceshi
{% Set list1 = [1,2,3,4,5,6,7,8,9,10]%}

{% for I in list1%}
{{i}}
{% ENDFOR%}
{{List1|to_nice_yaml}}}

{% Set list2 = [' K_1 ', ' k_2 ', ' k_3 ']%}

To_replace .....

{% for I in list2%}
{{I|to_replace}}}
{% ENDFOR%}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.