Ejemplo n.º 1
0
    def issue_state_change(self, group, identity, data):
        event_write_key = ApiKey(
            organization=group.project.organization, scope_list=["event:write"]
        )

        # undoing the enum structure of ACTION_TYPE to
        # get a more sensible analytics_event
        action_types = {
            ACTION_TYPE.RESOLVE: "resolve",
            ACTION_TYPE.IGNORE: "ignore",
            ACTION_TYPE.ASSIGN: "assign",
            ACTION_TYPE.UNRESOLVE: "unresolve",
            ACTION_TYPE.UNASSIGN: "unassign",
        }
        action_data = self.make_action_data(data, identity.user_id)
        status = action_types[data["payload"]["actionType"]]
        analytics_event = "integrations.msteams.%s" % status
        analytics.record(
            analytics_event,
            actor_id=identity.user_id,
            organization_id=group.project.organization.id,
        )

        return client.put(
            path=u"/projects/{}/{}/issues/".format(
                group.project.organization.slug, group.project.slug
            ),
            params={"id": group.id},
            data=action_data,
            user=identity.user,
            auth=event_write_key,
        )
Ejemplo n.º 2
0
    def _handle_builtin(self, request, project):
        endpoint = "/projects/{}/{}/releases/".format(
            project.organization.slug, project.slug)

        try:
            data = json.loads(request.body)
        except json.JSONDecodeError as exc:
            return HttpResponse(
                status=400,
                content=json.dumps({"error": six.text_type(exc)}),
                content_type="application/json",
            )

        try:
            # Ideally the API client would support some kind of god-mode here
            # as we've already confirmed credentials and simply want to execute
            # the view code. Instead we hack around it with an ApiKey instance
            god = ApiKey(organization=project.organization,
                         scope_list=["project:write"])

            resp = client.post(endpoint, data=data, auth=god)
        except client.ApiError as exc:
            return HttpResponse(
                status=exc.status_code,
                content=json.dumps(exc.body),
                content_type="application/json",
            )
        return HttpResponse(status=resp.status_code,
                            content=json.dumps(resp.data),
                            content_type="application/json")
Ejemplo n.º 3
0
 def set_refs(self, release, **values):
     # check if user exists, and then try to get refs based on version
     if values.get('owner', None):
         repo_project_option = ProjectOption.objects.get_value(
             project=self.project,
             key='heroku:repository',
         )
         deploy_project_option = ProjectOption.objects.get_value(
             project=self.project,
             key='heroku:environment',
             default='production',
         ) or 'production'
         if repo_project_option:
             try:
                 repository = Repository.objects.get(
                     organization_id=self.project.organization_id, name=repo_project_option
                 )
             except Repository.DoesNotExist:
                 logger.info(
                     'repository.missing',
                     extra={
                         'organization_id': self.project.organization_id,
                         'project_id': self.project.id,
                         'repository': repo_project_option,
                     }
                 )
             else:
                 release.set_refs(
                     refs=[{
                         'commit': release.version,
                         'repository': repository.name
                     }],
                     user=values['owner'],
                     fetch=True,
                 )
         # create deploy associated with release via ReleaseDeploysEndpoint
         endpoint = '/organizations/{}/releases/{}/deploys/'.format(
             self.project.organization.slug,
             release.version,
         )
         auth = ApiKey(
             organization=self.project.organization,
             scope_list=['project:write'],
         )
         client.post(
             endpoint,
             data={'environment': deploy_project_option},
             auth=auth,
         )
     else:
         logger.info(
             'owner.missing',
             extra={
                 'organization_id': self.project.organization_id,
                 'project_id': self.project.id,
             }
         )
Ejemplo n.º 4
0
    def update_group(self, group, identity, data):
        event_write_key = ApiKey(organization=group.project.organization,
                                 scope_list=["event:write"])

        return client.put(
            path=u"/projects/{}/{}/issues/".format(
                group.project.organization.slug, group.project.slug),
            params={"id": group.id},
            data=data,
            user=identity.user,
            auth=event_write_key,
        )
Ejemplo n.º 5
0
    def update_group(self, group: Group, identity: Identity, data: Mapping[str, str]) -> Response:
        event_write_key = ApiKey(
            organization=group.project.organization, scope_list=["event:write"]
        )

        return client.put(
            path=f"/projects/{group.project.organization.slug}/{group.project.slug}/issues/",
            params={"id": group.id},
            data=data,
            user=identity.user,
            auth=event_write_key,
        )
Ejemplo n.º 6
0
 def set_refs(self, release, **values):
     # check if user exists, and then try to get refs based on version
     if values.get("owner", None):
         repo_project_option = ProjectOption.objects.get_value(
             project=self.project, key="heroku:repository")
         deploy_project_option = (ProjectOption.objects.get_value(
             project=self.project,
             key="heroku:environment",
             default="production") or "production")
         if repo_project_option:
             try:
                 repository = Repository.objects.get(
                     organization_id=self.project.organization_id,
                     name=repo_project_option)
             except Repository.DoesNotExist:
                 logger.info(
                     "repository.missing",
                     extra={
                         "organization_id": self.project.organization_id,
                         "project_id": self.project.id,
                         "repository": repo_project_option,
                     },
                 )
             else:
                 release.set_refs(
                     refs=[{
                         "commit": release.version,
                         "repository": repository.name
                     }],
                     user=values["owner"],
                     fetch=True,
                 )
         # create deploy associated with release via ReleaseDeploysEndpoint
         endpoint = "/organizations/{}/releases/{}/deploys/".format(
             self.project.organization.slug, release.version)
         auth = ApiKey(organization=self.project.organization,
                       scope_list=["project:write"])
         client.post(endpoint,
                     data={"environment": deploy_project_option},
                     auth=auth)
     else:
         logger.info(
             "owner.missing",
             extra={
                 "organization_id": self.project.organization_id,
                 "project_id": self.project.id,
             },
         )
Ejemplo n.º 7
0
 def get_auth(self):
     try:
         return ApiKey(organization=self.project.organization,
                       scope_list=["project:write"])
     except ApiKey.DoesNotExist:
         return None
Ejemplo n.º 8
0
def unfurl_discover(data, integration,
                    links: List[UnfurlableUrl]) -> UnfurledUrl:
    orgs_by_slug = {org.slug: org for org in integration.organizations.all()}
    unfurls = {}

    for link in links:
        org_slug = link.args["org_slug"]
        org = orgs_by_slug.get(org_slug)

        # If the link shared is an org w/o the slack integration do not unfurl
        if not org:
            continue
        if not features.has("organizations:chart-unfurls", org):
            continue

        params = link.args["query"]
        query_id = params.get("id", None)

        saved_query = {}
        if query_id:
            try:
                response = client.get(
                    auth=ApiKey(organization=org, scope_list=["org:read"]),
                    path=
                    f"/organizations/{org_slug}/discover/saved/{query_id}/",
                )

            except Exception as exc:
                logger.error(
                    "Failed to load saved query for unfurl: %s",
                    str(exc),
                    exc_info=True,
                )
            else:
                saved_query = response.data

        # Override params from Discover Saved Query if they aren't in the URL
        params.setlist(
            "order",
            params.getlist("sort") or to_list(saved_query.get("orderby")))
        params.setlist(
            "name",
            params.getlist("name") or to_list(saved_query.get("name")))
        params.setlist(
            "yAxis",
            params.getlist("yAxis")
            or to_list(saved_query.get("yAxis", "count()")))
        params.setlist(
            "field",
            params.getlist("field") or to_list(saved_query.get("fields")))

        # Only override if key doesn't exist since we want to account for
        # an intermediate state where the query could have been cleared
        if "query" not in params:
            params.setlist(
                "query",
                params.getlist("query") or to_list(saved_query.get("query")))

        display_mode = str(
            params.get("display") or saved_query.get("display", "default"))

        if "daily" in display_mode:
            params.setlist("interval", ["1d"])
        if "top5" in display_mode:
            params.setlist("topEvents", [f"{TOP_N}"])

        try:
            resp = client.get(
                auth=ApiKey(organization=org, scope_list=["org:read"]),
                path=f"/organizations/{org_slug}/events-stats/",
                params=params,
            )
        except Exception as exc:
            logger.error(
                "Failed to load events-stats for unfurl: %s",
                str(exc),
                exc_info=True,
            )
            continue

        chart_data = {"seriesName": params.get("yAxis"), "stats": resp.data}

        style = display_modes.get(display_mode, display_modes["default"])

        try:
            url = generate_chart(style, chart_data)
        except RuntimeError as exc:
            logger.error(
                "Failed to generate chat for discover unfurl: %s",
                str(exc),
                exc_info=True,
            )
            continue

        unfurls[link.url] = build_discover_attachment(
            title=link.args["query"].get("name", "Dashboards query"),
            chart_url=url,
        )

    return unfurls
Ejemplo n.º 9
0
def unfurl_discover(data, integration,
                    links: List[UnfurlableUrl]) -> UnfurledUrl:
    orgs_by_slug = {org.slug: org for org in integration.organizations.all()}
    unfurls = {}

    for link in links:
        org_slug = link.args["org_slug"]
        org = orgs_by_slug.get(org_slug)

        # If the link shared is an org w/o the slack integration do not unfurl
        if not org:
            continue
        if not features.has("organizations:chart-unfurls", org):
            continue

        params = link.args["query"]
        params.setlist("order", params.get("sort"))
        display_mode = str(link.args["query"].get("display", "default"))

        if "daily" in display_mode:
            params.setlist("interval", ["1d"])
        if "top5" in display_mode:
            params.setlist("topEvents", [f"{TOP_N}"])

        try:
            resp = client.get(
                auth=ApiKey(organization=org, scope_list=["org:read"]),
                path=f"/organizations/{org_slug}/events-stats/",
                params=params,
            )
        except Exception as exc:
            logger.error(
                "Failed to load events-stats for unfurl: %s",
                str(exc),
                exc_info=True,
            )
            continue

        chart_data = {
            "seriesName": link.args["query"].get("yAxis", "count()"),
            "stats": resp.data
        }

        style = display_modes.get(display_mode, display_modes["default"])

        try:
            url = generate_chart(style, chart_data)
        except RuntimeError as exc:
            logger.error(
                "Failed to generate chat for discover unfurl: %s",
                str(exc),
                exc_info=True,
            )
            continue

        unfurls[link.url] = build_discover_attachment(
            title=link.args["query"].get("name", "Dashboards query"),
            chart_url=url,
        )

    return unfurls
Ejemplo n.º 10
0
def unfurl_discover(
    data: HttpRequest,
    integration: Integration,
    links: List[UnfurlableUrl],
    user: Optional["User"],
) -> UnfurledUrl:
    orgs_by_slug = {org.slug: org for org in integration.organizations.all()}
    unfurls = {}

    for link in links:
        org_slug = link.args["org_slug"]
        org = orgs_by_slug.get(org_slug)

        # If the link shared is an org w/o the slack integration do not unfurl
        if not org:
            continue
        if not features.has("organizations:discover-basic", org):
            continue

        params = link.args["query"]
        query_id = params.get("id", None)

        saved_query = {}
        if query_id:
            try:
                response = client.get(
                    auth=ApiKey(organization=org, scope_list=["org:read"]),
                    path=f"/organizations/{org_slug}/discover/saved/{query_id}/",
                )

            except Exception as exc:
                logger.error(
                    f"Failed to load saved query for unfurl: {exc}",
                    exc_info=True,
                )
            else:
                saved_query = response.data

        # Override params from Discover Saved Query if they aren't in the URL
        params.setlist(
            "order",
            params.getlist("sort")
            or (to_list(saved_query.get("orderby")) if saved_query.get("orderby") else []),
        )
        params.setlist("name", params.getlist("name") or to_list(saved_query.get("name")))

        fields = params.getlist("field") or to_list(saved_query.get("fields"))
        # Mimic Discover to pick the first aggregate as the yAxis option if
        # one isn't specified.
        axis_options = [field for field in fields if is_aggregate(field)] + [DEFAULT_AXIS_OPTION]
        params.setlist(
            "yAxis", params.getlist("yAxis") or to_list(saved_query.get("yAxis", axis_options[0]))
        )
        params.setlist("field", params.getlist("field") or to_list(saved_query.get("fields")))

        params.setlist(
            "project",
            params.getlist("project")
            or (to_list(saved_query.get("project")) if saved_query.get("project") else []),
        )

        # Only override if key doesn't exist since we want to account for
        # an intermediate state where the query could have been cleared
        if "query" not in params:
            params.setlist(
                "query", params.getlist("query") or to_list(saved_query.get("query", ""))
            )

        display_mode = str(params.get("display") or saved_query.get("display", "default"))

        if "daily" in display_mode:
            params.setlist("interval", ["1d"])

        if "top5" in display_mode:
            params.setlist(
                "topEvents",
                params.getlist("topEvents") or to_list(saved_query.get("topEvents", f"{TOP_N}")),
            )

            y_axis = params.getlist("yAxis")[0]
            if display_mode != "dailytop5":
                display_mode = get_top5_display_mode(y_axis)

        else:
            # topEvents param persists in the URL in some cases, we want to discard
            # it if it's not a top n display type.
            params.pop("topEvents", None)

        if "previous" in display_mode:
            stats_period = params.getlist("statsPeriod", [DEFAULT_PERIOD])[0]
            parsed_period = parse_stats_period(stats_period)
            if parsed_period and parsed_period <= timedelta(days=MAX_PERIOD_DAYS_INCLUDE_PREVIOUS):
                stats_period = get_double_period(stats_period)
                params.setlist("statsPeriod", [stats_period])

        endpoint = "events-stats/"
        if "worldmap" in display_mode:
            endpoint = "events-geo/"
            params.setlist("field", params.getlist("yAxis"))
            params.pop("sort", None)

        try:
            resp = client.get(
                auth=ApiKey(organization=org, scope_list=["org:read"]),
                user=user,
                path=f"/organizations/{org_slug}/{endpoint}",
                params=params,
            )
        except Exception as exc:
            logger.error(
                f"Failed to load {endpoint} for unfurl: {exc}",
                exc_info=True,
            )
            continue

        chart_data = {"seriesName": params.get("yAxis"), "stats": resp.data}

        style = display_modes.get(display_mode, display_modes["default"])

        try:
            url = generate_chart(style, chart_data)
        except RuntimeError as exc:
            logger.error(
                f"Failed to generate chart for discover unfurl: {exc}",
                exc_info=True,
            )
            continue

        unfurls[link.url] = SlackDiscoverMessageBuilder(
            title=link.args["query"].get("name", "Dashboards query"),
            chart_url=url,
        ).build()

    analytics.record(
        "integrations.slack.chart_unfurl",
        organization_id=integration.organizations.all()[0].id,
        user_id=user.id if user else None,
        unfurls_count=len(unfurls),
    )

    return unfurls