def test_list_applications_under_team(client, zk, test_token, fake_team, minimal_mode, present, expected): for name in present: if minimal_mode: zk.ensure_path('/huskar/config/%s' % name) sleep(0.1) else: Application.create(name, fake_team.id) if minimal_mode: r = client.get('/api/team/%s+1s' % Team.DEFAULT_NAME, headers={'Authorization': test_token}) assert r.status_code == 404 assert r.json['status'] == 'NotFound' r = client.get('/api/team/%s' % Team.DEFAULT_NAME, headers={'Authorization': test_token}) assert_response_ok(r) assert set(expected).issubset(r.json['data']) else: r = client.get('/api/team/%s+1s' % fake_team.team_name, headers={'Authorization': test_token}) assert r.status_code == 404 assert r.json['status'] == 'NotFound' r = client.get('/api/team/%s' % fake_team.team_name, headers={'Authorization': test_token}) assert_response_ok(r) assert r.json['data'] == expected
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()
def test_set_route_failed_dest_linked_empty_cluster(client, zk, test_team, test_application, test_application_token, exist): dest_application_name = '%s_dest' % test_application.application_name Application.create(dest_application_name, test_team.id) test_application_name = test_application.application_name cluster_name = 'stable' dest_cluster_name = 'channel-stable-1' physical_cluster = 'foo.bar' path = '/huskar/service/%s/%s' % (dest_application_name, dest_cluster_name) data = json.dumps({'link': [physical_cluster]}) zk.create(path, data, makepath=True) zk.ensure_path('/huskar/service/%s/%s' % (test_application_name, cluster_name)) if exist: zk.ensure_path('/huskar/service/%s/%s' % (dest_application_name, physical_cluster)) url = '/api/serviceroute/%s/%s/%s' % (test_application_name, cluster_name, dest_application_name) r = client.put(url, data={ 'cluster_name': dest_cluster_name, 'intent': 'direct' }, headers={'Authorization': test_application_token}) assert r.status_code == 400, r.data assert r.json['status'] == 'BadRequest' assert r.json['message'] == \ 'The target cluster %s is empty.' % dest_cluster_name
def test_create_application(db, zk, test_team, faker): application_name = faker.uuid4()[:8] stat = zk.exists('/huskar/service/%s' % application_name) assert stat is None application = Application.create(application_name, test_team.id) assert zk.exists('/huskar/service/%s' % application_name) assert application.id > 0 assert application.application_name == application_name assert application.domain_name == application_name assert application.team_id == test_team.id assert application.team.team_name == test_team.team_name user = User.get_by_name(application_name) assert user is not None assert user.is_application assert not user.is_admin assert application.check_auth(Authority.WRITE, user.id) assert application.check_auth(Authority.READ, user.id) with raises(NameOccupiedError): Application.create(application_name, test_team.id) # name conflicts application = Application.create('baz', test_team.id) assert application.application_name == 'baz'
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)
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
def test_delete_route_noauth(client, zk, test_application, test_team, test_token): Application.create('base.foo', test_team.id) url = '/api/serviceroute/%s/stable/base.foo' % ( test_application.application_name) r = client.delete(url, headers={'Authorization': test_token}) assert r.status_code == 400, r.data assert r.json['status'] == 'NoAuthError'
def test_set_route_noauth(client, zk, test_application, test_team, test_token): Application.create('base.foo', test_team.id) url = '/api/serviceroute/%s/stable/base.foo' % ( test_application.application_name) r = client.put(url, data={'cluster_name': 'channel-stable-1'}, headers={'Authorization': test_token}) assert r.status_code == 400, r.data assert r.json['status'] == 'NoAuthError'
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)
def test_table_cache_expiration(faker, monkeypatch, db, test_team, ttl, result_expected): monkeypatch.setattr(Application, 'TABLE_CACHE_EXPIRATION_TIME', ttl) application_name = faker.uuid4()[:8] application = Application.create(application_name, test_team.id) assert application cache_client = Application._cache_client raw_key = Application.gen_raw_key(application.id) key = cache_client._keygen(raw_key) assert int(cache_client.client.ttl(key)) == result_expected
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
def test_set_route_badintent(client, zk, test_team, test_application, test_application_token): Application.create('base.foo', test_team.id) url = '/api/serviceroute/%s/stable/base.foo' % ( test_application.application_name) r = client.put(url, data={ 'cluster_name': 'channel-stable-1', 'intent': 'freestyle' }, headers={'Authorization': test_application_token}) assert r.status_code == 400, r.data assert r.json['status'] == 'BadRequest' assert r.json['message'] == 'intent must be one of direct'
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()
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)
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
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
def test_set_route_with_dest_linked_cluster(client, zk, test_team, test_application, check_tree, test_application_token): dest_application_name = '%s_dest' % test_application.application_name Application.create(dest_application_name, test_team.id) test_application_name = test_application.application_name cluster_name = 'stable' dest_cluster_name = 'channel-stable-1' physical_cluster = 'foo.bar' path = '/huskar/service/%s/%s' % (dest_application_name, dest_cluster_name) data = json.dumps({'link': [physical_cluster]}) zk.create(path, data, makepath=True) zk.ensure_path('/huskar/service/%s/%s' % (test_application_name, cluster_name)) zk.ensure_path('/huskar/service/%s/%s' % (dest_application_name, physical_cluster)) zk.ensure_path('/huskar/service/%s/%s/key' % (dest_application_name, physical_cluster)) url = '/api/serviceroute/%s/%s/%s' % (test_application_name, cluster_name, dest_application_name) r = client.put(url, data={ 'cluster_name': dest_cluster_name, 'intent': 'direct' }, headers={'Authorization': test_application_token}) assert_response_ok(r) result = [ { 'path': '/huskar/service/%s' % test_application_name, 'data': '{"dependency":{"%s":["%s"]},"_version":"1"}' % (dest_application_name, cluster_name), }, { 'path': '/huskar/service/%s/%s' % (dest_application_name, cluster_name), 'data': '{"route":{"%s":"%s"},"_version":"1"}' % (test_application_name, dest_cluster_name), }, ] check_tree(result)
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)
def test_create_application_setup_default_zpath_oos(mocker, zk, test_team, faker): application_name = faker.uuid4()[:8] mocker.patch.object(ServiceInfo, 'save', side_effect=OutOfSyncError()) application = Application.create(application_name, test_team.id) assert application.id > 0 stat = zk.exists('/huskar/service/%s' % application_name) assert stat is None
def test_create_application_setup_default_zpath_bypass(mocker, zk, test_team, faker): application_name = faker.uuid4()[:8] path = '/huskar/service/%s' % application_name zk.create(path, b'{}', makepath=True) application = Application.create(application_name, test_team.id) assert application.id > 0 data, _ = zk.get(path) assert data == b'{}'
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)
def test_delete_team(team_foo, team_bar, user_foo): Application.create('biu', team_bar.id) TeamAdmin.ensure(team_foo.id, user_foo.id) # fill cache assert Team.get_by_name(team_foo.team_name) is team_foo assert Team.get_by_name(team_bar.team_name) is team_bar assert TeamAdmin.get_user_ids(team_foo.id) == [user_foo.id] Team.delete(team_foo.id) with raises(TeamNotEmptyError): Team.delete(team_bar.id) assert Team.get_by_name(team_foo.team_name) is None assert Team.get_by_name(team_bar.team_name) is not None assert Team.get(team_foo.id) is None assert Team.get(team_bar.id) is not None assert TeamAdmin.get_user_ids(team_foo.id) == [] Team.delete(team_foo.id) assert Team.get(team_foo.id) is None
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
def test_get_data_from_public_domain_application(client, zk, faker, test_application, test_application_token, data_type): name = 'public.%s' % faker.uuid4() application = Application.create(name, test_application.team_id) path = '/huskar/%s/%s/foo/bar' % (data_type, application.application_name) url = '/api/%s/%s/foo?key=bar' % (data_type, application.application_name) zk.create(path, b'1', makepath=True) r = client.get(url, headers={'Authorization': test_application_token}) assert_response_ok(r)
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
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
def test_set_route_failed_dest_empty_cluster(client, zk, test_team, test_application, test_application_token, exist): dest_application_name = '%s_dest' % test_application.application_name Application.create(dest_application_name, test_team.id) dest_cluster_name = 'channel-stable-1' if exist: zk.ensure_path('/huskar/service/%s/%s' % (dest_application_name, dest_cluster_name)) url = '/api/serviceroute/%s/stable/%s' % ( test_application.application_name, dest_application_name) r = client.put(url, data={ 'cluster_name': dest_cluster_name, 'intent': 'direct' }, headers={'Authorization': test_application_token}) assert r.status_code == 400, r.data assert r.json['status'] == 'BadRequest' assert r.json['message'] == \ 'The target cluster %s is empty.' % dest_cluster_name
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)
def get(self, team_name=None): """Gets the team list or application list. While ``team_name`` is specified, the application list in specified team will be responded. Otherwise, the team list will be responded. The response of team list looks like:: { "status": "SUCCESS", "message": "", "data": { "teams": [{"name": "team-1", "desc": "team-1"}, {"name": "team-2"}, "desc": "team-1"] } } And the response of application list looks like:: { "status": "SUCCESS", "message": "", "data": { "applications": ["base.foo", "base.bar"] } } :param team_name: The name of specified team. :<header Authorization: Huskar Token (See :ref:`token`) :status 404: The team with specified name is not found. :status 200: The team list or application list is responded. """ if team_name: if g.auth.is_minimal_mode: if team_name != Team.DEFAULT_NAME: abort(404, 'team "%s" does not exist' % team_name) applications = application_manifest.as_list() else: team = self._get_team_or_404(team_name) applications = Application.get_multi_by_team(team.id) applications = [x.application_name for x in applications] data = {'applications': applications} else: if g.auth.is_minimal_mode: data = {'teams': [{'name': Team.DEFAULT_NAME, 'desc': Team.DEFAULT_NAME}]} else: teams = Team.get_all() data = {'teams': [{'name': x.team_name, 'desc': x.team_desc} for x in teams]} return api_response(data)
def test_archive_team(db, team_foo, user_foo, user_bar): team_foo.grant_admin(user_foo.id) assert team_foo.is_active is True application = Application.create('biu', team_foo.id) assert application.is_active is True with raises(TeamNotEmptyError): team_foo.archive() application.archive() team_foo.archive() assert Team.get_by_name(team_foo.team_name) is None assert db.query(TeamAdmin.id).filter_by( team_id=team_foo.id, user_id=user_foo.id).first() is not None