Skip to content

Commit

Permalink
Remove ContactsData from CommonData
Browse files Browse the repository at this point in the history
This is because ContactsData comes from a different data source
(that may not be available) than the rest of the topology objects.
Now I have to pass ContactsData down to the methods that need it;
this is annoying but it lets me save the other topology objects
without embedding the ContactsData (or lack thereof) into them.
  • Loading branch information
matyasselmeci committed May 20, 2024
1 parent fc3020f commit 3b2bd3e
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 56 deletions.
25 changes: 16 additions & 9 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ def homepage():

@app.route('/map/iframe')
def map():
rgsummary = global_data.get_topology().get_resource_summary()
rgsummary = global_data.get_topology().get_resource_summary(contacts=None)

return _fix_unicode(render_template('iframe.html.j2', resourcegroups=rgsummary["ResourceSummary"]["ResourceGroup"]))

@app.route('/api/resource_group_summary')
def resource_summary():
data = global_data.get_topology().get_resource_summary()["ResourceSummary"]["ResourceGroup"]
data = global_data.get_topology().get_resource_summary(contacts=None)["ResourceSummary"]["ResourceGroup"]

return Response(
to_json_bytes(simplify_attr_list(data, namekey='GroupName', del_name=False)),
Expand Down Expand Up @@ -350,37 +350,44 @@ def miscfacility_json():
def miscresource_json():
resources = {}
topology = global_data.get_topology()
contacts_ = global_data.get_contacts_data()
for rg in topology.rgs.values():
for resource in rg.resources_by_name.values():
resources[resource.name] = {
"Name": resource.name,
"Site": rg.site.name,
"Facility": rg.site.facility.name,
"ResourceGroup": rg.name,
**resource.get_tree()
**resource.get_tree(contacts=contacts_)
}

return Response(to_json_bytes(resources), mimetype='application/json')

@app.route('/vosummary/xml')
def vosummary_xml():
return _get_xml_or_fail(global_data.get_vos_data().get_tree, request.args)
return _get_xml_or_fail(global_data.get_vos_data().get_tree,
global_data.get_contacts_data(),
request.args)

@app.route('/vosummary/json')
def vosummary_json():
return Response(to_json_bytes(
simplify_attr_list(global_data.get_vos_data().get_expansion(), namekey='Name')
simplify_attr_list(global_data.get_vos_data().get_expansion(contacts_data=None), namekey='Name')
), mimetype="application/json")


@app.route('/rgsummary/xml')
def rgsummary_xml():
return _get_xml_or_fail(global_data.get_topology().get_resource_summary, request.args)
return _get_xml_or_fail(global_data.get_topology().get_resource_summary,
global_data.get_contacts_data(),
request.args)


@app.route('/rgdowntime/xml')
def rgdowntime_xml():
return _get_xml_or_fail(global_data.get_topology().get_downtimes, request.args)
return _get_xml_or_fail(global_data.get_topology().get_downtimes,
global_data.get_contacts_data(),
request.args)


@app.route('/rgdowntime/ical')
Expand Down Expand Up @@ -1091,13 +1098,13 @@ def filter_value(filter_key):
return filters


def _get_xml_or_fail(getter_function, args):
def _get_xml_or_fail(getter_function, contacts_, args):
try:
filters = get_filters_from_args(args)
except InvalidArgumentsError as e:
return Response("Invalid arguments: " + str(e), status=400)
return Response(
to_xml_bytes(getter_function(_get_authorized(), filters)),
to_xml_bytes(getter_function(contacts_, _get_authorized(), filters)),
mimetype="text/xml"
)

Expand Down
4 changes: 2 additions & 2 deletions src/webapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ def update_topology(self):
ok = self._update_topology_repo()
if ok:
try:
self.topology.update(rg_reader.get_topology(self.topology_dir, self.get_contacts_data(), strict=self.strict))
self.topology.update(rg_reader.get_topology(self.topology_dir, strict=self.strict))
except Exception:
if self.strict:
raise
Expand All @@ -323,7 +323,7 @@ def get_vos_data(self) -> Optional[VOsData]:
ok = self._update_topology_repo()
if ok:
try:
self.vos_data.update(vo_reader.get_vos_data(self.vos_dir, self.get_contacts_data(), strict=self.strict))
self.vos_data.update(vo_reader.get_vos_data(self.vos_dir, strict=self.strict))
except Exception:
if self.strict:
raise
Expand Down
10 changes: 5 additions & 5 deletions src/webapp/rg_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,18 @@ def get_rgsummary_rgdowntime(indir, contacts_file=None, authorized=False, strict
contacts_data = None
if contacts_file:
contacts_data = get_contacts_data(contacts_file)
topology = get_topology(indir, contacts_data, strict=strict)
topology = get_topology(indir, strict=strict)
filters = Filters()
filters.past_days = -1
return topology.get_resource_summary(authorized=authorized, filters=filters), \
topology.get_downtimes(authorized=authorized, filters=filters)
return topology.get_resource_summary(contacts=contacts_data, authorized=authorized, filters=filters), \
topology.get_downtimes(contacts=contacts_data, authorized=authorized, filters=filters)


def get_topology(indir="../topology", contacts_data=None, strict=False):
def get_topology(indir="../topology", strict=False):
root = Path(indir)
support_centers = load_yaml_file(root / "support-centers.yaml")
service_types = load_yaml_file(root / "services.yaml")
tables = CommonData(contacts=contacts_data, service_types=service_types, support_centers=support_centers)
tables = CommonData(service_types=service_types, support_centers=support_centers)
topology = Topology(tables)

skip_msg = "skipping (non-strict mode)"
Expand Down
26 changes: 13 additions & 13 deletions src/webapp/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ class TopologyError(Exception): pass

class CommonData(object):
"""Global data, e.g. various mappings and contacts info"""
def __init__(self, contacts: ContactsData, service_types: Dict, support_centers: Dict):
self.contacts = contacts
def __init__(self, service_types: Dict, support_centers: Dict):
self.service_types = service_types
self.support_centers = support_centers

Expand Down Expand Up @@ -202,7 +201,7 @@ def get_stashcache_files(self, global_data, legacy):

return stashcache_files

def get_tree(self, authorized=False, filters: Filters = None) -> Optional[OrderedDict]:
def get_tree(self, contacts: Optional[ContactsData], authorized=False, filters: Filters = None) -> Optional[OrderedDict]:
if filters is None:
filters = Filters()

Expand Down Expand Up @@ -247,7 +246,7 @@ def get_tree(self, authorized=False, filters: Filters = None) -> Optional[Ordere
if "FQDNAliases" in self.data:
new_res["FQDNAliases"] = {"FQDNAlias": self.data["FQDNAliases"]}
if not is_null(self.data, "ContactLists"):
new_res["ContactLists"] = self._expand_contactlists(self.data["ContactLists"], authorized)
new_res["ContactLists"] = self._expand_contactlists(self.data["ContactLists"], authorized, contacts=contacts)
new_res["Name"] = self.name
if "WLCGInformation" in self.data and isinstance(self.data["WLCGInformation"], dict):
new_res["WLCGInformation"] = self._expand_wlcginformation(self.data["WLCGInformation"])
Expand Down Expand Up @@ -325,15 +324,15 @@ def _get_charturl(ownership):
("ChartURL", _get_charturl(voownership.items()))
])

def _expand_contactlists(self, contactlists: Dict, authorized: bool) -> Dict:
def _expand_contactlists(self, contactlists: Dict, authorized: bool, contacts: Optional[ContactsData]) -> Dict:
"""Return the data structure for an expanded ContactLists for a single Resource."""
new_contactlists = []
for contact_type, contact_data in contactlists.items():
contact_data = expand_attr_list(contact_data, "ContactRank", ["Name", "ID", "ContactRank"], ignore_missing=True)
for contact in contact_data:
contact_id = contact.pop("ID", None) # ID is for internal use - don't put it in the results
if self.common_data.contacts and contact_id in self.common_data.contacts.users_by_id:
user = self.common_data.contacts.users_by_id[contact_id] # type: User
if contacts and contact_id in contacts.users_by_id:
user = contacts.users_by_id[contact_id] # type: User
contact["CILogonID"] = user.cilogon_id
if authorized:
contact["Email"] = user.email
Expand Down Expand Up @@ -397,7 +396,7 @@ def resources(self):
def itb(self):
return not self.production

def get_tree(self, authorized=False, filters: Filters = None) -> Optional[OrderedDict]:
def get_tree(self, contacts: Optional[ContactsData], authorized=False, filters: Filters = None) -> Optional[OrderedDict]:
if filters is None:
filters = Filters()
for filter_list, attribute in [(filters.facility_id, self.site.facility.id),
Expand All @@ -413,7 +412,7 @@ def get_tree(self, authorized=False, filters: Filters = None) -> Optional[Ordere
filtered_resources = []
for res in self.resources:
try:
tree = res.get_tree(authorized, filters)
tree = res.get_tree(contacts, authorized, filters)
if tree:
filtered_resources.append(tree)
except (AttributeError, KeyError, ValueError) as err:
Expand Down Expand Up @@ -641,7 +640,7 @@ def parsetime(cls, time_str: str) -> datetime:

class Topology(object):
def __init__(self, common_data: CommonData):
self.downtimes_by_timeframe = {
self.downtimes_by_timeframe: Dict[Timeframe, List[Downtime]] = {
Timeframe.PAST: [],
Timeframe.PRESENT: [],
Timeframe.FUTURE: []}
Expand Down Expand Up @@ -691,23 +690,24 @@ def get_resource_group_list(self):
"""
return self.rgs.values()

def get_resource_summary(self, authorized=False, filters: Filters = None) -> Dict:
def get_resource_summary(self, contacts: Optional[ContactsData], authorized=False, filters: Filters = None) -> Dict:
if filters is None:
filters = Filters()
rglist = []
for rgkey in sorted(self.rgs.keys(), key=lambda x: x[1].lower()):
rgval = self.rgs[rgkey]
assert isinstance(rgval, ResourceGroup)
rgtree = rgval.get_tree(authorized, filters)
rgtree = rgval.get_tree(contacts, authorized, filters)
if rgtree:
rglist.append(rgtree)
return {"ResourceSummary":
{"@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"@xsi:schemaLocation": RGSUMMARY_SCHEMA_URL,
"ResourceGroup": rglist}}

def get_downtimes(self, authorized=False, filters: Filters = None) -> Dict:
def get_downtimes(self, contacts: Optional[ContactsData], authorized=False, filters: Filters = None) -> Dict:
_ = authorized
_ = contacts
if filters is None:
filters = Filters()

Expand Down
6 changes: 3 additions & 3 deletions src/webapp/vo_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
log = logging.getLogger(__name__)


def get_vos_data(indir, contacts_data, strict=False) -> VOsData:
def get_vos_data(indir, strict=False) -> VOsData:
reporting_groups_data = load_yaml_file(os.path.join(indir, "REPORTING_GROUPS.yaml"))
vos_data = VOsData(contacts_data=contacts_data, reporting_groups_data=reporting_groups_data)
vos_data = VOsData(reporting_groups_data=reporting_groups_data)
for file in os.listdir(indir):
if file == "REPORTING_GROUPS.yaml": continue
if not file.endswith(".yaml"): continue
Expand Down Expand Up @@ -59,7 +59,7 @@ def main(argv):
if args.contacts:
contacts_data = get_contacts_data(args.contacts)
xml = to_xml(
get_vos_data(args.indir, contacts_data=contacts_data, strict=args.strict).get_tree(authorized=True))
get_vos_data(args.indir, strict=args.strict).get_tree(contacts=contacts_data, authorized=True))
if args.outfile:
with open(args.outfile, "w") as fh:
fh.write(xml)
Expand Down
Loading

0 comments on commit 3b2bd3e

Please sign in to comment.