def test_rollback_route_change(db, client, faker, test_application_name, admin_token, action_type, cluster_name, dest_application_name, destination_cluster_name, zk): action = action_creator.make_action( action_type, application_name=test_application_name, cluster_name=cluster_name, intent='direct', dest_application_name=dest_application_name, dest_cluster_name=destination_cluster_name) audit_log = AuditLog.create(0, faker.ipv4(), action) db.close() rm = RouteManagement(huskar_client, test_application_name, cluster_name) prev_destination_cluster = faker.uuid4()[:8] for cluster in [destination_cluster_name, prev_destination_cluster]: path = '/huskar/service/%s/%s/fo' % (dest_application_name, cluster) zk.ensure_path(path) rm.set_route(dest_application_name, prev_destination_cluster) r = client.put('/api/audit-rollback/%s/%s' % (test_application_name, audit_log.id), headers={'Authorization': admin_token}) assert_response_ok(r) if action_type == action_types.DELETE_ROUTE: result = [(dest_application_name, 'direct', destination_cluster_name)] else: result = [] assert list(rm.list_route()) == result
def test_rollback_cluster_link_conflict(client, faker, db, test_application_name, admin_token, instance_management, action_type): action = action_creator.make_action( action_type, application_name=test_application_name, cluster_name='test', physical_name='alpha_stable', ) audit_log = AuditLog.create(0, faker.ipv4(), action) db.close() instance, _ = instance_management.get_instance('diff', 'key', resolve=False) instance.data = 'value' instance.save() cluster_info = instance_management.get_cluster_info('test') cluster_info.set_link('diff') cluster_info.save() r = client.put('/api/audit-rollback/%s/%s' % (test_application_name, audit_log.id), headers={'Authorization': admin_token}) assert r.status_code == 409
def test_get_multi_by_instance_index( db, redis_client, redis_flushall, faker, user, application): cluster_name = 'bar' key = 'test' action_type = action_types.UPDATE_CONFIG _, data_type = action_types[action_type].split('_', 1) data_type = data_type.lower() audit_num = 3 for _ in range(audit_num): extra = { 'application_name': application.application_name, 'cluster_name': 'bar', 'key': 'test', 'old_data': 'old', 'new_data': 'new' } action = action_creator.make_action( action_types.UPDATE_CONFIG, **extra) AuditLog.create(user.id, faker.ipv4(), action) audit_logs = AuditLog.get_multi_by_instance_index( AuditLog.TYPE_CONFIG, application.id, cluster_name, key) assert len(audit_logs[:]) == audit_num with DBSession().close_on_exit(False): DBSession.delete(user) User._db_session.close() redis_flushall(redis_client) audit_logs = AuditLog.get_multi_by_instance_index( AuditLog.TYPE_CONFIG, application.id, cluster_name, key) assert not any(getattr(x, 'user') for x in audit_logs)
def config_action(): extra = { 'application_name': 'base.foo', 'cluster_name': 'foo', 'key': 'bar' } return action_creator.make_action(action_types.UPDATE_CONFIG, **extra)
def audit_log(action_type, **extra): if not switch.is_switched_on(SWITCH_ENABLE_AUDIT_LOG): yield return action = action_creator.make_action(action_type, **extra) yield try: if g.auth.is_minimal_mode: action_name = action_types[action_type] fallback_audit_logger.info('%s %s %r', g.auth.username, action_name, action.action_data) else: user_id = g.auth.id if g.auth else 0 AuditLog.create(user_id, request.remote_addr, action) except AuditLogTooLongError: logger.info('Audit log is too long. %s %s %s', action_types[action_type], g.auth.username, request.remote_addr) return except AuditLogLostError: action_name = action_types[action_type] fallback_audit_logger.info('%s %s %r', g.auth.username, action_name, action.action_data) sentry.captureException(level=logging.WARNING) except Exception: logger.exception('Unexpected error of audit log') sentry.captureException()
def test_rollback_cluster_link_change(client, faker, admin_token, db, action_type, test_application_name, instance_management, cluster, link_to, final_link_to): action = action_creator.make_action( action_type, application_name=test_application_name, cluster_name=cluster, physical_name=link_to, ) audit_log = AuditLog.create(0, faker.ipv4(), action) db.close() if action_type == action_types.ASSIGN_CLUSTER_LINK: cluster_info = instance_management.get_cluster_info(cluster) cluster_info.set_link(link_to) cluster_info.save() else: instance, _ = instance_management.get_instance(link_to, 'key', resolve=False) instance.data = 'value' instance.save() r = client.put('/api/audit-rollback/%s/%s' % (test_application_name, audit_log.id), headers={'Authorization': admin_token}) assert_response_ok(r) cluster_info = instance_management.get_cluster_info(cluster) assert cluster_info.get_link() == final_link_to
def huskar_audit_log(action_type, **extra): if not switch.is_switched_on(SWITCH_ENABLE_AUDIT_LOG): yield return action = action_creator.make_action(action_type, **extra) yield try: if switch.is_switched_on(SWITCH_ENABLE_MINIMAL_MODE, False): action_name = action_types[action_type] fallback_audit_logger.info('arch.huskar_api %s %r', action_name, action.action_data) else: user = User.get_by_name('arch.huskar_api') user_id = user.id if user else 0 AuditLog.create(user_id, settings.LOCAL_REMOTE_ADDR, action) except AuditLogTooLongError: logger.info('Audit log is too long. %s arch.huskar_api', action_types[action_type]) return except AuditLogLostError: action_name = action_types[action_type] fallback_audit_logger.info('arch.huskar %s %r', action_name, action.action_data) except Exception: logger.exception('Unexpected error of audit log')
def unicode_action(application): extra = { 'application_name': application.application_name, 'cluster_name': 'bar', 'key': 'test', 'old_data': u'\u86e4', 'new_data': u'\u87c6', } return action_creator.make_action(action_types.UPDATE_CONFIG, **extra)
def large_action(request, application): extra = { 'application_name': application.application_name, 'cluster_name': 'stable', 'key': '169.254.0.1_5000', 'old_data': 'x' * request.param, 'new_data': 'y' * request.param, } return action_creator.make_action(action_types.UPDATE_SERVICE, **extra)
def wrapped(action_type, cluster, link=None): action = action_creator.make_action( action_type, application_name=test_application_name, cluster_name=cluster, physical_name=link) audit_log = AuditLog.create(0, faker.ipv4(), action) db.close() return audit_log
def wrapped(action_type, key, new_data, old_data): _, data_type = action_types[action_type].split('_', 1) path = zk_path(data_type.lower(), key) path_fragment = path.split('/') application_name, cluster_name = path_fragment[3:5] action = action_creator.make_action(action_type, application_name=application_name, cluster_name=cluster_name, key=key, old_data=old_data, new_data=new_data) audit_log = AuditLog.create(0, faker.ipv4(), action) db.close() return audit_log
def test_rollback_failed(client, db, faker, test_application_name, admin_token): fake_audit_id = int(faker.numerify()) action = action_creator.make_action(action_types.CREATE_CONFIG_CLUSTER, application_name=test_application_name, cluster_name='bar') audit_log = AuditLog.create(0, faker.ipv4(), action) db.close() r = client.put('/api/audit-rollback/%s/%s' % (test_application_name, fake_audit_id), headers={'Authorization': admin_token}) assert r.status_code == 404 assert r.json['status'] == 'NotFound' assert r.json['message'] == 'The audit log not existed.' r = client.put('/api/audit-rollback/%s/%s' % (test_application_name, audit_log.id), headers={'Authorization': admin_token}) assert r.status_code == 400 assert r.json['message'] == 'The audit log can\'t be rollbacked.'
def test_application_use_user_token_change_user_type( is_application, mocker, application, user, connect_new_action_detected): extra = { 'application_name': application.application_name, 'cluster_name': 'alta', 'key': 'b1b800dae3fca57fcb429615ff3e0a7054c59206640f1ef4dd30c12eccfdde43', 'new_data': { 'cluster': 'alta', 'ip': '192.168.1.2', 'meta': {'state': 'up'}, }, 'old_data': None, } if is_application: mocker.patch.object( settings, 'APPLICATION_USE_USER_TOKEN_USER_LIST', [user.username]) events = [] @connect_new_action_detected def test_event(sender, action_type, username, user_type, action_data, is_subscriable, severity): events.append([ action_type, username, user_type, action_data, is_subscriable, severity]) action = action_creator.make_action(action_types.UPDATE_SERVICE, **extra) AuditLog.create(user.id, '127.0.0.1', action) assert len(events) == 1 action_type, _, user_type, _, is_subscriable, severity = events[0] assert is_subscriable assert severity == SEVERITY_DANGEROUS if is_application: assert user_type == APPLICATION_USER else: assert user_type == NORMAL_USER assert action_type == action_types.UPDATE_SERVICE
def test_trace_all_application_events( mocker, application, user, monitor_client): extra = { 'application_name': application.application_name, 'cluster_name': 'alta', 'key': 'b1b800dae3fca57fcb429615ff3e0a7054c59206640f1ef4dd30c12eccfdde43', 'new_data': { 'cluster': 'alta', 'ip': '192.168.1.2', 'meta': {'state': 'up'}, }, 'old_data': None, } action = action_creator.make_action(action_types.UPDATE_SERVICE, **extra) AuditLog.create(user.id, '127.0.0.1', action) monitor_client.increment.assert_called_once_with( 'audit.application_event', tags={ 'action_name': 'UPDATE_SERVICE', 'application_name': application.application_name, })
def test_publish_new_action_with_low_severity( mocker, user, connect_new_action_detected): extra = { 'user': user, } events = [] @connect_new_action_detected def test_event(sender, action_type, username, user_type, action_data, is_subscriable, severity): events.append([ action_type, username, user_type, action_data, is_subscriable, severity]) action = action_creator.make_action( action_types.OBTAIN_USER_TOKEN, **extra) AuditLog.create(user.id, '127.0.0.1', action) assert len(events) == 1 action_type, _, user_type, _, is_subscriable, severity = events[0] assert not is_subscriable assert user_type == NORMAL_USER assert severity == SEVERITY_NORMAL assert action_type == action_types.OBTAIN_USER_TOKEN
def test_fix_create_action_value_error( mocker, application, user, connect_new_action_detected): extra = { 'application_name': 'foo.bar', 'cluster_name': 'alta', 'key': 'b1b800dae3fca57fcb429615ff3e0a7054c59206640f1ef4dd30c12eccfdde43', 'new_data': { 'cluster': 'alta', 'ip': '192.168.1.2', 'meta': {'state': 'up'}, }, 'old_data': None, } mocker.patch.object( Application, 'get_by_name', side_effect=[None, application]) events = [] @connect_new_action_detected def test_event(sender, action_type, username, user_type, action_data, is_subscriable, severity): events.append([ action_type, username, user_type, action_data, is_subscriable, severity]) action = action_creator.make_action(action_types.UPDATE_SERVICE, **extra) assert len(action.action_indices) == 1 assert len(action.action_indices[0]) == 4 AuditLog.create(user.id, '127.0.0.1', action) assert len(events) == 1 action_type, _, user_type, _, is_subscriable, severity = events[0] assert not is_subscriable assert severity == SEVERITY_DANGEROUS assert user_type == NORMAL_USER assert action_type == action_types.UPDATE_SERVICE
def test_rollback_infra_config_change(client, db, faker, test_application_name, admin_token, last_audit_log, _action_type, _scope_type, _scope_name, _old_value, _new_value, _expected_action_type, _expected_value): infra_type = 'redis' infra_name = 'default' infra_info = InfraInfo(huskar_client.client, test_application_name, infra_type) infra_info.load() action_type = getattr(action_types, _action_type) action = action_creator.make_action( action_type, application_name=test_application_name, infra_type=infra_type, infra_name=infra_name, scope_type=_scope_type, scope_name=_scope_name, old_value=_old_value, new_value=_new_value, ) audit_log = AuditLog.create(0, faker.ipv4(), action) db.close() r = client.put('/api/audit-rollback/%s/%s' % (test_application_name, audit_log.id), headers={'Authorization': admin_token}) assert_response_ok(r) last_audit = last_audit_log() infra_info.load() value = infra_info.get_by_name(infra_name, _scope_type, _scope_name) assert value == _expected_value assert last_audit.action_type == getattr(action_types, _expected_action_type)
def action(team): return action_creator.make_action(action_types.CREATE_TEAM, team=team)