mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-12-22 03:33:48 +01:00
Improve examples
This commit is contained in:
parent
f367207d01
commit
20a47d9444
0
bffhd/actors/shelly.rs
Normal file
0
bffhd/actors/shelly.rs
Normal file
179
examples/actor.py
Executable file
179
examples/actor.py
Executable file
@ -0,0 +1,179 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
def on_free(args, actor_name):
|
||||
"""
|
||||
Function called when the state of the connected machine changes to Free
|
||||
again
|
||||
"""
|
||||
if args.verbose > 2:
|
||||
print("on_free called!")
|
||||
|
||||
if actor_name == "DoorControl1":
|
||||
# Do whatever you want to do in case `DoorControl1` is returned back to free.
|
||||
# Keep in mind that process actors should return quickly to not miss
|
||||
# updates, so if you need to do things that take a while fork a new
|
||||
# process e.g. with the `subprocess` Module
|
||||
print("I'm locking door 1!")
|
||||
pass
|
||||
elif actor_name == "DoorControl2":
|
||||
print("I'm locking door 2!")
|
||||
pass # Close a different door
|
||||
else:
|
||||
if not args.quiet:
|
||||
print("process called with unknown id %s for state `Free`" % actor_name)
|
||||
# It's a good idea to exit with an error code in case something
|
||||
# unexpected happens.
|
||||
# The process module logs everything printed to stdout by actors into
|
||||
# the server log, but marks them as `Error` in case the actor process
|
||||
# exits with a code != 0, making debugging somewhat easier.
|
||||
exit(-1)
|
||||
|
||||
def on_use(args, actor_name, user_id):
|
||||
"""
|
||||
Function called when an user takes control of the connected machine
|
||||
|
||||
user_id contains the UID of the user now using the machine
|
||||
"""
|
||||
if args.verbose > 2:
|
||||
print("on_use called!")
|
||||
if actor_name == "DoorControl1":
|
||||
print("I'm opening door 1 for 10 seconds!")
|
||||
pass # Open door one
|
||||
elif actor_name == "DoorControl2":
|
||||
print("I'm opening door 2 for 10 seconds!")
|
||||
pass # Open a different door
|
||||
else:
|
||||
if not args.quiet:
|
||||
print("process called with unknown id %s for state `InUse`" % actor_name)
|
||||
# It's a good idea to exit with an error code in case something
|
||||
# unexpected happens.
|
||||
# The process module logs everything printed to stdout by actors into
|
||||
# the server log, but marks them as `Error` in case the actor process
|
||||
# exits with a code != 0, making debugging somewhat easier.
|
||||
exit(-1)
|
||||
|
||||
def on_tocheck(args, actor_name, user_id):
|
||||
"""
|
||||
Function called when an user returns control and the connected machine is
|
||||
configured to go to state `ToCheck` instead of `Free` in that case.
|
||||
|
||||
user_id contains the UID of the manager expected to check the machine.
|
||||
The user that used the machine beforehand has to be taken from the last
|
||||
user field using the API (via e.g. the mobile app)
|
||||
"""
|
||||
if args.verbose > 2:
|
||||
print("on_tocheck called!")
|
||||
if not args.quiet:
|
||||
print("process called with unexpected combo id %s and state 'ToCheck'" % actor_name)
|
||||
exit(-1)
|
||||
|
||||
def on_blocked(args, actor_name, user_id):
|
||||
"""
|
||||
Function called when an manager marks the connected machine as `Blocked`
|
||||
|
||||
user_id contains the UID of the manager that blocked the machine
|
||||
"""
|
||||
if args.verbose > 2:
|
||||
print("on_blocked called!")
|
||||
if not args.quiet:
|
||||
print("process called with unexpected combo id %s and state 'Blocked'" % actor_name)
|
||||
exit(-1)
|
||||
|
||||
def on_disabled(args, actor_name):
|
||||
"""
|
||||
Function called when the connected machine is marked `Disabled`
|
||||
"""
|
||||
if not args.quiet:
|
||||
print("process called with unexpected combo id %s and state 'Disabled'" % actor_name)
|
||||
exit(-1)
|
||||
|
||||
def on_reserve(args, actor_name, user_id):
|
||||
"""
|
||||
Function called when the connected machine has been reserved by somebody.
|
||||
|
||||
user_id contains the UID of the reserving user.
|
||||
"""
|
||||
if not args.quiet:
|
||||
print("process called with unexpected combo id %s and state 'Reserved'" % actor_name)
|
||||
exit(-1)
|
||||
|
||||
|
||||
def main(args):
|
||||
"""
|
||||
Python example actor
|
||||
|
||||
This is an example how to use the `process` actor type to run a Python script.
|
||||
"""
|
||||
|
||||
if args.verbose is not None:
|
||||
if args.verbose == 1:
|
||||
print("verbose output enabled")
|
||||
elif args.verbose == 2:
|
||||
print("loud output enabled!")
|
||||
elif args.verbose == 3:
|
||||
print("LOUD output enabled!!!")
|
||||
elif args.verbose > 4:
|
||||
print("Okay stop you're being ridiculous.")
|
||||
sys.exit(-2)
|
||||
else:
|
||||
args.verbose = 0
|
||||
|
||||
# You could also check the actor name here and call different functions
|
||||
# depending on that variable instead of passing it to the state change
|
||||
# methods.
|
||||
|
||||
new_state = args.state
|
||||
if new_state == "free":
|
||||
on_free(args, args.name)
|
||||
elif new_state == "inuse":
|
||||
on_use(args, args.name, args.userid)
|
||||
elif new_state == "tocheck":
|
||||
on_tocheck(args, args.name, args.userid)
|
||||
elif new_state == "blocked":
|
||||
on_blocked(args, args.name, args.userid)
|
||||
elif new_state == "disabled":
|
||||
on_disabled(args, args.name)
|
||||
elif new_state == "reserved":
|
||||
on_reserve(args, args.name, args.userid)
|
||||
else:
|
||||
print("Process actor called with unknown state %s" % new_state)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
# Parameters are passed to the Process actor as follows:
|
||||
# 1. the contents of params.args, split by whitespace as separate args
|
||||
# 2. the configured id of the actor (e.g. "DoorControl1")
|
||||
# 3. the new state as one of [free|inuse|tocheck|blocked|disabled|reserved]
|
||||
|
||||
parser.add_argument("-q", "--quiet", help="be less verbose", action="store_true")
|
||||
parser.add_argument("-v", "--verbose", help="be more verbose", action="count")
|
||||
|
||||
parser.add_argument("name",
|
||||
help="name of this actor as configured in bffh.dhall"
|
||||
)
|
||||
|
||||
# We parse the new state using subparsers so that we only require a userid
|
||||
# in case it's a state that sets one.
|
||||
subparsers = parser.add_subparsers(required=True, dest="state")
|
||||
|
||||
parser_free = subparsers.add_parser("free")
|
||||
|
||||
parser_inuse = subparsers.add_parser("inuse")
|
||||
parser_inuse.add_argument("userid", help="The user that is now using the machine")
|
||||
|
||||
parser_tocheck = subparsers.add_parser("tocheck")
|
||||
parser_tocheck.add_argument("userid", help="The user that should go check the machine")
|
||||
|
||||
parser_blocked = subparsers.add_parser("blocked")
|
||||
parser_blocked.add_argument("userid", help="The user that marked the machine as blocked")
|
||||
|
||||
parser_disabled = subparsers.add_parser("disabled")
|
||||
|
||||
parser_reserved = subparsers.add_parser("reserved")
|
||||
parser_reserved.add_argument("userid", help="The user that reserved the machine")
|
||||
|
||||
args = parser.parse_args()
|
||||
main(args)
|
@ -1,11 +0,0 @@
|
||||
{ Shelly_1234 = { module = "Shelly", params = {=} }
|
||||
, Bash =
|
||||
{ module = "Process"
|
||||
, params = { cmd = "./examples/actor.sh", args = "your ad could be here" }
|
||||
}
|
||||
, Bash2 =
|
||||
{ module = "Process"
|
||||
, params = { cmd = "./examples/actor.sh", args = "this is a different one" }
|
||||
}
|
||||
, FailBash = { module = "Process", params.cmd = "./examples/fail-actor.sh" }
|
||||
}
|
@ -38,6 +38,11 @@
|
||||
-- access into them.
|
||||
db_path = "/tmp/bffh",
|
||||
|
||||
-- Audit log path. Bffh will log state changes into this file, one per line.
|
||||
-- Audit log entries are for now JSON:
|
||||
-- {"timestamp":1641497361,"machine":"Testmachine","state":{"state":{"InUse":{"uid":"Testuser","subuid":null,"realm":null}}}}
|
||||
auditlog_path = "/tmp/bffh.audit",
|
||||
|
||||
-- In dhall you can also easily import definitions from other files, e.g. you could write
|
||||
-- roles = ./roles.dhall
|
||||
roles = {
|
||||
@ -175,6 +180,30 @@
|
||||
args = "your ad could be here"
|
||||
}
|
||||
},
|
||||
|
||||
DoorControl1 = {
|
||||
-- This actor calls the actor.py script in examples/
|
||||
-- It gets passed it's own name, so you can have several actors
|
||||
-- from the same script.
|
||||
-- If you need to pass more arguments to the command you can use the `args` key in
|
||||
-- `params` as is done with the actor `Bash`
|
||||
module = "Process",
|
||||
-- the `args` are passed in front of all other parameters so they are best suited to
|
||||
-- optional parameters like e.g. the verboseness
|
||||
params = { cmd = "./examples/actor.py", args = "-vvv" }
|
||||
},
|
||||
DoorControl2 = {
|
||||
module = "Process",
|
||||
params = { cmd = "./examples/actor.py" }
|
||||
},
|
||||
DoorControl3 = {
|
||||
-- This is an example for how it looks like if an actor is misconfigured.
|
||||
-- the actor.py doesn't know anything about DoorControl3 and, if this actor is enabled,
|
||||
-- will return with an error showing up in the server logs.
|
||||
module = "Process",
|
||||
params = { cmd = "./examples/actor.py" }
|
||||
},
|
||||
|
||||
Bash2 = { module = "Process", params = { cmd = "./examples/actor.sh" , args = "this is a different one" }},
|
||||
FailBash = { module = "Process", params = { cmd = "./examples/fail-actor.sh" }}
|
||||
},
|
||||
@ -195,11 +224,11 @@
|
||||
initiators = {=},
|
||||
-- The "Dummy" initiator will try to use and return a machine as the given user every few seconds. It's good to
|
||||
-- test your system but will spam your log so is disabled by default.
|
||||
--{ Initiator = { module = "Dummy", params = { uid = "Testuser" } } }
|
||||
--initiators = { Initiator = { module = "Dummy", params = { uid = "Testuser" } } },
|
||||
|
||||
-- Linking up machines to initiators. Similar to actors a machine can have several initiators assigned but an
|
||||
-- initiator can only be assigned to one machine.
|
||||
-- The below is once again how you have to define *no* initiators.
|
||||
init_connections = [] : List { machine : Text, initiator : Text }
|
||||
-- init_connections = [{ machine = "Testmachine", initiator = "Initiator" }]
|
||||
}
|
||||
--init_connections = [{ machine = "Testmachine", initiator = "Initiator" }]
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
{=}
|
@ -1,28 +0,0 @@
|
||||
{ Testmachine =
|
||||
{ description = Some "A test machine"
|
||||
, name = "Textmachine"
|
||||
|
||||
, manage = "lab.test.admin"
|
||||
, read = "lab.test.read"
|
||||
, write = "lab.test.write"
|
||||
, disclose = "lab.test.read"
|
||||
}
|
||||
, Another =
|
||||
{ description = Some "Another test machine"
|
||||
, name = "Another"
|
||||
|
||||
, disclose = "lab.test.read"
|
||||
, manage = "lab.test.admin"
|
||||
, read = "lab.test.read"
|
||||
, write = "lab.test.write"
|
||||
},
|
||||
Yetmore =
|
||||
{ description = Some "Yet more test machines"
|
||||
, name = "Yetmore"
|
||||
|
||||
, disclose = "lab.test.read"
|
||||
, manage = "lab.test.admin"
|
||||
, read = "lab.test.read"
|
||||
, write = "lab.test.write"
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
Testuser = "secret"
|
@ -1,14 +0,0 @@
|
||||
{ testrole =
|
||||
{ permissions = [ "lab.test.*" ] }
|
||||
, somerole =
|
||||
{ parents = ["testparent"]
|
||||
, permissions = [ "lab.some.admin" ]
|
||||
}
|
||||
, testparent =
|
||||
{ permissions =
|
||||
[ "lab.some.write"
|
||||
, "lab.some.read"
|
||||
, "lab.some.disclose"
|
||||
]
|
||||
}
|
||||
}
|
19
examples/self-signed-cert.pem
Normal file
19
examples/self-signed-cert.pem
Normal file
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDFzCCAf+gAwIBAgIUDr+1F3zzyza+soLtiurKEXW9pGIwDQYJKoZIhvcNAQEL
|
||||
BQAwGzEZMBcGA1UEAwwQYmZmaC1kZXZlbG9wbWVudDAeFw0yMTEyMDkxODQ2Mjla
|
||||
Fw0zMTEyMDkxODQ2MjlaMBsxGTAXBgNVBAMMEGJmZmgtZGV2ZWxvcG1lbnQwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGwNy7yGaURR08dWfoDmnJeyx1
|
||||
0FVRmozoGCIb3Oj6c2t+84QUxqTdknE7Cdcz5Wi1o0x2CWPZG4z1vgTaCcJVhcME
|
||||
hxn+7eK1NtDQEjs8Ojs7uaraVvooIe8R7jat0qs7Dmf8RO9P0I4MMZlvijhI7aLw
|
||||
0C6vNsr1ebeppIiwO5aUuCGuKqxJGghHeqZv18ZcPayunyNrxMC6uyX7y6nUVkfq
|
||||
x0m9gDsN112Iv9Dd/ZE5Gxivm8jZvVUGZgJD2szK7zbeCDeo5aU3cRWfYaoN0QDx
|
||||
AKmo4bjciJzfMDDgvcIBq9lGS3FxEv394Mc5YX/ZdP+KRTiHcYCXfBzr3B6HAgMB
|
||||
AAGjUzBRMB0GA1UdDgQWBBTtUvvWXlo5tU8cEoxbs5UJdodOVDAfBgNVHSMEGDAW
|
||||
gBTtUvvWXlo5tU8cEoxbs5UJdodOVDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
|
||||
DQEBCwUAA4IBAQAB3IxRnWi/LrxCvlHNaWEi3ZvlbN+KpegWZeKtjHwQoizhR/Fi
|
||||
SMC7z4y6trJE7LXUOSb9Pu8QQSvpVQZd3W4XCPZMl10Lt7iV8vc3pVviCseDnT9r
|
||||
X1gXdbeuyYm9lE8KtlhX03jD/CiEx7Qe/q8Rc20AQIKAAJzvl7sXU2tmJ5kpzMEO
|
||||
v5czlLaX2ajlD/QMgNBUuDyw6wPo3wx9Khph484RygN2LHeT6kfu/PBiF0dGDTUu
|
||||
mgxg4K0GfwTcHgtz5Bag/HyuuJEKx8Wv7jth59PyKPT+lMVBznxIm3gLS5U+Nnr1
|
||||
uAws8dgLXRlPo5HJORuJCcZWVBClruZUpyDT
|
||||
-----END CERTIFICATE-----
|
28
examples/self-signed-key.pem
Normal file
28
examples/self-signed-key.pem
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDGwNy7yGaURR08
|
||||
dWfoDmnJeyx10FVRmozoGCIb3Oj6c2t+84QUxqTdknE7Cdcz5Wi1o0x2CWPZG4z1
|
||||
vgTaCcJVhcMEhxn+7eK1NtDQEjs8Ojs7uaraVvooIe8R7jat0qs7Dmf8RO9P0I4M
|
||||
MZlvijhI7aLw0C6vNsr1ebeppIiwO5aUuCGuKqxJGghHeqZv18ZcPayunyNrxMC6
|
||||
uyX7y6nUVkfqx0m9gDsN112Iv9Dd/ZE5Gxivm8jZvVUGZgJD2szK7zbeCDeo5aU3
|
||||
cRWfYaoN0QDxAKmo4bjciJzfMDDgvcIBq9lGS3FxEv394Mc5YX/ZdP+KRTiHcYCX
|
||||
fBzr3B6HAgMBAAECggEAS5DGG6ssvRCt9e+ZatQYCl+HXt+voJAHJLMQPNG3zokV
|
||||
hLXnMNL5mbh0zoKGTJfbQLvudS5KxR/BbykoxRFSzptFszH+gztEp6tIpuNXnCVz
|
||||
odiMiejpwVptf763EU14hsKKbJJ0/j6H00EEWjEOB0Q6YB52sW0+qyf02U3SHlZN
|
||||
k2PZYkpHi3YCONtOGj7jOdW7M3RfvcBNg9EW7fZc1KkiRAlscUAYLMkKcOLevil0
|
||||
lUuF/JWj4iH22Oq6+JeSiecf6izF6lyIGvMXPry+woa8Iq0BBdmbZsK7r/Pa+wlz
|
||||
+E6xHGn2rcyrnYB2pPc+RfHhYlodaOo69DxAYlRYaQKBgQDxnKySmlcfHe8lMqR4
|
||||
2LvqMyGjNRo2+q9VZYej2mvr6+TGyd7Op/fRJ1t5f9DgtINomNQYSOtYAsPiEnl+
|
||||
43z2N/Rdh6XSmOj4gLkDeiYNSpy86L/F39uCWZpkkqiy2zxYLWOs15MA0GWOtQGh
|
||||
dz4cM0b/jyZOdHZR//L5WiMLawKBgQDSltEfQKqCEKJTqp4SU9BCHQmyheIjepY2
|
||||
eKakgcsjpFjRBK2VrUalDLOQV74rtd7wp8F8kqqPJpRshb+oVuDCg6JB17UxYd34
|
||||
iB+5cMdLRpg8f0HOqcYz4KOql2QhJQhFc3jzY7n1piPEhFO/MqFwmlUB4RdgJ3ix
|
||||
HqX+F/T8VQKBgGos76l9KcwC25T9LEnu9KV20tFmBJ8kiuh8NZ9L3SFQCLlS/RbT
|
||||
uZOwOAKsqJ4WtajBgHMrmECU9n/inoGkdsW80SZI9hYWHEsYRjXA9/ffUgGyRpQu
|
||||
S8h8l9yalogC0AHv8F2EXpV8/yQ3ZwAN5r19yzWDMtJHW7etQplRgxUBAoGAGeOy
|
||||
t+3iSHU1D6YlIsmtC8O4Int1LrluaCnzCrxuNeaJiMDTelhAHCBwnuk6lvMYAmwN
|
||||
THxXfZvXmXPj+RUdMqyuMPwM6ZJHkLtjcw/bYHTAWIeolnimxk/yrxFHnQ+Jcchd
|
||||
cUasYPfY49sE1Lerw0Ul+EIs9oRDwTqsW42kb7UCgYEA2y+oc7Fz2eq38hSbTfy7
|
||||
OcATtny+xQ1+4IELtQIP7VctkMInJs57J+vS//IT41P0L2K1YjvL8RacnvG7yMvP
|
||||
GnwHBcKgvL6zuoy11I3zPPYtbKGwcJoVGomPX7W0csfl4gdST3uugd9iCDEB8NsS
|
||||
QmOYM/dk8x8aWpndBjRF5ig=
|
||||
-----END PRIVATE KEY-----
|
@ -1,15 +0,0 @@
|
||||
let Map = https://prelude.dhall-lang.org/v20.2.0/Map/Type
|
||||
sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
|
||||
|
||||
let Machine =
|
||||
{ Type =
|
||||
{ description : Optional Text
|
||||
, manage : Text
|
||||
, write : Text
|
||||
, read : Text
|
||||
, disclose : Text
|
||||
}
|
||||
, default = { description = None }
|
||||
}
|
||||
|
||||
in Machine
|
@ -11,17 +11,3 @@ passwd = "secret"
|
||||
# It will get stored in the `kv` field in UserData.
|
||||
# This is not used for anything at the moment
|
||||
noot = "noot!"
|
||||
|
||||
[Differentuser]
|
||||
# Define them in roles.toml as well
|
||||
roles = ["somerole/internal", "testrole/internal"]
|
||||
|
||||
# If two or more users want to use the same machine at once the higher prio
|
||||
# wins
|
||||
priority = 0
|
||||
|
||||
passwd = "secret"
|
||||
|
||||
# You can add whatever random data you want.
|
||||
# It will get stored in the `kv` field in UserData.
|
||||
noot = "noot!"
|
||||
|
Loading…
Reference in New Issue
Block a user