commit
75e8374371
41 changed files with 394 additions and 345 deletions
|
|
@ -6,3 +6,5 @@ venv
|
|||
.idea
|
||||
.DS_Store
|
||||
.env
|
||||
|
||||
CHANGELOG.md
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ grafana:
|
|||
- name: DATABASE_PASSWORD
|
||||
value: oncallpassword
|
||||
env:
|
||||
GF_FEATURE_TOGGLES_ENABLE: topnav,externalServiceAccounts
|
||||
GF_FEATURE_TOGGLES_ENABLE: externalServiceAccounts
|
||||
GF_SECURITY_ADMIN_PASSWORD: oncall
|
||||
GF_SECURITY_ADMIN_USER: oncall
|
||||
GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: grafana-oncall-app
|
||||
|
|
|
|||
|
|
@ -34,21 +34,21 @@ To configure supported messaging apps, refer to the following topics:
|
|||
|
||||
{{< section >}}
|
||||
|
||||
## Configure user notification policies
|
||||
## Configure user notification rules
|
||||
|
||||
Notification policies are a configurable set of notification steps that determine how you're notified of alert in OnCall. Users with the Admin or Editor role are
|
||||
Notification rules are a configurable set of notification steps that determine how you're notified of alert in OnCall. Users with the Admin or Editor role are
|
||||
able to receive notifications.
|
||||
Users can verify phone numbers and email addresses in the **Users** tab of Grafana OnCall.
|
||||
|
||||
- **Default Notifications** dictate how a user is notified for most escalation thresholds.
|
||||
- **Default notification rules** dictate how a user is notified for most escalation thresholds.
|
||||
|
||||
- **Important Notifications** are labeled in escalation chains. If an escalation event is marked as an important notification,
|
||||
it will bypass **Default Notification** settings and notify the user by the method specified.
|
||||
- **Important notification rules** are labeled in escalation chains. If an escalation event is marked as an important notification,
|
||||
it will bypass **Default notification rules** settings and notify the user by the method specified.
|
||||
|
||||
> **NOTE**: You cannot add users or manage permissions in Grafana OnCall. User settings are found on the
|
||||
> organizational level of your Grafana instance in **Configuration > Users**.
|
||||
|
||||
To configure a users notification policy:
|
||||
To configure a users notification rules:
|
||||
|
||||
1. Navigate to the **Users** tab of Grafana OnCall and search for or select a user.
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ def test_user_is_oncall(make_organization, make_user_for_organization, make_sche
|
|||
)
|
||||
on_call_shift.add_rolling_users([[oncall_user]])
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
|
||||
assert user_is_oncall(not_oncall_user) is False
|
||||
assert user_is_oncall(oncall_user) is True
|
||||
|
|
|
|||
|
|
@ -2344,3 +2344,41 @@ def test_alert_group_external_urls(
|
|||
"url": "https://some-url",
|
||||
}
|
||||
assert response.json()["external_urls"] == [expected]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_filter_default_started_at(
|
||||
make_organization_and_user_with_plugin_token,
|
||||
make_alert_receive_channel,
|
||||
make_channel_filter,
|
||||
make_alert_group,
|
||||
make_alert,
|
||||
make_user_auth_headers,
|
||||
):
|
||||
organization, user, token = make_organization_and_user_with_plugin_token()
|
||||
alert_receive_channel = make_alert_receive_channel(organization)
|
||||
channel_filter = make_channel_filter(alert_receive_channel, is_default=True)
|
||||
|
||||
old_alert_group = make_alert_group(alert_receive_channel, channel_filter=channel_filter)
|
||||
old_alert_group.started_at = timezone.now() - timezone.timedelta(days=31)
|
||||
old_alert_group.save(update_fields=["started_at"])
|
||||
make_alert(alert_group=old_alert_group, raw_request_data=alert_raw_request_data)
|
||||
|
||||
new_alert_group = make_alert_group(alert_receive_channel, channel_filter=channel_filter)
|
||||
make_alert(alert_group=new_alert_group, raw_request_data=alert_raw_request_data)
|
||||
|
||||
client = APIClient()
|
||||
|
||||
# by default, no alert groups older than 30 days should be listed
|
||||
response = client.get(reverse("api-internal:alertgroup-list"), **make_user_auth_headers(user, token))
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.json()["results"]) == 1
|
||||
assert response.json()["results"][0]["pk"] == new_alert_group.public_primary_key
|
||||
|
||||
# but it should still be possible to retrieve an old alert group by its ID
|
||||
response = client.get(
|
||||
reverse("api-internal:alertgroup-detail", kwargs={"pk": old_alert_group.public_primary_key}),
|
||||
**make_user_auth_headers(user, token),
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.json()["pk"] == old_alert_group.public_primary_key
|
||||
|
|
|
|||
|
|
@ -435,6 +435,7 @@ def test_get_list_schedules_by_mine(
|
|||
)
|
||||
override.add_rolling_users([[user]])
|
||||
web_schedule.refresh_ical_file()
|
||||
web_schedule.refresh_ical_final_schedule()
|
||||
|
||||
url = reverse("api-internal:schedule-list") + query_param
|
||||
response = client.get(url, format="json", **make_user_auth_headers(user, token))
|
||||
|
|
@ -1497,6 +1498,7 @@ def test_next_shifts_per_user(
|
|||
override.add_rolling_users([[user_c]])
|
||||
|
||||
# final schedule: 7-12: B, 15-16: A, 16-17: B, 17-18: C (override), 18-20: C
|
||||
schedule.refresh_ical_final_schedule()
|
||||
|
||||
url = reverse("api-internal:schedule-next-shifts-per-user", kwargs={"pk": schedule.public_primary_key})
|
||||
response = client.get(url, format="json", **make_user_auth_headers(admin, token))
|
||||
|
|
@ -1569,6 +1571,7 @@ def test_next_shifts_per_user_ical_schedule_using_emails(
|
|||
schedule_class=OnCallScheduleICal,
|
||||
cached_ical_file_primary=cached_ical_primary_schedule,
|
||||
)
|
||||
schedule.refresh_ical_final_schedule()
|
||||
|
||||
url = reverse("api-internal:schedule-next-shifts-per-user", kwargs={"pk": schedule.public_primary_key})
|
||||
response = client.get(url, format="json", **make_user_auth_headers(admin, token))
|
||||
|
|
@ -1628,6 +1631,7 @@ def test_related_users(
|
|||
)
|
||||
override.add_rolling_users([[user_c]])
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
|
||||
url = reverse("api-internal:schedule-related-users", kwargs={"pk": schedule.public_primary_key})
|
||||
response = client.get(url, format="json", **make_user_auth_headers(admin, token))
|
||||
|
|
|
|||
|
|
@ -332,8 +332,7 @@ class AlertGroupView(
|
|||
alert_receive_channels_ids = list(alert_receive_channels_qs.values_list("id", flat=True))
|
||||
queryset = AlertGroup.objects.filter(channel__in=alert_receive_channels_ids)
|
||||
|
||||
# This is a quick fix to speed up requests from mobile app by adding default `started_at` filter value
|
||||
if not self.request.query_params.get("started_at"):
|
||||
if self.action in ("list", "stats") and not self.request.query_params.get("started_at"):
|
||||
queryset = queryset.filter(started_at__gte=timezone.now() - timezone.timedelta(days=30))
|
||||
|
||||
if self.action in ("list", "stats") and settings.ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX:
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ def test_notify_shift_swap_request_success(
|
|||
on_call_shift.add_rolling_users([[user]])
|
||||
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
schedule.refresh_from_db()
|
||||
|
||||
swap_start = now + timezone.timedelta(days=100)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import pytz
|
|||
from django.conf import settings
|
||||
from django.core.validators import MinLengthValidator
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.db.utils import DatabaseError
|
||||
from django.utils import timezone
|
||||
from django.utils.functional import cached_property
|
||||
|
|
@ -158,10 +157,7 @@ class OnCallScheduleQuerySet(PolymorphicQuerySet):
|
|||
def related_to_user(self, user):
|
||||
username_regex = RE_ICAL_SEARCH_USERNAME.format(user.username)
|
||||
return self.filter(
|
||||
Q(cached_ical_file_primary__regex=username_regex)
|
||||
| Q(cached_ical_file_primary__contains=user.email)
|
||||
| Q(cached_ical_file_overrides__regex=username_regex)
|
||||
| Q(cached_ical_file_overrides__contains=user.email),
|
||||
cached_ical_final_schedule__regex=username_regex,
|
||||
organization=user.organization,
|
||||
)
|
||||
|
||||
|
|
@ -344,10 +340,8 @@ class OnCallSchedule(PolymorphicModel):
|
|||
def related_users(self):
|
||||
"""Return users referenced in the schedule."""
|
||||
usernames = []
|
||||
if self.cached_ical_file_primary:
|
||||
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_file_primary)
|
||||
if self.cached_ical_file_overrides:
|
||||
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_file_overrides)
|
||||
if self.cached_ical_final_schedule:
|
||||
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_final_schedule)
|
||||
return self.organization.users.filter(username__in=usernames)
|
||||
|
||||
def filter_events(
|
||||
|
|
@ -1128,16 +1122,6 @@ class OnCallScheduleICal(OnCallSchedule):
|
|||
)
|
||||
self.save(update_fields=["cached_ical_file_overrides", "prev_ical_file_overrides", "ical_file_error_overrides"])
|
||||
|
||||
def related_users(self):
|
||||
"""Return users referenced in the schedule."""
|
||||
# combine users based on usernames and users via email (allowed in iCal based schedules)
|
||||
usernames = []
|
||||
if self.cached_ical_file_primary:
|
||||
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_file_primary)
|
||||
if self.cached_ical_file_overrides:
|
||||
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_file_overrides)
|
||||
return self.organization.users.filter(Q(username__in=usernames) | Q(email__in=usernames))
|
||||
|
||||
# Insight logs
|
||||
@property
|
||||
def insight_logs_serialized(self):
|
||||
|
|
|
|||
|
|
@ -1206,7 +1206,7 @@ def test_schedule_related_users(make_organization, make_user_for_organization, m
|
|||
now = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
start_date = now - timezone.timedelta(days=7)
|
||||
|
||||
user_a, _, _, user_d, user_e = (make_user_for_organization(organization, username=i) for i in "ABCDE")
|
||||
user_a, user_b, _, user_d, user_e = (make_user_for_organization(organization, username=i) for i in "ABCDE")
|
||||
|
||||
shifts = (
|
||||
# user, priority, start time (h), duration (hs)
|
||||
|
|
@ -1239,7 +1239,20 @@ def test_schedule_related_users(make_organization, make_user_for_organization, m
|
|||
)
|
||||
override.add_rolling_users([[user_e]])
|
||||
|
||||
# override: 22-23, a month ago / B (won't be considered a related user)
|
||||
override_data = {
|
||||
"start": start_date - timezone.timedelta(hours=22, days=30),
|
||||
"rotation_start": start_date - timezone.timedelta(hours=22, days=30),
|
||||
"duration": timezone.timedelta(hours=1),
|
||||
"schedule": schedule,
|
||||
}
|
||||
override = make_on_call_shift(
|
||||
organization=organization, shift_type=CustomOnCallShift.TYPE_OVERRIDE, **override_data
|
||||
)
|
||||
override.add_rolling_users([[user_b]])
|
||||
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
schedule.refresh_from_db()
|
||||
|
||||
users = schedule.related_users()
|
||||
|
|
@ -1282,6 +1295,7 @@ def test_schedule_related_users_usernames(
|
|||
on_call_shift.add_rolling_users([[user]])
|
||||
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
schedule.refresh_from_db()
|
||||
|
||||
assert set(schedule.related_users()) == set(users)
|
||||
|
|
@ -1304,7 +1318,7 @@ def test_schedule_related_users_emails(make_organization, make_user_for_organiza
|
|||
DTSTAMP:20230127T151619Z
|
||||
UID:something
|
||||
SUMMARY:testing@testing.com
|
||||
RRULE:FREQ=WEEKLY;UNTIL=20221231T010101
|
||||
RRULE:FREQ=WEEKLY
|
||||
DTSTART;TZID=Europe/Madrid:20220309T130000
|
||||
DTEND;TZID=Europe/Madrid:20220309T133000
|
||||
SEQUENCE:4
|
||||
|
|
@ -1317,6 +1331,8 @@ def test_schedule_related_users_emails(make_organization, make_user_for_organiza
|
|||
schedule_class=OnCallScheduleICal,
|
||||
cached_ical_file_primary=cached_ical_primary_schedule,
|
||||
)
|
||||
schedule.refresh_ical_final_schedule()
|
||||
schedule.refresh_from_db()
|
||||
|
||||
assert set(schedule.related_users()) == {user}
|
||||
|
||||
|
|
@ -1604,6 +1620,7 @@ def test_user_related_schedules(
|
|||
)
|
||||
on_call_shift.add_rolling_users([[user]])
|
||||
schedule1.refresh_ical_file()
|
||||
schedule1.refresh_ical_final_schedule()
|
||||
|
||||
schedule2 = make_schedule(organization, schedule_class=OnCallScheduleWeb)
|
||||
override_data = {
|
||||
|
|
@ -1617,10 +1634,27 @@ def test_user_related_schedules(
|
|||
)
|
||||
override.add_rolling_users([[admin]])
|
||||
schedule2.refresh_ical_file()
|
||||
schedule2.refresh_ical_final_schedule()
|
||||
|
||||
# schedule3
|
||||
make_schedule(organization, schedule_class=OnCallScheduleWeb)
|
||||
|
||||
# schedule4
|
||||
schedule4 = make_schedule(organization, schedule_class=OnCallScheduleWeb)
|
||||
# user was part of the schedule some time ago (outside of the final schedule window)
|
||||
override_data = {
|
||||
"start": today - timezone.timedelta(days=21),
|
||||
"rotation_start": today - timezone.timedelta(days=21),
|
||||
"duration": timezone.timedelta(hours=1),
|
||||
"schedule": schedule4,
|
||||
}
|
||||
override = make_on_call_shift(
|
||||
organization=organization, shift_type=CustomOnCallShift.TYPE_OVERRIDE, **override_data
|
||||
)
|
||||
override.add_rolling_users([[admin]])
|
||||
schedule4.refresh_ical_file()
|
||||
schedule4.refresh_ical_final_schedule()
|
||||
|
||||
schedules = OnCallSchedule.objects.related_to_user(admin)
|
||||
assert set(schedules) == {schedule1, schedule2}
|
||||
|
||||
|
|
@ -1658,6 +1692,7 @@ def test_user_related_schedules_only_username(
|
|||
)
|
||||
on_call_shift.add_rolling_users([[user]])
|
||||
schedule1.refresh_ical_file()
|
||||
schedule1.refresh_ical_final_schedule()
|
||||
|
||||
schedule2 = make_schedule(organization, schedule_class=OnCallScheduleWeb)
|
||||
override_data = {
|
||||
|
|
@ -1671,6 +1706,7 @@ def test_user_related_schedules_only_username(
|
|||
)
|
||||
override.add_rolling_users([[user]])
|
||||
schedule2.refresh_ical_file()
|
||||
schedule2.refresh_ical_final_schedule()
|
||||
|
||||
# schedule3
|
||||
schedule3 = make_schedule(organization, schedule_class=OnCallScheduleWeb)
|
||||
|
|
@ -1685,6 +1721,7 @@ def test_user_related_schedules_only_username(
|
|||
)
|
||||
override.add_rolling_users([[other_user]])
|
||||
schedule3.refresh_ical_file()
|
||||
schedule3.refresh_ical_final_schedule()
|
||||
|
||||
schedules = OnCallSchedule.objects.related_to_user(user)
|
||||
assert set(schedules) == {schedule1, schedule2}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ def test_add_user_no_warning(manage_responders_setup, make_schedule, make_on_cal
|
|||
)
|
||||
on_call_shift.add_rolling_users([[user]])
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
# setup notification policy
|
||||
make_user_notification_policy(
|
||||
user=user,
|
||||
|
|
@ -199,6 +200,7 @@ def test_get_users_select(make_organization, make_user, make_schedule, make_on_c
|
|||
)
|
||||
on_call_shift.add_rolling_users([[oncall_user]])
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
|
||||
select_input = _get_users_select(
|
||||
organization=organization, input_id_prefix="test", action_id="test", max_options_per_group=2
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ def test_add_user_no_warning(make_organization_and_user_with_slack_identities, m
|
|||
)
|
||||
on_call_shift.add_rolling_users([[user]])
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
|
||||
payload = make_paging_view_slack_payload(selected_org=organization, user=user)
|
||||
|
||||
|
|
@ -221,6 +222,7 @@ def test_add_user_maximum_exceeded(make_organization_and_user_with_slack_identit
|
|||
)
|
||||
on_call_shift.add_rolling_users([[user]])
|
||||
schedule.refresh_ical_file()
|
||||
schedule.refresh_ical_final_schedule()
|
||||
|
||||
payload = make_paging_view_slack_payload(selected_org=organization, user=user)
|
||||
|
||||
|
|
|
|||
39
grafana-plugin/CHANGELOG.md
Normal file
39
grafana-plugin/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Changelog
|
||||
|
||||
## [1.9.27](https://github.com/grafana/irm/compare/grafana-oncall-app-v1.9.26...grafana-oncall-app-v1.9.27) (2024-09-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* address RBAC Admin issue ([#183](https://github.com/grafana/irm/issues/183)) ([508857b](https://github.com/grafana/irm/commit/508857b719641ce405910bb1b110dec62f1a7af5))
|
||||
* Bring webhooks to IRM ([#144](https://github.com/grafana/irm/issues/144)) ([1a883e1](https://github.com/grafana/irm/commit/1a883e1e44fe154ec0a7d36fa8183444fb90c773))
|
||||
* run go mod tidy ([#174](https://github.com/grafana/irm/issues/174)) ([df2cf75](https://github.com/grafana/irm/commit/df2cf75ac5d4f57661af722f4785ef4996644bbc))
|
||||
* style links in incident message ([#143](https://github.com/grafana/irm/issues/143)) ([2e55b07](https://github.com/grafana/irm/commit/2e55b07c1069cebfb30ba944b1c0b6f7dbfb1bad))
|
||||
|
||||
|
||||
### Dependencies
|
||||
|
||||
* bump `github.com/grafana/grafana-plugin-sdk-go` to `v0.250.2` to address CVE-2024-8986 ([#173](https://github.com/grafana/irm/issues/173)) ([2385dc3](https://github.com/grafana/irm/commit/2385dc39e0108ca8ee4047046a34a735d1598ec8))
|
||||
* bump micromatch version from 4.0.6 to 4.0.8 ([#181](https://github.com/grafana/irm/issues/181)) ([b1123fd](https://github.com/grafana/irm/commit/b1123fd8d54db080eb90c9959494a3bd00a89540))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* release main ([#157](https://github.com/grafana/irm/issues/157)) ([1b2901c](https://github.com/grafana/irm/commit/1b2901c952cc8e82f94becfa44db146fc0abe076))
|
||||
* release main ([#187](https://github.com/grafana/irm/issues/187)) ([3221340](https://github.com/grafana/irm/commit/3221340148ac972ed32cd16194a5eaf3cc29db3d))
|
||||
* release main ([#190](https://github.com/grafana/irm/issues/190)) ([e2489d0](https://github.com/grafana/irm/commit/e2489d0a31c4ac80dc72dca57c42eb3068fa4661))
|
||||
|
||||
## [1.9.26](https://github.com/grafana/irm/compare/grafana-oncall-app-v1.9.25...grafana-oncall-app-v1.9.26) (2024-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix template editor layout ([#142](https://github.com/grafana/irm/issues/142)) ([c8ac3b0](https://github.com/grafana/irm/commit/c8ac3b0f60cb5472fb93b59255ca30bc8ba64653))
|
||||
* make sure GMT elem is selected from the dropdown options is sele… ([#141](https://github.com/grafana/irm/issues/141)) ([cc86f17](https://github.com/grafana/irm/commit/cc86f1751f7378d981d6e60a20cef746f090f1df))
|
||||
* rename OnCall notification titles ([#126](https://github.com/grafana/irm/issues/126)) ([7df0120](https://github.com/grafana/irm/commit/7df01208271b29640939730375d035b5d5a13f98))
|
||||
* update how config page is rendered in cloud ([#137](https://github.com/grafana/irm/issues/137)) ([3cf9bc2](https://github.com/grafana/irm/commit/3cf9bc23bee92dd8dde77fe225efebaeaf38a233))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* improve (again) ui pod readiness probe ([#120](https://github.com/grafana/irm/issues/120)) ([c4ee02b](https://github.com/grafana/irm/commit/c4ee02b5253a7cfaf983518c6475f6207a66e253))
|
||||
|
|
@ -77,10 +77,12 @@ export const sendDemoAlert = async (page: Page): Promise<void> => {
|
|||
export const createIntegrationAndSendDemoAlert = async (
|
||||
page: Page,
|
||||
integrationName: string,
|
||||
escalationChainName: string
|
||||
escalationChainName?: string
|
||||
): Promise<void> => {
|
||||
await createIntegration({ page, integrationName });
|
||||
await assignEscalationChainToIntegration(page, escalationChainName);
|
||||
if (escalationChainName) {
|
||||
await assignEscalationChainToIntegration(page, escalationChainName);
|
||||
}
|
||||
await sendDemoAlert(page);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export const createOnCallSchedule = async (
|
|||
|
||||
// create an oncall-rotation schedule
|
||||
await clickButton({ page, buttonText: 'New Schedule' });
|
||||
(await page.waitForSelector('button >> text=Create >> nth=0')).click();
|
||||
await page.getByRole('button', { name: 'Create' }).first().click();
|
||||
|
||||
// fill in the name input
|
||||
await page.getByTestId('schedule-form').locator('input[name="name"]').fill(scheduleName);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ module github.com/grafana/grafana-oncall-app
|
|||
|
||||
go 1.21.5
|
||||
|
||||
require github.com/grafana/grafana-plugin-sdk-go v0.228.0
|
||||
require github.com/grafana/grafana-plugin-sdk-go v0.250.0
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
|
|
@ -16,7 +16,7 @@ require (
|
|||
github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/getkin/kin-openapi v0.124.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.8 // indirect
|
||||
|
|
@ -27,16 +27,18 @@ require (
|
|||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/grafana/otel-profiling-go v0.5.1 // indirect
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.0 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.1 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/magefile/mage v1.15.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
|
|
@ -48,45 +50,44 @@ require (
|
|||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.18 // indirect
|
||||
github.com/prometheus/client_golang v1.19.0 // indirect
|
||||
github.com/prometheus/client_golang v1.20.3 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
github.com/prometheus/procfs v0.14.0 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.1 // indirect
|
||||
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect
|
||||
github.com/unknwon/com v1.0.1 // indirect
|
||||
github.com/unknwon/log v0.0.0-20150304194804-e617c87089d3 // indirect
|
||||
github.com/urfave/cli v1.22.15 // indirect
|
||||
github.com/yudai/gojsondiff v1.0.0 // indirect
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
|
||||
github.com/zeebo/xxh3 v1.0.2 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.26.0 // indirect
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.26.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.29.0 // indirect
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 // indirect
|
||||
go.opentelemetry.io/otel v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.29.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/mod v0.13.0 // indirect
|
||||
golang.org/x/net v0.24.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.14.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
|
||||
google.golang.org/grpc v1.63.2 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||
google.golang.org/grpc v1.66.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
|||
github.com/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M=
|
||||
github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
|
||||
|
|
@ -64,18 +65,22 @@ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1
|
|||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.228.0 h1:LlPqyB+RZTtDy8RVYD7iQVJW5A0gMoGSI/+Ykz8HebQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.228.0/go.mod h1:u4K9vVN6eU86loO68977eTXGypC4brUCnk4sfDzutZU=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.250.0 h1:9EBucp9jLqMx2b8NTlOXH+4OuQWUh6L85c6EJUN8Jdo=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.250.0/go.mod h1:gCGN9kHY3KeX4qyni3+Kead38Q+85pYOrsDcxZp6AIk=
|
||||
github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8=
|
||||
github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls=
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg=
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A=
|
||||
github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI=
|
||||
github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI=
|
||||
github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0=
|
||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
|
||||
|
|
@ -90,17 +95,16 @@ github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpR
|
|||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
|
||||
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
|
|
@ -129,6 +133,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
|||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
|
|
@ -139,22 +145,20 @@ github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ
|
|||
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
|
||||
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
|
||||
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
|
||||
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
|
||||
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||
github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s=
|
||||
github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
|
||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
|
|
@ -165,7 +169,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
|
|||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
|
|
@ -183,40 +186,40 @@ github.com/unknwon/log v0.0.0-20150304194804-e617c87089d3/go.mod h1:1xEUf2abjfP9
|
|||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM=
|
||||
github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0=
|
||||
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
|
||||
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
||||
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
|
||||
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0 h1:974XTyIwHI4nHa1+uSLxHtUnlJ2DiVtAJjk7fd07p/8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0/go.mod h1:ZvX/taFlN6TGaOOM6D42wrNwPKUV1nGO2FuUXkityBU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.26.0 h1:RH76Cl2pfOLLoCtxAPax9c7oYzuL1tiI7/ZPJEmEmOw=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.26.0/go.mod h1:W/cylm0ZtJK1uxsuTqoYGYPnqpZ8CeVGgW7TwfXPsGw=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0 h1:ja+d7Aea/9PgGxB63+E0jtRFpma717wubS0KFkZpmYw=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0/go.mod h1:Yc1eg51SJy7xZdOTyg1xyFcwE+ghcWh3/0hKeLo6Wlo=
|
||||
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
|
||||
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo=
|
||||
go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
|
||||
go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs=
|
||||
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 h1:IVtyPth4Rs5P8wIf0mP2KVKFNTJ4paX9qQ4Hkh5gFdc=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0/go.mod h1:ImRBLMJv177/pwiLZ7tU7HDGNdBv7rS0HQ99eN/zBl8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.29.0 h1:+YPiqF5rR6PqHBlmEFLPumbSP0gY0WmCGFayXRcCLvs=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.29.0/go.mod h1:6PD7q7qquWSp3Z4HeM3e/2ipRubaY1rXZO8NIHVDZjs=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 h1:qKi9ntCcronqWqfuKxqrxZlZd82jXJEgGiAWH1+phxo=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0/go.mod h1:1kbAgQa5lgYC3rC6cE3jSxQ/Q13l33wv/WI8U+htwag=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
|
||||
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw=
|
||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
|
||||
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
|
||||
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
|
||||
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
|
@ -226,19 +229,19 @@ golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM
|
|||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191020152052-9984515f0562/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -251,18 +254,19 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
@ -271,16 +275,15 @@ golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3j
|
|||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
gonum.org/v1/gonum v0.12.0 h1:xKuo6hzt+gMav00meVPUlXwSdoEJP46BR+wdxQEFK2o=
|
||||
gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
|
||||
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
|
||||
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo=
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@ import { TextEncoder, TextDecoder } from 'util';
|
|||
jest.mock('@grafana/runtime', () => ({
|
||||
__esModule: true,
|
||||
config: {
|
||||
featureToggles: {
|
||||
topNav: false,
|
||||
},
|
||||
featureToggles: {},
|
||||
bootData: {
|
||||
user: {
|
||||
timezone: 'UTC',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "grafana-oncall-app",
|
||||
"version": "1.9.23",
|
||||
"version": "1.9.27",
|
||||
"description": "Grafana OnCall Plugin",
|
||||
"scripts": {
|
||||
"lint": "eslint --ext .js,.jsx,.ts,.tsx --max-warnings=20 ./src ./e2e-tests",
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
"@grafana/data": "^11.1.3",
|
||||
"@grafana/faro-web-sdk": "^1.4.2",
|
||||
"@grafana/faro-web-tracing": "^1.4.2",
|
||||
"@grafana/labels": "^1.6.5",
|
||||
"@grafana/labels": "^1.6.6",
|
||||
"@grafana/runtime": "^11.1.3",
|
||||
"@grafana/scenes": "^1.28.0",
|
||||
"@grafana/schema": "^11.1.3",
|
||||
|
|
@ -183,6 +183,6 @@
|
|||
},
|
||||
"resolutions": {
|
||||
"braces": "3.0.3",
|
||||
"micromatch": "4.0.6"
|
||||
"micromatch": "4.0.8"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
grafana-plugin/pnpm-lock.yaml
generated
40
grafana-plugin/pnpm-lock.yaml
generated
|
|
@ -6,7 +6,7 @@ settings:
|
|||
|
||||
overrides:
|
||||
braces: 3.0.3
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
|
||||
importers:
|
||||
|
||||
|
|
@ -37,8 +37,8 @@ importers:
|
|||
specifier: ^1.4.2
|
||||
version: 1.9.1
|
||||
'@grafana/labels':
|
||||
specifier: ^1.6.5
|
||||
version: 1.6.5(@grafana/ui@11.2.0(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
specifier: ^1.6.6
|
||||
version: 1.6.6(@grafana/ui@11.2.0(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
'@grafana/runtime':
|
||||
specifier: ^11.1.3
|
||||
version: 11.2.0(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
|
|
@ -746,8 +746,8 @@ packages:
|
|||
'@grafana/faro-web-tracing@1.9.1':
|
||||
resolution: {integrity: sha512-BuXMxUX6N8kDwOJO2wfCFOWfyEwfduEdJGT9HhgA3VPGmpgzpvZD6FOt1vsBMOZWsKsI20EcNM21moUy08dWAA==}
|
||||
|
||||
'@grafana/labels@1.6.5':
|
||||
resolution: {integrity: sha512-Z0Ho69My9evZkTYtgmYEIWuPGRfsHeM77pbExdPLvA8ZOB8LqoEEdRWJW7tyY3xPr1lGj//aSA2j697JoiXVrg==}
|
||||
'@grafana/labels@1.6.6':
|
||||
resolution: {integrity: sha512-jDmiCNpv9wXEQyB16Ptj2msQjykUecUtRicNpNowOG6eQ6GPktLiDSvbj+z5Ce8ieJ0pRuDcF7n3w1mf8ias6w==}
|
||||
peerDependencies:
|
||||
'@grafana/ui': ^11.0.0
|
||||
react: ^17.0.0 || ^18.0.0
|
||||
|
|
@ -4286,8 +4286,8 @@ packages:
|
|||
micro-memoize@4.1.2:
|
||||
resolution: {integrity: sha512-+HzcV2H+rbSJzApgkj0NdTakkC+bnyeiUxgT6/m7mjcz1CmM22KYFKp+EVj1sWe4UYcnriJr5uqHQD/gMHLD+g==}
|
||||
|
||||
micromatch@4.0.6:
|
||||
resolution: {integrity: sha512-Y4Ypn3oujJYxJcMacVgcs92wofTHxp9FzfDpQON4msDefoC0lb3ETvQLOdLcbhSwU1bz8HrL/1sygfBIHudrkQ==}
|
||||
micromatch@4.0.8:
|
||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
mime-db@1.33.0:
|
||||
|
|
@ -6991,7 +6991,7 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@grafana/labels@1.6.5(@grafana/ui@11.2.0(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
'@grafana/labels@1.6.6(@grafana/ui@11.2.0(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
dependencies:
|
||||
'@emotion/css': 11.13.0
|
||||
'@grafana/ui': 11.2.0(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
|
|
@ -7219,7 +7219,7 @@ snapshots:
|
|||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
jest-watcher: 29.7.0
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
pretty-format: 29.7.0
|
||||
slash: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
|
@ -7356,7 +7356,7 @@ snapshots:
|
|||
jest-haste-map: 29.7.0
|
||||
jest-regex-util: 29.6.3
|
||||
jest-util: 29.7.0
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
pirates: 4.0.6
|
||||
slash: 3.0.0
|
||||
write-file-atomic: 4.0.2
|
||||
|
|
@ -9873,7 +9873,7 @@ snapshots:
|
|||
'@types/eslint': 8.56.12
|
||||
eslint: 8.57.0
|
||||
jest-worker: 29.7.0
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
normalize-path: 3.0.0
|
||||
schema-utils: 4.2.0
|
||||
webpack: 5.94.0(@swc/core@1.7.22(@swc/helpers@0.5.12))(webpack-cli@5.1.4)
|
||||
|
|
@ -10084,7 +10084,7 @@ snapshots:
|
|||
'@nodelib/fs.walk': 1.2.8
|
||||
glob-parent: 5.1.2
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
|
||||
fast-json-stable-stringify@2.1.0: {}
|
||||
|
||||
|
|
@ -10839,7 +10839,7 @@ snapshots:
|
|||
jest-runner: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
parse-json: 5.2.0
|
||||
pretty-format: 29.7.0
|
||||
slash: 3.0.0
|
||||
|
|
@ -10916,7 +10916,7 @@ snapshots:
|
|||
jest-regex-util: 29.6.3
|
||||
jest-util: 29.7.0
|
||||
jest-worker: 29.7.0
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
walker: 1.0.8
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
|
@ -10952,7 +10952,7 @@ snapshots:
|
|||
'@types/stack-utils': 2.0.3
|
||||
chalk: 4.1.2
|
||||
graceful-fs: 4.2.11
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
pretty-format: 27.5.1
|
||||
slash: 3.0.0
|
||||
stack-utils: 2.0.6
|
||||
|
|
@ -10964,7 +10964,7 @@ snapshots:
|
|||
'@types/stack-utils': 2.0.3
|
||||
chalk: 4.1.2
|
||||
graceful-fs: 4.2.11
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
pretty-format: 29.7.0
|
||||
slash: 3.0.0
|
||||
stack-utils: 2.0.6
|
||||
|
|
@ -11298,7 +11298,7 @@ snapshots:
|
|||
execa: 4.1.0
|
||||
listr2: 3.14.0(enquirer@2.4.1)
|
||||
log-symbols: 4.1.0
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
normalize-path: 3.0.0
|
||||
please-upgrade-node: 3.2.0
|
||||
string-argv: 0.3.1
|
||||
|
|
@ -11471,10 +11471,10 @@ snapshots:
|
|||
|
||||
micro-memoize@4.1.2: {}
|
||||
|
||||
micromatch@4.0.6:
|
||||
micromatch@4.0.8:
|
||||
dependencies:
|
||||
braces: 3.0.3
|
||||
picomatch: 4.0.2
|
||||
picomatch: 2.3.1
|
||||
|
||||
mime-db@1.33.0: {}
|
||||
|
||||
|
|
@ -13197,7 +13197,7 @@ snapshots:
|
|||
known-css-properties: 0.26.0
|
||||
mathml-tag-names: 2.1.3
|
||||
meow: 9.0.0
|
||||
micromatch: 4.0.6
|
||||
micromatch: 4.0.8
|
||||
normalize-path: 3.0.0
|
||||
picocolors: 1.0.1
|
||||
postcss: 8.4.43
|
||||
|
|
|
|||
|
|
@ -6,13 +6,12 @@ import { Header } from 'navbar/Header/Header';
|
|||
|
||||
import { RenderConditionally } from 'components/RenderConditionally/RenderConditionally';
|
||||
import { pages } from 'pages/pages';
|
||||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
|
||||
interface AppPluginPageProps extends PluginPageProps {
|
||||
page?: string;
|
||||
}
|
||||
|
||||
export const PluginPage = (isTopNavbar() ? RealPlugin : PluginPageFallback) as React.ComponentType<AppPluginPageProps>;
|
||||
export const PluginPage = RealPlugin as React.ComponentType<AppPluginPageProps>;
|
||||
|
||||
function RealPlugin(props: AppPluginPageProps): React.ReactNode {
|
||||
const { page } = props;
|
||||
|
|
@ -33,7 +32,3 @@ function RealPlugin(props: AppPluginPageProps): React.ReactNode {
|
|||
</RealPluginPage>
|
||||
);
|
||||
}
|
||||
|
||||
export function PluginPageFallback(props: PluginPageProps): React.ReactNode {
|
||||
return props.children;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React, { ReactElement, useMemo } from 'react';
|
|||
|
||||
import { locationUtil, PluginExtensionLink, PluginExtensionTypes } from '@grafana/data';
|
||||
import { IconName, Menu } from '@grafana/ui';
|
||||
import { getPluginId } from 'helpers/consts';
|
||||
import { getPluginId, PLUGIN_ROOT } from 'helpers/consts';
|
||||
import { truncateTitle } from 'helpers/string';
|
||||
|
||||
import { PluginBridge, SupportedPlugin } from 'components/PluginBridge/PluginBridge';
|
||||
|
|
@ -58,14 +58,23 @@ const IRMActionSection: React.FC<Props> = ({ webhookModal, extensions, declareIn
|
|||
return (
|
||||
<Menu.Group key={'IRM'} label={'IRM'}>
|
||||
<Menu.Item icon={'upload'} key={'triggerWebhook'} label={'Trigger webhook'} onClick={webhookModal.onOpenModal} />
|
||||
|
||||
{extensions.length > 0 && (
|
||||
<DeclareIncidentMenuItem
|
||||
extensions={extensions}
|
||||
declareIncidentLink={declareIncidentLink}
|
||||
grafanaIncidentId={grafanaIncidentId}
|
||||
<RenderConditionally
|
||||
shouldRender={getPluginId() === 'grafana-irm-app'}
|
||||
backupChildren={
|
||||
<DeclareIncidentMenuItem
|
||||
extensions={extensions}
|
||||
declareIncidentLink={declareIncidentLink}
|
||||
grafanaIncidentId={grafanaIncidentId}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Menu.Item
|
||||
label="Declare incident"
|
||||
icon="fire"
|
||||
// TODO: At some point we should update link on the backend so it points to IRM plugin and use it directly
|
||||
url={`${PLUGIN_ROOT}/incidents?declare=new&${declareIncidentLink.split('?')[1].replace('oncall', 'irm')}`}
|
||||
/>
|
||||
)}
|
||||
</RenderConditionally>
|
||||
</Menu.Group>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import { getSlackMessage } from 'containers/DefaultPageLayout/DefaultPageLayout.
|
|||
import { SlackError } from 'containers/DefaultPageLayout/DefaultPageLayout.types';
|
||||
import { getIfChatOpsConnected } from 'containers/DefaultPageLayout/helper';
|
||||
import { UserHelper } from 'models/user/user.helpers';
|
||||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
import { AppFeature } from 'state/features';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
||||
|
|
@ -72,7 +71,7 @@ export const Alerts = observer(() => {
|
|||
return null;
|
||||
}
|
||||
return (
|
||||
<div className={cx(styles.alertsContainer, { [styles.alertsContainerLegacy]: !isTopNavbar() })}>
|
||||
<div className={styles.alertsContainer}>
|
||||
{showSlackInstallAlert && (
|
||||
<Alert
|
||||
className={styles.alert}
|
||||
|
|
@ -192,13 +191,5 @@ const getStyles = (theme: GrafanaTheme2) => {
|
|||
instructionsLink: css`
|
||||
color: ${theme.colors.primary.text};
|
||||
`,
|
||||
|
||||
alertsContainerLegacy: css`
|
||||
paddingtop: '10px';
|
||||
|
||||
@media (max-width: 768px) {
|
||||
padding-top: 50px;
|
||||
}
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
import React, { FC, ReactElement } from 'react';
|
||||
import React, { FC } from 'react';
|
||||
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { css } from '@emotion/css';
|
||||
import { AppRootProps, NavModelItem } from '@grafana/data';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { PluginPage } from 'PluginPage';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import { Alerts } from 'containers/Alerts/Alerts';
|
||||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
|
||||
interface DefaultPageLayoutProps extends AppRootProps {
|
||||
children?: any;
|
||||
|
|
@ -19,39 +17,11 @@ export const DefaultPageLayout: FC<DefaultPageLayoutProps> = observer((props) =>
|
|||
const { children, page, pageNav } = props;
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
if (isTopNavbar()) {
|
||||
return renderTopNavbar();
|
||||
}
|
||||
|
||||
return renderLegacyNavbar();
|
||||
|
||||
function renderTopNavbar(): ReactElement {
|
||||
return (
|
||||
<PluginPage page={page} pageNav={pageNav as any}>
|
||||
<div className={styles.root}>{children}</div>
|
||||
</PluginPage>
|
||||
);
|
||||
}
|
||||
|
||||
function renderLegacyNavbar(): ReactElement {
|
||||
return (
|
||||
<PluginPage page={page}>
|
||||
<div
|
||||
className={cx(
|
||||
'page-container',
|
||||
css`
|
||||
height: 100%;
|
||||
`
|
||||
)}
|
||||
>
|
||||
<div className={cx(styles.root)}>
|
||||
<Alerts />
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</PluginPage>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<PluginPage page={page} pageNav={pageNav as any}>
|
||||
<div className={styles.root}>{children}</div>
|
||||
</PluginPage>
|
||||
);
|
||||
});
|
||||
|
||||
const getStyles = () => {
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ export const IntegrationForm = observer(
|
|||
onHide();
|
||||
|
||||
async function createNewIntegration(): Promise<void | ApiSchemas['AlertReceiveChannelCreate']> {
|
||||
const response = await alertReceiveChannelStore.create({ data, skipErrorHandling: true });
|
||||
const response = await alertReceiveChannelStore.create({ data });
|
||||
const pushHistory = (id: ApiSchemas['AlertReceiveChannel']['id']) =>
|
||||
navigate(`${PLUGIN_ROOT}/integrations/${id}`);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@ import { rootStore } from 'state/rootStore';
|
|||
|
||||
import { MobileAppConnection } from './MobileAppConnection';
|
||||
|
||||
jest.mock('plugin/GrafanaPluginRootPage.helpers', () => ({
|
||||
isTopNavbar: () => false,
|
||||
}));
|
||||
|
||||
jest.mock('helpers/authorization/authorization', () => ({
|
||||
...jest.requireActual('helpers/authorization/authorization'),
|
||||
isUserActionAllowed: jest.fn().mockReturnValue(true),
|
||||
|
|
|
|||
|
|
@ -100,7 +100,11 @@ export const OutgoingWebhookForm = observer((props: OutgoingWebhookFormProps) =>
|
|||
defaultValues: data,
|
||||
});
|
||||
|
||||
const { setValue, reset, setError } = formMethods;
|
||||
const {
|
||||
setValue,
|
||||
reset,
|
||||
setError,
|
||||
} = formMethods;
|
||||
|
||||
const onSubmit = useCallback(
|
||||
async (rawData: Partial<ApiSchemas['Webhook']>) => {
|
||||
|
|
@ -115,8 +119,11 @@ export const OutgoingWebhookForm = observer((props: OutgoingWebhookFormProps) =>
|
|||
onHide();
|
||||
onUpdate();
|
||||
} catch (error) {
|
||||
const values = formMethods.getValues();
|
||||
Object.keys(error.response.data).forEach((key) => {
|
||||
setError(key as WebhookFormFieldName, { message: error.response.data[key][0] });
|
||||
if (key in values) {
|
||||
setError(key as WebhookFormFieldName, { message: error.response.data[key][0] });
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { Dayjs, ManipulateType } from 'dayjs';
|
||||
import { GRAFANA_HEADER_HEIGHT, GRAFANA_LEGACY_SIDEBAR_WIDTH } from 'helpers/consts';
|
||||
import { GRAFANA_HEADER_HEIGHT } from 'helpers/consts';
|
||||
import { DraggableData } from 'react-draggable';
|
||||
|
||||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
|
||||
import { RepeatEveryPeriod } from './RotationForm.types';
|
||||
|
||||
export const getRepeatShiftsEveryOptions = (repeatEveryPeriod: number) => {
|
||||
|
|
@ -195,20 +193,13 @@ export function getDraggableModalCoordinatesOnInit(
|
|||
const baseReferenceElRect = body.getBoundingClientRect();
|
||||
const { innerHeight } = window;
|
||||
|
||||
const { right, bottom } = baseReferenceElRect;
|
||||
const { right } = baseReferenceElRect;
|
||||
|
||||
return isTopNavbar()
|
||||
? {
|
||||
// values are adjusted by any padding/margin differences
|
||||
left: -data.node.offsetLeft + 12,
|
||||
right: right - (data.node.offsetLeft + data.node.offsetWidth) - 12,
|
||||
top: -offsetTop + GRAFANA_HEADER_HEIGHT + 12,
|
||||
bottom: innerHeight - data.node.offsetHeight - offsetTop - 12,
|
||||
}
|
||||
: {
|
||||
left: -data.node.offsetLeft + 12 + GRAFANA_LEGACY_SIDEBAR_WIDTH,
|
||||
right: right - (data.node.offsetLeft + data.node.offsetWidth) - 12,
|
||||
top: -offsetTop + 12,
|
||||
bottom: bottom - data.node.offsetHeight - offsetTop - 12,
|
||||
};
|
||||
return {
|
||||
// values are adjusted by any padding/margin differences
|
||||
left: -data.node.offsetLeft + 12,
|
||||
right: right - (data.node.offsetLeft + data.node.offsetWidth) - 12,
|
||||
top: -offsetTop + GRAFANA_HEADER_HEIGHT + 12,
|
||||
bottom: innerHeight - data.node.offsetHeight - offsetTop - 12,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { GrafanaBootConfig } from '@grafana/runtime';
|
||||
import { OnCallAppPluginMeta } from 'app-types';
|
||||
|
||||
//@ts-ignore
|
||||
|
|
@ -9,8 +10,10 @@ export const PluginId = {
|
|||
} as const;
|
||||
export type PluginId = (typeof PluginId)[keyof typeof PluginId];
|
||||
|
||||
export const getIsIrmPluginPresent = () => PluginId.Irm in (window.grafanaBootData?.settings as GrafanaBootConfig).apps;
|
||||
|
||||
// Determine current environment: cloud, oss or local
|
||||
const CLOUD_VERSION_REGEX = /^(v\d+\.\d+\.\d+|github-actions-[a-zA-Z0-9-]+)$/
|
||||
const CLOUD_VERSION_REGEX = /^(v\d+\.\d+\.\d+|github-actions-[a-zA-Z0-9-]+)$/;
|
||||
const determineCurrentEnv = (): 'oss' | 'cloud' | 'local' => {
|
||||
if (CLOUD_VERSION_REGEX.test(plugin?.version)) {
|
||||
return 'cloud';
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ export class AlertReceiveChannelStore {
|
|||
this.rootStore = rootStore;
|
||||
}
|
||||
|
||||
@WithGlobalNotification({ failure: 'There was an issue creating Integration. Please try again.' })
|
||||
async create({
|
||||
data,
|
||||
skipErrorHandling,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ComponentClass } from 'react';
|
||||
|
||||
import { AppPlugin, PluginExtensionPoints } from '@grafana/data';
|
||||
import { IRM_TAB } from 'helpers/consts';
|
||||
import { getIsIrmPluginPresent, IRM_TAB } from 'helpers/consts';
|
||||
import { isCurrentGrafanaVersionEqualOrGreaterThan } from 'helpers/helpers';
|
||||
|
||||
import { MobileAppConnectionWrapper } from 'containers/MobileAppConnection/MobileAppConnection';
|
||||
|
|
@ -45,7 +45,8 @@ function isUseProfileExtensionPointEnabled(): boolean {
|
|||
isCurrentGrafanaVersionEqualOrGreaterThan({ minMajor: 10, minMinor: 3 }) &&
|
||||
'configureExtensionComponent' in plugin &&
|
||||
PluginExtensionPoints != null &&
|
||||
'UserProfileTab' in PluginExtensionPoints
|
||||
'UserProfileTab' in PluginExtensionPoints &&
|
||||
!getIsIrmPluginPresent()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { observer } from 'mobx-react';
|
|||
import gitHubStarSVG from 'assets/img/github_star.svg';
|
||||
import logo from 'assets/img/logo.svg';
|
||||
import { Alerts } from 'containers/Alerts/Alerts';
|
||||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
|
||||
import { getHeaderStyles } from './Header.styles';
|
||||
|
||||
|
|
@ -18,7 +17,7 @@ export const Header = observer(() => {
|
|||
return (
|
||||
<>
|
||||
<div>
|
||||
<div className={cx('page-header__inner', { [styles.headerTopNavbar]: isTopNavbar() })}>
|
||||
<div className={cx('page-header__inner', styles.headerTopNavbar)}>
|
||||
<div className={styles.navbarLeft}>
|
||||
<span className={cx('page-header__logo', styles.logoContainer)}>
|
||||
<img className={styles.pageHeaderImage} src={logo} alt="Grafana OnCall" />
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
|
||||
interface LegacyNavHeadingProps {
|
||||
children: JSX.Element;
|
||||
show?: boolean;
|
||||
}
|
||||
|
||||
export const LegacyNavHeading = function (props: LegacyNavHeadingProps): JSX.Element {
|
||||
const { show = !isTopNavbar(), children } = props;
|
||||
const { show = false, children } = props;
|
||||
return show ? children : null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ export const getIncidentStyles = (theme: GrafanaTheme2) => {
|
|||
|
||||
a {
|
||||
word-break: break-all;
|
||||
color: ${theme.colors.text.link};
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
|
|
|||
|
|
@ -196,17 +196,19 @@ class OutgoingWebhooks extends React.Component<OutgoingWebhooksProps, OutgoingWe
|
|||
}
|
||||
/>
|
||||
)}
|
||||
<div className={styles.newWebhookButton}>
|
||||
<PluginLink
|
||||
query={{ page: 'outgoing_webhooks', id: 'new' }}
|
||||
disabled={!isUserActionAllowed(UserActions.OutgoingWebhooksWrite)}
|
||||
>
|
||||
<WithPermissionControlTooltip userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Button variant="primary" icon="plus">
|
||||
New Outgoing Webhook
|
||||
</Button>
|
||||
</WithPermissionControlTooltip>
|
||||
</PluginLink>
|
||||
<div className={styles.relative}>
|
||||
<div className={styles.newWebhookButton}>
|
||||
<PluginLink
|
||||
query={{ page: 'outgoing_webhooks', id: 'new' }}
|
||||
disabled={!isUserActionAllowed(UserActions.OutgoingWebhooksWrite)}
|
||||
>
|
||||
<WithPermissionControlTooltip userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Button variant="primary" icon="plus">
|
||||
New Outgoing Webhook
|
||||
</Button>
|
||||
</WithPermissionControlTooltip>
|
||||
</PluginLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-testid="outgoing-webhooks-table">
|
||||
|
|
@ -464,10 +466,15 @@ const getStyles = () => {
|
|||
align-items: baseline;
|
||||
`,
|
||||
|
||||
relative: css`
|
||||
position: relative;
|
||||
padding-top: 16px;
|
||||
`,
|
||||
|
||||
newWebhookButton: css`
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -48px;
|
||||
top: -40px;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { UserActions, UserAction, isUserActionAllowed } from 'helpers/authorizat
|
|||
import { PLUGIN_ROOT } from 'helpers/consts';
|
||||
import { matchPath } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
import { AppFeature } from 'state/features';
|
||||
import { RootBaseStore } from 'state/rootBaseStore/RootBaseStore';
|
||||
|
||||
|
|
@ -109,7 +108,7 @@ export const pages: { [id: string]: PageDefinition } = [
|
|||
text: 'ChatOps',
|
||||
path: getPath('chat-ops'),
|
||||
hideFromBreadcrumbs: true,
|
||||
hideFromTabs: isTopNavbar(),
|
||||
hideFromTabs: true,
|
||||
action: UserActions.ChatOpsRead,
|
||||
},
|
||||
{
|
||||
|
|
@ -126,7 +125,7 @@ export const pages: { [id: string]: PageDefinition } = [
|
|||
text: 'Env Variables',
|
||||
hideFromTabsFn: (store: RootBaseStore) => {
|
||||
const hasLiveSettings = store.hasFeature(AppFeature.LiveSettings);
|
||||
return isTopNavbar() || !hasLiveSettings;
|
||||
return !hasLiveSettings;
|
||||
},
|
||||
path: getPath('live-settings'),
|
||||
action: UserActions.OtherSettingsRead,
|
||||
|
|
@ -137,7 +136,7 @@ export const pages: { [id: string]: PageDefinition } = [
|
|||
text: 'Cloud',
|
||||
hideFromTabsFn: (store: RootBaseStore) => {
|
||||
const hasCloudFeature = store.hasFeature(AppFeature.CloudConnection);
|
||||
return isTopNavbar() || !hasCloudFeature;
|
||||
return !hasCloudFeature;
|
||||
},
|
||||
path: getPath('cloud'),
|
||||
action: UserActions.OtherSettingsWrite,
|
||||
|
|
@ -161,7 +160,7 @@ export const pages: { [id: string]: PageDefinition } = [
|
|||
...current,
|
||||
getPageNav: (pageTitle: string) =>
|
||||
({
|
||||
text: isTopNavbar() ? '' : current.text,
|
||||
text: '',
|
||||
parentItem: current.getParentItem ? current.getParentItem(pageTitle) : undefined,
|
||||
hideFromBreadcrumbs: current.hideFromBreadcrumbs,
|
||||
hideFromTabs: current.hideFromTabs,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { observer } from 'mobx-react';
|
|||
|
||||
import { ChatOpsPage } from 'pages/settings/tabs/ChatOps/ChatOps';
|
||||
import { MainSettings } from 'pages/settings/tabs/MainSettings/MainSettings';
|
||||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
import { AppFeature } from 'state/features';
|
||||
import { WithStoreProps } from 'state/types';
|
||||
import { withMobXProviderContext } from 'state/withStore';
|
||||
|
|
@ -54,52 +53,48 @@ class Settings extends React.Component<SettingsPageProps, SettingsPageState> {
|
|||
const showCloudPage = hasCloudPage && isUserActionAllowed(UserActions.OtherSettingsWrite);
|
||||
const showLiveSettings = hasLiveSettings && isUserActionAllowed(UserActions.OtherSettingsRead);
|
||||
|
||||
if (isTopNavbar()) {
|
||||
return (
|
||||
<>
|
||||
<TabsBar>
|
||||
return (
|
||||
<>
|
||||
<TabsBar>
|
||||
<Tab
|
||||
key={SettingsPageTab.MainSettings.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.MainSettings.key)}
|
||||
active={activeTab === SettingsPageTab.MainSettings.key}
|
||||
label={SettingsPageTab.MainSettings.value}
|
||||
/>
|
||||
<Tab
|
||||
key={SettingsPageTab.ChatOps.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.ChatOps.key)}
|
||||
active={activeTab === SettingsPageTab.ChatOps.key}
|
||||
label={SettingsPageTab.ChatOps.value}
|
||||
/>
|
||||
<Tab
|
||||
key={SettingsPageTab.TeamsSettings.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.TeamsSettings.key)}
|
||||
active={activeTab === SettingsPageTab.TeamsSettings.key}
|
||||
label={SettingsPageTab.TeamsSettings.value}
|
||||
/>
|
||||
{showLiveSettings && (
|
||||
<Tab
|
||||
key={SettingsPageTab.MainSettings.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.MainSettings.key)}
|
||||
active={activeTab === SettingsPageTab.MainSettings.key}
|
||||
label={SettingsPageTab.MainSettings.value}
|
||||
key={SettingsPageTab.EnvVariables.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.EnvVariables.key)}
|
||||
active={activeTab === SettingsPageTab.EnvVariables.key}
|
||||
label={SettingsPageTab.EnvVariables.value}
|
||||
/>
|
||||
)}
|
||||
{showCloudPage && (
|
||||
<Tab
|
||||
key={SettingsPageTab.ChatOps.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.ChatOps.key)}
|
||||
active={activeTab === SettingsPageTab.ChatOps.key}
|
||||
label={SettingsPageTab.ChatOps.value}
|
||||
key={SettingsPageTab.Cloud.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.Cloud.key)}
|
||||
active={activeTab === SettingsPageTab.Cloud.key}
|
||||
label={SettingsPageTab.Cloud.value}
|
||||
/>
|
||||
<Tab
|
||||
key={SettingsPageTab.TeamsSettings.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.TeamsSettings.key)}
|
||||
active={activeTab === SettingsPageTab.TeamsSettings.key}
|
||||
label={SettingsPageTab.TeamsSettings.value}
|
||||
/>
|
||||
{showLiveSettings && (
|
||||
<Tab
|
||||
key={SettingsPageTab.EnvVariables.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.EnvVariables.key)}
|
||||
active={activeTab === SettingsPageTab.EnvVariables.key}
|
||||
label={SettingsPageTab.EnvVariables.value}
|
||||
/>
|
||||
)}
|
||||
{showCloudPage && (
|
||||
<Tab
|
||||
key={SettingsPageTab.Cloud.key}
|
||||
onChangeTab={() => onTabChange(SettingsPageTab.Cloud.key)}
|
||||
active={activeTab === SettingsPageTab.Cloud.key}
|
||||
label={SettingsPageTab.Cloud.value}
|
||||
/>
|
||||
)}
|
||||
</TabsBar>
|
||||
)}
|
||||
</TabsBar>
|
||||
|
||||
<TabsContent activeTab={activeTab} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return <MainSettings />;
|
||||
<TabsContent activeTab={activeTab} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
getMatchingPageNav() {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ import { LegacyNavHeading } from 'navbar/LegacyNavHeading';
|
|||
import { Text } from 'components/Text/Text';
|
||||
import { ApiTokenSettings } from 'containers/ApiTokenSettings/ApiTokenSettings';
|
||||
import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip';
|
||||
import { TeamsSettings } from 'pages/settings/tabs/TeamsSettings/TeamsSettings';
|
||||
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
||||
export const MainSettings = observer(() => {
|
||||
|
|
@ -50,14 +48,6 @@ export const MainSettings = observer(() => {
|
|||
</WithPermissionControlTooltip>
|
||||
</Field>
|
||||
</div>
|
||||
{!isTopNavbar() && (
|
||||
<div style={{ marginBottom: '20px' }}>
|
||||
<Text.Title level={3} className={styles.title}>
|
||||
Teams and Access Settings
|
||||
</Text.Title>
|
||||
<TeamsSettings />
|
||||
</div>
|
||||
)}
|
||||
<Text.Title level={3} className={styles.title}>
|
||||
API URL
|
||||
</Text.Title>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
import { config } from '@grafana/runtime';
|
||||
|
||||
export function isTopNavbar(): boolean {
|
||||
return !!config.featureToggles.topnav;
|
||||
}
|
||||
|
||||
export function getQueryParams(): any {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ import { DEFAULT_PAGE, getOnCallApiUrl } from 'helpers/consts';
|
|||
import { FaroHelper } from 'helpers/faro';
|
||||
import { useOnMount } from 'helpers/hooks';
|
||||
import { observer, Provider } from 'mobx-react';
|
||||
import { Header } from 'navbar/Header/Header';
|
||||
import { LegacyNavTabsBar } from 'navbar/LegacyNavTabsBar';
|
||||
import { Navigate, Route, Routes, useLocation } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { RenderConditionally } from 'components/RenderConditionally/RenderConditionally';
|
||||
|
|
@ -34,10 +32,10 @@ import { LiveSettings } from 'pages/settings/tabs/LiveSettings/LiveSettingsPage'
|
|||
import { UsersPage } from 'pages/users/Users';
|
||||
import { rootStore } from 'state/rootStore';
|
||||
import { useStore } from 'state/useStore';
|
||||
import 'assets/style/global.css';
|
||||
|
||||
import { getQueryParams, isTopNavbar } from './GrafanaPluginRootPage.helpers';
|
||||
import { getQueryParams } from './GrafanaPluginRootPage.helpers';
|
||||
|
||||
import globalStyles from '!raw-loader!assets/style/global.css';
|
||||
import grafanaGlobalStyle from '!raw-loader!assets/style/grafanaGlobalStyles.css';
|
||||
|
||||
export const GrafanaPluginRootPage = observer((props: AppRootProps) => {
|
||||
|
|
@ -86,6 +84,7 @@ export const Root = observer((props: AppRootProps) => {
|
|||
const styleEl = document.createElement('style');
|
||||
const head = document.head || document.getElementsByTagName('head')[0];
|
||||
styleEl.appendChild(document.createTextNode(grafanaGlobalStyle));
|
||||
styleEl.appendChild(document.createTextNode(globalStyles));
|
||||
|
||||
// append grafana overriding styles to head
|
||||
head.appendChild(styleEl);
|
||||
|
|
@ -112,22 +111,12 @@ export const Root = observer((props: AppRootProps) => {
|
|||
|
||||
return (
|
||||
<DefaultPageLayout {...props} page={page} pageNav={getPageNav()}>
|
||||
{!isTopNavbar() && (
|
||||
<>
|
||||
<Header />
|
||||
<LegacyNavTabsBar currentPage={page} />
|
||||
</>
|
||||
)}
|
||||
<div
|
||||
className={cx(
|
||||
css`
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
`,
|
||||
{
|
||||
'u-overflow-x-auto': !isTopNavbar(),
|
||||
'page-body': !isTopNavbar(),
|
||||
}
|
||||
)}
|
||||
>
|
||||
<RenderConditionally
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@
|
|||
export const GIT_COMMIT = 'dev';
|
||||
|
||||
// Declare a constant that will be updated by release-please action
|
||||
export const CURRENT_VERSION = '1.9.23' as string; // x-release-please-version
|
||||
export const CURRENT_VERSION = '1.9.27' as string; // x-release-please-version
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue