machine_access_control 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/PKG-INFO +1 -1
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/pyproject.toml +1 -1
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/models/machine.py +53 -26
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/slack_handler.py +24 -24
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/prometheus.py +19 -36
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/LICENSE +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/README.rst +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/__init__.py +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/cli_utils.py +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/models/__init__.py +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/models/users.py +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/neongetter.py +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/py.typed +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/utils.py +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/__init__.py +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/api.py +0 -0
- {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/machine.py +0 -0
|
@@ -60,6 +60,11 @@ CONFIG_SCHEMA: Dict[str, Any] = {
|
|
|
60
60
|
"Displays 'Always On' and relay is always "
|
|
61
61
|
"on unless Oopsed or Locked.",
|
|
62
62
|
},
|
|
63
|
+
"alias": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"description": "Optional human-friendly alias for the machine. "
|
|
66
|
+
"Used in Slack messages and logs instead of the machine name.",
|
|
67
|
+
},
|
|
63
68
|
},
|
|
64
69
|
"additionalProperties": False,
|
|
65
70
|
"description": "Unique machine name, alphanumeric _ and - only.",
|
|
@@ -77,6 +82,7 @@ class Machine:
|
|
|
77
82
|
authorizations_or: List[str],
|
|
78
83
|
unauthorized_warn_only: bool = False,
|
|
79
84
|
always_enabled: bool = False,
|
|
85
|
+
alias: Optional[str] = None,
|
|
80
86
|
):
|
|
81
87
|
"""Initialize a new MachineState instance."""
|
|
82
88
|
#: The name of the machine
|
|
@@ -88,6 +94,8 @@ class Machine:
|
|
|
88
94
|
self.unauthorized_warn_only: bool = unauthorized_warn_only
|
|
89
95
|
#: Whether machine is always enabled without RFID authentication
|
|
90
96
|
self.always_enabled: bool = always_enabled
|
|
97
|
+
#: Optional human-friendly alias for the machine
|
|
98
|
+
self.alias: Optional[str] = alias
|
|
91
99
|
#: state of the machine
|
|
92
100
|
self.state: "MachineState" = MachineState(self)
|
|
93
101
|
|
|
@@ -145,6 +153,11 @@ class Machine:
|
|
|
145
153
|
return
|
|
146
154
|
await slack.log_unoops(self, source)
|
|
147
155
|
|
|
156
|
+
@property
|
|
157
|
+
def display_name(self) -> str:
|
|
158
|
+
"""Return the display name for this machine (alias if present, else name)."""
|
|
159
|
+
return self.alias if self.alias else self.name
|
|
160
|
+
|
|
148
161
|
@property
|
|
149
162
|
def as_dict(self) -> Dict[str, Any]:
|
|
150
163
|
"""Return a dict representation of this machine."""
|
|
@@ -153,6 +166,7 @@ class Machine:
|
|
|
153
166
|
"authorizations_or": self.authorizations_or,
|
|
154
167
|
"unauthorized_warn_only": self.unauthorized_warn_only,
|
|
155
168
|
"always_enabled": self.always_enabled,
|
|
169
|
+
"alias": self.alias,
|
|
156
170
|
}
|
|
157
171
|
|
|
158
172
|
|
|
@@ -163,6 +177,7 @@ class MachinesConfig:
|
|
|
163
177
|
"""Initialize MachinesConfig."""
|
|
164
178
|
logger.debug("Initializing MachinesConfig")
|
|
165
179
|
self.machines_by_name: Dict[str, Machine] = {}
|
|
180
|
+
self.machines_by_alias: Dict[str, Machine] = {}
|
|
166
181
|
self.machines: List[Machine] = []
|
|
167
182
|
mdict: Dict[str, Any]
|
|
168
183
|
mname: str
|
|
@@ -170,8 +185,16 @@ class MachinesConfig:
|
|
|
170
185
|
mach: Machine = Machine(name=mname, **mdict)
|
|
171
186
|
self.machines.append(mach)
|
|
172
187
|
self.machines_by_name[mach.name] = mach
|
|
188
|
+
if mach.alias:
|
|
189
|
+
self.machines_by_alias[mach.alias] = mach
|
|
173
190
|
self.load_time: float = time()
|
|
174
191
|
|
|
192
|
+
def get_machine(self, name_or_alias: str) -> Optional[Machine]:
|
|
193
|
+
"""Get a machine by name or alias."""
|
|
194
|
+
return self.machines_by_name.get(name_or_alias) or self.machines_by_alias.get(
|
|
195
|
+
name_or_alias
|
|
196
|
+
)
|
|
197
|
+
|
|
175
198
|
def _load_and_validate_config(self) -> Dict[str, Dict[str, Any]]:
|
|
176
199
|
"""Load and validate the config file."""
|
|
177
200
|
config: Dict[str, Dict[str, Any]] = cast(
|
|
@@ -307,7 +330,8 @@ class MachineState:
|
|
|
307
330
|
For always-enabled machines, restores the always-on state.
|
|
308
331
|
"""
|
|
309
332
|
logging.getLogger("AUTH").warning(
|
|
310
|
-
"Machine %s rebooted; resetting relay and RFID state",
|
|
333
|
+
"Machine %s rebooted; resetting relay and RFID state",
|
|
334
|
+
self.machine.display_name,
|
|
311
335
|
)
|
|
312
336
|
# locking handled in update()
|
|
313
337
|
self.current_user = None
|
|
@@ -327,12 +351,12 @@ class MachineState:
|
|
|
327
351
|
if not slack:
|
|
328
352
|
# Slack integration is not enabled
|
|
329
353
|
return
|
|
330
|
-
await slack.admin_log(f"Machine {self.machine.
|
|
354
|
+
await slack.admin_log(f"Machine {self.machine.display_name} has rebooted.")
|
|
331
355
|
|
|
332
356
|
def lockout(self) -> None:
|
|
333
357
|
"""Lock-out the machine."""
|
|
334
358
|
logging.getLogger("OOPS").warning(
|
|
335
|
-
"Machine %s was locked out for maintenance.", self.machine.
|
|
359
|
+
"Machine %s was locked out for maintenance.", self.machine.display_name
|
|
336
360
|
)
|
|
337
361
|
with self._lock:
|
|
338
362
|
self.is_locked_out = True
|
|
@@ -345,7 +369,8 @@ class MachineState:
|
|
|
345
369
|
def unlock(self) -> None:
|
|
346
370
|
"""Un-lock-out the machine."""
|
|
347
371
|
logging.getLogger("OOPS").warning(
|
|
348
|
-
"Machine %s was removed from maintenance lock-out.",
|
|
372
|
+
"Machine %s was removed from maintenance lock-out.",
|
|
373
|
+
self.machine.display_name,
|
|
349
374
|
)
|
|
350
375
|
with self._lock:
|
|
351
376
|
self.is_locked_out = False
|
|
@@ -364,7 +389,9 @@ class MachineState:
|
|
|
364
389
|
|
|
365
390
|
def oops(self, do_locking: bool = True) -> None:
|
|
366
391
|
"""Oops the machine."""
|
|
367
|
-
logging.getLogger("OOPS").warning(
|
|
392
|
+
logging.getLogger("OOPS").warning(
|
|
393
|
+
"Machine %s was Oopsed.", self.machine.display_name
|
|
394
|
+
)
|
|
368
395
|
locker = self._lock if do_locking else nullcontext()
|
|
369
396
|
with locker:
|
|
370
397
|
self.is_oopsed = True
|
|
@@ -377,7 +404,7 @@ class MachineState:
|
|
|
377
404
|
def unoops(self, do_locking: bool = True) -> None:
|
|
378
405
|
"""Un-oops the machine."""
|
|
379
406
|
logging.getLogger("OOPS").warning(
|
|
380
|
-
"Machine %s was un-Oopsed.", self.machine.
|
|
407
|
+
"Machine %s was un-Oopsed.", self.machine.display_name
|
|
381
408
|
)
|
|
382
409
|
locker = self._lock if do_locking else nullcontext()
|
|
383
410
|
with locker:
|
|
@@ -465,7 +492,7 @@ class MachineState:
|
|
|
465
492
|
ustr = f" Current user is: {user.full_name}."
|
|
466
493
|
uname = user.full_name
|
|
467
494
|
logging.getLogger("OOPS").warning(
|
|
468
|
-
"Machine %s was Oopsed.%s", self.machine.
|
|
495
|
+
"Machine %s was Oopsed.%s", self.machine.display_name, ustr
|
|
469
496
|
)
|
|
470
497
|
# locking handled in update()
|
|
471
498
|
self.oops(do_locking=False)
|
|
@@ -485,12 +512,12 @@ class MachineState:
|
|
|
485
512
|
"""Handle RFID card removed."""
|
|
486
513
|
logging.getLogger("AUTH").info(
|
|
487
514
|
"RFID logout on %s by %s; session duration %d seconds",
|
|
488
|
-
self.machine.
|
|
515
|
+
self.machine.display_name,
|
|
489
516
|
self.current_user.full_name if self.current_user else self.rfid_value,
|
|
490
517
|
time() - cast(float, self.rfid_present_since),
|
|
491
518
|
)
|
|
492
519
|
log_str: str = (
|
|
493
|
-
f"RFID logout on {self.machine.
|
|
520
|
+
f"RFID logout on {self.machine.display_name} by "
|
|
494
521
|
+ (self.current_user.full_name if self.current_user else "unknown")
|
|
495
522
|
+ "; session duration "
|
|
496
523
|
+ naturaldelta(time() - cast(float, self.rfid_present_since))
|
|
@@ -521,13 +548,13 @@ class MachineState:
|
|
|
521
548
|
if not user:
|
|
522
549
|
logging.getLogger("AUTH").warning(
|
|
523
550
|
"RFID login attempt on %s by unknown fob %s",
|
|
524
|
-
self.machine.
|
|
551
|
+
self.machine.display_name,
|
|
525
552
|
rfid_value,
|
|
526
553
|
)
|
|
527
554
|
if self.is_oopsed or self.is_locked_out:
|
|
528
555
|
if slack:
|
|
529
556
|
await slack.admin_log(
|
|
530
|
-
f"RFID login attempt on {self.machine.
|
|
557
|
+
f"RFID login attempt on {self.machine.display_name} "
|
|
531
558
|
"by unknown fob when oopsed or locked out."
|
|
532
559
|
)
|
|
533
560
|
return
|
|
@@ -536,7 +563,7 @@ class MachineState:
|
|
|
536
563
|
self.status_led_brightness = self.STATUS_LED_BRIGHTNESS
|
|
537
564
|
if slack:
|
|
538
565
|
await slack.admin_log(
|
|
539
|
-
f"RFID login attempt on {self.machine.
|
|
566
|
+
f"RFID login attempt on {self.machine.display_name} by unknown fob"
|
|
540
567
|
)
|
|
541
568
|
return
|
|
542
569
|
# ok, we have a known user
|
|
@@ -544,26 +571,26 @@ class MachineState:
|
|
|
544
571
|
if self.is_oopsed:
|
|
545
572
|
logging.getLogger("AUTH").warning(
|
|
546
573
|
"RFID login attempt while oopsed on %s by %s",
|
|
547
|
-
self.machine.
|
|
574
|
+
self.machine.display_name,
|
|
548
575
|
logname,
|
|
549
576
|
)
|
|
550
577
|
# don't change anything
|
|
551
578
|
if slack:
|
|
552
579
|
await slack.admin_log(
|
|
553
|
-
f"RFID login attempt on {self.machine.
|
|
580
|
+
f"RFID login attempt on {self.machine.display_name} by "
|
|
554
581
|
f"{user.full_name} when oopsed."
|
|
555
582
|
)
|
|
556
583
|
return
|
|
557
584
|
if self.is_locked_out:
|
|
558
585
|
logging.getLogger("AUTH").warning(
|
|
559
586
|
"RFID login attempt while locked out on %s by %s",
|
|
560
|
-
self.machine.
|
|
587
|
+
self.machine.display_name,
|
|
561
588
|
logname,
|
|
562
589
|
)
|
|
563
590
|
# don't change anything
|
|
564
591
|
if slack:
|
|
565
592
|
await slack.admin_log(
|
|
566
|
-
f"RFID login attempt on {self.machine.
|
|
593
|
+
f"RFID login attempt on {self.machine.display_name} by "
|
|
567
594
|
f"{user.full_name} when machine locked-out."
|
|
568
595
|
)
|
|
569
596
|
return
|
|
@@ -572,7 +599,7 @@ class MachineState:
|
|
|
572
599
|
"User %s (%s) authorized for %s; session start",
|
|
573
600
|
user.full_name,
|
|
574
601
|
user.account_id,
|
|
575
|
-
self.machine.
|
|
602
|
+
self.machine.display_name,
|
|
576
603
|
)
|
|
577
604
|
self.current_user = user
|
|
578
605
|
self.relay_desired_state = True
|
|
@@ -581,7 +608,7 @@ class MachineState:
|
|
|
581
608
|
self.status_led_brightness = self.STATUS_LED_BRIGHTNESS
|
|
582
609
|
if slack:
|
|
583
610
|
await slack.admin_log(
|
|
584
|
-
f"RFID login on {self.machine.
|
|
611
|
+
f"RFID login on {self.machine.display_name} by authorized user "
|
|
585
612
|
f"{user.full_name}"
|
|
586
613
|
)
|
|
587
614
|
else:
|
|
@@ -589,7 +616,7 @@ class MachineState:
|
|
|
589
616
|
"User %s (%s) UNAUTHORIZED for %s",
|
|
590
617
|
user.full_name,
|
|
591
618
|
user.account_id,
|
|
592
|
-
self.machine.
|
|
619
|
+
self.machine.display_name,
|
|
593
620
|
)
|
|
594
621
|
self.relay_desired_state = False
|
|
595
622
|
self.display_text = "Unauthorized"
|
|
@@ -597,7 +624,7 @@ class MachineState:
|
|
|
597
624
|
self.status_led_brightness = self.STATUS_LED_BRIGHTNESS
|
|
598
625
|
if slack:
|
|
599
626
|
await slack.admin_log(
|
|
600
|
-
f"rejected RFID login on {self.machine.
|
|
627
|
+
f"rejected RFID login on {self.machine.display_name} by "
|
|
601
628
|
f"UNAUTHORIZED user {user.full_name}"
|
|
602
629
|
)
|
|
603
630
|
|
|
@@ -614,7 +641,7 @@ class MachineState:
|
|
|
614
641
|
# RFID removed
|
|
615
642
|
logging.getLogger("AUTH").info(
|
|
616
643
|
"RFID removed on always-enabled machine %s (was %s); session duration %d seconds",
|
|
617
|
-
self.machine.
|
|
644
|
+
self.machine.display_name,
|
|
618
645
|
self.current_user.full_name if self.current_user else self.rfid_value,
|
|
619
646
|
(
|
|
620
647
|
time() - cast(float, self.rfid_present_since)
|
|
@@ -635,14 +662,14 @@ class MachineState:
|
|
|
635
662
|
self.current_user = user
|
|
636
663
|
logging.getLogger("AUTH").info(
|
|
637
664
|
"RFID inserted on always-enabled machine %s by %s (%s)",
|
|
638
|
-
self.machine.
|
|
665
|
+
self.machine.display_name,
|
|
639
666
|
user.full_name,
|
|
640
667
|
rfid_value,
|
|
641
668
|
)
|
|
642
669
|
else:
|
|
643
670
|
logging.getLogger("AUTH").warning(
|
|
644
671
|
"RFID inserted on always-enabled machine %s by unknown fob %s",
|
|
645
|
-
self.machine.
|
|
672
|
+
self.machine.display_name,
|
|
646
673
|
rfid_value,
|
|
647
674
|
)
|
|
648
675
|
# State remains always-on (relay/display/LED not changed)
|
|
@@ -657,7 +684,7 @@ class MachineState:
|
|
|
657
684
|
"User %s (%s) authorized for %s based on %s",
|
|
658
685
|
user.full_name,
|
|
659
686
|
user.account_id,
|
|
660
|
-
self.machine.
|
|
687
|
+
self.machine.display_name,
|
|
661
688
|
auth,
|
|
662
689
|
)
|
|
663
690
|
return True
|
|
@@ -667,12 +694,12 @@ class MachineState:
|
|
|
667
694
|
"unauthorized_warn_only==True",
|
|
668
695
|
user.full_name,
|
|
669
696
|
user.account_id,
|
|
670
|
-
self.machine.
|
|
697
|
+
self.machine.display_name,
|
|
671
698
|
)
|
|
672
699
|
if slack:
|
|
673
700
|
await slack.admin_log(
|
|
674
701
|
f"WARNING - Authorizing user {user.full_name} for "
|
|
675
|
-
f"{self.machine.
|
|
702
|
+
f"{self.machine.display_name} based on unauthorized_warn_only "
|
|
676
703
|
"setting for machine. User is NOT authorized for this "
|
|
677
704
|
"machine."
|
|
678
705
|
)
|
|
@@ -160,11 +160,11 @@ class SlackHandler:
|
|
|
160
160
|
msg.channel_id,
|
|
161
161
|
)
|
|
162
162
|
return None
|
|
163
|
-
if msg.command[0] == "oops" and len(msg.command)
|
|
163
|
+
if msg.command[0] == "oops" and len(msg.command) >= 2:
|
|
164
164
|
return await self.oops(msg, say)
|
|
165
|
-
elif msg.command[0] == "lock" and len(msg.command)
|
|
165
|
+
elif msg.command[0] == "lock" and len(msg.command) >= 2:
|
|
166
166
|
return await self.lock(msg, say)
|
|
167
|
-
elif msg.command[0] == "clear" and len(msg.command)
|
|
167
|
+
elif msg.command[0] == "clear" and len(msg.command) >= 2:
|
|
168
168
|
return await self.clear(msg, say)
|
|
169
169
|
await say(self.HELP_RESPONSE)
|
|
170
170
|
|
|
@@ -175,7 +175,7 @@ class SlackHandler:
|
|
|
175
175
|
mname: str
|
|
176
176
|
mach: Machine
|
|
177
177
|
for mname, mach in sorted(mconf.machines_by_name.items()):
|
|
178
|
-
resp +=
|
|
178
|
+
resp += mach.display_name + ": "
|
|
179
179
|
if mach.state.is_oopsed or mach.state.is_locked_out:
|
|
180
180
|
if mach.state.is_oopsed:
|
|
181
181
|
resp += "Oopsed "
|
|
@@ -199,44 +199,44 @@ class SlackHandler:
|
|
|
199
199
|
|
|
200
200
|
async def oops(self, msg: Message, say: AsyncSay) -> None:
|
|
201
201
|
"""Set oops status on a machine."""
|
|
202
|
-
mname: str = msg.command[1]
|
|
202
|
+
mname: str = " ".join(msg.command[1:])
|
|
203
203
|
mconf: MachinesConfig = self.quart.config["MACHINES"]
|
|
204
|
-
mach: Optional[Machine] = mconf.
|
|
204
|
+
mach: Optional[Machine] = mconf.get_machine(mname)
|
|
205
205
|
if not mach:
|
|
206
206
|
await say(
|
|
207
|
-
f"Invalid machine name '{mname}'. Use status command to "
|
|
207
|
+
f"Invalid machine name or alias '{mname}'. Use status command to "
|
|
208
208
|
f"list all machines."
|
|
209
209
|
)
|
|
210
210
|
return
|
|
211
211
|
if mach.state.is_oopsed:
|
|
212
|
-
await say(f"Machine {
|
|
212
|
+
await say(f"Machine {mach.display_name} is already oopsed.")
|
|
213
213
|
return
|
|
214
214
|
await mach.oops(slack=self)
|
|
215
215
|
|
|
216
216
|
async def lock(self, msg: Message, say: AsyncSay) -> None:
|
|
217
217
|
"""Set lock status on a machine."""
|
|
218
|
-
mname: str = msg.command[1]
|
|
218
|
+
mname: str = " ".join(msg.command[1:])
|
|
219
219
|
mconf: MachinesConfig = self.quart.config["MACHINES"]
|
|
220
|
-
mach: Optional[Machine] = mconf.
|
|
220
|
+
mach: Optional[Machine] = mconf.get_machine(mname)
|
|
221
221
|
if not mach:
|
|
222
222
|
await say(
|
|
223
|
-
f"Invalid machine name '{mname}'. Use status command to "
|
|
223
|
+
f"Invalid machine name or alias '{mname}'. Use status command to "
|
|
224
224
|
f"list all machines."
|
|
225
225
|
)
|
|
226
226
|
return
|
|
227
227
|
if mach.state.is_locked_out:
|
|
228
|
-
await say(f"Machine {
|
|
228
|
+
await say(f"Machine {mach.display_name} is already locked-out.")
|
|
229
229
|
return
|
|
230
230
|
await mach.lockout(slack=self)
|
|
231
231
|
|
|
232
232
|
async def clear(self, msg: Message, say: AsyncSay) -> None:
|
|
233
233
|
"""Clear oops and lock status on a machine."""
|
|
234
|
-
mname: str = msg.command[1]
|
|
234
|
+
mname: str = " ".join(msg.command[1:])
|
|
235
235
|
mconf: MachinesConfig = self.quart.config["MACHINES"]
|
|
236
|
-
mach: Optional[Machine] = mconf.
|
|
236
|
+
mach: Optional[Machine] = mconf.get_machine(mname)
|
|
237
237
|
if not mach:
|
|
238
238
|
await say(
|
|
239
|
-
f"Invalid machine name '{mname}'. Use status command to "
|
|
239
|
+
f"Invalid machine name or alias '{mname}'. Use status command to "
|
|
240
240
|
f"list all machines."
|
|
241
241
|
)
|
|
242
242
|
return
|
|
@@ -248,7 +248,7 @@ class SlackHandler:
|
|
|
248
248
|
await mach.unlock(slack=self)
|
|
249
249
|
acted = True
|
|
250
250
|
if not acted:
|
|
251
|
-
await say(f"Machine {
|
|
251
|
+
await say(f"Machine {mach.display_name} is not oopsed or locked-out.")
|
|
252
252
|
|
|
253
253
|
async def log_unoops(self, machine: Machine, source: str) -> None:
|
|
254
254
|
"""
|
|
@@ -262,13 +262,13 @@ class SlackHandler:
|
|
|
262
262
|
create_task(
|
|
263
263
|
self.app.client.chat_postMessage(
|
|
264
264
|
channel=self.control_channel_id,
|
|
265
|
-
text=f"Machine {machine.
|
|
265
|
+
text=f"Machine {machine.display_name} un-oopsed via {source}.",
|
|
266
266
|
)
|
|
267
267
|
)
|
|
268
268
|
create_task(
|
|
269
269
|
self.app.client.chat_postMessage(
|
|
270
270
|
channel=self.oops_channel_id,
|
|
271
|
-
text=f"Machine {machine.
|
|
271
|
+
text=f"Machine {machine.display_name} oops has been cleared.",
|
|
272
272
|
)
|
|
273
273
|
)
|
|
274
274
|
|
|
@@ -286,13 +286,13 @@ class SlackHandler:
|
|
|
286
286
|
create_task(
|
|
287
287
|
self.app.client.chat_postMessage(
|
|
288
288
|
channel=self.control_channel_id,
|
|
289
|
-
text=f"Machine {machine.
|
|
289
|
+
text=f"Machine {machine.display_name} oopsed via {source} by {user_name}.",
|
|
290
290
|
)
|
|
291
291
|
)
|
|
292
292
|
create_task(
|
|
293
293
|
self.app.client.chat_postMessage(
|
|
294
294
|
channel=self.oops_channel_id,
|
|
295
|
-
text=f"Machine {machine.
|
|
295
|
+
text=f"Machine {machine.display_name} has been Oops'ed!",
|
|
296
296
|
)
|
|
297
297
|
)
|
|
298
298
|
|
|
@@ -308,13 +308,13 @@ class SlackHandler:
|
|
|
308
308
|
create_task(
|
|
309
309
|
self.app.client.chat_postMessage(
|
|
310
310
|
channel=self.control_channel_id,
|
|
311
|
-
text=f"Machine {machine.
|
|
311
|
+
text=f"Machine {machine.display_name} locked-out cleared via {source}.",
|
|
312
312
|
)
|
|
313
313
|
)
|
|
314
314
|
create_task(
|
|
315
315
|
self.app.client.chat_postMessage(
|
|
316
316
|
channel=self.oops_channel_id,
|
|
317
|
-
text=f"Machine {machine.
|
|
317
|
+
text=f"Machine {machine.display_name} is no longer locked-out for "
|
|
318
318
|
f"maintenance.",
|
|
319
319
|
)
|
|
320
320
|
)
|
|
@@ -331,13 +331,13 @@ class SlackHandler:
|
|
|
331
331
|
create_task(
|
|
332
332
|
self.app.client.chat_postMessage(
|
|
333
333
|
channel=self.control_channel_id,
|
|
334
|
-
text=f"Machine {machine.
|
|
334
|
+
text=f"Machine {machine.display_name} locked-out via {source}.",
|
|
335
335
|
)
|
|
336
336
|
)
|
|
337
337
|
create_task(
|
|
338
338
|
self.app.client.chat_postMessage(
|
|
339
339
|
channel=self.oops_channel_id,
|
|
340
|
-
text=f"Machine {machine.
|
|
340
|
+
text=f"Machine {machine.display_name} is locked-out for maintenance.",
|
|
341
341
|
)
|
|
342
342
|
)
|
|
343
343
|
|
{machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/prometheus.py
RENAMED
|
@@ -134,52 +134,35 @@ class PromCustomCollector:
|
|
|
134
134
|
)
|
|
135
135
|
m: Machine
|
|
136
136
|
for m in mconf.machines:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
{"machine_name": m.name}, 1 if m.state.rfid_value else 0
|
|
153
|
-
)
|
|
154
|
-
m_rfid_present_since.add_metric(
|
|
155
|
-
{"machine_name": m.name}, m.state.rfid_present_since or 0
|
|
156
|
-
)
|
|
157
|
-
current_amps.add_metric({"machine_name": m.name}, m.state.current_amps)
|
|
158
|
-
m_user.add_metric(
|
|
159
|
-
{"machine_name": m.name}, 1 if m.state.current_user else 0
|
|
160
|
-
)
|
|
161
|
-
uptime.add_metric({"machine_name": m.name}, m.state.uptime)
|
|
162
|
-
wifi_db.add_metric({"machine_name": m.name}, m.state.wifi_signal_db or 0)
|
|
163
|
-
wifi_percent.add_metric(
|
|
164
|
-
{"machine_name": m.name}, m.state.wifi_signal_percent or 0
|
|
165
|
-
)
|
|
166
|
-
temp_c.add_metric(
|
|
167
|
-
{"machine_name": m.name}, m.state.internal_temperature_c or 0
|
|
168
|
-
)
|
|
137
|
+
labels = {"machine_name": m.name, "display_name": m.display_name}
|
|
138
|
+
relay_state.add_metric(labels, 1 if m.state.relay_desired_state else 0)
|
|
139
|
+
oops_state.add_metric(labels, 1 if m.state.is_oopsed else 0)
|
|
140
|
+
lockout_state.add_metric(labels, 1 if m.state.is_locked_out else 0)
|
|
141
|
+
unauth_state.add_metric(labels, 1 if m.unauthorized_warn_only else 0)
|
|
142
|
+
m_checkin.add_metric(labels, m.state.last_checkin or 0)
|
|
143
|
+
m_update.add_metric(labels, m.state.last_update or 0)
|
|
144
|
+
m_rfid_present.add_metric(labels, 1 if m.state.rfid_value else 0)
|
|
145
|
+
m_rfid_present_since.add_metric(labels, m.state.rfid_present_since or 0)
|
|
146
|
+
current_amps.add_metric(labels, m.state.current_amps)
|
|
147
|
+
m_user.add_metric(labels, 1 if m.state.current_user else 0)
|
|
148
|
+
uptime.add_metric(labels, m.state.uptime)
|
|
149
|
+
wifi_db.add_metric(labels, m.state.wifi_signal_db or 0)
|
|
150
|
+
wifi_percent.add_metric(labels, m.state.wifi_signal_percent or 0)
|
|
151
|
+
temp_c.add_metric(labels, m.state.internal_temperature_c or 0)
|
|
169
152
|
led.add_metric(
|
|
170
|
-
{
|
|
153
|
+
{**labels, "led_attribute": "red"},
|
|
171
154
|
m.state.status_led_rgb[0],
|
|
172
155
|
)
|
|
173
156
|
led.add_metric(
|
|
174
|
-
{
|
|
157
|
+
{**labels, "led_attribute": "green"},
|
|
175
158
|
m.state.status_led_rgb[1],
|
|
176
159
|
)
|
|
177
160
|
led.add_metric(
|
|
178
|
-
{
|
|
161
|
+
{**labels, "led_attribute": "blue"},
|
|
179
162
|
m.state.status_led_rgb[2],
|
|
180
163
|
)
|
|
181
164
|
led.add_metric(
|
|
182
|
-
{
|
|
165
|
+
{**labels, "led_attribute": "brightness"},
|
|
183
166
|
m.state.status_led_brightness,
|
|
184
167
|
)
|
|
185
168
|
yield mconf_load
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|