Skip to content

Commit

Permalink
Merge pull request #56 from diggyk/master
Browse files Browse the repository at this point in the history
Added forOwner and forCreator support to Web UI
  • Loading branch information
jathanism committed Sep 30, 2015
2 parents 00d54ff + 3a565c0 commit 9f09b9c
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 115 deletions.
10 changes: 10 additions & 0 deletions db/update_to_046.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ALTER TABLE `fates` ADD `for_owner` INT(1) NOT NULL DEFAULT 1 AFTER `follows_id`;
ALTER TABLE `fates` ADD `for_creator` INT(1) NOT NULL DEFAULT 0 AFTER `follows_id`;
ALTER TABLE `labors` ADD `for_owner` INT(1) NOT NULL DEFAULT 1 AFTER `host_id`;
ALTER TABLE `labors` ADD `for_creator` INT(1) NOT NULL DEFAULT 0 AFTER `host_id`;

UPDATE `fates` SET `for_owner`=0 where `id`=2;
UPDATE `fates` SET `for_creator`=1 where `id`=2;

UPDATE `labors` SET `for_owner`=1, `for_creator`=0 where `starting_labor_id` IS NULL;
UPDATE `labors` SET `for_owner`=0, `for_creator`=1 where `starting_labor_id` IS NOT NULL;
68 changes: 55 additions & 13 deletions hermes/handlers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1514,7 +1514,7 @@ def get(self):
:query string hostname: (*optional*) filter Labors by a particular hostname
:query string startingLaborId: (*optional*) get Labors by the Id or the Id of the starting labor
:query string hostQuery: (*optional*) the query to send to the plugin to come up with the list of hostnames
:query string userQuery: (*optional*) the user query to send to the plugin to come up with the list of hostnames
:query string userQuery: (*optional*) get labors for machines ownen by this user or for which this user is responsible
:query string category: (*optional*) limit labors to ones where the starting event type is of this category
:query string state: (*optional*) limit labors to ones where the starting event type is of this state
:query boolean open: if true, filter Labors to those still open
Expand All @@ -1537,8 +1537,10 @@ def get(self):

labors = self.session.query(Labor)

# if filtering by category or state, find the event types that match
# these conditions and add them to the query
if category or state:
event_types = self.session.query(EventType);
event_types = self.session.query(EventType)
if category:
event_types = event_types.filter(
EventType.category == category
Expand All @@ -1552,6 +1554,7 @@ def get(self):
EventType.id.in_(valid_event_types)
)

# if specifying to filter by open or closed state, add that to the query
if open_flag and open_flag.lower() == "true":
labors = labors.filter(Labor.completion_event_id == None)
if open_flag and open_flag.lower() == "false":
Expand All @@ -1566,6 +1569,8 @@ def get(self):
Labor.starting_labor_id == starting_labor_id
))

# if user wants to filter by a specific host, verify that the host is
# good and add that to the query
if hostname is not None:
try:
host = (
Expand All @@ -1581,6 +1586,8 @@ def get(self):
.order_by(desc(Labor.creation_time))
)

# if the user specified a host query, we need to translate that into a
# list of hostnames to use.
host_query_hostnames = []
if host_query:
response = PluginHelper.request_get(params={"query": host_query})
Expand All @@ -1594,7 +1601,10 @@ def get(self):
else:
raise exc.BadRequest("Bad host query: {}".format(host_query))

# if the user wants to filter by user, let's first find the hostnames
# of machines the user would be responsible for
user_query_hostnames = []
user_created_quests = []
if user_query:
response = PluginHelper.request_get(params={"user": user_query})
if (
Expand All @@ -1606,26 +1616,58 @@ def get(self):
else:
raise exc.BadRequest("Bad user query: {}".format(user_query))

user_created_quests =[
quest.id for quest in
(
self.session.query(Quest).filter(
Quest.creator == user_query
).all()
)
]

# since we may have used multiple ways to get hostname lists, compile
# into a final list of hostnames we care about
hostnames = []
if host_query and user_query:
hostnames = list(set(host_query_hostnames) & set(user_query_hostnames))
hostnames = list(
set(host_query_hostnames) & set(user_query_hostnames)
)
elif host_query_hostnames:
hostnames = host_query_hostnames
elif user_query_hostnames:
hostnames = user_query_hostnames;
hostnames = user_query_hostnames

# if we are just doing a simple host_query, we can just filter by
# the hostnames we collected. Otherwise, if we are doing a user_query
# we need not just hosts owned by the user, but also labors that belong
# to a quest creator that matches the user name
if host_query or user_query:
if hostnames:
hosts = (
self.session.query(Host).filter(
Host.hostname.in_(hostnames)
)
)
host_ids = [host.id for host in hosts]
labors = labors.filter(Labor.host_id.in_(host_ids))
else:
if not hostnames:
raise exc.BadRequest("Querying on 0 hosts")

hosts = (
self.session.query(Host).filter(
Host.hostname.in_(hostnames)
)
)
host_ids = [host.id for host in hosts]
if not user_query:
labors = labors.filter(and_(
Labor.host_id.in_(host_ids),
Labor.for_owner == 1
))
elif hostnames and user_query:
labors = labors.filter(or_(
and_(
Labor.host_id.in_(host_ids),
Labor.for_owner == 1
),
and_(
Labor.for_creator == 1,
Labor.quest_id.in_(user_created_quests)
)
))

offset, limit, expand = self.get_pagination_values()
labors, total = self.paginate_query(labors, offset, limit)

Expand Down
8 changes: 4 additions & 4 deletions hermes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -885,8 +885,8 @@ def to_dict(self, base_uri=None, expand=None):
"completionEventTypeId": self.completion_type_id,
"follows_id": self.follows_id,
"precedes_ids": [labor.id for labor in self.precedes],
"for_creator": self.for_creator,
"for_owner": self.for_owner,
"forCreator": self.for_creator,
"forOwner": self.for_owner,
"description": self.description,
}

Expand Down Expand Up @@ -1635,8 +1635,8 @@ def to_dict(self, base_uri=None, expand=None):
"startingLaborId": self.starting_labor_id,
"questId": self.quest_id,
"hostId": self.host_id,
"for_creator": self.for_creator,
"for_owner": self.for_owner,
"forCreator": self.for_creator,
"forOwner": self.for_owner,
"creationTime": str(self.creation_time),
"creationEventId": self.creation_event_id,
"completionTime": (
Expand Down
3 changes: 1 addition & 2 deletions hermes/webapp/src/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -579,5 +579,4 @@ button:hover {
-moz-border-radius: 5px;
border-radius: 5px;
background: #ffffff;
}

}
2 changes: 1 addition & 1 deletion hermes/webapp/src/js/controllers/laborStatusCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
vm.offset = data['offset'] || vm.offset;
vm.totalLabors = data['totalLabors'] || vm.totalLabors;

// find the quest requested and make that the selection
// find the labor requested and make that the selection
var index = 0;
for (var idx in vm.laborData) {
if (vm.laborData[idx]['id'] == $routeParams.laborId) {
Expand Down
99 changes: 76 additions & 23 deletions hermes/webapp/src/js/controllers/questStatusCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,44 +200,97 @@
}
}

// sort the unique labors into a buckets based on the owner and labor type
var sortedLabors = {};
vm.types = {};
for (var idx in laborsUnique) {
var hostname = laborsUnique[idx]['host']['hostname'];
var owner = null;

var owner = ownerData[hostname];
var creator = questData['creator'];
var forOwner = laborsUnique[idx]['forOwner'];
var forCreator = laborsUnique[idx]['forCreator'];

if (forOwner && !sortedLabors[owner]) {
sortedLabors[owner] = {};
}

if (!sortedLabors[owner]) {
sortedLabors[owner] = {}
if (forCreator && !sortedLabors[creator]) {
sortedLabors[creator] = {};
}
var ownerLabors = sortedLabors[owner];

// if this labor is completed, we will file it by the complete event type
if (laborsUnique[idx]['completionEvent']) {
var completionEventType = laborsUnique[idx]['completionEvent']['eventType'];
var key = completionEventType['category'] + " " + completionEventType['state'];
// update the count of labors by type
vm.types[key] ? vm.types[key]++ : vm.types[key] = 1;
if (ownerLabors[key]) {
ownerLabors[key]['count']++;
ownerLabors[key]['hosts'].push(
laborsUnique[idx]['host']['hostname']
)
} else {
ownerLabors[key] = {
'count': 1,
'hosts': [laborsUnique[idx]['host']['hostname']]

// sort into the bucket for this owner, if the labor is for the server owner
if (forOwner) {
if (sortedLabors[owner][key]) {
sortedLabors[owner][key]['count']++;
sortedLabors[owner][key]['hosts'].push(
laborsUnique[idx]['host']['hostname']
)
} else {
sortedLabors[owner][key] = {
'count': 1,
'hosts': [laborsUnique[idx]['host']['hostname']]
}
}
}
} else {

// sort into the bucket for the quest creator, if this labor is for the quest creator
if (forCreator) {
if (sortedLabors[creator][key]) {
sortedLabors[creator][key]['count']++;
sortedLabors[creator][key]['hosts'].push(
laborsUnique[idx]['host']['hostname']
)
} else {
sortedLabors[creator][key] = {
'count': 1,
'hosts': [laborsUnique[idx]['host']['hostname']]
}
}
}

} else { // for incomplete labors, file by the creating event type
var creationEventType = laborsUnique[idx]['creationEvent']['eventType'];
var key = creationEventType['category'] + " " + creationEventType['state']
var key = creationEventType['category'] + " " + creationEventType['state'];

// update the count of labors by type
vm.types[key] ? vm.types[key]++ : vm.types[key] = 1;
if (ownerLabors[key]) {
ownerLabors[key]['count']++;
ownerLabors[key]['hosts'].push(
laborsUnique[idx]['host']['hostname']
)
} else {
ownerLabors[key] = {
'count': 1,
'hosts': [laborsUnique[idx]['host']['hostname']]

// sort into the bucket for the server owner if the labor is for the owner
if (forOwner) {
if (sortedLabors[owner][key]) {
sortedLabors[owner][key]['count']++;
sortedLabors[owner][key]['hosts'].push(
laborsUnique[idx]['host']['hostname']
)
} else {
sortedLabors[owner][key] = {
'count': 1,
'hosts': [laborsUnique[idx]['host']['hostname']]
}
}
}

// sort into the bucket for the quest creator if the labor is designate for them
if (forCreator) {
if (sortedLabors[creator][key]) {
sortedLabors[creator][key]['count']++;
sortedLabors[creator][key]['hosts'].push(
laborsUnique[idx]['host']['hostname']
)
} else {
sortedLabors[creator][key] = {
'count': 1,
'hosts': [laborsUnique[idx]['host']['hostname']]
}
}
}
}
Expand Down
18 changes: 11 additions & 7 deletions hermes/webapp/src/templates/laborList.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,24 @@
<div class="row">
<div class="info-panel col-md-6">
<strong class="label">Tags:</strong>
<div>
<img ng-if="!lsc.hostTags" src="/img/loading_15.gif" alt="Tag information loading" />
<ul ng-if="lsc.hostTags">
<li ng-repeat="tag in lsc.hostTags[labor.host.hostname]">
<li>
owner=<img ng-if="!lsc.hostOwners" src="/img/loading_15.gif" alt="Owner information loading" />
<span ng-if="lsc.hostOwners">{{lsc.hostOwners[labor.host.hostname]}}</span>
</li>
<li ng-repeat="tag in lsc.hostTags[labor.host.hostname] track by $index">
{{tag}}
</li>
</ul>
</div>
</div>
<div class="info-panel col-md-6">
<strong class="label">Owner:</strong>
<div class="details">
<img ng-if="!lsc.hostOwners" src="/img/loading_15.gif" alt="Owner information loading" />
<span ng-if="lsc.hostOwners">{{lsc.hostOwners[labor.host.hostname]}}</span>
<strong class="label">Labor For:</strong>
<div ng-if="labor.forOwner == true" class="details">
Server Owner
</div>
<div ng-if="labor.forCreator == true" class="details">
Quest Creator
</div>
</div>
<div class="row" ng-if="labor.quest">
Expand Down

0 comments on commit 9f09b9c

Please sign in to comment.