Skip to content

Commit

Permalink
Initial work on Auditor accounting plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-k committed Aug 24, 2022
1 parent d45425a commit 8dfee02
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ def get_cryptography_version():
"python-multipart",
"typing_extensions",
"backports.cached_property",
"python-auditor",
"pytz",
"tzlocal",
],
extras_require={
"docs": [
Expand Down
105 changes: 105 additions & 0 deletions tardis/plugins/auditor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from ..configuration.configuration import Configuration
from ..interfaces.plugin import Plugin
from ..interfaces.state import State
from ..utilities.attributedict import AttributeDict
from ..resources.dronestates import AvailableState, DownState

from pyauditor import AuditorClientBuilder, Record, Component, Score

import logging
from datetime import timezone
import pytz
from tzlocal import get_localzone


class Auditor(Plugin):
"""
The :py:class:`~tardis.plugins.auditor.Auditor` TODO
"""

def __init__(self):
self.logger = logging.getLogger("cobald.runtime.tardis.plugins.auditor")
config = Configuration()
config_auditor = config.Plugins.Auditor

self._resources = {}
self._factors = {}
for site in config.Sites:
self._resources[site.name] = {}
self._factors[site.name] = {}
for machine_type in getattr(config, site.name).MachineTypes:
self._resources[site.name][machine_type] = {}
self._factors[site.name][machine_type] = {}
for r in getattr(config, site.name).MachineMetaData[machine_type]:
self._resources[site.name][machine_type][r] = getattr(
config, site.name
).MachineMetaData[machine_type][r]
try:
self._factors[site.name][machine_type][r] = config_auditor[
"factors"
][machine_type][r]
except KeyError:
# Note: removed `'None': 1`
self._factors[site.name][machine_type][r] = {}

self._user = config_auditor.user if config_auditor.user else "tardis"
self._group = config_auditor.group if config_auditor.group else "tardis"
auditor_timeout = config_auditor.timeout if config_auditor.timeout else 30
self._local_timezone = get_localzone()
self._client = (
AuditorClientBuilder()
.address(config_auditor.host, config_auditor.port)
.timeout(auditor_timeout)
.build()
)

async def notify(self, state: State, resource_attributes: AttributeDict) -> None:
"""
TODO
:param state: New state of the Drone
:type state: State
:param resource_attributes: Contains all meta-data of the Drone (created and
updated timestamps, dns name, unique id, site_name, machine_type, etc.)
:type resource_attributes: AttributeDict
:return: None
"""
self.logger.debug(
f"Drone: {str(resource_attributes)} has changed state to {state}"
)

if isinstance(state, AvailableState):
record = self.construct_record(resource_attributes)
await self._client.add(record)
elif isinstance(state, DownState):
record = self.construct_record(resource_attributes)
record.with_stop_time(
resource_attributes["updated"]
.replace(tzinfo=self._local_timezone)
.astimezone(pytz.utc)
)
await self._client.update(record)

def construct_record(self, resource_attributes: AttributeDict):
record = Record(
resource_attribtues["drone_uuid"],
resource_attributes["site_name"],
self._user,
self._group,
resource_attribute["updated"]
.replace(tzinfo=self._local_timezone)
.astimezone(pytz.utc),
)

for (resource, amount) in self._resources[resource_attributes["site_name"]][
resource_attributes["machine_type"]
].items():
component = Component(resource, amount)
for score_name, score_val in self._factors[
resource_attributes["site_name"]
][resource_attributes["machine_type"]][resource].items():
component = component.with_score(Score(score_name, score_val))

record = record.with_component(component)

return record

0 comments on commit 8dfee02

Please sign in to comment.