ansible api base complete...

pull/26/head
Zi Chuanxiu 2015-10-31 11:55:19 +08:00
parent dd4ac4e6d6
commit df9d879f22
1 changed files with 120 additions and 46 deletions

View File

@ -7,6 +7,14 @@ from ansible.inventory import Inventory
from ansible.runner import Runner from ansible.runner import Runner
from ansible.playbook import PlayBook from ansible.playbook import PlayBook
from ansible import callbacks
from ansible import utils
from passlib.hash import sha512_crypt
import os.path
JPERM_DIR = os.path.dirname(os.path.abspath(__file__))
ANSIBLE_DIR = os.path.join(JPERM_DIR, 'playbooks')
class AnsibleError(StandardError): class AnsibleError(StandardError):
""" """
@ -38,21 +46,28 @@ class MyInventory(object):
def __init__(self, resource): def __init__(self, resource):
""" """
resource : resource :
必须是一个字典列表比如 resource的数据格式是一个列表字典比如
[{"hostname": "10.10.10.10", "port": "22", {
"username": "test", "password": "mypass"}, ...] "group1": [{"hostname": "10.10.10.10", "port": "22",
"username": "test", "password": "mypass"}, ...],
"group2": [{"hostname": "10.10.10.10", "port": "22",
"username": "test", "password": "mypass"}, ...]
}
如果你只传入1个列表这默认该列表内的所有主机属于my_group组,比如
[{"hostname": "10.10.10.10", "port": "22",
"username": "test", "password": "mypass"}, ...]
""" """
self.resource = resource self.resource = resource
self._gen_inventory() self.inventory = Inventory()
self.gen_inventory()
def add_group(self, hosts, groupname):
def _gen_inventory(self):
""" """
add hosts to inventory. add hosts to a group
""" """
my_group = Group(name='my_group') my_group = Group(name=groupname)
for host in hosts:
for host in self.resource:
hostname = host.get("hostname") hostname = host.get("hostname")
hostport = host.get("hostport") hostport = host.get("hostport")
username = host.get("username") username = host.get("username")
@ -64,11 +79,17 @@ class MyInventory(object):
my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_pass', password)
my_group.add_host(my_host) my_group.add_host(my_host)
my_inventory = Inventory() self.inventory.add_group(my_group)
my_inventory.add_group(my_group)
my_inventory.subset('my_group')
self.inventory = my_inventory def gen_inventory(self):
"""
add hosts to inventory.
"""
if isinstance(self.resource, list):
self.add_group(self.resource, 'my_group')
elif isinstance(self.resource, dict):
for groupname, hosts in self.resource.iteritems():
self.add_group(hosts, groupname)
class Command(MyInventory): class Command(MyInventory):
@ -78,7 +99,6 @@ class Command(MyInventory):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Command, self).__init__(*args, **kwargs) super(Command, self).__init__(*args, **kwargs)
def run(self, command, module_name="command", timeout=5, forks=10): def run(self, command, module_name="command", timeout=5, forks=10):
""" """
run command from andible ad-hoc. run command from andible ad-hoc.
@ -99,7 +119,6 @@ class Command(MyInventory):
self.results = hoc.run() self.results = hoc.run()
return self.stdout return self.stdout
@property @property
def raw_results(self): def raw_results(self):
""" """
@ -107,7 +126,6 @@ class Command(MyInventory):
""" """
return self.results return self.results
@property @property
def exec_time(self): def exec_time(self):
""" """
@ -122,7 +140,6 @@ class Command(MyInventory):
"delta": value.get("delta"),} "delta": value.get("delta"),}
return result return result
@property @property
def stdout(self): def stdout(self):
""" """
@ -134,7 +151,6 @@ class Command(MyInventory):
result[key] = value.get("stdout") result[key] = value.get("stdout")
return result return result
@property @property
def stderr(self): def stderr(self):
""" """
@ -163,7 +179,6 @@ class Tasks(Command):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Tasks, self).__init__(*args, **kwargs) super(Tasks, self).__init__(*args, **kwargs)
def __run(self, module_args, module_name="command", timeout=5, forks=10): def __run(self, module_args, module_name="command", timeout=5, forks=10):
""" """
run command from andible ad-hoc. run command from andible ad-hoc.
@ -180,6 +195,18 @@ class Tasks(Command):
self.results = hoc.run() self.results = hoc.run()
@property
def msg(self):
"""
get the contacted and dark msg
"""
msg = {}
for result in ["contacted", "dark"]:
all = self.results.get(result)
for key, value in all.iteritems():
if value.get("msg"):
msg[key] = value.get("msg")
return msg
def push_key(self, user, key_path): def push_key(self, user, key_path):
""" """
@ -188,32 +215,60 @@ class Tasks(Command):
module_args = 'user="%s" key="{{ lookup("file", "%s") }}"' % (user, key_path) module_args = 'user="%s" key="{{ lookup("file", "%s") }}"' % (user, key_path)
self.__run(module_args, "authorized_key") self.__run(module_args, "authorized_key")
msg = {} return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
for result in ["contacted", "dark"]:
all = self.results.get(result)
for key, value in all.iteritems():
if value.get("msg"):
msg[key] = value.get("msg")
return {"status": "ok"} if msg else {"status": "failed","msg": msg} def add_user(self, username, password):
def add_user(self, user):
""" """
add a host user. add a host user.
""" """
pass encrypt_pass = sha512_crypt.encrypt(password)
module_args = 'name=%s shell=/bin/bash password=%s' % (username, encrypt_pass)
self.__run(module_args, "user")
return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
def del_user(self, user): def del_user(self, username):
""" """
delete a host user. delete a host user.
""" """
pass module_args = 'name=%s state=absent remove=yes move_home=yes force=yes' % (username)
self.__run(module_args, "user")
return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
class CustomAggregateStats(callbacks.AggregateStats):
"""
Holds stats about per-host activity during playbook runs.
"""
def __init__(self):
super(CustomAggregateStats, self).__init__()
self.results = []
def compute(self, runner_results, setup=False, poll=False,
ignore_errors=False):
"""
Walk through all results and increment stats.
"""
super(CustomAggregateStats, self).compute(runner_results, setup, poll,
ignore_errors)
self.results.append(runner_results)
def summarize(self, host):
"""
Return information about a particular host
"""
summarized_info = super(CustomAggregateStats, self).summarize(host)
# Adding the info I need
summarized_info['result'] = self.results
return summarized_info
class MyPlaybook(MyInventory): class MyPlaybook(MyInventory):
""" """
@ -223,11 +278,32 @@ class MyPlaybook(MyInventory):
super(MyPlaybook, self).__init__(*args, **kwargs) super(MyPlaybook, self).__init__(*args, **kwargs)
def deploy(self): def run(self, playbook_relational_path):
""" """
use ansible playbook to deploy a application. run ansible playbook,
only surport relational path.
""" """
pass stats = CustomAggregateStats()
playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)
playbook_path = os.path.join(ANSIBLE_DIR, playbook_relational_path)
pb = PlayBook(
playbook = playbook_path,
stats = stats,
callbacks = playbook_cb,
runner_callbacks = runner_cb,
inventory = self.inventory,
check=True)
self.results = pb.run()
@property
def raw_results(self):
"""
get the raw results after playbook run.
"""
return self.results
class App(MyPlaybook): class App(MyPlaybook):
@ -240,15 +316,13 @@ class App(MyPlaybook):
if __name__ == "__main__": if __name__ == "__main__":
resource = [ {"hostname": "192.168.10.128", "port": "22", "username": "root", "password": "xxx"}] resource = {"test": [{"hostname": "192.168.10.128", "port": "22", "username": "root", "password": "xxx"}]}
task = Tasks(resource) playbook = MyPlaybook(resource)
print task.push_key('root', '/root/.ssh/id_rsa.pub') playbook.run('test.yml')
print playbook.raw_results
# print task.add_user('test', 'mypass')
# print task.del_user('test')
# print task.push_key('root', '/root/.ssh/id_rsa.pub')