hcs-cli 0.1.330__py3-none-any.whl → 0.1.332__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.
- hcs_cli/__init__.py +1 -1
- hcs_cli/cmds/hoc/log.py +327 -0
- hcs_cli/cmds/hoc/search.py +11 -97
- hcs_cli/cmds/task.py +9 -4
- hcs_cli/cmds/vm/log.py +5 -4
- hcs_cli/service/hoc/es.py +7 -3
- hcs_cli/service/task.py +5 -3
- hcs_cli/support/exec_util.py +138 -1
- {hcs_cli-0.1.330.dist-info → hcs_cli-0.1.332.dist-info}/METADATA +2 -2
- {hcs_cli-0.1.330.dist-info → hcs_cli-0.1.332.dist-info}/RECORD +12 -16
- hcs_cli/cmds/hoc/connect.py +0 -24
- hcs_cli/cmds/hoc/oncall.py +0 -24
- hcs_cli/cmds/hoc/org.py +0 -24
- hcs_cli/cmds/hoc/template.py +0 -24
- hcs_cli/cmds/hoc/vm.py +0 -27
- {hcs_cli-0.1.330.dist-info → hcs_cli-0.1.332.dist-info}/WHEEL +0 -0
- {hcs_cli-0.1.330.dist-info → hcs_cli-0.1.332.dist-info}/entry_points.txt +0 -0
hcs_cli/__init__.py
CHANGED
hcs_cli/cmds/hoc/log.py
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright © 2025 Omnissa, LLC.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
import sys
|
|
8
|
+
from datetime import timezone
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
import click
|
|
12
|
+
import yumako
|
|
13
|
+
from hcs_core.ctxp import util
|
|
14
|
+
from hcs_core.sglib import cli_options as cli
|
|
15
|
+
|
|
16
|
+
from hcs_cli.service import hoc
|
|
17
|
+
from hcs_cli.support import predefined_payload
|
|
18
|
+
|
|
19
|
+
_hdcs = ["US", "EU", "JP"]
|
|
20
|
+
|
|
21
|
+
_regions = [
|
|
22
|
+
"eastus2",
|
|
23
|
+
"westus2",
|
|
24
|
+
"northcentralus",
|
|
25
|
+
"northeurope",
|
|
26
|
+
"germanywestcentral",
|
|
27
|
+
"uksouth",
|
|
28
|
+
"japaneast",
|
|
29
|
+
"australiaeast",
|
|
30
|
+
"centralindia",
|
|
31
|
+
]
|
|
32
|
+
_stacks = ["prod", "staging", "stress"]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@click.command()
|
|
36
|
+
@cli.org_id
|
|
37
|
+
@click.option(
|
|
38
|
+
"--from",
|
|
39
|
+
"from_param",
|
|
40
|
+
type=str,
|
|
41
|
+
required=False,
|
|
42
|
+
default="-24h",
|
|
43
|
+
help="Sepcify the from date. E.g. '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
44
|
+
)
|
|
45
|
+
@click.option(
|
|
46
|
+
"--to",
|
|
47
|
+
type=str,
|
|
48
|
+
required=False,
|
|
49
|
+
default="now",
|
|
50
|
+
help="Sepcify the to date. E.g. 'now', or '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
51
|
+
)
|
|
52
|
+
@click.option("--hdc", required=False, type=click.Choice(_hdcs, case_sensitive=False), help="The HDC location")
|
|
53
|
+
@click.option("--region", required=False, type=click.Choice(_regions, case_sensitive=False), help="The region")
|
|
54
|
+
@click.option("--stack", required=False, type=click.Choice(_stacks, case_sensitive=False), help="The stack")
|
|
55
|
+
@click.option(
|
|
56
|
+
"--service",
|
|
57
|
+
required=False,
|
|
58
|
+
help="Filter by kubernetes.pod_labels.app. If multiple apps, use comma to separate, e.g. --service inventory,lcm",
|
|
59
|
+
)
|
|
60
|
+
@click.option("--raw", is_flag=True, default=False, help="If raw, output the raw result.")
|
|
61
|
+
@click.argument("query", type=str, required=False)
|
|
62
|
+
def log(org: str, from_param: str, to: str, hdc: str, region: str, stack: str, service: str, raw: bool, query: str):
|
|
63
|
+
"""Search Kibana Log."""
|
|
64
|
+
|
|
65
|
+
# org_id = cli.get_org_id(org)
|
|
66
|
+
|
|
67
|
+
if not hdc:
|
|
68
|
+
hdc = "US"
|
|
69
|
+
else:
|
|
70
|
+
hdc = hdc.upper()
|
|
71
|
+
index_map = {
|
|
72
|
+
"US": "prod110-hdc-westus2-cp102-*",
|
|
73
|
+
# "US": "prod110-hdc-centralus-cp102-*",
|
|
74
|
+
"EU": "hoc-logs-eu-prod-*",
|
|
75
|
+
"JP": "hoc-logs-jp-prod-*",
|
|
76
|
+
"AUS": "",
|
|
77
|
+
"IND": "",
|
|
78
|
+
"GER": "",
|
|
79
|
+
"UK": "",
|
|
80
|
+
"US_APM": "prod110-hdc-westus2-cp102-*",
|
|
81
|
+
"EU_APM": "",
|
|
82
|
+
"JP_APM": "",
|
|
83
|
+
}
|
|
84
|
+
es_logs_search_index = index_map[hdc]
|
|
85
|
+
|
|
86
|
+
text = predefined_payload.load("hoc/logs.jsont")
|
|
87
|
+
replacements = {
|
|
88
|
+
"from": int(yumako.time.of(from_param, tz=timezone.utc).timestamp() * 1000),
|
|
89
|
+
"to": int(yumako.time.of(to, tz=timezone.utc).timestamp() * 1000),
|
|
90
|
+
"query": query or "",
|
|
91
|
+
"es_logs_search_index": es_logs_search_index,
|
|
92
|
+
}
|
|
93
|
+
try:
|
|
94
|
+
text = yumako.template.replace(
|
|
95
|
+
text=text,
|
|
96
|
+
mapping=replacements,
|
|
97
|
+
raise_on_unresolved_vars=True,
|
|
98
|
+
raise_on_unused_vars=True,
|
|
99
|
+
)
|
|
100
|
+
except ValueError as e:
|
|
101
|
+
return util.error_details(e), 1
|
|
102
|
+
|
|
103
|
+
parts = text.split("///", 2)
|
|
104
|
+
try:
|
|
105
|
+
first_line = json.loads(parts[0])
|
|
106
|
+
except Exception as e:
|
|
107
|
+
print(text, file=sys.stderr)
|
|
108
|
+
print(e, file=sys.stderr)
|
|
109
|
+
return
|
|
110
|
+
try:
|
|
111
|
+
second_line = json.loads(parts[1])
|
|
112
|
+
except Exception as e:
|
|
113
|
+
print(text, file=sys.stderr)
|
|
114
|
+
print(e, file=sys.stderr)
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
_update_query(second_line, any_apps=service)
|
|
118
|
+
|
|
119
|
+
payload_jsonp = json.dumps(first_line) + "\n" + json.dumps(second_line) + "\n"
|
|
120
|
+
|
|
121
|
+
hdc_location_mapping = {
|
|
122
|
+
# "US", "EU", "JP", "AUS", "IND", "GER", "UK", "US_APM", "EU_APM", "JP_APM"
|
|
123
|
+
"US": "US_APM",
|
|
124
|
+
"EU": "EU_APM",
|
|
125
|
+
"JP": "JP_APM",
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# print(payload_jsonp)
|
|
129
|
+
result = hoc.es.raw_query(payload_jsonp, hdc_location=hdc_location_mapping[hdc])
|
|
130
|
+
if raw:
|
|
131
|
+
return result
|
|
132
|
+
|
|
133
|
+
# format the result to pure message array
|
|
134
|
+
ret = []
|
|
135
|
+
for item in result:
|
|
136
|
+
message = item["message"]
|
|
137
|
+
parsed = _parse_message(message)
|
|
138
|
+
ret.append(parsed)
|
|
139
|
+
return ret
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# Pattern 1: LCM / service-gateway style
|
|
143
|
+
# "...INFO [163053][mplateMonitor-119158] c.v.h.servicegateway.lcm.utils.KopLog..."
|
|
144
|
+
_PATTERN_LCM = re.compile(
|
|
145
|
+
r"(?P<timestamp>\S+)"
|
|
146
|
+
r"\s+\[trace_id=(?P<trace_id>[^\]]*)\]"
|
|
147
|
+
r"\s+\[transaction_id=(?P<transaction_id>[^\]]*)\]"
|
|
148
|
+
r"\s+(?P<level>\S+)"
|
|
149
|
+
r"\s+\[(?P<thread_id>[^\]]*)\]\[(?P<thread_name>[^\]]*)\]"
|
|
150
|
+
r"\s+(?P<logger>\S+)"
|
|
151
|
+
r"\s+-\s+"
|
|
152
|
+
r"(?P<body>.*)",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Pattern 2: clouddriver style (single thread bracket after level)
|
|
156
|
+
# "...INFO [http-nio-8080-exec-6] c.v.horizon.sg.clouddriver..."
|
|
157
|
+
_PATTERN_CLOUDDRIVER = re.compile(
|
|
158
|
+
r"(?P<timestamp>\S+)"
|
|
159
|
+
r"\s+\[trace_id=(?P<trace_id>[^\]]*)\]"
|
|
160
|
+
r"\s+\[transaction_id=(?P<transaction_id>[^\]]*)\]"
|
|
161
|
+
r"\s+(?P<level>\S+)"
|
|
162
|
+
r"\s+\[(?P<thread_name>[^\]]*)\]"
|
|
163
|
+
r"\s+(?P<logger>\S+)"
|
|
164
|
+
r"\s+-\s+"
|
|
165
|
+
r"(?P<body>.*)",
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# Pattern 3: task-service style (thread bracket before level)
|
|
169
|
+
# "...[transaction_id=...] [tsch:iss-32521] INFO c.v.h.s.t.service.TaskService..."
|
|
170
|
+
_PATTERN_TASK = re.compile(
|
|
171
|
+
r"(?P<timestamp>\S+)"
|
|
172
|
+
r"\s+\[trace_id=(?P<trace_id>[^\]]*)\]"
|
|
173
|
+
r"\s+\[transaction_id=(?P<transaction_id>[^\]]*)\]"
|
|
174
|
+
r"\s+\[(?P<thread_name>[^\]]*)\]"
|
|
175
|
+
r"\s+(?P<level>\S+)"
|
|
176
|
+
r"\s+(?P<logger>\S+)"
|
|
177
|
+
r"\s+-\s+"
|
|
178
|
+
r"(?P<body>.*)",
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Pattern 4
|
|
182
|
+
# "2026-04-10 00:24:26,559 [http-nio-8080-exec-10] WARN co.elastic.apm.agent.impl.transaction.TraceState - sample rate already set to 1.0, trying to set it to 1.0 through header will be ignored"
|
|
183
|
+
_PATTERN_ELASTIC = re.compile(
|
|
184
|
+
r"(?P<timestamp>\S+\s\S+)" r"\s+\[(?P<thread_name>[^\]]*)\]" r"\s+(?P<level>\S+)" r"\s+(?P<logger>\S+)" r"\s+-\s+" r"(?P<body>.*)",
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Pattern 5: JSON structured log (apm-server style)
|
|
188
|
+
# "{\"log.level\":\"info\",\"@timestamp\":\"2026-04-10T00:24:26.596Z\",\"log.logger\":\"request\",...}"
|
|
189
|
+
_PATTERN_JSON_LOG = re.compile(r"\s*\{.*\"@timestamp\".*\}")
|
|
190
|
+
|
|
191
|
+
# Pattern 6: Envoy/Istio access log
|
|
192
|
+
# "[2026-04-10T00:24:25.684Z] \"POST /ad-twin/v1/... HTTP/1.1\" 200 ..."
|
|
193
|
+
_PATTERN_ENVOY = re.compile(
|
|
194
|
+
r"\[(?P<timestamp>[^\]]+)\]"
|
|
195
|
+
r"\s+\"(?P<method>\S+)\s+(?P<path>\S+)\s+(?P<protocol>[^\"]+)\""
|
|
196
|
+
r"\s+(?P<status_code>\d+)"
|
|
197
|
+
r"\s+(?P<body>.*)",
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# Pattern 7 & 8: portal/pool style (empty transaction_id bracket)
|
|
201
|
+
# "2026-04-10T00:27:57.372Z [trace_id=...] [] [kafka-consumer-listener-...] INFO c.v.h.p.handler..."
|
|
202
|
+
# "2026-04-10T00:27:57.376Z [trace_id=...] [] [http-nio-8080-exec-26] INFO c.v.h.portal.service..."
|
|
203
|
+
_PATTERN_PORTAL = re.compile(
|
|
204
|
+
r"(?P<timestamp>\S+)"
|
|
205
|
+
r"\s+\[trace_id=(?P<trace_id>[^\]]*)\]"
|
|
206
|
+
r"\s+\[(?P<transaction_id>[^\]]*)\]"
|
|
207
|
+
r"\s+\[(?P<thread_name>[^\]]*)\]"
|
|
208
|
+
r"\s+(?P<level>\S+)"
|
|
209
|
+
r"\s+(?P<logger>\S+)"
|
|
210
|
+
r"\s+-\s+"
|
|
211
|
+
r"(?P<body>.*)",
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# Pattern 9: Spring Boot style (--- separator)
|
|
215
|
+
# "2026-04-10 00:29:34.037 INFO 8 --- [istenerId-0-C-1] c.v.h.a.f.kafka.KafkaConsumerService : Created ..."
|
|
216
|
+
_PATTERN_SPRING = re.compile(
|
|
217
|
+
r"(?P<timestamp>\S+\s\S+)"
|
|
218
|
+
r"\s+(?P<level>\S+)"
|
|
219
|
+
r"\s+\S+"
|
|
220
|
+
r"\s+---"
|
|
221
|
+
r"\s+\[(?P<thread_name>[^\]]*)\]"
|
|
222
|
+
r"\s+(?P<logger>\S+)"
|
|
223
|
+
r"\s+:\s+"
|
|
224
|
+
r"(?P<body>.*)",
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
_PATTERNS = [_PATTERN_LCM, _PATTERN_CLOUDDRIVER, _PATTERN_TASK, _PATTERN_ELASTIC, _PATTERN_ENVOY, _PATTERN_PORTAL, _PATTERN_SPRING]
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _parse_message(message: str) -> dict:
|
|
231
|
+
if _PATTERN_JSON_LOG.match(message):
|
|
232
|
+
try:
|
|
233
|
+
obj = json.loads(message)
|
|
234
|
+
return {
|
|
235
|
+
"timestamp": obj.get("@timestamp", ""),
|
|
236
|
+
"level": obj.get("log.level", ""),
|
|
237
|
+
"logger": obj.get("log.logger", ""),
|
|
238
|
+
"body": obj.get("message", ""),
|
|
239
|
+
}
|
|
240
|
+
except json.JSONDecodeError:
|
|
241
|
+
pass
|
|
242
|
+
for pattern in _PATTERNS:
|
|
243
|
+
m = pattern.match(message)
|
|
244
|
+
if m:
|
|
245
|
+
return m.groupdict()
|
|
246
|
+
return {"body": message}
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _update_query(query_object: dict, any_apps: Optional[str]) -> dict:
|
|
250
|
+
# Example query object: query string "KOP" and "V1-CUSFP0101I", time range, and kubernetes.pod_labels.app=lcm
|
|
251
|
+
# {
|
|
252
|
+
# "query": {
|
|
253
|
+
# "bool": {
|
|
254
|
+
# "must": [],
|
|
255
|
+
# "filter": [
|
|
256
|
+
# {
|
|
257
|
+
# "bool": {
|
|
258
|
+
# "filter": [
|
|
259
|
+
# {
|
|
260
|
+
# "multi_match": {
|
|
261
|
+
# "type": "phrase",
|
|
262
|
+
# "query": "KOP",
|
|
263
|
+
# "lenient": true
|
|
264
|
+
# }
|
|
265
|
+
# },
|
|
266
|
+
# {
|
|
267
|
+
# "multi_match": {
|
|
268
|
+
# "type": "phrase",
|
|
269
|
+
# "query": "V1-CUSFP0101I",
|
|
270
|
+
# "lenient": true
|
|
271
|
+
# }
|
|
272
|
+
# }
|
|
273
|
+
# ]
|
|
274
|
+
# }
|
|
275
|
+
# },
|
|
276
|
+
# {
|
|
277
|
+
# "range": {
|
|
278
|
+
# "timestamp": {
|
|
279
|
+
# "format": "strict_date_optional_time",
|
|
280
|
+
# "gte": "2026-04-09T22:42:54.486Z",
|
|
281
|
+
# "lte": "2026-04-09T22:47:54.486Z"
|
|
282
|
+
# }
|
|
283
|
+
# }
|
|
284
|
+
# },
|
|
285
|
+
# {
|
|
286
|
+
# "match_phrase": {
|
|
287
|
+
# "kubernetes.pod_labels.app": "lcm"
|
|
288
|
+
# }
|
|
289
|
+
# }
|
|
290
|
+
# ],
|
|
291
|
+
# "should": [],
|
|
292
|
+
# "must_not": []
|
|
293
|
+
# }
|
|
294
|
+
# }
|
|
295
|
+
# }
|
|
296
|
+
|
|
297
|
+
# example of the last match condition, if there are multiple app specified (is one of):
|
|
298
|
+
# {
|
|
299
|
+
# "bool": {
|
|
300
|
+
# "minimum_should_match": 1,
|
|
301
|
+
# "should": [
|
|
302
|
+
# {
|
|
303
|
+
# "match_phrase": {
|
|
304
|
+
# "kubernetes.pod_labels.app": "clouddriver"
|
|
305
|
+
# }
|
|
306
|
+
# },
|
|
307
|
+
# {
|
|
308
|
+
# "match_phrase": {
|
|
309
|
+
# "kubernetes.pod_labels.app": "lcm"
|
|
310
|
+
# }
|
|
311
|
+
# }
|
|
312
|
+
# ]
|
|
313
|
+
# }
|
|
314
|
+
# }
|
|
315
|
+
|
|
316
|
+
filter_array = query_object["query"]["bool"]["filter"]
|
|
317
|
+
|
|
318
|
+
if any_apps:
|
|
319
|
+
apps = [a.strip() for a in any_apps.split(",") if a.strip()]
|
|
320
|
+
if len(apps) == 1:
|
|
321
|
+
filter_array.append({"match_phrase": {"kubernetes.pod_labels.app": apps[0]}})
|
|
322
|
+
elif len(apps) > 1:
|
|
323
|
+
filter_array.append(
|
|
324
|
+
{"bool": {"minimum_should_match": 1, "should": [{"match_phrase": {"kubernetes.pod_labels.app": app}} for app in apps]}}
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
return query_object
|
hcs_cli/cmds/hoc/search.py
CHANGED
|
@@ -36,6 +36,17 @@ def _formalize_query_string(input_str):
|
|
|
36
36
|
return " ".join(parts).strip()
|
|
37
37
|
|
|
38
38
|
|
|
39
|
+
def _parse_kv_args(arg_list: list[str]) -> dict[str, str]:
|
|
40
|
+
result = {}
|
|
41
|
+
for arg in arg_list:
|
|
42
|
+
if "=" not in arg:
|
|
43
|
+
raise ValueError(f"Invalid argument: {arg}. Expected format: key=value")
|
|
44
|
+
key, value = arg.split("=", 1)
|
|
45
|
+
key = key.strip()
|
|
46
|
+
result[key] = value.strip()
|
|
47
|
+
return result
|
|
48
|
+
|
|
49
|
+
|
|
39
50
|
@click.command()
|
|
40
51
|
@cli.org_id
|
|
41
52
|
@click.option(
|
|
@@ -167,100 +178,3 @@ def es(org: str, from_param: str, to: str, file, raw: bool, predefined: str, arg
|
|
|
167
178
|
|
|
168
179
|
print(payload_jsonp)
|
|
169
180
|
return hoc.es.raw_query(payload_jsonp)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
_hdcs = ["US", "EU", "JP"]
|
|
173
|
-
_regions = [
|
|
174
|
-
"eastus2",
|
|
175
|
-
"westus2",
|
|
176
|
-
"northcentralus",
|
|
177
|
-
"northeurope",
|
|
178
|
-
"germanywestcentral",
|
|
179
|
-
"uksouth",
|
|
180
|
-
"japaneast",
|
|
181
|
-
"australiaeast",
|
|
182
|
-
"centralindia",
|
|
183
|
-
]
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
@click.command()
|
|
187
|
-
@cli.org_id
|
|
188
|
-
@click.option(
|
|
189
|
-
"--from",
|
|
190
|
-
"from_param",
|
|
191
|
-
type=str,
|
|
192
|
-
required=False,
|
|
193
|
-
default="-12h",
|
|
194
|
-
help="Sepcify the from date. E.g. '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
195
|
-
)
|
|
196
|
-
@click.option(
|
|
197
|
-
"--to",
|
|
198
|
-
type=str,
|
|
199
|
-
required=False,
|
|
200
|
-
default="now",
|
|
201
|
-
help="Sepcify the to date. E.g. 'now', or '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
202
|
-
)
|
|
203
|
-
@click.option("--hdc", required=False, type=click.Choice(_hdcs, case_sensitive=False), help="The HDC location")
|
|
204
|
-
@click.option("--region", required=False, type=click.Choice(_regions, case_sensitive=False), help="The HDC location")
|
|
205
|
-
@click.argument("query", type=str, required=False)
|
|
206
|
-
def logs(org: str, from_param: str, to: str, hdc: str, region: str, query: str):
|
|
207
|
-
"""Perform a raw ES query for HCS logs."""
|
|
208
|
-
|
|
209
|
-
# org_id = cli.get_org_id(org)
|
|
210
|
-
|
|
211
|
-
if not hdc:
|
|
212
|
-
hdc = "US"
|
|
213
|
-
else:
|
|
214
|
-
hdc = hdc.upper()
|
|
215
|
-
index_map = {
|
|
216
|
-
"US": "prod110-hdc-centralus-cp102-*",
|
|
217
|
-
"EU": "hoc-logs-eu-prod-*",
|
|
218
|
-
"JP": "hoc-logs-jp-prod-*",
|
|
219
|
-
}
|
|
220
|
-
es_logs_search_index = index_map[hdc]
|
|
221
|
-
|
|
222
|
-
text = predefined_payload.load("hoc/logs.jsont")
|
|
223
|
-
replacements = {
|
|
224
|
-
"from": int(yumako.time.of(from_param, tz=timezone.utc).timestamp() * 1000),
|
|
225
|
-
"to": int(yumako.time.of(to, tz=timezone.utc).timestamp() * 1000),
|
|
226
|
-
"query": query if query else "",
|
|
227
|
-
"es_logs_search_index": es_logs_search_index,
|
|
228
|
-
}
|
|
229
|
-
try:
|
|
230
|
-
text = yumako.template.replace(
|
|
231
|
-
text=text,
|
|
232
|
-
mapping=replacements,
|
|
233
|
-
raise_on_unresolved_vars=True,
|
|
234
|
-
raise_on_unused_vars=True,
|
|
235
|
-
)
|
|
236
|
-
except ValueError as e:
|
|
237
|
-
return util.error_details(e), 1
|
|
238
|
-
|
|
239
|
-
parts = text.split("///", 2)
|
|
240
|
-
try:
|
|
241
|
-
first_line = json.loads(parts[0])
|
|
242
|
-
except Exception as e:
|
|
243
|
-
print(text, file=sys.stderr)
|
|
244
|
-
print(e, file=sys.stderr)
|
|
245
|
-
return
|
|
246
|
-
try:
|
|
247
|
-
second_line = json.loads(parts[1])
|
|
248
|
-
except Exception as e:
|
|
249
|
-
print(text, file=sys.stderr)
|
|
250
|
-
print(e, file=sys.stderr)
|
|
251
|
-
return
|
|
252
|
-
payload_jsonp = json.dumps(first_line) + "\n" + json.dumps(second_line) + "\n"
|
|
253
|
-
|
|
254
|
-
print(payload_jsonp)
|
|
255
|
-
return hoc.es.raw_query(payload_jsonp)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
def _parse_kv_args(arg_list: list[str]) -> dict[str, str]:
|
|
259
|
-
result = {}
|
|
260
|
-
for arg in arg_list:
|
|
261
|
-
if "=" not in arg:
|
|
262
|
-
raise ValueError(f"Invalid argument: {arg}. Expected format: key=value")
|
|
263
|
-
key, value = arg.split("=", 1)
|
|
264
|
-
key = key.strip()
|
|
265
|
-
result[key] = value.strip()
|
|
266
|
-
return result
|
hcs_cli/cmds/task.py
CHANGED
|
@@ -495,12 +495,15 @@ def list_tasks(
|
|
|
495
495
|
@cli.org_id
|
|
496
496
|
@click.option("--namespace", "-n", type=str, required=False)
|
|
497
497
|
@click.option("--group", "-g", type=str, required=False)
|
|
498
|
+
@click.option(
|
|
499
|
+
"--location", hidden=True, type=str, required=False, help="Task location, only for global scheduler. E.g. US, JP, IN, AU, DE, IE."
|
|
500
|
+
) # to be removed later
|
|
498
501
|
@click.argument("smart_path", type=str, required=False)
|
|
499
|
-
def get(org: str, namespace: str, group: str, smart_path: str, **kwargs):
|
|
502
|
+
def get(org: str, namespace: str, group: str, location: str, smart_path: str, **kwargs):
|
|
500
503
|
"""Get a task. E.g. 'task get [[<namespace>/]<group>/]<key>'."""
|
|
501
504
|
namespace, group, key = _parse_task_param(namespace, group, smart_path)
|
|
502
505
|
org_id = cli.get_org_id(org)
|
|
503
|
-
return task.get(org_id, namespace, group, key, **kwargs)
|
|
506
|
+
return task.get(org_id, namespace, group, key, location=location, **kwargs)
|
|
504
507
|
|
|
505
508
|
|
|
506
509
|
@task_cmd_group.command()
|
|
@@ -551,7 +554,9 @@ def get_logs(org: str, namespace: str, group: str, smart_path: str, last: bool,
|
|
|
551
554
|
if state and last:
|
|
552
555
|
return "--state cannot be used with --last.", 1
|
|
553
556
|
|
|
554
|
-
if
|
|
557
|
+
if last and org is None:
|
|
558
|
+
org_id = cli.get_org_id(org)
|
|
559
|
+
elif org == "all" or org is None:
|
|
555
560
|
org_id = None
|
|
556
561
|
else:
|
|
557
562
|
org_id = cli.get_org_id(org)
|
|
@@ -568,7 +573,7 @@ def get_logs(org: str, namespace: str, group: str, smart_path: str, last: bool,
|
|
|
568
573
|
search = state_search
|
|
569
574
|
|
|
570
575
|
if last:
|
|
571
|
-
t = task.last(org_id, namespace, group, key
|
|
576
|
+
t = task.last(org_id, namespace, group, key)
|
|
572
577
|
if t:
|
|
573
578
|
return t.log
|
|
574
579
|
else:
|
hcs_cli/cmds/vm/log.py
CHANGED
|
@@ -28,7 +28,7 @@ _DCT_FAILED = frozenset({"ERROR", "EXPIRED"})
|
|
|
28
28
|
help="Whether to recreate the log if it already exists. By default, it will not recreate the log and just return the existing log.",
|
|
29
29
|
)
|
|
30
30
|
@click.option(
|
|
31
|
-
"--
|
|
31
|
+
"--verbose", is_flag=True, default=False, help="Whether to print progress messages. By default, it will print progress messages."
|
|
32
32
|
)
|
|
33
33
|
@click.option(
|
|
34
34
|
"--save-as",
|
|
@@ -39,15 +39,13 @@ _DCT_FAILED = frozenset({"ERROR", "EXPIRED"})
|
|
|
39
39
|
)
|
|
40
40
|
@click.argument("vm_path", type=str, required=False)
|
|
41
41
|
@cli.org_id
|
|
42
|
-
def log(recreate: bool,
|
|
42
|
+
def log(recreate: bool, verbose: bool, save_path, vm_path: str, org: str, **kwargs):
|
|
43
43
|
"""Download VM DCT log"""
|
|
44
44
|
org_id = cli.get_org_id(org)
|
|
45
45
|
template_id, vm_id = parse_vm_path(vm_path)
|
|
46
46
|
|
|
47
47
|
is_ops = has_any_permission(["sgadm:supportw", "sgadm:supportlog", "sgadm:service", "sgadm:support"])
|
|
48
48
|
|
|
49
|
-
verbose = not silent
|
|
50
|
-
|
|
51
49
|
dct_info = dct_service.latest(org_id, template_id, vm_id, is_ops)
|
|
52
50
|
if not dct_info:
|
|
53
51
|
if verbose:
|
|
@@ -102,6 +100,9 @@ def log(recreate: bool, silent: bool, save_path, vm_path: str, org: str, **kwarg
|
|
|
102
100
|
return f"Failed to download archive: {e}", 1
|
|
103
101
|
|
|
104
102
|
dct_info["file_path"] = file_path
|
|
103
|
+
|
|
104
|
+
if verbose:
|
|
105
|
+
click.secho("----- DCT log downloaded -----", fg="bright_black")
|
|
105
106
|
return dct_info
|
|
106
107
|
|
|
107
108
|
|
hcs_cli/service/hoc/es.py
CHANGED
|
@@ -46,6 +46,7 @@ def query(
|
|
|
46
46
|
to_date: Union[str, datetime] = "now",
|
|
47
47
|
template_file: str = None,
|
|
48
48
|
template: str = None,
|
|
49
|
+
hdc_location: str = None,
|
|
49
50
|
**kwargs,
|
|
50
51
|
):
|
|
51
52
|
if template_file:
|
|
@@ -87,8 +88,11 @@ def query(
|
|
|
87
88
|
raise e
|
|
88
89
|
|
|
89
90
|
payload_jsonp = json.dumps(payload_type) + "\n" + json.dumps(payload_query) + "\n"
|
|
90
|
-
return raw_query(payload_jsonp)
|
|
91
|
+
return raw_query(payload_jsonp, hdc_location=hdc_location)
|
|
91
92
|
|
|
92
93
|
|
|
93
|
-
def raw_query(payload_jsonp: str):
|
|
94
|
-
|
|
94
|
+
def raw_query(payload_jsonp: str, hdc_location: str = None):
|
|
95
|
+
url = "/v1/data/query/search"
|
|
96
|
+
if hdc_location:
|
|
97
|
+
url = f"/v1/data/query/search?hdcLocation={hdc_location}"
|
|
98
|
+
return _client.post(url, text=payload_jsonp)
|
hcs_cli/service/task.py
CHANGED
|
@@ -312,7 +312,7 @@ def _get_v1(namespace: str, group: str, key: str) -> Optional[TaskModel]:
|
|
|
312
312
|
return t
|
|
313
313
|
|
|
314
314
|
|
|
315
|
-
def _get_v2(org_id: str, namespace: str, group: str, key: str) -> Optional[TaskModel]:
|
|
315
|
+
def _get_v2(org_id: str, namespace: str, group: str, key: str, location: str = None) -> Optional[TaskModel]:
|
|
316
316
|
url = f"/v1/tasks/{key}?"
|
|
317
317
|
if org_id:
|
|
318
318
|
url += f"&orgId={org_id}"
|
|
@@ -320,6 +320,8 @@ def _get_v2(org_id: str, namespace: str, group: str, key: str) -> Optional[TaskM
|
|
|
320
320
|
url += f"&namespace={namespace}"
|
|
321
321
|
if group:
|
|
322
322
|
url += f"&group={group}"
|
|
323
|
+
if location:
|
|
324
|
+
url += f"&location={location}"
|
|
323
325
|
t = _scm_client.get(url, type=TaskModel)
|
|
324
326
|
if not t:
|
|
325
327
|
return
|
|
@@ -333,14 +335,14 @@ def get(org_id: str, namespace: str, group: str, key: str, **kwargs) -> Optional
|
|
|
333
335
|
t = _get_v1(namespace, group, key)
|
|
334
336
|
t.log = _lastlog(org_id, namespace, group, key)
|
|
335
337
|
elif version == "v2":
|
|
336
|
-
t = _get_v2(org_id, namespace, group, key)
|
|
338
|
+
t = _get_v2(org_id, namespace, group, key, location=kwargs.get("location"))
|
|
337
339
|
else:
|
|
338
340
|
t = _get_v1(namespace, group, key)
|
|
339
341
|
if t:
|
|
340
342
|
t.log = _lastlog(org_id, namespace, group, key)
|
|
341
343
|
_task_temp_lru[_k] = "v1"
|
|
342
344
|
else:
|
|
343
|
-
t = _get_v2(org_id, namespace, group, key)
|
|
345
|
+
t = _get_v2(org_id, namespace, group, key, location=kwargs.get("location"))
|
|
344
346
|
if t:
|
|
345
347
|
_task_temp_lru[_k] = "v2"
|
|
346
348
|
|
hcs_cli/support/exec_util.py
CHANGED
|
@@ -2,7 +2,8 @@ import json
|
|
|
2
2
|
import os
|
|
3
3
|
import shlex
|
|
4
4
|
import subprocess
|
|
5
|
-
|
|
5
|
+
import threading
|
|
6
|
+
from typing import Any, List, Optional, Tuple, Union
|
|
6
7
|
|
|
7
8
|
import click
|
|
8
9
|
|
|
@@ -17,6 +18,13 @@ def _split_command(cmd: Union[str, List[str]]) -> Tuple[List[str], str]:
|
|
|
17
18
|
raise TypeError("cmd must be a string or a list of strings")
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
# ANSI bright black / grey (same family as click.style(..., fg="bright_black"))
|
|
22
|
+
_STREAM_GREY = b"\x1b[90m"
|
|
23
|
+
# Yellow (same family as click.style(..., fg="yellow"))
|
|
24
|
+
_STREAM_YELLOW = b"\x1b[33m"
|
|
25
|
+
_STREAM_RESET = b"\x1b[0m"
|
|
26
|
+
|
|
27
|
+
|
|
20
28
|
def exec(
|
|
21
29
|
cmd,
|
|
22
30
|
log_error=True,
|
|
@@ -102,3 +110,132 @@ def run_cli(
|
|
|
102
110
|
input=input,
|
|
103
111
|
show_command=show_command,
|
|
104
112
|
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def stream_cli(
|
|
116
|
+
cmd: str,
|
|
117
|
+
raise_on_error=True,
|
|
118
|
+
input: Union[str, dict[Any, Any], list[Any]] = None,
|
|
119
|
+
show_command: bool = True,
|
|
120
|
+
env: dict = None,
|
|
121
|
+
color: Optional[bool] = None,
|
|
122
|
+
) -> str:
|
|
123
|
+
"""Run ``hcs ...``, stream stdout and stderr as they arrive, return full stdout text.
|
|
124
|
+
|
|
125
|
+
Uses unbuffered binary reads from the pipes so data is forwarded as the OS delivers it
|
|
126
|
+
(``text=True`` would wrap pipes in a buffered ``TextIOWrapper`` and can delay reads).
|
|
127
|
+
|
|
128
|
+
The child ``hcs`` process is Python: ``PYTHONUNBUFFERED=1`` is set so its stdout is not
|
|
129
|
+
block-buffered when piped. If ``input`` is omitted, stdin is ``DEVNULL`` so the subprocess
|
|
130
|
+
does not inherit the parent's stdin and block waiting for input; otherwise stdin is a pipe
|
|
131
|
+
and the given payload is written (dict/list are JSON-encoded, same as :func:`exec`).
|
|
132
|
+
|
|
133
|
+
Output is written with :func:`click.get_binary_stream` so it matches what :func:`click.echo`
|
|
134
|
+
uses (not always identical to :data:`sys.stdout`).
|
|
135
|
+
|
|
136
|
+
ANSI wrapping (grey on stdout, yellow on stderr): if ``color`` is ``True`` or ``False``,
|
|
137
|
+
that choice always wins. If ``color`` is omitted (``None``), wrapping is applied per stream
|
|
138
|
+
only when that stream is a TTY (same as :meth:`~io.IOBase.isatty` on the binary stream).
|
|
139
|
+
"""
|
|
140
|
+
child_env = os.environ.copy()
|
|
141
|
+
child_env["HCS_CLI_CHECK_UPGRADE"] = "false"
|
|
142
|
+
child_env["PYTHONUNBUFFERED"] = "1"
|
|
143
|
+
if env:
|
|
144
|
+
child_env.update(env)
|
|
145
|
+
|
|
146
|
+
commands, cmd_text = _split_command(cmd)
|
|
147
|
+
if show_command:
|
|
148
|
+
text = f"RUNNING: {cmd_text}"
|
|
149
|
+
if input:
|
|
150
|
+
text += " <input-redacted>"
|
|
151
|
+
click.echo(click.style(text, fg="bright_black"))
|
|
152
|
+
|
|
153
|
+
stdin_bytes: Union[bytes, None] = None
|
|
154
|
+
if input is not None:
|
|
155
|
+
if isinstance(input, dict) or isinstance(input, list):
|
|
156
|
+
stdin_bytes = json.dumps(input).encode("utf-8")
|
|
157
|
+
else:
|
|
158
|
+
stdin_bytes = str(input).encode("utf-8")
|
|
159
|
+
|
|
160
|
+
parts: list[bytes] = []
|
|
161
|
+
proc = subprocess.Popen(
|
|
162
|
+
commands,
|
|
163
|
+
stdout=subprocess.PIPE,
|
|
164
|
+
stderr=subprocess.PIPE,
|
|
165
|
+
stdin=subprocess.PIPE if stdin_bytes is not None else subprocess.DEVNULL,
|
|
166
|
+
env=child_env,
|
|
167
|
+
bufsize=0,
|
|
168
|
+
)
|
|
169
|
+
assert proc.stdout is not None
|
|
170
|
+
assert proc.stderr is not None
|
|
171
|
+
|
|
172
|
+
out_bin = click.get_binary_stream("stdout")
|
|
173
|
+
err_bin = click.get_binary_stream("stderr")
|
|
174
|
+
|
|
175
|
+
try:
|
|
176
|
+
stdout_is_tty = out_bin.isatty()
|
|
177
|
+
except OSError:
|
|
178
|
+
stdout_is_tty = False
|
|
179
|
+
try:
|
|
180
|
+
stderr_is_tty = err_bin.isatty()
|
|
181
|
+
except OSError:
|
|
182
|
+
stderr_is_tty = False
|
|
183
|
+
|
|
184
|
+
if color is None:
|
|
185
|
+
wrap_stdout = stdout_is_tty
|
|
186
|
+
wrap_stderr = stderr_is_tty
|
|
187
|
+
else:
|
|
188
|
+
wrap_stdout = color
|
|
189
|
+
wrap_stderr = color
|
|
190
|
+
|
|
191
|
+
def pump_stdin() -> None:
|
|
192
|
+
assert proc.stdin is not None
|
|
193
|
+
try:
|
|
194
|
+
if stdin_bytes is not None:
|
|
195
|
+
proc.stdin.write(stdin_bytes)
|
|
196
|
+
proc.stdin.flush()
|
|
197
|
+
finally:
|
|
198
|
+
proc.stdin.close()
|
|
199
|
+
|
|
200
|
+
def pump_stdout() -> None:
|
|
201
|
+
try:
|
|
202
|
+
while True:
|
|
203
|
+
chunk = proc.stdout.read(4096)
|
|
204
|
+
if not chunk:
|
|
205
|
+
break
|
|
206
|
+
out = (_STREAM_GREY + chunk + _STREAM_RESET) if wrap_stdout else chunk
|
|
207
|
+
out_bin.write(out)
|
|
208
|
+
out_bin.flush()
|
|
209
|
+
parts.append(out)
|
|
210
|
+
finally:
|
|
211
|
+
proc.stdout.close()
|
|
212
|
+
|
|
213
|
+
def pump_stderr() -> None:
|
|
214
|
+
try:
|
|
215
|
+
while True:
|
|
216
|
+
chunk = proc.stderr.read(4096)
|
|
217
|
+
if not chunk:
|
|
218
|
+
break
|
|
219
|
+
out = (_STREAM_YELLOW + chunk + _STREAM_RESET) if wrap_stderr else chunk
|
|
220
|
+
err_bin.write(out)
|
|
221
|
+
err_bin.flush()
|
|
222
|
+
finally:
|
|
223
|
+
proc.stderr.close()
|
|
224
|
+
|
|
225
|
+
threads: list[threading.Thread] = []
|
|
226
|
+
if stdin_bytes is not None:
|
|
227
|
+
threads.append(threading.Thread(target=pump_stdin))
|
|
228
|
+
threads.extend(
|
|
229
|
+
[
|
|
230
|
+
threading.Thread(target=pump_stdout),
|
|
231
|
+
threading.Thread(target=pump_stderr),
|
|
232
|
+
]
|
|
233
|
+
)
|
|
234
|
+
for t in threads:
|
|
235
|
+
t.start()
|
|
236
|
+
for t in threads:
|
|
237
|
+
t.join()
|
|
238
|
+
rc = proc.wait()
|
|
239
|
+
if rc != 0 and raise_on_error:
|
|
240
|
+
raise click.ClickException(f"Command '{cmd_text}' failed with return code {rc}.")
|
|
241
|
+
return b"".join(parts).decode("utf-8", errors="replace")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hcs-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.332
|
|
4
4
|
Summary: Horizon Cloud Service CLI.
|
|
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
|
|
@@ -14,7 +14,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
16
|
Requires-Python: >=3.9
|
|
17
|
-
Requires-Dist: hcs-core>=0.1.
|
|
17
|
+
Requires-Dist: hcs-core>=0.1.332
|
|
18
18
|
Requires-Dist: inquirerpy>=0.3.4
|
|
19
19
|
Requires-Dist: matplotlib>=3.8.0
|
|
20
20
|
Requires-Dist: paho-mqtt>=2.1.0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
hcs_cli/__init__.py,sha256=
|
|
1
|
+
hcs_cli/__init__.py,sha256=nPvtkDDB3R6Uz-e6LUQVWGRnxx8UYe4qTvGgMXtbZow,72
|
|
2
2
|
hcs_cli/__main__.py,sha256=mReIxxxuvlcxzSdPfIgptZ_Qkrg0MPOgT37utukr65g,125
|
|
3
3
|
hcs_cli/main.py,sha256=CzGoya6yabf5akJ3l0gEzxBmMKznIhxGRXbsngtuPWc,3014
|
|
4
4
|
hcs_cli/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -7,7 +7,7 @@ hcs_cli/cmds/inspect.py,sha256=QBhBOkf2mHlGhgAhY9FXCfvViL2p4D3BudoKjyADdfE,659
|
|
|
7
7
|
hcs_cli/cmds/login.py,sha256=0j2VA4cy2pgy6-Rm3ys9JMKHbyrdvCS8tw3LdijM9gk,10606
|
|
8
8
|
hcs_cli/cmds/logout.py,sha256=FDYXnie1jytnEsFj-XuVSU4sZL9VPzaLO1KHFProX4g,185
|
|
9
9
|
hcs_cli/cmds/query.py,sha256=hh1TVeSkvRiB07fqIA3GGpEBtP3XMz5XCmAGTXD7FOM,9302
|
|
10
|
-
hcs_cli/cmds/task.py,sha256=
|
|
10
|
+
hcs_cli/cmds/task.py,sha256=N9EYRGoTtCVF2yktD0bmSlugGykRaysdwjNoT2al9jY,29037
|
|
11
11
|
hcs_cli/cmds/test.py,sha256=rBFbcpUtwxxm6thl7uZGqmZTyCyFRpMO-xa7wExEhuM,755
|
|
12
12
|
hcs_cli/cmds/upgrade.py,sha256=p1QKlacY5kPIQecN6sFRDXgS-_HrsGu_0Hjb1DXbjgI,377
|
|
13
13
|
hcs_cli/cmds/ad/__init__.py,sha256=oB4WrRdC96cMS2OXs-1ITr8U_3ylI3QQNKZk51KsMJI,82
|
|
@@ -113,13 +113,9 @@ hcs_cli/cmds/entitlement/delete.py,sha256=fcdpVtZKpDdEZ9TS11r6OwwbNOVeBIf0bjpK6n
|
|
|
113
113
|
hcs_cli/cmds/entitlement/get.py,sha256=Ia4eG3Kh6plXc3f94MtrRC9g27U3Z4xHSqsB4Et3cRw,477
|
|
114
114
|
hcs_cli/cmds/entitlement/list.py,sha256=xCahx0Sr4r5w2rhI9eBNmYPsc0NHEbivApLNcvuWTZY,420
|
|
115
115
|
hcs_cli/cmds/hoc/__init__.py,sha256=OL0_-lSzNCCDefv2m_DIkUAvTnA2qDbLtUdPsN9lsPk,128
|
|
116
|
-
hcs_cli/cmds/hoc/
|
|
117
|
-
hcs_cli/cmds/hoc/
|
|
118
|
-
hcs_cli/cmds/hoc/org.py,sha256=fi2rjO4hLuJuLSinWG3s8-dTdAj9EIrIFcN82LM8mtI,570
|
|
119
|
-
hcs_cli/cmds/hoc/search.py,sha256=TrmuXd0_Mr7HlQouktjdgUq9I2WJgeg2nfpB4nxXddA,7972
|
|
116
|
+
hcs_cli/cmds/hoc/log.py,sha256=dDMm4kqoVUCdz9zrVwE9xX1vpbejCr-m4W_IAC9yT_M,10518
|
|
117
|
+
hcs_cli/cmds/hoc/search.py,sha256=YNFRiNXqNQNYOC8QfocXDJTZeLOmNMgmmkGcPOGqG-E,5513
|
|
120
118
|
hcs_cli/cmds/hoc/stats.py,sha256=QEnAULDIhvsEgMLJg4Ql9cI6wUqd0zQW2QjwBWwXdno,2641
|
|
121
|
-
hcs_cli/cmds/hoc/template.py,sha256=M9bPYDuPfYQjjR8SYS4r4NknckSAfrMJGW6GeczCZvw,574
|
|
122
|
-
hcs_cli/cmds/hoc/vm.py,sha256=YjijTxpSbnUKyCtsc9wIYDYZULM4RKo2JfROdilmNvk,664
|
|
123
119
|
hcs_cli/cmds/hoc/util/__init__.py,sha256=AC-hl0F-5R4V2uejk5FzFDlvT7uKGfjQyWq0quSznQs,14
|
|
124
120
|
hcs_cli/cmds/hoc/util/inv_cache.py,sha256=p1Y2MLlzdVvcmWUyBN-55X0irqTihjgGTgRGF-diw4Q,398
|
|
125
121
|
hcs_cli/cmds/hst/__init__.py,sha256=tAbpunGkAG0fBOaOBQybQzv9r6Ij7kgp4SWUpBEB1e0,119
|
|
@@ -284,7 +280,7 @@ hcs_cli/cmds/vm/actions.py,sha256=PdwqGc8rjX7QabhnTZR6do4NaGjvDZotx22LeiE1HJw,33
|
|
|
284
280
|
hcs_cli/cmds/vm/delete.py,sha256=n6e4pPc26nujJN93bwFBE4rV00hNJZEQhlRMdakJwLU,934
|
|
285
281
|
hcs_cli/cmds/vm/get.py,sha256=IJqxnuIXEBTDxBS2-SbqNFU-sKKn0tzOX5blaVFpxrU,483
|
|
286
282
|
hcs_cli/cmds/vm/list.py,sha256=tMFs7VcVE-7MphtiqTlwGP41JWjIsbFnQFc0wHKF-J0,6044
|
|
287
|
-
hcs_cli/cmds/vm/log.py,sha256=
|
|
283
|
+
hcs_cli/cmds/vm/log.py,sha256=ejWr_7KGIOnbFEFCIJsO1DE42eqDJR1199FCovtb_Ws,5316
|
|
288
284
|
hcs_cli/cmds/vm/pairing_info.py,sha256=Oq4bXWXj_GP_ejnK5fouc7928PDFk11-vGUjRXQnT6w,623
|
|
289
285
|
hcs_cli/cmds/vm/put.py,sha256=bOqwdEVqI3_6F6C_3WH7P4PZP0iAhkJmm6Y9RHBVgl8,645
|
|
290
286
|
hcs_cli/cmds/vm/use.py,sha256=EONJqWcF176tUyQ9OnkSpR92HBzTgFNwB__Dt10WAVU,1276
|
|
@@ -402,7 +398,7 @@ hcs_cli/service/edge.py,sha256=YN5uWrXKARfuOnqCKZQYCVP2BrNiAEDdS2AIIAgQdEo,3714
|
|
|
402
398
|
hcs_cli/service/graphql.py,sha256=Vqt4wMeRSPV_2YhGvb9vs0vlac0_fMAhg1BijKX6reg,468
|
|
403
399
|
hcs_cli/service/pool.py,sha256=aWdW0bRGlE58z95HvdSs7i8kwM79_dzqsrGjtnLv7lA,712
|
|
404
400
|
hcs_cli/service/site.py,sha256=CMKMAhKaXZ67tFGkg5bPPBHsD3Ud76mOZKh4Vw_nx5g,1014
|
|
405
|
-
hcs_cli/service/task.py,sha256=
|
|
401
|
+
hcs_cli/service/task.py,sha256=uyewZ4FctrAcdEUbt_mxhcS4iCf3mXz_QAuqdAl8kCE,16912
|
|
406
402
|
hcs_cli/service/template.py,sha256=qKJ09Toe5NmApgd2H0TcVIoFshz-8fh2j3hDtvMO7z4,2242
|
|
407
403
|
hcs_cli/service/uag.py,sha256=HabShUiLzZN-VM_UlPbfb4cQiWcgvsn3eB4CVPOzee0,3193
|
|
408
404
|
hcs_cli/service/vm.py,sha256=Aw1AKvFSPlNTh1VWCdQXf21Yu_tDDao2NhMj5muGzwc,4839
|
|
@@ -439,7 +435,7 @@ hcs_cli/service/edgehub/edgecontroller.py,sha256=O6tSOm2auxtgSgxLbmEyXTLEi2d1l_0
|
|
|
439
435
|
hcs_cli/service/edgehub/edgetwin.py,sha256=Wk6mDzL0CldI8wASicJ8y6IQX3HKn44v8VioPD4G2mw,405
|
|
440
436
|
hcs_cli/service/hoc/__init__.py,sha256=fHFaB2296HgzIKwMPkB9BDxezIYI6M4OD-woPsrtOts,48
|
|
441
437
|
hcs_cli/service/hoc/diagnostic.py,sha256=3sS1Saydsy-kYuF4IQMlz4scv1O4nMjnHOM7Trqh9cY,1465
|
|
442
|
-
hcs_cli/service/hoc/es.py,sha256=
|
|
438
|
+
hcs_cli/service/hoc/es.py,sha256=91eEgOMLXAucsu8BksVlE_Gj9OsxpsC_fyzi4GyLum8,3675
|
|
443
439
|
hcs_cli/service/ims/__init__.py,sha256=CTtPWRJqthcWW7jMyqD-4fP09xSGEfVEj75GbrtyDsA,86
|
|
444
440
|
hcs_cli/service/ims/gold_pattern.py,sha256=Q2zltOH051cii_-WJxtFouuA_okqJpzcWCuAYcNO2j4,2606
|
|
445
441
|
hcs_cli/service/ims/helper.py,sha256=kruncMu5bUUA4mNCdzgdcgrSu7h6ZRjoI02_Fj6dqC0,1794
|
|
@@ -486,7 +482,7 @@ hcs_cli/service/vmm/hoc_event.py,sha256=NSU8Wj2cc8vWod-YDTEMuUXD4ToEKhgIrj3u1lTv
|
|
|
486
482
|
hcs_cli/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
487
483
|
hcs_cli/support/constant.py,sha256=dVOiIaiH4rhC-cZJhTruXyv5ieS1j32YUhF8wEFjbEw,171
|
|
488
484
|
hcs_cli/support/debug_util.py,sha256=X8gOsXzDDPwJxLKPPW7j_j4mZ3Up9xNLu1TDVv_VBRE,2678
|
|
489
|
-
hcs_cli/support/exec_util.py,sha256=
|
|
485
|
+
hcs_cli/support/exec_util.py,sha256=Njqu-pgSTCexJFypYKna8ZvngHhUVkSmJOq81tXw37c,7692
|
|
490
486
|
hcs_cli/support/inspect_util.py,sha256=weLylRM1_3O6nz0yUOiJUEBfR9TpUe-jpghmrQblSjE,3192
|
|
491
487
|
hcs_cli/support/param_util.py,sha256=CHXWJvBF9EwFLYPn_CTOpFWdSyCP3w6iLlYByiz-nvE,1492
|
|
492
488
|
hcs_cli/support/patch_util.py,sha256=r4IjpLA5yGqKer-wuSMB7d93BGPVnse_FhHcAxwYg7A,1524
|
|
@@ -501,7 +497,7 @@ hcs_cli/support/vm_table.py,sha256=hqNUKLVUuBiuDwlqcAQ7uAT1-4z6ZYOIGRcFWn8lnAo,2
|
|
|
501
497
|
hcs_cli/support/scm/html_util.py,sha256=clgMpM90HxRRs3D9ORYYNB57AYh7y_-UzJrB4KX3dsY,458
|
|
502
498
|
hcs_cli/support/scm/plan-editor.html.template,sha256=HtXMmvIvTixVEYN1gblCeqFTt_F8JF6ltDC11Eb_GMw,46975
|
|
503
499
|
hcs_cli/support/scm/plan_editor.py,sha256=TxfHyyozoQ_DCyaPrYXFG9n8AnBuUD8753009FUD0GU,8722
|
|
504
|
-
hcs_cli-0.1.
|
|
505
|
-
hcs_cli-0.1.
|
|
506
|
-
hcs_cli-0.1.
|
|
507
|
-
hcs_cli-0.1.
|
|
500
|
+
hcs_cli-0.1.332.dist-info/METADATA,sha256=HQSDAbv69tNoL5kWve6ZIWmoABWWaPiWx7Yd8zzEfw0,3222
|
|
501
|
+
hcs_cli-0.1.332.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
502
|
+
hcs_cli-0.1.332.dist-info/entry_points.txt,sha256=5uH-af1WUETSBSer2bu4YMGQNY5RriJHsjepb8ACiX8,42
|
|
503
|
+
hcs_cli-0.1.332.dist-info/RECORD,,
|
hcs_cli/cmds/hoc/connect.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
from hcs_core.sglib import cli_options as cli
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@click.command()
|
|
6
|
-
@cli.org_id
|
|
7
|
-
@click.option(
|
|
8
|
-
"--from",
|
|
9
|
-
"from_param",
|
|
10
|
-
type=str,
|
|
11
|
-
required=False,
|
|
12
|
-
default="-12h",
|
|
13
|
-
help="Sepcify the from date. E.g. '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
14
|
-
)
|
|
15
|
-
@click.option(
|
|
16
|
-
"--to",
|
|
17
|
-
type=str,
|
|
18
|
-
required=False,
|
|
19
|
-
default="now",
|
|
20
|
-
help="Sepcify the to date. E.g. 'now', or '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
21
|
-
)
|
|
22
|
-
def connect(org: str, from_param: str, to: str):
|
|
23
|
-
"""Analyse connect issue."""
|
|
24
|
-
pass
|
hcs_cli/cmds/hoc/oncall.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
from hcs_core.sglib import cli_options as cli
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@click.command()
|
|
6
|
-
@cli.org_id
|
|
7
|
-
@click.option(
|
|
8
|
-
"--from",
|
|
9
|
-
"from_param",
|
|
10
|
-
type=str,
|
|
11
|
-
required=False,
|
|
12
|
-
default="-12h",
|
|
13
|
-
help="Sepcify the from date. E.g. '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
14
|
-
)
|
|
15
|
-
@click.option(
|
|
16
|
-
"--to",
|
|
17
|
-
type=str,
|
|
18
|
-
required=False,
|
|
19
|
-
default="now",
|
|
20
|
-
help="Sepcify the to date. E.g. 'now', or '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
21
|
-
)
|
|
22
|
-
def oncall(org: str, from_param: str, to: str):
|
|
23
|
-
"""Perform on-call tasks."""
|
|
24
|
-
pass
|
hcs_cli/cmds/hoc/org.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
from hcs_core.sglib import cli_options as cli
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@click.command()
|
|
6
|
-
@cli.org_id
|
|
7
|
-
@click.option(
|
|
8
|
-
"--from",
|
|
9
|
-
"from_param",
|
|
10
|
-
type=str,
|
|
11
|
-
required=False,
|
|
12
|
-
default="-12h",
|
|
13
|
-
help="Sepcify the from date. E.g. '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
14
|
-
)
|
|
15
|
-
@click.option(
|
|
16
|
-
"--to",
|
|
17
|
-
type=str,
|
|
18
|
-
required=False,
|
|
19
|
-
default="now",
|
|
20
|
-
help="Sepcify the to date. E.g. 'now', or '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
21
|
-
)
|
|
22
|
-
def template(org: str, from_param: str, to: str):
|
|
23
|
-
"""Analyse an org."""
|
|
24
|
-
pass
|
hcs_cli/cmds/hoc/template.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
from hcs_core.sglib import cli_options as cli
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@click.command()
|
|
6
|
-
@cli.org_id
|
|
7
|
-
@click.option(
|
|
8
|
-
"--from",
|
|
9
|
-
"from_param",
|
|
10
|
-
type=str,
|
|
11
|
-
required=False,
|
|
12
|
-
default="-12h",
|
|
13
|
-
help="Sepcify the from date. E.g. '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
14
|
-
)
|
|
15
|
-
@click.option(
|
|
16
|
-
"--to",
|
|
17
|
-
type=str,
|
|
18
|
-
required=False,
|
|
19
|
-
default="now",
|
|
20
|
-
help="Sepcify the to date. E.g. 'now', or '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
21
|
-
)
|
|
22
|
-
def template(org: str, from_param: str, to: str):
|
|
23
|
-
"""Analyse a template."""
|
|
24
|
-
pass
|
hcs_cli/cmds/hoc/vm.py
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
from hcs_core.sglib import cli_options as cli
|
|
3
|
-
|
|
4
|
-
from hcs_cli.service import VM
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@click.command()
|
|
8
|
-
@cli.org_id
|
|
9
|
-
@click.option(
|
|
10
|
-
"--from",
|
|
11
|
-
"from_param",
|
|
12
|
-
type=str,
|
|
13
|
-
required=False,
|
|
14
|
-
default="-12h",
|
|
15
|
-
help="Sepcify the from date. E.g. '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
16
|
-
)
|
|
17
|
-
@click.option(
|
|
18
|
-
"--to",
|
|
19
|
-
type=str,
|
|
20
|
-
required=False,
|
|
21
|
-
default="now",
|
|
22
|
-
help="Sepcify the to date. E.g. 'now', or '-1d', or '-1h35m', or '-1w', or '2023-12-04T00:19:22.854Z'.",
|
|
23
|
-
)
|
|
24
|
-
def template(org: str, from_param: str, to: str):
|
|
25
|
-
"""Analyse a VM."""
|
|
26
|
-
vm = VM(org, "688d055e4f363c64c9c56764", "az-1-m-001")
|
|
27
|
-
return vm
|
|
File without changes
|
|
File without changes
|