コード例 #1
0
ファイル: test_application.py プロジェクト: zhoudaqing/huskar
def test_get_application_by_name(db, test_application):
    application = Application.get_by_name(test_application.application_name)
    assert application is test_application
    assert application.domain_name == 'foo'

    application = Application.get_by_name(test_application.application_name +
                                          '1s')
    assert application is None
コード例 #2
0
ファイル: test_application.py プロジェクト: zhoudaqing/huskar
def test_create_application_cache_invalidation(db, test_team):
    assert Application.get_by_name('bar') is None
    assert len(Application.get_multi_by_team(test_team.id)) == 0
    assert len(Application.get_all()) == 0

    Application.create('bar', test_team.id)

    assert Application.get_by_name('bar') is not None
    assert len(Application.get_multi_by_team(test_team.id)) == 1
    assert len(Application.get_all()) == 1
コード例 #3
0
ファイル: test_application.py プロジェクト: zhoudaqing/huskar
def test_unarchive_application(db, test_user, test_team, test_application,
                               test_application_auth):
    test_application.archive()
    assert Application.get_by_name(test_application.application_name) is None
    test_application.unarchive()
    assert Application.get_by_name(
        test_application.application_name) is not None

    test_application.archive()
    test_team.archive()
    test_application.unarchive()
    assert Application.get_by_name(test_application.application_name) is None
コード例 #4
0
ファイル: test_application.py プロジェクト: zhoudaqing/huskar
def test_delete_application(db, test_user, test_team, test_application,
                            test_application_auth):
    assert Application.get_by_name(
        test_application.application_name) is test_application
    assert Application.get_multi_by_team(test_team.id) == [test_application]
    assert Application.get_all() == [test_application]

    Application.delete(test_application.id)

    assert Application.get_by_name(test_application.application_name) is None
    assert Application.get_multi_by_team(test_team.id) == []
    assert Application.get_all() == []
    assert ApplicationAuth.get(test_application_auth.id) is None
コード例 #5
0
ファイル: test_application.py プロジェクト: zhoudaqing/huskar
def test_archive_application(db, test_user, test_team, test_application,
                             test_application_auth):
    instance = Application.get_by_name(test_application.application_name)
    assert instance is test_application
    assert Application.get_multi_by_team(test_team.id) == [test_application]
    assert Application.get_all() == [test_application]

    test_application.archive()

    assert Application.get_by_name(test_application.application_name) is None
    assert Application.get_multi_by_team(test_team.id) == []
    assert Application.get_all() == []
    assert ApplicationAuth.find(Authority.READ, test_user.id,
                                test_application.id) is not None
コード例 #6
0
ファイル: webhook.py プロジェクト: zhoudaqing/huskar
    def put(self, webhook_id):
        """To update subscription settings of an application

        Request body schema same to ``POST`` method.

        :param application_name: The name of application.
        :param webhook_id: The id of webhook.
        :param webhoo_type: default 0, set universal with 1
        :status 200: thr request is successful.
        :status 404: The application or webhoook not found.
        """
        webhook = self._get_webhook_or_404(webhook_id)
        self._check_authority(webhook)

        data = request.get_json() or {}
        validate_fields(webhook_schema, data, partial=False)
        if not webhook.is_normal:
            webhook.update_url(data['webhook_url'])
            return api_response()

        application_name = request.args['application_name']
        application = Application.get_by_name(application_name)
        webhook.batch_unsubscribe(application.id)
        webhook.update_url(data['webhook_url'])
        for action_name in data.get('event_list', []):
            action_type = getattr(action_types, action_name)
            webhook.subscribe(application.id, action_type)
        return api_response()
コード例 #7
0
ファイル: audit.py プロジェクト: zhoudaqing/huskar
    def get(self, application_name, cluster_name, key):
        """Get the audit logs of specified instance key.

        :param application_name: The name of application.
        :param cluster_name: The name of clsuter.
        :param key: The key of instance.
        :query date: The date specified to search, default is today.
        :query start: The offset of pagination. Default is ``0``.
        :>header Authorization: Huskar Token (See :ref:`token`)
        :status 403: You don't have required authority.
        :status 501: The server is in minimal mode.
        :status 200: The result is in the response.
                     (See :ref:`Audit Log Schema <audit_schema>`)
        """
        check_application(application_name)
        check_cluster_name(cluster_name, application_name)

        start = request.args.get('start', type=int, default=0)
        application = Application.get_by_name(application_name)
        can_view_sensitive_data = AuditLog.can_view_sensitive_data(
            g.auth.id, self.instance_type, application.id)
        items = AuditLog.get_multi_by_instance_index(self.instance_type,
                                                     application.id,
                                                     cluster_name, key)
        items = items[start:start + 20]
        if not can_view_sensitive_data:
            items = [item.desensitize() for item in items]
        return api_response(audit_log_schema.dump(items, many=True).data)
コード例 #8
0
ファイル: organization.py プロジェクト: zhoudaqing/huskar
    def _create(self, ignore_existed=False):
        team_name = request.values['team'].strip()
        application_name = request.values['application'].strip()
        validate_fields(application_schema,
                        {'name': application_name, 'team_name': team_name})

        team = Team.get_by_name(team_name)
        if team is None:
            abort(400, 'team "%s" does not exist' % team_name)

        require_team_admin_or_site_admin(team)

        application = Application.get_by_name(application_name)
        if application is not None:
            if ignore_existed:
                return api_response()
            raise ApplicationExistedError(
                'application: {} has existed, application is globally '
                'unique'.format(application))

        try:
            application = Application.create(application_name, team.id)
        except NameOccupiedError:
            abort(400, 'The application name {0} has been occupied.'.format(
                application_name))
        audit_log.emit(
            audit_log.types.CREATE_APPLICATION, application=application,
            team=team)
        return api_response()
コード例 #9
0
ファイル: test_token.py プロジェクト: zhoudaqing/huskar
def test_get_team_application_token_with_unknown_application(
        client, db, test_team, admin_user, admin_token, application_name):
    application = Application.get_by_name(application_name)
    assert application is None

    r = client.post(
        '/api/team/%s/application/%s/token' %
        (test_team.team_name, application_name),
        data={'owner_email': admin_user.username + '@foo.bar'},
        headers={'Authorization': admin_token},
    )

    assert_response_ok(r)
    application = Application.get_by_name(application_name)
    assert application is not None
    user = User.get_by_token(settings.SECRET_KEY, r.json['data']['token'])
    assert user and user.username == application.application_name
コード例 #10
0
ファイル: test_application.py プロジェクト: zhoudaqing/huskar
def test_application_transfer_team(db, test_application, faker):
    orig_team_id = test_application.team_id
    dest_team = Team.create(faker.name())
    test_application.transfer_team(dest_team.id)
    application = Application.get_by_name(test_application.application_name)
    assert application.team_id == dest_team.id
    assert test_application.id not in Application.get_ids_by_team(orig_team_id)
    assert test_application.id in Application.get_ids_by_team(dest_team.id)
コード例 #11
0
ファイル: action.py プロジェクト: zhoudaqing/huskar
def _optional_instance_indices(application_name, cluster_name, instance_key,
                               action_type):
    _, action_name = action_types[action_type].split('_', 1)
    instance_type = INSTANCE_TYPE_MAP[action_name.lower()]
    application = None
    with _suppress_exception(application_name=application_name):
        application = Application.get_by_name(application_name)
    if application:
        yield (instance_type, application.id, cluster_name, instance_key)
コード例 #12
0
def destroy_application(name):
    application = Application.get_by_name(name)
    if application is not None:
        Application.delete(application.id)
        logger.info('Removed application from DBMS: %s', name)

    for type_name in (SERVICE_SUBDOMAIN, SWITCH_SUBDOMAIN, CONFIG_SUBDOMAIN):
        path = '/huskar/%s/%s' % (type_name, name)
        if huskar_client.client.exists(path):
            huskar_client.client.delete(path, recursive=True)
            logger.info('Removed application from ZooKeeper: %s', path)
コード例 #13
0
ファイル: action.py プロジェクト: zhoudaqing/huskar
def _optional_indices(application_name):
    application = None
    team = None
    with _suppress_exception(application_name=application_name):
        application = Application.get_by_name(application_name)
    with _suppress_exception(application_name=application_name):
        team = application and application.team
    if application:
        yield (TYPE_APPLICATION, application.id)
    if team:
        yield (TYPE_TEAM, team.id)
コード例 #14
0
def check_application(application_name):
    if is_application_blacklisted(application_name):
        raise ApplicationNotExistedError(
            'application: {} is blacklisted'.format(application_name))

    if g.auth.is_minimal_mode:
        return
    application = Application.get_by_name(application_name)
    if application is None:
        raise ApplicationNotExistedError(
            "application: {} doesn't exist".format(application_name))
    return application
コード例 #15
0
ファイル: audit.py プロジェクト: zhoudaqing/huskar
    def _find_target(self, name):
        if self.target_type is AuditLog.TYPE_SITE:
            return 0

        if self.target_type is AuditLog.TYPE_TEAM:
            team = Team.get_by_name(name)
            if team is not None:
                return team.id

        if self.target_type is AuditLog.TYPE_APPLICATION:
            application = Application.get_by_name(name)
            if application is not None:
                return application.id
コード例 #16
0
def test_add_application_without_validation(client, mocker, test_user,
                                            admin_token, fake_team):
    invalid_name = '@_@::+1s'
    data = {'team': fake_team.team_name, 'application': invalid_name}
    headers = {'Authorization': admin_token}

    r = client.post('/api/application', data=data, headers=headers)
    assert r.status_code == 400
    assert r.json['status'] == 'ValidationError'
    assert json.loads(r.json['message'])['name'][0]
    assert Application.get_by_name(invalid_name) is None

    def fake_switch(name, default=True):
        if name == SWITCH_VALIDATE_SCHEMA:
            return False
        return default

    mocker.patch.object(switch, 'is_switched_on', fake_switch)

    r = client.post('/api/application', data=data, headers=headers)
    assert_response_ok(r)
    assert Application.get_by_name(invalid_name)
コード例 #17
0
ファイル: webhook.py プロジェクト: zhoudaqing/huskar
    def get(self, webhook_id):
        """Get the webhook subscriptions list of specified application and
        The ``read`` authority is required.

        The response looks like::

            {
              "status": "SUCCESS",
              "message": "",
              "data": {
                "webhook_id": 1,
                "webhook_url": "http://www.example.com",
                "webhook_type": 0,
                "event_list": [
                    "CREATE_CONFIG_CLUSTER",
                    "DELETE_CONFIG_CLUSTER",
                    ...
                ]
              }
            }

        The content of ``event_list`` is a list of action that
        already defined in Huskar.

        :param application_name: The name of application.
        :status 200: The request is successful.
        :status 404: The application not found.
        """
        webhook = self._get_webhook_or_404(webhook_id)
        if not webhook.is_normal:
            return api_response(
                data={
                    'webhook_id': webhook.id,
                    'webhook_url': webhook.url,
                    'webhook_type': webhook.hook_type,
                    'event_list': []
                })

        application_name = request.args['application_name']
        check_application_auth(application_name, Authority.READ)
        application = Application.get_by_name(application_name)
        subscriptions = webhook.get_multi_subscriptions(application.id)
        data = {
            'webhook_id': webhook.id,
            'webhook_url': webhook.url,
            'webhook_type': webhook.hook_type,
            'event_list': [action_types[x.action_type] for x in subscriptions]
        }
        return api_response(data=data)
コード例 #18
0
ファイル: organization.py プロジェクト: zhoudaqing/huskar
    def get(self, application_name):
        """Gets an application by its name.

        The response looks like::

            {
              "status": "SUCCESS",
              "message": "",
              "data": {
                "item": {
                  "name": "foo.test",
                  "team_name": "foo",
                  "team_desc": "foo-bar",
                  "is_deprecated": false,
                  "is_blacklisted": false,
                  "route_stage": {
                    "altc1-channel-stable-1": "S"
                  }
                }
              }
            }

        There is nothing acts HTTP cache in this API like the
        :ref:`application_list` was done.

        :param application_name: The name of deleting application.
        :<header Authorization: Huskar Token (See :ref:`token`)
        :status 404: The application does not exist yet.
        :status 200: The application was returned successfully.
        """
        if g.auth.is_minimal_mode:
            if not application_manifest.check_is_application(application_name):
                abort(404, 'application does not exist')
            result = application_schema.dump({
                'name': application_name,
                'team_name': Team.DEFAULT_NAME,
                'team_desc': Team.DEFAULT_NAME,
            })
        else:
            application = Application.get_by_name(application_name)
            if application is None:
                abort(404, 'application does not exist')
            result = application_schema.dump({
                'name': application.application_name,
                'team_name': application.team.team_name,
                'team_desc': application.team.team_desc,
            })
        return api_response({'item': result.data})
コード例 #19
0
ファイル: infra_config.py プロジェクト: zhoudaqing/huskar
    def put(self, application_name, infra_type, infra_name):
        """Configures the infrastructure in specified application.

        The input schema looks like::

            {
              "url": "sam+redis://redis.foobar/overall"
            }

        :param application_name: The application which uses infrastructure.
        :param infra_type: ``database``, ``redis`` or ``amqp``.
        :param infra_name: The unique code-reference name of infrastructure.
        :query scope_type: ``idcs`` or ``clusters``.
        :query scope_name: The ezone id or cluster name.
        :query owner_mail: The email of resource owner which will receive the
                           notification of infra config creation.
        :<header Authorization: Huskar Token (See :ref:`token`)
        :<header Content-Type: ``application/json``
        :status 200: The same as ``GET``.
        """
        with self._update(application_name, request, infra_type,
                          infra_name) as args:
            application_name, infra_info, scope_type, scope_name, value = args
            owner_mail = request.args.get('owner_mail', '').strip()
            is_newcomer = len(infra_info.list_by_infra_name(infra_name)) == 0
            infra_info.set_by_name(infra_name, scope_type, scope_name, value)

        if is_newcomer and owner_mail:
            owned_application = Application.get_by_name(application_name)
            owner_user = User.get_by_email(owner_mail)
            infra_owner_emails = settings.ADMIN_INFRA_OWNER_EMAILS.get(
                infra_type, [])
            is_authorized = (owner_user is not None
                             and owned_application.check_auth(
                                 Authority.READ, owner_user.id))
            deliver_email_safe(EmailTemplate.INFRA_CONFIG_CREATE,
                               owner_mail, {
                                   'application_name': application_name,
                                   'infra_name': infra_name,
                                   'infra_type': infra_type,
                                   'is_authorized': is_authorized,
                               },
                               cc=infra_owner_emails)
        infra_config = infra_info.list_by_infra_name(infra_name)
        return api_response({'infra_config': dump_infra_config(infra_config)})
コード例 #20
0
ファイル: webhook.py プロジェクト: zhoudaqing/huskar
    def post(self):
        """Create a new webhook.

        The request accepting a JSON body, the schema likes::

            {
                "webhook_url": "http://www.example.com",
                "event_list": [
                    "CREATE_CONFIG_CLUSTER",
                    "DELETE_CONFIG_CLUSTER"
                ]
            }

        The content of ``event_list`` should be a list of action that
        already defined in Huskar.

        The ``application_name`` is only required when the ``webhook_type``
        is 0, it means the webhook want to subscribe some events of specified
        application. If the ``webhook_type`` value specified with 1,
        a universal webhook will be registered which will receive all
        the events of Huskar site, so the ``event_list`` will be ignored
        because that is unnecessary.

        :param webhook_type: default 0, set ``site`` level with 1.
        :param application_name: The name of application, optional.
        :form webhook_url: the webhook url.
        :form event_list: event list want subscribed
        :status 404: The application not found.
        :status 200: successful request.
        """
        webhook_type = request.args.get('webhook_type', default=0, type=int)
        self._check_authority(webhook_type)
        data = request.get_json() or {}
        validate_fields(webhook_schema, data, partial=False)

        if webhook_type == Webhook.TYPE_UNIVERSAL:
            webhook = Webhook.create(data['webhook_url'], webhook_type)
            return api_response()
        application_name = request.args['application_name']
        application = Application.get_by_name(application_name)
        webhook = Webhook.create(data['webhook_url'], webhook_type)
        for action_name in data.get('event_list', []):
            action_type = getattr(action_types, action_name)
            webhook.subscribe(application.id, action_type)
        return api_response()
コード例 #21
0
ファイル: notify.py プロジェクト: zhoudaqing/huskar
 def publish(self, application_names, user_name, user_type,
             action_type, action_data=None, severity=SEVERITY_DANGEROUS):
     for application_name in application_names:
         action_name = action_types[action_type]
         application = Application.get_by_name(application_name)
         if application is not None:
             subs = Webhook.search_subscriptions(
                 application_id=application.id,
                 action_type=action_type)
             event_data = {
                 'application_name': application_name,
                 'user_name': user_name,
                 'user_type': user_type,
                 'severity': severity,
                 'action_name': action_name,
                 'action_data': action_data
             }
             for sub in subs:
                 self._add(notify_callback, url=sub.webhook.url,
                           data=event_data)
コード例 #22
0
 def _get_application_or_404(self, application_name):
     application = Application.get_by_name(application_name)
     if application is None:
         abort(404, 'application %s does not exist' % application_name)
     return application
コード例 #23
0
 def ensure_application(self):
     return (Application.get_by_name(self.application_name)
             or Application.create(self.application_name,
                                   self.ensure_team().id))