Created
November 25, 2014 06:15
-
-
Save wolfdancer/6a0aa339a311e08abd70 to your computer and use it in GitHub Desktop.
pull host info from agents under an acconut
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2.7 | |
""" | |
This plugin will hit the monitoring API, pull entities, agents and host info from the account, and push to another service. | |
To use: | |
./hostinfo.py --user <username> --api-key <api key> | |
Todo: | |
============= | |
# The entities response is paginated at 100. Need to handle the case where there are more entities | |
# The agents response is paginated at 100 | |
# Handle the case where info type is not supported (agents/<agent_id>/host_info_types) | |
""" | |
import argparse | |
import urllib2 | |
import json | |
import sys | |
import re | |
from sets import Set | |
from datetime import datetime | |
import requests | |
monitoring_api = 'https://monitoring.api.rackspacecloud.com/v1.0/' | |
dbaas_uri = re.compile( | |
'^https:\/\/(ord|dfw|lon|syd|iad|hkg)\.databases\.api.rackspacecloud\.com\/') | |
cloudserver_uri = re.compile( | |
'^https:\/\/((ORD|LON|DFW|HKG|IAD|ord|dfw|lon|syd|iad|hkg)?\.)?servers\.api\.rackspacecloud\.com\/') | |
def login(): | |
auth_payload = { | |
'auth':{ | |
'RAX-KSKEY:apiKeyCredentials':{ | |
'username': args.user, | |
'apiKey': args.api_key | |
} | |
} | |
} | |
try: | |
auth_req = urllib2.Request(args.auth_uri) | |
auth_req.add_header('Content-type', 'application/json') | |
auth_resp = json.loads(urllib2.urlopen(auth_req, json.dumps(auth_payload)).read()) | |
except urllib2.HTTPError: | |
print 'status err Unable to authenticate user {0}'.format(args.user) | |
sys.exit(1) | |
else: | |
auth_token = auth_resp['access']['token']['id'] | |
tenant_id = auth_resp['access']['token']['tenant']['id'] | |
return auth_token, tenant_id | |
def urlopen(api, auth_token, tenant_id): | |
url = monitoring_api + api | |
print("loading " + url) | |
request = urllib2.Request(url) | |
request.add_header('X-Auth-Token', auth_token) | |
request.add_header('X-Tenant-Id', tenant_id) | |
return json.loads(urllib2.urlopen(request).read()) | |
def to_json(content): | |
return json.dumps(content, sort_keys="True", indent=2, separators=(',', ': ')) | |
def derive_product(uri): | |
if not uri: | |
return "unknown" | |
elif dbaas_uri.match(uri): | |
return "cloud_database" | |
elif cloudserver_uri.match(uri): | |
return "cloud_server" | |
return "unknown" | |
def copy(source, fields): | |
values = {} | |
for field in fields: | |
if source.get(field): | |
values[field] = source[field] | |
return values | |
def retrieve_hostinfo(auth_token, tenant_id, agent_id, infotype, fields): | |
payload = urlopen("agents/{}/host_info/{}".format(agent_id, infotype), auth_token, tenant_id) | |
if payload["error"]: | |
entity["error"][infotype] = processes_payload["error"] | |
info_payload = payload["info"] | |
updatedtime = payload["timestamp"] | |
if isinstance(info_payload, list): | |
entries = [] | |
for item in info_payload: | |
entries.append(copy(item, fields)) | |
return entries, updatedtime | |
else: | |
return copy(info_payload, fields), updatedtime | |
def date_string(timestamp): | |
return datetime.fromtimestamp(timestamp/1000).strftime("%Y-%m-%d %H:%M:%S") | |
def main(): | |
auth_token, tenant_id = login() | |
print("X-Auth-Token:" + auth_token) | |
print("X-Tenant-Id:" + tenant_id) | |
entities = urlopen("entities", auth_token, tenant_id) | |
payload = [] | |
for entity in entities["values"]: | |
entity_payload = { | |
"id": entity["id"], | |
"agent_id": entity["agent_id"], | |
"label": entity["label"], | |
"tenant_id": tenant_id, | |
"uri": entity["uri"] | |
} | |
entity_payload["product"] = derive_product(entity["uri"]) | |
payload.append(entity_payload) | |
agents_payload = urlopen("agents", auth_token, tenant_id) | |
agents = Set() | |
for agent in agents_payload["values"]: | |
agents.add(agent["id"]) | |
for entity in payload: | |
agent_id = entity["agent_id"] | |
entity["error"] = {} | |
if not agent_id: | |
continue | |
elif agent_id not in agents: | |
entity["agent_id"] = "(not connected) " + agent_id | |
continue | |
entity["processes"], updatedtime = retrieve_hostinfo(auth_token, tenant_id, agent_id, "processes", ["pid", "exe_name", "exe_cwd", "exe_root", "state_name"]) | |
entity['network_interfaces'], updatedtime = retrieve_hostinfo(auth_token, tenant_id, agent_id, "network_interfaces", ["address", "address6", "hwaddr", "name", "netmask", "type"]) | |
entity["system"], updatedtime = retrieve_hostinfo(auth_token, tenant_id, agent_id, "system", ["arch", "name", "vendor", "vendor_name", "vendor_version", "version"]) | |
entity["update_time"] = date_string(updatedtime) | |
print to_json(payload) | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser(description='Monitornig host info') | |
parser.add_argument('--user', dest='user', action='store', | |
required=True, help='The Rackspace user') | |
parser.add_argument('--api-key', dest='api_key', action='store', | |
required=True, help='The Rackspace API key') | |
parser.add_argument('--auth-uri', dest='auth_uri', action='store', | |
default='https://identity.api.rackspacecloud.com/v2.0/tokens', | |
help='The Rackspace Identity token endpoint') | |
args = parser.parse_args() | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment