Skip to content

Commit

Permalink
[FEATURE]: Config Vars
Browse files Browse the repository at this point in the history
  • Loading branch information
amadolid committed Jul 4, 2023
1 parent 726554c commit 9552f17
Show file tree
Hide file tree
Showing 16 changed files with 390 additions and 160 deletions.
17 changes: 9 additions & 8 deletions jaseci_core/jaseci/cli_tools/tests/test_jsctl.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,17 @@ def test_jsctl_config_cmds(self):
self.call(
f"sentinel register {os.path.dirname(__file__)}/zsb.jac -name zsb -set_active true"
)
self.call('config set CONFIG_EXAMPLE -value "TEST" -do_check False')
self.call("config set APPLE -value Grape2 -do_check False")
self.call("config set APPLE_JSON -value '{\"test\":true}' -do_check False")
self.call('config set "Banana" -value "Grape" -do_check False')
self.call('config set "Pear" -value "Banana" -do_check False')
r = self.call("config get APPLE -do_check False")
self.call('global set CONFIG_EXAMPLE -value "TEST"')
self.call("global set APPLE -value Grape2")
self.call("global set APPLE_JSON -value '{\"test\":true}'")
self.call('global set "Banana" -value "Grape"')
self.call('global set "Pear" -value "Banana"')
r = self.call("global get APPLE")
self.assertEqual(r.strip(), "Grape2")
r = self.call_cast("config list")
r = self.call_cast("global list")

self.assertEqual(len(r), 1)
# should now display everything
self.assertEqual(len(r), 5)

def test_jsctl_default_snt_setting(self):
"""Tests that alias mapping api works"""
Expand Down
10 changes: 3 additions & 7 deletions jaseci_core/jaseci/extens/act_lib/std.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ def set_global(name: str, value, meta):
mast = master_from_meta(meta)
if not mast.is_master(super_check=True, silent=False):
return False
mast.global_set(name, json.dumps(value))
return json.loads(mast.global_get(name)["value"])
mast.global_set(name, value)
return mast.global_get(name)


@jaseci_action()
Expand All @@ -97,11 +97,7 @@ def get_global(name: str, meta):
Param 1 - name
"""
mast = master_from_meta(meta)
val = mast.global_get(name)["value"]
if val:
return json.loads(val)
else:
return None
return mast.global_get(name)


@jaseci_action()
Expand Down
95 changes: 27 additions & 68 deletions jaseci_core/jaseci/extens/api/config_api.py
Original file line number Diff line number Diff line change
@@ -1,61 +1,46 @@
"""
Admin config api functions as a mixin
"""

from typing import Optional
from json import dumps, loads
from jaseci.utils.utils import manipulate_data
from jaseci.extens.api.interface import Interface


class ConfigApi:
"""
Admin config APIs
Abstracted since there are no valid configs in core atm, see jaseci_serv
to see how used.
"""

def __init__(self, *args, **kwargs):
self._valid_configs = [
"CONFIG_EXAMPLE",
"ACTION_SETS",
"REDIS_CONFIG",
"TASK_CONFIG",
"MAIL_CONFIG",
"PROME_CONFIG",
"ELASTIC_CONFIG",
"STRIPE_CONFIG",
"KUBE_CONFIG",
"JSORC_CONFIG",
]

@Interface.admin_api(cli_args=["name"])
def config_get(self, name: str, do_check: bool = True):
def config_get(self, name: str):
"""
Get a config
"""
if do_check and not self.name_check(name):
return self.name_error(name)
return self._h.get_glob(name)
conf = self._h.get_conf(name)
if isinstance(conf, (str, bytes, bytearray)):
try:
return loads(conf)
except Exception:
pass

return conf

@Interface.admin_api(cli_args=["name"])
def config_set(self, name: str, value: str or dict, do_check: bool = True):
def config_set(self, name: str, value: str or dict or list or tuple):
"""
Set a config
"""
if do_check and not self.name_check(name):
return self.name_error(name)

if not (value is None) and type(value) is dict:
if not (value is None) and isinstance(value, (dict, list, tuple)):
value = dumps(value)

self._h.save_glob(name, value)
return [f"Config of '{name}' to '{value}' set!"]
self._h.save_conf(name, value)
return [f"Config '{name}' to '{value}' set!"]

@Interface.admin_api(cli_args=["name"])
def config_update(
self,
name: str,
field_key: str,
field_key: str or int or list or tuple,
field_value: str
or int
or float
Expand All @@ -64,66 +49,40 @@ def config_update(
or bool
or tuple
or None, # json serializable types
do_check: bool = True,
):
"""
Update a key-value of a config
"""
if do_check and not self.name_check(name):
return self.name_error(name)

conf = self._h.get_glob(name)
conf = self._h.get_conf(name)
try:
conf = loads(conf)
except Exception:
conf = manipulate_data(conf, field_key, field_value)
self._h.save_conf(name, conf)
return [
f"Config {name} is not a dictionary. Uses config_set to set the value for this config."
f"Config '{name}' is updated with {field_key}:{field_value}. Current config value: {conf}"
]
except Exception as e:
return [
f"Config {name} is not a dictionary or list. Uses config_set to set the value for this config."
]
if field_key not in conf:
return [f"Field {field_key} does not exist in config {name}"]

conf[field_key] = field_value
conf = dumps(conf)
self._h.save_glob(name, conf)
return [
f"Config of '{name}' is updated with {field_key}:{field_value}. Current config value: {conf}"
]

@Interface.admin_api()
def config_list(self):
"""
Check a config is present
"""
return [v for v in self._h.list_glob() if v in self._valid_configs]

@Interface.admin_api()
def config_index(self):
"""
List all valid configs
"""
return self._valid_configs
return self._h.list_conf()

@Interface.admin_api(cli_args=["name"])
def config_exists(self, name: str):
"""
Check a config is present
"""
return self._h.has_glob(name)
return self._h.has_conf(name)

@Interface.admin_api(cli_args=["name"])
def config_delete(self, name: str, do_check: bool = True):
def config_delete(self, name: str):
"""
Delete a config
"""
if do_check and not self.name_check(name):
return self.name_error(name)
self._h.destroy_glob(name)
self._h.destroy_conf(name)
return [f"{name} Deleted."]

def name_error(self, name):
"""Much used error output"""
return [f"Config {name} not recognized, must be in {self._valid_configs}!"]

def name_check(self, name):
"""Much used name check"""
return name in self._valid_configs
93 changes: 75 additions & 18 deletions jaseci_core/jaseci/extens/api/global_api.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,100 @@
"""
Admin Global api functions as a mixin
"""
from jaseci.utils.utils import manipulate_data
from jaseci.extens.api.interface import Interface
from jaseci.prim.sentinel import Sentinel
import uuid
from json import dumps, loads


class GlobalApi:
"""
Admin global APIs
"""

@Interface.private_api(cli_args=["name"])
def global_get(self, name: str):
"""
Get a global
"""
glob = self._h.get_glob(name)

if isinstance(glob, (str, bytes, bytearray)):
try:
return loads(glob)
except Exception:
pass

return glob

@Interface.admin_api(cli_args=["name"])
def global_set(self, name: str, value: str):
def global_set(self, name: str, value: str or dict or list or tuple):
"""
Set a global
"""
ret = {"success": True}
if name == "GLOB_SENTINEL" or name in self._valid_configs:
ret["response"] = f"{name} is sacred!"
ret["success"] = False
else:
self._h.save_glob(name, value)
ret["response"] = f"Global variable '{name}' to '{value}' set!"
return ret
if name == "GLOB_SENTINEL":
return f"{name} is sacred!"

if not (value is None) and isinstance(value, (dict, list, tuple)):
value = dumps(value)

self._h.save_glob(name, value)
return [f"Global '{name}' to '{value}' set!"]

@Interface.admin_api(cli_args=["name"])
def global_update(
self,
name: str,
field_key: str or int or list or tuple,
field_value: str
or int
or float
or list
or dict
or bool
or tuple
or None, # json serializable types
):
"""
Update a key-value of a global
"""

glob = self._h.get_glob(name)
try:
glob = manipulate_data(glob, field_key, field_value)
self._h.save_glob(name, glob)
return [
f"Global '{name}' is updated with {field_key}:{field_value}. Current global value: {glob}"
]
except Exception:
return [
f"Global {name} is not a dictionary or list. Uses global_set to set the value."
]

@Interface.admin_api()
def global_list(self):
"""
Check a global is present
"""
return self._h.list_glob()

@Interface.admin_api(cli_args=["name"])
def global_exists(self, name: str):
"""
Check a global is present
"""
return self._h.has_glob(name)

@Interface.admin_api(cli_args=["name"])
def global_delete(self, name: str):
"""
Delete a global
"""
ret = {"success": True}
if name == "GLOB_SENTINEL" or name in self._valid_configs:
ret["response"] = f"{name} is sacred!"
ret["success"] = False
else:
self._h.destroy_glob(name)
ret["response"] = f"Global {name} deleted."
return ret
if name == "GLOB_SENTINEL":
return f"{name} is sacred!"

self._h.destroy_glob(name)
return [f"{name} Deleted."]

@Interface.admin_api()
def global_sentinel_set(self, snt: Sentinel = None):
Expand Down
7 changes: 0 additions & 7 deletions jaseci_core/jaseci/extens/api/object_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ def __init__(self):
self.perm_default = "private"
self._valid_perms = ["public", "private", "read_only"]

@Interface.private_api(cli_args=["name"])
def global_get(self, name: str):
"""
Get a global var
"""
return {"value": self._h.get_glob(name)}

@Interface.private_api(cli_args=["obj"])
def object_get(self, obj: Element, depth: int = 0, detailed: bool = False):
"""Returns object details for any Jaseci object."""
Expand Down
8 changes: 4 additions & 4 deletions jaseci_core/jaseci/extens/api/tests/test_global_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,17 @@ def test_global_set_get_delete(self):
"""Test setting global sentinel"""
api = ["global_get", {"name": "apple"}]
r = self.call(self.smast, api)
self.assertIsNone(r["value"])
api = ["global_set", {"name": "apple", "value": "56"}]
self.assertIsNone(r)
api = ["global_set", {"name": "apple", "value": 56}]
r = self.call(self.smast, api)
api = ["global_get", {"name": "apple"}]
r = self.call(self.smast2, api)
self.assertEqual(r["value"], "56")
self.assertEqual(r, 56)
api = ["global_delete", {"name": "apple"}]
r = self.call(self.smast2, api)
api = ["global_get", {"name": "apple"}]
r = self.call(self.smast, api)
self.assertIsNone(r["value"])
self.assertIsNone(r)

def test_user_create(self):
"""Test master create operation"""
Expand Down
Loading

0 comments on commit 9552f17

Please sign in to comment.