Beispiel #1
0
 def get(self):
     query = filter_query(Server, request.args)
     return [s.to_json(add_gates=check_param_in_uri('gates'),
                       human=check_param_in_uri('human'),
                       no_delete=True,
                       add_ignore=True) for s in
             query.all()]
Beispiel #2
0
 def get(self):
     query = filter_query(OrchExecution, request.args)
     return [
         oe.to_json(human=check_param_in_uri('human'),
                    add_step_exec=check_param_in_uri('steps'),
                    split_lines=True)
         for oe in query.order_by(OrchExecution.start_time).all()
     ]
Beispiel #3
0
 def get(self):
     if check_param_in_uri('scopes'):
         return [r[0] for r in
                 db.session.query(distinct(Vault.scope)).filter_by(user_id=get_jwt_identity()).filter_by(
                     deleted=0).all()]
     elif check_param_in_uri('vars'):
         query = db.session.query(distinct(Vault.name)).filter_by(user_id=get_jwt_identity()).filter_by(deleted=0)
         if 'scope' in request.args:
             query = query.filter_by(scope=request.args.get('scope'))
         return [r[0] for r in query.order_by(Vault.name)]
     else:
         query = filter_query(Vault, request.args, exclude=["user_id", "value"]).filter_by(
             user_id=get_jwt_identity())
         return [vault.to_json(no_delete=True, human=check_param_in_uri('human')) for vault in query.all()]
Beispiel #4
0
 def get(self, file_id):
     query = filter_query(FileServerAssociation,
                          request.args).filter_by(file_id=file_id)
     return [
         fsa.to_json(human=check_param_in_uri('human'), no_delete=True)
         for fsa in query.all()
     ]
Beispiel #5
0
 def get(self, execution_id):
     query = filter_query(StepExecution, request.args)
     return [
         oe.to_json(human=check_param_in_uri('human'))
         for oe in query.filter_by(orch_execution_id=execution_id).order_by(
             StepExecution.start_time).all()
     ]
Beispiel #6
0
def healthcheck():
    if request.method == 'POST' and isinstance(g.source, Server):
        data = request.get_json()
        try:
            heartbeat = dt.datetime.strptime(data['heartbeat'],
                                             defaults.DATETIME_FORMAT)
        except:
            raise errors.InvalidDateFormat(data['heartbeat'],
                                           defaults.DATETIME_FORMAT)
        current_app.dm.cluster_manager.put(data['me'], heartbeat)

    catalog_ver = Catalog.max_catalog()
    data = {
        "version":
        dimensigon.__version__,
        "catalog_version":
        catalog_ver.strftime(defaults.DATEMARK_FORMAT)
        if catalog_ver else None,
        "services": [],
    }
    if not check_param_in_uri('human'):
        server = {'id': str(g.server.id), 'name': g.server.name}
        neighbours = [{
            'id': str(s.id),
            'name': s.name
        } for s in Server.get_neighbours()]
        cluster = {
            'alive': current_app.dm.cluster_manager.get_alive(),
            'in_coma': current_app.dm.cluster_manager.get_zombies()
        }
    else:
        server = g.server.name
        neighbours = sorted([s.name for s in Server.get_neighbours()])
        cluster = {
            'alive':
            sorted([
                getattr(Server.query.get(i), 'name', i)
                for i in current_app.dm.cluster_manager.get_alive()
            ]),
            'in_coma':
            sorted([
                getattr(Server.query.get(i), 'name', i)
                for i in current_app.dm.cluster_manager.get_zombies()
            ])
        }
    data.update(server=server,
                neighbours=neighbours,
                cluster=cluster,
                now=get_now().strftime(defaults.DATETIME_FORMAT))

    return data
Beispiel #7
0
 def get(self):
     query = filter_query(Orchestration,
                          request.args).order_by(Orchestration.created_at)
     return [
         o.to_json(add_target=check_param_in_uri('target'),
                   add_params=check_param_in_uri('vars'),
                   add_steps=check_param_in_uri('steps'),
                   add_action=check_param_in_uri('action'),
                   split_lines=check_param_in_uri('split_lines'),
                   add_schema=check_param_in_uri('schema'))
         for o in query.all()
     ]
Beispiel #8
0
def routes():
    if request.method == 'GET':
        route_table = []
        for route in Route.query.join(Server.route).order_by(
                Server.name).filter(Server.deleted == False).all():
            route_table.append(
                route.to_json(human=check_param_in_uri('human')))
        data = {'route_list': route_table}
        data.update(server=dict(name=g.server.name, id=str(g.server.id)))
        return data

    elif request.method == 'POST':
        data = request.get_json()
        current_app.dm.route_manager.refresh_table(
            discover_new_neighbours=data.get('discover_new_neighbours', False),
            check_current_neighbours=data.get('check_current_neighbours',
                                              False),
            max_num_discovery=data.get('max_num_discovery', 5))
        return {}, 204

    elif request.method == 'PATCH':
        current_app.dm.route_manager.new_routes(request.get_json())
        return {}, 204
Beispiel #9
0
 def get(self, server_id):
     return Server.query.get_or_raise(server_id).to_json(add_gates=check_param_in_uri('gates'),
                                                         human=check_param_in_uri('human'),
                                                         no_delete=True,
                                                         add_ignore=True)
Beispiel #10
0
 def get(self):
     query = filter_query(Log, request.args)
     return [log.to_json(human=check_param_in_uri('human'), delete_data=False) for log in query.all()]
Beispiel #11
0
 def get(self, execution_id):
     return OrchExecution.query.get_or_raise(execution_id).to_json(
         add_step_exec=check_param_in_uri('steps'),
         human=check_param_in_uri('human'),
         split_lines=True)
Beispiel #12
0
 def get(self, orchestration_id):
     return Orchestration.query.get_or_raise(orchestration_id).to_json(
         check_param_in_uri('target'),
         add_schema=check_param_in_uri('schema'),
         split_lines=check_param_in_uri('split_lines'))
Beispiel #13
0
 def get(self):
     query = filter_query(Software, request.args)
     return [
         soft.to_json(servers=check_param_in_uri('servers'),
                      no_delete=False) for soft in query.all()
     ]
Beispiel #14
0
 def get(self, execution_id):
     return StepExecution.query.get_or_raise(execution_id).to_json(
         human=check_param_in_uri('human'), split_lines=True)
Beispiel #15
0
 def get(self, file_id):
     return File.query.get_or_raise(file_id).to_json(human=check_param_in_uri('human'), delete_data=False,
                                                     destinations=True)
Beispiel #16
0
def launch_command():
    data = request.get_json()

    server_list = []
    if 'target' in data:
        not_found = []
        servers = Server.query.all()
        if data['target'] == 'all':
            server_list = servers
        elif is_iterable_not_string(data['target']):
            for vv in data['target']:
                sl = search(vv, servers)
                if len(sl) == 0:
                    not_found.append(vv)
                else:
                    server_list.extend(sl)
        else:
            sl = search(data['target'], servers)
            if len(sl) == 0:
                not_found.append(data['target'])
            else:
                server_list.extend(sl)
        if not_found:
            return {
                'error':
                "Following granules or ids did not match to any server: " +
                ', '.join(not_found)
            }, 404
    else:
        server_list.append(g.server)

    if re.search(r'rm\s+((-\w+|--[-=\w]*)\s+)*(-\w*[rR]\w*|--recursive)',
                 data['command']):
        return {'error': 'rm with recursion is not allowed'}, 403
    data.pop('target', None)
    start = None

    username = getattr(User.query.get(get_jwt_identity()), 'name', None)
    if not username:
        raise errors.EntityNotFound('User', get_jwt_identity())
    cmd = wrap_sudo(username, data['command'])
    if g.server in server_list:
        start = time.time()
        server_list.pop(server_list.index(g.server))
        proc = subprocess.Popen(
            cmd,
            stdin=subprocess.PIPE if data.get('input', None) else None,
            stderr=subprocess.PIPE,
            stdout=subprocess.PIPE,
            shell=True,
            close_fds=True,
            encoding='utf-8')

    resp_data = {}
    if check_param_in_uri("human"):
        attr = 'name'
    else:
        attr = 'id'
    if server_list:
        resp: t.List[ntwrk.Response] = asyncio.run(
            ntwrk.parallel_requests(server_list,
                                    method='POST',
                                    view_or_url='api_1_0.launch_command',
                                    json=data))
        for s, r in zip(server_list, resp):
            key = getattr(s, attr, s.id)
            if r.ok:
                resp_data[key] = r.msg[s.id]
            else:
                if not r.exception:
                    resp_data[key] = {
                        'error': {
                            'status_code': r.code,
                            'response': r.msg
                        }
                    }
                else:
                    if isinstance(r.exception, errors.BaseError):
                        resp_data[key] = errors.format_error_content(
                            r.exception, current_app.config['DEBUG'])
                    else:
                        resp_data[key] = {
                            'error':
                            format_exception(r.exception) if
                            current_app.config['DEBUG'] else str(r.exception)
                            or str(r.exception.__class__.__name__)
                        }

    if start:
        key = getattr(g.server, attr, g.server.id)
        timeout = data.get('timeout', defaults.TIMEOUT_COMMAND)
        try:
            outs, errs = proc.communicate(input=(data.get('input', '') or ''),
                                          timeout=timeout)
        except (TimeoutError, subprocess.TimeoutExpired):
            proc.kill()
            try:
                outs, errs = proc.communicate(timeout=1)
            except:
                resp_data[key] = {
                    'error':
                    f"Command '{cmd}' timed out after {timeout} seconds. Unable to communicate with the process launched."
                }
            else:
                resp_data[key] = {
                    'error':
                    f"Command '{cmd}' timed out after {timeout} seconds",
                    'stdout': outs.split('\n'),
                    'stderr': errs.split('\n')
                }
        except Exception as e:
            current_app.logger.exception(
                "Exception raised while trying to run command")
            resp_data[key] = {
                'error':
                traceback.format_exc() if current_app.config['DEBUG'] else
                str(r.exception) or str(r.exception.__class__.__name__)
            }
        else:
            resp_data[key] = {
                'stdout': outs.split('\n'),
                'stderr': errs.split('\n'),
                'returncode': proc.returncode
            }
    resp_data['cmd'] = cmd
    resp_data['input'] = data.get('input', None)
    return resp_data, 200
Beispiel #17
0
 def get(self, step_id):
     return Step.query.get_or_raise(step_id).to_json(split_lines=check_param_in_uri('split_lines'))
Beispiel #18
0
 def get(self):
     query = filter_query(Step, request.args)
     return [s.to_json(split_lines=check_param_in_uri('split_lines')) for s in query.all()]
Beispiel #19
0
 def get(self, action_template_id):
     return ActionTemplate.query.get_or_raise(action_template_id).to_json(
         split_lines=check_param_in_uri('split_lines'))
Beispiel #20
0
 def get(self):
     query = filter_query(ActionTemplate, request.args)
     return [
         at.to_json(split_lines=check_param_in_uri('split_lines'))
         for at in query.all()
     ]
Beispiel #21
0
def launch_orchestration(orchestration_id):
    data = request.get_json()
    if orchestration_id:
        orchestration = Orchestration.query.get_or_raise(orchestration_id)
    else:
        iden = (data.get('orchestration'), )
        columns = ('orchestration', )
        query = Orchestration.query.filter_by(name=data.get('orchestration'))
        if 'version' in data:
            iden += (data.get('version'), )
            columns += ('version', )
            query = query.filter_by(version=data.get('version'))
        query = query.order_by(Orchestration.version.desc())
        if query.count() <= 1:
            orchestration = query.one_or_none()
        else:
            orchestration = query.first()
        if not orchestration:
            raise errors.EntityNotFound('Orchestration', iden, columns)

    if not orchestration.steps:
        return errors.GenericError(
            'orchestration does not have steps to execute',
            orchestration_id=orchestration_id)

    params = data.get('params') or {}
    hosts = data.get('hosts', Server.get_current().id)

    a = set(orchestration.target)
    if not isinstance(hosts, dict):
        hosts = dict(all=hosts)
    b = set(hosts.keys())
    c = a - b
    if len(c) > 0:
        raise errors.TargetUnspecified(c)
    c = b - a
    if len(c) > 0:
        raise errors.TargetNotNeeded(c)

    not_found = normalize_hosts(hosts)
    if not_found:
        raise errors.ServerNormalizationError(not_found)

    for target, target_hosts in hosts.items():
        if len(target_hosts) == 0:
            raise errors.EmptyTarget(target)
    # check param entries
    # rest = orchestration.user_parameters - set(params.keys())
    # if rest:
    #     rest = list(rest)
    #     rest.sort()
    #     return {'error': f"Parameter(s) not specified: {', '.join(rest)}"}, 404

    execution_id = str(uuid.uuid4())

    executor_id = get_jwt_identity()
    vc = Context(params,
                 dict(execution_id=None,
                      root_orch_execution_id=execution_id,
                      orch_execution_id=execution_id,
                      executor_id=executor_id),
                 vault=Vault.get_variables_from(executor_id,
                                                scope=data.get(
                                                    'scope', 'global')))

    if not data.get('skip_validation', False):
        validate_input_chain(
            orchestration, {
                'input': set(params.keys()),
                'env': set(vc.env.keys()),
                'vault': set(vc.vault.keys())
            })

    if request.get_json().get('background', True):
        future = executor.submit(deploy_orchestration,
                                 orchestration=orchestration.id,
                                 var_context=vc,
                                 hosts=hosts,
                                 timeout=data.get('timeout', None))
        try:
            future.result(5)
        except concurrent.futures.TimeoutError:
            return {'execution_id': execution_id}, 202
        except Exception as e:
            current_app.logger.exception(
                f"Exception got when executing orchestration {orchestration}")
            raise
    else:
        try:
            deploy_orchestration(orchestration=orchestration,
                                 var_context=vc,
                                 hosts=hosts,
                                 timeout=data.get('timeout', None))
        except Exception as e:
            current_app.logger.exception(
                f"Exception got when executing orchestration {orchestration}")
            raise
    return OrchExecution.query.get(execution_id).to_json(
        add_step_exec=True,
        human=check_param_in_uri('human'),
        split_lines=True), 200
Beispiel #22
0
 def get(self, name, scope='global'):
     return Vault.query.get_or_raise((get_jwt_identity(), scope, name)).to_json(human=check_param_in_uri('human'),
                                                                                no_delete=True)
Beispiel #23
0
 def get(self):
     query = filter_query(StepExecution, request.args)
     return [
         e.to_json(human=check_param_in_uri('human'), split_lines=True)
         for e in query.order_by(StepExecution.start_time).all()
     ]
Beispiel #24
0
 def get(self):
     query = filter_query(File, request.args)
     return [file.to_json(human=check_param_in_uri('human'), no_delete=True,
                          destinations=check_param_in_uri('destinations')) for file in
             query.all()]