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%}