Fix: Schema implementation across plugins
This commit is contained in:
parent
45a40dfa86
commit
50c7af2f58
@ -26,6 +26,12 @@ class App():
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"default": {},
|
"default": {},
|
||||||
|
"$def" :{
|
||||||
|
'backends_items': None,
|
||||||
|
'backends_config': None,
|
||||||
|
'rules_items': None,
|
||||||
|
'rules_config': None,
|
||||||
|
},
|
||||||
"patternProperties": {
|
"patternProperties": {
|
||||||
".*": {
|
".*": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -64,10 +70,12 @@ class App():
|
|||||||
"tree": {
|
"tree": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"default": [],
|
"default": [],
|
||||||
|
"arrayItem": { "$ref": "#/$defs/backends_items" },
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"default": [],
|
"default": [],
|
||||||
|
"arrayItem": { "$ref": "#/$defs/rules_items" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -104,3 +112,23 @@ class App():
|
|||||||
print ("=== Query Result ===")
|
print ("=== Query Result ===")
|
||||||
|
|
||||||
|
|
||||||
|
def dump_schema(self):
|
||||||
|
|
||||||
|
import json
|
||||||
|
import albero.plugin as AlberoPlugins
|
||||||
|
from albero.managers import BackendsManager, RulesManager
|
||||||
|
|
||||||
|
r1 = BackendsManager.get_schema(AlberoPlugins)
|
||||||
|
r2 = RulesManager.get_schema(AlberoPlugins)
|
||||||
|
|
||||||
|
d = self.schema
|
||||||
|
d['$def']['backends_items'] = r1
|
||||||
|
d['$def']['rules_items'] = r2
|
||||||
|
d['$def']['backends_config'] = None
|
||||||
|
d['$def']['rules_config'] = None
|
||||||
|
|
||||||
|
#pprint(d)
|
||||||
|
print(json.dumps(d, indent=2))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -107,6 +107,8 @@ class CmdApp:
|
|||||||
subparsers = parser.add_subparsers(
|
subparsers = parser.add_subparsers(
|
||||||
title="subcommands", description="valid subcommands", dest="command"
|
title="subcommands", description="valid subcommands", dest="command"
|
||||||
)
|
)
|
||||||
|
# Manage command: schema
|
||||||
|
add_p = subparsers.add_parser("schema")
|
||||||
|
|
||||||
# Manage command: demo
|
# Manage command: demo
|
||||||
add_p = subparsers.add_parser("lookup")
|
add_p = subparsers.add_parser("lookup")
|
||||||
@ -175,6 +177,14 @@ class CmdApp:
|
|||||||
explain=self.args.explain
|
explain=self.args.explain
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def cli_schema(self):
|
||||||
|
"""Display configuration schema"""
|
||||||
|
|
||||||
|
config = '/home/jez/prj/bell/training/tiger-ansible/tree.yml'
|
||||||
|
|
||||||
|
app = Albero.App(config=config) #, namespace=self.args.namespace)
|
||||||
|
app.dump_schema()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = CmdApp()
|
app = CmdApp()
|
||||||
|
|||||||
@ -44,23 +44,48 @@ class LoadPlugin():
|
|||||||
# Return plugin Classe
|
# Return plugin Classe
|
||||||
return plugin_cls.Plugin
|
return plugin_cls.Plugin
|
||||||
|
|
||||||
|
class Manager():
|
||||||
|
|
||||||
|
plugins_kind = []
|
||||||
|
|
||||||
|
_schema_props_default = {}
|
||||||
|
_schema_props_default = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_schema(cls, plugins_db):
|
||||||
|
pprint (cls.plugins_kind)
|
||||||
|
|
||||||
|
ret = {}
|
||||||
|
ret3 = []
|
||||||
|
|
||||||
|
for kind in cls.plugins_kind:
|
||||||
|
ret[kind] = {}
|
||||||
|
plugin_kind = getattr(plugins_db, kind)
|
||||||
|
|
||||||
|
for plugin_name in [i for i in dir(plugin_kind) if not i.startswith('_')]:
|
||||||
|
plugin = getattr(plugin_kind, plugin_name)
|
||||||
|
print (plugin.Plugin)
|
||||||
|
#pprint (dir(plugin))
|
||||||
|
plugin_cls = getattr(plugin, 'Plugin', None)
|
||||||
|
if plugin_cls:
|
||||||
|
schema_props = getattr(plugin_cls, '_schema_props_new', 'MISSING ITEM')
|
||||||
|
if schema_props:
|
||||||
|
ret[kind][plugin_name] = schema_props
|
||||||
|
print (plugin_name)
|
||||||
|
ret3.append( schema_props )
|
||||||
|
|
||||||
|
ret3.append( cls._schema_props_new )
|
||||||
|
|
||||||
|
ret1 = cls._schema_props_default
|
||||||
|
ret1["$def"]["items"] = ret3
|
||||||
|
return ret1
|
||||||
|
|
||||||
|
|
||||||
class BackendsManager():
|
class BackendsManager(Manager):
|
||||||
|
|
||||||
_schema_props_default = {
|
plugins_kind = ['engine', 'backend']
|
||||||
"$schema": 'http://json-schema.org/draft-04/schema#',
|
|
||||||
"default": "",
|
_schema_props_new = {
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"default": "BLAAAAHHH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": True,
|
|
||||||
"default": {},
|
|
||||||
"properties": {
|
|
||||||
"engine": {
|
"engine": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "jerakia",
|
"default": "jerakia",
|
||||||
@ -70,7 +95,25 @@ class BackendsManager():
|
|||||||
"default": 'UNSET',
|
"default": 'UNSET',
|
||||||
"optional": False,
|
"optional": False,
|
||||||
},
|
},
|
||||||
},
|
#### INSERT HERE SUBSCHEMA !!!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
_schema_props_default = {
|
||||||
|
"$schema": 'http://json-schema.org/draft-04/schema#',
|
||||||
|
"default": "",
|
||||||
|
"$def": {
|
||||||
|
"items": {},
|
||||||
|
},
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"default": "BLAAAAHHH"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": True,
|
||||||
|
"default": {},
|
||||||
|
"properties": { "$ref": "#/$defs/name" },
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -173,13 +216,11 @@ class BackendsManager():
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RulesManager():
|
class RulesManager(Manager):
|
||||||
|
|
||||||
rule_schema = {
|
plugins_kind = ['strategy']
|
||||||
"$schema": 'http://json-schema.org/draft-04/schema#',
|
|
||||||
"type": "object",
|
_schema_props_new = {
|
||||||
"additionalProperties": False,
|
|
||||||
"properties": {
|
|
||||||
"rule": {
|
"rule": {
|
||||||
"default": ".*",
|
"default": ".*",
|
||||||
"optional": True,
|
"optional": True,
|
||||||
@ -192,6 +233,14 @@ class RulesManager():
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
"strategy": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "schema",
|
||||||
|
# "default": "last",
|
||||||
|
"optional": True,
|
||||||
|
# "enum": ["first", "last", "merge"],
|
||||||
|
},
|
||||||
|
|
||||||
"trace": {
|
"trace": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": False,
|
"default": False,
|
||||||
@ -200,26 +249,49 @@ class RulesManager():
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": False,
|
"default": False,
|
||||||
},
|
},
|
||||||
"strategy": {
|
}
|
||||||
"type": "string",
|
|
||||||
"default": "schema",
|
_schema_props_default = {
|
||||||
# "default": "last",
|
"$schema": 'http://json-schema.org/draft-04/schema#',
|
||||||
"optional": True,
|
"default": "",
|
||||||
# "enum": ["first", "last", "merge"],
|
"$def": {
|
||||||
|
"items": {},
|
||||||
},
|
},
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"default": "BLAAAAHHH"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": True,
|
||||||
|
"default": {},
|
||||||
|
"properties": { "$ref": "#/$defs/name" },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
OLD_rule_schema = {
|
||||||
|
"$schema": 'http://json-schema.org/draft-04/schema#',
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": False,
|
||||||
|
"properties": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"default": None,
|
"default": None,
|
||||||
"optional": True,
|
"optional": True,
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "null",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null",
|
"type": "string",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"additionalProperties": True,
|
||||||
|
"default": {},
|
||||||
|
"properties": { "$ref": "#/$defs/name" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -262,14 +334,14 @@ class RulesManager():
|
|||||||
|
|
||||||
matched_rule['trace'] = trace
|
matched_rule['trace'] = trace
|
||||||
matched_rule['explain'] = explain
|
matched_rule['explain'] = explain
|
||||||
schema_validate(matched_rule, self.rule_schema)
|
schema_validate(matched_rule, self._schema_props_default)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Prepare plugins
|
# Prepare plugins
|
||||||
assert(isinstance(matched_candidates, list)), f"Got: {matched_candidates}"
|
assert(isinstance(matched_candidates, list)), f"Got: {matched_candidates}"
|
||||||
assert(isinstance(matched_rule, dict)), f"Got: {matched_rule}"
|
assert(isinstance(matched_rule, dict)), f"Got: {matched_rule}"
|
||||||
strategy = matched_rule.get('strategy', 'first')
|
strategy = matched_rule.get('strategy', 'schema')
|
||||||
log.debug(f"Key '{key}' matched rule '{rule}' with '{strategy}' strategy")
|
log.debug(f"Key '{key}' matched rule '{rule}' with '{strategy}' strategy")
|
||||||
|
|
||||||
# Load plugin
|
# Load plugin
|
||||||
|
|||||||
@ -18,48 +18,49 @@ log = logging.getLogger(__name__)
|
|||||||
class Plugin(PluginBackendClass):
|
class Plugin(PluginBackendClass):
|
||||||
|
|
||||||
_plugin_name = "hier"
|
_plugin_name = "hier"
|
||||||
_schema_props_files = {
|
_schema_props_new = {
|
||||||
"path": {
|
"hier": {
|
||||||
"anyOf": [
|
"default": None,
|
||||||
|
"optional": True,
|
||||||
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "null",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"additionalProperties": True,
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"default": None,
|
||||||
|
"anyOf": [
|
||||||
|
{ "type": "null" },
|
||||||
|
{ "type": "string" },
|
||||||
|
{ "type": "array" },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"var": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "hier_item",
|
||||||
|
"optional": True,
|
||||||
|
},
|
||||||
|
"separator": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "/",
|
||||||
|
"optional": True,
|
||||||
|
},
|
||||||
|
"reversed": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": False,
|
||||||
|
"optional": True,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sssss_schema_props_default = {
|
|
||||||
"$schema": 'http://json-schema.org/draft-04/schema#',
|
|
||||||
"default": "",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"default": "BLAAAAHHH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": True,
|
|
||||||
"default": {},
|
|
||||||
"properties": {
|
|
||||||
"engine": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "jerakia",
|
|
||||||
"optional": False,
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"default": 'UNSET',
|
|
||||||
"optional": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def process(self, backends: list, ctx: dict) -> (list, dict):
|
def process(self, backends: list, ctx: dict) -> (list, dict):
|
||||||
|
|||||||
@ -10,52 +10,10 @@ import copy
|
|||||||
class Plugin(PluginBackendClass):
|
class Plugin(PluginBackendClass):
|
||||||
|
|
||||||
_plugin_name = "init"
|
_plugin_name = "init"
|
||||||
_schema_props_files = {
|
_schema_props_new = None
|
||||||
"path": {
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sssss_schema_props_default = {
|
|
||||||
"$schema": 'http://json-schema.org/draft-04/schema#',
|
|
||||||
"default": "",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"default": "BLAAAAHHH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": True,
|
|
||||||
"default": {},
|
|
||||||
"properties": {
|
|
||||||
"engine": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "jerakia",
|
|
||||||
"optional": False,
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"default": 'UNSET',
|
|
||||||
"optional": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
default_engine = 'jerakia'
|
default_engine = 'jerakia'
|
||||||
|
|
||||||
|
|
||||||
def process(self, backends: list, ctx: dict) -> (list, dict):
|
def process(self, backends: list, ctx: dict) -> (list, dict):
|
||||||
|
|
||||||
new_backends = []
|
new_backends = []
|
||||||
|
|||||||
@ -14,48 +14,41 @@ import textwrap
|
|||||||
class Plugin(PluginBackendClass):
|
class Plugin(PluginBackendClass):
|
||||||
|
|
||||||
_plugin_name = "loop"
|
_plugin_name = "loop"
|
||||||
_schema_props_files = {
|
_schema_props_new = {
|
||||||
"path": {
|
"loop": {
|
||||||
"anyOf": [
|
"default": None,
|
||||||
{
|
"optional": True,
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sssss_schema_props_default = {
|
|
||||||
"$schema": 'http://json-schema.org/draft-04/schema#',
|
|
||||||
"default": "",
|
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "BLAAAAHHH"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": True,
|
"additionalProperties": True,
|
||||||
"default": {},
|
"default": {},
|
||||||
"properties": {
|
"properties": {
|
||||||
"engine": {
|
"data": {
|
||||||
"type": "string",
|
"default": None,
|
||||||
"default": "jerakia",
|
|
||||||
"optional": False,
|
"optional": False,
|
||||||
|
"anyOf":[
|
||||||
|
{"type": "null"},
|
||||||
|
{"type": "string"},
|
||||||
|
{"type": "array"},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"var": {
|
||||||
"default": 'UNSET',
|
"type": "string",
|
||||||
"optional": False,
|
"default": "loop_item",
|
||||||
|
"optional": True,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def process(self, backends: list, ctx: dict) -> (list, dict):
|
def process(self, backends: list, ctx: dict) -> (list, dict):
|
||||||
|
|||||||
@ -50,6 +50,9 @@ class Candidate():
|
|||||||
class PluginClass():
|
class PluginClass():
|
||||||
_plugin_type = "none"
|
_plugin_type = "none"
|
||||||
_plugin_value = None
|
_plugin_value = None
|
||||||
|
|
||||||
|
_schema_props_new = "UNSET PLUGIN PROPRIETIES"
|
||||||
|
|
||||||
_schema_props_plugin = {
|
_schema_props_plugin = {
|
||||||
"engine": {
|
"engine": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@ -31,26 +31,23 @@ class Plugin(PluginEngineClass, PluginFileGlob):
|
|||||||
|
|
||||||
### OLD
|
### OLD
|
||||||
_plugin_engine = "jerakia"
|
_plugin_engine = "jerakia"
|
||||||
_schema_props_files = {
|
# _schema_props_files = {
|
||||||
|
_schema_props_new = {
|
||||||
"path": {
|
"path": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# def __repr__(self):
|
|
||||||
# engine = self.config.get('engine')
|
|
||||||
# value = self.
|
|
||||||
# return f"Plugin instance {engine}: {value}"
|
|
||||||
|
|
||||||
|
|
||||||
def _init(self):
|
def _init(self):
|
||||||
|
|||||||
@ -7,6 +7,7 @@ log = logging.getLogger(__name__)
|
|||||||
class Plugin(PluginStrategyClass):
|
class Plugin(PluginStrategyClass):
|
||||||
|
|
||||||
_plugin_name = "last"
|
_plugin_name = "last"
|
||||||
|
_schema_props_new = None
|
||||||
|
|
||||||
def process(self, candidates: list, rule=None) -> (list, dict):
|
def process(self, candidates: list, rule=None) -> (list, dict):
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,44 @@ from prettytable import PrettyTable
|
|||||||
class Plugin(PluginStrategyClass):
|
class Plugin(PluginStrategyClass):
|
||||||
|
|
||||||
_plugin_name = "schema"
|
_plugin_name = "schema"
|
||||||
|
_schema_props_new = {
|
||||||
|
"schema": {
|
||||||
|
"default": None,
|
||||||
|
"optional": True,
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": True,
|
||||||
|
"default": {},
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"default": None,
|
||||||
|
"optional": False,
|
||||||
|
"anyOf":[
|
||||||
|
{"type": "null"},
|
||||||
|
{"type": "string"},
|
||||||
|
{"type": "array"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"var": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "loop_item",
|
||||||
|
"optional": True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default_merge_schema = {
|
default_merge_schema = {
|
||||||
"$schema": 'http://json-schema.org/draft-04/schema#',
|
"$schema": 'http://json-schema.org/draft-04/schema#',
|
||||||
|
|||||||
@ -14,6 +14,7 @@ python-box = "^5.4.1"
|
|||||||
prettytable = "^3.0.0"
|
prettytable = "^3.0.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
|
json-schema-for-humans = "^0.40"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core>=1.0.0"]
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user