Skip to content

Commit

Permalink
feat: configure keria with environment variables (WebOfTrust#333)
Browse files Browse the repository at this point in the history
* configure via env variables

* feat: configure keria env with environment variables
  • Loading branch information
lenkan committed Dec 12, 2024
1 parent 2a649c8 commit ffca5fb
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 64 deletions.
67 changes: 40 additions & 27 deletions src/keria/app/agenting.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@


def setup(name, bran, adminPort, bootPort, base='', httpPort=None, configFile=None, configDir=None,
keypath=None, certpath=None, cafilepath=None):
keypath=None, certpath=None, cafilepath=None, cors=False, curls=None, iurls=None, durls=None):
""" Set up an ahab in Signify mode """

agency = Agency(name=name, base=base, bran=bran, configFile=configFile, configDir=configDir)
agency = Agency(name=name, base=base, bran=bran, configFile=configFile, configDir=configDir, curls=curls, iurls=iurls, durls=durls)
bootApp = falcon.App(middleware=falcon.CORSMiddleware(
allow_origins='*', allow_credentials='*',
expose_headers=['cesr-attachment', 'cesr-date', 'content-type', 'signature', 'signature-input',
Expand All @@ -73,7 +73,7 @@ def setup(name, bran, adminPort, bootPort, base='', httpPort=None, configFile=No
allow_origins='*', allow_credentials='*',
expose_headers=['cesr-attachment', 'cesr-date', 'content-type', 'signature', 'signature-input',
'signify-resource', 'signify-timestamp']))
if os.getenv("KERI_AGENT_CORS", "false").lower() in ("true", "1"):
if cors:
app.add_middleware(middleware=httping.HandleCORS())
app.add_middleware(authing.SignatureValidationComponent(agency=agency, authn=authn, allowed=["/agent"]))
app.req_options.media_handlers.update(media.Handlers())
Expand Down Expand Up @@ -152,15 +152,19 @@ class Agency(doing.DoDoer):
"""

def __init__(self, name, bran, base="", configFile=None, configDir=None, adb=None, temp=False):
def __init__(self, name, bran, base="", configFile=None, configDir=None, adb=None, temp=False, curls=None, iurls=None, durls=None):
self.name = name
self.base = base
self.bran = bran
self.temp = temp
self.configFile = configFile
self.configDir = configDir
self.cf = None
if self.configFile is not None: # Load config file if creating database
self.curls = curls
self.iurls = iurls
self.durls = durls

if self.configFile is not None:
self.cf = configing.Configer(name=self.configFile,
base="",
headDirPath=self.configDir,
Expand All @@ -179,32 +183,42 @@ def create(self, caid):
temp=self.temp,
reopen=True)

cf = None
if self.cf is not None: # Load config file if creating database
data = dict(self.cf.get())
if "keria" in data:
curls = data["keria"]
data[f"agent-{caid}"] = curls
del data["keria"]

cf = configing.Configer(name=f"{caid}",
base="",
human=False,
temp=self.temp,
reopen=True,
clear=False)
cf.put(data)
timestamp = nowIso8601()
data = dict(self.cf.get() if self.cf is not None else { "dt": timestamp })

habName = f"agent-{caid}"
if "keria" in data:
data[habName] = data["keria"]
del data["keria"]

if self.curls is not None and isinstance(self.curls, list):
data[habName] = { "dt": timestamp, "curls": self.curls }

if self.iurls is not None and isinstance(self.iurls, list):
data["iurls"] = self.iurls

if self.durls is not None and isinstance(self.durls, list):
data["durls"] = self.durls

config = configing.Configer(name=f"{caid}",
base="",
human=False,
temp=self.temp,
reopen=True,
clear=False)

config.put(data)

# Create the Hab for the Agent with only 2 AIDs
agentHby = habbing.Habery(name=caid, base=self.base, bran=self.bran, ks=ks, cf=cf, temp=self.temp)
agentHab = agentHby.makeHab(f"agent-{caid}", ns="agent", transferable=True, delpre=caid)
agentHby = habbing.Habery(name=caid, base=self.base, bran=self.bran, ks=ks, cf=config, temp=self.temp)
agentHab = agentHby.makeHab(habName, ns="agent", transferable=True, delpre=caid)
agentRgy = Regery(hby=agentHby, name=agentHab.name, base=self.base, temp=self.temp)

agent = Agent(agentHby, agentRgy, agentHab,
agent = Agent(hby=agentHby,
rgy=agentRgy,
agentHab=agentHab,
caid=caid,
agency=self,
configDir=self.configDir,
configFile=self.configFile)
agency=self)

res = self.adb.agnt.pin(keys=(caid,),
val=coring.Prefixer(qb64=agent.pre))
Expand Down Expand Up @@ -759,7 +773,6 @@ def recur(self, tyme):

return False


def loadEnds(app):
opColEnd = longrunning.OperationCollectionEnd()
app.add_route("/operations", opColEnd)
Expand Down
69 changes: 32 additions & 37 deletions src/keria/app/cli/commands/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""
import argparse
import logging
import os

from keri import __version__
from keri import help
Expand All @@ -25,29 +26,32 @@
parser.add_argument('-a', '--admin-http-port',
dest="admin",
action='store',
default=3901,
type=int,
default=os.getenv("KERIA_ADMIN_PORT", "3901"),
help="Admin port number the HTTP server listens on. Default is 3901.")
parser.add_argument('-H', '--http',
action='store',
default=3902,
type=int,
default=os.getenv("KERIA_HTTP_PORT", "3902"),
help="Local port number the HTTP server listens on. Default is 3902.")
parser.add_argument('-B', '--boot',
action='store',
default=3903,
type=int,
default=os.getenv("KERIA_BOOT_PORT", "3903"),
help="Boot port number the Boot HTTP server listens on. This port needs to be secured."
" Default is 3903.")
parser.add_argument('-n', '--name',
action='store',
default="keria",
help="Name of controller. Default is agent.")
help="Name of controller. Default is 'keria'.")
parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore',
required=False, default="")
parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)',
dest="bran", default=None) # passcode => bran
dest="bran",
default=os.getenv("KERIA_PASSCODE")) # passcode => bran
parser.add_argument('--config-file',
dest="configFile",
action='store',
default="",
help="configuration filename")
parser.add_argument("--config-dir",
dest="configDir",
Expand All @@ -61,6 +65,9 @@
parser.add_argument("--cafilepath", action="store", required=False, default=None,
help="TLS server CA certificate chain")

def getListVariable(name):
value = os.getenv(name)
return value.split(";") if value else None

def launch(args):
help.ogler.level = logging.CRITICAL
Expand All @@ -71,37 +78,25 @@ def launch(args):
logger.info("******* Starting Agent for %s listening: admin/%s, http/%s "
".******", args.name, args.admin, args.http)

runAgent(name=args.name,
base=args.base,
bran=args.bran,
admin=int(args.admin),
http=int(args.http),
boot=int(args.boot),
configFile=args.configFile,
configDir=args.configDir,
keypath=args.keypath,
certpath=args.certpath,
cafilepath=args.cafilepath)

logger.info("******* Ended Agent for %s listening: admin/%s, http/%s"
".******", args.name, args.admin, args.http)
agency = agenting.setup(name=args.name or "ahab",
base=args.base or "",
bran=args.bran,
adminPort=args.admin,
httpPort=args.http,
bootPort=args.boot,
configFile=args.configFile,
configDir=args.configDir,
keypath=args.keypath,
certpath=args.certpath,
cafilepath=args.cafilepath,
cors=os.getenv("KERI_AGENT_CORS", "false").lower() in ("true", "1"),
releaseTimeout=int(os.getenv("KERIA_RELEASER_TIMEOUT", "86400")),
curls=getListVariable("KERIA_CURLS"),
iurls=getListVariable("KERIA_IURLS"),
durls=getListVariable("KERIA_DURLS"))

directing.runController(doers=agency, expire=0.0)

def runAgent(name="ahab", base="", bran="", admin=3901, http=3902, boot=3903, configFile=None,
configDir=None, keypath=None, certpath=None, cafilepath=None, expire=0.0):
"""
Setup and run a KERIA Agency
"""

doers = []
doers.extend(agenting.setup(name=name, base=base, bran=bran,
adminPort=admin,
httpPort=http,
bootPort=boot,
configFile=configFile,
configDir=configDir,
keypath=keypath,
certpath=certpath,
cafilepath=cafilepath))

directing.runController(doers=doers, expire=expire)
logger.info("******* Ended Agent for %s listening: admin/%s, http/%s"
".******", args.name, args.admin, args.http)
46 changes: 46 additions & 0 deletions tests/app/test_agenting.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,52 @@ def test_agency():
shutil.rmtree(f'/usr/local/var/keri/adb/{base}')


def test_agency_without_config_file():
salt = b'0123456789abcdef'
salter = core.Salter(raw=salt)
cf = configing.Configer(name="keria", headDirPath=SCRIPTS_DIR, temp=True, reopen=True, clear=False)

with habbing.openHby(name="keria", salt=salter.qb64, temp=True, cf=cf) as hby:
hby.makeHab(name="test")

agency = agenting.Agency(name="agency", base="", bran=None, temp=True, configFile=None, configDir=SCRIPTS_DIR)
assert agency.cf is None

doist = doing.Doist(limit=1.0, tock=0.03125, real=True)
doist.extend(doers=[agency])

# Ensure we can still create agent
caid = "ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose"
agent = agency.create(caid, salt=salter.qb64)
assert agent.pre == "EIAEKYpTygdBtFHBrHKWeh0aYCdx0ZJqZtzQLFnaDB2b"

def test_agency_with_urls_from_arguments():
salt = b'0123456789abcdef'
salter = core.Salter(raw=salt)
cf = configing.Configer(name="keria", headDirPath=SCRIPTS_DIR, temp=True, reopen=True, clear=False)

with habbing.openHby(name="keria", salt=salter.qb64, temp=True, cf=cf) as hby:
hby.makeHab(name="test")

curls = ["http://example.com:3902/"]
iurls = ["http://example.com:5432/oobi"]
durls = ["http://example.com:7723/oobi"]
agency = agenting.Agency(name="agency", base="", bran=None, temp=True, configDir=SCRIPTS_DIR, curls=curls, iurls=iurls, durls=durls)
assert agency.cf is None

doist = doing.Doist(limit=1.0, tock=0.03125, real=True)
doist.extend(doers=[agency])

# Ensure we can still create agent
caid = "ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose"
agent = agency.create(caid, salt=salter.qb64)
assert agent.pre == "EIAEKYpTygdBtFHBrHKWeh0aYCdx0ZJqZtzQLFnaDB2b"

assert agent.hby.cf is not None
assert agent.hby.cf.get()[f"agent-{caid}"]["curls"] == curls
assert agent.hby.cf.get()["iurls"] == iurls
assert agent.hby.cf.get()["durls"] == durls

def test_boot_ends(helpers):
agency = agenting.Agency(name="agency", bran=None, temp=True)
doist = doing.Doist(limit=1.0, tock=0.03125, real=True)
Expand Down

0 comments on commit ffca5fb

Please sign in to comment.