Skip to content

Commit 5b3a26a

Browse files
Adityashankar KiniAdityashankar Kini
authored andcommitted
Merge branch 'teams-api' of https://github.com/draios/python-sdc-client into teams-api
2 parents b13e90b + ef027e5 commit 5b3a26a

File tree

6 files changed

+179
-99
lines changed

6 files changed

+179
-99
lines changed

.travis.yml

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,34 @@ script:
2828
- examples/print_explore_grouping.py XXX
2929
- examples/print_user_info.py XXX
3030
- examples/list_sysdig_captures.py XXX
31-
- examples/create_sysdig_capture.py XXX ip-10-0-2-202.ec2.internal apicapture 10
31+
- examples/create_sysdig_capture.py XXX ip-10-0-1-110.ec2.internal apicapture 10
32+
- examples/notification_channels.py XXX
3233
- echo "Testing pip version"
3334
- rm -rf sdcclient
3435
- pip install sdcclient
35-
- examples/create_alert.py XXX
36-
- examples/delete_alert.py XXX
37-
- examples/dashboard.py XXX
38-
- examples/create_dashboard.py XXX
39-
- examples/delete_dashboard.py XXX
40-
- examples/get_data_advanced.py XXX ip-10-0-2-180.ec2.internal
41-
- examples/get_data_datasource.py XXX
42-
- examples/get_data_simple.py XXX
43-
- examples/list_alerts.py XXX
44-
- examples/list_alert_notifications.py XXX
45-
- examples/resolve_alert_notifications.py XXX 1
46-
- examples/list_dashboards.py XXX
47-
- examples/list_hosts.py XXX
48-
- examples/list_metrics.py XXX
49-
- examples/post_event.py XXX "test event name" -d "test event description"
50-
- examples/post_event_simple.py XXX "test event name" "test event description"
51-
- examples/list_events.py XXX
52-
- examples/delete_event.py XXX
53-
- examples/print_data_retention_info.py XXX
54-
- examples/print_explore_grouping.py XXX
55-
- examples/print_user_info.py XXX
56-
- examples/list_sysdig_captures.py XXX
57-
- examples/create_sysdig_capture.py XXX ip-10-0-2-202.ec2.internal apicapture 10
36+
# - examples/create_alert.py XXX
37+
# - examples/delete_alert.py XXX
38+
# - examples/dashboard.py XXX
39+
# - examples/create_dashboard.py XXX
40+
# - examples/delete_dashboard.py XXX
41+
# - examples/get_data_advanced.py XXX ip-10-0-2-180.ec2.internal
42+
# - examples/get_data_datasource.py XXX
43+
# - examples/get_data_simple.py XXX
44+
# - examples/list_alerts.py XXX
45+
# - examples/list_alert_notifications.py XXX
46+
# - examples/resolve_alert_notifications.py XXX 1
47+
# - examples/list_dashboards.py XXX
48+
# - examples/list_hosts.py XXX
49+
# - examples/list_metrics.py XXX
50+
# - examples/post_event.py XXX "test event name" -d "test event description"
51+
# - examples/post_event_simple.py XXX "test event name" "test event description"
52+
# - examples/list_events.py XXX
53+
# - examples/delete_event.py XXX
54+
# - examples/print_data_retention_info.py XXX
55+
# - examples/print_explore_grouping.py XXX
56+
# - examples/print_user_info.py XXX
57+
# - examples/list_sysdig_captures.py XXX
58+
# - examples/create_sysdig_capture.py XXX ip-10-0-2-202.ec2.internal apicapture 10
5859
notifications:
5960
slack:
6061
secure: GJ0H2wAaW67t3+x+cCjOVLw/b+YAZjH9rebAfluCFJklJS9u+V6/qqIyiNDAkMPIcgilFyhiyOQCZYXapgthQ1ieFbZZo//mrRtuGo2wuxCAwcOx2mXAZpZ4I5b3+Q/znVqSuqkwFRid1d138z4TW7sYSIburouDX3QUNoUOy+g7VJxCFQCcqlN8LYxGJHQYdOZa9zIGCtKrOtZ/B8C1TLgXmDMwAAVNO2WzL4GiBTLCGuMsQWMTLw2Qmv1ayZPztmeDWo1C9oa7HIH8Bg2YVjssR87el28X+EqEO533mgYjPmW2/hii30WVFOUE5hMdvKeQLBvy5N3/OCch1np0RQBd8eYEtaPv38rc5L2wAnUq9G5Zzr252z7vnwSLi6lap9jWU8tOerSTEPU+jG05PnuCnufVDXVNPyiPsH6BDP4qxHmLjooNpxfe63Df7NNyUi2I3QoroLj/UzI7zZVQjJEqsTrr5BbsH4z6NTGY91+ZqobBn62+hV3ESAam0ivQgC7s2AKko0qkKyIUGjj7ozU8ebo1UpagNvKC/J9szMqtdXJgKtG8BeonyLMeN6MEEyEvcMJbB4dCcfet+1Sb9AZWnGvYVdajhVLb1HE6OrbzZyhC3KqCe06J9O5BCY9ncy+l16i7MyIfcKTibHQlxPU+Id/VijD97JSRXxnd2i4=

examples/create_alert.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@
3030
# Find notification channels (you need IDs to create an alert).
3131
#
3232
notify_channels = [ {'type': 'SLACK', 'channel': 'sysdig-demo2-alerts'},
33-
{'type': 'EMAIL', 'emailRecipients': [u'kini@sysdig.com']},
34-
{'type': 'SNS', 'snsTopicARNs': [u'arn:aws:sns:us-east-1:273107874544:alarms-stg']}
33+
{'type': 'EMAIL', 'emailRecipients': ['gianluca@sysdig.com']},
34+
{'type': 'SNS', 'snsTopicARNs': ['arn:aws:sns:us-east-1:273107874544:alarms-stg']}
3535
]
36+
3637
res = sdclient.get_notification_ids(notify_channels)
3738
if not res[0]:
38-
print "Could not get IDs and hence not creating the alert"
39+
print "Could not get IDs and hence not creating the alert: " + res[1]
3940
sys.exit(-1)
4041

4142
notification_channel_ids = res[1]

examples/delete_event.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,3 @@
4444
if not res[0]:
4545
print res[1]
4646
sys.exit(1)
47-
else:
48-
sys.exit(0)

examples/list_hosts.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@
3737
# come as a single sample.
3838
#
3939
res = sdclient.get_data(metrics, # metrics list
40-
-600, # cover the last 300 seconds...
40+
-600, # cover the last 600 seconds...
4141
0, # ... ending now...
42-
600) # ... with just one 300s sample
42+
600) # ... with just one 600s sample
4343

4444
#
4545
# Show the results!

examples/notification_channels.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env python
2+
#
3+
# This script shows how to manipulate the notification channel list for alerts
4+
#
5+
6+
import os
7+
import sys
8+
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), '..'))
9+
from sdcclient import SdcClient
10+
11+
#
12+
# Parse arguments
13+
#
14+
if len(sys.argv) != 2:
15+
print 'usage: %s <sysdig-token>' % sys.argv[0]
16+
print 'You can find your token at https://app.sysdigcloud.com/#/settings/user'
17+
sys.exit(1)
18+
19+
sdc_token = sys.argv[1]
20+
21+
#
22+
# Instantiate the SDC client
23+
#
24+
sdclient = SdcClient(sdc_token)
25+
26+
#
27+
# Create an email notification channel
28+
#
29+
res = sdclient.create_email_notification_channel('Api Channel', ['[email protected]', '[email protected]', '[email protected]'])
30+
if not res[0]:
31+
print res[1]
32+
sys.exit(1)
33+
34+
#
35+
# The notification channel will contain the id, that can be used when creating alerts
36+
#
37+
channel = res[1]['notificationChannel']
38+
print channel
39+
40+
#
41+
# Notification channels can also be programmatically deleted
42+
#
43+
res = sdclient.delete_notification_channel(channel)
44+
if not res[0]:
45+
print res[1]
46+
sys.exit(1)

sdcclient/_client.py

Lines changed: 102 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import copy
55

66
class SdcClient:
7-
userinfo = None
8-
n_connected_agents = None
97
lasterr = None
108

119
def __init__(self, token="", sdc_url='https://app-staging.sysdigcloud.com'):
@@ -44,12 +42,18 @@ def __checkResponse(self, res):
4442

4543

4644
def get_user_info(self):
47-
if self.userinfo is None:
48-
res = requests.get(self.url + '/api/user/me', headers=self.hdrs)
49-
if not self.__checkResponse(res):
50-
return [False, self.lasterr]
51-
self.userinfo = res.json()
52-
return [True, self.userinfo]
45+
res = requests.get(self.url + '/api/user/me', headers=self.hdrs)
46+
if not self.__checkResponse(res):
47+
return [False, self.lasterr]
48+
return [True, res.json()]
49+
50+
def get_user_token(self):
51+
res = requests.get(self.url + '/api/token', headers=self.hdrs)
52+
if not self.__checkResponse(res):
53+
return [False, self.lasterr]
54+
tkinfo = res.json()
55+
56+
return [True, tkinfo['token']['key']]
5357

5458
def get_connected_agents(self):
5559
res = requests.get(self.url + '/api/agents/connected', headers=self.hdrs)
@@ -93,7 +97,7 @@ def get_notifications(self, from_ts, to_ts, state=None, resolved=None):
9397

9498
def update_notification_resolution(self, notification, resolved):
9599
if 'id' not in notification:
96-
return [False, "Invalid notification format"]
100+
return [False, 'Invalid notification format']
97101

98102
notification['resolved'] = resolved
99103
data = {'notification': notification}
@@ -103,35 +107,42 @@ def update_notification_resolution(self, notification, resolved):
103107
return [False, self.lasterr]
104108
return [True, res.json()]
105109

106-
def get_notification_channel_ids(self, channels):
107-
res = requests.get(self.url + '/api/notificationChannels', headers=self.hdrs)
108-
ids = []
109-
if not self.__checkResponse(res):
110-
return [False, self.lasterr]
111-
# Should try and improve this M * N lookup
112-
for ch in res.json()["notificationChannels"]:
110+
def get_notification_ids(self, channels):
111+
res = requests.get(self.url + '/api/notificationChannels', headers=self.hdrs)
112+
113+
if not self.__checkResponse(res):
114+
return [False, self.lasterr]
115+
116+
# Should try and improve this M * N lookup
117+
ids = []
113118
for c in channels:
114-
if c['type'] == ch['type']:
115-
print c, ch
116-
if c['type'] == 'SNS':
117-
opt = ch['options']
118-
if set(opt['snsTopicARNs']) == set(c['snsTopicARNs']):
119-
ids.append(ch['id'])
120-
elif c['type'] == 'EMAIL':
121-
opt = ch['options']
122-
if set(c['emailRecipients']) == set(opt['emailRecipients']):
123-
ids.append(ch['id'])
124-
elif c['type'] == 'PAGER_DUTY':
125-
opt = ch['options']
126-
if opt['account'] == c['account'] and opt['serviceName'] == c['serviceName']:
127-
ids.append(ch['id'])
128-
elif c['type'] == 'SLACK':
129-
opt = ch['options']
130-
if opt['channel'] == c['channel']:
131-
ids.append(ch['id'])
132-
print ids
133-
return [True, ids]
134-
119+
found = False
120+
for ch in res.json()["notificationChannels"]:
121+
if c['type'] == ch['type']:
122+
if c['type'] == 'SNS':
123+
opt = ch['options']
124+
if set(opt['snsTopicARNs']) == set(c['snsTopicARNs']):
125+
found = True
126+
ids.append(ch['id'])
127+
elif c['type'] == 'EMAIL':
128+
opt = ch['options']
129+
if set(c['emailRecipients']) == set(opt['emailRecipients']):
130+
found = True
131+
ids.append(ch['id'])
132+
elif c['type'] == 'PAGER_DUTY':
133+
opt = ch['options']
134+
if opt['account'] == c['account'] and opt['serviceName'] == c['serviceName']:
135+
found = True
136+
ids.append(ch['id'])
137+
elif c['type'] == 'SLACK':
138+
opt = ch['options']
139+
if 'channel' in opt and opt['channel'] == c['channel']:
140+
found = True
141+
ids.append(ch['id'])
142+
if not found:
143+
return [False, "Channel not found: " + str(c)]
144+
145+
return [True, ids]
135146

136147
def create_alert(self, name, description, severity, for_atleast_s, condition, segmentby=[],
137148
segment_condition='ANY', user_filter='', notify=None, enabled=True, annotations={}):
@@ -187,50 +198,39 @@ def create_alert(self, name, description, severity, for_atleast_s, condition, se
187198

188199
def delete_alert(self, alert):
189200
if 'id' not in alert:
190-
return [False, "Invalid alert format"]
201+
return [False, 'Invalid alert format']
191202

192203
res = requests.delete(self.url + '/api/alerts/' + str(alert['id']), headers=self.hdrs)
193204
if not self.__checkResponse(res):
194205
return [False, self.lasterr]
195206

196207
return [True, None]
197208

198-
def get_notification_settings(self):
199-
res = requests.get(self.url + '/api/settings/notifications', headers=self.hdrs)
200-
if not self.__checkResponse(res):
201-
return [False, self.lasterr]
202-
return [True, res.json()]
209+
def create_email_notification_channel(self, channel_name, email_recipients):
210+
channel_json = {
211+
'notificationChannel' : {
212+
'type' : 'EMAIL',
213+
'name' : channel_name,
214+
'enabled' : True,
215+
'options' : {
216+
'emailRecipients' : email_recipients
217+
}
218+
}
219+
}
203220

204-
def set_notification_settings(self, settings):
205-
res = requests.put(self.url + '/api/settings/notifications', headers=self.hdrs,
206-
data=json.dumps(settings))
221+
res = requests.post(self.url + '/api/notificationChannels', headers=self.hdrs, data=json.dumps(channel_json))
207222
if not self.__checkResponse(res):
208223
return [False, self.lasterr]
209224
return [True, res.json()]
210225

211-
def add_email_notification_recipient(self, email):
212-
#
213-
# Retirieve the user's notification settings
214-
#
215-
res = requests.get(self.url + '/api/settings/notifications', headers=self.hdrs)
226+
def delete_notification_channel(self, channel):
227+
if 'id' not in channel:
228+
return [False, "Invalid channel format"]
229+
230+
res = requests.delete(self.url + '/api/notificationChannels/' + str(channel['id']), headers=self.hdrs)
216231
if not self.__checkResponse(res):
217232
return [False, self.lasterr]
218-
j = res.json()
219-
220-
#
221-
# Enable email notifications
222-
#
223-
j['userNotification']['email']['enabled'] = True
224-
225-
#
226-
# Add the given recipient
227-
#
228-
if email not in j['userNotification']['email']['recipients']:
229-
j['userNotification']['email']['recipients'].append(email)
230-
else:
231-
return [False, 'notification target ' + email + ' already present']
232-
233-
return self.set_notification_settings(j)
233+
return [True, None]
234234

235235
def get_explore_grouping_hierarchy(self):
236236
res = requests.get(self.url + '/api/groupConfigurations', headers=self.hdrs)
@@ -256,6 +256,22 @@ def get_explore_grouping_hierarchy(self):
256256

257257
return [False, 'corrupted groupConfigurations API response, missing "explore" entry']
258258

259+
def set_explore_grouping_hierarchy(self, new_hierarchy):
260+
body = {
261+
'id': 'explore',
262+
'groups': [{'groupBy':[]}]
263+
}
264+
265+
for item in new_hierarchy:
266+
body['groups'][0]['groupBy'].append({'metric': item})
267+
268+
res = requests.put(self.url + '/api/groupConfigurations/explore', headers=self.hdrs,
269+
data=json.dumps(body))
270+
if not self.__checkResponse(res):
271+
return [False, self.lasterr]
272+
else:
273+
return [True, None]
274+
259275
def get_data_retention_info(self):
260276
res = requests.get(self.url + '/api/history/timelines/', headers=self.hdrs)
261277
if not self.__checkResponse(res):
@@ -610,6 +626,7 @@ def create_dashboard_from_template(self, newdashname, template, scope):
610626
#
611627
template['id'] = None
612628
template['version'] = None
629+
template['schema'] = 1
613630
template['name'] = newdashname
614631
template['isShared'] = False # make sure the dashboard is not shared
615632

@@ -803,7 +820,7 @@ def delete_event(self, event):
803820
return [True, None]
804821

805822
def get_data(self, metrics, start_ts, end_ts=0, sampling_s=0,
806-
filter='', datasource_type='host'):
823+
filter='', datasource_type='host', paging=None):
807824
reqbody = {
808825
'metrics': metrics,
809826
'dataSourceType': datasource_type,
@@ -820,6 +837,9 @@ def get_data(self, metrics, start_ts, end_ts=0, sampling_s=0,
820837
if filter != '':
821838
reqbody['filter'] = filter
822839

840+
if paging is not None:
841+
reqbody['paging'] = paging
842+
823843
if sampling_s != 0:
824844
reqbody['sampling'] = sampling_s
825845

@@ -1054,4 +1074,18 @@ def delete_team(self, name):
10541074
return [False, self.lasterr]
10551075
return [True, None]
10561076

1077+
def switch_user_team(self, new_team_id):
1078+
res = self.get_user_info()
1079+
if not res[0]:
1080+
return res
1081+
1082+
myuinfo = res[1]['user']
1083+
myuinfo['currentTeam'] = new_team_id
1084+
uid = myuinfo['id']
1085+
1086+
res = requests.put(self.url + '/api/user/' + str(uid), headers=self.hdrs, data=json.dumps(myuinfo))
1087+
if not self.__checkResponse(res):
1088+
return [False, self.lasterr]
1089+
else:
1090+
return [True, None]
10571091

0 commit comments

Comments
 (0)