Skip to content

Commit

Permalink
Merge pull request #21 from diggyk/master
Browse files Browse the repository at this point in the history
Add support for creating events for each host in a Quest.
  • Loading branch information
gmjosack committed Jun 30, 2015
2 parents c491727 + e31b991 commit e1845e9
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 11 deletions.
71 changes: 69 additions & 2 deletions bin/hermes
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,37 @@ def request_post(path, json):
return response


def request_put(path, json):
"""Make an HTTP PUT request for the given path
If a non-OK status is returned, display the error message and exit
Args:
path: the full path to the resource
json: the json to send in the body
Returns:
the http response
"""
for attempt in retry(settings.api_retries):
response = requests.put(settings.hermes_server + path, json=json)
if response.status_code < 500:
break

if (
response.status_code != requests.codes.ok
or not response.content
):
try:
data = response.json()["error"]["message"]
except Exception:
data = "Received invalid response: {}".format(response.content)
raise HermesException(
"Error: {}".format(data)
)

return response


def ping_server(args):
"""Ping the Hermes API server and ensure it responds. Return output
appropriate for a Nagios-style monitoring service.
Expand Down Expand Up @@ -325,6 +356,30 @@ def add_host(args):
)


def rename_host(args):
logging.debug("rename_host(%s, %s)", args.oldname, args.newname)
response = request_get("/api/v1/hosts?hostname={}".format(args.oldname))
hosts = response.json()

if hosts["totalHosts"] != 1:
sys.exit("Host {} does not exist".format(args.oldname))

json = {
"hostname": args.newname
}

response = request_put("/api/v1/hosts/{}".format(args.oldname), json)

if response.json()["status"] == "ok":
print "Renamed host {} to {}".format(
args.oldname, response.json()["hostname"]
)
else:
sys.exit(
"Received unexpected status renaming host {}".format(args.oldname)
)


def list_host_last_state(args):
logging.debug("list_host_last_state(%s)", args.hostname)

Expand Down Expand Up @@ -506,8 +561,9 @@ def list_labors(args):
def create_event(args):
logging.debug("create_event()")
logging.debug(
"host: %s category: %s state: %s note: %s query: %s",
args.hostname, args.category, args.state, args.note, args.query
"host: %s category: %s state: %s note: %s query: %s, quest: %s",
args.hostname, args.category, args.state, args.note, args.query,
args.quest_id
)

response = request_get("/api/v1/eventtypes?limit=all")
Expand Down Expand Up @@ -542,6 +598,8 @@ def create_event(args):
if args.query:
json["hostQuery"] = args.query

if args.quest_id:
json["questId"] = args.quest_id

response = request_post("/api/v1/events", json)

Expand Down Expand Up @@ -880,6 +938,11 @@ def parse_cli_args():
host_add_parser = host_subparser.add_parser("add")
host_add_parser.add_argument("hostname")
host_add_parser.set_defaults(func=add_host)
# Host rename parser
host_rename_parser = host_subparser.add_parser("rename")
host_rename_parser.add_argument("oldname")
host_rename_parser.add_argument("newname")
host_rename_parser.set_defaults(func=rename_host)
# Host events parsers
host_events_parser = host_subparser.add_parser("events")
host_events_parser.add_argument("hostname")
Expand Down Expand Up @@ -944,6 +1007,10 @@ def parse_cli_args():
"--query", type=str,
help="Query for Hosts for which to create this Event"
)
event_create_parser.add_argument(
"--questId", type=str, dest="quest_id",
help="Create Events for each of the Hosts in this Quest"
)
event_create_parser.set_defaults(func=create_event)

# monitoring ping command line parser
Expand Down
55 changes: 48 additions & 7 deletions hermes/handlers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,12 +797,39 @@ def post(self):
Content-Type: application/json
{
"hostname": "example",
"user": "johnny",
"eventTypeId": 3,
"note": "Sample description"
}
or
.. sourcecode:: http
POST /api/v1/events HTTP/1.1
Host: localhost
Content-Type: application/json
{
"hostQuery": "tag=value",
"user": "johnny",
"eventTypeId": 3,
"note": "Sample description"
}
or
.. sourcecode:: http
POST /api/v1/events HTTP/1.1
Host: localhost
Content-Type: application/json
{
"questId": 1,
"user": "johnny",
"eventTypeId": 3,
"note": "Sample description"
}
**Example response:**
.. sourcecode:: http
Expand Down Expand Up @@ -841,9 +868,11 @@ def post(self):
]
}
:reqjson string hostname: The hostname of the Host of this Event
:reqjson string hostname: (*optional*) The hostname of the Host of this Event
:reqjson string hostQuery: (*optional*) The external query to run to get Hosts for which to create Events
:regjson int queryId: (*optional*) The Quest ID which has hosts for which we want to create Events
:regjson string user: The user responsible for throwing this Event
:regjson string eventTypeId: The id of the EventType
:regjson int eventTypeId: The id of the EventType
:regjson string note: (*optional*) The human readable note describing this Event
:reqheader Content-Type: The server expects a json body specified with
Expand All @@ -858,10 +887,6 @@ def post(self):
"""

try:
hostnames = (
[self.jbody.get("hostname", None)]
if self.jbody.get("hostname", None) else []
)
user = self.jbody["user"]
if not EMAIL_REGEX.match(user):
user += "@" + self.domain
Expand All @@ -880,6 +905,11 @@ def post(self):
self.write_error(400, message="Bad event type")
return

hostnames = (
[self.jbody.get("hostname", None)]
if self.jbody.get("hostname", None) else []
)

# If a host query was specified, we need to talk to the external
# query server to resolve this into a list of hostnames
if "hostQuery" in self.jbody:
Expand All @@ -888,6 +918,17 @@ def post(self):
if response.json()["status"] == "ok":
hostnames.extend(response.json()["results"])

# If a quest Id was given, look up the labors in that quest and
# get all the hostnames for those labors.
if "questId" in self.jbody:
quest = self.session.query(Quest).filter_by(
id=self.jbody["questId"]
).scalar()
if not quest:
raise exc.NotFound("No such Quest {} found".format(id))
for labor in quest.labors:
hostnames.append(labor.host.hostname)

# We need to create a list of hostnames that don't have a Host record
new_hosts_needed = list(hostnames)
hosts = (
Expand All @@ -905,7 +946,7 @@ def post(self):
).all()
)

if len(hosts) == 0:
if not hosts:
raise exc.BadRequest("No hosts found with given list")

try:
Expand Down
2 changes: 1 addition & 1 deletion hermes/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def slack_message(message):
"icon_emoji": ":hermes:",
}
try:
log.info("{} {}".format(settings.slack_webhook, json))
log.debug("{} {}".format(settings.slack_webhook, json))
response = requests.post(
settings.slack_webhook, json=json, proxies=proxies
)
Expand Down
2 changes: 1 addition & 1 deletion hermes/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.1.29"
__version__ = "0.1.30"
19 changes: 19 additions & 0 deletions tests/api_tests/test_quests.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,25 @@ def test_creation(sample_data1_server):
strip=["events"]
)

# see if we can create events based on quest id
client.create(
"/events",
questId=1,
user="testman@example.com",
eventTypeId=2,
note="These are test events for the quest"
)

assert_success(
client.get("/events"),
{
"href": "/api/v1/events",
"limit": 10,
"offset": 0,
"totalEvents": 8
},
strip=["events"]
)

def test_update(sample_data1_server):
client = sample_data1_server
Expand Down

0 comments on commit e1845e9

Please sign in to comment.