jaseci 1.4.2.6__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.

Files changed (187) hide show
  1. jaseci/__init__.py +3 -37
  2. jaseci-2.0.0.dist-info/METADATA +65 -0
  3. jaseci-2.0.0.dist-info/RECORD +4 -0
  4. {jaseci-1.4.2.6.dist-info → jaseci-2.0.0.dist-info}/WHEEL +1 -2
  5. jaseci/VERSION +0 -1
  6. jaseci/cli_tools/__init__.py +0 -0
  7. jaseci/cli_tools/book_tools.py +0 -457
  8. jaseci/cli_tools/jsctl.py +0 -500
  9. jaseci/cli_tools/tests/__init__.py +0 -0
  10. jaseci/cli_tools/tests/test_jsctl.py +0 -556
  11. jaseci/extens/__init__.py +0 -0
  12. jaseci/extens/act_lib/__init__.py +0 -0
  13. jaseci/extens/act_lib/date.py +0 -118
  14. jaseci/extens/act_lib/elastic.py +0 -87
  15. jaseci/extens/act_lib/file.py +0 -77
  16. jaseci/extens/act_lib/file_handler.py +0 -190
  17. jaseci/extens/act_lib/internal.py +0 -19
  18. jaseci/extens/act_lib/jaseci.py +0 -62
  19. jaseci/extens/act_lib/mail.py +0 -10
  20. jaseci/extens/act_lib/maths.py +0 -168
  21. jaseci/extens/act_lib/net.py +0 -192
  22. jaseci/extens/act_lib/rand.py +0 -83
  23. jaseci/extens/act_lib/regex.py +0 -85
  24. jaseci/extens/act_lib/request.py +0 -170
  25. jaseci/extens/act_lib/std.py +0 -236
  26. jaseci/extens/act_lib/storage.py +0 -53
  27. jaseci/extens/act_lib/stripe.py +0 -338
  28. jaseci/extens/act_lib/task.py +0 -14
  29. jaseci/extens/act_lib/tests/__init__.py +0 -0
  30. jaseci/extens/act_lib/tests/std_test_code.py +0 -37
  31. jaseci/extens/act_lib/tests/test_date.py +0 -26
  32. jaseci/extens/act_lib/tests/test_elastic.py +0 -159
  33. jaseci/extens/act_lib/tests/test_file.py +0 -116
  34. jaseci/extens/act_lib/tests/test_file_lib.py +0 -40
  35. jaseci/extens/act_lib/tests/test_mail_lib.py +0 -33
  36. jaseci/extens/act_lib/tests/test_maths.py +0 -147
  37. jaseci/extens/act_lib/tests/test_net_lib.py +0 -62
  38. jaseci/extens/act_lib/tests/test_regex.py +0 -61
  39. jaseci/extens/act_lib/tests/test_std.py +0 -51
  40. jaseci/extens/act_lib/tests/test_std_lib.py +0 -36
  41. jaseci/extens/act_lib/tests/test_url.py +0 -32
  42. jaseci/extens/act_lib/tests/test_vector.py +0 -36
  43. jaseci/extens/act_lib/tests/test_webtool.py +0 -44
  44. jaseci/extens/act_lib/tests/test_zlib.py +0 -24
  45. jaseci/extens/act_lib/url.py +0 -80
  46. jaseci/extens/act_lib/vector.py +0 -158
  47. jaseci/extens/act_lib/webtool.py +0 -29
  48. jaseci/extens/act_lib/zip.py +0 -34
  49. jaseci/extens/api/__init__.py +0 -0
  50. jaseci/extens/api/actions_api.py +0 -171
  51. jaseci/extens/api/alias_api.py +0 -140
  52. jaseci/extens/api/architype_api.py +0 -197
  53. jaseci/extens/api/config_api.py +0 -129
  54. jaseci/extens/api/global_api.py +0 -85
  55. jaseci/extens/api/graph_api.py +0 -168
  56. jaseci/extens/api/health_api.py +0 -21
  57. jaseci/extens/api/interface.py +0 -269
  58. jaseci/extens/api/jac_api.py +0 -172
  59. jaseci/extens/api/jsorc_api.py +0 -317
  60. jaseci/extens/api/logger_api.py +0 -90
  61. jaseci/extens/api/master_api.py +0 -134
  62. jaseci/extens/api/object_api.py +0 -102
  63. jaseci/extens/api/prometheus_api.py +0 -75
  64. jaseci/extens/api/queue_api.py +0 -141
  65. jaseci/extens/api/sentinel_api.py +0 -271
  66. jaseci/extens/api/share_api.py +0 -64
  67. jaseci/extens/api/super_api.py +0 -65
  68. jaseci/extens/api/tests/__init__.py +0 -0
  69. jaseci/extens/api/tests/test_architype_api.py +0 -66
  70. jaseci/extens/api/tests/test_global_api.py +0 -179
  71. jaseci/extens/api/tests/test_graph_api.py +0 -64
  72. jaseci/extens/api/tests/test_logger_api.py +0 -43
  73. jaseci/extens/api/tests/test_object_api.py +0 -20
  74. jaseci/extens/api/tests/test_sentinel_api.py +0 -66
  75. jaseci/extens/api/tests/test_uncommon.py +0 -107
  76. jaseci/extens/api/tests/test_user_api.py +0 -32
  77. jaseci/extens/api/tests/test_walker_api.py +0 -316
  78. jaseci/extens/api/user_api.py +0 -166
  79. jaseci/extens/api/walker_api.py +0 -299
  80. jaseci/extens/api/webhook_api.py +0 -77
  81. jaseci/extens/svc/__init__.py +0 -0
  82. jaseci/extens/svc/elastic_svc.py +0 -366
  83. jaseci/extens/svc/kube_svc.py +0 -432
  84. jaseci/extens/svc/mail_svc.py +0 -156
  85. jaseci/extens/svc/prome_svc.py +0 -378
  86. jaseci/extens/svc/redis_svc.py +0 -63
  87. jaseci/extens/svc/storage_svc.py +0 -193
  88. jaseci/extens/svc/stripe_svc.py +0 -51
  89. jaseci/extens/svc/task_svc.py +0 -155
  90. jaseci/extens/svc/tasks.py +0 -302
  91. jaseci/jac/__init__.py +0 -0
  92. jaseci/jac/interpreter/__init__.py +0 -0
  93. jaseci/jac/interpreter/architype_interp.py +0 -219
  94. jaseci/jac/interpreter/interp.py +0 -1784
  95. jaseci/jac/interpreter/sentinel_interp.py +0 -260
  96. jaseci/jac/interpreter/tests/__init__.py +0 -0
  97. jaseci/jac/interpreter/tests/test_interp.py +0 -42
  98. jaseci/jac/interpreter/walker_interp.py +0 -249
  99. jaseci/jac/ir/__init__.py +0 -0
  100. jaseci/jac/ir/ast.py +0 -73
  101. jaseci/jac/ir/ast_builder.py +0 -249
  102. jaseci/jac/ir/jac_code.py +0 -151
  103. jaseci/jac/ir/passes/__init__.py +0 -6
  104. jaseci/jac/ir/passes/ast_prune_pass.py +0 -9
  105. jaseci/jac/ir/passes/codegen_pass.py +0 -244
  106. jaseci/jac/ir/passes/ir_pass.py +0 -29
  107. jaseci/jac/ir/passes/printer_pass.py +0 -23
  108. jaseci/jac/ir/passes/pt_prune_pass.py +0 -29
  109. jaseci/jac/ir/passes/schedule.py +0 -23
  110. jaseci/jac/ir/passes/stats_pass.py +0 -16
  111. jaseci/jac/jac.g4 +0 -450
  112. jaseci/jac/jac_parse/__init__.py +0 -0
  113. jaseci/jac/jac_parse/jacLexer.py +0 -809
  114. jaseci/jac/jac_parse/jacListener.py +0 -853
  115. jaseci/jac/jac_parse/jacParser.py +0 -9192
  116. jaseci/jac/jac_set.py +0 -120
  117. jaseci/jac/jsci_vm/__init__.py +0 -0
  118. jaseci/jac/jsci_vm/disasm.py +0 -94
  119. jaseci/jac/jsci_vm/inst_ptr.py +0 -31
  120. jaseci/jac/jsci_vm/machine.py +0 -188
  121. jaseci/jac/jsci_vm/op_codes.py +0 -82
  122. jaseci/jac/jsci_vm/tests/__init__.py +0 -0
  123. jaseci/jac/jsci_vm/tests/test_codegen.py +0 -31
  124. jaseci/jac/machine/__init__.py +0 -0
  125. jaseci/jac/machine/jac_scope.py +0 -86
  126. jaseci/jac/machine/jac_value.py +0 -227
  127. jaseci/jac/machine/machine_state.py +0 -386
  128. jaseci/jac/tests/__init__.py +0 -0
  129. jaseci/jac/tests/book_code.py +0 -624
  130. jaseci/jac/tests/test_book.py +0 -380
  131. jaseci/jac/tests/test_lang_14.py +0 -49
  132. jaseci/jsorc/__init__.py +0 -7
  133. jaseci/jsorc/jsorc.py +0 -642
  134. jaseci/jsorc/jsorc_settings.py +0 -211
  135. jaseci/jsorc/jsorc_utils.py +0 -298
  136. jaseci/jsorc/live_actions.py +0 -365
  137. jaseci/jsorc/manifests/__init__.py +0 -0
  138. jaseci/jsorc/manifests/database.yaml +0 -109
  139. jaseci/jsorc/manifests/elastic.yaml +0 -6029
  140. jaseci/jsorc/manifests/prometheus.yaml +0 -1383
  141. jaseci/jsorc/manifests/redis.yaml +0 -64
  142. jaseci/jsorc/memory.py +0 -258
  143. jaseci/jsorc/redis.py +0 -140
  144. jaseci/jsorc/remote_actions.py +0 -158
  145. jaseci/jsorc/tests/__init__.py +0 -0
  146. jaseci/jsorc/tests/test_actions.py +0 -542
  147. jaseci/jsorc/tests/test_jsorc.py +0 -112
  148. jaseci/prim/__init__.py +0 -0
  149. jaseci/prim/ability.py +0 -94
  150. jaseci/prim/architype.py +0 -90
  151. jaseci/prim/edge.py +0 -173
  152. jaseci/prim/element.py +0 -233
  153. jaseci/prim/graph.py +0 -27
  154. jaseci/prim/master.py +0 -67
  155. jaseci/prim/node.py +0 -533
  156. jaseci/prim/obj_mixins.py +0 -238
  157. jaseci/prim/sentinel.py +0 -282
  158. jaseci/prim/super_master.py +0 -31
  159. jaseci/prim/walker.py +0 -261
  160. jaseci/svc/__init__.py +0 -0
  161. jaseci/tests/__init__.py +0 -0
  162. jaseci/tests/infer.py +0 -39
  163. jaseci/tests/jac_test_code.py +0 -1293
  164. jaseci/tests/jac_test_progs.py +0 -774
  165. jaseci/tests/test_core.py +0 -153
  166. jaseci/tests/test_jac.py +0 -824
  167. jaseci/tests/test_node.py +0 -89
  168. jaseci/tests/test_progs.py +0 -702
  169. jaseci/tests/test_stack.py +0 -220
  170. jaseci/tests/test_stripe.py +0 -225
  171. jaseci/utils/__init__.py +0 -0
  172. jaseci/utils/actions/__init__.py +0 -0
  173. jaseci/utils/actions/actions_manager.py +0 -254
  174. jaseci/utils/actions/actions_optimizer.py +0 -517
  175. jaseci/utils/actions/actions_state.py +0 -95
  176. jaseci/utils/file_handler.py +0 -171
  177. jaseci/utils/gprof2dot.py +0 -3786
  178. jaseci/utils/id_list.py +0 -169
  179. jaseci/utils/json_handler.py +0 -70
  180. jaseci/utils/log_utils.py +0 -57
  181. jaseci/utils/test_core.py +0 -62
  182. jaseci/utils/utils.py +0 -387
  183. jaseci-1.4.2.6.dist-info/LICENSE +0 -21
  184. jaseci-1.4.2.6.dist-info/METADATA +0 -39
  185. jaseci-1.4.2.6.dist-info/RECORD +0 -185
  186. jaseci-1.4.2.6.dist-info/entry_points.txt +0 -3
  187. jaseci-1.4.2.6.dist-info/top_level.txt +0 -1
@@ -1,432 +0,0 @@
1
- from base64 import b64decode
2
- from datetime import datetime
3
- from kubernetes import config as kubernetes_config
4
- from kubernetes.client import (
5
- ApiClient,
6
- CoreV1Api,
7
- AppsV1Api,
8
- RbacAuthorizationV1Api,
9
- ApiextensionsV1Api,
10
- AdmissionregistrationV1Api,
11
- CustomObjectsApi,
12
- )
13
- from kubernetes.client.rest import ApiException
14
-
15
- from jaseci.jsorc.jsorc import JsOrc
16
- from jaseci.jsorc.jsorc_utils import ManifestType, placeholder_resolver
17
- from jaseci.utils.utils import logger
18
-
19
-
20
- @JsOrc.service(name="kube", config="KUBE_CONFIG")
21
- class KubeService(JsOrc.CommonService):
22
- ###################################################
23
- # BUILDER #
24
- ###################################################
25
-
26
- _no_namespace = [
27
- "Namespace",
28
- "ClusterRole",
29
- "ClusterRoleBinding",
30
- "CustomResourceDefinition",
31
- "ValidatingWebhookConfiguration",
32
- ]
33
-
34
- def run(self):
35
- self._in_cluster = self.config.get("in_cluster", True)
36
- if self._in_cluster:
37
- kubernetes_config.load_incluster_config()
38
- else:
39
- kubernetes_config.load_kube_config()
40
-
41
- self.namespace = self.config.get("namespace", "default")
42
- config = self.config.get("config")
43
-
44
- self.app = ApiClient(config)
45
- self.core = CoreV1Api(config)
46
- self.api = AppsV1Api(self.app)
47
- self.api_ext = ApiextensionsV1Api(self.app)
48
- self.auth = RbacAuthorizationV1Api(self.app)
49
- self.reg_api = AdmissionregistrationV1Api(self.app)
50
- self.custom = CustomObjectsApi(self.app)
51
-
52
- self._cached_namespace = set()
53
-
54
- self.ping()
55
- self.defaults()
56
-
57
- def defaults(self):
58
- self.create_apis = {
59
- "Namespace": self.core.create_namespace,
60
- "Service": self.core.create_namespaced_service,
61
- "Deployment": self.api.create_namespaced_deployment,
62
- "ConfigMap": self.core.create_namespaced_config_map,
63
- "ServiceAccount": self.core.create_namespaced_service_account,
64
- "ClusterRole": self.auth.create_cluster_role,
65
- "ClusterRoleBinding": self.auth.create_cluster_role_binding,
66
- "Secret": self.core.create_namespaced_secret,
67
- "PersistentVolumeClaim": (
68
- self.core.create_namespaced_persistent_volume_claim
69
- ),
70
- "DaemonSet": self.api.create_namespaced_daemon_set,
71
- "StatefulSet": self.api.create_namespaced_stateful_set,
72
- "CustomResourceDefinition": self.api_ext.create_custom_resource_definition,
73
- "ValidatingWebhookConfiguration": self.reg_api.create_validating_webhook_configuration,
74
- "Elasticsearch": lambda namespace, body: self.custom.create_namespaced_custom_object(
75
- group="elasticsearch.k8s.elastic.co",
76
- version="v1",
77
- namespace=namespace,
78
- plural="elasticsearches",
79
- body=body,
80
- ),
81
- "Kibana": lambda namespace, body: self.custom.create_namespaced_custom_object(
82
- group="kibana.k8s.elastic.co",
83
- version="v1",
84
- namespace=namespace,
85
- plural="kibanas",
86
- body=body,
87
- ),
88
- "Beat": lambda namespace, body: self.custom.create_namespaced_custom_object(
89
- group="beat.k8s.elastic.co",
90
- version="v1beta1",
91
- namespace=namespace,
92
- plural="beats",
93
- body=body,
94
- ),
95
- }
96
- self.patch_apis = {
97
- "Namespace": self.core.patch_namespace,
98
- "Service": self.core.patch_namespaced_service,
99
- "Deployment": self.api.patch_namespaced_deployment,
100
- "ConfigMap": self.core.patch_namespaced_config_map,
101
- "ServiceAccount": self.core.patch_namespaced_service_account,
102
- "ClusterRole": self.auth.patch_cluster_role,
103
- "ClusterRoleBinding": self.auth.patch_cluster_role_binding,
104
- "Secret": self.core.patch_namespaced_secret,
105
- "PersistentVolumeClaim": (
106
- self.core.patch_namespaced_persistent_volume_claim
107
- ),
108
- "DaemonSet": self.api.patch_namespaced_daemon_set,
109
- "StatefulSet": self.api.patch_namespaced_stateful_set,
110
- "CustomResourceDefinition": self.api_ext.patch_custom_resource_definition,
111
- "ValidatingWebhookConfiguration": self.reg_api.patch_validating_webhook_configuration,
112
- "Elasticsearch": lambda name, namespace, body: self.custom.patch_namespaced_custom_object(
113
- group="elasticsearch.k8s.elastic.co",
114
- version="v1",
115
- namespace=namespace,
116
- plural="elasticsearches",
117
- name=name,
118
- body=body,
119
- ),
120
- "Kibana": lambda name, namespace, body: self.custom.patch_namespaced_custom_object(
121
- group="kibana.k8s.elastic.co",
122
- version="v1",
123
- namespace=namespace,
124
- plural="kibanas",
125
- name=name,
126
- body=body,
127
- ),
128
- "Beat": lambda name, namespace, body: self.custom.patch_namespaced_custom_object(
129
- group="beat.k8s.elastic.co",
130
- version="v1beta1",
131
- namespace=namespace,
132
- plural="beats",
133
- name=name,
134
- body=body,
135
- ),
136
- }
137
- self.delete_apis = {
138
- "Namespace": self.core.delete_namespace,
139
- "Service": self.core.delete_namespaced_service,
140
- "Deployment": self.api.delete_namespaced_deployment,
141
- "ConfigMap": self.core.delete_namespaced_config_map,
142
- "ServiceAccount": self.core.delete_namespaced_service_account,
143
- "ClusterRole": self.auth.delete_cluster_role,
144
- "ClusterRoleBinding": self.auth.delete_cluster_role_binding,
145
- "Secret": self.core.delete_namespaced_secret,
146
- "PersistentVolumeClaim": (
147
- self.core.delete_namespaced_persistent_volume_claim
148
- ),
149
- "DaemonSet": self.api.delete_namespaced_daemon_set,
150
- "StatefulSet": self.api.delete_namespaced_stateful_set,
151
- "CustomResourceDefinition": self.api_ext.delete_custom_resource_definition,
152
- "ValidatingWebhookConfiguration": self.reg_api.delete_validating_webhook_configuration,
153
- "Elasticsearch": lambda name, namespace: self.custom.delete_namespaced_custom_object(
154
- group="elasticsearch.k8s.elastic.co",
155
- version="v1",
156
- namespace=namespace,
157
- plural="elasticsearches",
158
- name=name,
159
- ),
160
- "Kibana": lambda name, namespace: self.custom.delete_namespaced_custom_object(
161
- group="kibana.k8s.elastic.co",
162
- version="v1",
163
- namespace=namespace,
164
- plural="kibanas",
165
- name=name,
166
- ),
167
- "Beat": lambda name, namespace: self.custom.delete_namespaced_custom_object(
168
- group="beat.k8s.elastic.co",
169
- version="v1beta1",
170
- namespace=namespace,
171
- plural="beats",
172
- name=name,
173
- ),
174
- }
175
- self.read_apis = {
176
- "Namespace": self.core.read_namespace,
177
- "Service": self.core.read_namespaced_service,
178
- "Endpoints": self.core.read_namespaced_endpoints,
179
- "Deployment": self.api.read_namespaced_deployment,
180
- "ConfigMap": self.core.read_namespaced_config_map,
181
- "ServiceAccount": self.core.read_namespaced_service_account,
182
- "ClusterRole": self.auth.read_cluster_role,
183
- "ClusterRoleBinding": self.auth.read_cluster_role_binding,
184
- "Secret": self.core.read_namespaced_secret,
185
- "PersistentVolumeClaim": self.core.read_namespaced_persistent_volume_claim,
186
- "DaemonSet": self.api.read_namespaced_daemon_set,
187
- "StatefulSet": self.api.read_namespaced_stateful_set,
188
- "CustomResourceDefinition": self.api_ext.read_custom_resource_definition,
189
- "ValidatingWebhookConfiguration": self.reg_api.read_validating_webhook_configuration,
190
- "Elasticsearch": lambda name, namespace: self.custom.get_namespaced_custom_object(
191
- group="elasticsearch.k8s.elastic.co",
192
- version="v1",
193
- namespace=namespace,
194
- plural="elasticsearches",
195
- name=name,
196
- ),
197
- "Kibana": lambda name, namespace: self.custom.get_namespaced_custom_object(
198
- group="kibana.k8s.elastic.co",
199
- version="v1",
200
- namespace=namespace,
201
- plural="kibanas",
202
- name=name,
203
- ),
204
- "Beat": lambda name, namespace: self.custom.get_namespaced_custom_object(
205
- group="beat.k8s.elastic.co",
206
- version="v1beta1",
207
- namespace=namespace,
208
- plural="beats",
209
- name=name,
210
- ),
211
- }
212
-
213
- ###################################################
214
- # COMMONS #
215
- ###################################################
216
-
217
- def ping(self):
218
- res = self.app.call_api("/readyz", "GET")
219
- return res[1] == 200
220
-
221
- def in_cluster(self):
222
- """
223
- Check if JSORC/Jaseci is running in a kubernetes cluster
224
- """
225
- try:
226
- return self._in_cluster and self.ping()
227
- except ApiException as e:
228
- logger.info(f"Kubernetes cluster environment check failed: {e}")
229
- return False
230
-
231
- def create(
232
- self,
233
- kind: str,
234
- name: str,
235
- conf: dict,
236
- namespace: str,
237
- log_pref: str = "",
238
- quiet: bool = False,
239
- ):
240
- try:
241
- quiet or logger.info(
242
- f"{log_pref} Creating {kind} for `{name}` with namespace: `{namespace}`"
243
- )
244
- if kind in self._no_namespace:
245
- self.create_apis[kind](body=conf)
246
- else:
247
- self.create_apis[kind](namespace=namespace, body=conf)
248
- except ApiException as e:
249
- quiet or logger.error(
250
- f"{log_pref} Error creating {kind} for `{name}` with namespace: `{namespace}` -- {e}"
251
- )
252
-
253
- def patch(
254
- self,
255
- kind: str,
256
- name: str,
257
- conf: dict,
258
- namespace: str,
259
- log_pref: str = "",
260
- quiet: bool = False,
261
- ):
262
- try:
263
- quiet or logger.info(
264
- f"{log_pref} Patching {kind} for `{name}` with namespace: `{namespace}`"
265
- )
266
- if kind in self._no_namespace:
267
- self.patch_apis[kind](name=name, body=conf)
268
- else:
269
- self.patch_apis[kind](name=name, namespace=namespace, body=conf)
270
- except ApiException as e:
271
- quiet or logger.error(
272
- f"{log_pref} Error patching {kind} for `{name}` with namespace: `{namespace}` -- {e}"
273
- )
274
-
275
- def read(
276
- self,
277
- kind: str,
278
- name: str,
279
- namespace: str,
280
- log_pref: str = "",
281
- quiet: bool = False,
282
- ):
283
- try:
284
- quiet or logger.info(
285
- f"{log_pref} Retrieving {kind} for `{name}` with namespace: `{namespace}`"
286
- )
287
- if kind in self._no_namespace:
288
- return self.read_apis[kind](name=name)
289
- else:
290
- return self.read_apis[kind](name=name, namespace=namespace)
291
- except ApiException as e:
292
- quiet or logger.error(
293
- f"{log_pref} Error retrieving {kind} for `{name}` with namespace: `{namespace}` -- {e}"
294
- )
295
- return e
296
-
297
- def delete(
298
- self,
299
- kind: str,
300
- name: str,
301
- namespace: str,
302
- log_pref: str = "",
303
- quiet: bool = False,
304
- ):
305
- try:
306
- quiet or logger.info(
307
- f"{log_pref} Deleting {kind} for `{name}` with namespace: `{namespace}`"
308
- )
309
- if kind in self._no_namespace:
310
- return self.delete_apis[kind](name=name)
311
- else:
312
- return self.delete_apis[kind](name=name, namespace=namespace)
313
- except ApiException as e:
314
- quiet or logger.error(
315
- f"{log_pref} Error deleting {kind} for `{name}` with namespace: `{namespace}` -- {e}"
316
- )
317
- return e
318
-
319
- def is_pod_running(self, name: str, namespace: str):
320
- try:
321
- return (
322
- self.core.list_namespaced_pod(
323
- namespace=namespace, label_selector=f"pod={name}"
324
- )
325
- .items[0]
326
- .status.phase
327
- == "Running"
328
- )
329
- except Exception:
330
- return False
331
-
332
- def get_secret(
333
- self,
334
- name: str,
335
- attr: str,
336
- namespace: str,
337
- log_pref: str = "",
338
- quiet: bool = False,
339
- ):
340
- try:
341
- return b64decode(
342
- self.core.read_namespaced_secret(
343
- name=name,
344
- namespace=namespace,
345
- ).data[attr]
346
- ).decode()
347
- except Exception as e:
348
- quiet or logger.error(
349
- f"{log_pref} Error getting secret `{attr}` from `{name}` with namespace: `{namespace}` -- {e}"
350
- )
351
- return None
352
-
353
- def resolve_manifest(
354
- self,
355
- manifest: dict,
356
- manifest_type: ManifestType = ManifestType.DEDICATED,
357
- manual_namespace: str = None,
358
- ) -> dict:
359
- for kind, confs in manifest.items():
360
- if kind not in self._no_namespace:
361
- for conf in confs.values():
362
- metadata: dict = conf["metadata"]
363
- namespace = metadata.get("namespace", "default")
364
- if not namespace.startswith("jsorc-dedicated"):
365
- if manifest_type == ManifestType.DEDICATED:
366
- namespace = self.namespace
367
- metadata["namespace"] = namespace
368
- elif manifest_type == ManifestType.MANUAL:
369
- namespace = manual_namespace
370
- metadata["namespace"] = namespace
371
-
372
- if namespace and namespace not in self._cached_namespace:
373
- res = self.read("Namespace", namespace, None)
374
- if hasattr(res, "status") and res.status == 404:
375
- self.create(
376
- "Namespace",
377
- namespace,
378
- {
379
- "apiVersion": "v1",
380
- "kind": "Namespace",
381
- "metadata": {
382
- "name": namespace,
383
- "labels": {"name": namespace},
384
- },
385
- },
386
- None,
387
- )
388
- # don't add it on cache since create is possible to fail
389
- elif (
390
- isinstance(res, dict) and "metadata" in res
391
- ) or res.metadata:
392
- self._cached_namespace.add(namespace)
393
-
394
- placeholder_resolver(manifest, manifest)
395
-
396
- return manifest
397
-
398
- def has_replicas(self):
399
- try:
400
- return (
401
- self.read(
402
- "Deployment", "jaseci", self.namespace, quiet=self.quiet
403
- ).spec.replicas
404
- > 1
405
- )
406
- except Exception as e:
407
- self.quiet or logger.error(f"Error checking jaseci replica -- {e}")
408
-
409
- def restart(self):
410
- try:
411
- return self.api.patch_namespaced_deployment(
412
- name="jaseci",
413
- namespace=self.namespace,
414
- body={
415
- "spec": {
416
- "template": {
417
- "metadata": {
418
- "annotations": {
419
- "kubectl.kubernetes.io/restartedAt": datetime.utcnow().isoformat(
420
- "T"
421
- )
422
- + "Z"
423
- }
424
- }
425
- }
426
- }
427
- },
428
- )
429
- except ApiException as e:
430
- self.quiet or logger.error(
431
- f"Error triggering jaseci rollout restart -- {e}"
432
- )
@@ -1,156 +0,0 @@
1
- import ssl
2
- from json import dumps
3
- from email.mime.multipart import MIMEMultipart
4
- from email.mime.text import MIMEText
5
- from smtplib import SMTP, SMTP_SSL
6
-
7
- from jaseci.jsorc.jsorc import JsOrc
8
-
9
-
10
- #################################################
11
- # EMAIL APP #
12
- #################################################
13
-
14
-
15
- @JsOrc.service(name="mail", config="MAIL_CONFIG")
16
- class MailService(JsOrc.CommonService):
17
- ###################################################
18
- # BUILDER #
19
- ###################################################
20
-
21
- def run(self):
22
- self.__convert_config()
23
- self.app = self.connect()
24
-
25
- # ----------- BACKWARD COMPATIBILITY ------------ #
26
- # ---------------- TO BE REMOVED ---------------- #
27
-
28
- def __convert(self, hook, holder, mapping: dict):
29
- for k, v in mapping.items():
30
- if hook.has_glob(k):
31
- conf = hook.get_glob(k)
32
- if not (conf is None):
33
- if v == "tls":
34
- holder[v] = conf.lower() == "true"
35
- else:
36
- holder[v] = conf
37
- return holder
38
-
39
- def __convert_config(self):
40
- hook = JsOrc.hook()
41
- version = self.config.get("version", 2)
42
- migrate = self.config.get("migrate", False)
43
- if version == 1 or migrate:
44
- self.__convert(
45
- hook,
46
- self.config,
47
- {
48
- "EMAIL_BACKEND": "backend",
49
- "EMAIL_HOST": "host",
50
- "EMAIL_PORT": "port",
51
- "EMAIL_HOST_USER": "user",
52
- "EMAIL_HOST_PASSWORD": "pass",
53
- "EMAIL_DEFAULT_FROM": "sender",
54
- "EMAIL_USE_TLS": "tls",
55
- },
56
- )
57
-
58
- if "templates" not in self.config:
59
- self.config["templates"] = {}
60
-
61
- self.__convert(
62
- hook,
63
- self.config["templates"],
64
- {
65
- "EMAIL_ACTIVATION_SUBJ": "activation_subj",
66
- "EMAIL_ACTIVATION_BODY": "activation_body",
67
- "EMAIL_ACTIVATION_HTML_BODY": "activation_html_body",
68
- "EMAIL_RESETPASS_SUBJ": "resetpass_subj",
69
- "EMAIL_RESETPASS_BODY": "resetpass_body",
70
- "EMAIL_RESETPASS_HTML_BODY": "resetpass_html_body",
71
- },
72
- )
73
-
74
- if migrate:
75
- hook.save_glob(
76
- "MAIL_CONFIG",
77
- dumps(
78
- {
79
- **{
80
- "enabled": self.enabled,
81
- "quiet": self.quiet,
82
- "automated": self.automated,
83
- },
84
- **self.config,
85
- "migrate": False,
86
- }
87
- ),
88
- )
89
- hook.commit()
90
-
91
- ###################################################
92
- # CLEANER #
93
- ###################################################
94
-
95
- # ---------------- PROXY EVENTS ----------------- #
96
-
97
- def on_delete(self):
98
- if self.is_running():
99
- self.app.terminate()
100
-
101
- ####################################################
102
- # OVERRIDDEN #
103
- ####################################################
104
-
105
- def connect(self):
106
- host = self.config.get("host")
107
- port = self.config.get("port")
108
- user = self.config.get("user")
109
- _pass = self.config.get("pass")
110
- sender = self.config.get("sender", user)
111
-
112
- context = ssl.create_default_context()
113
-
114
- if self.config.get("tls", True):
115
- server = SMTP(host, port)
116
- server.ehlo()
117
- server.starttls(context=context)
118
- server.ehlo()
119
- else:
120
- server = SMTP_SSL(host, port, context=context)
121
-
122
- server.login(user, _pass)
123
-
124
- return Mailer(server, sender)
125
-
126
-
127
- # ----------------------------------------------- #
128
-
129
- ####################################################
130
- # MAILER #
131
- ####################################################
132
-
133
-
134
- class Mailer:
135
- def __init__(self, server: SMTP, sender):
136
- self.server = server
137
- self.sender = sender
138
-
139
- def send_custom_email(
140
- self,
141
- sender: str = None,
142
- recipients: list = [],
143
- subject: str = "Jaseci Email",
144
- body: tuple = ("", ""),
145
- ):
146
- message = MIMEMultipart()
147
- message["Subject"] = subject
148
- message["From"] = self.sender if sender is None else sender
149
- message["To"] = ", ".join(recipients)
150
-
151
- message.attach(MIMEText(body[0], "plain"))
152
- message.attach(MIMEText(body[1], "html"))
153
- self.server.sendmail(message["From"], recipients, message.as_string())
154
-
155
- def terminate(self):
156
- self.server.quit()