diff --git a/apps/common/utils.py b/apps/common/utils.py index 2a6c78dfb..3e543a107 100644 --- a/apps/common/utils.py +++ b/apps/common/utils.py @@ -303,12 +303,12 @@ def iso8601_to_unixtime(time_string): return to_unixtime(time_string, _ISO8601_FORMAT) -def http_to_unixtime(time_string): - """把HTTP Date格式的字符串转换为UNIX时间(自1970年1月1日UTC零点的秒数)。 - - HTTP Date形如 `Sat, 05 Dec 2015 11:10:29 GMT` 。 - """ - return to_unixtime(time_string, "%a, %d %b %Y %H:%M:%S GMT") +# def http_to_unixtime(time_string): +# """把HTTP Date格式的字符串转换为UNIX时间(自1970年1月1日UTC零点的秒数)。 +# +# HTTP Date形如 `Sat, 05 Dec 2015 11:10:29 GMT` 。 +# """ +# return to_unixtime(time_string, "%a, %d %b %Y %H:%M:%S GMT") def make_signature(access_key_secret, date=None): diff --git a/apps/ops/ansible/callback.py b/apps/ops/ansible/callback.py index 4103ca0f5..148117991 100644 --- a/apps/ops/ansible/callback.py +++ b/apps/ops/ansible/callback.py @@ -62,36 +62,6 @@ class AdHocResultCallback(CallbackBase): pass -class SingleAdHocResultCallback(CallbackBase): - """ - AdHoc result Callback - """ - def __init__(self, display=None): - self.result_q = dict(contacted={}, dark={}) - super(SingleAdHocResultCallback, self).__init__(display) - - def gather_result(self, n, res): - self.result_q[n][res._host.name].append(res._result) - - def v2_runner_on_ok(self, result): - self.gather_result("contacted", result) - - def v2_runner_on_failed(self, result, ignore_errors=False): - self.gather_result("dark", result) - - def v2_runner_on_unreachable(self, result): - self.gather_result("dark", result) - - def v2_runner_on_skipped(self, result): - self.gather_result("dark", result) - - def v2_playbook_on_task_start(self, task, is_conditional): - pass - - def v2_playbook_on_play_start(self, play): - pass - - class PlaybookResultCallBack(CallbackBase): """ Custom callback model for handlering the output data of diff --git a/apps/ops/tasks.py b/apps/ops/tasks.py index 8aca5fcb4..6101ab932 100644 --- a/apps/ops/tasks.py +++ b/apps/ops/tasks.py @@ -10,14 +10,11 @@ from django.utils import timezone from assets.models import Asset from common.utils import get_logger, encrypt_password -from ops.ansible.runner import AdHocRunner +from .ansible.runner import AdHocRunner logger = get_logger(__file__) - - - @shared_task(bind=True) def run_AdHoc(self, task_tuple, assets, task_name='Ansible AdHoc runner', diff --git a/apps/ops/utils.py b/apps/ops/utils.py new file mode 100644 index 000000000..b2b4d7b4f --- /dev/null +++ b/apps/ops/utils.py @@ -0,0 +1,77 @@ +# ~*~ coding: utf-8 ~*~ + +from __future__ import absolute_import, unicode_literals + +import json +import time +import uuid + +from django.utils import timezone + +from assets.models import Asset +from common.utils import get_logger +from .ansible.runner import AdHocRunner + +logger = get_logger(__file__) + + +def run_AdHoc(task_tuple, assets, + task_name='Ansible AdHoc runner', + task_id=None, pattern='all', record=True): + + if not assets: + logger.warning('Empty assets, runner cancel') + return + if isinstance(assets[0], Asset): + assets = [asset._to_secret_json() for asset in assets] + if task_id is None: + task_id = str(uuid.uuid4()) + + runner = AdHocRunner(assets) + if record: + from .models import TaskRecord + if not TaskRecord.objects.filter(uuid=task_id): + record = TaskRecord(uuid=task_id, + name=task_name, + assets=','.join(str(asset['id']) for asset in assets), + module_args=task_tuple, + pattern=pattern) + record.save() + else: + record = TaskRecord.objects.get(uuid=task_id) + record.date_start = timezone.now() + ts_start = time.time() + logger.warn('Start runner {}'.format(task_name)) + result = runner.run(task_tuple, pattern=pattern, task_name=task_name) + timedelta = round(time.time() - ts_start, 2) + summary = runner.clean_result() + if record: + record.date_finished = timezone.now() + record.is_finished = True + record.result = json.dumps(result) + record.summary = json.dumps(summary) + record.timedelta = timedelta + if len(summary['failed']) == 0: + record.is_success = True + else: + record.is_success = False + record.save() + return summary, result + + +def rerun_AdHoc(task_id): + from .models import TaskRecord + record = TaskRecord.objects.get(uuid=task_id) + assets = record.assets_json + task_tuple = record.module_args + pattern = record.pattern + task_name = record.name + return run_AdHoc(task_tuple, assets, pattern=pattern, + task_name=task_name, task_id=task_id) + + + + + + + diff --git a/apps/ops/utils/__init__.py b/apps/ops/utils/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/perms/tasks.py b/apps/perms/tasks.py new file mode 100644 index 000000000..50ced1ee3 --- /dev/null +++ b/apps/perms/tasks.py @@ -0,0 +1,48 @@ +# ~*~ coding: utf-8 ~*~ +from __future__ import absolute_import, unicode_literals + +from celery import shared_task +from common.utils import get_logger, encrypt_password +from ops.utils import run_AdHoc + +logger = get_logger(__file__) + + +@shared_task(bind=True) +def push_users(self, assets, users): + """ + user: { + name: 'web', + username: 'web', + shell: '/bin/bash', + password: '123123123', + public_key: 'string', + sudo: '/bin/whoami,/sbin/ifconfig' + } + """ + if isinstance(users, dict): + users = [users] + if isinstance(assets, dict): + assets = [assets] + task_tuple = [] + + for user in users: + # 添加用户, 设置公钥, 设置sudo + task_tuple.extend([ + ('user', 'name={} shell={} state=present password={}'.format( + user['username'], user.get('shell', '/bin/bash'), + encrypt_password(user.get('password', None)))), + ('authorized_key', "user={} state=present key='{}'".format( + user['username'], user['public_key'])), + ('lineinfile', + "name=/etc/sudoers state=present regexp='^{0} ALL=(ALL)' " + "line='{0} ALL=(ALL) NOPASSWD: {1}' " + "validate='visudo -cf %s'".format( + user['username'], user.get('sudo', '/bin/whoami') + )) + ]) + task_name = 'Push user {}'.format(','.join([user['name'] for user in users])) + task = run_AdHoc(task_tuple, assets, pattern='all', + task_name=task_name, task_id=self.request.id) + return task +