Ejemplo n.º 1
0
    def execute(self,
                params: Kwargs,
                timeout=None,
                context: Context = None) -> CompletedProcess:
        """
        StepExecution wrapper
        Parameters
        ----------
        properties:
            properties passed to execute implementation
        env:
            environment variables

        Returns
        -------
        StepExecution:
            dataclass containing all the information from the result execution
        """
        start = get_now()
        try:
            return self._execute(params, timeout=timeout, context=context)
        except Exception as e:
            return CompletedProcess(
                success=False,
                stderr=f"Error creating execution: {format_exception(e)}",
                start_time=start,
                end_time=get_now())
Ejemplo n.º 2
0
    def _main_loop(self):
        with self.dm.flask_app.app_context():
            last_shutdown = Parameter.get('last_graceful_shutdown')

            try:
                last_shutdown = dt.datetime.strptime(last_shutdown,
                                                     defaults.DATETIME_FORMAT)
            except:
                last_shutdown = get_now()
            else:
                last_shutdown = last_shutdown

            if self.dm.config.force_scan or last_shutdown < (
                    get_now() - dt.timedelta(seconds=self.refresh_interval)):
                scan = True
            else:
                scan = False
            changed_routes = self._loop.run_until_complete(
                self._async_refresh_route_table(discover_new_neighbours=scan,
                                                check_current_neighbours=scan,
                                                max_num_discovery=None))
            self.session.commit()
            self.publish_q.safe_put(InitialRouteSet())

            super()._main_loop()

            Parameter.set('last_graceful_shutdown',
                          get_now().strftime(defaults.DATETIME_FORMAT))
Ejemplo n.º 3
0
def _deploy_orchestration(orchestration: Orchestration,
                          var_context: 'Context',
                          hosts: t.Dict[str, t.List[Id]],
                          execution: OrchExecution,
                          lock_retries,
                          lock_delay,
                          timeout
                          ) -> Id:
    """
    Parameters
    ----------
    orchestration
        orchestration to deploy
    params
        parameters to pass to the steps

    Returns
    -------
    t.Tuple[bool, bool, t.Dict[int, dpl.CompletedProcess]]:
        tuple with 3 values. (boolean indicating if invoke process ended up successfully,
        boolean indicating if undo process ended up successfully,
        dict with all the executions). If undo process not executed, boolean set to None
    """
    rse = RegisterStepExecution(execution)
    kwargs = dict()
    kwargs['start_time'] = execution.start_time or get_now()
    cc = create_cmd_from_orchestration(orchestration, var_context, hosts=hosts, register=rse, executor=executor)

    # convert UUID into str as in_ filter does not handle UUID type
    all = [str(s) for s in hosts['all']]
    servers = Server.query.filter(Server.id.in_(all)).all()
    scope_enabled = locker_scope_enabled(Scope.ORCHESTRATION)
    if scope_enabled:
        try:
            applicant = lock.lock(Scope.ORCHESTRATION, servers, applicant=var_context.env.get('root_orch_execution_id'),
                                  retries=lock_retries, delay=lock_delay)
        except errors.LockError as e:
            kwargs.update(success=False, message=str(e))
            rse.update_orch_execution(**kwargs)
            raise
    try:
        kwargs['success'] = cc.invoke(timeout=timeout)
        if not kwargs['success'] and orchestration.undo_on_error:
            kwargs['undo_success'] = cc.undo()
        kwargs['end_time'] = get_now()
        rse.update_orch_execution(**kwargs)
    except Exception as e:
        current_app.logger.exception("Exception while executing invocation command")
        kwargs.update(success=False, message=str(e))
        rse.update_orch_execution(**kwargs)
        try:
            db.session.rollback()
        except:
            pass

    finally:
        if scope_enabled:
            lock.unlock(Scope.ORCHESTRATION, applicant=applicant, servers=servers)

    return execution.id
Ejemplo n.º 4
0
    def post(self, transfer_id):
        """Generates the chunk into disk"""
        data = request.get_json()
        trans: Transfer = Transfer.query.get_or_raise(transfer_id)
        if trans.status == TransferStatus.WAITING_CHUNKS:
            trans.started_on = get_now()
            trans.status = TransferStatus.IN_PROGRESS
            db.session.commit()
        elif trans.status != TransferStatus.IN_PROGRESS:
            raise errors.TransferNotInValidState(transfer_id,
                                                 trans.status.name)

        chunk = data.get('content')
        chunk_id = data.get('chunk')
        if trans.num_chunks == 1:
            file = os.path.join(trans.dest_path, f'{trans.filename}')
        else:
            file = os.path.join(trans.dest_path,
                                f'{trans.filename}_chunk.{chunk_id}')
        with open(file, 'wb') as fd:
            raw = base64.b64decode(chunk.encode('ascii'))
            fd.write(raw)
        if trans.num_chunks == 1:
            msg = f"File {trans.filename} from transfer {transfer_id} generated successfully"
            trans.status = TransferStatus.COMPLETED
            trans.ended_on = get_now()
            db.session.commit()
        else:
            msg = f"Chunk {chunk_id} from transfer {transfer_id} generated successfully"

        current_app.logger.debug(msg)
        return {'message': msg}, 201
    def test_composite_command_error2(self):
        mocked_imp_succ = mock.Mock()
        mocked_imp_error = mock.Mock()

        start_time = get_now()
        end_time = get_now() + datetime.timedelta(5 / (24 * 60 * 60))

        mocked_imp_succ.execute.return_value = StepExecution(
            success=True,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=start_time,
            end_time=end_time)
        mocked_imp_error.execute.return_value = StepExecution(
            success=False,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=start_time,
            end_time=end_time)

        uc1 = UndoCommand(implementation=mocked_imp_succ, id_=1)
        uc2 = UndoCommand(implementation=mocked_imp_succ, id_=2)
        uc3 = UndoCommand(implementation=mocked_imp_succ, id_=3)
        uc4 = UndoCommand(implementation=mocked_imp_succ, id_=4)
        uc5 = UndoCommand(implementation=mocked_imp_succ, id_=5)

        ccu1 = CompositeCommand({uc1: []}, async_operator=self.ao)
        ccu2 = CompositeCommand({
            uc2: [uc3],
            uc3: [uc4]
        },
                                async_operator=self.ao)

        c1 = Command(implementation=mocked_imp_succ,
                     undo_implementation=ccu1,
                     id_=6)
        c2 = Command(implementation=mocked_imp_error,
                     undo_implementation=ccu2,
                     id_=7)
        c3 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc5,
                     id_=8)

        cc = CompositeCommand({c1: [c2], c2: [c3]}, async_operator=self.ao)

        res = cc.invoke()

        self.assertEqual(False, res)
        self.assertEqual(1, mocked_imp_succ.execute.call_count)
        self.assertEqual(1, mocked_imp_error.execute.call_count)

        res = cc.undo()

        self.assertEqual(True, res)
        self.assertEqual(2, mocked_imp_succ.execute.call_count)
        self.assertEqual(1, mocked_imp_error.execute.call_count)
Ejemplo n.º 6
0
def ping():
    req_data = request.get_json()
    if req_data:
        req_data.update(dest_time=get_now().strftime(defaults.DATETIME_FORMAT))
        if 'servers' not in req_data:
            req_data.update(servers={})
    else:
        req_data = dict(dest_time=get_now().strftime(defaults.DATETIME_FORMAT))
    return req_data, 200
Ejemplo n.º 7
0
 def _execute(self,
              params: Kwargs,
              timeout=None,
              context: Context = None) -> CompletedProcess:
     tokens = self.rpl_params(**params, env=context.env)
     return CompletedProcess(success=True,
                             stdout=tokens,
                             rc=0,
                             start_time=get_now(),
                             end_time=get_now())
    def test_undo_on_error(self):
        mocked_imp_succ = mock.Mock()
        mocked_imp_error = mock.Mock()

        mocked_imp_succ.execute.return_value = StepExecution(
            success=True,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=get_now(),
            end_time=get_now() + datetime.timedelta(5 / (24 * 60 * 60)))

        mocked_imp_error.execute.return_value = StepExecution(
            success=False,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=get_now(),
            end_time=get_now() + datetime.timedelta(5 / (24 * 60 * 60)))

        uc1 = UndoCommand(implementation=mocked_imp_succ, id_=1)
        uc2 = UndoCommand(implementation=mocked_imp_error, id_=2)
        uc3 = UndoCommand(implementation=mocked_imp_succ, id_=3)

        c1 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc1,
                     id_=1)
        c2 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc2,
                     id_=2)
        c3 = Command(implementation=mocked_imp_error,
                     undo_implementation=uc3,
                     undo_on_error=True,
                     id_=3)

        cc1 = CompositeCommand({
            c1: [c2],
            c2: [c3]
        },
                               force_all=True,
                               id_=1,
                               async_operator=self.ao)

        res = cc1.invoke()

        self.assertFalse(res)

        res = cc1.undo()

        self.assertEqual(3, mocked_imp_succ.execute.call_count)
        self.assertEqual(2, mocked_imp_error.execute.call_count)
        self.assertFalse(res)
Ejemplo n.º 9
0
 def _notify_cluster_out(self):
     with self.dm.flask_app.app_context():
         servers = Server.get_neighbours()
         if servers:
             self.logger.debug(
                 f"Sending shutdown to {', '.join([s.name for s in servers])}"
             )
         else:
             self.logger.debug("No server to send shutdown information")
         if servers:
             responses = asyncio.run(
                 ntwrk.parallel_requests(
                     servers,
                     'post',
                     view_or_url='api_1_0.cluster_out',
                     view_data=dict(server_id=str(Server.get_current().id)),
                     json={
                         'death':
                         get_now().strftime(defaults.DATEMARK_FORMAT)
                     },
                     timeout=2,
                     auth=get_root_auth()))
             if self.logger.level <= logging.DEBUG:
                 for r in responses:
                     if not r.ok:
                         self.logger.warning(
                             f"Unable to send data to {r.server}: {r}")
Ejemplo n.º 10
0
def _proxy_request(request: 'flask.Request', destination: Server, verify=False) -> requests.Response:
    url = destination.url() + request.full_path
    req_data = request.get_json()

    if request.path == '/ping':
        server_data = {'id': str(g.server.id), 'name': g.server.name,
                       'time': get_now().strftime(defaults.DATETIME_FORMAT)}
        if req_data:
            if 'servers' not in req_data:
                req_data['servers'] = {}
            req_data['servers'].update({len(req_data['servers']) + 1: server_data})
        else:
            req_data = dict(servers={1: server_data})
    kwargs = {
        'json': req_data,
        'allow_redirects': False
    }

    headers = {key.lower(): value for key, value in request.headers.items()}

    # Let requests reset the host for us.
    if 'host' in headers:
        del headers['host']

    headers['d-source'] = headers.get('d-source', '') + ':' + str(g.server.id)

    kwargs['headers'] = headers

    cookies = request.cookies

    kwargs['cookies'] = cookies

    return requests.request(request.method, url, verify=verify, **kwargs)
Ejemplo n.º 11
0
    def test_set_and_get(self):
        p = Parameter(
            'data',
            dump=lambda x: x.strftime(defaults.DATETIME_FORMAT),
            load=lambda x: dt.datetime.strptime(x, defaults.DATETIME_FORMAT))
        db.session.add(p)
        now = get_now()
        Parameter.set('data', now)

        p = Parameter.query.get('data')
        self.assertEqual(now.strftime(defaults.DATETIME_FORMAT), p.value)

        p = Parameter('integer', load=int, dump=str)
        db.session.add(p)
        Parameter.set('integer', 5)
        p = Parameter.query.get('integer')
        self.assertEqual('5', p.value)

        p = Parameter('name')
        db.session.add(p)
        Parameter.set('name', 'Joan')
        p = Parameter.query.get('name')
        self.assertEqual('Joan', p.value)

        # test get
        self.assertEqual(now, Parameter.get('data'))
        self.assertEqual(5, Parameter.get('integer'))
        self.assertEqual('Joan', Parameter.get('name'))

        p = Parameter('none')
        db.session.add(p)

        self.assertIsNone(Parameter.get('none'))
        self.assertEqual('default', Parameter.get('none', 'default'))
Ejemplo n.º 12
0
 def set_alive(self,
               iden: Id,
               session: Id,
               alive=None) -> t.Optional[t.Dict]:
     with self._lock:
         alive = alive or get_now()
         if iden in self._cluster:
             if self._cluster[iden].session == session:
                 if self._cluster[iden].death is not None:
                     if alive < self._cluster[iden].birth:
                         self._cluster[iden].birth = alive
                     self._cluster[iden].keepalive = alive
                     self._cluster[iden].death = None
                 else:
                     return None
             else:
                 self._cluster[iden].session = session
                 self._cluster[iden].birth = alive
                 self._cluster[iden].keepalive = alive
                 self._cluster[iden].death = None
         else:
             self._cluster[iden] = self._register_class(iden,
                                                        session=session,
                                                        birth=alive,
                                                        keepalive=alive)
         return self._cluster[iden].to_dict()
Ejemplo n.º 13
0
 def get_delta_keepalive(self, delta: dt.timedelta):
     with self._lock:
         now = get_now()
         return [
             cr.id for cr in self._cluster.values()
             if cr.birth is not None and cr.death is None and
             (now - (cr.keepalive or cr.birth)) < delta
         ]
Ejemplo n.º 14
0
def run_command_and_callback(operation: 'IOperationEncapsulation',
                             params,
                             context: Context,
                             source: Server,
                             step_execution: StepExecution,
                             event_id,
                             identity,
                             timeout=None):
    execution: StepExecution = db.session.merge(step_execution)
    exec_id = execution.id
    source = db.session.merge(source)
    start = get_now()
    try:
        cp = operation.execute(params, timeout=timeout, context=context)
    except Exception as e:
        cp = CompletedProcess(
            success=False,
            stderr=f"Error while executing operation. {format_exception(e)}",
            start_time=start,
            end_time=get_now())
    finally:
        execution.load_completed_result(cp)

    data = dict(step_execution=execution.to_json())
    if execution.child_orch_execution:
        data['step_execution'].update(
            orch_execution=execution.child_orch_execution.to_json(
                add_step_exec=True))

    # commit after data is dumped
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.exception(
            f"Error on commit for execution {exec_id}")

    resp, code = ntwrk.post(server=source,
                            view_or_url='api_1_0.events',
                            view_data={'event_id': event_id},
                            json=data,
                            identity=identity)
    if code != 202:
        current_app.logger.error(
            f"Error while sending result for execution {exec_id}: {code}, {resp}"
        )
    return data
Ejemplo n.º 15
0
def delete_old_temp_servers():
    global servers_to_be_created
    now = get_now()
    for s_id, data in list(servers_to_be_created.items()):
        s_created = dt.datetime.strptime(data['created_on'],
                                         defaults.DATETIME_FORMAT)
        if now - s_created > dt.timedelta(hours=1):
            servers_to_be_created.pop(s_id, None)
Ejemplo n.º 16
0
    def test_to_from_json(self):
        created = get_now()
        s2 = Step(orchestration=self.o, undo=True,
                  stop_on_error=False,
                  action_template=self.at2,
                  expected_stdout='expected',
                  expected_stderr='stderr',
                  id='11111111-2222-3333-4444-111111110002',
                  created_on=created)
        s1 = Step(orchestration=self.o, undo=True,
                  stop_on_error=False,
                  action_template=self.at1,
                  expected_stdout='expected',
                  expected_stderr='stderr',
                  expected_rc=0,
                  system_kwargs={'timeout': 180},
                  children_steps=[s2],
                  id='11111111-2222-3333-4444-111111110001',
                  created_on=created)

        s1_json = s1.to_json()
        s2_json = s2.to_json()
        self.assertDictEqual(
            dict(id='11111111-2222-3333-4444-111111110001',
                 orchestration_id='11111111-2222-3333-4444-666666660001',
                 undo=True,
                 stop_on_error=False,
                 action_template_id=str(self.at1.id),
                 expected_stdout='expected',
                 expected_stderr='stderr',
                 parent_step_ids=[],
                 expected_rc=0,
                 system_kwargs={'timeout': 180},
                 created_on=created.strftime(defaults.DATETIME_FORMAT)), s1_json)
        self.assertDictEqual(
            dict(id='11111111-2222-3333-4444-111111110002',
                 orchestration_id='11111111-2222-3333-4444-666666660001',
                 undo=True,
                 stop_on_error=False,
                 action_template_id=str(self.at2.id),
                 expected_stdout='expected',
                 expected_stderr='stderr',
                 parent_step_ids=['11111111-2222-3333-4444-111111110001'],
                 system_kwargs={},
                 created_on=created.strftime(defaults.DATETIME_FORMAT)), s2_json)

        with self.assertRaises(errors.EntityNotFound):
            Step.from_json(s1_json)

        db.session.add(s1)

        smashed_s1 = Step.from_json(s1_json)
        self.assertEqual(s1, smashed_s1)

        s1_json['parent_step_ids'].append('11111111-2222-3333-4444-111111110003')
        with self.assertRaises(errors.EntityNotFound):
            smashed_s1 = Step.from_json(s1_json)
Ejemplo n.º 17
0
def ping(node):
    for n in node:
        dprint(f"### {n}:") if len(node) > 1 else None
        node_id = normalize2id(n)
        resp = ntwrk.post(
            'root.ping',
            headers={'D-Destination': node_id},
            json={'start_time': get_now().strftime(defaults.DATETIME_FORMAT)})
        dprint(resp)
Ejemplo n.º 18
0
 def create_step_execution(self, command):
     ident = str(uuid.uuid4())
     with self.session_scope() as s:
         se = StepExecution(id=ident, step_id=command.id[1],
                            server_id=command.id[0], orch_execution_id=self.json_orch_execution.get('id'),
                            start_time=get_now())
         s.add(se)
     self._store[ident] = se
     return ident
Ejemplo n.º 19
0
    def store_string(self, string: str) -> None:
        # Save to file.
        with open(self.filename, "ab") as f:

            def write(t: str) -> None:
                f.write(t.encode("utf-8"))

            write("\n# %s\n" % get_now())
            for line in string.split("\n"):
                write("%s+%s\n" % (self.tag, line))
Ejemplo n.º 20
0
    def test_from_to_json_with_gate(self, mock_get_now, mock_uuid):
        mock_get_now.return_value = get_now()
        mock_uuid.return_value = '22cd859d-ee91-4079-a112-000000000002'
        s = Server('server2', id='22cd859d-ee91-4079-a112-000000000001')

        gate = mock.MagicMock()
        gate.to_json.return_value = {'server_id': 1, 'server': 'n1'}

        type(s).gates = mock.PropertyMock(return_value=[gate])

        self.assertDictEqual(
            {
                'id':
                '22cd859d-ee91-4079-a112-000000000001',
                'name':
                'server2',
                'granules': [],
                'gates': [{}],
                'created_on':
                mock_get_now.return_value.strftime(defaults.DATETIME_FORMAT),
                '_old_name':
                None,
                'deleted':
                False
            }, s.to_json(add_gates=True))
        db.session.add(s)
        db.session.commit()

        s_json = s.to_json(add_gates=True)
        smashed = Server.from_json(s_json)

        self.assertIs(s, smashed)
        self.assertEqual(s.id, smashed.id)
        self.assertEqual(s.name, smashed.name)
        self.assertEqual(s.granules, smashed.granules)
        self.assertEqual(s.last_modified_at, smashed.last_modified_at)
        self.assertListEqual(s.gates, smashed.gates)

        # from new Server
        db.session.remove()
        db.drop_all()
        db.create_all()

        with patch('dimensigon.domain.entities.server.Gate.from_json'
                   ) as mock_gate_from_json:
            smashed = Server.from_json(s_json)

            self.assertEqual(s.id, smashed.id)
            self.assertEqual(s.name, smashed.name)
            self.assertEqual(s.granules, smashed.granules)
            self.assertEqual(s.last_modified_at, smashed.last_modified_at)
            self.assertEqual(1, len(smashed.gates))
            mock_gate_from_json.assert_called_once()
Ejemplo n.º 21
0
 def upgrade_process(self):
     self.logger.debug("Starting check catalog from neighbours")
     # cluster information
     cluster_hearthbeat_id = get_now().strftime(defaults.DATETIME_FORMAT)
     # check version update before catalog update to match database revision
     data = asyncio.run(
         self._async_get_neighbour_healthcheck(cluster_hearthbeat_id))
     if data:
         self.check_new_version(data)
         self.catalog_update(data)
     else:
         raise NoServerFound()
Ejemplo n.º 22
0
 def receive_before_insert(mapper, connection, target):
     if not hasattr(catalog, 'data'):
         catalog.data = {}
     if getattr(catalog, 'datemark', True):
         target.last_modified_at = get_now()
     if not target.__class__ in catalog.data:
         catalog.data.update({target.__class__: target.last_modified_at})
     else:
         catalog.data.update({
             target.__class__:
             max(target.last_modified_at, catalog.data[target.__class__])
         })
Ejemplo n.º 23
0
    def test_to_from_json(self, mock_uuid, mock_get_now):
        now = get_now()
        mock_get_now.return_value = now
        mock_uuid.side_effect = [
            '22cd859d-ee91-4079-a112-000000000001',
            '22cd859d-ee91-4079-a112-000000000002',
            '22cd859d-ee91-4079-a112-000000000003'
        ]

        s = Server('server',
                   dns_or_ip='dns',
                   gates=[('gdns', 6000)],
                   created_on=now)
        self.assertDictEqual(
            {
                'id': '22cd859d-ee91-4079-a112-000000000001',
                'name': 'server',
                'granules': [],
                'created_on': now.strftime(defaults.DATETIME_FORMAT),
                'deleted': False,
                '_old_name': None
            }, s.to_json())

        self.assertDictEqual(
            {
                'id': '22cd859d-ee91-4079-a112-000000000001',
                'name': 'server',
                'granules': [],
                'created_on': now.strftime(defaults.DATETIME_FORMAT),
                'ignore_on_lock': False,
            }, s.to_json(no_delete=True, add_ignore=True))
        db.session.add(s)
        db.session.commit()
        db.session.remove()
        del s
        s = Server.query.get('22cd859d-ee91-4079-a112-000000000001')
        self.assertDictEqual(
            {
                'id': '22cd859d-ee91-4079-a112-000000000001',
                'name': 'server',
                'granules': [],
                'last_modified_at': now.strftime(defaults.DATEMARK_FORMAT),
                'created_on': now.strftime(defaults.DATETIME_FORMAT),
            }, s.to_json(no_delete=True))

        smashed = Server.from_json(s.to_json())

        self.assertIs(s, smashed)
        self.assertEqual(s.id, smashed.id)
        self.assertEqual(s.name, smashed.name)
        self.assertEqual(s.granules, smashed.granules)
        self.assertEqual(s.last_modified_at, smashed.last_modified_at)
Ejemplo n.º 24
0
    def test_equality(self):
        created = get_now()
        s1 = Step(orchestration=self.o, undo=True, stop_on_error=False, action_template=self.at1,
                  expected_stdout='expected', expected_stderr='stderr',
                  expected_rc=0, system_kwargs={'timeout': 30}, created_on=created)
        s2 = Step(orchestration=self.o, undo=True, stop_on_error=False, action_template=self.at2,
                  expected_stdout='expected', expected_stderr='stderr',
                  expected_rc=0, system_kwargs={'timeout': 30}, created_on=created)

        self.assertTrue(s1.eq_imp(s2))

        s2.post_process = 'post_process'
        self.assertFalse(s1.eq_imp(s2))
Ejemplo n.º 25
0
 def save_step_execution(self, command: ImplementationCommand, params=None, pre_process_time=None,
                         execution_time=None,
                         post_process_time=None):
     with self.session_scope() as s:
         se = s.merge(self._store[command.step_execution_id])
         se.load_completed_result(command._cp)
         se.params = params
         se.pre_process_elapsed_time = pre_process_time
         se.execution_elapsed_time = execution_time
         se.post_process_elapsed_time = post_process_time
         se.end_time = get_now()
         if command._cp.stdout and ORCH_EXEC_PATTERN.match(command._cp.stdout):
             se.child_orch_execution_id = ORCH_EXEC_PATTERN.match(command._cp.stdout)[1]
Ejemplo n.º 26
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
Ejemplo n.º 27
0
def _ping(dest: t.Union[Server, Gate],
          source: Server,
          retries=None,
          timeout=None,
          verify=False):
    tries = 0
    cost = None
    elapsed = None
    exc = None

    if isinstance(dest, Gate):
        server = dest.server
        try:
            schema = current_app.config['PREFERRED_URL_SCHEME'] or 'https'
        except:
            schema = 'https'
        url = f"{schema}://{dest}/{url_for('root.ping', _external=False)}"
    else:
        server = dest
        try:
            url = dest.url('root.ping')
        except:
            return None, None
    while tries < retries:
        try:
            tries += 1
            resp = requests.post(url,
                                 json={
                                     'start_time':
                                     get_now().strftime(
                                         defaults.DATETIME_FORMAT)
                                 },
                                 headers={
                                     'D-Source': str(source.id),
                                     'D-Destination': str(server.id)
                                 },
                                 verify=verify,
                                 timeout=timeout)
        except requests.exceptions.ReadTimeout as e:
            resp = None
            exc = e
        except requests.exceptions.ConnectionError as e:
            # unable to reach actual server through current gateway
            resp = None
            exc = e
        if resp is not None and resp.status_code == 200:
            cost = len(resp.json().get('servers', {}))
            elapsed = resp.elapsed
            tries = retries
    return cost, elapsed
Ejemplo n.º 28
0
def fetch_catalog(data_mark=None):
    data = {}
    now = get_now()
    for name, obj in get_distributed_entities():
        c = Catalog.query.get(name)
        # db.session.query to bypass deleted objects to spread deleted changes
        if data_mark:
            query = obj.query.filter(obj.last_modified_at > data_mark)
        else:
            query = obj.query
        repo_data = query.filter(obj.last_modified_at <= now).all()
        if name == 'User':
            data.update({name: [e.to_json(password=True) for e in repo_data]})
        else:
            data.update({name: [e.to_json() for e in repo_data]})
    return data
Ejemplo n.º 29
0
 def set_keepalive(self, iden: Id, keepalive=None) -> t.Optional[t.Dict]:
     with self._lock:
         keepalive = keepalive or get_now()
         initial_cr = copy.deepcopy(self._cluster.get(iden, None))
         if iden in self._cluster:
             if self._cluster[iden].death is not None:
                 self.set_alive(iden)
             if not self._cluster[iden].keepalive or self._cluster[
                     iden].keepalive < keepalive - self.threshold:
                 self._cluster[iden].keepalive = keepalive
         else:
             self._cluster[iden] = self._register_class(iden,
                                                        birth=keepalive,
                                                        keepalive=keepalive)
         return self._cluster[iden].to_dict(
         ) if self._cluster[iden] != initial_cr else None
Ejemplo n.º 30
0
 def set_keepalive(self,
                   iden: Id,
                   session: Id = None,
                   keepalive=None) -> t.Optional[t.Dict]:
     with self._lock:
         keepalive = keepalive or get_now()
         if iden in self._cluster:
             if self._cluster[iden].session == session:
                 self.set_alive(iden, session, keepalive)
             self._cluster[iden].keepalive = keepalive
         else:
             self._cluster[iden] = self._register_class(iden,
                                                        session=session,
                                                        birth=keepalive,
                                                        keepalive=keepalive)
         return self._cluster[iden].to_dict()