mirror of https://github.com/jumpserver/jumpserver
				
				
				
			[Change] 拆分tasks
							parent
							
								
									0fbd9843bd
								
							
						
					
					
						commit
						a4504dc0c7
					
				| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue