设为首页 收藏本站
查看: 2667|回复: 0

[经验分享] ansible通过cmdb资产接口动态创建hosts列表

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-7-15 13:27:07 | 显示全部楼层 |阅读模式
前言:
        在自动化、批量化操作主机的时候,有时候咱们需要定义主机组。 比如,saltstack的group组,及salt -N参数 ,在ansible下的自己搞定ansible的主机组。有些麻烦,要知道,你既然选择了用saltstack、ansible这类的集群操作工具,如果你再选择把几十个多到几百个手动地,一个个地把主机组及相关联的主机写入配置,是不是显得很1+1。

    这里简单说下我的一些个方法,首先可以避免这些个配置的写入,在产生minion的id的时候,就给他一个完美又规范的主机域名。 比如,bj-zw-nginx,很容易定位到北京,兆维,nginx机组。 其实主要你的主机域名相当的规范了,啥都好办了。 如果一些难搞的主机,非要自定义group,可以通过cmdb资产接口,来取值,然后复写到配置文件里面,这个方法很有效,在没有了解到ansible有动态inventory的功能前,我一直在用这个方法,间隔性的会从cmdb接口拿到最新的主机及配置信息,复写到类hosts文件里面。


其实我上面说的功能,已经算是可以实现动态的hosts功能,看了沈灿和金山小伙的晓聪的讨论,才知道有个叫 Dynamic Inventory 的东西,这个功能其实是我上面讲解第二个方法的集成版,他省略了这一步,直接调用一个有inventory功能的脚本,然后取出相关的主机list,然后执行。

(这里打个广告,这两天通过朋友了解了猎豹那边的技术氛围,还不错,人虽然不多,因为是面向国外业务的团队,能力真心牛叉,那边运维研发的水平最少不比我差,欢迎牛人去猎豹面试,祝好运 !!! )

好了,正题!

我觉得官网有些太实在了,一些例子说的简单点就行,好让我们自己去扩展思维。 官网一上来就是cobbler和ec2的实例,谁看都有点麻。。。 我是真麻。


wKiom1OAwivQMfZdAAJjsCXI-gA948.jpg

模拟从cmdb资产接口获取数据,然后返回json的脚本  getcmdb.py的内容
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/python
#xiaorui.cc
import argparse
import ConfigParser
import os
import re
from time import time
import xmlrpclib

try:
    import json
except ImportError:
    import simplejson as json

def good():
    parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on Cobbler')
    parser.add_argument('--list', action='store_true', default=True, help='List instances (default: True)')
    parser.add_argument('--host', action='store', help='Get all the variables about a specific instance')

    print json.dumps({"web":{"hosts":["10.10.10.66"]}})


class CobblerInventory(object):
    def __init__(self):
        """ Main execution path """
        self.conn = None

        self.inventory = dict()  # A list of groups and the hosts in that group
        self.cache = dict()  # Details about hosts in the inventory

        # Read settings and parse CLI arguments
        self.parse_cli_args()

        # Cache
        if self.args.refresh_cache:
            self.update_cache()
        elif not self.is_cache_valid():
            self.update_cache()
        else:
            self.load_inventory_from_cache()
            self.load_cache_from_cache()

        data_to_print = ""

        # Data to print
        if self.args.host:
            data_to_print = self.get_host_info()

        elif self.args.list:
            # Display list of instances for inventory
            data_to_print = self.json_format_dict(self.inventory, True)

        else:  # default action with no options
            data_to_print = self.json_format_dict(self.inventory, True)

        print data_to_print

    def _connect(self):
        if not self.conn:
            self.conn = xmlrpclib.Server(self.cobbler_host, allow_none=True)

    ............尼玛太多了。
    def json_format_dict(self, data, pretty=False):
        """ Converts a dict to a JSON object and dumps it as a formatted string """

        if pretty:
            return json.dumps(data, sort_keys=True, indent=2)
        else:
            return json.dumps(data)

good()




脚本后面都是官网的cobbler的,大家可以直接摘出来。只需要上面的good函数就可以了。
不仅可以返回hosts的主机列表,还可以获取vars的变量,然后引用。 我这边用了最简单的例子,直接echo {{ vars }}。  一般来说,可以用 -m template模块,来推送配置。  其实我个人觉得 inventory动态信息和自定义模块的facts在某种程度有些功能重复了。   就我个人的看法,比如 我在操作一个nginx的vhosts和upstream信息组,这个时候用inventory动态和模块都可以从cmdb资产系统里面取出相关的信息来,只是inventory更能精确的返回,需要在那些target主机执行,这些指令!

引用vars变量:
话说,我这里的例子相当的简单,具体的从接口取数据,大家用urllib2 搞就是了。
1
2
3
4
5
6
7
8
#xiaorui.cc
def good():
    parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on Cobbler')
    parser.add_argument('--list', action='store_true', default=True, help='List instances (default: True)')
    parser.add_argument('--host', action='store', help='Get all the variables about a specific instance')
#    print json.dumps({"web":{"hosts":["10.10.10.66"]},{"vars":{"todo":"this server whill restart"}}})
    print json.dumps({"web":{"hosts":["10.10.10.66"],"vars":{"todo":"this server whill restart"}},"nginx":{"hosts":["10.10.10.69"],"va
rs":{"todo":"this nginx is restart"}}})





wKiom1OAxf7BOS3IAAHZpc0tp5Y600.jpg

大家注意下ansible inventory的返回格式,web相当于/etc/ansible/hosts里面的[web]标题,hosts相当于[web]下面的主机list,vars相当于变量。 当然这些变量是供应给hosts主机,通过jinja2引用的。  一般来说,返回不能正确的执行,原因在于格式不对,如果格式对了,没道理不行!(this is 废话)
原来的hosts的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest




这是ansible能通过inventory返回的json信息。
wKioL1OAxmmDZbKnAAC6YrUo8v8855.jpg

来一个比较完整的例子:
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/env python

import sqlite3
import sys
try:
    import json
except ImportError:
    import simplejson as json

dbname = '/etc/inv.db'

def grouplist(conn):

    inventory ={}


    inventory['local'] = [ '127.0.0.1' ]

    cur = conn.cursor()
    cur.execute("SELECT type, name FROM hosts ORDER BY 1, 2")

    for row in cur.fetchall():
        group = row['type']
        if group is None:
            group = 'ungrouped'


        if not group in inventory:
            inventory[group] = {
                'hosts' : []
            }
        inventory[group]['hosts'].append(row['name'])

    cur.close()
    print json.dumps(inventory, indent=4)

def hostinfo(conn, name):

    vars = {}

    cur = conn.cursor()
    cur.execute("SELECT COUNT(*) FROM hosts WHERE name=?", (name, ))

    row = cur.fetchone()
    if row[0] == 0:
        print json.dumps({})
        sys.exit(0)

    # Inject some variables for all hosts
    vars = {
        'admin'         : 'Jane Jolie',
        'datacenter'    : 1
    }

#从ldap重组数据
    if 'ldap' in name.lower():
        vars['baseDN'] = 'dc=mens,dc=de'


    print json.dumps(vars, indent=4)


if __name__ == '__main__':
    con = sqlite3.connect(dbname)
    con.row_factory=sqlite3.Row

    if len(sys.argv) == 2 and (sys.argv[1] == '--list'):
        grouplist(con)
    elif len(sys.argv) == 3 and (sys.argv[1] == '--host'):
        hostinfo(con, sys.argv[2])
    else:
        print "Usage: %s --list or --host <hostname>" % sys.argv[0]
        sys.exit(1)

    con.close()




单纯的看只是格式不一样罢了。好了,就这么着了 ,ansible的中文的文档有些少,真的希望我的这些个小文,能为大家在工作中提高效率及一些实现的思路。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-22078-1-1.html 上篇帖子: 利用ansible modules模块来自定义集群管理 下篇帖子: 探索ansible runner的源码及执行api原理 动态 接口
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表