Skip to content

Commit

Permalink
feat: add Grafana IDs to users and teams public API endpoints (#5075)
Browse files Browse the repository at this point in the history
# What this PR does

- add Grafana IDs to users and teams public API endpoints
- update Schedules public API docs to reflect the fact that [we allow
filtering by
`team_id`](https://github.com/grafana/oncall/blob/dev/engine/apps/public_api/views/schedules.py#L42)

## Checklist

- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] Added the relevant release notes label (see labels prefixed w/
`release:`). These labels dictate how your PR will
    show up in the autogenerated release notes.
  • Loading branch information
joeyorlando authored Sep 24, 2024
1 parent fc58aaa commit 51c72fc
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 18 deletions.
1 change: 1 addition & 0 deletions docs/sources/oncall-api-reference/schedules.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ The above command returns JSON structured in the following way:
The following available filter parameter should be provided as a `GET` argument:

- `name` (Exact match)
- `team_id` (Exact match, team ID)

**HTTP request**

Expand Down
15 changes: 9 additions & 6 deletions docs/sources/oncall-api-reference/teams.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The above command returns JSON structured in the following way:
```json
{
"id": "TI73TDU19W48J",
"grafana_id": 123,
"name": "my test team",
"email": "",
"avatar_url": "/avatar/3f49c15916554246daa714b9bd0ee398"
Expand All @@ -38,12 +39,13 @@ The above command returns JSON structured in the following way:

`GET {{API_URL}}/api/v1/teams/<TEAM_ID>/`

| Parameter | Unique | Description |
| ---------- | :-----: | :----------------------------------------------------------------- |
| `id` | Yes/org | Team ID |
| `name` | Yes/org | Team name |
| `email` | Yes/org | Team e-mail |
| `avatar_url` | Yes | Avatar URL of the Grafana team |
| Parameter | Unique | Description |
| ----------------- | :-----: | :----------------------------- |
| `id` | Yes/org | OnCall team ID |
| `grafana_id` | Yes/org | Grafana team ID |
| `name` | Yes/org | Team name |
| `email` | Yes/org | Team e-mail |
| `avatar_url` | Yes | Avatar URL of the Grafana team |

## List Teams

Expand All @@ -64,6 +66,7 @@ The above command returns JSON structured in the following way:
"results": [
{
"id": "TI73TDU19W48J",
"grafana_id": 123,
"name": "my test team",
"email": "",
"avatar_url": "/avatar/3f49c15916554246daa714b9bd0ee398"
Expand Down
21 changes: 12 additions & 9 deletions docs/sources/oncall-api-reference/users.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The above command returns JSON structured in the following way:
```json
{
"id": "U4DNY931HHJS5",
"grafana_id": 456,
"email": "[email protected]",
"slack": [
{
Expand All @@ -48,15 +49,16 @@ The above command returns JSON structured in the following way:

Use `{{API_URL}}/api/v1/users/current` to retrieve the current user.

| Parameter | Unique | Description |
| ---------- | :-----: | :----------------------------------------------------------------- |
| `id` | Yes/org | User ID |
| `email` | Yes/org | User e-mail |
| `slack` | Yes/org | List of user IDs from connected Slack. User linking key is e-mail. |
| `username` | Yes/org | User username |
| `role` | No | One of: `user`, `observer`, `admin`. |
| `timezone` | No | timezone of the user one of [time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). |
| `teams` | No | List of team IDs the user belongs to |
| Parameter | Unique | Description |
| ----------------- | :-----: | :----------------------------------------------------------------- |
| `id` | Yes/org | OnCall user ID |
| `grafana_id` | Yes/org | Grafana user ID |
| `email` | Yes/org | User e-mail |
| `slack` | Yes/org | List of user IDs from connected Slack. User linking key is e-mail. |
| `username` | Yes/org | User username |
| `role` | No | One of: `user`, `observer`, `admin`. |
| `timezone` | No | timezone of the user one of [time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). |
| `teams` | No | List of team IDs the user belongs to |

## List Users

Expand All @@ -77,6 +79,7 @@ The above command returns JSON structured in the following way:
"results": [
{
"id": "U4DNY931HHJS5",
"grafana_id": 456,
"email": "[email protected]",
"slack": [
{
Expand Down
9 changes: 8 additions & 1 deletion engine/apps/public_api/serializers/teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@

class TeamSerializer(serializers.ModelSerializer):
id = serializers.CharField(read_only=True, source="public_primary_key")
grafana_id = serializers.IntegerField(read_only=True, source="team_id")

class Meta:
model = Team
fields = ("id", "name", "email", "avatar_url")
fields = [
"id",
"grafana_id",
"name",
"email",
"avatar_url",
]
23 changes: 21 additions & 2 deletions engine/apps/public_api/serializers/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,21 @@ class Meta:

class FastUserSerializer(serializers.ModelSerializer):
id: str = serializers.ReadOnlyField(read_only=True, source="public_primary_key")
grafana_id: int = serializers.IntegerField(read_only=True, source="user_id")
email: str = serializers.EmailField(read_only=True)
role: str = serializers.SerializerMethodField() # LEGACY, should be removed eventually
is_phone_number_verified: bool = serializers.SerializerMethodField()

class Meta:
model = User
fields = ["id", "email", "username", "role", "is_phone_number_verified"]
fields = [
"id",
"grafana_id",
"email",
"username",
"role",
"is_phone_number_verified",
]

@staticmethod
def get_role(obj: User) -> str:
Expand All @@ -41,6 +49,7 @@ def get_is_phone_number_verified(self, obj: User) -> bool:

class UserSerializer(serializers.ModelSerializer, EagerLoadingMixin):
id: str = serializers.ReadOnlyField(read_only=True, source="public_primary_key")
grafana_id: int = serializers.IntegerField(read_only=True, source="user_id")
email: str = serializers.EmailField(read_only=True)
slack: SlackUserIdentity = SlackUserIdentitySerializer(read_only=True, source="slack_user_identity")
role: str = serializers.SerializerMethodField() # LEGACY, should be removed eventually
Expand All @@ -55,7 +64,17 @@ class UserSerializer(serializers.ModelSerializer, EagerLoadingMixin):

class Meta:
model = User
fields = ["id", "email", "slack", "username", "role", "is_phone_number_verified", "timezone", "teams"]
fields = [
"id",
"grafana_id",
"email",
"slack",
"username",
"role",
"is_phone_number_verified",
"timezone",
"teams",
]
read_only_fields = ["timezone"]

@staticmethod
Expand Down
2 changes: 2 additions & 0 deletions engine/apps/public_api/tests/test_teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def test_get_teams_list(team_public_api_setup):
"results": [
{
"id": team.public_primary_key,
"grafana_id": team.team_id,
"name": team.name,
"email": team.email,
"avatar_url": team.avatar_url,
Expand All @@ -59,6 +60,7 @@ def test_get_team(team_public_api_setup):

expected_payload = {
"id": team.public_primary_key,
"grafana_id": team.team_id,
"name": team.name,
"email": team.email,
"avatar_url": team.avatar_url,
Expand Down
6 changes: 6 additions & 0 deletions engine/apps/public_api/tests/test_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def test_get_user(

expected_response = {
"id": user.public_primary_key,
"grafana_id": user.user_id,
"email": user.email,
"slack": {"user_id": slack_user_identity.slack_id, "team_id": slack_team_identity.slack_id},
"username": user.username,
Expand Down Expand Up @@ -72,6 +73,7 @@ def test_get_users_list(
"results": [
{
"id": user_1.public_primary_key,
"grafana_id": user_1.user_id,
"email": user_1.email,
"slack": {"user_id": slack_user_identity.slack_id, "team_id": slack_team_identity.slack_id},
"username": user_1.username,
Expand All @@ -82,6 +84,7 @@ def test_get_users_list(
},
{
"id": user_2.public_primary_key,
"grafana_id": user_2.user_id,
"email": user_2.email,
"slack": None,
"username": user_2.username,
Expand Down Expand Up @@ -120,13 +123,15 @@ def test_get_users_list_short(
"results": [
{
"id": user_1.public_primary_key,
"grafana_id": user_1.user_id,
"email": user_1.email,
"username": user_1.username,
"role": "admin",
"is_phone_number_verified": False,
},
{
"id": user_2.public_primary_key,
"grafana_id": user_2.user_id,
"email": user_2.email,
"username": user_2.username,
"role": "admin",
Expand Down Expand Up @@ -178,6 +183,7 @@ def test_get_users_list_all_role_users(user_public_api_setup, make_user_for_orga
"results": [
{
"id": user.public_primary_key,
"grafana_id": user.user_id,
"email": user.email,
"username": user.username,
"role": role,
Expand Down

0 comments on commit 51c72fc

Please sign in to comment.