moira-python-client 4.2.1__tar.gz → 4.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/CHANGELOG.md +8 -0
  2. {moira_python_client-4.2.1/moira_python_client.egg-info → moira_python_client-4.3.1}/PKG-INFO +1 -1
  3. moira_python_client-4.3.1/README.md +285 -0
  4. moira_python_client-4.3.1/VERSION.txt +1 -0
  5. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/contact.py +1 -0
  6. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/subscription.py +82 -52
  7. moira_python_client-4.3.1/moira_client/models/team/__init__.py +8 -0
  8. moira_python_client-4.3.1/moira_client/models/team/_managers.py +96 -0
  9. moira_python_client-4.3.1/moira_client/models/team/_models.py +19 -0
  10. moira_python_client-4.3.1/moira_client/models/team/contact/__init__.py +5 -0
  11. moira_python_client-4.3.1/moira_client/models/team/contact/_managers.py +24 -0
  12. moira_python_client-4.3.1/moira_client/models/team/settings/__init__.py +7 -0
  13. moira_python_client-4.3.1/moira_client/models/team/settings/_managers.py +23 -0
  14. moira_python_client-4.3.1/moira_client/models/team/settings/_models.py +11 -0
  15. moira_python_client-4.3.1/moira_client/models/team/subscription/__init__.py +5 -0
  16. moira_python_client-4.3.1/moira_client/models/team/subscription/_managers.py +30 -0
  17. moira_python_client-4.3.1/moira_client/models/team/user/__init__.py +7 -0
  18. moira_python_client-4.3.1/moira_client/models/team/user/_managers.py +43 -0
  19. moira_python_client-4.3.1/moira_client/models/team/user/_models.py +6 -0
  20. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/moira.py +11 -0
  21. {moira_python_client-4.2.1 → moira_python_client-4.3.1/moira_python_client.egg-info}/PKG-INFO +1 -1
  22. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_python_client.egg-info/SOURCES.txt +13 -0
  23. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/setup.py +6 -1
  24. moira_python_client-4.2.1/README.md +0 -128
  25. moira_python_client-4.2.1/VERSION.txt +0 -1
  26. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/LICENSE +0 -0
  27. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/MANIFEST.in +0 -0
  28. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/__init__.py +0 -0
  29. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/client.py +0 -0
  30. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/__init__.py +0 -0
  31. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/base.py +0 -0
  32. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/config.py +0 -0
  33. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/event.py +0 -0
  34. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/health.py +0 -0
  35. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/notification.py +0 -0
  36. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/pattern.py +0 -0
  37. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/tag.py +0 -0
  38. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/trigger.py +0 -0
  39. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_client/models/user.py +0 -0
  40. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_python_client.egg-info/dependency_links.txt +0 -0
  41. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_python_client.egg-info/requires.txt +0 -0
  42. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/moira_python_client.egg-info/top_level.txt +0 -0
  43. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/requirements.txt +0 -0
  44. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/setup.cfg +0 -0
  45. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/test-requirements.txt +0 -0
  46. {moira_python_client-4.2.1 → moira_python_client-4.3.1}/tests/test_client.py +0 -0
@@ -1,3 +1,11 @@
1
+ # 4.3.1
2
+
3
+ Fix package issues
4
+
5
+ # 4.3.0
6
+
7
+ Add support for Team APIs
8
+
1
9
  # 4.2.1
2
10
 
3
11
  Add support for name field in contacts
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: moira-python-client
3
- Version: 4.2.1
3
+ Version: 4.3.1
4
4
  Summary: Client for Moira - Alerting system based on Graphite data
5
5
  Home-page: https://github.com/moira-alert/python-moira-client
6
6
  Author: Alexander Lukyanchenko
@@ -0,0 +1,285 @@
1
+ [![Build Status](https://travis-ci.org/moira-alert/python-moira-client.svg?branch=master)](https://travis-ci.org/moira-alert/python-moira-client)
2
+
3
+ # Moira Client
4
+
5
+ If you're new here, better check out our main [README](https://github.com/moira-alert/moira/blob/master/README.md).
6
+
7
+ Python client for Moira.
8
+
9
+ # Installation
10
+
11
+ ```
12
+ pip install moira-python-client
13
+ ```
14
+
15
+ # Getting started
16
+
17
+ Initialize Moira client:
18
+ ```
19
+ from moira_client import Moira
20
+
21
+ moira = Moira('http://localhost:8888/api/')
22
+ ```
23
+
24
+ ## Triggers
25
+
26
+ ### Create new trigger
27
+ ```
28
+ from moira_client.models.trigger import STATE_ERROR
29
+
30
+ trigger = moira.trigger.create(
31
+ id='service_trigger_name',
32
+ name='Trigger name',
33
+ tags=['service'],
34
+ targets=['prefix.service.*.postfix'],
35
+ warn_value=300,
36
+ error_value=600,
37
+ desc='my trigger',
38
+ ttl_state=STATE_ERROR
39
+ )
40
+
41
+ trigger.disable_day('Tue')
42
+ trigger.save()
43
+ print(trigger.id)
44
+ ```
45
+
46
+ > **Note:** id parameter is not required but highly recommended for large production solutions <br>
47
+ > (e.q. fetch_by_id will work faster than is_exist).
48
+ > If parameter is not specified, random trigger guid will be generated.
49
+
50
+ ### Update triggers
51
+ Turn off all triggers for Monday.
52
+ ```
53
+ triggers = moira.trigger.fetch_all()
54
+ for trigger in triggers:
55
+ trigger.disable_day('Mon')
56
+ trigger.update()
57
+ ```
58
+
59
+ ### Delete trigger
60
+ ```
61
+ trigger = moira.trigger.fetch_by_id('bb1a8514-128b-406e-bec3-25e94153ab30')
62
+ moira.trigger.delete(trigger.id)
63
+ ```
64
+
65
+ ### Check whether trigger exists or not (manually)
66
+ ```
67
+ trigger = moira.trigger.create(
68
+ name='service',
69
+ targets=['service.rps'],
70
+ tags=['ops']
71
+ )
72
+
73
+ if not moira.trigger.is_exist(trigger):
74
+ trigger.save()
75
+ ```
76
+
77
+ ### Get non existent triggers
78
+ ```
79
+ trigger1 = moira.trigger.create(
80
+ name='service',
81
+ targets=['service.rps'],
82
+ tags=['ops']
83
+ )
84
+
85
+ trigger2 = moira.trigger.create(
86
+ name='site',
87
+ targets=['site.rps'],
88
+ tags=['ops']
89
+ )
90
+
91
+ triggers = [trigger1, trigger2]
92
+
93
+ non_existent_triggers = moira.trigger.get_non_existent(triggers)
94
+ ```
95
+
96
+ ## Subscription
97
+
98
+ ### Create subscription
99
+ ```
100
+ subscription = moira.subscription.create(
101
+ contacts=['79ac9de2-a3b3-4f94-b3ea-74f6f4094fd2'],
102
+ tags=['tag']
103
+ )
104
+ subscription.save()
105
+ ```
106
+
107
+ ### Delete subscription
108
+ Delete all subscriptions
109
+ ```
110
+ subscriptions = moira.subscription.fetch_all()
111
+ for subscription in subscriptions:
112
+ moira.subscription.delete(subscription.id)
113
+ ```
114
+
115
+ ## Contact
116
+
117
+ ### Get all contacts
118
+ ```
119
+ contacts = moira.contact.fetch_all()
120
+ for contact in contacts:
121
+ print(contact.id)
122
+ ```
123
+
124
+ ### Get contact id by type and value
125
+ ```
126
+ contact_id = moira.contact.get_id(type='slack', value='#err')
127
+ print(contact_id)
128
+ ```
129
+
130
+ ## Team
131
+
132
+ ### Get all teams
133
+ ```python
134
+ teams = moira.team.get_all()
135
+ ```
136
+
137
+ ### Create a new team
138
+ ```python
139
+ from moira_client.models.team import TeamModel
140
+
141
+ team = TeamModel(
142
+ description="Team that holds all members of infrastructure division",
143
+ name="Infrastructure Team",
144
+ )
145
+
146
+ saved_team = moira.team.create(team)
147
+ ```
148
+
149
+ ### Delete a team
150
+ ```python
151
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
152
+
153
+ deleted_team = moira.team.delete(team_id)
154
+ ```
155
+
156
+ ### Get a team by ID
157
+ ```python
158
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
159
+
160
+ team = moira.team.get(team_id)
161
+ ```
162
+
163
+ ### Update existing team
164
+ ```python
165
+ from moira_client.models.team import TeamModel
166
+
167
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
168
+ team = TeamModel(
169
+ description="Team that holds all members of infrastructure division",
170
+ name="Infrastructure Team",
171
+ )
172
+
173
+ updated_team = moira.team.update(team_id, team)
174
+ ```
175
+
176
+ ### Team Settings
177
+
178
+ #### Get team settings
179
+ ```python
180
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
181
+
182
+ settings = moira.team.settings.get(team_id)
183
+ ```
184
+
185
+ ### Team User
186
+
187
+ #### Get users of a team
188
+
189
+ ```python
190
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
191
+
192
+ users = moira.team.user.get(team_id)
193
+ ```
194
+
195
+ #### Add users to a team
196
+
197
+ ```python
198
+ from moira_client.models.team.user import TeamMembers
199
+
200
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
201
+ users_to_add = TeamMembers(usernames=["anonymous", ])
202
+
203
+ users = moira.team.user.add(team_id, users_to_add)
204
+ ```
205
+
206
+ #### Set users of a team
207
+
208
+ ```python
209
+ from moira_client.models.team.user import TeamMembers
210
+
211
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
212
+ users_to_set = TeamMembers(usernames=["anonymous", ])
213
+
214
+ users = moira.team.user.set(team_id, users_to_set)
215
+ ```
216
+
217
+ #### Delete a user from a team
218
+
219
+ ```python
220
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
221
+ team_user_id = "anonymous"
222
+
223
+ users = moira.team.user.delete(team_id, team_user_id)
224
+ ```
225
+
226
+ ### Team Subscription
227
+
228
+ #### Create a new team subscription
229
+
230
+ ```python
231
+ from moira_client.models.subscription import SubscriptionModel
232
+
233
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
234
+ subscription_to_create = SubscriptionModel(
235
+ any_tags=False,
236
+ contacts=[
237
+ "acd2db98-1659-4a2f-b227-52d71f6e3ba1"
238
+ ],
239
+ enabled=True,
240
+ ignore_recoverings=False,
241
+ ignore_warnings=False,
242
+ plotting={
243
+ "enabled": True,
244
+ "theme": "dark"
245
+ },
246
+ sched={
247
+ "days": [
248
+ {
249
+ "enabled": True,
250
+ "name": "Mon"
251
+ }
252
+ ],
253
+ "endOffset": 1439,
254
+ "startOffset": 0,
255
+ "tzOffset": -60
256
+ },
257
+ tags=[
258
+ "server",
259
+ "cpu"
260
+ ],
261
+ throttling=False,
262
+ user="",
263
+ )
264
+
265
+ subscription = moira.team.subscription.create(team_id, subscription_to_create)
266
+ ```
267
+
268
+ ### Team Contact
269
+
270
+ #### Create a new team contact
271
+
272
+ ```python
273
+ from moira_client.models.contact import Contact
274
+
275
+ team_id = "d5d98eb3-ee18-4f75-9364-244f67e23b54"
276
+ contact_to_create = Contact(
277
+ name="Mail Alerts",
278
+ team_id=team_id,
279
+ type="mail",
280
+ user="",
281
+ value="devops@example.com",
282
+ )
283
+
284
+ contact = moira.team.contact.create(team_id, contact_to_create)
285
+ ```
@@ -0,0 +1 @@
1
+ 4.3.1
@@ -23,6 +23,7 @@ class Contact(Base):
23
23
  self.user = kwargs.get('user', None)
24
24
  self.name = kwargs.get('name', None)
25
25
  self._id = kwargs.get('id', None)
26
+ self.team_id = kwargs.get('team_id', None)
26
27
 
27
28
 
28
29
  class ContactManager:
@@ -2,12 +2,10 @@ from ..client import InvalidJSONError
2
2
  from ..client import ResponseStructureError
3
3
  from .base import Base
4
4
 
5
- class Subscription(Base):
6
- def __init__(self, client, tags, contacts=None, enabled=None, throttling=None, sched=None,
5
+ class SubscriptionModel(Base):
6
+ def __init__(self, tags, contacts=None, enabled=None, throttling=None, sched=None,
7
7
  ignore_warnings=False, ignore_recoverings=False, plotting=None, any_tags=False, **kwargs):
8
8
  """
9
-
10
- :param client: api client
11
9
  :param tags: list of str tags
12
10
  :param contacts: list of contact id's
13
11
  :param enabled: bool is enabled
@@ -19,8 +17,6 @@ class Subscription(Base):
19
17
  :param any_tags: bool any tags
20
18
  :param kwargs: additional parameters
21
19
  """
22
- self._client = client
23
-
24
20
  self._id = kwargs.get('id', None)
25
21
  self.tags = tags if not any_tags else []
26
22
  if not contacts:
@@ -38,32 +34,7 @@ class Subscription(Base):
38
34
  if not plotting:
39
35
  plotting = {'enabled': False, 'theme': 'light'}
40
36
  self.plotting = plotting
41
-
42
- def _send_request(self, subscription_id=None):
43
- data = {
44
- 'contacts': self.contacts,
45
- 'tags': self.tags,
46
- 'enabled': self.enabled,
47
- 'any_tags': self.any_tags,
48
- 'throttling': self.throttling,
49
- 'sched': self.sched,
50
- 'ignore_warnings': self.ignore_warnings,
51
- 'ignore_recoverings': self.ignore_recoverings,
52
- 'plotting': self.plotting
53
- }
54
-
55
- if subscription_id:
56
- data['id'] = subscription_id
57
-
58
- if subscription_id:
59
- result = self._client.put('subscription/{id}'.format(id=subscription_id), json=data)
60
- else:
61
- result = self._client.put('subscription', json=data)
62
- if 'id' not in result:
63
- raise ResponseStructureError("id doesn't exist in response", result)
64
-
65
- self._id = result['id']
66
- return self._id
37
+ self.team_id = kwargs.get('team_id', None)
67
38
 
68
39
  def disable_day(self, day):
69
40
  """
@@ -124,26 +95,6 @@ class Subscription(Base):
124
95
  'theme': 'light'
125
96
  }
126
97
 
127
- def save(self):
128
- """
129
- Save subscription
130
-
131
- :return: subscription id
132
- """
133
- if self._id:
134
- return self.update()
135
- self._send_request()
136
-
137
- def update(self):
138
- """
139
- Update subscription
140
-
141
- :return: subscription id
142
- """
143
- if not self._id:
144
- return self.save()
145
- self._send_request(self._id)
146
-
147
98
  def set_start_hour(self, hour):
148
99
  """
149
100
  Set start hour
@@ -185,6 +136,85 @@ class Subscription(Base):
185
136
  self._end_minute = minute
186
137
 
187
138
 
139
+ class Subscription(SubscriptionModel):
140
+ def __init__(self, client, tags, contacts=None, enabled=None, throttling=None, sched=None,
141
+ ignore_warnings=False, ignore_recoverings=False, plotting=None, any_tags=False, **kwargs):
142
+ """
143
+ :param client: api client
144
+ :param tags: list of str tags
145
+ :param contacts: list of contact id's
146
+ :param enabled: bool is enabled
147
+ :param throttling: bool throttling
148
+ :param sched: dict schedule
149
+ :param ignore_warnings: bool ignore warnings
150
+ :param ignore_recoverings: bool ignore recoverings
151
+ :param plotting: dict plotting settings
152
+ :param any_tags: bool any tags
153
+ :param kwargs: additional parameters
154
+ """
155
+ self._client = client
156
+
157
+ super().__init__(
158
+ tags=tags,
159
+ contacts=contacts,
160
+ enabled=enabled,
161
+ throttling=throttling,
162
+ sched=sched,
163
+ ignore_warnings=ignore_warnings,
164
+ ignore_recoverings=ignore_recoverings,
165
+ plotting=plotting,
166
+ any_tags=any_tags,
167
+ **kwargs,
168
+ )
169
+
170
+ def _send_request(self, subscription_id=None):
171
+ data = {
172
+ 'contacts': self.contacts,
173
+ 'tags': self.tags,
174
+ 'enabled': self.enabled,
175
+ 'any_tags': self.any_tags,
176
+ 'throttling': self.throttling,
177
+ 'sched': self.sched,
178
+ 'ignore_warnings': self.ignore_warnings,
179
+ 'ignore_recoverings': self.ignore_recoverings,
180
+ 'plotting': self.plotting,
181
+ 'team_id': self.team_id,
182
+ }
183
+
184
+ if subscription_id:
185
+ data['id'] = subscription_id
186
+
187
+ if subscription_id:
188
+ result = self._client.put('subscription/{id}'.format(id=subscription_id), json=data)
189
+ else:
190
+ result = self._client.put('subscription', json=data)
191
+ if 'id' not in result:
192
+ raise ResponseStructureError("id doesn't exist in response", result)
193
+
194
+ self._id = result['id']
195
+ return self._id
196
+
197
+ def save(self):
198
+ """
199
+ Save subscription
200
+
201
+ :return: subscription id
202
+ """
203
+ if self._id:
204
+ return self.update()
205
+ self._send_request()
206
+
207
+ def update(self):
208
+ """
209
+ Update subscription
210
+
211
+ :return: subscription id
212
+ """
213
+ if not self._id:
214
+ return self.save()
215
+ self._send_request(self._id)
216
+
217
+
188
218
  class SubscriptionManager:
189
219
  def __init__(self, client):
190
220
  self._client = client
@@ -0,0 +1,8 @@
1
+ from ._managers import TeamManager
2
+ from ._models import TeamModel
3
+
4
+
5
+ __all__ = [
6
+ "TeamManager",
7
+ "TeamModel",
8
+ ]
@@ -0,0 +1,96 @@
1
+ from typing import Optional
2
+
3
+ from ._models import TeamModel, UserTeams, SaveTeamResponse
4
+ from .contact import TeamContactManager
5
+ from .settings import TeamSettingsManager
6
+ from .subscription import TeamSubscriptionManager
7
+ from .user import TeamUserManager
8
+ from ...client import Client
9
+
10
+
11
+ class TeamManager:
12
+ def __init__(self, client: Client) -> None:
13
+ self._client = client
14
+ self._user = None # type: Optional[TeamUserManager]
15
+ self._settings = None # type: Optional[TeamSettingsManager]
16
+ self._subscription = None # type: Optional[TeamSubscriptionManager]
17
+ self._contact = None # type: Optional[TeamContactManager]
18
+
19
+ def get_all(self) -> UserTeams:
20
+ """Get all teams"""
21
+ response = self._client.get(self._full_path())
22
+
23
+ return UserTeams(teams=[TeamModel(**team) for team in response["teams"]])
24
+
25
+ def create(self, team: TeamModel) -> SaveTeamResponse:
26
+ """Create a new team"""
27
+ payload = {
28
+ "name": team.name,
29
+ "description": team.description,
30
+ }
31
+
32
+ response = self._client.post(self._full_path(), json=payload)
33
+
34
+ return SaveTeamResponse(**response)
35
+
36
+ def delete(self, team_id: str) -> SaveTeamResponse:
37
+ """Delete a team"""
38
+ response = self._client.delete(self._full_path(team_id))
39
+
40
+ return SaveTeamResponse(**response)
41
+
42
+ def get(self, team_id: str) -> TeamModel:
43
+ """Get a team by ID"""
44
+ response = self._client.get(self._full_path(team_id))
45
+
46
+ return TeamModel(**response)
47
+
48
+ def update(self, team_id: str, team: TeamModel) -> SaveTeamResponse:
49
+ """Update existing team"""
50
+ payload = {
51
+ "name": team.name,
52
+ "description": team.description,
53
+ }
54
+
55
+ response = self._client.put(self._full_path(team_id), json=payload)
56
+
57
+ return SaveTeamResponse(**response)
58
+
59
+ @property
60
+ def user(self) -> TeamUserManager:
61
+ """Get team user manager"""
62
+ if self._user is None:
63
+ self._user = TeamUserManager(self._client)
64
+
65
+ return self._user
66
+
67
+ @property
68
+ def settings(self) -> TeamSettingsManager:
69
+ """Get team settings manager"""
70
+ if self._settings is None:
71
+ self._settings = TeamSettingsManager(self._client)
72
+
73
+ return self._settings
74
+
75
+ @property
76
+ def subscription(self) -> TeamSubscriptionManager:
77
+ """Get team subscription manager"""
78
+ if self._subscription is None:
79
+ self._subscription = TeamSubscriptionManager(self._client)
80
+
81
+ return self._subscription
82
+
83
+ @property
84
+ def contact(self) -> TeamContactManager:
85
+ """Get team contact manager"""
86
+ if self._contact is None:
87
+ self._contact = TeamContactManager(self._client)
88
+
89
+ return self._contact
90
+
91
+ @staticmethod
92
+ def _full_path(team_id: Optional[str] = None) -> str:
93
+ if team_id is None:
94
+ return "teams"
95
+
96
+ return "teams/{team_id}".format(team_id=team_id)
@@ -0,0 +1,19 @@
1
+ from ..base import Base
2
+ from typing import List
3
+
4
+
5
+ class TeamModel(Base):
6
+ def __init__(self, description: str, name: str, **kwargs):
7
+ self.description = description
8
+ self.name = name
9
+ self._id = kwargs.get("id", None)
10
+
11
+
12
+ class UserTeams:
13
+ def __init__(self, teams: List[TeamModel]):
14
+ self.teams = teams
15
+
16
+
17
+ class SaveTeamResponse(Base):
18
+ def __init__(self, **kwargs):
19
+ self._id = kwargs.get("id")
@@ -0,0 +1,5 @@
1
+ from ._managers import TeamContactManager
2
+
3
+ __all__ = [
4
+ "TeamContactManager",
5
+ ]
@@ -0,0 +1,24 @@
1
+ from ...contact import Contact
2
+ from ....client import Client
3
+
4
+
5
+ class TeamContactManager:
6
+ def __init__(self, client: Client) -> None:
7
+ self._client = client
8
+
9
+ def create(self, team_id: str, contact: Contact) -> Contact:
10
+ """Create a new team contact"""
11
+ payload = {
12
+ "team_id": team_id,
13
+ "name": contact.name,
14
+ "type": contact.type,
15
+ "value": contact.value,
16
+ }
17
+
18
+ response = self._client.post(self._full_path(team_id), json=payload)
19
+
20
+ return Contact(**response)
21
+
22
+ @staticmethod
23
+ def _full_path(team_id: str) -> str:
24
+ return "teams/{team_id}/contacts".format(team_id=team_id)
@@ -0,0 +1,7 @@
1
+ from ._managers import TeamSettingsManager
2
+ from ._models import TeamSettings
3
+
4
+ __all__ = [
5
+ "TeamSettings",
6
+ "TeamSettingsManager",
7
+ ]
@@ -0,0 +1,23 @@
1
+ from ._models import TeamSettings
2
+ from ...contact import Contact
3
+ from ...subscription import Subscription
4
+ from ....client import Client
5
+
6
+
7
+ class TeamSettingsManager:
8
+ def __init__(self, client: Client) -> None:
9
+ self._client = client
10
+
11
+ def get(self, team_id: str) -> TeamSettings:
12
+ """Get team settings"""
13
+ response = self._client.get(self._full_path(team_id))
14
+
15
+ return TeamSettings(
16
+ contacts=[Contact(**contact) for contact in response["contacts"]],
17
+ subscriptions=[Subscription(self._client, **subscription) for subscription in response["subscriptions"]],
18
+ team_id=response["team_id"],
19
+ )
20
+
21
+ @staticmethod
22
+ def _full_path(team_id: str) -> str:
23
+ return "teams/{team_id}/settings".format(team_id=team_id)
@@ -0,0 +1,11 @@
1
+ from typing import List
2
+
3
+ from ...contact import Contact
4
+ from ...subscription import Subscription
5
+
6
+
7
+ class TeamSettings:
8
+ def __init__(self, contacts: List[Contact], subscriptions: List[Subscription], team_id: str) -> None:
9
+ self.contacts = contacts
10
+ self.subscriptions = subscriptions
11
+ self.team_id = team_id
@@ -0,0 +1,5 @@
1
+ from ._managers import TeamSubscriptionManager
2
+
3
+ __all__ = [
4
+ "TeamSubscriptionManager",
5
+ ]
@@ -0,0 +1,30 @@
1
+ from ...subscription import SubscriptionModel, Subscription
2
+ from ....client import Client
3
+
4
+
5
+ class TeamSubscriptionManager:
6
+ def __init__(self, client: Client) -> None:
7
+ self._client = client
8
+
9
+ def create(self, team_id: str, subscription: SubscriptionModel) -> Subscription:
10
+ """Create a new team subscription"""
11
+ payload = {
12
+ "team_id": team_id,
13
+ "contacts": subscription.contacts,
14
+ "tags": subscription.tags,
15
+ "enabled": subscription.enabled,
16
+ "any_tags": subscription.any_tags,
17
+ "throttling": subscription.throttling,
18
+ "sched": subscription.sched,
19
+ "ignore_warnings": subscription.ignore_warnings,
20
+ "ignore_recoverings": subscription.ignore_recoverings,
21
+ "plotting": subscription.plotting,
22
+ }
23
+
24
+ response = self._client.post(self._full_path(team_id), json=payload)
25
+
26
+ return Subscription(self._client, **response)
27
+
28
+ @staticmethod
29
+ def _full_path(team_id: str) -> str:
30
+ return "teams/{team_id}/subscriptions".format(team_id=team_id)
@@ -0,0 +1,7 @@
1
+ from ._managers import TeamUserManager
2
+ from ._models import TeamMembers
3
+
4
+ __all__ = [
5
+ "TeamMembers",
6
+ "TeamUserManager",
7
+ ]
@@ -0,0 +1,43 @@
1
+ from ._models import TeamMembers
2
+ from ....client import Client
3
+ from typing import Optional
4
+
5
+
6
+ class TeamUserManager:
7
+ def __init__(self, client: Client) -> None:
8
+ self._client = client
9
+
10
+ def get(self, team_id: str) -> TeamMembers:
11
+ """Get users of a team"""
12
+ response = self._client.get(self._full_path(team_id))
13
+
14
+ return TeamMembers(**response)
15
+
16
+ def add(self, team_id: str, members: TeamMembers) -> TeamMembers:
17
+ """Add users to a team"""
18
+ payload = {"usernames": members.usernames}
19
+
20
+ response = self._client.post(self._full_path(team_id), json=payload)
21
+
22
+ return TeamMembers(**response)
23
+
24
+ def set(self, team_id: str, members: TeamMembers) -> TeamMembers:
25
+ """Set users of a team"""
26
+ payload = {"usernames": members.usernames}
27
+
28
+ response = self._client.put(self._full_path(team_id), json=payload)
29
+
30
+ return TeamMembers(**response)
31
+
32
+ def delete(self, team_id: str, team_user_id: str) -> TeamMembers:
33
+ """Delete a user from a team"""
34
+ response = self._client.delete(self._full_path(team_id, team_user_id))
35
+
36
+ return TeamMembers(**response)
37
+
38
+ @staticmethod
39
+ def _full_path(team_id: str, team_user_id: Optional[str] = None) -> str:
40
+ if team_user_id is None:
41
+ return "teams/{team_id}/users".format(team_id=team_id)
42
+
43
+ return "teams/{team_id}/users/{team_user_id}".format(team_id=team_id, team_user_id=team_user_id)
@@ -0,0 +1,6 @@
1
+ from typing import List
2
+
3
+
4
+ class TeamMembers:
5
+ def __init__(self, usernames: List[str]) -> None:
6
+ self.usernames = usernames
@@ -9,6 +9,7 @@ from .models.trigger import TriggerManager
9
9
  from .models.health import HealthManager
10
10
  from .models.config import ConfigManager
11
11
  from .models.user import UserManager
12
+ from .models.team import TeamManager
12
13
 
13
14
 
14
15
  class Moira:
@@ -34,6 +35,7 @@ class Moira:
34
35
  self._health = None
35
36
  self._config = None
36
37
  self._user = None
38
+ self._team = None
37
39
 
38
40
  @property
39
41
  def trigger(self):
@@ -145,3 +147,12 @@ class Moira:
145
147
  if not self._user:
146
148
  self._user = UserManager(self._client)
147
149
  return self._user
150
+
151
+ @property
152
+ def team(self) -> TeamManager:
153
+ """Get team manager
154
+ """
155
+ if not self._team:
156
+ self._team = TeamManager(self._client)
157
+
158
+ return self._team
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: moira-python-client
3
- Version: 4.2.1
3
+ Version: 4.3.1
4
4
  Summary: Client for Moira - Alerting system based on Graphite data
5
5
  Home-page: https://github.com/moira-alert/python-moira-client
6
6
  Author: Alexander Lukyanchenko
@@ -22,6 +22,19 @@ moira_client/models/subscription.py
22
22
  moira_client/models/tag.py
23
23
  moira_client/models/trigger.py
24
24
  moira_client/models/user.py
25
+ moira_client/models/team/__init__.py
26
+ moira_client/models/team/_managers.py
27
+ moira_client/models/team/_models.py
28
+ moira_client/models/team/contact/__init__.py
29
+ moira_client/models/team/contact/_managers.py
30
+ moira_client/models/team/settings/__init__.py
31
+ moira_client/models/team/settings/_managers.py
32
+ moira_client/models/team/settings/_models.py
33
+ moira_client/models/team/subscription/__init__.py
34
+ moira_client/models/team/subscription/_managers.py
35
+ moira_client/models/team/user/__init__.py
36
+ moira_client/models/team/user/_managers.py
37
+ moira_client/models/team/user/_models.py
25
38
  moira_python_client.egg-info/PKG-INFO
26
39
  moira_python_client.egg-info/SOURCES.txt
27
40
  moira_python_client.egg-info/dependency_links.txt
@@ -23,7 +23,12 @@ setup(
23
23
  author_email = 'al.lukyanchenko@gmail.com',
24
24
  packages=[
25
25
  'moira_client',
26
- 'moira_client.models'
26
+ 'moira_client.models',
27
+ 'moira_client.models.team',
28
+ 'moira_client.models.team.contact',
29
+ 'moira_client.models.team.settings',
30
+ 'moira_client.models.team.subscription',
31
+ 'moira_client.models.team.user',
27
32
  ],
28
33
  classifiers=[
29
34
  'Development Status :: 4 - Beta',
@@ -1,128 +0,0 @@
1
- [![Build Status](https://travis-ci.org/moira-alert/python-moira-client.svg?branch=master)](https://travis-ci.org/moira-alert/python-moira-client)
2
-
3
- # Moira Client
4
-
5
- If you're new here, better check out our main [README](https://github.com/moira-alert/moira/blob/master/README.md).
6
-
7
- Python client for Moira.
8
-
9
- # Installation
10
-
11
- ```
12
- pip install moira-python-client
13
- ```
14
-
15
- # Getting started
16
-
17
- Initialize Moira client:
18
- ```
19
- from moira_client import Moira
20
-
21
- moira = Moira('http://localhost:8888/api/')
22
- ```
23
-
24
- ## Triggers
25
-
26
- ### Create new trigger
27
- ```
28
- from moira_client.models.trigger import STATE_ERROR
29
-
30
- trigger = moira.trigger.create(
31
- id='service_trigger_name',
32
- name='Trigger name',
33
- tags=['service'],
34
- targets=['prefix.service.*.postfix'],
35
- warn_value=300,
36
- error_value=600,
37
- desc='my trigger',
38
- ttl_state=STATE_ERROR
39
- )
40
-
41
- trigger.disable_day('Tue')
42
- trigger.save()
43
- print(trigger.id)
44
- ```
45
-
46
- > **Note:** id parameter is not required but highly recommended for large production solutions <br>
47
- > (e.q. fetch_by_id will work faster than is_exist).
48
- > If parameter is not specified, random trigger guid will be generated.
49
-
50
- ### Update triggers
51
- Turn off all triggers for Monday.
52
- ```
53
- triggers = moira.trigger.fetch_all()
54
- for trigger in triggers:
55
- trigger.disable_day('Mon')
56
- trigger.update()
57
- ```
58
-
59
- ### Delete trigger
60
- ```
61
- trigger = moira.trigger.fetch_by_id('bb1a8514-128b-406e-bec3-25e94153ab30')
62
- moira.trigger.delete(trigger.id)
63
- ```
64
-
65
- ### Check whether trigger exists or not (manually)
66
- ```
67
- trigger = moira.trigger.create(
68
- name='service',
69
- targets=['service.rps'],
70
- tags=['ops']
71
- )
72
-
73
- if not moira.trigger.is_exist(trigger):
74
- trigger.save()
75
- ```
76
-
77
- ### Get non existent triggers
78
- ```
79
- trigger1 = moira.trigger.create(
80
- name='service',
81
- targets=['service.rps'],
82
- tags=['ops']
83
- )
84
-
85
- trigger2 = moira.trigger.create(
86
- name='site',
87
- targets=['site.rps'],
88
- tags=['ops']
89
- )
90
-
91
- triggers = [trigger1, trigger2]
92
-
93
- non_existent_triggers = moira.trigger.get_non_existent(triggers)
94
- ```
95
-
96
- ## Subscription
97
-
98
- ### Create subscription
99
- ```
100
- subscription = moira.subscription.create(
101
- contacts=['79ac9de2-a3b3-4f94-b3ea-74f6f4094fd2'],
102
- tags=['tag']
103
- )
104
- subscription.save()
105
- ```
106
-
107
- ### Delete subscription
108
- Delete all subscriptions
109
- ```
110
- subscriptions = moira.subscription.fetch_all()
111
- for subscription in subscriptions:
112
- moira.subscription.delete(subscription.id)
113
- ```
114
-
115
- ## Contact
116
-
117
- ### Get all contacts
118
- ```
119
- contacts = moira.contact.fetch_all()
120
- for contact in contacts:
121
- print(contact.id)
122
- ```
123
-
124
- ### Get contact id by type and value
125
- ```
126
- contact_id = moira.contact.get_id(type='slack', value='#err')
127
- print(contact_id)
128
- ```
@@ -1 +0,0 @@
1
- 4.2.1