jaseci 1.4.2.5__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jaseci might be problematic. Click here for more details.
- jaseci/__init__.py +3 -37
- jaseci-2.0.0.dist-info/METADATA +65 -0
- jaseci-2.0.0.dist-info/RECORD +4 -0
- {jaseci-1.4.2.5.dist-info → jaseci-2.0.0.dist-info}/WHEEL +1 -2
- jaseci/VERSION +0 -1
- jaseci/cli_tools/__init__.py +0 -0
- jaseci/cli_tools/book_tools.py +0 -457
- jaseci/cli_tools/jsctl.py +0 -500
- jaseci/cli_tools/tests/__init__.py +0 -0
- jaseci/cli_tools/tests/test_jsctl.py +0 -556
- jaseci/extens/__init__.py +0 -0
- jaseci/extens/act_lib/__init__.py +0 -0
- jaseci/extens/act_lib/date.py +0 -117
- jaseci/extens/act_lib/elastic.py +0 -87
- jaseci/extens/act_lib/file.py +0 -76
- jaseci/extens/act_lib/file_handler.py +0 -189
- jaseci/extens/act_lib/internal.py +0 -18
- jaseci/extens/act_lib/jaseci.py +0 -61
- jaseci/extens/act_lib/mail.py +0 -10
- jaseci/extens/act_lib/maths.py +0 -168
- jaseci/extens/act_lib/net.py +0 -191
- jaseci/extens/act_lib/rand.py +0 -82
- jaseci/extens/act_lib/regex.py +0 -85
- jaseci/extens/act_lib/request.py +0 -169
- jaseci/extens/act_lib/std.py +0 -235
- jaseci/extens/act_lib/storage.py +0 -53
- jaseci/extens/act_lib/stripe.py +0 -337
- jaseci/extens/act_lib/task.py +0 -13
- jaseci/extens/act_lib/tests/__init__.py +0 -0
- jaseci/extens/act_lib/tests/std_test_code.py +0 -37
- jaseci/extens/act_lib/tests/test_date.py +0 -26
- jaseci/extens/act_lib/tests/test_elastic.py +0 -159
- jaseci/extens/act_lib/tests/test_file.py +0 -116
- jaseci/extens/act_lib/tests/test_file_lib.py +0 -40
- jaseci/extens/act_lib/tests/test_mail_lib.py +0 -33
- jaseci/extens/act_lib/tests/test_maths.py +0 -147
- jaseci/extens/act_lib/tests/test_net_lib.py +0 -62
- jaseci/extens/act_lib/tests/test_regex.py +0 -61
- jaseci/extens/act_lib/tests/test_std.py +0 -51
- jaseci/extens/act_lib/tests/test_std_lib.py +0 -36
- jaseci/extens/act_lib/tests/test_url.py +0 -32
- jaseci/extens/act_lib/tests/test_vector.py +0 -36
- jaseci/extens/act_lib/tests/test_webtool.py +0 -44
- jaseci/extens/act_lib/tests/test_zlib.py +0 -24
- jaseci/extens/act_lib/url.py +0 -79
- jaseci/extens/act_lib/vector.py +0 -157
- jaseci/extens/act_lib/webtool.py +0 -28
- jaseci/extens/act_lib/zip.py +0 -33
- jaseci/extens/api/__init__.py +0 -0
- jaseci/extens/api/actions_api.py +0 -170
- jaseci/extens/api/alias_api.py +0 -139
- jaseci/extens/api/architype_api.py +0 -196
- jaseci/extens/api/config_api.py +0 -129
- jaseci/extens/api/global_api.py +0 -84
- jaseci/extens/api/graph_api.py +0 -167
- jaseci/extens/api/health_api.py +0 -20
- jaseci/extens/api/interface.py +0 -268
- jaseci/extens/api/jac_api.py +0 -171
- jaseci/extens/api/jsorc_api.py +0 -316
- jaseci/extens/api/logger_api.py +0 -89
- jaseci/extens/api/master_api.py +0 -133
- jaseci/extens/api/object_api.py +0 -101
- jaseci/extens/api/prometheus_api.py +0 -74
- jaseci/extens/api/queue_api.py +0 -140
- jaseci/extens/api/sentinel_api.py +0 -270
- jaseci/extens/api/super_api.py +0 -64
- jaseci/extens/api/tests/__init__.py +0 -0
- jaseci/extens/api/tests/test_architype_api.py +0 -66
- jaseci/extens/api/tests/test_global_api.py +0 -179
- jaseci/extens/api/tests/test_graph_api.py +0 -64
- jaseci/extens/api/tests/test_logger_api.py +0 -43
- jaseci/extens/api/tests/test_object_api.py +0 -20
- jaseci/extens/api/tests/test_sentinel_api.py +0 -66
- jaseci/extens/api/tests/test_uncommon.py +0 -107
- jaseci/extens/api/tests/test_user_api.py +0 -32
- jaseci/extens/api/tests/test_walker_api.py +0 -316
- jaseci/extens/api/user_api.py +0 -144
- jaseci/extens/api/walker_api.py +0 -298
- jaseci/extens/api/webhook_api.py +0 -74
- jaseci/extens/svc/__init__.py +0 -0
- jaseci/extens/svc/elastic_svc.py +0 -366
- jaseci/extens/svc/kube_svc.py +0 -432
- jaseci/extens/svc/mail_svc.py +0 -156
- jaseci/extens/svc/prome_svc.py +0 -378
- jaseci/extens/svc/redis_svc.py +0 -63
- jaseci/extens/svc/storage_svc.py +0 -193
- jaseci/extens/svc/stripe_svc.py +0 -51
- jaseci/extens/svc/task_svc.py +0 -155
- jaseci/extens/svc/tasks.py +0 -302
- jaseci/jac/__init__.py +0 -0
- jaseci/jac/interpreter/__init__.py +0 -0
- jaseci/jac/interpreter/architype_interp.py +0 -214
- jaseci/jac/interpreter/interp.py +0 -1783
- jaseci/jac/interpreter/sentinel_interp.py +0 -257
- jaseci/jac/interpreter/tests/__init__.py +0 -0
- jaseci/jac/interpreter/tests/test_interp.py +0 -42
- jaseci/jac/interpreter/walker_interp.py +0 -248
- jaseci/jac/ir/__init__.py +0 -0
- jaseci/jac/ir/ast.py +0 -73
- jaseci/jac/ir/ast_builder.py +0 -249
- jaseci/jac/ir/jac_code.py +0 -152
- jaseci/jac/ir/passes/__init__.py +0 -6
- jaseci/jac/ir/passes/ast_prune_pass.py +0 -9
- jaseci/jac/ir/passes/codegen_pass.py +0 -244
- jaseci/jac/ir/passes/ir_pass.py +0 -29
- jaseci/jac/ir/passes/printer_pass.py +0 -23
- jaseci/jac/ir/passes/pt_prune_pass.py +0 -29
- jaseci/jac/ir/passes/schedule.py +0 -23
- jaseci/jac/ir/passes/stats_pass.py +0 -16
- jaseci/jac/jac.g4 +0 -450
- jaseci/jac/jac_parse/__init__.py +0 -0
- jaseci/jac/jac_parse/jacLexer.py +0 -809
- jaseci/jac/jac_parse/jacListener.py +0 -853
- jaseci/jac/jac_parse/jacParser.py +0 -9192
- jaseci/jac/jac_set.py +0 -119
- jaseci/jac/jsci_vm/__init__.py +0 -0
- jaseci/jac/jsci_vm/disasm.py +0 -94
- jaseci/jac/jsci_vm/inst_ptr.py +0 -31
- jaseci/jac/jsci_vm/machine.py +0 -188
- jaseci/jac/jsci_vm/op_codes.py +0 -82
- jaseci/jac/jsci_vm/tests/__init__.py +0 -0
- jaseci/jac/jsci_vm/tests/test_codegen.py +0 -31
- jaseci/jac/machine/__init__.py +0 -0
- jaseci/jac/machine/jac_scope.py +0 -85
- jaseci/jac/machine/jac_value.py +0 -226
- jaseci/jac/machine/machine_state.py +0 -383
- jaseci/jac/tests/__init__.py +0 -0
- jaseci/jac/tests/book_code.py +0 -624
- jaseci/jac/tests/test_book.py +0 -380
- jaseci/jac/tests/test_lang_14.py +0 -49
- jaseci/jsorc/__init__.py +0 -7
- jaseci/jsorc/jsorc.py +0 -642
- jaseci/jsorc/jsorc_settings.py +0 -211
- jaseci/jsorc/jsorc_utils.py +0 -298
- jaseci/jsorc/live_actions.py +0 -364
- jaseci/jsorc/manifests/__init__.py +0 -0
- jaseci/jsorc/manifests/database.yaml +0 -109
- jaseci/jsorc/manifests/elastic.yaml +0 -6024
- jaseci/jsorc/manifests/prometheus.yaml +0 -1383
- jaseci/jsorc/manifests/redis.yaml +0 -64
- jaseci/jsorc/memory.py +0 -258
- jaseci/jsorc/redis.py +0 -139
- jaseci/jsorc/remote_actions.py +0 -157
- jaseci/jsorc/tests/__init__.py +0 -0
- jaseci/jsorc/tests/test_actions.py +0 -542
- jaseci/jsorc/tests/test_jsorc.py +0 -112
- jaseci/prim/__init__.py +0 -0
- jaseci/prim/ability.py +0 -93
- jaseci/prim/architype.py +0 -89
- jaseci/prim/edge.py +0 -172
- jaseci/prim/element.py +0 -233
- jaseci/prim/graph.py +0 -26
- jaseci/prim/master.py +0 -64
- jaseci/prim/node.py +0 -532
- jaseci/prim/obj_mixins.py +0 -235
- jaseci/prim/sentinel.py +0 -281
- jaseci/prim/super_master.py +0 -31
- jaseci/prim/walker.py +0 -261
- jaseci/svc/__init__.py +0 -0
- jaseci/tests/__init__.py +0 -0
- jaseci/tests/infer.py +0 -39
- jaseci/tests/jac_test_code.py +0 -1293
- jaseci/tests/jac_test_progs.py +0 -774
- jaseci/tests/test_core.py +0 -153
- jaseci/tests/test_jac.py +0 -824
- jaseci/tests/test_node.py +0 -89
- jaseci/tests/test_progs.py +0 -702
- jaseci/tests/test_stack.py +0 -220
- jaseci/tests/test_stripe.py +0 -225
- jaseci/utils/__init__.py +0 -0
- jaseci/utils/actions/__init__.py +0 -0
- jaseci/utils/actions/actions_manager.py +0 -254
- jaseci/utils/actions/actions_optimizer.py +0 -516
- jaseci/utils/actions/actions_state.py +0 -95
- jaseci/utils/file_handler.py +0 -171
- jaseci/utils/gprof2dot.py +0 -3786
- jaseci/utils/id_list.py +0 -168
- jaseci/utils/json_handler.py +0 -70
- jaseci/utils/log_utils.py +0 -57
- jaseci/utils/test_core.py +0 -62
- jaseci/utils/utils.py +0 -387
- jaseci-1.4.2.5.dist-info/LICENSE +0 -21
- jaseci-1.4.2.5.dist-info/METADATA +0 -39
- jaseci-1.4.2.5.dist-info/RECORD +0 -184
- jaseci-1.4.2.5.dist-info/entry_points.txt +0 -3
- jaseci-1.4.2.5.dist-info/top_level.txt +0 -1
jaseci/jsorc/jsorc.py
DELETED
|
@@ -1,642 +0,0 @@
|
|
|
1
|
-
import signal
|
|
2
|
-
import psycopg2
|
|
3
|
-
|
|
4
|
-
from time import sleep
|
|
5
|
-
from copy import deepcopy
|
|
6
|
-
from json import dumps
|
|
7
|
-
from datetime import datetime
|
|
8
|
-
from typing import TypeVar, Any, Union
|
|
9
|
-
|
|
10
|
-
from jaseci.utils.utils import logger
|
|
11
|
-
from jaseci.jsorc.jsorc_settings import JsOrcSettings
|
|
12
|
-
from jaseci.jsorc.jsorc_utils import State, CommonService as cs, ManifestType
|
|
13
|
-
|
|
14
|
-
from kubernetes.client.rest import ApiException
|
|
15
|
-
|
|
16
|
-
# For future use
|
|
17
|
-
# from concurrent.futures import ThreadPoolExecutor
|
|
18
|
-
# from os import cpu_count
|
|
19
|
-
|
|
20
|
-
T = TypeVar("T")
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class JsOrc:
|
|
24
|
-
# ------------------- ALIAS ------------------- #
|
|
25
|
-
|
|
26
|
-
CommonService = cs
|
|
27
|
-
|
|
28
|
-
# ----------------- REFERENCE ----------------- #
|
|
29
|
-
|
|
30
|
-
_contexts = {}
|
|
31
|
-
_context_instances = {}
|
|
32
|
-
|
|
33
|
-
_services = {}
|
|
34
|
-
_service_instances = {}
|
|
35
|
-
|
|
36
|
-
_repositories = {}
|
|
37
|
-
|
|
38
|
-
# ----------------- SETTINGS ----------------- #
|
|
39
|
-
|
|
40
|
-
_use_proxy = False
|
|
41
|
-
_settings = JsOrcSettings
|
|
42
|
-
|
|
43
|
-
# For future use
|
|
44
|
-
# _executor = ThreadPoolExecutor(
|
|
45
|
-
# min(4, int((cpu_count() or 2) / 4) + 1)
|
|
46
|
-
# )
|
|
47
|
-
|
|
48
|
-
# ------------------ COMMONS ------------------ #
|
|
49
|
-
|
|
50
|
-
_config = None
|
|
51
|
-
_backoff_interval = 10
|
|
52
|
-
_running_interval = 0
|
|
53
|
-
__running__ = False
|
|
54
|
-
__proxy__ = cs.proxy()
|
|
55
|
-
|
|
56
|
-
# ------------------- REGEN ------------------- #
|
|
57
|
-
|
|
58
|
-
_regeneration_queues = []
|
|
59
|
-
_regenerating = False
|
|
60
|
-
_has_db = False
|
|
61
|
-
|
|
62
|
-
@staticmethod
|
|
63
|
-
def push(name: str, target: dict, entry: dict):
|
|
64
|
-
if name not in target:
|
|
65
|
-
target[name] = [entry]
|
|
66
|
-
else:
|
|
67
|
-
target[name] = sorted(
|
|
68
|
-
target[name] + [entry],
|
|
69
|
-
key=lambda item: (-item["priority"], -item["date_added"]),
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
@classmethod
|
|
73
|
-
def configure(cls):
|
|
74
|
-
config: dict = cls.settings("JSORC_CONFIG")
|
|
75
|
-
|
|
76
|
-
if cls.db_check():
|
|
77
|
-
hook = cls.hook()
|
|
78
|
-
config = hook.get_or_create_glob("JSORC_CONFIG", config)
|
|
79
|
-
|
|
80
|
-
cls._config = config
|
|
81
|
-
cls._backoff_interval = max(5, config.get("backoff_interval", 10))
|
|
82
|
-
cls._regeneration_queues = config.get("pre_loaded_services", [])
|
|
83
|
-
|
|
84
|
-
@classmethod
|
|
85
|
-
def run(cls):
|
|
86
|
-
if not cls.__running__:
|
|
87
|
-
cls.__running__ = True
|
|
88
|
-
cls.configure()
|
|
89
|
-
cls.push_interval(1)
|
|
90
|
-
|
|
91
|
-
@classmethod
|
|
92
|
-
def push_interval(cls, interval):
|
|
93
|
-
if cls._running_interval == 0:
|
|
94
|
-
cls._running_interval += 1
|
|
95
|
-
signal.alarm(interval)
|
|
96
|
-
else:
|
|
97
|
-
logger.info("Reusing current running interval...")
|
|
98
|
-
|
|
99
|
-
@classmethod
|
|
100
|
-
def kube(cls):
|
|
101
|
-
if not cls._kube:
|
|
102
|
-
raise Exception(f"Kubernetes is not yet ready!")
|
|
103
|
-
return cls._kube
|
|
104
|
-
|
|
105
|
-
#################################################
|
|
106
|
-
# HELPER #
|
|
107
|
-
#################################################
|
|
108
|
-
|
|
109
|
-
# ------------------ context ------------------ #
|
|
110
|
-
|
|
111
|
-
@classmethod
|
|
112
|
-
def get(cls, context: str, cast: T = None, *args, **kwargs) -> Union[T, Any]:
|
|
113
|
-
"""
|
|
114
|
-
Get existing context instance or build a new one that will persists
|
|
115
|
-
ex: master
|
|
116
|
-
|
|
117
|
-
context: name of the context to be build
|
|
118
|
-
cast: to cast the return and allow code hinting
|
|
119
|
-
*arsgs: additional argument used to initialize context
|
|
120
|
-
**kwargs: additional keyword argument used to initialize context
|
|
121
|
-
"""
|
|
122
|
-
if context not in cls._contexts:
|
|
123
|
-
raise Exception(f"Context {context} is not existing!")
|
|
124
|
-
|
|
125
|
-
if context not in cls._context_instances:
|
|
126
|
-
cls._context_instances[context] = cls.ctx(context, cast, *args, **kwargs)
|
|
127
|
-
|
|
128
|
-
return cls._context_instances[context]
|
|
129
|
-
|
|
130
|
-
@classmethod
|
|
131
|
-
def destroy(cls, context: str):
|
|
132
|
-
"""
|
|
133
|
-
remove existing context instance
|
|
134
|
-
ex: master
|
|
135
|
-
|
|
136
|
-
context: name of the context to be build
|
|
137
|
-
"""
|
|
138
|
-
if context not in cls._contexts:
|
|
139
|
-
raise Exception(f"Context {context} is not existing!")
|
|
140
|
-
|
|
141
|
-
if context in cls._context_instances:
|
|
142
|
-
del cls._context_instances[context]
|
|
143
|
-
|
|
144
|
-
@classmethod
|
|
145
|
-
def renew(cls, context: str, cast: T = None, *args, **kwargs) -> Union[T, Any]:
|
|
146
|
-
"""
|
|
147
|
-
renew existing context instance or build a new one that will persists
|
|
148
|
-
ex: master
|
|
149
|
-
|
|
150
|
-
context: name of the context to be build
|
|
151
|
-
cast: to cast the return and allow code hinting
|
|
152
|
-
*arsgs: additional argument used to initialize context
|
|
153
|
-
**kwargs: additional keyword argument used to initialize context
|
|
154
|
-
"""
|
|
155
|
-
cls.destroy(context)
|
|
156
|
-
|
|
157
|
-
cls._context_instances[context] = cls.ctx(context, cast, *args, **kwargs)
|
|
158
|
-
return cls._context_instances[context]
|
|
159
|
-
|
|
160
|
-
@classmethod
|
|
161
|
-
def ctx(cls, context: str, cast: T = None, *args, **kwargs) -> Union[T, Any]:
|
|
162
|
-
"""
|
|
163
|
-
Build new instance of the context
|
|
164
|
-
ex: master
|
|
165
|
-
|
|
166
|
-
context: name of the context to be build
|
|
167
|
-
cast: to cast the return and allow code hinting
|
|
168
|
-
*arsgs: additional argument used to initialize context
|
|
169
|
-
**kwargs: additional keyword argument used to initialize context
|
|
170
|
-
"""
|
|
171
|
-
if context not in cls._contexts:
|
|
172
|
-
raise Exception(f"Context {context} is not existing!")
|
|
173
|
-
|
|
174
|
-
# highest priority
|
|
175
|
-
context = cls._contexts[context][0]
|
|
176
|
-
|
|
177
|
-
return context["type"](*args, **kwargs)
|
|
178
|
-
|
|
179
|
-
@classmethod
|
|
180
|
-
def ctx_cls(cls, context: str):
|
|
181
|
-
"""
|
|
182
|
-
Get the context class
|
|
183
|
-
"""
|
|
184
|
-
if context not in cls._contexts:
|
|
185
|
-
return None
|
|
186
|
-
|
|
187
|
-
return cls._contexts[context][0]["type"]
|
|
188
|
-
|
|
189
|
-
@classmethod
|
|
190
|
-
def master(cls, cast: T = None, *args, **kwargs) -> Union[T, Any]:
|
|
191
|
-
"""
|
|
192
|
-
Generate master instance
|
|
193
|
-
"""
|
|
194
|
-
return cls.__gen_with_hook("master", cast, *args, **kwargs)
|
|
195
|
-
|
|
196
|
-
@classmethod
|
|
197
|
-
def super_master(cls, cast: T = None, *args, **kwargs) -> Union[T, Any]:
|
|
198
|
-
"""
|
|
199
|
-
Generate super_master instance
|
|
200
|
-
"""
|
|
201
|
-
return cls.__gen_with_hook("super_master", cast, *args, **kwargs)
|
|
202
|
-
|
|
203
|
-
@classmethod
|
|
204
|
-
def __gen_with_hook(cls, context: str, *args, **kwargs):
|
|
205
|
-
"""
|
|
206
|
-
Common process on master and super_master
|
|
207
|
-
"""
|
|
208
|
-
if not kwargs.get("h", None):
|
|
209
|
-
kwargs["h"] = cls.hook()
|
|
210
|
-
|
|
211
|
-
return cls.ctx(context, None, *args, **kwargs)
|
|
212
|
-
|
|
213
|
-
# ------------------ service ------------------ #
|
|
214
|
-
|
|
215
|
-
@classmethod
|
|
216
|
-
def _svc(cls, service: str) -> cs:
|
|
217
|
-
if service not in cls._services:
|
|
218
|
-
raise Exception(f"Service {service} is not existing!")
|
|
219
|
-
|
|
220
|
-
# highest priority
|
|
221
|
-
instance = cls._services[service][0]
|
|
222
|
-
|
|
223
|
-
config = cls.settings(instance["config"], cls.settings("DEFAULT_CONFIG"))
|
|
224
|
-
manifest = cls.settings(
|
|
225
|
-
instance["manifest"] or "DEFAULT_MANIFEST", cls.settings("DEFAULT_MANIFEST")
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
if cls.db_check():
|
|
229
|
-
hook = cls.hook(use_proxy=instance["proxy"])
|
|
230
|
-
|
|
231
|
-
config = hook.get_or_create_glob(instance["config"], config)
|
|
232
|
-
|
|
233
|
-
manifest = (
|
|
234
|
-
hook.get_or_create_glob(instance["manifest"], manifest)
|
|
235
|
-
if instance["manifest"]
|
|
236
|
-
else {}
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
instance: cs = instance["type"](
|
|
240
|
-
config, manifest, instance["manifest_type"], instance
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
if instance.has_failed() and service not in cls._regeneration_queues:
|
|
244
|
-
cls._regeneration_queues.append(service)
|
|
245
|
-
|
|
246
|
-
return instance
|
|
247
|
-
|
|
248
|
-
@classmethod
|
|
249
|
-
def svc(cls, service: str, cast: T = None) -> Union[T, cs]:
|
|
250
|
-
"""
|
|
251
|
-
Get service. Initialize when not yet existing.
|
|
252
|
-
ex: task
|
|
253
|
-
|
|
254
|
-
service: name of the service to be reference
|
|
255
|
-
cast: to cast the return and allow code hinting
|
|
256
|
-
"""
|
|
257
|
-
if service not in cls._services:
|
|
258
|
-
raise Exception(f"Service {service} is not existing!")
|
|
259
|
-
|
|
260
|
-
if service not in cls._service_instances:
|
|
261
|
-
if cls._use_proxy and cls._services[service][0]["proxy"]:
|
|
262
|
-
return cls.__proxy__
|
|
263
|
-
cls._service_instances[service] = cls._svc(service)
|
|
264
|
-
|
|
265
|
-
return cls._service_instances[service]
|
|
266
|
-
|
|
267
|
-
@classmethod
|
|
268
|
-
def svc_conf_set(
|
|
269
|
-
cls, service: str, config: dict, hook: None, cast: T = None
|
|
270
|
-
) -> Union[T, cs]:
|
|
271
|
-
from jaseci.extens.svc.kube_svc import KubeService
|
|
272
|
-
|
|
273
|
-
if service not in cls._services:
|
|
274
|
-
raise Exception(f"Service {service} is not existing!")
|
|
275
|
-
|
|
276
|
-
if cls.db_check():
|
|
277
|
-
instance = cls._services[service][0]
|
|
278
|
-
hook = hook or cls.hook(use_proxy=instance["proxy"])
|
|
279
|
-
hook.save_glob(instance["config"], dumps(config))
|
|
280
|
-
hook.commit()
|
|
281
|
-
|
|
282
|
-
kube = cls.svc("kube", KubeService)
|
|
283
|
-
if kube.is_running() and kube.has_replicas():
|
|
284
|
-
hook.clear_cache(True)
|
|
285
|
-
return (
|
|
286
|
-
"Rollout restart commencing..."
|
|
287
|
-
if not isinstance(kube.restart(), ApiException)
|
|
288
|
-
else "Attempt to rollout restart failed! Please check the logs for further information!"
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
return cls.svc_reset(service).info()
|
|
292
|
-
|
|
293
|
-
@classmethod
|
|
294
|
-
def svc_reset(cls, service, cast: T = None) -> Union[T, cs]:
|
|
295
|
-
"""
|
|
296
|
-
Service reset now deletes the actual instance and rebuild it
|
|
297
|
-
"""
|
|
298
|
-
if service in cls._service_instances:
|
|
299
|
-
instance = cls._service_instances.pop(service)
|
|
300
|
-
del instance
|
|
301
|
-
return cls.svc(service)
|
|
302
|
-
|
|
303
|
-
# ---------------- repository ----------------- #
|
|
304
|
-
|
|
305
|
-
@classmethod
|
|
306
|
-
def src(cls, repository: str, cast: T = None) -> Union[T, Any]:
|
|
307
|
-
"""
|
|
308
|
-
Initialize datasource class (repository)
|
|
309
|
-
ex: hook
|
|
310
|
-
|
|
311
|
-
repository: name of the repository to be reference
|
|
312
|
-
cast: to cast the return and allow code hinting
|
|
313
|
-
"""
|
|
314
|
-
if repository not in cls._repositories:
|
|
315
|
-
raise Exception(f"Repository {repository} is not existing!")
|
|
316
|
-
|
|
317
|
-
# highest priority
|
|
318
|
-
repository = cls._repositories[repository][0]
|
|
319
|
-
|
|
320
|
-
return repository["type"]()
|
|
321
|
-
|
|
322
|
-
@classmethod
|
|
323
|
-
def hook(cls, cast: T = None, use_proxy: bool = False) -> Union[T, Any]:
|
|
324
|
-
"""
|
|
325
|
-
Generate hook repository instance
|
|
326
|
-
"""
|
|
327
|
-
cls._use_proxy = use_proxy
|
|
328
|
-
hook = cls.src("hook")
|
|
329
|
-
cls._use_proxy = False
|
|
330
|
-
return hook
|
|
331
|
-
|
|
332
|
-
#################################################
|
|
333
|
-
# DECORATORS #
|
|
334
|
-
#################################################
|
|
335
|
-
|
|
336
|
-
@classmethod
|
|
337
|
-
def service(
|
|
338
|
-
cls,
|
|
339
|
-
name: str = None,
|
|
340
|
-
config: str = None,
|
|
341
|
-
manifest: str = None,
|
|
342
|
-
manifest_type: ManifestType = ManifestType.DEDICATED,
|
|
343
|
-
priority: int = 0,
|
|
344
|
-
proxy: bool = False,
|
|
345
|
-
):
|
|
346
|
-
"""
|
|
347
|
-
Save the class in services options
|
|
348
|
-
name: name to be used for reference
|
|
349
|
-
config: config name from datasource
|
|
350
|
-
manifest: manifest name from datasource
|
|
351
|
-
priority: duplicate name will use the highest priority
|
|
352
|
-
proxy: allow proxy service
|
|
353
|
-
manifest_type: manifest process type
|
|
354
|
-
"""
|
|
355
|
-
|
|
356
|
-
def decorator(service: T) -> T:
|
|
357
|
-
cls.push(
|
|
358
|
-
name=name or service.__name__,
|
|
359
|
-
target=cls._services,
|
|
360
|
-
entry={
|
|
361
|
-
"type": service,
|
|
362
|
-
"config": (config or f"{name}_CONFIG").upper(),
|
|
363
|
-
"manifest": manifest,
|
|
364
|
-
"manifest_type": manifest_type,
|
|
365
|
-
"priority": priority,
|
|
366
|
-
"proxy": proxy,
|
|
367
|
-
"date_added": int(datetime.utcnow().timestamp() * 1000),
|
|
368
|
-
},
|
|
369
|
-
)
|
|
370
|
-
return service
|
|
371
|
-
|
|
372
|
-
return decorator
|
|
373
|
-
|
|
374
|
-
@classmethod
|
|
375
|
-
def repository(cls, name: str = None, priority: int = 0):
|
|
376
|
-
"""
|
|
377
|
-
Save the class in repositories options
|
|
378
|
-
name: name to be used for reference
|
|
379
|
-
priority: duplicate name will use the highest priority
|
|
380
|
-
"""
|
|
381
|
-
|
|
382
|
-
def decorator(repository: T) -> T:
|
|
383
|
-
cls.push(
|
|
384
|
-
name=name or repository.__name__,
|
|
385
|
-
target=cls._repositories,
|
|
386
|
-
entry={
|
|
387
|
-
"type": repository,
|
|
388
|
-
"priority": priority,
|
|
389
|
-
"date_added": int(datetime.utcnow().timestamp() * 1000),
|
|
390
|
-
},
|
|
391
|
-
)
|
|
392
|
-
return repository
|
|
393
|
-
|
|
394
|
-
return decorator
|
|
395
|
-
|
|
396
|
-
@classmethod
|
|
397
|
-
def context(cls, name: str = None, priority: int = 0):
|
|
398
|
-
"""
|
|
399
|
-
Save the class in contexts options
|
|
400
|
-
name: name to be used for reference
|
|
401
|
-
priority: duplicate name will use the highest priority
|
|
402
|
-
"""
|
|
403
|
-
|
|
404
|
-
def decorator(context: T) -> T:
|
|
405
|
-
cls.push(
|
|
406
|
-
name=name or context.__name__,
|
|
407
|
-
target=cls._contexts,
|
|
408
|
-
entry={
|
|
409
|
-
"type": context,
|
|
410
|
-
"priority": priority,
|
|
411
|
-
"date_added": int(datetime.utcnow().timestamp() * 1000),
|
|
412
|
-
},
|
|
413
|
-
)
|
|
414
|
-
return context
|
|
415
|
-
|
|
416
|
-
return decorator
|
|
417
|
-
|
|
418
|
-
@classmethod
|
|
419
|
-
def inject(cls, contexts: list = [], services: list = [], repositories: list = []):
|
|
420
|
-
"""
|
|
421
|
-
Allow to inject instance on specific method/class
|
|
422
|
-
contexts: list of context name to inject
|
|
423
|
-
- can use tuple per entry (name, alias) instead of string
|
|
424
|
-
services: list of service name to inject
|
|
425
|
-
- can use tuple per entry (name, alias) instead of string
|
|
426
|
-
repositories: list of service name to inject
|
|
427
|
-
- can use tuple per entry (name, alias) instead of string
|
|
428
|
-
"""
|
|
429
|
-
|
|
430
|
-
def decorator(callable):
|
|
431
|
-
def argument_handler(*args, **kwargs):
|
|
432
|
-
_instances = {}
|
|
433
|
-
|
|
434
|
-
for context in contexts:
|
|
435
|
-
if isinstance(context, tuple):
|
|
436
|
-
_instances[context[1]] = cls.ctx(context[0])
|
|
437
|
-
else:
|
|
438
|
-
_instances[context] = cls.ctx(context)
|
|
439
|
-
for repository in repositories:
|
|
440
|
-
if isinstance(repository, tuple):
|
|
441
|
-
_instances[repository[1]] = cls.src(repository[0])
|
|
442
|
-
else:
|
|
443
|
-
_instances[repository] = cls.src(repository)
|
|
444
|
-
for service in services:
|
|
445
|
-
if isinstance(service, tuple):
|
|
446
|
-
_instances[service[1]] = cls.svc(service[0])
|
|
447
|
-
else:
|
|
448
|
-
_instances[service] = cls.svc(service)
|
|
449
|
-
|
|
450
|
-
kwargs.update(_instances)
|
|
451
|
-
callable(*args, **kwargs)
|
|
452
|
-
|
|
453
|
-
return argument_handler
|
|
454
|
-
|
|
455
|
-
return decorator
|
|
456
|
-
|
|
457
|
-
@classmethod
|
|
458
|
-
def settings(cls, name: str, default: T = None) -> Union[T, Any]:
|
|
459
|
-
return getattr(cls._settings, name, default)
|
|
460
|
-
|
|
461
|
-
@classmethod
|
|
462
|
-
def overrided_namespace(
|
|
463
|
-
cls, name: str, manifest_type: ManifestType = ManifestType.DEDICATED
|
|
464
|
-
) -> tuple:
|
|
465
|
-
manual_namespace = cls.settings("SERVICE_MANIFEST_MAP").get(name)
|
|
466
|
-
if manual_namespace:
|
|
467
|
-
if manual_namespace == "SOURCE":
|
|
468
|
-
manifest_type = ManifestType.SOURCE
|
|
469
|
-
else:
|
|
470
|
-
manual_namespace == manual_namespace.lower()
|
|
471
|
-
manifest_type = ManifestType.MANUAL
|
|
472
|
-
return manifest_type, manual_namespace
|
|
473
|
-
|
|
474
|
-
return (manifest_type,)
|
|
475
|
-
|
|
476
|
-
#################################################
|
|
477
|
-
# AUTOMATION #
|
|
478
|
-
#################################################
|
|
479
|
-
|
|
480
|
-
@classmethod
|
|
481
|
-
def add_regeneration_queue(cls, service: str):
|
|
482
|
-
cls.svc(service).state = State.RESTART
|
|
483
|
-
cls._regeneration_queues.append(service)
|
|
484
|
-
|
|
485
|
-
@classmethod
|
|
486
|
-
def regenerate(cls):
|
|
487
|
-
if not cls._regenerating:
|
|
488
|
-
cls._regenerating = True
|
|
489
|
-
|
|
490
|
-
if cls._has_db:
|
|
491
|
-
cls.regenerate_service()
|
|
492
|
-
else:
|
|
493
|
-
cls.regenerate_database()
|
|
494
|
-
|
|
495
|
-
cls._regenerating = False
|
|
496
|
-
|
|
497
|
-
@classmethod
|
|
498
|
-
def regenerate_service(cls):
|
|
499
|
-
from jaseci.extens.svc.kube_svc import KubeService
|
|
500
|
-
from jaseci.utils.actions.actions_manager import ActionManager
|
|
501
|
-
|
|
502
|
-
kube = cls.svc("kube", KubeService)
|
|
503
|
-
regeneration_queues = cls._regeneration_queues.copy()
|
|
504
|
-
cls._regeneration_queues.clear()
|
|
505
|
-
while regeneration_queues:
|
|
506
|
-
regeneration_queue = regeneration_queues.pop(0)
|
|
507
|
-
service = cls.svc(regeneration_queue)
|
|
508
|
-
hook = cls.hook(use_proxy=service.source["proxy"])
|
|
509
|
-
if not service.is_running() and service.enabled and service.automated:
|
|
510
|
-
if service.manifest and kube.is_running():
|
|
511
|
-
try:
|
|
512
|
-
manifest = kube.resolve_manifest(
|
|
513
|
-
hook.get_or_create_glob(
|
|
514
|
-
service.source["manifest"], service.manifest
|
|
515
|
-
),
|
|
516
|
-
*cls.overrided_namespace(
|
|
517
|
-
regeneration_queue, service.manifest_type
|
|
518
|
-
),
|
|
519
|
-
)
|
|
520
|
-
|
|
521
|
-
rmhists: dict = hook.get_or_create_glob(
|
|
522
|
-
"RESOLVED_MANIFEST_HISTORY", {}
|
|
523
|
-
)
|
|
524
|
-
|
|
525
|
-
_rmhist = rmhists.get(service.source["manifest"], [{}])[0]
|
|
526
|
-
rmhist = deepcopy(_rmhist)
|
|
527
|
-
|
|
528
|
-
for kind, confs in manifest.items():
|
|
529
|
-
for name, conf in confs.items():
|
|
530
|
-
namespace = conf["metadata"].get("namespace")
|
|
531
|
-
|
|
532
|
-
if kind in rmhist and name in rmhist[kind]:
|
|
533
|
-
rmhist[kind].pop(name, None)
|
|
534
|
-
|
|
535
|
-
res = kube.read(kind, name, namespace)
|
|
536
|
-
if hasattr(res, "status") and res.status == 404:
|
|
537
|
-
kube.create(kind, name, conf, namespace)
|
|
538
|
-
elif not isinstance(res, ApiException):
|
|
539
|
-
config_version = 1
|
|
540
|
-
|
|
541
|
-
if isinstance(res, dict):
|
|
542
|
-
if "labels" in res["metadata"]:
|
|
543
|
-
config_version = (
|
|
544
|
-
res["metadata"]
|
|
545
|
-
.get("labels", {})
|
|
546
|
-
.get("config_version", 1)
|
|
547
|
-
)
|
|
548
|
-
elif res.metadata.labels:
|
|
549
|
-
config_version = res.metadata.labels.get(
|
|
550
|
-
"config_version", 1
|
|
551
|
-
)
|
|
552
|
-
|
|
553
|
-
if config_version != conf.get("metadata").get(
|
|
554
|
-
"labels", {}
|
|
555
|
-
).get("config_version", 1):
|
|
556
|
-
kube.patch(kind, name, conf, namespace)
|
|
557
|
-
|
|
558
|
-
for kind, confs in rmhist.items():
|
|
559
|
-
for name, conf in confs.items():
|
|
560
|
-
namespace = conf["metadata"].get("namespace")
|
|
561
|
-
res = kube.read(kind, name, namespace, quiet=True)
|
|
562
|
-
if not isinstance(res, ApiException) and (
|
|
563
|
-
(isinstance(res, dict) and res.get("metadata"))
|
|
564
|
-
or res.metadata
|
|
565
|
-
):
|
|
566
|
-
if kind not in cls.settings(
|
|
567
|
-
"UNSAFE_KINDS"
|
|
568
|
-
) or service.manifest_unsafe_paraphrase == cls.settings(
|
|
569
|
-
"UNSAFE_PARAPHRASE"
|
|
570
|
-
):
|
|
571
|
-
kube.delete(kind, name, namespace)
|
|
572
|
-
else:
|
|
573
|
-
logger.info(
|
|
574
|
-
f"You don't have permission to delete `{kind}` for `{name}` with namespace `{namespace}`!"
|
|
575
|
-
)
|
|
576
|
-
|
|
577
|
-
if _rmhist != manifest:
|
|
578
|
-
if service.source["manifest"] not in rmhists:
|
|
579
|
-
rmhists[service.source["manifest"]] = [manifest]
|
|
580
|
-
else:
|
|
581
|
-
rmhists[service.source["manifest"]].insert(0, manifest)
|
|
582
|
-
hook.save_glob("RESOLVED_MANIFEST_HISTORY", dumps(rmhists))
|
|
583
|
-
hook.commit()
|
|
584
|
-
|
|
585
|
-
except Exception as e:
|
|
586
|
-
logger.error(f"Unhandled exception: {e}")
|
|
587
|
-
|
|
588
|
-
cls.svc_reset(regeneration_queue)
|
|
589
|
-
|
|
590
|
-
action_manager = cls.get("action_manager", ActionManager)
|
|
591
|
-
action_manager.optimize(jsorc_interval=cls._backoff_interval)
|
|
592
|
-
action_manager.record_system_state()
|
|
593
|
-
|
|
594
|
-
@classmethod
|
|
595
|
-
def regenerate_database(cls):
|
|
596
|
-
from jaseci.extens.svc.kube_svc import KubeService
|
|
597
|
-
|
|
598
|
-
kube = cls.svc("kube", KubeService)
|
|
599
|
-
|
|
600
|
-
if kube.is_running():
|
|
601
|
-
while not cls.db_check():
|
|
602
|
-
for kind, confs in kube.resolve_manifest(
|
|
603
|
-
cls.settings("DB_REGEN_MANIFEST", {}),
|
|
604
|
-
*cls.overrided_namespace("database"),
|
|
605
|
-
).items():
|
|
606
|
-
for name, conf in confs.items():
|
|
607
|
-
namespace = conf["metadata"].get("namespace")
|
|
608
|
-
res = kube.read(kind, name, namespace)
|
|
609
|
-
if hasattr(res, "status") and res.status == 404 and conf:
|
|
610
|
-
kube.create(kind, name, conf, namespace)
|
|
611
|
-
sleep(1)
|
|
612
|
-
raise SystemExit("Force termination to restart the pod!")
|
|
613
|
-
|
|
614
|
-
@classmethod
|
|
615
|
-
def db_check(cls):
|
|
616
|
-
if not cls._has_db:
|
|
617
|
-
try:
|
|
618
|
-
dbrc = cls.settings("DB_REGEN_CONFIG")
|
|
619
|
-
if dbrc["enabled"]:
|
|
620
|
-
connection = psycopg2.connect(
|
|
621
|
-
host=dbrc["host"],
|
|
622
|
-
dbname=dbrc["db"],
|
|
623
|
-
user=dbrc["user"],
|
|
624
|
-
password=dbrc["password"],
|
|
625
|
-
port=dbrc["port"],
|
|
626
|
-
)
|
|
627
|
-
connection.close()
|
|
628
|
-
cls._has_db = True
|
|
629
|
-
except Exception:
|
|
630
|
-
cls._has_db = False
|
|
631
|
-
return cls._has_db
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
def interval_check(signum, frame):
|
|
635
|
-
JsOrc.regenerate()
|
|
636
|
-
|
|
637
|
-
# wait interval_check to be finished before decrement
|
|
638
|
-
JsOrc._running_interval -= 1
|
|
639
|
-
JsOrc.push_interval(JsOrc._backoff_interval)
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
signal.signal(signal.SIGALRM, interval_check)
|