Skip to content

Add support for Sysdig Secure compliance tasks #77

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 76 additions & 89 deletions sdcclient/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ def get_user_info(self):
`examples/print_user_info.py <https://github.com/draios/python-sdc-client/blob/master/examples/print_user_info.py>`_
'''
res = requests.get(self.url + '/api/user/me', headers=self.hdrs, verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def get_user_token(self):
'''**Description**
Expand Down Expand Up @@ -203,9 +201,7 @@ def create_email_notification_channel(self, channel_name, email_recipients):
}

res = requests.post(self.url + '/api/notificationChannels', headers=self.hdrs, data=json.dumps(channel_json), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def get_notification_channel(self, id):

Expand All @@ -220,10 +216,7 @@ def update_notification_channel(self, channel):
return [False, "Invalid channel format"]

res = requests.put(self.url + '/api/notificationChannels/' + str(channel['id']), headers=self.hdrs, data=json.dumps({"notificationChannel": channel}), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]

return [True, res.json()]
return self._request_result(res)

def delete_notification_channel(self, channel):
if 'id' not in channel:
Expand All @@ -245,9 +238,7 @@ def get_data_retention_info(self):
`examples/print_data_retention_info.py <https://github.com/draios/python-sdc-client/blob/master/examples/print_data_retention_info.py>`_
'''
res = requests.get(self.url + '/api/history/timelines/', headers=self.hdrs, verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def get_topology_map(self, grouping_hierarchy, time_window_s, sampling_time_s):
#
Expand Down Expand Up @@ -326,9 +317,7 @@ def get_topology_map(self, grouping_hierarchy, time_window_s, sampling_time_s):
#
res = requests.post(self.url + '/api/data?format=map', headers=self.hdrs,
data=json.dumps(req_json), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def post_event(self, name, description=None, severity=None, event_filter=None, tags=None):
'''**Description**
Expand All @@ -348,28 +337,18 @@ def post_event(self, name, description=None, severity=None, event_filter=None, t
- `examples/post_event_simple.py <https://github.com/draios/python-sdc-client/blob/master/examples/post_event_simple.py>`_
- `examples/post_event.py <https://github.com/draios/python-sdc-client/blob/master/examples/post_event.py>`_
'''
options = {
'name': name,
'description': description,
'severity': severity,
'filter': event_filter,
'tags': tags
}
edata = {
'event': {
'name': name
}
'event': {k: v for k, v in options.items() if v is not None}
}

if description is not None:
edata['event']['description'] = description

if severity is not None:
edata['event']['severity'] = severity

if event_filter is not None:
edata['event']['filter'] = event_filter

if tags is not None:
edata['event']['tags'] = tags

res = requests.post(self.url + '/api/events/', headers=self.hdrs, data=json.dumps(edata), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def get_events(self, name=None, from_ts=None, to_ts=None, tags=None):
'''**Description**
Expand All @@ -387,24 +366,15 @@ def get_events(self, name=None, from_ts=None, to_ts=None, tags=None):
**Example**
`examples/list_events.py <https://github.com/draios/python-sdc-client/blob/master/examples/list_events.py>`_
'''
params = {}

if name is not None:
params['name'] = name

if from_ts is not None:
params['from'] = from_ts

if to_ts is not None:
params['to'] = to_ts

if tags is not None:
params['tags'] = tags

options = {
'name': name,
'from': from_ts,
'to': to_ts,
'tags': tags
}
params = {k: v for k, v in options.items() if v is not None}
res = requests.get(self.url + '/api/events/', headers=self.hdrs, params=params, verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def delete_event(self, event):
'''**Description**
Expand Down Expand Up @@ -473,24 +443,31 @@ def get_data(self, metrics, start_ts, end_ts=0, sampling_s=0,
reqbody['sampling'] = sampling_s

res = requests.post(self.url + '/api/data/', headers=self.hdrs, data=json.dumps(reqbody), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def get_sysdig_captures(self):
def get_sysdig_captures(self, from_sec=None, to_sec=None, scope_filter=None):
'''**Description**
Returns the list of sysdig captures for the user.

**Arguments**
- from_sec: the start of the timerange for which to get the captures
- end_sec: the end of the timerange for which to get the captures
- scope_filter: this is a SysdigMonitor-like filter (e.g 'container.image=ubuntu'). When provided, events are filtered by their scope, so only a subset will be returned (e.g. 'container.image=ubuntu' will provide only events that have happened on an ubuntu container).

**Success Return Value**
A dictionary containing the list of captures.

**Example**
`examples/list_sysdig_captures.py <https://github.com/draios/python-sdc-client/blob/master/examples/list_sysdig_captures.py>`_
'''
res = requests.get(self.url + '/api/sysdig', headers=self.hdrs, verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
url = '{url}/api/sysdig?source={source}{frm}{to}{scopeFilter}'.format(
url=self.url,
source=self.product,
frm="&from=%d" % (from_sec * 10**6) if from_sec else "",
to="&to=%d" % (to_sec * 10**6) if to_sec else "",
scopeFilter="&scopeFilter=%s" % scope_filter if scope_filter else "")
res = requests.get(url, headers=self.hdrs, verify=self.ssl_verify)
return self._request_result(res)

def poll_sysdig_capture(self, capture):
'''**Description**
Expand All @@ -508,10 +485,10 @@ def poll_sysdig_capture(self, capture):
if 'id' not in capture:
return [False, 'Invalid capture format']

res = requests.get(self.url + '/api/sysdig/' + str(capture['id']), headers=self.hdrs, verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
url = '{url}/api/sysdig/{id}?source={source}'.format(
url=self.url, id=capture['id'], source=self.product)
res = requests.get(url, headers=self.hdrs, verify=self.ssl_verify)
return self._request_result(res)

def create_sysdig_capture(self, hostname, capture_name, duration, capture_filter='', folder='/'):
'''**Description**
Expand Down Expand Up @@ -550,13 +527,30 @@ def create_sysdig_capture(self, hostname, capture_name, duration, capture_filter
'duration': duration,
'folder': folder,
'filters': capture_filter,
'bucketName': ''
'bucketName': '',
'source': self.product
}

res = requests.post(self.url + '/api/sysdig', headers=self.hdrs, data=json.dumps(data), verify=self.ssl_verify)
return self._request_result(res)

def download_sysdig_capture(self, capture_id):
'''**Description**
Download a sysdig capture by id.

**Arguments**
- **capture_id**: the capture id to download.

**Success Return Value**
The bytes of the scap
'''
url = '{url}/api/sysdig/{id}/download?_product={product}'.format(
url=self.url, id=capture_id, product=self.product)
res = requests.get(url, headers=self.hdrs, verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return False, self.lasterr

return True, res.content

def create_user_invite(self, user_email, first_name=None, last_name=None, system_role=None):
'''**Description**
Expand Down Expand Up @@ -586,21 +580,14 @@ def create_user_invite(self, user_email, first_name=None, last_name=None, system
return [False, 'user ' + user_email + ' already exists']

# Create the user
user_json = {'username': user_email}

if first_name is not None:
user_json['firstName'] = first_name

if last_name is not None:
user_json['lastName'] = last_name

if system_role is not None:
user_json['systemRole'] = system_role
options = {'username': user_email,
'firstName': first_name,
'lastName': last_name,
'systemRole': system_role}
user_json = {k: v for k, v in options.items() if v is not None}

res = requests.post(self.url + '/api/users', headers=self.hdrs, data=json.dumps(user_json), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def delete_user(self, user_email):
'''**Description**
Expand Down Expand Up @@ -786,9 +773,7 @@ def create_team(self, name, memberships=None, filter='', description='', show='h
reqbody['filter'] = filter

res = requests.post(self.url + '/api/teams', headers=self.hdrs, data=json.dumps(reqbody), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def edit_team(self, name, memberships=None, filter=None, description=None, show=None, theme=None,
perm_capture=None, perm_custom_events=None, perm_aws_data=None):
Expand Down Expand Up @@ -859,9 +844,7 @@ def edit_team(self, name, memberships=None, filter=None, description=None, show=
reqbody['filter'] = t['filter']

res = requests.put(self.url + '/api/teams/' + str(t['id']), headers=self.hdrs, data=json.dumps(reqbody), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def delete_team(self, name):
'''**Description**
Expand Down Expand Up @@ -977,9 +960,7 @@ def get_agents_config(self):

def set_agents_config(self, config):
res = requests.put(self.url + '/api/agents/config', headers=self.hdrs, data=json.dumps(config), verify=self.ssl_verify)
if not self._checkResponse(res):
return [False, self.lasterr]
return [True, res.json()]
return self._request_result(res)

def clear_agents_config(self):
data = {'files': []}
Expand All @@ -997,3 +978,9 @@ def get_user_api_token(self, username, teamname):
return [False, self.lasterr]
data = res.json()
return [True, data['token']['key']]

def _request_result(self, res):
if not self._checkResponse(res):
return False, self.lasterr

return True, res.json()
Loading