ansible 自定义filter_plugins的用法

ansible playbook 一个非常强大的功能就是允许我们自定义filter_plugins,这个filter_plugin是什么呢?

就是我们一般看到的

{{item|max}}

其实,后边的这个 max就是一个函数,我们可以定义自己的函数,例如:

|-- filter_plugins
|   |-- zhiming_filter.py
|   `-- zhiming_filter.pyc
`-- main.yml
目录结构就是我们在我们的playbook下创建filter_plugins文件夹,然后写一个python文件,里边定义一些方法:

例如我的:

#!/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,
}

 

这个函数的功能事,例如我们有一串字符串

xiaoming-s7d7f7s7-we32sdfa-asdfasdf

我们只想取到xiaoming-s7d7f7s7

我们直接在playbook中使用我的方法就可以了,例如

– debug: msg=” the id infof is {{abc|get_ebs_id}}”

然后就可以了

例子,ilter_plugins插件实现jinja2模板filter过滤器

ansible支持jinja2中默认的内置过滤器用法的,这些是一部分 ! 具体的每个功能我就不详细说了,大家自己测测就知道用途了。

abs(number)
绝对值

attr(obj, name)
属性

{{ my_variable|default('my_variable is not defined') }}
如果没有值,可以定义默认的

 

{% 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)
安全的代码模式

first(seq)
第一个

float(value, default=0.0)
浮点型

forceescape(value)
强制html转义

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 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 test to an attribute of an object or the attribute and rejecting the ones 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 that even if rounded to 0 precision, a float is returned. If you need a real integer, pipe it through int:

{{ 42.55|round|int }}
  -> 43
safe(value)
Mark the value as safe which means that in an environment with automatic escaping enabled this variable will not be escaped.

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 an attribute (for example to sort by the date of an object) by specifying the attribute parameter:

{% for item in iterable|sort(attribute='date') %}
  ...
{% endfor %}
Changed in version 2.6: The attribute parameter was added.

string(object)
Make a string unicode if it isn’t already. That way a markup string is not 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 well as pairwise iterables.

wordcount(s)
个数
下面是实现自定义的jinja2 filter的代码。 里面已经实现了调用ansible的template的时候,有可能会用到的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 = item.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 for 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 its 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', 'eq': '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 only be used with integer values')
    return r.choice(end)
  else:
    raise errors.AnsibleFilterError('random can only be 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,
    }

模板的代码,这里只是做个测试而已。模板里面的变量不是从外面引入的,是我自己设的变量。

 

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

时间: 2024-09-30 18:36:25

ansible 自定义filter_plugins的用法的相关文章

Excel的自定义格式的用法实例

Excel的自定义格式的用法实例   这种带上下箭头的样式,是使用了Excel的自定义格式,可以随数据变化自动改变箭头朝向和字体颜色. 其实实现这样的效果并不难. 选中C2:C10单元格区域,按Ctrl+1,弹出[设置单元格格式]对话框. 在[数字]选项卡下单击[自定义],在格式框中输入以下格式代码: [蓝色]↑0.0%;[红色]↓0.0%;0.0% OK,完成了,就这么简单. 说说格式代码的意思: [蓝色]↑0.0%;[红色]↓0.0%;0.0% 格式分为三部分,用分号隔开. 第一部分是对大于

php自定义错误处理用法实例

 这篇文章主要介绍了php自定义错误处理用法,实例分析了php通过自定义函数进行错误处理的技巧,需要的朋友可以参考下     本文实例讲述了php自定义错误处理用法.分享给大家供大家参考.具体如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <

smarty自定义函数htmlcheckboxes用法实例_php实例

本文实例讲述了smarty自定义函数htmlcheckboxes用法.分享给大家供大家参考.具体如下: 访问文件:index.php: 复制代码 代码如下: <?php require_once('libs/Smarty.class.php'); $smarty = new Smarty(); $smarty->setTemplateDir($_SERVER['DOCUMENT_ROOT']."/php/templates/"); $smarty->setCompil

Android开发之自定义View(视图)用法详解_Android

本文实例讲述了Android开发之自定义View(视图)用法.分享给大家供大家参考,具体如下: View类是Android的一个超类,这个类几乎包含了所有的屏幕类型.每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展.在游戏开发中往往需要自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要.在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等. 为了实现自定义View,需要创建

CodeIgniter自定义控制器MY_Controller用法分析_php实例

本文实例讲述了CodeIgniter自定义控制器MY_Controller用法.分享给大家供大家参考,具体如下: Codeigniter所有的控制器都必须继承CI_Controller类,但CI_Controller类位于system目录下,不太方便修改.为方便做一些公用的处理,通常情况下我们会在core下创建MY_Controller,用来继承CI_Controller,从而项目中所有的控制器继承MY_Controller. 那么,MY_Controller 通常会做些什么呢? 所有的控制器都

php自定义错误处理用法实例_php技巧

本文实例讲述了php自定义错误处理用法.分享给大家供大家参考.具体如下: <?php error_reporting(E_ALL); function ErrHandler($errorno, $errorstr, $errorfile, $errorline) { $display = true; $notify = false; $halt_script = false; $error_msg = "<br>The $errorno error is occurring a

Android开发之自定义View(视图)用法详解

本文实例讲述了Android开发之自定义View(视图)用法.分享给大家供大家参考,具体如下: View类是Android的一个超类,这个类几乎包含了所有的屏幕类型.每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展.在游戏开发中往往需要自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要.在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等. 为了实现自定义View,需要创建

java自定义拦截器用法实例_java

本文实例讲述了java自定义拦截器及其用法.分享给大家供大家参考.具体如下: LoginInterceptor.java文件如下: package com.tq365.util; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwo

关于自定义sitemapprovider的用法,如何清除生成的目录树?

问题描述 当前的代码可以根据数据库自动生成目录,但是注销登陆后,以其他角色用户登录时,目录没有重新生成,还是第一次登陆时生成的目录,代码中有Clear()函数,但是没起作用,不知道该在什么地方调用.希望各位前辈指导!usingSystem;usingSystem.Web;usingSystem.Web.UI;usingSystem.Data.SqlClient;usingSystem.Collections.Specialized;usingSystem.Configuration;usingS