Exemplo n.º 1
0
    def get(self, container_id):
        """Gets all instances bound to this container.

        An example of response::

            {
              "status": "SUCCESS",
              "data": {
                "registry": [
                  {
                    "application_name": "base.foo",
                    "cluster_name": "test_cluster"
                  }
                ]
              }
            }

        :param container_id: The container id (a.k.a CID, Task ID).
        :<header Authorization: Huskar Token (See :ref:`token`)
        :status 200: The request is successful.
        """
        cm = ContainerManagement(huskar_client, container_id)
        registry = [
            {'application_name': a, 'cluster_name': c} for a, c in cm.lookup()]
        barrier = cm.has_barrier()
        return api_response({'registry': registry, 'barrier': barrier})
Exemplo n.º 2
0
    def delete(self, application_name, cluster_name):
        """Deregisters a service instance.

        The ``write`` authority is required. See :ref:`application_auth` also.

        :param application_name: The name of application.
        :param cluster_name: The name of cluster.
        :form key: The name of instance.
        :<header Authorization: Huskar Token (See :ref:`token`)
        :status 404: The application is not found.
        :status 400: The request body is invalid.
        :status 200: The service instance is deregistered successfully.
        """
        check_application_auth(application_name, Authority.WRITE)
        check_cluster_name(cluster_name, application_name)

        key = request.values['key'].strip()
        validate_fields(instance_schema, {
            'application': application_name,
            'cluster': cluster_name,
            'key': key,
        })

        im = InstanceManagement(huskar_client, application_name,
                                SERVICE_SUBDOMAIN)
        instance, _ = im.get_instance(cluster_name, key, resolve=False)
        if instance.stat is None:
            abort(
                404, '%s %s/%s/%s does not exist' % (
                    SERVICE_SUBDOMAIN,
                    application_name,
                    cluster_name,
                    key,
                ))

        old_data = instance.data
        with audit_log(audit_log.types.DELETE_SERVICE,
                       application_name=application_name,
                       cluster_name=cluster_name,
                       key=key,
                       old_data=old_data):
            service_facade.delete(application_name,
                                  cluster_name,
                                  key,
                                  strict=True)

        # Writes container registry finally
        if is_container_id(key):
            cm = ContainerManagement(huskar_client, key)
            cm.deregister_from(application_name, cluster_name)

        return api_response()
Exemplo n.º 3
0
def test_add_service_instance_from_container(
        client, test_application_name, zk, add_service, minimal_mode,
        key, value):
    if minimal_mode:
        zk.ensure_path('/huskar/service/%s' % test_application_name)
        sleep(0.1)

    args, r = add_service(key, value, cluster_name='stable')
    assert_response_ok(r)

    instance_data, instance_stat = zk.get(
        '/huskar/service/%s/stable/%s' % (test_application_name, key))
    assert json.loads(instance_data) == json.loads(value)
    assert instance_stat.version == 0

    cm = ContainerManagement(huskar_client, key)
    assert cm.lookup() == [(test_application_name, 'stable')]
Exemplo n.º 4
0
def test_add_service_instance_from_container_but_meets_barrier(
        client, test_application_name, zk, add_service, minimal_mode,
        key, value):
    if minimal_mode:
        zk.ensure_path('/huskar/service/%s' % test_application_name)
        sleep(0.1)

    cm = ContainerManagement(huskar_client, key)
    cm.set_barrier()

    args, r = add_service(key, value, cluster_name='stable')
    assert r.status_code == 409
    assert r.json['status'] == 'Conflict'
    assert r.json['message'] == 'this container has been unbound recently'

    assert not zk.exists(
        '/huskar/service/%s/stable/%s' % (test_application_name, key))
    assert cm.lookup() == []
Exemplo n.º 5
0
def vacuum_stale_barriers():
    logger.info('Begin to vacuum stale container barriers')
    vacuum_iterator = ContainerManagement.vacuum_stale_barriers(huskar_client)
    for container_id, is_stale in vacuum_iterator:
        if is_stale:
            logger.info('Delete stale barrier of container %s', container_id)
        else:
            logger.info('Skip barrier of container %s', container_id)
    logger.info('Done to vacuum stale container barriers')
Exemplo n.º 6
0
def test_add_service_instance(client, test_application_name, zk, add_service,
                              webhook_backends, add_webhook_subscriptions,
                              minimal_mode, key, value, runtime, whole,
                              last_audit_log):
    if minimal_mode:
        zk.ensure_path('/huskar/service/%s' % test_application_name)
        sleep(0.1)

    args, r = add_service(key, value, runtime)
    assert_response_ok(r)
    assert r.json['data']['meta']
    assert r.json['data']['value'] == json.loads(whole)

    children = zk.get_children(
        '/huskar/service/%s/overall' % test_application_name)
    assert children == [args['key']]

    instance_data, instance_stat = zk.get(
        '/huskar/service/%s/overall/%s' % (test_application_name, args['key']))
    assert json.loads(instance_data) == json.loads(whole)
    assert instance_stat.version == 0

    instance_children = zk.get_children(
        '/huskar/service/%s/overall/%s' % (test_application_name, args['key']))
    assert instance_children == []  # runtime node should not exist

    cm = ContainerManagement(huskar_client, key)
    assert cm.lookup() == []

    if not minimal_mode:
        audit_log = last_audit_log()
        assert audit_log.action_name == 'UPDATE_SERVICE'
        assert audit_log.action_json['application_name'] == \
            test_application_name
        assert audit_log.action_json['cluster_name'] == 'overall'
        assert audit_log.action_json['key'] == args['key']

        for result in webhook_backends:
            assert result['action_name'] == 'UPDATE_SERVICE'
            assert result['action_data']['application_name'] == \
                test_application_name
            assert result['action_data']['cluster_name'] == 'overall'
            assert result['action_data']['key'] == args['key']
Exemplo n.º 7
0
def test_management_vacuum_stale_barriers(zk):
    zk.delete('/huskar/container-barrier', recursive=True)
    zk.ensure_path('/huskar/container-barrier/foo')
    zk.ensure_path('/huskar/container-barrier/bar')

    vacuum = ContainerManagement.vacuum_stale_barriers(huskar_client)
    assert list(vacuum) == [('bar', False), ('foo', False)]
    assert zk.exists('/huskar/container-barrier/foo')
    assert zk.exists('/huskar/container-barrier/bar')

    with freeze_time() as frozen_time:
        frozen_time.tick(datetime.timedelta(hours=2))
        vacuum = ContainerManagement.vacuum_stale_barriers(huskar_client)
        assert list(vacuum) == [('bar', False), ('foo', False)]
        assert zk.exists('/huskar/container-barrier/foo')
        assert zk.exists('/huskar/container-barrier/bar')

        frozen_time.tick(datetime.timedelta(days=1))
        vacuum = ContainerManagement.vacuum_stale_barriers(huskar_client)
        assert list(vacuum) == [('bar', True), ('foo', True)]
        assert not zk.exists('/huskar/container-barrier/foo')
        assert not zk.exists('/huskar/container-barrier/bar')
Exemplo n.º 8
0
    def delete(self, container_id):
        """Reregisters all instances bound to this container.

        The site admin authority is required. See :ref:`site_admin` also.

        :param container_id: The container id (a.k.a CID, Task ID).
        :<header Authorization: Huskar Token (See :ref:`token`)
        :status 409: The container is still using by another one, and who are
                     registering new service instance on it. It is recommended
                     to try again since the container is truly dead.
        :status 200: The request is successful.
        """
        g.auth.require_admin()

        cm = ContainerManagement(huskar_client, container_id)
        cm.set_barrier()

        for application_name, cluster_name in cm.lookup():
            # Deregister current instance
            old_data = service_facade.get_value(
                application_name, cluster_name, container_id)
            service_facade.delete(
                application_name, cluster_name, container_id, strict=False)
            audit_log.emit(
                audit_log.types.DELETE_SERVICE,
                application_name=application_name, cluster_name=cluster_name,
                key=container_id, old_data=old_data)
            # Release container record
            cm.deregister_from(application_name, cluster_name)

        try:
            cm.destroy()
        except NotEmptyError:
            message = 'Container {0} is still registering new instance'.format(
                container_id)
            abort(409, message)

        return api_response()
Exemplo n.º 9
0
def test_list_registry(client, container_id, container_management, test_token,
                       minimal_mode, preset, result):
    container_management.set_barrier()
    for application_name, cluster_name in preset:
        container_management.register_to(application_name, cluster_name)

    url = '/api/_internal/tools/container/registry/%s' % container_id
    r = client.get(url, headers={'Authorization': test_token})
    assert_response_ok(r)
    assert r.json['data'] == {'registry': result, 'barrier': True}

    with freeze_time() as frozen_time:
        frozen_time.tick(datetime.timedelta(days=1.1))
        for _ in ContainerManagement.vacuum_stale_barriers(huskar_client):
            pass

    r = client.get(url, headers={'Authorization': test_token})
    assert_response_ok(r)
    assert r.json['data']['barrier'] is False
Exemplo n.º 10
0
def test_delete_service_from_container(
        client, zk, test_application_name, test_application_token,
        minimal_mode, key, value):
    cm = ContainerManagement(huskar_client, key)

    path = '/huskar/service/%s/beta/%s' % (test_application_name, key)
    zk.create(path, json.dumps(value), makepath=True)
    cm.register_to(test_application_name, 'beta')

    if minimal_mode:
        zk.ensure_path('/huskar/service/%s' % test_application_name)
        sleep(0.1)

    assert zk.exists(path)
    assert cm.lookup() == [(test_application_name, 'beta')]

    url = '/api/service/%s/%s' % (test_application_name, 'beta')
    headers = {'Authorization': test_application_token}
    r = client.delete(url, data={'key': key}, headers=headers)
    assert_response_ok(r)

    assert not zk.exists(path)
    assert cm.lookup() == []
Exemplo n.º 11
0
def container_management(container_id):
    return ContainerManagement(huskar_client, container_id)
Exemplo n.º 12
0
 def register_container(self):
     cm = ContainerManagement(huskar_client, self.key)
     cm.raise_for_unbound(self.application_name, self.cluster_name,
                          self.key)
     cm.register_to(self.application_name, self.cluster_name)