internal/policy/mda.go (view raw)
1package policy
2
3import (
4 "errors"
5 "net/netip"
6
7 "go.starlark.net/starlark"
8)
9
10// MDA implements starlark.Value and starlark.HasAttrs
11// so it can be exposed as the `mda` global object in the script.
12type MDA struct {
13 parsedListeners []ListenerConfig
14}
15
16func (m *MDA) String() string { return "<module mda>" }
17func (m *MDA) Type() string { return "module" }
18func (m *MDA) Freeze() {}
19func (m *MDA) Truth() starlark.Bool { return true }
20func (m *MDA) Hash() (uint32, error) {
21 return 0, errors.New("unhashable")
22}
23
24func (m *MDA) Attr(name string) (starlark.Value, error) {
25 switch name {
26 case "listen":
27 return starlark.NewBuiltin("listen", m.mdaListen), nil
28 }
29 return nil, nil
30}
31func (m *MDA) AttrNames() []string {
32 return []string{"listen"}
33}
34
35// mdaListen handles mda.listen(address="...", role="...")
36func (m *MDA) mdaListen(_ *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
37 var address, role, tlsCertFile, tlsKeyFile string
38
39 // starlark.UnpackArgs maps Starlark arguments to Go variables safely
40 err := starlark.UnpackArgs(
41 b.Name(),
42 args,
43 kwargs,
44 "address", &address,
45 "role", &role,
46 "tls_cert_file", &tlsCertFile,
47 "tls_key_file", &tlsKeyFile)
48 if err != nil {
49 return nil, err
50 }
51
52 addrPort, err := netip.ParseAddrPort(address)
53 if err != nil {
54 return nil, err
55 }
56
57 // Save to our Go state
58 m.parsedListeners = append(m.parsedListeners, ListenerConfig{
59 Address: addrPort,
60 Role: role,
61 TLSCertFile: tlsCertFile,
62 TLSKeyFile: tlsKeyFile,
63 })
64
65 return starlark.None, nil
66}