Пример #1
0
def task_generator(action, selector):
    log.debug("call task_generator: %s", action)
    try:
        service = Prototype.objects.get(bundle=action.prototype.bundle,
                                        type='service',
                                        name='ZOOKEEPER',
                                        version='1.2')
    except Prototype.DoesNotExist:
        raise AdcmEx('TASK_GENERATOR_ERROR', 'service ZOOKEEPER not found')

    try:
        stop = Action.objects.get(prototype=service, name='stop')
    except Prototype.DoesNotExist:
        raise AdcmEx('TASK_GENERATOR_ERROR',
                     'action stop of service ZOOKEEPER not found')

    try:
        start = Action.objects.get(prototype=service, name='start')
    except Prototype.DoesNotExist:
        raise AdcmEx('TASK_GENERATOR_ERROR',
                     'action start of service ZOOKEEPER not found')

    return (
        {
            'action': stop,
            'selector': selector
        },
        {
            'action': start,
            'selector': selector
        },
    )
Пример #2
0
    def run(self, tmp=None, task_vars=None):
        super().run(tmp, task_vars)
        job_id = None
        if task_vars is not None and 'job' in task_vars or 'id' in task_vars[
                'job']:
            job_id = task_vars['job']['id']

        old_optional_condition = 'msg' in self._task.args
        new_optional_condition = 'fail_msg' in self._task.args and 'success_msg' in self._task.args
        optional_condition = old_optional_condition or new_optional_condition
        required_condition = ('title' in self._task.args
                              and 'result' in self._task.args
                              and optional_condition)

        if not required_condition:
            return {
                "failed":
                True,
                "msg": ("title, result and msg, fail_msg or success"
                        "_msg are mandatory args of adcm_check")
            }

        title = self._task.args['title']
        result = self._task.args['result']
        msg = self._task.args.get('msg', '')
        fail_msg = self._task.args.get('fail_msg', '')
        success_msg = self._task.args.get('success_msg', '')

        group_title = self._task.args.get('group_title', '')
        group_fail_msg = self._task.args.get('group_fail_msg', '')
        group_success_msg = self._task.args.get('group_success_msg', '')

        if result:
            msg = success_msg if success_msg else msg
        else:
            msg = fail_msg if fail_msg else msg

        group = {
            'title': group_title,
            'success_msg': group_success_msg,
            'fail_msg': group_fail_msg
        }

        check = {
            'title': title,
            'result': result,
            'message': msg,
        }

        log.debug('ansible adcm_check: %s, %s',
                  ', '.join([f'{k}: {v}' for k, v in group.items() if v]),
                  ', '.join([f'{k}: {v}' for k, v in check.items() if v]))

        try:
            cm.job.log_check(job_id, group, check)
        except AdcmEx as e:
            return {"failed": True, "msg": e.code + ":" + e.msg}

        return {"failed": False, "changed": False}
Пример #3
0
def encrypt_passwords(apps, schema_editor):
    ConfigLog = apps.get_model('cm', 'ConfigLog')
    PrototypeConfig = apps.get_model('cm', 'PrototypeConfig')
    for model_name in 'Cluster', 'ClusterObject', 'HostProvider', 'Host', 'ADCM':
        log.debug('QQ model %s', model_name)
        Model = apps.get_model('cm', model_name)
        for obj in Model.objects.filter(config__isnull=False):
            log.debug('QQ model %s, obj %s', model_name, obj)
            process_objects(obj, ConfigLog, PrototypeConfig)
Пример #4
0
def lock_obj(obj, event):
    stack = obj.stack

    if not stack:
        stack = [obj.state]
    elif stack[-1] != obj.state:
        stack.append(obj.state)

    log.debug('lock %s, stack: %s', obj_ref(obj), stack)
    obj.stack = stack
    api.set_object_state(obj, config.Job.LOCKED, event)
Пример #5
0
def run_job(task_id, job_id, err_file):
    log.debug("run job #%s of task #%s", job_id, task_id)
    try:
        proc = subprocess.Popen([
            os.path.join(config.CODE_DIR, 'job_runner.py'),
            str(job_id)
        ], stderr=err_file)
        res = proc.wait()
        return res
    except:
        log.error("exception runnung job %s", job_id)
        return 1
Пример #6
0
def run_task(task_id, args=None):
    log.debug("task_runner.py called as: %s", sys.argv)
    try:
        task = TaskLog.objects.get(id=task_id)
    except ObjectDoesNotExist:
        log.error("no task %s", task_id)
        return

    jobs = JobLog.objects.filter(task_id=task.id).order_by('id')
    if not jobs:
        log.error("no jobs for task %s", task.id)
        cm.job.finish_task(task, None, config.Job.FAILED)
        return

    err_file = open(os.path.join(config.LOG_DIR, 'job_runner.err'),
                    'a+',
                    encoding='utf_8')

    log.info("run task #%s", task_id)

    job = None
    count = 0
    res = 0
    for job in jobs:
        if args == 'restart' and job.status == config.Job.SUCCESS:
            log.info('skip job #%s status "%s" of task #%s', job.id,
                     job.status, task_id)
            continue
        cm.job.re_prepare_job(task, job)
        job.start_date = timezone.now()
        job.save()
        res = run_job(task.id, job.id, err_file)
        set_body_ansible(job)
        # For multi jobs task object state and/or config can be changed by adcm plugins
        if task.task_object is not None:
            try:
                task.task_object.refresh_from_db()
            except ObjectDoesNotExist:
                task.object_id = 0
                task.object_type = None
        count += 1
        if res != 0:
            break

    if res == 0:
        cm.job.finish_task(task, job, config.Job.SUCCESS)
    else:
        cm.job.finish_task(task, job, config.Job.FAILED)

    err_file.close()

    log.info("finish task #%s, ret %s", task_id, res)
Пример #7
0
def post_event(event, obj_type, obj_id, det_type=None, det_val=None):
    details = {'type': det_type, 'value': det_val}
    if det_type and not det_val:
        details = det_type
    data = {
        'event': event,
        'object': {
            'type': obj_type,
            'id': int(obj_id),
            'details': details,
        },
    }
    log.debug('post_event %s', data)
    return api_post('/event/', data)
Пример #8
0
def unlock_obj(obj, event):
    if obj.stack:
        stack = obj.stack
    else:
        log.warning('no stack in %s for unlock', obj_ref(obj))
        return
    try:
        state = stack.pop()
    except IndexError:
        log.warning('empty stack in %s for unlock', obj_ref(obj))
        return
    log.debug('unlock %s, stack: %s', obj_ref(obj), stack)
    obj.stack = stack
    api.set_object_state(obj, state, event)
Пример #9
0
def fix_task(apps, schema_editor):
    TaskLog = apps.get_model('cm', 'TaskLog')
    Action = apps.get_model('cm', 'Action')
    for task in TaskLog.objects.all():
        try:
            action = Action.objects.get(id=task.action_id)
        except Action.DoesNotExist:
            continue
        selector = task.selector
        if action.prototype.type == 'service':
            if 'service' not in selector:
                selector['service'] = task.object_id
                log.debug('update task #%s new selector: %s', task.id, selector)
                task.selector = selector
                task.save()
Пример #10
0
def run_ansible(job_id):
    log.debug("job_runner.py called as: %s", sys.argv)
    conf = read_config(job_id)
    playbook = conf['job']['playbook']
    out_file = open_file(config.RUN_DIR, 'ansible-stdout', job_id)
    err_file = open_file(config.RUN_DIR, 'ansible-stderr', job_id)
    post_log(job_id, 'stdout', 'ansible')
    post_log(job_id, 'stderr', 'ansible')
    event = Event()

    os.chdir(conf['env']['stack_dir'])
    cmd = [
        '/adcm/python/job_venv_wrapper.sh',
        get_venv(int(job_id)),
        'ansible-playbook',
        '--vault-password-file',
        f'{config.CODE_DIR}/ansible_secret.py',
        '-e',
        f'@{config.RUN_DIR}/{job_id}/config.json',
        '-i',
        f'{config.RUN_DIR}/{job_id}/inventory.json',
        playbook,
    ]
    if 'params' in conf['job']:
        if 'ansible_tags' in conf['job']['params']:
            cmd.append('--tags=' + conf['job']['params']['ansible_tags'])
    if 'verbose' in conf['job'] and conf['job']['verbose']:
        cmd.append('-vvvv')

    log.info("job run cmd: %s", ' '.join(cmd))
    proc = subprocess.Popen(cmd,
                            env=env_configuration(conf),
                            stdout=out_file,
                            stderr=err_file)
    cm.job.set_job_status(job_id, config.Job.RUNNING, event, proc.pid)
    event.send_state()
    log.info("run ansible job #%s, pid %s, playbook %s", job_id, proc.pid,
             playbook)
    ret = proc.wait()
    finish_check(job_id)
    ret = set_job_status(job_id, ret, proc.pid, event)
    event.send_state()

    out_file.close()
    err_file.close()

    log.info("finish ansible job #%s, pid %s, ret %s", job_id, proc.pid, ret)
    sys.exit(ret)
Пример #11
0
def run_job(task_id, job_id, err_file):
    log.debug("task run job #%s of task #%s", job_id, task_id)
    cmd = [
        '/adcm/python/job_venv_wrapper.sh',
        TaskLog.objects.get(id=task_id).action.venv,
        os.path.join(config.CODE_DIR, 'job_runner.py'),
        str(job_id),
    ]
    log.info("task run job cmd: %s", ' '.join(cmd))
    try:
        proc = subprocess.Popen(cmd, stderr=err_file)
        res = proc.wait()
        return res
    except:
        log.error("exception runnung job %s", job_id)
        return 1
Пример #12
0
def task_get(action, selector):
    log.debug("call task: %s", action)
    try:
        service = Prototype.objects.get(type='service', name='Simple_service')
    except Prototype.DoesNotExist:
        raise AdcmEx('TASK_GET_ERR', 'my error description') from None
    try:
        stop = Action.object.get(context='service',
                                 context_id=service.id,
                                 name='stop')
    except Prototype.DoesNotExist:
        raise AdcmEx(
            'TASK_GENERATOR_ERROR',
            'action stop in service Simple_service not found') from None

    return {'action': stop, 'selector': selector}
Пример #13
0
def fix_job(apps, schema_editor):
    JobLog = apps.get_model('cm', 'JobLog')
    TaskLog = apps.get_model('cm', 'TaskLog')
    Action = apps.get_model('cm', 'Action')
    for job in JobLog.objects.all():
        try:
            action = Action.objects.get(id=job.action_id)
        except Action.DoesNotExist:
            continue
        task = TaskLog.objects.get(id=job.task_id)
        selector = job.selector
        if action.prototype.type == 'service':
            if 'service' not in selector:
                selector['service'] = task.object_id
                log.debug('update job #%s new selector: %s', job.id, selector)
                job.selector = selector
                job.save()
Пример #14
0
def process_adcm():
    sp = StagePrototype.objects.get(type='adcm')
    adcm = ADCM.objects.filter()
    if adcm:
        old_proto = adcm[0].prototype
        new_proto = sp
        if old_proto.version == new_proto.version:
            log.debug('adcm vesrion %s, skip upgrade', old_proto.version)
        elif rpm.compare_versions(old_proto.version, new_proto.version) < 0:
            bundle = copy_stage('adcm', sp)
            upgrade_adcm(adcm[0], bundle)
        else:
            msg = 'Current adcm version {} is more than or equal to upgrade version {}'
            err('UPGRADE_ERROR',
                msg.format(old_proto.version, new_proto.version))
    else:
        bundle = copy_stage('adcm', sp)
        init_adcm(bundle)
Пример #15
0
    def get_job_data(self):
        env = os.environ
        ansible_config = env.get('ANSIBLE_CONFIG')
        if not ansible_config:
            return

        job_id = Path(ansible_config).parent.name
        try:
            self.job = models.JobLog.objects.select_related('task', 'task__lock').get(
                id=int(job_id)
            )
        except (ValueError, models.ObjectDoesNotExist):
            return

        self.task = getattr(self.job, 'task', None)
        self.lock = getattr(self.task, 'lock', None)
        msg = f'API context was initialized with {self.job}, {self.task}, {self.lock}'
        log.debug(msg)
Пример #16
0
    def run(self, terms, variables=None, **kwargs):  # pylint: disable=too-many-branches
        log.debug('run %s %s', terms, kwargs)
        ret = []

        if len(terms) < 3:
            msg = 'not enough arguments to set config ({} of 3)'
            raise AnsibleError(msg.format(len(terms)))

        if terms[0] == 'service':
            if 'cluster' not in variables:
                raise AnsibleError('there is no cluster in hostvars')
            cluster = variables['cluster']
            if 'service_name' in kwargs:
                res = set_service_config_by_name(cluster['id'],
                                                 kwargs['service_name'],
                                                 terms[1], terms[2])
            elif 'job' in variables and 'service_id' in variables['job']:
                res = set_service_config(cluster['id'],
                                         variables['job']['service_id'],
                                         terms[1], terms[2])
            else:
                msg = 'no service_id in job or service_name and service_version in params'
                raise AnsibleError(msg)
        elif terms[0] == 'cluster':
            if 'cluster' not in variables:
                raise AnsibleError('there is no cluster in hostvars')
            cluster = variables['cluster']
            res = set_cluster_config(cluster['id'], terms[1], terms[2])
        elif terms[0] == 'provider':
            if 'provider' not in variables:
                raise AnsibleError('there is no host provider in hostvars')
            provider = variables['provider']
            res = set_provider_config(provider['id'], terms[1], terms[2])
        elif terms[0] == 'host':
            if 'adcm_hostid' not in variables:
                raise AnsibleError('there is no adcm_hostid in hostvars')
            res = set_host_config(variables['adcm_hostid'], terms[1], terms[2])
        else:
            raise AnsibleError(f'unknown object type: {terms[0]}')

        ret.append(res)
        return ret
Пример #17
0
def load_service_map():
    comps = {}
    hosts = {}
    hc_map = {}
    services = {}
    passive = {}
    for c in ServiceComponent.objects.filter(prototype__monitoring='passive'):
        passive[c.id] = True

    for hc in HostComponent.objects.all():
        if hc.component.id in passive:
            continue
        key = '{}.{}'.format(hc.host.id, hc.component.id)
        hc_map[key] = {'cluster': hc.cluster.id, 'service': hc.service.id}
        if str(hc.cluster.id) not in comps:
            comps[str(hc.cluster.id)] = {}
        if str(hc.service.id) not in comps[str(hc.cluster.id)]:
            comps[str(hc.cluster.id)][str(hc.service.id)] = []
        comps[str(hc.cluster.id)][str(hc.service.id)].append(key)

    for host in Host.objects.filter(prototype__monitoring='active'):
        if host.cluster:
            cluster_id = host.cluster.id
        else:
            cluster_id = 0
        if cluster_id not in hosts:
            hosts[cluster_id] = []
        hosts[cluster_id].append(host.id)

    for co in ClusterObject.objects.filter(prototype__monitoring='active'):
        if co.cluster.id not in services:
            services[co.cluster.id] = []
        services[co.cluster.id].append(co.id)

    m = {
        'hostservice': hc_map,
        'component': comps,
        'service': services,
        'host': hosts,
    }
    log.debug("service map: %s", m)
    return api_post('/servicemap/', m)
Пример #18
0
    def run(self, terms, variables=None, **kwargs):  # pylint: disable=too-many-branches
        log.debug('run %s %s', terms, kwargs)
        ret = []
        event = Event()
        if len(terms) < 2:
            msg = 'not enough arguments to set state ({} of 2)'
            raise AnsibleError(msg.format(len(terms)))

        if terms[0] == 'service':
            if 'cluster' not in variables:
                raise AnsibleError('there is no cluster in hostvars')
            cluster = variables['cluster']
            if 'service_name' in kwargs:
                res = cm.api.set_service_state(cluster['id'],
                                               kwargs['service_name'],
                                               terms[1])
            elif 'job' in variables and 'service_id' in variables['job']:
                res = cm.api.set_service_state_by_id(
                    cluster['id'], variables['job']['service_id'], terms[1])
            else:
                msg = 'no service_id in job or service_name in params'
                raise AnsibleError(msg)
        elif terms[0] == 'cluster':
            if 'cluster' not in variables:
                raise AnsibleError('there is no cluster in hostvars')
            cluster = variables['cluster']
            res = cm.api.set_cluster_state(cluster['id'], terms[1])
        elif terms[0] == 'provider':
            if 'provider' not in variables:
                raise AnsibleError('there is no provider in hostvars')
            provider = variables['provider']
            res = cm.api.set_provider_state(provider['id'], terms[1], event)
        elif terms[0] == 'host':
            if 'adcm_hostid' not in variables:
                raise AnsibleError('there is no adcm_hostid in hostvars')
            res = cm.api.set_host_state(variables['adcm_hostid'], terms[1])
        else:
            raise AnsibleError('unknown object type: %s' % terms[0])
        event.send_state()
        ret.append(res)
        return ret
Пример #19
0
    def run(self, tmp=None, task_vars=None):
        super().run(tmp, task_vars)
        if task_vars is not None and 'job' in task_vars or 'id' in task_vars['job']:
            job_id = task_vars['job']['id']

        name = self._task.args.get('name')
        log_format = self._task.args.get('format')
        path = self._task.args.get('path')
        content = self._task.args.get('content')
        if not name and log_format and (path or content):
            return {
                "failed": True,
                "msg": "name, format and path or content are mandatory args of adcm_custom_log",
            }

        try:
            if path is None:
                log.debug(
                    'ansible adcm_custom_log: %s, %s, %s, %s', job_id, name, log_format, content
                )
                log_custom(job_id, name, log_format, content)
            else:
                log.debug('ansible adcm_custom_log: %s, %s, %s, %s', job_id, name, log_format, path)
                slurp_return = self._execute_module(
                    module_name='slurp', module_args={'src': path}, task_vars=task_vars, tmp=tmp
                )
                try:
                    body = base64.standard_b64decode(slurp_return['content']).decode()
                except Error as error:
                    raise AdcmEx('UNKNOWN_ERROR', msg='Error b64decode for slurp module') from error
                except UnicodeDecodeError as error:
                    raise AdcmEx(
                        'UNKNOWN_ERROR', msg='Error UnicodeDecodeError for slurp module'
                    ) from error
                log_custom(job_id, name, log_format, body)

        except AdcmEx as e:
            return {"failed": True, "msg": f"{e.code}: {e.msg}"}

        return {"failed": False, "changed": False}
Пример #20
0
def task_generator(action, selector):
    log.debug("call task_generator: %s", action)
    try:
        service = Prototype.objects.get(type='service',
                                        name='Simple_service',
                                        version='new_version')
    except Prototype.DoesNotExist:
        raise AdcmEx('TASK_GENERATOR_ERROR',
                     'service Simple_service not found') from None

    try:
        stop = Action.objects.get(context='service',
                                  context_id=service.id,
                                  name='stop')
    except Prototype.DoesNotExist:
        raise AdcmEx('TASK_GENERATOR_ERROR',
                     'action stop of service ZOOKEEPER not found') from None

    try:
        start = Action.objects.get(context='service',
                                   context_id=service.id,
                                   name='start')
    except Prototype.DoesNotExist:
        raise AdcmEx('TASK_GENERATOR_ERROR',
                     'action start of service ZOOKEEPER not found') from None

    return (
        {
            'action': stop,
            'selector': selector
        },
        {
            'action': start,
            'selector': selector
        },
    )
Пример #21
0
def cook_delta(  # pylint: disable=too-many-branches
    cluster: Cluster,
    new_hc: List[Tuple[ClusterObject, Host, ServiceComponent]],
    action_hc: List[dict],
    old: dict = None,
) -> dict:
    def add_delta(delta, action, key, fqdn, host):
        service, comp = key.split('.')
        if not check_action_hc(action_hc, service, comp, action):
            msg = (f'no permission to "{action}" component "{comp}" of '
                   f'service "{service}" to/from hostcomponentmap')
            err('WRONG_ACTION_HC', msg)
        add_to_dict(delta[action], key, fqdn, host)

    new = {}
    for service, host, comp in new_hc:
        key = cook_comp_key(service.prototype.name, comp.prototype.name)
        add_to_dict(new, key, host.fqdn, host)

    if not old:
        old = {}
        for hc in HostComponent.objects.filter(cluster=cluster):
            key = cook_comp_key(hc.service.prototype.name,
                                hc.component.prototype.name)
            add_to_dict(old, key, hc.host.fqdn, hc.host)

    delta = {'add': {}, 'remove': {}}
    for key, value in new.items():
        if key in old:
            for host in value:
                if host not in old[key]:
                    add_delta(delta, 'add', key, host, value[host])
            for host in old[key]:
                if host not in value:
                    add_delta(delta, 'remove', key, host, old[key][host])
        else:
            for host in value:
                add_delta(delta, 'add', key, host, value[host])

    for key, value in old.items():
        if key not in new:
            for host in value:
                add_delta(delta, 'remove', key, host, value[host])

    log.debug('OLD: %s', old)
    log.debug('NEW: %s', new)
    log.debug('DELTA: %s', delta)
    return delta
Пример #22
0
def cook_delta(cluster, new_hc, action_hc, old=None):
    def add_delta(delta, action, key, fqdn, host):
        service, comp = key.split('.')
        if not check_action_hc(action_hc, service, comp, action):
            msg = (f'no permission to "{action}" component "{comp}" of '
                   f'service "{service}" to/from hostcomponentmap')
            err('WRONG_ACTION_HC', msg)
        add_to_dict(delta[action], key, fqdn, host)

    new = {}
    for service, host, comp in new_hc:
        key = cook_comp_key(service.prototype.name, comp.prototype.name)
        add_to_dict(new, key, host.fqdn, host)

    if not old:
        old = {}
        for hc in HostComponent.objects.filter(cluster=cluster):
            key = cook_comp_key(hc.service.prototype.name, hc.component.prototype.name)
            add_to_dict(old, key, hc.host.fqdn, hc.host)

    delta = {'add': {}, 'remove': {}}
    for key in new:
        if key in old:
            for host in new[key]:
                if host not in old[key]:
                    add_delta(delta, 'add', key, host, new[key][host])
            for host in old[key]:
                if host not in new[key]:
                    add_delta(delta, 'remove', key, host, old[key][host])
        else:
            for host in new[key]:
                add_delta(delta, 'add', key, host, new[key][host])

    for key in old:
        if key not in new:
            for host in old[key]:
                add_delta(delta, 'remove', key, host, old[key][host])

    log.debug('OLD: %s', old)
    log.debug('NEW: %s', new)
    log.debug('DELTA: %s', delta)
    return delta
Пример #23
0
def task_generator(action):
    log.debug("call task_generator: %s", action)

    return {'action'}