前言:
在自动化、批量化操作主机的时候,有时候咱们需要定义主机组。 比如,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,然后执行。
(这里打个广告,这两天通过朋友了解了猎豹那边的技术氛围,还不错,人虽然不多,因为是面向国外业务的团队,能力真心牛叉,那边运维研发的水平最少不比我差,欢迎牛人去猎豹面试,祝好运 !!! )
好了,正题!
原文:http://rfyiamcool.blog.51cto.com/1030776/1416808
我觉得官网有些太实在了,一些例子说的简单点就行,好让我们自己去扩展思维。 官网一上来就是cobbler和ec2的实例,谁看都有点麻。。。 我是真麻。
模拟从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
):
#原文:http://rfyiamcool.blog.51cto.com/1030776/1416808
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"}}})
|
大家注意下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信息。
来一个比较完整的例子:
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的中文的文档有些少,真的希望我的这些个小文,能为大家在工作中提高效率及一些实现的思路。
本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1416808,如需转载请自行联系原作者