Skip to content

Commit 165853c

Browse files
PatrickDuncanDavide Schiera
authored andcommitted
IBM Cloud IAM Support (#102)
* Enable authentication with IBM Cloud IAM * Added IBM Cloud IAM auth example * Changes from review
1 parent f9a5abf commit 165853c

File tree

7 files changed

+151
-8
lines changed

7 files changed

+151
-8
lines changed

examples/dashboard_ibm_cloud.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env python
2+
3+
# This example uses IBM Cloud IAM authentication and makes a few calls to the
4+
# Dashboard API as validation. Creates, edits and then deletes a dashboard.
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 IbmAuthHelper, SdMonitorClient
10+
11+
# Parse arguments.
12+
def usage():
13+
print('usage: %s <endpoint-url> <apikey> <instance-guid>' % sys.argv[0])
14+
print('endpoint-url: The endpoint URL that should point to IBM Cloud')
15+
print('apikey: IBM Cloud IAM apikey that will be used to retrieve an access token')
16+
print('instance-guid: GUID of an IBM Cloud Monitoring with Sysdig instance')
17+
sys.exit(1)
18+
19+
if len(sys.argv) != 4:
20+
usage()
21+
22+
URL = sys.argv[1]
23+
APIKEY = sys.argv[2]
24+
GUID = sys.argv[3]
25+
DASHBOARD_NAME = 'IBM Cloud IAM with Python Client Example'
26+
PANEL_NAME = 'CPU Over Time'
27+
28+
# Instantiate the client with an IBM Cloud auth object
29+
ibm_headers = IbmAuthHelper.get_headers(URL, APIKEY, GUID)
30+
sdclient = SdMonitorClient(sdc_url=URL, custom_headers=ibm_headers)
31+
32+
# Create an empty dashboard
33+
ok, res = sdclient.create_dashboard(DASHBOARD_NAME)
34+
35+
# Check the result
36+
dashboard_configuration = None
37+
if ok:
38+
print('Dashboard %d created successfully' % res['dashboard']['id'])
39+
dashboard_configuration = res['dashboard']
40+
else:
41+
print(res)
42+
sys.exit(1)
43+
44+
# Add a time series panel
45+
panel_type = 'timeSeries'
46+
metrics = [
47+
{'id': 'proc.name'},
48+
{'id': 'cpu.used.percent', 'aggregations': {'time': 'avg', 'group': 'avg'}}
49+
]
50+
ok, res = sdclient.add_dashboard_panel(
51+
dashboard_configuration, PANEL_NAME, panel_type, metrics)
52+
53+
# Check the result
54+
if ok:
55+
print('Panel added successfully')
56+
dashboard_configuration = res['dashboard']
57+
else:
58+
print(res)
59+
sys.exit(1)
60+
61+
# Remove the time series panel
62+
ok, res = sdclient.remove_dashboard_panel(dashboard_configuration, PANEL_NAME)
63+
64+
# Check the result
65+
if ok:
66+
print('Panel removed successfully')
67+
dashboard_configuration = res['dashboard']
68+
else:
69+
print(res)
70+
sys.exit(1)
71+
72+
# Delete the dashboard
73+
ok, res = sdclient.delete_dashboard(dashboard_configuration)
74+
75+
# Check the result
76+
if ok:
77+
print('Dashboard deleted successfully')
78+
else:
79+
print(res)
80+
sys.exit(1)
81+
82+
print('IBM Cloud IAM auth worked successfully!')

sdcclient/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
from sdcclient._monitor_v1 import SdMonitorClientV1
44
from sdcclient._secure import SdSecureClient
55
from sdcclient._scanning import SdScanningClient
6+
from sdcclient.ibm_auth_helper import IbmAuthHelper

sdcclient/_common.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,32 @@ class _SdcCommon(object):
1010
- **token**: A Sysdig Monitor/Secure API token from the *Sysdig Cloud API* section of the Settings page for `monitor <https://app.sysdigcloud.com/#/settings/user>`_ or .`secure <https://secure.sysdig.com/#/settings/user>`_.
1111
- **sdc_url**: URL for contacting the Sysdig API server. Set this in `On-Premises installs <https://support.sysdigcloud.com/hc/en-us/articles/206519903-On-Premises-Installation-Guide>`__.
1212
- **ssl_verify**: Whether to verify certificate. Set to False if using a self-signed certificate in an `On-Premises install <https://support.sysdigcloud.com/hc/en-us/articles/206519903-On-Premises-Installation-Guide>`__.
13+
- **custom_headers**: [dict] Pass in custom headers. Useful for authentication and will override the default headers.
1314
1415
**Returns**
1516
An object for further interactions with the Sysdig Monitor/Secure API. See methods below.
1617
'''
1718
lasterr = None
1819

19-
def __init__(self, token="", sdc_url='https://app.sysdigcloud.com', ssl_verify=True):
20+
def __init__(self, token="", sdc_url='https://app.sysdigcloud.com', ssl_verify=True, custom_headers=None):
2021
self.token = os.environ.get("SDC_TOKEN", token)
21-
self.hdrs = {'Authorization': 'Bearer ' + self.token, 'Content-Type': 'application/json'}
22+
self.hdrs = self.__get_headers(custom_headers)
2223
self.url = os.environ.get("SDC_URL", sdc_url)
2324
self.ssl_verify = os.environ.get("SDC_SSL_VERIFY", None)
2425
if self.ssl_verify == None:
2526
self.ssl_verify = ssl_verify
2627
else:
2728
self.ssl_verify = self.ssl_verify.lower() == 'true'
2829

30+
def __get_headers(self, custom_headers):
31+
headers = {
32+
'Content-Type': 'application/json',
33+
'Authorization': 'Bearer ' + self.token
34+
}
35+
if custom_headers:
36+
headers.update(custom_headers)
37+
return headers
38+
2939
def _checkResponse(self, res):
3040
if res.status_code >= 300:
3141
errorcode = res.status_code

sdcclient/_monitor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
class SdMonitorClient(_SdcCommon):
1515

16-
def __init__(self, token="", sdc_url='https://app.sysdigcloud.com', ssl_verify=True):
17-
super(SdMonitorClient, self).__init__(token, sdc_url, ssl_verify)
16+
def __init__(self, token="", sdc_url='https://app.sysdigcloud.com', ssl_verify=True, custom_headers=None):
17+
super(SdMonitorClient, self).__init__(token, sdc_url, ssl_verify, custom_headers)
1818
self.product = "SDC"
1919
self._dashboards_api_version = 'v2'
2020
self._dashboards_api_endpoint = '/api/{}/dashboards'.format(self._dashboards_api_version)

sdcclient/_scanning.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
class SdScanningClient(_SdcCommon):
1717

18-
def __init__(self, token="", sdc_url='https://secure.sysdig.com', ssl_verify=True):
19-
super(SdScanningClient, self).__init__(token, sdc_url, ssl_verify)
18+
def __init__(self, token="", sdc_url='https://secure.sysdig.com', ssl_verify=True, custom_headers=None):
19+
super(SdScanningClient, self).__init__(token, sdc_url, ssl_verify, custom_headers)
2020
self.product = "SDS"
2121

2222
def add_image(self, image, force=False, dockerfile=None, annotations={}, autosubscribe=True):

sdcclient/_secure.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
class SdSecureClient(_SdcCommon):
1313

14-
def __init__(self, token="", sdc_url='https://secure.sysdig.com', ssl_verify=True):
15-
super(SdSecureClient, self).__init__(token, sdc_url, ssl_verify)
14+
def __init__(self, token="", sdc_url='https://secure.sysdig.com', ssl_verify=True, custom_headers=None):
15+
super(SdSecureClient, self).__init__(token, sdc_url, ssl_verify, custom_headers)
1616

1717
self.customer_id = None
1818
self.product = "SDS"

sdcclient/ibm_auth_helper.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import requests
2+
3+
class IbmAuthHelper():
4+
'''Authenticate with IBM Cloud IAM.
5+
6+
**Arguments**
7+
**url**: Sysdig endpoint URL that should point to IBM Cloud
8+
**apikey**: IBM Cloud IAM apikey that will be used to retrieve an access token
9+
**guid**: GUID of an IBM Cloud Monitoring with Sysdig instance
10+
11+
**Returns**
12+
A dictionary that will authenticate you with the IBM Cloud IAM API.
13+
'''
14+
15+
@staticmethod
16+
def get_headers(url, apikey, guid):
17+
iam_token = IbmAuthHelper.__get_iam_token(url, apikey)
18+
return {
19+
'Authorization': 'Bearer ' + iam_token,
20+
'IBMInstanceID': guid
21+
}
22+
23+
@staticmethod
24+
def __get_iam_endpoint(url):
25+
IAM_ENDPOINT = {
26+
'stage': 'iam.test.cloud.ibm.com',
27+
'prod': 'iam.cloud.ibm.com'
28+
}
29+
if '.test.' in url:
30+
return IAM_ENDPOINT['stage']
31+
else:
32+
return IAM_ENDPOINT['prod']
33+
34+
@staticmethod
35+
def __get_iam_token(url, apikey):
36+
env_url = IbmAuthHelper.__get_iam_endpoint(url)
37+
response = requests.post(
38+
'https://' + env_url + '/identity/token',
39+
data={
40+
'grant_type': 'urn:ibm:params:oauth:grant-type:apikey',
41+
'response_type': 'cloud_iam',
42+
'apikey': apikey
43+
},
44+
headers={
45+
'Accept': 'application/json'
46+
})
47+
if response.status_code == 200:
48+
return response.json()['access_token']
49+
else:
50+
response.raise_for_status()

0 commit comments

Comments
 (0)