hcs-core 0.1.285__tar.gz → 0.1.287__tar.gz
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.
- {hcs_core-0.1.285 → hcs_core-0.1.287}/PKG-INFO +2 -1
- hcs_core-0.1.287/hcs_core/__init__.py +1 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/profile.py +0 -1
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/task_schd.py +0 -2
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/core.py +4 -4
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/dag.py +7 -7
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/kop.py +18 -6
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/auth.py +6 -1
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/login_support.py +0 -4
- {hcs_core-0.1.285 → hcs_core-0.1.287}/pyproject.toml +1 -0
- hcs_core-0.1.285/hcs_core/__init__.py +0 -1
- {hcs_core-0.1.285 → hcs_core-0.1.287}/.gitignore +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/README.md +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/__init__.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/_init.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/built_in_cmds/__init__.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/built_in_cmds/_ut.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/built_in_cmds/context.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/built_in_cmds/profile.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/cli_options.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/cli_processor.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/cmd_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/config.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/context.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/data_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/dispatcher.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/duration.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/extension.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/fn_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/fstore.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/jsondot.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/logger.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/profile_store.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/recent.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/state.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/template_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/timeutil.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/ctxp/var_template.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/__init__.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/actions.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/base_provider.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/context.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/helper.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/provider/__init__.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/provider/dev/__init__.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/provider/dev/_prepare.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/provider/dev/dummy.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/plan/provider/dev/fibonacci.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/__init__.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/cli_options.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/client_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/csp.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/ez_client.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/hcs_client.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/init.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/payload_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/requtil.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/sglib/utils.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/__init__.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/check_license.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/duration.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/exit.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/hcs_constants.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/job_view.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/pki_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/query_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/scheduler.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/ssl_util.py +0 -0
- {hcs_core-0.1.285 → hcs_core-0.1.287}/hcs_core/util/versions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hcs-core
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.287
|
|
4
4
|
Summary: Horizon Cloud Service CLI module.
|
|
5
5
|
Project-URL: Homepage, https://github.com/euc-eng/hcs-cli
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/euc-eng/hcs-cli/issues
|
|
@@ -40,6 +40,7 @@ Provides-Extra: dev
|
|
|
40
40
|
Requires-Dist: bandit; extra == 'dev'
|
|
41
41
|
Requires-Dist: black; extra == 'dev'
|
|
42
42
|
Requires-Dist: build; extra == 'dev'
|
|
43
|
+
Requires-Dist: flake8; extra == 'dev'
|
|
43
44
|
Requires-Dist: mypy; extra == 'dev'
|
|
44
45
|
Requires-Dist: pylint; extra == 'dev'
|
|
45
46
|
Requires-Dist: pytest; extra == 'dev'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.287"
|
|
@@ -111,7 +111,6 @@ def statistics(reset_cycle: bool = False):
|
|
|
111
111
|
|
|
112
112
|
def _daemon_worker():
|
|
113
113
|
log.info("task scheduler daemon thread start")
|
|
114
|
-
global _g_flag_stop_daemon
|
|
115
114
|
while not _g_flag_stop_daemon.is_set():
|
|
116
115
|
if _g_flag_running:
|
|
117
116
|
schedule.run_pending()
|
|
@@ -149,7 +148,6 @@ def resume():
|
|
|
149
148
|
|
|
150
149
|
|
|
151
150
|
def stop_daemon():
|
|
152
|
-
global _g_flag_stop_daemon
|
|
153
151
|
global _g_worker_thread
|
|
154
152
|
if _g_worker_thread:
|
|
155
153
|
_g_flag_stop_daemon.set()
|
|
@@ -127,7 +127,7 @@ def apply(
|
|
|
127
127
|
dag.process_blueprint(
|
|
128
128
|
blueprint=blueprint,
|
|
129
129
|
fn_process_node=process_resource_node,
|
|
130
|
-
|
|
130
|
+
fail_fast=True,
|
|
131
131
|
reverse=False,
|
|
132
132
|
concurrency=concurrency,
|
|
133
133
|
target_node_name=target_resource_name,
|
|
@@ -524,7 +524,7 @@ def _destroy_res(name, res_node, state, force):
|
|
|
524
524
|
|
|
525
525
|
def destroy(
|
|
526
526
|
data,
|
|
527
|
-
|
|
527
|
+
fail_fast: bool,
|
|
528
528
|
target_resource_name: str = None,
|
|
529
529
|
include_dependencies: bool = True,
|
|
530
530
|
concurrency: int = 4,
|
|
@@ -542,7 +542,7 @@ def destroy(
|
|
|
542
542
|
if not node:
|
|
543
543
|
return dag.walker.next
|
|
544
544
|
|
|
545
|
-
_destroy_res(node_name, node, state,
|
|
545
|
+
_destroy_res(node_name, node, state, fail_fast)
|
|
546
546
|
data_util.save_data_file(state, state_file)
|
|
547
547
|
return dag.walker.next
|
|
548
548
|
|
|
@@ -550,7 +550,7 @@ def destroy(
|
|
|
550
550
|
dag.process_blueprint(
|
|
551
551
|
blueprint=blueprint,
|
|
552
552
|
fn_process_node=destroy_resource,
|
|
553
|
-
|
|
553
|
+
fail_fast=fail_fast,
|
|
554
554
|
reverse=True,
|
|
555
555
|
concurrency=concurrency,
|
|
556
556
|
target_node_name=target_resource_name,
|
|
@@ -72,7 +72,7 @@ class DAG:
|
|
|
72
72
|
def process_blueprint(
|
|
73
73
|
blueprint,
|
|
74
74
|
fn_process_node: Callable,
|
|
75
|
-
|
|
75
|
+
fail_fast: bool = False,
|
|
76
76
|
reverse: bool = False,
|
|
77
77
|
concurrency: int = 3,
|
|
78
78
|
target_node_name: str = None,
|
|
@@ -88,7 +88,7 @@ def process_blueprint(
|
|
|
88
88
|
return walker.next
|
|
89
89
|
return fn_process_node(name)
|
|
90
90
|
|
|
91
|
-
return _walkthrough(dag, fn_process_node_impl,
|
|
91
|
+
return _walkthrough(dag, fn_process_node_impl, fail_fast, concurrency)
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
def _filter_dag_by_target_node(dag: DAG, target_node_name, include_dependencies):
|
|
@@ -225,7 +225,7 @@ def _get_provider_id(node_data):
|
|
|
225
225
|
return provider_type
|
|
226
226
|
|
|
227
227
|
|
|
228
|
-
def _walkthrough(dag: DAG, fn_process_node: Callable,
|
|
228
|
+
def _walkthrough(dag: DAG, fn_process_node: Callable, fail_fast: bool, concurrency: int):
|
|
229
229
|
topological_sorter = TopologicalSorter(dag.graph)
|
|
230
230
|
topological_sorter.prepare()
|
|
231
231
|
lock = threading.Lock()
|
|
@@ -250,10 +250,10 @@ def _walkthrough(dag: DAG, fn_process_node: Callable, continue_on_error: bool, c
|
|
|
250
250
|
except Exception as e:
|
|
251
251
|
with lock:
|
|
252
252
|
flags["err"] = e
|
|
253
|
-
if
|
|
254
|
-
topological_sorter.done(node_id)
|
|
255
|
-
else:
|
|
253
|
+
if fail_fast:
|
|
256
254
|
flag_stop.set()
|
|
255
|
+
else:
|
|
256
|
+
topological_sorter.done(node_id)
|
|
257
257
|
except SystemExit as e:
|
|
258
258
|
with lock:
|
|
259
259
|
flags["err"] = e
|
|
@@ -292,7 +292,7 @@ def _walkthrough(dag: DAG, fn_process_node: Callable, continue_on_error: bool, c
|
|
|
292
292
|
if flag_stop.is_set():
|
|
293
293
|
break
|
|
294
294
|
with lock:
|
|
295
|
-
if
|
|
295
|
+
if fail_fast and flags["err"]:
|
|
296
296
|
break
|
|
297
297
|
read_nodes = topological_sorter.get_ready()
|
|
298
298
|
if not len(read_nodes):
|
|
@@ -85,7 +85,8 @@ class KOP:
|
|
|
85
85
|
self._started = False
|
|
86
86
|
self._closed = False
|
|
87
87
|
job_id = kind + "/" + name
|
|
88
|
-
_job_view
|
|
88
|
+
if _job_view:
|
|
89
|
+
_job_view.add(job_id, job_id)
|
|
89
90
|
|
|
90
91
|
def _job_id(self):
|
|
91
92
|
return self._kind + "/" + self._name
|
|
@@ -103,7 +104,8 @@ class KOP:
|
|
|
103
104
|
|
|
104
105
|
def id(self, res_id: str):
|
|
105
106
|
self._id = res_id
|
|
106
|
-
_job_view
|
|
107
|
+
if _job_view:
|
|
108
|
+
_job_view.update(self._job_id(), res_id)
|
|
107
109
|
|
|
108
110
|
def start(self, mode: str = None, eta: str = None):
|
|
109
111
|
if self._started:
|
|
@@ -114,7 +116,8 @@ class KOP:
|
|
|
114
116
|
self._mode = mode
|
|
115
117
|
self._started = True
|
|
116
118
|
self._add_log(KopAction.start)
|
|
117
|
-
_job_view
|
|
119
|
+
if _job_view:
|
|
120
|
+
_job_view.start(self._job_id(), eta)
|
|
118
121
|
|
|
119
122
|
def _success(self):
|
|
120
123
|
if not self._started:
|
|
@@ -125,7 +128,8 @@ class KOP:
|
|
|
125
128
|
raise KopException("Kop already closed. This is a framework logging issue.")
|
|
126
129
|
self._add_log(KopAction.success)
|
|
127
130
|
self._closed = True
|
|
128
|
-
_job_view
|
|
131
|
+
if _job_view:
|
|
132
|
+
_job_view.success(self._job_id())
|
|
129
133
|
|
|
130
134
|
def error(self, err):
|
|
131
135
|
if isinstance(err, Exception):
|
|
@@ -136,12 +140,14 @@ class KOP:
|
|
|
136
140
|
details = str(err)
|
|
137
141
|
self._add_log(KopAction.error, details)
|
|
138
142
|
self._closed = True
|
|
139
|
-
_job_view
|
|
143
|
+
if _job_view:
|
|
144
|
+
_job_view.error(self._job_id(), details)
|
|
140
145
|
|
|
141
146
|
def skip(self, reason):
|
|
142
147
|
self._add_log(KopAction.skip, reason)
|
|
143
148
|
self._closed = True
|
|
144
|
-
_job_view
|
|
149
|
+
if _job_view:
|
|
150
|
+
_job_view.skip(self._job_id(), reason)
|
|
145
151
|
|
|
146
152
|
def _add_log(self, action: str, details: str = None):
|
|
147
153
|
labels = {
|
|
@@ -174,6 +180,12 @@ class KOP:
|
|
|
174
180
|
|
|
175
181
|
if _job_view == _DummyJobView:
|
|
176
182
|
log.info(msg)
|
|
183
|
+
elif _job_view is None:
|
|
184
|
+
# explicitly set by user to disable log
|
|
185
|
+
pass
|
|
186
|
+
else:
|
|
187
|
+
# custom job view
|
|
188
|
+
pass
|
|
177
189
|
entry = {"name": self._name, "time": int(time.time()), "action": action, "id": self._id}
|
|
178
190
|
if details:
|
|
179
191
|
entry["details"] = details
|
|
@@ -125,12 +125,17 @@ def _get_new_oauth_token(old_oauth_token, effective_profile):
|
|
|
125
125
|
def refresh_oauth_token(old_oauth_token: dict, csp_url: str):
|
|
126
126
|
with OAuth2Client(token=old_oauth_token) as client:
|
|
127
127
|
log.debug("Refresh auth token...")
|
|
128
|
-
|
|
128
|
+
token_url = csp_url + "/csp/gateway/am/api/auth/token"
|
|
129
|
+
from .login_support import identify_client_id
|
|
130
|
+
|
|
131
|
+
csp_specific_req_not_oauth_standard = (identify_client_id(csp_url), "")
|
|
132
|
+
new_token = client.refresh_token(token_url, auth=csp_specific_req_not_oauth_standard)
|
|
129
133
|
log.debug(f"New auth token: {new_token}")
|
|
130
134
|
if not new_token:
|
|
131
135
|
raise Exception("CSP auth refresh failed.")
|
|
132
136
|
if "cspErrorCode" in new_token:
|
|
133
137
|
raise Exception(f"CSP auth failed: {new_token.get('message')}")
|
|
138
|
+
|
|
134
139
|
return new_token
|
|
135
140
|
|
|
136
141
|
|
|
@@ -19,17 +19,13 @@ limitations under the License.
|
|
|
19
19
|
import logging
|
|
20
20
|
import secrets
|
|
21
21
|
import threading
|
|
22
|
-
import time
|
|
23
22
|
import webbrowser
|
|
24
23
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
25
|
-
from typing import Callable
|
|
26
24
|
from urllib.parse import parse_qs, urlparse
|
|
27
25
|
|
|
28
26
|
from authlib.integrations.httpx_client import OAuth2Client
|
|
29
27
|
from authlib.oauth2.rfc7636 import create_s256_code_challenge
|
|
30
28
|
|
|
31
|
-
from hcs_core.util.scheduler import ThreadPoolScheduler
|
|
32
|
-
|
|
33
29
|
log = logging.getLogger(__name__)
|
|
34
30
|
|
|
35
31
|
_server_address = ("127.0.0.1", 10762)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.285"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|