Esempio n. 1
0
from sentry.integrations.vsts.issues import VstsIssueSync
from sentry.pipeline import NestedPipelineView
from sentry.identity.pipeline import IdentityProviderPipeline
from sentry.identity.vsts import VSTSIdentityProvider
from sentry.utils.http import absolute_uri
from .client import VstsApiClient
from .repository import VstsRepositoryProvider
DESCRIPTION = """
VSTS
"""

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    author='The Sentry Team',
    noun=_('Account'),
    issue_url=
    'https://github.com/getsentry/sentry/issues/new?title=VSTS%20Integration:%20&labels=Component%3A%20Integrations',
    source_url=
    'https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/vsts',
    aspects={},
)


class VstsIntegration(Integration, VstsIssueSync):
    def __init__(self, *args, **kwargs):
        super(VstsIntegration, self).__init__(*args, **kwargs)
        self.default_identity = None

    def get_client(self):
        if self.default_identity is None:
            self.default_identity = self.get_default_identity()
Esempio n. 2
0
from .client import JiraApiClient


alert_link = {
    'text': 'Visit the **Atlassian Marketplace** to install this integration.',
    # TODO(jess): update this when we have our app listed on the
    # atlassian marketplace
    'link': 'https://marketplace.atlassian.com/',
}

metadata = IntegrationMetadata(
    description='Sync Sentry and JIRA issues.',
    author='The Sentry Team',
    noun=_('Instance'),
    issue_url='https://github.com/getsentry/sentry/issues/new?title=JIRA%20Integration:%20&labels=Component%3A%20Integrations',
    source_url='https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/jira',
    aspects={
        'alert_link': alert_link,
    },
)

# A list of common builtin custom field types for JIRA for easy reference.
JIRA_CUSTOM_FIELD_TYPES = {
    'select': 'com.atlassian.jira.plugin.system.customfieldtypes:select',
    'textarea': 'com.atlassian.jira.plugin.system.customfieldtypes:textarea',
    'multiuserpicker': 'com.atlassian.jira.plugin.system.customfieldtypes:multiuserpicker',
    'tempo_account': 'com.tempoplugin.tempo-accounts:accounts.customfield'
}


class JiraIntegration(Integration, IssueSyncMixin):
Esempio n. 3
0
            pipeline.bind_state('name', request.POST['name'])
            return pipeline.next_step()

        return HttpResponse(self.TEMPLATE)


DESCRIPTION = """
This is an example integration

 * Descriptions support _markdown rendering_.
"""

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    author='The Sentry Team',
    noun='example',
    issue_url='https://github.com/getsentry/sentry/issues/new',
    source_url='https://github.com/getsentry/sentry',
    aspects={},
)


class ExampleIntegration(Integration, IssueSyncMixin):
    def create_comment(self):
        pass

    def get_link_issue_config(self, group, **kwargs):
        return [{
            'name': 'externalIssue',
            'label': 'Issue',
            'default': '',
            'type': 'string',
Esempio n. 4
0
        IntegrationFeatures.ISSUE_BASIC,
    ),
    FeatureDescription(
        """
        Link Sentry issues to existing Bitbucket issues
        """,
        IntegrationFeatures.ISSUE_BASIC,
    ),
]

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author='The Sentry Team',
    noun=_('Installation'),
    issue_url=
    'https://github.com/getsentry/sentry/issues/new?title=Bitbucket%20Integration:%20&labels=Component%3A%20Integrations',
    source_url=
    'https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/bitbucket',
    aspects={},
)
# see https://developer.atlassian.com/bitbucket/api/2/reference/meta/authentication#scopes-bbc
scopes = (
    'issue:write',
    'pullrequest',
    'webhook',
)


class BitbucketIntegration(IntegrationInstallation, BitbucketIssueBasicMixin,
                           RepositoryMixin):
Esempio n. 5
0
    ),
]

setup_alert = {
    'type':
    'info',
    'text':
    'The Pagerduty integration adds a new Alert Rule action to all projects. To enable automatic alerts sent to Pagerduty you must create a rule using the pagerduty account action in your project settings.',
}

metadata = IntegrationMetadata(
    description=_(DESCRIPTION.strip()),
    features=FEATURES,
    author='Kumarappan Arumugam',
    noun=_('Installation'),
    issue_url=
    'https://github.com/kumarappan-arumugam/sentry-pagerduty/issues/new?title=Pagerduty%20Integration:%20&labels=Component%3A%20Integrations',
    source_url=
    'https://github.com/kumarappan-arumugam/sentry-pagerduty/tree/master/sentry_pagerduty',
    aspects={
        'alerts': [setup_alert],
    })


class InstallationForm(forms.Form):
    service_name = forms.CharField(
        label="Provide a name of the pagerduty service for the integration",
        # choices=[],
        help_text=
        _('It will be easier to idenify the integration on the alert rules page with the name.'
          ),
        widget=forms.TextInput(
Esempio n. 6
0
Visit the Jira Marketplace to install this integration. After installing the
Sentry add-on, access the settings panel in your Jira instance to enable the
integration for this Organization.
"""

external_install = {
    "url": "https://marketplace.atlassian.com/apps/1219432/sentry-for-jira",
    "buttonText": _("Jira Marketplace"),
    "noticeText": _(INSTALL_NOTICE_TEXT.strip()),
}

metadata = IntegrationMetadata(
    description=_(DESCRIPTION.strip()),
    features=FEATURE_DESCRIPTIONS,
    author="The Sentry Team",
    noun=_("Instance"),
    issue_url="https://github.com/getsentry/sentry/issues/new?assignees=&labels=Component:%20Integrations&template=bug_report.md&title=Jira%20Integration%20Problem",
    source_url="https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/jira",
    aspects={"externalInstall": external_install},
)

# Hide linked issues fields because we don't have the necessary UI for fully specifying
# a valid link (e.g. "is blocked by ISSUE-1").
HIDDEN_ISSUE_FIELDS = ["issuelinks"]

# A list of common builtin custom field types for Jira for easy reference.
JIRA_CUSTOM_FIELD_TYPES = {
    "select": "com.atlassian.jira.plugin.system.customfieldtypes:select",
    "textarea": "com.atlassian.jira.plugin.system.customfieldtypes:textarea",
    "multiuserpicker": "com.atlassian.jira.plugin.system.customfieldtypes:multiuserpicker",
    "tempo_account": "com.tempoplugin.tempo-accounts:accounts.customfield",
Esempio n. 7
0
Sentry add-on, access the settings panel in your Jira instance to enable the
integration for this Organization.
"""

external_install = {
    'url': 'https://marketplace.atlassian.com/apps/1219432/sentry-for-jira',
    'buttonText': _('Jira Marketplace'),
    'noticeText': _(INSTALL_NOTICE_TEXT.strip()),
}

metadata = IntegrationMetadata(
    description=_(DESCRIPTION.strip()),
    features=FEATURE_DESCRIPTIONS,
    author='The Sentry Team',
    noun=_('Instance'),
    issue_url='https://github.com/getsentry/sentry/issues/new?title=Jira%20Integration:%20&labels=Component%3A%20Integrations',
    source_url='https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/jira',
    aspects={
        'externalInstall': external_install,
    },
)

# hide sprint, epic link, parent and linked issues fields because they don't work
# since sprint and epic link are "custom" we need to search for them by name
HIDDEN_ISSUE_FIELDS = {
    'keys': ['parent', 'issuelinks'],
    'names': ['Sprint', 'Epic Link'],
}

# A list of common builtin custom field types for Jira for easy reference.
JIRA_CUSTOM_FIELD_TYPES = {
Esempio n. 8
0
    'icon-warning-sm',
    'text':
    'Your GitHub enterprise instance must be able to communicate with'
    ' Sentry. Sentry makes outbound requests from a [static set of IP'
    ' addresses](https://docs.sentry.io/ip-ranges/) that you may wish'
    ' to whitelist to support this integration.',
}

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author='The Sentry Team',
    noun=_('Installation'),
    issue_url=
    'https://github.com/getsentry/sentry/issues/new?title=GitHub%20Integration:%20&labels=Component%3A%20Integrations',
    source_url=
    'https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/github_enterprise',
    aspects={
        'disable_dialog': disable_dialog,
        'removal_dialog': removal_dialog,
        'alerts': [setup_alert],
    },
)

API_ERRORS = {
    404: 'GitHub Enterprise returned a 404 Not Found error.',
    401: ERR_UNAUTHORIZED,
}


class GitHubEnterpriseIntegration(IntegrationInstallation, GitHubIssueBasic,
Esempio n. 9
0
external_install = {
    "url":
    "https://teams.microsoft.com/l/app/{}".format(
        options.get("msteams.app-id")),
    "buttonText":
    _("Teams Marketplace"),
    "noticeText":
    _(INSTALL_NOTICE_TEXT),
}

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url=
    "https://github.com/getsentry/sentry/issues/new?title=Microsoft%20Teams%20Integration:%20&labels=Component%3A%20Integrations",
    source_url=
    "https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/msteams",
    aspects={"externalInstall": external_install},
)


class MsTeamsIntegration(IntegrationInstallation):
    pass


class MsTeamsIntegrationProvider(IntegrationProvider):
    key = "msteams"
    name = "Microsoft Teams"
    can_add = False
Esempio n. 10
0
    "warning",
    "icon":
    "icon-warning-sm",
    "text":
    "Your Jira instance must be able to communicate with Sentry."
    " Sentry makes outbound requests from a [static set of IP"
    " addresses](https://docs.sentry.io/ip-ranges/) that you may wish"
    " to allow in your firewall to support this integration.",
}

metadata = IntegrationMetadata(
    description=_(DESCRIPTION.strip()),
    features=FEATURE_DESCRIPTIONS,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url=
    "https://github.com/getsentry/sentry/issues/new?assignees=&labels=Component:%20Integrations&template=bug.yml&title=Jira%20Server%20Integration%20Problem",
    source_url=
    "https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/jira_server",
    aspects={"alerts": [setup_alert]},
)


class InstallationForm(forms.Form):
    url = forms.CharField(
        label=_("Jira URL"),
        help_text=
        _("The base URL for your Jira Server instance, including the host and protocol."
          ),
        widget=forms.TextInput(
            attrs={"placeholder": "https://jira.example.com"}),
Esempio n. 11
0
DESCRIPTION = """
This is an example integration. Descriptions support _markdown rendering_.
"""

FEATURES = [
    FeatureDescription(
        "This is a feature description. Also *supports markdown*",
        IntegrationFeatures.ISSUE_SYNC)
]

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun="example",
    issue_url="https://github.com/getsentry/sentry/issues/new",
    source_url="https://github.com/getsentry/sentry",
    aspects={},
)


class ExampleIntegration(IntegrationInstallation, IssueSyncMixin):
    comment_key = "sync_comments"
    outbound_status_key = "sync_status_outbound"
    inbound_status_key = "sync_status_inbound"
    outbound_assignee_key = "sync_assignee_outbound"
    inbound_assignee_key = "sync_assignee_inbound"

    def get_issue_url(self, key):
        return u"https://example/issues/{}".format(key)
Esempio n. 12
0
 * Configure rule based Slack notifications to automatically be posted into the
   specified channel.
"""

alert_link = {
    'text':
    'Looking to send Sentry alerts to Slack? Add an **Alert Rule** to a project.',
    'link': '/settings/:orgId/:projectId/alerts/rules/'
}

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    author='The Sentry Team',
    noun=_('Workspace'),
    issue_url=
    'https://github.com/getsentry/sentry/issues/new?title=Slack%20Integration:%20&labels=Component%3A%20Integrations',
    source_url=
    'https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/slack',
    aspects={
        'alert_link': alert_link,
    })


class SlackIntegrationProvider(IntegrationProvider):
    key = 'slack'
    name = 'Slack'
    metadata = metadata

    identity_oauth_scopes = frozenset([
        'channels:read',
        'groups:read',
Esempio n. 13
0
DESCRIPTION = """
This is an example integration. Descriptions support _markdown rendering_.
"""

FEATURES = [
    FeatureDescription(
        "This is a feature description. Also *supports markdown*",
        IntegrationFeatures.ISSUE_SYNC)
]

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun="example",
    issue_url=
    "https://github.com/getsentry/sentry/issues/new?assignees=&labels=Component:%20Integrations&template=bug_report.md&title=Integration%20Problem",
    source_url="https://github.com/getsentry/sentry",
    aspects={},
)


class ExampleIntegration(IntegrationInstallation, IssueSyncMixin):
    comment_key = "sync_comments"
    outbound_status_key = "sync_status_outbound"
    inbound_status_key = "sync_status_inbound"
    outbound_assignee_key = "sync_assignee_outbound"
    inbound_assignee_key = "sync_assignee_inbound"

    def get_issue_url(self, key):
        return f"https://example/issues/{key}"
Esempio n. 14
0
]

setup_alert = {
    "type": "warning",
    "icon": "icon-warning-sm",
    "text": "Your Bitbucket Server instance must be able to communicate with Sentry."
    " Sentry makes outbound requests from a [static set of IP"
    " addresses](https://docs.sentry.io/ip-ranges/) that you may wish"
    " to explicitly allow in your firewall to support this integration.",
}

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url="https://github.com/getsentry/sentry/issues/new?assignees=&labels=Component:%20Integrations&template=bug_report.md&title=Bitbucket%Server%20Integration%20Problem",
    source_url="https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/bitbucket_server",
    aspects={},
)


class InstallationForm(forms.Form):
    url = forms.CharField(
        label=_("Bitbucket URL"),
        help_text=_(
            "The base URL for your Bitbucket Server instance, including the host and protocol."
        ),
        widget=forms.TextInput(attrs={"placeholder": "https://bitbucket.example.com"}),
        validators=[URLValidator()],
    )
Esempio n. 15
0
from sentry.utils.http import absolute_uri
from sentry.integrations.github.integration import GitHubIntegrationProvider
from sentry.integrations.github.utils import get_jwt

from .repository import GitHubEnterpriseRepositoryProvider
from .client import GitHubEnterpriseAppsClient

DESCRIPTION = """
    Fill me out (Enterprise)
"""

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    author='The Sentry Team',
    noun=_('Installation'),
    issue_url=
    'https://github.com/getsentry/sentry/issues/new?title=GitHub%20Integration:%20&labels=Component%3A%20Integrations',
    source_url=
    'https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/github_enterprise',
    aspects={})

API_ERRORS = {
    404: 'GitHub Enterprise returned a 404 Not Found error.',
    401: ERR_UNAUTHORIZED,
}


class GitHubEnterpriseIntegration(Integration, RepositoryMixin):
    def get_client(self):
        return GitHubEnterpriseAppsClient(
            base_url=self.model.metadata['domain_name'],
Esempio n. 16
0
    'icon':
    'icon-warning-sm',
    'text':
    'Your Jira instance must be able to communicate with Sentry.'
    ' Sentry makes outbound requests from a [static set of IP'
    ' addresses](https://docs.sentry.io/ip-ranges/) that you may wish'
    ' to whitelist to support this integration.',
}

metadata = IntegrationMetadata(
    description=_(DESCRIPTION.strip()),
    features=FEATURE_DESCRIPTIONS,
    author='The Sentry Team',
    noun=_('Installation'),
    issue_url=
    'https://github.com/getsentry/sentry/issues/new?title=Jira%20Server%20Integration:%20&labels=Component%3A%20Integrations',
    source_url=
    'https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/jira_server',
    aspects={
        'alerts': [setup_alert],
    },
)


class InstallationForm(forms.Form):
    url = forms.CharField(
        label=_('Jira URL'),
        help_text=
        _('The base URL for your Jira Server instance, including the host and protocol.'
          ),
        widget=forms.TextInput(
Esempio n. 17
0
    ),
]

setup_alert = {
    "type":
    "info",
    "text":
    "The Slack integration adds a new Alert Rule action to all projects. To enable automatic notifications sent to Slack you must create a rule using the slack workspace action in your project settings.",
}

metadata = IntegrationMetadata(
    description=_(DESCRIPTION.strip()),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Workspace"),
    issue_url=
    "https://github.com/getsentry/sentry/issues/new?title=Slack%20Integration:%20&labels=Component%3A%20Integrations",
    source_url=
    "https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/slack",
    aspects={"alerts": [setup_alert]},
)


class SlackIntegrationProvider(IntegrationProvider):
    key = "slack"
    name = "Slack"
    metadata = metadata
    features = frozenset([
        IntegrationFeatures.ACTION_NOTIFICATION,
        IntegrationFeatures.CHAT_UNFURL,
        IntegrationFeatures.ALERT_RULE,
Esempio n. 18
0
    "noticeText": _(INSTALL_NOTICE_TEXT),
}

configure_integration = {"title": _("Connect Your Projects")}
create_project_instruction = _(
    "Don't have a project yet? Click [here]({}) to create one.")
install_source_code_integration = _(
    "Install a [source code integration]({}) and configure your repositories.")

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url=
    "https://github.com/getsentry/sentry/issues/new?assignees=&labels=Component:%20Integrations&template=bug.yml&title=Vercel%20Integration%20Problem",
    source_url=
    "https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/vercel",
    aspects={
        "externalInstall": external_install,
        "configure_integration": configure_integration,
    },
)

internal_integration_overview = (
    "This internal integration was auto-generated during the installation process of your Vercel"
    " integration. It is needed to provide the token used to create a release. If this integration is "
    "deleted, your Vercel integration will stop working!")


class VercelIntegration(IntegrationInstallation):
    @property
Esempio n. 19
0
disable_dialog = {
    "actionText":
    _("Visit Vercel"),
    "body":
    _("In order to uninstall this integration, you must go"
      " to Vercel and uninstall there by clicking 'Remove Configuration'."),
}

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url=
    "https://github.com/getsentry/sentry/issues/new?title=Vercel%20Integration:%20&labels=Component%3A%20Integrations",
    source_url=
    "https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/vercel",
    aspects={
        "externalInstall": external_install,
        "configure_integration": configure_integration,
        "disable_dialog": disable_dialog,
    },
)

internal_integration_overview = (
    "This internal integration was auto-generated during the installation process of your Vercel"
    " integration. It is needed to provide the token used to create a release. If this integration is "
    "deleted, your Vercel integration will stop working!")


class VercelIntegration(IntegrationInstallation):
Esempio n. 20
0
from sentry.utils.http import absolute_uri

DESCRIPTION = """
Define a relationship between Sentry and your Slack workspace(s).

 * Unfurls Sentry URLs in slack, providing context and actionability on issues
   directly within your Slack workspace.
 * Resolve, ignore, and assign issues with minimal context switching.
 * Configure rule based Slack notifications to automatically be posted into the
   specified channel.
"""

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    author='The Sentry Team',
    issue_url=
    'https://github.com/getsentry/sentry/issues/new?title=Slack%20Integration:%20&labels=Component%3A%20Integrations',
    source_url=
    'https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/slack'
)


class SlackIntegration(Integration):
    key = 'slack'
    name = 'Slack'
    metadata = metadata

    identity_oauth_scopes = frozenset([
        'bot',
        'channels:read',
        'chat:write:bot',
        'commands',
Esempio n. 21
0
        """,
        IntegrationFeatures.ISSUE_BASIC,
    ),
    FeatureDescription(
        """
        Link Sentry issues to existing GitLab issues
        """,
        IntegrationFeatures.ISSUE_BASIC,
    ),
]

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url="https://github.com/getsentry/sentry/issues/",
    source_url="https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/gitlab",
    aspects={},
)


class GitlabIntegration(IntegrationInstallation, GitlabIssueBasic, RepositoryMixin):
    repo_search = True

    def __init__(self, *args, **kwargs):
        super(GitlabIntegration, self).__init__(*args, **kwargs)
        self.default_identity = None

    def get_group_id(self):
        return self.model.metadata["group_id"]
Esempio n. 22
0
removal_dialog = {
    "actionText":
    "Delete",
    "body":
    "Deleting this integration will delete all associated repositories"
    " and commit data. This action cannot be undone. Are you sure you"
    " want to delete your integration?",
}

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url=
    "https://github.com/getsentry/sentry/issues/new?title=GitHub%20Integration:%20&labels=Component%3A%20Integrations",
    source_url=
    "https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/github",
    aspects={
        "disable_dialog": disable_dialog,
        "removal_dialog": removal_dialog
    },
)

API_ERRORS = {
    404:
    "If this repository exists, ensure"
    " that your installation has permission to access this repository"
    " (https://github.com/settings/installations).",
    401:
    ERR_UNAUTHORIZED,
}
Esempio n. 23
0
        IntegrationFeatures.ISSUE_SYNC,
    ),
    FeatureDescription(
        """
        Automatically create Azure DevOps work items based on Issue Alert conditions.
        """,
        IntegrationFeatures.TICKET_RULES,
    ),
]

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url=
    "https://github.com/getsentry/sentry/issues/new?assignees=&labels=Component:%20Integrations&template=bug.yml&title=Azure%20DevOps%20Integration%20Problem",
    source_url=
    "https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/vsts",
    aspects={},
)

logger = logging.getLogger("sentry.integrations")


class VstsIntegration(IntegrationInstallation, RepositoryMixin,
                      VstsIssueSync):  # type: ignore
    logger = logger
    comment_key = "sync_comments"
    outbound_status_key = "sync_status_forward"
    inbound_status_key = "sync_status_reverse"
Esempio n. 24
0
setup_alert = {
    "type": "warning",
    "icon": "icon-warning-sm",
    "text": "Your GitHub enterprise instance must be able to communicate with"
    " Sentry. Sentry makes outbound requests from a [static set of IP"
    " addresses](https://docs.sentry.io/ip-ranges/) that you may wish"
    " to allow in your firewall to support this integration.",
}

metadata = IntegrationMetadata(
    description=DESCRIPTION.strip(),
    features=FEATURES,
    author="The Sentry Team",
    noun=_("Installation"),
    issue_url="https://github.com/getsentry/sentry/issues/new?assignees=&labels=Component:%20Integrations&template=bug.yml&title=GitHub%20Enterprise%20Integration%20Problem",
    source_url="https://github.com/getsentry/sentry/tree/master/src/sentry/integrations/github_enterprise",
    aspects={
        "disable_dialog": disable_dialog,
        "removal_dialog": removal_dialog,
        "alerts": [setup_alert],
    },
)


API_ERRORS = {
    404: "If this repository exists, ensure"
    + " that your installation has permission to access this repository"
    + " (https://github.com/settings/installations).",
    401: ERR_UNAUTHORIZED,
}