def init(): if len(sys.argv) != 3: print 'usage: %s <sysdig-token> <slack-token>' % sys.argv[0] sys.exit(1) else: sdc_token = sys.argv[1] slack_token = sys.argv[2] # # Instantiate the SDC client and Retrieve the SDC user information to make sure we have a valid connection # sdclient = SdcClient(sdc_token) # # Make a connection to the slack API # sc = SlackClient(slack_token) sc.rtm_connect() slack_id = json.loads(sc.api_call('auth.test'))['user_id'] # # Start talking! # dude = SlackBuddy(sdclient, sc, slack_id) dude.run()
def __init__(self, token=""): if not token: token = os.getenv("SYSDIG_TOKEN") self._Token = token if not self._Token: raise ValueError((f"Invalid Sysdig configuration. " f"Token not set (SYSDIG_TOKEN) or passes")) self._Severity = 7 self._Client = SdcClient(self._Token)
def init(): sdc_token = None try: sdc_token = os.environ["SYSDIG_API_TOKEN"] except KeyError: pass slack_token = None try: slack_token = os.environ["SLACK_TOKEN"] except KeyError: pass parser = argparse.ArgumentParser(description='Sysdigbot: the Sysdig Cloud Slack bot.') parser.add_argument('--sysdig-api-token', dest='sdc_token', required=(sdc_token is None), default=sdc_token, type=str, help='Sysdig API Token, you can use also SYSDIG_API_TOKEN environment variable to set it') parser.add_argument('--slack-token', dest='slack_token', required=(slack_token is None), default=slack_token, type=str, help='Slack Token, you can use also SLACK_TOKEN environment variable to set it') parser.add_argument('--quiet', dest='quiet', action='store_true', help='Prevents the bot from printing output on channels, which is useful to avoid any kind of channel pollution') parser.add_argument('--no-auto-events', dest='auto_events', action='store_false', help='By default Sysdigbot converts every message in a channel in a Sysdig Cloud event, this flag disables it') parser.add_argument('--log-level', dest='log_level', type=LogLevelFromString, help='Logging level, available values: debug, info, warning, error') args = parser.parse_args() logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=args.log_level) # requests generates too noise on information level logging.getLogger("requests").setLevel(logging.WARNING) logging.getLogger("urllib3").setLevel(logging.WARNING) logging.debug("Starting Sysdigbot, config=%s", repr(args)) # # Instantiate the SDC client and Retrieve the SDC user information to make sure we have a valid connection # sdclient = SdcClient(args.sdc_token) # # Make a connection to the slack API # sc = SlackClient(args.slack_token) sc.rtm_connect() sinfo = sc.api_call('auth.test') slack_id = sinfo['user_id'] # # Start talking! # dude = SlackBuddy(sdclient, sc, slack_id, args.quiet) dude.auto_events = args.auto_events dude.run()
def get_pod_cpu_memory_usage(pod_name): """Get cpus and memory usage in a pod. :return: (float, float) the cores used. the mem used, the unit is M. """ sdclient = SdcClient("5e7d3f61-e1fe-4467-928e-15cec005b79c") pod_filter = "kubernetes.pod.name = '%s'" % pod_name start = -60 end = 0 sampling = 60 cpus_metrics = [{ "id": "cpu.cores.used", "aggregations": { "time": "max", "group": "max" } }] cpus_metric_data = sdclient.get_data(cpus_metrics, start, end, sampling, filter=pod_filter) cpus = float(cpus_metric_data[1].get('data')[0].get('d')[0]) mem_metrics = [{ "id": "memory.bytes.used", "aggregations": { "time": "max", "group": "max" } }] mem_metrics_data = sdclient.get_data(mem_metrics, start, end, sampling, filter=pod_filter) mem = float(mem_metrics_data[1].get('data')[0].get('d')[0])/1024/1024 return (cpus, mem)
def get_pod_cpu_memory_limits(pod_name): """Get cpus and memory limits of a pod. :return: (float, float) the cores used. the mem used, the unit is M. """ sdclient = SdcClient("5e7d3f61-e1fe-4467-928e-15cec005b79c") pod_filter = "kubernetes.pod.name = '%s'" % pod_name start = -60 end = 0 sampling = 60 cpus_limit_metrics = [{"id": "kubernetes.pod.resourceLimits.cpuCores", "aggregations": { "time": "timeAvg", "group": "max" }}] cpus_limit_data = sdclient.get_data(cpus_limit_metrics, start, end, sampling, filter=pod_filter) cpus_limit = float(cpus_limit_data[1].get('data')[0].get('d')[0]) mem_limit_metrics = [{"id": "kubernetes.pod.resourceLimits.memBytes", "aggregations": { "time": "timeAvg", "group": "max" }}] mem_limit_data = sdclient.get_data(mem_limit_metrics, start, end, sampling, filter=pod_filter) mem_limit = float(mem_limit_data[1].get('data')[0].get('d')[0])/1024/1024 return (cpus_limit, mem_limit)
# # Parse arguments # if len(sys.argv) != 2: print('usage: %s <sysdig-token>' % sys.argv[0]) print( 'You can find your token at https://app.sysdigcloud.com/#/settings/user' ) sys.exit(1) sdc_token = sys.argv[1] # # Instantiate the SDC client # sdclient = SdcClient(sdc_token, 'https://app.sysdigcloud.com') # # Get the configuration # ok, res = sdclient.get_agents_config() # # Return the result # if ok: if not ("files" in res) or len(res["files"]) == 0: print("No current auto configuration") else: print("Current contents of config file:") print("--------------------------------")
sdc_token = sys.argv[1] sdc_tokens = [] if not '.json' in sdc_token: sdc_tokens.append(sdc_token) else: with open(sdc_token) as f: data = json.load(f) for apikey in data['apikeys']: sdc_tokens.append(apikey) for token in sdc_tokens: # # Instantiate the SDC client # For on-pmreises, add ssl_verify=False # sdclient = SdcClient(token, sdc_url='https://app.sysdigcloud.com') dashboard_state_file = 'dashboards' + token + '.zip' zipf = zipfile.ZipFile(dashboard_state_file, 'r') dashboard_conf_items = [ 'showAsType', 'filterRoot', 'linkMetrics', 'singleTimeNavigation', 'gridConfiguration', 'responsive', 'nodesNoiseFilter', 'compareWith', 'format', 'linksNoiseFilter', 'filterProcesses', 'isLegendExpanded', 'inhertitTimeNavigation', 'schema', 'sortAscending', 'mapDataLimit', 'metrics', 'filterExtNodes', 'sorting', 'name', 'sourceExploreView', 'items', 'showAs', 'eventsFilter', 'timeMode', 'isShared', 'sourceDrilldownView', 'filterExpression' ] for info in zipf.infolist(): data = zipf.read(info.filename)
from kubernetes import client, config, watch from sdcclient import SdcClient config.load_kube_config() v1 = client.CoreV1Api() api_token = "149aa03f-c0e4-47c5-80a5-7c25ef8bc09b" sdclient = SdcClient(api_token) sysdig_metric = "net.http.request.time" metrics = [{ "id": sysdig_metric, "aggregations": { "time": "timeAvg", "group": "avg" } }] scheduler_name = "my-scheduler" def get_request_time(hostname): hostfilter = "host.hostName = '%s'" % hostname start = -60 end = 0 sampling = 60 metricdata = sdclient.get_data(metrics, start, end, sampling, filter=hostfilter)
parser.add_argument('-d','--description') parser.add_argument('-s','--severity', help='syslog style from 0 (high) to 7 (low)') parser.add_argument('-c','--scope', help='metadata, in Sysdig Cloud format, of nodes to associate with the event, eg: \'host.hostName = "ip-10-1-1-1" and container.name = "foo"\'') parser.add_argument('-t','--tags', help='dictionary of arbitrary key-value pairs, eg: \'{"app":"my_app", "file":"text.py"}\'') parser.add_argument('sysdig_token', help='You can find your token at https://app.sysdigcloud.com/#/settings/user') parser.add_argument('name') args = parser.parse_args() tags=None if args.tags: tags=json.loads(args.tags) # # Instantiate the SDC client # sdclient = SdcClient(args.sysdig_token) # # Post the event using post_event(self, name, description=None, severity=None, event_filter=None, tags=None) # res = sdclient.post_event(args.name, args.description, args.severity, args.scope, tags) # # Return the result # if res[0]: print 'Event Posted Successfully' else: print res[1] sys.exit(1)
0, os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), '..')) from sdcclient import SdcClient # # Parse arguments # if len(sys.argv) != 4: print 'usage: %s <sysdig-token> team-name user-name' % sys.argv[0] print 'You can find your token at https://app.sysdigcloud.com/#/settings/user' sys.exit(1) sdc_token = sys.argv[1] # # Instantiate the SDC client # sdclient = SdcClient(sdc_token, sdc_url='https://app-staging.sysdigcloud.com') team_name = sys.argv[2] user_name = sys.argv[3] print 'Trying to invite a user ', user_name res = sdclient.create_user_invite(user_name) if res[0] == False: print 'User creation failed: ', res[1] else: print 'User creation succeeded' print 'Now trying to create a team with name ', team_name res = sdclient.create_team(team_name) if res[0] == False: print 'Team creation failed: ', res[1]
from sdcclient import SdcClient # 30 day dev # d416132e-2285-4d85-b9cc-84d02be3cef1 # https://app.sysdigcloud.com sdclient = SdcClient('d416132e-2285-4d85-b9cc-84d02be3cef1') #ok, res = client.PostAlert(alert_info) test = { 'name': 'test 1', 'description': 'This is a test of the national broadcast system', 'severity': 5, 'scope': '', 'tags': '{"action":"UpgradeWorkerNodes"}' } def PostAlert(client, info): return client.post_event(name=info['name'], description=info['description'], severity=info['severity']) ok, resp = PostAlert(sdclient, test) print(ok, '\n', resp)
#!/usr/bin/env python import time import random import json from kubernetes import client, config, watch from sdcclient import SdcClient config.load_incluster_config() v1 = client.CoreV1Api() sdclient = SdcClient(open("/etc/sysdigtoken/token.txt","r").read().rstrip()) sysdig_metric = "net.http.request.time" metrics = [{ "id": sysdig_metric, "aggregations": { "time": "timeAvg", "group": "avg" } }] scheduler_name = "sysdigsched" def get_request_time(hostname): hostfilter = "host.hostName = '%s'" % hostname start = -60 end = 0 sampling = 60 metricdata = sdclient.get_data(metrics, start, end, sampling, filter=hostfilter) request_time = float(metricdata[1].get('data')[0].get('d')[0]) print hostname + " (" + sysdig_metric + "): " + str(request_time) return request_time def best_request_time(nodes): if not nodes:
sys.exit(1) DEFAULT_TEAM_PREFIX = '' team_prefix = os.getenv('TEAM_PREFIX', DEFAULT_TEAM_PREFIX) KUBE_URL = os.getenv('KUBE_URL') if not KUBE_URL: log( 'Did not find Kubernetes API server URL at env variable "KUBE_URL". Will attempt to autodiscover.', 'info') # # Instantiate the customer admin SDC client # log('SDC_URL = ' + SDC_URL, 'info') ca_sdclient = SdcClient(SDC_ADMIN_TOKEN, SDC_URL) res = ca_sdclient.get_user_info() if res[0] == False: Logger.log( 'Can\'t retrieve info for Sysdig Cloud Admin user: '******'. Exiting.', 'error') sys.exit(1) customer_id = res[1]['user']['username'] # # Allocate the parsers. # Note: the parsers keep state, so we allocate them during startup and then we # use them in the main loop #
import time import random import json from kubernetes import client, config, watch from sdcclient import SdcClient config.load_kube_config() v1 = client.CoreV1Api() sdclient = SdcClient("2b9e3c0a-cee6-443a-90b5-7530682b4d71") sysdig_metric = "cpu.used.percent" metrics = [{ "id": sysdig_metric, "aggregations": { "time": "timeAvg", "group": "avg" } }] scheduler_name = "sysdigsched" def get_request_time(hostname): hostfilter = "host.hostName = '%s'" % hostname start = -60 end = 0 sampling = 60 metricdata = sdclient.get_data(metrics, start, end, sampling, filter=hostfilter) print(metricdata) request_time = float(metricdata[1].get('data')[0].get('d')[0]) print(hostname + " (" + sysdig_metric + "): " + str(request_time)) return request_time def best_request_time(nodes): if not nodes: return []
def __init__(self, token): # # Connect to the backend # self.sdclient = SdcClient(token)
def parse(self, objdata): user_id_map = {} ################################################################### # TEAM CREATION ################################################################### obj_name = objdata['metadata']['name'] team_members = objdata['metadata']['annotations'].get('sysdigTeamMembers', '').split(',') trecipients = objdata['metadata']['annotations'].get('sysdigAlertEmails', '').split(',') tdashboards = objdata['metadata']['annotations'].get('sysdigDashboards', '').split(',') alertsj = objdata['metadata']['annotations'].get('sysdigAlerts', json.dumps([])) if self._type == 'deployment' or self._type == 'service': ns_name = objdata['metadata']['namespace'] team_name = "%s%s_%s_%s" % (self._team_prefix, self._type, ns_name, obj_name) elif self._type == 'namespace': ns_name = objdata['metadata']['name'] team_name = "%s%s_%s" % (self._team_prefix, self._type, ns_name) else: Logger.log('unrecognized type argument', 'error') return False # # Resolve the user emails. # Add the users that are not part of sysdig cloud yet. # for o in team_members: uname = o.strip() res = self._customer_admin_sdclient.get_user(uname) if res[0] == False: if res[1] == USER_NOT_FOUND_ERR: Logger.log("adding user " + uname) res = self._customer_admin_sdclient.create_user_invite(uname) res = self._customer_admin_sdclient.get_user(uname) Logger.log("User added") if res[0] == False: Logger.log('cannot get user %s: %s' % (uname, res[1]), 'error') continue else: Logger.log('cannot get user %s: %s' % (uname, res[1]), 'error') continue user_id_map[uname] = res[1]['id'] if len(user_id_map) == 0: Logger.log('No users specified for this team. Skipping.', 'error') return False # # Normalize alert recipients # recipients = [] for r in trecipients: recipients.append(r.strip()) # # Normalize the dashboards list # dashboards = [] for d in tdashboards: dashboards.append(d.strip()) # # Parse the alerts json # alerts = [] try: alerts = json.loads(alertsj) except ValueError: Logger.log('Invalid JSON in the "alerts" field', 'error') return False # XXX This is here for testing purposes only # res = self._customer_admin_sdclient.delete_team(team_name) # # Check the existence of the team and create it if it doesn't exist # team_exists = True res = self._customer_admin_sdclient.get_team(team_name) if res[0] == False: if res[1] == TEAM_NOT_EXISTING_ERR: team_exists = False new_memberships = dict(map(lambda u: (u, 'ROLE_TEAM_EDIT'), user_id_map.keys())) else: teaminfo = res[1] teamid = teaminfo['id'] old_memberships = dict(map(lambda m: (m['userId'], m['role']), teaminfo['userRoles'])) new_memberships = dict(map(lambda u: (u, 'ROLE_TEAM_EDIT') if user_id_map[u] not in old_memberships else (u, old_memberships[user_id_map[u]]), user_id_map.keys())) if team_exists: # Team exists. Detect if there are users to add and edit the team users list. newusers = [] team_uids = set(old_memberships.keys()) if team_uids != set(user_id_map.values()): Logger.log("Detected modified %s %s, editing team %s" % (self._type, obj_name, team_name)) newusers.append([u for u in user_id_map.keys() if user_id_map[u] not in team_uids]) res = self._customer_admin_sdclient.edit_team(team_name, memberships=new_memberships) if res[0] == False: Logger.log('Team editing failed: ' + res[1], 'error') return False else: Logger.log("Detected new %s %s, adding team %s" % (self._type, obj_name, team_name)) # Team doesn't exist. Try to create it. if self._type == 'deployment': flt = 'kubernetes.namespace.name = "%s" and kubernetes.deployment.name = "%s"' % (ns_name, obj_name) elif self._type == 'service': flt = 'kubernetes.namespace.name = "%s" and kubernetes.service.name = "%s"' % (ns_name, obj_name) elif self._type == 'namespace': flt = 'kubernetes.namespace.name = "%s"' % ns_name desc = 'automatically generated team based on deployment annotations' res = self._customer_admin_sdclient.create_team(team_name, filter=flt, description=desc, show='container', memberships=new_memberships) if res[0] == False: Logger.log('Team creation failed: ' + res[1], 'error') return False teamid = res[1]['team']['id'] newusers = user_id_map.keys() ################################################################### # TEAM CONFIGURATION ################################################################### # # If we have alerts, create a notification channel and point the # alerts at it. # if alerts: Logger.log('adding notification recipients') # # These steps can be done as the admin user since notification # channels have global scope and alerts has team scope, and admin # users are members of all teams. # res = self._customer_admin_sdclient.get_user_api_token(self._customer_id, team_name) if res[0] == False: Logger.log('Can\'t fetch token for user ' + user, 'error') return False else: utoken_t = res[1] teamclient = SdcClient(utoken_t, self._sdc_url) # # Add the email notification channel. This will silently fail # if it has already been created. # res = teamclient.create_email_notification_channel(team_name, recipients) if not res[0]: if res[1][:20] != EXISTING_CHANNEL_ERR: Logger.log('Error setting email recipient: ' + res[1], 'error') return False # # Get the notification channel ID to use for the alerts. # notify_channels = [{'type': 'EMAIL', 'name': team_name}] res = teamclient.get_notification_ids(notify_channels) if not res[0]: Logger.log("cannot create the email notification channel: " + res[1], 'error') return False notification_channel_ids = res[1] # # Make sure the members of the email notification channel are current. # Since we searched for the channel by name, there should only be one. But # since get_notification_ids() returns a list, treat it as such. # for channel_id in notification_channel_ids: res = teamclient.get_notification_channel(channel_id) if not res[0]: Logger.log("cannot find the email notification channel: " + res[1], 'error') return False c = res[1] current_recip = c['options']['emailRecipients'] if set(current_recip) == set(recipients): Logger.log('email recipients have not changed since last update', 'info') else: Logger.log('email recipients have changed - updating', 'info') c['options']['emailRecipients'] = copy.deepcopy(recipients) teamclient.update_notification_channel(c) # # Add the Alerts # res = teamclient.get_alerts() if not res[0]: Logger.log("cannot get user alerts: " + res[1], 'error') return False cur_alerts = res[1]['alerts'] for a in alerts: aname = a.get('name', '') # # Check if this alert already exists # skip = False for ca in cur_alerts: if ca['name'] == aname and 'annotations' in ca: skip = True break if skip: # # Alert already exists, skip the creation # continue Logger.log('adding alert %s' % aname) res = teamclient.create_alert(aname, # Alert name. a.get('description', ''), # Alert description. a.get('severity', 6), # Syslog-encoded severity. 6 means 'info'. a.get('timespan', 60000000), # The alert will fire if the condition is met for at least 60 seconds. a.get('condition', ''), # The condition. a.get('segmentBy', []), # Segmentation. We want to check this metric for every process on every machine. a.get('segmentCondition', 'ANY'), # in case there is more than one tomcat process, this alert will fire when a single one of them crosses the 80% threshold. a.get('filter', ''), # Filter. We want to receive a notification only if the name of the process meeting the condition is 'tomcat'. notification_channel_ids, a.get('enabled', True), {'engineTeam': team_name + aname}) if not res[0]: Logger.log('Error creating alert: ' + res[1], 'error') # # Go through the list of new users and set them up for this team # for user in user_id_map.keys(): # # First of all, we need to impersonate the users in this team # so that we can configure their workplace. This is # currently a little bit tricky because it involves: # - finding the user token using the admin API # - logging in with the new user token # Logger.log('impersonating user ' + user) res = self._customer_admin_sdclient.get_user_api_token(user, team_name) if res[0] == False: Logger.log('Can\'t fetch token for user ' + user, 'error') return False else: utoken_t = res[1] teamclient = SdcClient(utoken_t, self._sdc_url) Logger.log('waiting for activation of user ' + user) while True: res = teamclient.get_user_token() if res[0] == True: break else: time.sleep(3) # # Now that we are in the right user context, we can start to apply the # configurations. First of all we set a default kube-friendly grouping hierarchy. # We do this only is the user is new to the group, because we don't want to # pollute the grouping of existing users. # if user in newusers: Logger.log('setting grouping') if self._type == 'service': res = teamclient.set_explore_grouping_hierarchy(['kubernetes.namespace.name', 'kubernetes.service.name', 'kubernetes.pod.name', 'container.id']) else: res = teamclient.set_explore_grouping_hierarchy(['kubernetes.namespace.name', 'kubernetes.deployment.name', 'kubernetes.pod.name', 'container.id']) if res[0] == False: Logger.log('Failed setting team grouping: ' + res[1], 'error') return False # # Add the dashboards # res = teamclient.get_dashboards() if not res[0]: Logger.log('Error getting the dasboards list: ' + res[1], 'error') break existing_dasboards = res[1]['dashboards'] for d in dashboards: skip = False for ex in existing_dasboards: if ex['name'] == d: if ex['isShared'] and 'annotations' in ex and ex['annotations'].get('engineTeam') == team_name + d: # dashboard already exists. Skip adding it skip = True break if skip: continue Logger.log('adding dasboard ' + d) res = teamclient.create_dashboard_from_view(d, d, None, True, {'engineTeam': team_name + d, 'ownerUser': user}) if not res[0]: Logger.log('Error creating dasboard: ' + res[1], 'error')
print( 'You can find your token at https://app.sysdigcloud.com/#/settings/user' ) sys.exit(1) sdc_token = sys.argv[1] if len(sys.argv) == 3: hostname = sys.argv[2] else: hostname = None # # Instantiate the SDC client # sdclient = SdcClient(sdc_token) # # Prepare the metrics list. # metrics = [{ "id": "net.local.endpoint" }, { "id": "net.local.service" }, { "id": "net.remote.endpoint" }, { "id": "net.remote.service" }, { "id": "net.connection.count.total", "aggregations": {
import os import copy import json import requests import sys import hashlib import traceback sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), '..')) from sdcclient import SdcClient # Input Sysdig API token sdc_token = os.environ['SYSDIG_API_TOKEN'] # Instantiate the Sysdig client sdclient = SdcClient(sdc_token) #### TEAM CREATION ColonialOne #### nsfilter="kubernetes.namespace.name='devops-wekan'" print (filter) print('Now trying to create a team with name:', 'ColonialOne') ok, res = sdclient.create_team( 'ColonialOne', filter=nsfilter, show="container" ) if not ok: print('Team creation failed:', res, '. Exiting.') else: print('Team creation succeeded.', res)