def update_project_symbol_source(self, project: Project, allow_multiple: bool) -> json.JSONData: """Updates this configuration in the Project's symbol sources. If a symbol source of type ``appStoreConnect`` already exists the ID must match and it will be updated. If no ``appStoreConnect`` source exists yet it is added. :param allow_multiple: Whether multiple appStoreConnect sources are allowed for this project. :returns: The new value of the sources. Use this in a call to `ProjectEndpoint.create_audit_entry()` to create an audit log. :raises ValueError: if an ``appStoreConnect`` source already exists but the ID does not match """ with transaction.atomic(): all_sources_raw = project.get_option(SYMBOL_SOURCES_PROP_NAME) all_sources = json.loads( all_sources_raw) if all_sources_raw else [] for i, source in enumerate(all_sources): if source.get("type") == SYMBOL_SOURCE_TYPE_NAME: if source.get("id") == self.id: all_sources[i] = self.to_json() break elif not allow_multiple: raise ValueError( "Existing appStoreConnect symbolSource config does not match id" ) else: # No matching existing appStoreConnect symbol source, append it. all_sources.append(self.to_json()) project.update_option(SYMBOL_SOURCES_PROP_NAME, json.dumps(all_sources)) return all_sources
def index_event_tags(project_id, event_id, tags, **kwargs): from sentry.models import EventTag, Project, TagKey, TagValue for key, value in tags: tagkey, _ = TagKey.objects.get_or_create( project=Project(id=project_id), key=key, ) tagvalue, _ = TagValue.objects.get_or_create( project=Project(id=project_id), key=key, value=value, ) try: # handle replaying of this task with transaction.atomic(): EventTag.objects.create( project_id=project_id, event_id=event_id, key_id=tagkey.id, value_id=tagvalue.id, ) except IntegrityError: pass
def index_event_tags(organization_id, project_id, event_id, tags, group_id=None, **kwargs): from sentry.models import EventTag, Project, TagKey, TagValue Raven.tags_context({ 'project': project_id, }) for key, value in tags: tagkey, _ = TagKey.objects.get_or_create( project=Project(id=project_id), key=key, ) tagvalue, _ = TagValue.objects.get_or_create( project=Project(id=project_id, organization_id=organization_id), key=key, value=value, ) try: # handle replaying of this task with transaction.atomic(): EventTag.objects.create( project_id=project_id, group_id=group_id, event_id=event_id, key_id=tagkey.id, value_id=tagvalue.id, ) except IntegrityError: pass
def update_build_refresh_date(project: Project, config_id: str) -> None: serialized_option = project.get_option( appconnect.APPSTORECONNECT_BUILD_REFRESHES_OPTION, default="{}") build_refresh_dates = json.loads(serialized_option) build_refresh_dates[config_id] = datetime.now() serialized_refresh_dates = json.dumps_htmlsafe(build_refresh_dates) project.update_option(appconnect.APPSTORECONNECT_BUILD_REFRESHES_OPTION, serialized_refresh_dates)
def new_event(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', level=logging.ERROR, ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) rule = Rule(label="An example rule") interface_list = [] for interface in event.interfaces.itervalues(): body = interface.to_email_html(event) if not body: continue interface_list.append((interface.get_title(), mark_safe(body))) preview = MailPreview( html_template='sentry/emails/error.html', text_template='sentry/emails/error.html', context={ 'rule': rule, 'group': group, 'event': event, 'link': 'http://example.com/link', 'interfaces': interface_list, 'tags': event.get_tags(), 'project_label': project.name, }, ) return render_to_response('sentry/debug/mail/preview.html', { 'preview': preview, })
def get(self, request): org = Organization(id=1, slug="organization", name="My Company") project = Project(id=1, organization=org, slug="project", name="My Project") group = next(make_group_generator(get_random(request), project)) data = dict(load_data("python")) data["message"] = group.message data.pop("logentry", None) event_manager = EventManager(data) event_manager.normalize() data = event_manager.get_data() event_type = event_manager.get_event_type() event = eventstore.create_event( event_id="a" * 32, group_id=group.id, project_id=project.id, data=data.data ) group.message = event.search_message group.data = {"type": event_type.key, "metadata": event_type.get_metadata(data)} activity = Activity(group=group, project=event.project, **self.get_activity(request, event)) return render_to_response( "sentry/debug/mail/preview.html", context={ "preview": ActivityMailPreview(request, activity), "format": request.GET.get("format"), }, )
def test_notify_users_does_email(self, _send_mail): project = Project(id=1, name='Project Name') group = Group() group.first_seen = timezone.now() group.last_seen = group.first_seen group.project = project group.id = 2 event = Event() event.group = group event.message = 'hello world' event.logger = 'root' event.project = project event.date = group.last_seen with self.Settings(SENTRY_URL_PREFIX='http://example.com'): p = MailProcessor(send_to=['*****@*****.**']) p.notify_users(group, event) _send_mail.assert_called_once() args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get('fail_silently'), False) self.assertEquals(kwargs.get('project'), project) self.assertEquals(kwargs.get('subject'), u"[Project Name] ERROR: hello world")
def test_should_notify_excluded(self): p = MailProcessor(min_level=None, exclude_loggers=['root']) group = Mock(spec=Group) group.project = Project() group.level = 5 group.logger = 'root' self.assertFalse(p.should_notify(group=group, event=Mock()))
def test_process_saves_data(self): group = Group.objects.create(project=Project(id=1)) columns = {"times_seen": 1} filters = {"id": group.id, "project_id": 1} self.buf.process(Group, columns, filters) assert Group.objects.get( id=group.id).times_seen == group.times_seen + 1
def test_process_saves_data(self): group = Group.objects.create(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buf.process(Group, columns, filters) assert Group.objects.get( pk=group.pk).times_seen == group.times_seen + 1
def test_process_does_save_call_with_results(self, process): group = Group.objects.create(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buf.conn.set('foo', 2) self.buf.process(Group, columns, filters) process.assert_called_once_with(Group, {'times_seen': 2}, filters, None)
def get(self, request: Request) -> Response: organization = Organization(slug="myorg") project = Project(slug="myproject", organization=organization) query = SnubaQuery( time_window=60, query="transaction:/some/transaction", aggregate="count()" ) alert_rule = AlertRule(id=1, organization=organization, name="My Alert", snuba_query=query) incident = Incident( id=2, identifier=123, organization=organization, title="Something broke", alert_rule=alert_rule, status=IncidentStatus.CRITICAL, ) trigger = AlertRuleTrigger(alert_rule=alert_rule) context = generate_incident_trigger_email_context( project, incident, trigger, TriggerStatus.ACTIVE ) return MailPreview( text_template="sentry/emails/incidents/trigger.txt", html_template="sentry/emails/incidents/trigger.html", context=context, ).render(request)
def get(self, request): org = Organization(id=1, slug="organization", name="My Company") project = Project(id=1, organization=org, slug="project", name="My Project") event = create_sample_event( project=project, platform="python", event_id="595", timestamp=1452683305 ) group = event.group link = absolute_uri( f"/{project.organization.slug}/{project.slug}/issues/{group.id}/feedback/" ) return MailPreview( html_template="sentry/emails/activity/new-user-feedback.html", text_template="sentry/emails/activity/new-user-feedback.txt", context={ "group": group, "report": { "name": "Homer Simpson", "email": "*****@*****.**", "comments": "I hit a bug.\n\nI went to https://example.com, hit the any key, and then it stopped working. DOH!", }, "link": link, "reason": "are subscribed to this issue", "enhanced_privacy": False, }, ).render(request)
def test_process_does_clear_buffer(self, process): group = Group.objects.create(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buf.conn.set('foo', 2) self.buf.process(Group, columns, filters) self.assertEquals(self.buf.conn.get('foo'), '0')
def get(self, request: Request) -> Response: from sentry.notifications.utils import summarize_issues org = Organization(id=1, slug="organization", name="My Company") project = Project(id=1, organization=org, slug="project", name="My Project") return MailPreview( html_template="sentry/emails/activity/new_processing_issues.html", text_template="sentry/emails/activity/new_processing_issues.txt", context={ "project": project, "reason": GroupSubscriptionReason.descriptions[ GroupSubscriptionReason.processing_issue], "issues": summarize_issues(get_issues_data()), "reprocessing_active": self.reprocessing_active, "info_url": absolute_uri( f"/settings/{org.slug}/projects/{project.slug}/processing-issues/" ), }, ).render(request)
def test_process_does_save_call_with_results(self, process): group = Group(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buffer._tnt.insert(self.sentry_space, ('foo', 2, 0L)) self.buffer.process(Group, columns, filters) process.assert_called_once_with(Group, {'times_seen': 2}, filters, None)
def test_process_does_clear_buffer(self, process): group = Group(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} self.buffer._tnt.insert(self.sentry_space, ('foo', 2, 0L)) self.buffer.process(Group, columns, filters) response = self.buffer._tnt.select(self.sentry_space, ['foo']) self.assertEquals(int(response[0][1]), 0)
def loaddata(): with open('initial_data.json') as data_file: structure = json.load(data_file) organization = Organization.objects.get(pk=1) for record in structure: try: team = Team.objects.get(name=record['team'], organization=organization) except ObjectDoesNotExist: team = Team() team.name = record['team'] team.organization = organization team.save() try: project = Project.objects.get(name=record['project'], team=team, organization=organization) except ObjectDoesNotExist: project = Project() project.team = team project.name = record['project'] project.organization = organization project.save() key = ProjectKey.objects.filter(project=project)[0] if 'key' in record: parts = record['key'].split(':') key.public_key = parts[0] if len(parts) > 1: key.secret_key = parts[1] key.save() print 'PROJECT_NAME = "%s"' % (project.name, ) print 'SENTRY_DSN = "%s"' % (key.get_dsn(), ) print ''
def all_for_project(cls, project: Project) -> "List[AppStoreConnectConfig]": sources = [] raw = project.get_option(SYMBOL_SOURCES_PROP_NAME, default="[]") all_sources = json.loads(raw) for source in all_sources: if source.get("type") == SYMBOL_SOURCE_TYPE_NAME: sources.append(cls.from_json(source)) return sources
def disabled_users_from_project(self, project: Project) -> Set[User]: """ Get a set of users that have disabled Issue Alert notifications for a given project. """ alert_settings = project.get_member_alert_settings( self.alert_option_key) disabled_users = { user for user, setting in alert_settings.items() if setting == 0 } return disabled_users
def test_signal_only(self, create_or_update): group = Group.objects.create(project=Project(id=1)) columns = {"times_seen": 1} filters = {"id": group.id, "project_id": 1} the_date = timezone.now() + timedelta(days=5) prev_times_seen = group.times_seen self.buf.process(Group, columns, filters, {"last_seen": the_date}, signal_only=True) group.refresh_from_db() assert group.times_seen == prev_times_seen
def test_process_saves_extra(self): group = Group.objects.create(project=Project(id=1)) columns = {"times_seen": 1} filters = {"id": group.id, "project_id": 1} the_date = timezone.now() + timedelta(days=5) self.buf.process(Group, columns, filters, {"last_seen": the_date}) group_ = Group.objects.get(id=group.id) assert group_.times_seen == group.times_seen + 1 assert group_.last_seen == the_date
def test_process_saves_extra(self): group = Group.objects.create(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} the_date = (timezone.now() + timedelta(days=5)).replace(microsecond=0) self.buf.conn.set('foo', 1) self.buf.conn.hset('extra', 'last_seen', pickle.dumps(the_date)) self.buf.process(Group, columns, filters) group_ = Group.objects.get(pk=group.pk) self.assertEquals(group_.last_seen.replace(microsecond=0), the_date)
def create_event(data, group_id=123): mgr = EventManager(data=data, grouping_config=get_default_grouping_config_dict()) mgr.normalize() data = mgr.get_data() evt = eventstore.create_event(data=data) evt.project = project = Project(id=123) evt.group = Group(id=group_id, project=project) return evt
def all_config_ids(project: Project) -> List[str]: """Return the config IDs of all appStoreConnect symbol sources configured in the project.""" raw = project.get_option(SYMBOL_SOURCES_PROP_NAME) if not raw: raw = "[]" all_sources = json.loads(raw) return [ s.get("id") for s in all_sources if s.get("type") == SYMBOL_SOURCE_TYPE_NAME and s.get("id") ]
def test_process_saves_extra(self): group = Group.objects.create(project=Project(id=1)) columns = {'times_seen': 1} filters = {'pk': group.pk} # strip micrseconds because MySQL doesnt seem to handle them correctly the_date = (timezone.now() + timedelta(days=5)).replace(microsecond=0) self.buf.process(Group, columns, filters, {'last_seen': the_date}) group_ = Group.objects.get(pk=group.pk) assert group_.times_seen == group.times_seen + 1 assert group_.last_seen.replace(microsecond=0) == the_date
def get(self, request): org = Organization( id=1, slug='organization', name='My Company', ) project = Project( id=1, organization=org, slug='project', name='My Project', ) group = next(make_group_generator( get_random(request), project, ), ) data = dict(load_data('python')) data['message'] = group.message data.pop('logentry', None) event_manager = EventManager(data) event_manager.normalize() data = event_manager.get_data() event_type = event_manager.get_event_type() group.message = event_manager.get_search_message() group.data = { 'type': event_type.key, 'metadata': event_type.get_metadata(data), } event = Event(id=1, project=project, message=event_manager.get_search_message(), group=group, datetime=datetime(2016, 6, 13, 3, 8, 24, tzinfo=timezone.utc), data=event_manager.get_data()) activity = Activity(group=event.group, project=event.project, **self.get_activity(request, event)) return render_to_response( 'sentry/debug/mail/preview.html', { 'preview': ActivityMailPreview(request, activity), 'format': request.GET.get('format'), })
def new_note(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) note = Activity( group=event.group, event=event, project=event.project, type=Activity.NOTE, user=request.user, data={'text': 'This is an example note!'}, ) preview = MailPreview( html_template='sentry/emails/activity/note.html', text_template='sentry/emails/activity/note.txt', context={ 'data': note.data, 'author': note.user, 'date': note.datetime, 'group': group, 'link': group.get_absolute_url(), }, ) return render_to_response('sentry/debug/mail/preview.html', { 'preview': preview, })
def get(self, request): from sentry.plugins.sentry_mail.activity.new_processing_issues import summarize_issues org = Organization(id=1, slug='organization', name='My Company') project = Project( id=1, organization=org, slug='project', name='My Project', ) return MailPreview( html_template='sentry/emails/activity/new_processing_issues.html', text_template='sentry/emails/activity/new_processing_issues.txt', context={ 'project': project, 'reason': GroupSubscriptionReason.descriptions[ GroupSubscriptionReason.processing_issue], 'issues': summarize_issues([ { 'data': { 'image_arch': 'arm64', 'image_path': '/var/containers/Bundle/Application/FB14D416-DE4E-4224-9789-6B88E9C42601/CrashProbeiOS.app/CrashProbeiOS', 'image_uuid': 'a2df1794-e0c7-371c-baa4-93eac340a78a' }, 'object': 'dsym:a2df1794-e0c7-371c-baa4-93eac340a78a', 'scope': 'native', 'type': 'native_missing_dsym' }, { 'data': { 'image_arch': 'arm64', 'image_path': '/var/containers/Bundle/Application/FB14D416-DE4E-4224-9789-6B88E9C42601/CrashProbeiOS.app/libCrashProbeiOS', 'image_uuid': '12dc1b4c-a01b-463f-ae88-5cf0c31ae680' }, 'object': 'dsym:12dc1b4c-a01b-463f-ae88-5cf0c31ae680', 'scope': 'native', 'type': 'native_bad_dsym' }, ]), 'reprocessing_active': self.reprocessing_active, 'info_url': absolute_uri( '/settings/{}/projects/{}/processing-issues/'.format( org.slug, project.slug, )), }, ).render(request)
def assigned(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) assigned = Activity( group=event.group, project=event.project, type=Activity.ASSIGNED, user=request.user, data={ 'text': 'This is an example note!', 'assignee': '*****@*****.**' }, ) return MailPreview( html_template='sentry/emails/activity/assigned.html', text_template='sentry/emails/activity/assigned.txt', context={ 'data': assigned.data, 'author': assigned.user, 'date': assigned.datetime, 'group': group, 'link': group.get_absolute_url(), }, ).render()
# Bootstrap the Sentry environment from sentry.utils.runner import configure # YOU MUST COPY THE SETTINGS FILE TO /root/.sentry/sentry.conf.py configure() # Do something crazy from sentry.models import Team, Project, ProjectKey, User user = User.objects.get(username="******") team = Team() team.name = 'Sentry' team.owner = user team.save() project = Project() project.team = team project.owner = user project.name = 'Default' project.save() key = ProjectKey.objects.filter(project=project)[0] print '%s' % (key.get_dsn(),)
# Bootstrap the Sentry environment from sentry.utils.runner import configure configure() # Do something crazy from sentry.models import Team, Project, ProjectKey, User user = User() user.username = '******' user.email = 'admin@localhost' user.is_superuser = True user.set_password('admin') user.save() team = Team() team.name = 'Sentry' team.owner = user team.save() project = Project() project.team = team project.owner = user project.name = 'Test' project.save() key = ProjectKey.objects.filter(project=project)[0] print 'SENTRY_DSN = "%s"' % (key.get_dsn(),)
if Organization.objects.filter(name=name).count() == 0: organization = Organization() organization.name = name organization.save() om = OrganizationMember() om.organization = organization om.role = 'owner' om.user = user om.save() team = Team() team.name = name team.organization = organization team.save() project = Project() project.team = team project.name = name2 project.organization = organization project.save() else: organization = Organization.objects.filter(name=name).all()[0] team = Team.objects.filter(name=name, organization=organization).all()[0] project =Project.objects.filter(team=team, name=name2, organization=organization).all()[0] key = ProjectKey.objects.filter(project=project)[0] dsn = key.get_dsn() print(dsn)
# Do something crazy from sentry.models import Team, Project, ProjectKey, User, Organization user = User.objects.get(pk=1) organization = Organization() organization.name = 'AgoraVoting' organization.owner = user organization.save() team = Team() team.name = 'AgoraVoting' team.organization = organization team.save() project = Project() project.team = team project.name = 'AuthApi' project.organization = organization project.save() key = ProjectKey.objects.filter(project=project)[0] dsn = key.get_dsn() # writting the sentry configuration to deploy.conf authapi_conf = ''' # sentry RAVEN_CONFIG = { 'dsn': '%s', } INSTALLED_APPS = INSTALLED_APPS + (
from sentry.models import Team, Project, ProjectKey, User, Organization user = User() user.username = '******' user.email = 'admin@localhost' user.is_superuser = True user.set_password('admin') user.save() organization = Organization() organization.name = 'MyOrg' organization.owner = user organization.save() team = Team() team.name = 'Sentry' team.organization = organization team.owner = user team.save() project = Project() project.team = team project.name = 'Default' project.organization = organization project.save() f = open('dsn', 'wb') key = ProjectKey.objects.filter(project=project)[0] f.write(key.get_dsn()) f.close()
if not User.objects.filter(username='******').exists(): user = User() user.username = '******' user.email = '*****@*****.**' user.is_superuser = True user.set_password('admin') user.save() organization = Organization.objects.filter(slug='sentry')[0] team = Team() team.name = 'COD' team.organization = organization team.save() project = Project() project.team = team project.add_team(team) project.name = 'Cern Open Data Portal' project.organization = organization project.save() ProjectKey.objects.get(project=project).delete() public_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' secret_key = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' key = ProjectKey.objects.create(project=project, public_key=public_key, secret_key=secret_key, roles=1) member = OrganizationMember.objects.create(
user.is_superuser = True user.set_password('{{sentry.bootstrap.password}}') user.save() organization = Organization() organization.name = '{{sentry.bootstrap.organization}}' organization.owner = user organization.save() team = Team() team.organization = organization team.name = '{{sentry.bootstrap.team}}' team.owner = user team.save() project = Project() project.organization = organization project.team = team project.owner = user project.name = '{{sentry.bootstrap.project}}' project.save() #let's replace the key key = ProjectKey.objects.filter(project=project)[0] key.public_key = '{{sentry.bootstrap.public_key}}' key.secret_key = '{{sentry.bootstrap.secret_key}}' key.save() print 'SENTRY_DSN = "%s"' % (key.get_dsn(),) with open('/srv/sentry/application/shared/bootstrap_project', 'w') as f: f.write(key.get_dsn())