-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into deployment-docs
- Loading branch information
Showing
37 changed files
with
1,594 additions
and
43 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Application tree information.""" | ||
|
||
from dataclasses import dataclass | ||
|
||
from django.utils.safestring import mark_safe | ||
|
||
|
||
@dataclass | ||
class AppTree: | ||
"""Application tree information.""" | ||
|
||
name: str | ||
"""The name of the application.""" | ||
|
||
children: list["AppTree"] | ||
"""The children of the application.""" | ||
|
||
host: str | ||
"""The hostname of the application.""" | ||
|
||
detector: str = "" | ||
"""The detector of the application.""" | ||
|
||
def to_list(self, indent: str = "") -> list[dict[str, str]]: | ||
"""Convert the app tree to a list of dicts with name indentation. | ||
Args: | ||
indent: The string to use to indent the app name in the table. | ||
Returns: | ||
The list of dicts with the app tree information, indenting the name based | ||
on the depth within the tree. | ||
""" | ||
table_data = [ | ||
{ | ||
"name": mark_safe(indent + self.name), | ||
"host": self.host, | ||
"detector": self.detector, | ||
} | ||
] | ||
for child in self.children: | ||
table_data.extend(child.to_list(indent + "⋅" + " " * 8)) | ||
|
||
return table_data |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
"""Module to create a Django form from a list of Arguments.""" | ||
|
||
from django.forms import BooleanField, CharField, Field, FloatField, Form, IntegerField | ||
from druncschema.controller_pb2 import Argument | ||
|
||
from . import controller_interface as ci | ||
|
||
|
||
def get_form_for_event(event: str) -> type[Form]: | ||
"""Creates a form from a list of Arguments. | ||
We loop over the arguments and create a form field for each one. The field | ||
type is determined by the argument type. The initial value is set to the | ||
default value of the argument, which needs decoding as it is received in binary | ||
form. If the argument is mandatory, the field is required. Finally, the form class | ||
is created dynamically and returned. | ||
Args: | ||
event: Event to get the form for. | ||
Returns: | ||
A form class including the required arguments. | ||
""" | ||
data = ci.get_arguments(event) | ||
fields: dict[str, Field] = {} | ||
for item in data: | ||
name = item.name | ||
mandatory = item.presence == Argument.Presence.MANDATORY | ||
initial = item.default_value.value.decode() | ||
match item.type: | ||
case Argument.Type.INT: | ||
initial = int(initial) if initial else initial | ||
fields[name] = IntegerField(required=mandatory, initial=initial) | ||
case Argument.Type.FLOAT: | ||
initial = float(initial) if initial else initial | ||
fields[name] = FloatField(required=mandatory, initial=initial) | ||
case Argument.Type.STRING: | ||
# Remove the new line and end of string characters causing trouble | ||
# when submitting the form | ||
initial = initial.strip().replace(chr(4), "") | ||
fields[name] = CharField(required=mandatory, initial=initial) | ||
case Argument.Type.BOOL: | ||
# We assume this is provided as an integer, 1 or 0 | ||
initial = bool(int(initial)) if initial else initial | ||
fields[name] = BooleanField(required=mandatory, initial=initial) | ||
|
||
return type("DynamicForm", (Form,), fields) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
"""Module that implements `drunc` finite state machine.""" | ||
|
||
STATES: dict[str, list[str]] = { | ||
"initial": ["conf"], | ||
"configured": ["scrap", "start"], | ||
"ready": ["enable_triggers", "drain_dataflow"], | ||
"running": ["disable_triggers"], | ||
"dataflow_drained": ["stop_trigger_sources"], | ||
"trigger_sources_stopped": ["stop"], | ||
} | ||
|
||
EVENTS: dict[str, str] = { | ||
"conf": "configured", | ||
"scrap": "initial", | ||
"start": "ready", | ||
"enable_triggers": "running", | ||
"disable_triggers": "ready", | ||
"drain_dataflow": "dataflow_drained", | ||
"stop_trigger_sources": "trigger_sources_stopped", | ||
"stop": "configured", | ||
} | ||
|
||
|
||
def get_fsm_architecture() -> dict[str, dict[str, str]]: | ||
"""Return the FSM states and events as a dictionary. | ||
The states will be the keys and the valid events for each state a list of | ||
values with their corresponding target state. All in all, this provides the whole | ||
architecture of the FSM. | ||
Returns: | ||
The states and events as a dictionary. | ||
""" | ||
return { | ||
state: {event: EVENTS[event] for event in events} | ||
for state, events in STATES.items() | ||
} |
Oops, something went wrong.