Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/sentry/api/bases/organization_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,7 @@ class OrganizationEventsEndpointBase(OrganizationEndpoint):
owner = ApiOwner.DATA_BROWSING

def has_feature(self, organization: Organization, request: Request) -> bool:
return (
features.has("organizations:discover-basic", organization, actor=request.user)
or features.has("organizations:performance-view", organization, actor=request.user)
or features.has(
"organizations:visibility-explore-view",
organization,
actor=request.user,
)
)
return True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we able to remove has_feature altogether if it just always return True?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that and originally had it remove everything, but I felt like it was a good pattern to keep around to be consistent with the early return if for some reason access wasn't there.

But now that I think about it again, maybe we just remove it because there's no point keeping the stubs for structural reasons if they actually mean nothing


def get_equation_list(
self, organization: Organization, request: Request, param_name: str = "field"
Expand Down
18 changes: 1 addition & 17 deletions src/sentry/api/endpoints/organization_trace_item_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
as_validation_errors,
)
from sentry.apidocs.utils import inline_sentry_response_serializer
from sentry.auth.principal import acting_user
from sentry.auth.staff import is_active_staff
from sentry.auth.superuser import is_active_superuser
from sentry.exceptions import InvalidSearchQuery
Expand Down Expand Up @@ -250,24 +249,9 @@ class OrganizationTraceItemAttributesEndpointBase(OrganizationEventsEndpointBase
"GET": ApiPublishStatus.PRIVATE,
}
owner = ApiOwner.DATA_BROWSING
feature_flags = [
"organizations:ourlogs-enabled",
"organizations:visibility-explore-view",
"organizations:tracemetrics-enabled",
]

def has_feature(self, organization: Organization, request: Request) -> bool:
batch_features = features.batch_has(
self.feature_flags, organization=organization, actor=acting_user(request.user)
)

if batch_features is None:
return False

key = f"organization:{organization.id}"
org_features = batch_features.get(key, {})

return any(org_features.get(feature) for feature in self.feature_flags)
return True


class OrganizationTraceItemAttributesEndpointSerializer(serializers.Serializer):
Expand Down
7 changes: 1 addition & 6 deletions src/sentry/api/endpoints/organization_traces.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from snuba_sdk import BooleanCondition, BooleanOp, Column, Condition, Function, Op
from urllib3.exceptions import ReadTimeoutError

from sentry import features, options
from sentry import options
from sentry.api.api_owners import ApiOwner
from sentry.api.api_publish_status import ApiPublishStatus
from sentry.api.base import cell_silo_endpoint
Expand Down Expand Up @@ -247,11 +247,6 @@ def get(
List traces containing at least one span that matches the query, with a
per-project timing breakdown for each trace.
"""
if not features.has(
"organizations:visibility-explore-view", organization, actor=request.user
):
return Response(status=404)

try:
snuba_params = self.get_snuba_params(request, organization)
except NoProjects:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from rest_framework.request import Request
from rest_framework.response import Response

from sentry import features
from sentry.api.api_owners import ApiOwner
from sentry.api.api_publish_status import ApiPublishStatus
from sentry.api.base import cell_silo_endpoint
Expand Down Expand Up @@ -45,9 +44,7 @@ class DiscoverSavedQueryStarredEndpoint(OrganizationEndpoint):
permission_classes = (MemberPermission,)

def has_feature(self, organization: Organization, request: Request) -> bool:
return features.has(
"organizations:visibility-explore-view", organization, actor=request.user
)
return True

def post(self, request: Request, organization: Organization, id: int) -> Response:
"""
Expand Down
4 changes: 1 addition & 3 deletions src/sentry/explore/endpoints/explore_saved_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,7 @@ class ExploreSavedQueriesEndpoint(OrganizationEndpoint):
permission_classes = (ExploreSavedQueryPermission,)

def has_feature(self, organization: Organization, request: Request) -> bool:
return features.has(
"organizations:visibility-explore-view", organization, actor=request.user
)
return True

@extend_schema(
operation_id="List an Organization's Explore Saved Queries",
Expand Down
9 changes: 2 additions & 7 deletions src/sentry/explore/endpoints/explore_saved_query_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from rest_framework.request import Request
from rest_framework.response import Response

from sentry import features
from sentry.api.api_owners import ApiOwner
from sentry.api.api_publish_status import ApiPublishStatus
from sentry.api.base import cell_silo_endpoint
Expand Down Expand Up @@ -70,9 +69,7 @@ class ExploreSavedQueryDetailEndpoint(ExploreSavedQueryBase):
}

def has_feature(self, organization: Organization, request: Request) -> bool:
return features.has(
"organizations:visibility-explore-view", organization, actor=request.user
)
return True

@extend_schema(
operation_id="Retrieve an Organization's Explore Saved Query",
Expand Down Expand Up @@ -194,9 +191,7 @@ class ExploreSavedQueryVisitEndpoint(ExploreSavedQueryBase):
}

def has_feature(self, organization: Organization, request: Request) -> bool:
return features.has(
"organizations:visibility-explore-view", organization, actor=request.user
)
return True

@extend_schema(
operation_id="Record a Visit to an Organization's Explore Saved Query",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from rest_framework.request import Request
from rest_framework.response import Response

from sentry import features
from sentry.api.api_owners import ApiOwner
from sentry.api.api_publish_status import ApiPublishStatus
from sentry.api.base import cell_silo_endpoint
Expand Down Expand Up @@ -62,9 +61,7 @@ class ExploreSavedQueryStarredEndpoint(OrganizationEndpoint):
permission_classes = (MemberPermission,)

def has_feature(self, organization: Organization, request: Request) -> bool:
return features.has(
"organizations:visibility-explore-view", organization, actor=request.user
)
return True

@extend_schema(
operation_id="Star an Organization's Explore Saved Query",
Expand Down
4 changes: 1 addition & 3 deletions src/sentry/explore/endpoints/saved_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,7 @@ class SavedQueriesEndpoint(OrganizationEndpoint):
permission_classes = (ExploreSavedQueryPermission,)

def has_feature(self, organization: Organization, request: Request) -> bool:
return features.has(
"organizations:visibility-explore-view", organization, actor=request.user
)
return True

@extend_schema(
operation_id="List an Organization's Explore and Discover Saved Queries",
Expand Down
5 changes: 1 addition & 4 deletions src/sentry/explore/endpoints/saved_query_starred_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from rest_framework.request import Request
from rest_framework.response import Response

from sentry import features
from sentry.api.api_owners import ApiOwner
from sentry.api.api_publish_status import ApiPublishStatus
from sentry.api.base import cell_silo_endpoint
Expand Down Expand Up @@ -75,9 +74,7 @@ class SavedQueryStarredOrderEndpoint(OrganizationEndpoint):
permission_classes = (MemberPermission,)

def has_feature(self, organization: Organization, request: Request) -> bool:
return features.has(
"organizations:visibility-explore-view", organization, actor=request.user
)
return True

@extend_schema(
operation_id="Reorder an Organization's Starred Saved Queries",
Expand Down
4 changes: 0 additions & 4 deletions src/sentry/incidents/utils/subscription_limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
# coupling to individual dataset→feature mappings.
METRIC_SUBSCRIPTION_FEATURE_FLAGS: dict[str, bool] = {
"organizations:performance-view": True,
"organizations:visibility-explore-view": True,
"organizations:on-demand-metrics-extraction": True,
}

Expand All @@ -28,9 +27,6 @@ def is_metric_subscription_allowed(dataset: str, organization: Organization) ->
if dataset == Dataset.Transactions.value:
return features.has("organizations:performance-view", organization)

if dataset == Dataset.EventsAnalyticsPlatform.value:
return features.has("organizations:visibility-explore-view", organization)

if dataset == Dataset.PerformanceMetrics.value:
return features.has("organizations:on-demand-metrics-extraction", organization)

Expand Down
12 changes: 3 additions & 9 deletions src/sentry/integrations/slack/unfurl/explore.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from django.http.request import QueryDict

from sentry import analytics, features, options
from sentry import analytics, options
from sentry.api.client import client
from sentry.charts import backend as charts
from sentry.charts.types import ChartSize, ChartType
Expand Down Expand Up @@ -550,20 +550,14 @@ def _unfurl_explore(
)
orgs_by_slug = {org.slug: org for org in organizations}

enabled_orgs = {
slug: org
for slug, org in orgs_by_slug.items()
if features.has("organizations:visibility-explore-view", org, actor=user)
}

if not enabled_orgs:
if not orgs_by_slug:
return {}

unfurls = {}

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

if not org:
continue
Expand Down
3 changes: 1 addition & 2 deletions src/sentry/integrations/slack/webhooks/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,13 @@ def _get_unfurlable_links(

feature_flag = {
LinkType.DISCOVER: "organizations:discover-basic",
LinkType.EXPLORE: "organizations:visibility-explore-view",
}.get(link_type)

if (
organization
and not slack_request.has_identity
and (
link_type == LinkType.DASHBOARDS
link_type in {LinkType.DASHBOARDS, LinkType.EXPLORE}
or (
feature_flag
and features.has(feature_flag, organization, actor=request.user)
Expand Down
3 changes: 1 addition & 2 deletions src/sentry/seer/assisted_query/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ def get_transformation_capabilities(
) -> TransformationCapabilities:
datasets: list[TransformationDataset] = []
if features.has("organizations:explore-interpolation-and-smoothing", organization, actor=actor):
if features.has("organizations:visibility-explore-view", organization, actor=actor):
datasets.append("spans")
datasets.append("spans")
if features.has("organizations:ourlogs-enabled", organization, actor=actor):
datasets.append("logs")
if features.has("organizations:tracemetrics-enabled", organization, actor=actor):
Expand Down
53 changes: 24 additions & 29 deletions tests/acceptance/test_explore_spans.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
from sentry.testutils.helpers.datetime import before_now
from sentry.testutils.silo import no_silo_test

FEATURE_FLAGS = [
"organizations:visibility-explore-view",
]


@no_silo_test
class ExploreSpansTest(AcceptanceTestCase, SpanTestCase, SnubaTestCase):
Expand Down Expand Up @@ -44,29 +40,28 @@ def test_spans_table_loads_all_events(self, mock_now: MagicMock) -> None:
self.browser.driver.get_window_size().get("width") == 1680
) # This test makes assertions based on the current default window size.

with self.feature(FEATURE_FLAGS):
spans = [
self.create_span(
{"description": "foo", "sentry_tags": {"status": "success"}},
start_ts=self.start_minus_one_minute,
),
self.create_span(
{
"description": "bar",
"sentry_tags": {"status": "invalid_argument"},
},
start_ts=self.start_minus_two_minutes,
),
]
self.store_spans(
spans,
)
spans = [
self.create_span(
{"description": "foo", "sentry_tags": {"status": "success"}},
start_ts=self.start_minus_one_minute,
),
self.create_span(
{
"description": "bar",
"sentry_tags": {"status": "invalid_argument"},
},
start_ts=self.start_minus_two_minutes,
),
]
self.store_spans(
spans,
)

self.page.visit_explore_spans(self.organization.slug)
for span in spans:
span_row = self.page.get_spans_row_with_id(span["span_id"][:8])
column_objects = self.page.get_spans_row_columns(span_row)
row_text = [element.text for element in column_objects]
# Just checking that the attrs of the span are here so test isn't dependent on the order of columns
assert span["span_id"][:8] in row_text
assert span["description"] in row_text
self.page.visit_explore_spans(self.organization.slug)
for span in spans:
span_row = self.page.get_spans_row_with_id(span["span_id"][:8])
column_objects = self.page.get_spans_row_columns(span_row)
row_text = [element.text for element in column_objects]
# Just checking that the attrs of the span are here so test isn't dependent on the order of columns
assert span["span_id"][:8] in row_text
assert span["description"] in row_text
1 change: 0 additions & 1 deletion tests/acceptance/test_trace_view_from_explore.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
class TraceViewFromExploreTest(AcceptanceTestCase, TraceTestCase, SnubaTestCase):
viewname = "sentry-api-0-organization-events"
FEATURES = [
"organizations:visibility-explore-view",
"organizations:performance-view",
]

Expand Down
1 change: 0 additions & 1 deletion tests/acceptance/test_trace_view_waterfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
class TraceViewWaterfallTest(AcceptanceTestCase, TraceTestCase, SnubaTestCase):
viewname = "sentry-api-0-organization-trace"
FEATURES = [
"organizations:visibility-explore-view",
"organizations:performance-view",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
class OrganizationTraceItemAttributesDocs(APIDocsTestCase):
feature_flags = {
"organizations:ourlogs-enabled": True,
"organizations:visibility-explore-view": True,
"organizations:tracemetrics-enabled": True,
}

Expand Down
Loading
Loading