appmesh 1.4.0__py3-none-any.whl → 1.4.1__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.
- appmesh/app_run.py +8 -8
- appmesh/http_client.py +159 -138
- appmesh/tcp_client.py +3 -3
- {appmesh-1.4.0.dist-info → appmesh-1.4.1.dist-info}/METADATA +1 -1
- {appmesh-1.4.0.dist-info → appmesh-1.4.1.dist-info}/RECORD +7 -7
- {appmesh-1.4.0.dist-info → appmesh-1.4.1.dist-info}/WHEEL +0 -0
- {appmesh-1.4.0.dist-info → appmesh-1.4.1.dist-info}/top_level.txt +0 -0
appmesh/app_run.py
CHANGED
@@ -21,18 +21,18 @@ class AppRun(object):
|
|
21
21
|
self._client = client
|
22
22
|
"""Instance of `AppMeshClient` used to manage this application run."""
|
23
23
|
|
24
|
-
self._forwarding_host = client.
|
24
|
+
self._forwarding_host = client.forward_to
|
25
25
|
"""Target server for the application run, used for forwarding."""
|
26
26
|
|
27
27
|
@contextmanager
|
28
|
-
def
|
29
|
-
"""Context manager to override the `
|
30
|
-
original_value = self._client.
|
31
|
-
self._client.
|
28
|
+
def forward_to(self):
|
29
|
+
"""Context manager to override the `forward_to` for the duration of the run."""
|
30
|
+
original_value = self._client.forward_to
|
31
|
+
self._client.forward_to = self._forwarding_host
|
32
32
|
try:
|
33
33
|
yield
|
34
34
|
finally:
|
35
|
-
self._client.
|
35
|
+
self._client.forward_to = original_value
|
36
36
|
|
37
37
|
def wait(self, stdout_print: bool = True, timeout: int = 0) -> int:
|
38
38
|
"""Wait for the asynchronous run to complete.
|
@@ -44,5 +44,5 @@ class AppRun(object):
|
|
44
44
|
Returns:
|
45
45
|
int: Exit code if the process finishes successfully. Returns `None` on timeout or exception.
|
46
46
|
"""
|
47
|
-
with self.
|
48
|
-
return self._client.
|
47
|
+
with self.forward_to():
|
48
|
+
return self._client.wait_for_async_run(self, stdout_print, timeout)
|
appmesh/http_client.py
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
import abc
|
4
4
|
import base64
|
5
5
|
import json
|
6
|
+
import warnings
|
6
7
|
import os
|
7
8
|
from datetime import datetime
|
8
9
|
from enum import Enum, unique
|
@@ -47,56 +48,56 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
47
48
|
# Authentication Management
|
48
49
|
- login()
|
49
50
|
- logoff()
|
50
|
-
-
|
51
|
-
-
|
52
|
-
-
|
53
|
-
-
|
54
|
-
-
|
51
|
+
- authenticate()
|
52
|
+
- renew_token()
|
53
|
+
- disable_totp()
|
54
|
+
- get_totp_secret()
|
55
|
+
- setup_totp()
|
55
56
|
|
56
57
|
# Application Management
|
57
|
-
-
|
58
|
-
-
|
59
|
-
-
|
60
|
-
-
|
61
|
-
-
|
62
|
-
-
|
63
|
-
-
|
64
|
-
-
|
58
|
+
- add_app()
|
59
|
+
- delete_app()
|
60
|
+
- disable_app()
|
61
|
+
- enable_app()
|
62
|
+
- check_app_health()
|
63
|
+
- get_app_output()
|
64
|
+
- view_app()
|
65
|
+
- view_all_apps()
|
65
66
|
|
66
67
|
# Run Application Operations
|
67
|
-
-
|
68
|
-
-
|
69
|
-
-
|
68
|
+
- run_app_async()
|
69
|
+
- wait_for_async_run()
|
70
|
+
- run_app_sync()
|
70
71
|
|
71
72
|
# System Management
|
72
|
-
-
|
73
|
-
-
|
74
|
-
-
|
75
|
-
-
|
76
|
-
-
|
73
|
+
- forward_to
|
74
|
+
- set_config()
|
75
|
+
- view_config()
|
76
|
+
- set_log_level()
|
77
|
+
- view_host_resources()
|
77
78
|
- metrics()
|
78
|
-
-
|
79
|
-
-
|
80
|
-
-
|
79
|
+
- add_tag()
|
80
|
+
- delete_tag()
|
81
|
+
- view_tags()
|
81
82
|
|
82
83
|
# File Management
|
83
|
-
-
|
84
|
-
-
|
84
|
+
- download_file()
|
85
|
+
- upload_file()
|
85
86
|
|
86
87
|
# User and Role Management
|
87
|
-
-
|
88
|
-
-
|
89
|
-
-
|
90
|
-
-
|
91
|
-
-
|
92
|
-
-
|
93
|
-
-
|
94
|
-
-
|
95
|
-
-
|
96
|
-
-
|
97
|
-
-
|
98
|
-
-
|
99
|
-
-
|
88
|
+
- add_user()
|
89
|
+
- delete_user()
|
90
|
+
- lock_user()
|
91
|
+
- update_user_password()
|
92
|
+
- view_self()
|
93
|
+
- unlock_user()
|
94
|
+
- view_users()
|
95
|
+
- view_user_permissions()
|
96
|
+
- view_permissions()
|
97
|
+
- delete_role()
|
98
|
+
- update_role()
|
99
|
+
- view_roles()
|
100
|
+
- view_groups()
|
100
101
|
"""
|
101
102
|
|
102
103
|
DURATION_ONE_WEEK_ISO = "P1W"
|
@@ -203,7 +204,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
203
204
|
self._jwt_token = token
|
204
205
|
|
205
206
|
@property
|
206
|
-
def
|
207
|
+
def forward_to(self) -> str:
|
207
208
|
"""Get the target host address for request forwarding in a cluster setup.
|
208
209
|
|
209
210
|
This property manages the destination host where requests will be forwarded to
|
@@ -225,8 +226,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
225
226
|
"""
|
226
227
|
return self._forwarding_host
|
227
228
|
|
228
|
-
@
|
229
|
-
def
|
229
|
+
@forward_to.setter
|
230
|
+
def forward_to(self, host: str) -> None:
|
230
231
|
"""Set the target host address for request forwarding.
|
231
232
|
|
232
233
|
Configure the destination host where requests should be forwarded to. This is
|
@@ -241,9 +242,9 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
241
242
|
Pass empty string to disable forwarding.
|
242
243
|
|
243
244
|
Examples:
|
244
|
-
>>> client.
|
245
|
-
>>> client.
|
246
|
-
>>> client.
|
245
|
+
>>> client.forward_to = "backend-node:6060" # Use specific port
|
246
|
+
>>> client.forward_to = "backend-node" # Use current service port
|
247
|
+
>>> client.forward_to = None # Disable forwarding
|
247
248
|
"""
|
248
249
|
|
249
250
|
self._forwarding_host = host
|
@@ -297,7 +298,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
297
298
|
return self.jwt_token
|
298
299
|
|
299
300
|
def logoff(self) -> bool:
|
300
|
-
"""
|
301
|
+
"""Log out of the current session from the server.
|
301
302
|
|
302
303
|
Returns:
|
303
304
|
bool: logoff success or failure.
|
@@ -309,8 +310,12 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
309
310
|
return resp.status_code == HTTPStatus.OK
|
310
311
|
|
311
312
|
def authentication(self, token: str, permission=None) -> bool:
|
312
|
-
"""
|
313
|
-
|
313
|
+
"""Deprecated: Use authenticate() instead."""
|
314
|
+
warnings.warn("authentication() is deprecated, use authenticate() instead.", DeprecationWarning, stacklevel=2)
|
315
|
+
return self.authenticate(token, permission)
|
316
|
+
|
317
|
+
def authenticate(self, token: str, permission: str = None) -> bool:
|
318
|
+
"""Authenticate with a token and verify permission if specified.
|
314
319
|
|
315
320
|
Args:
|
316
321
|
token (str): JWT token returned from login().
|
@@ -333,8 +338,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
333
338
|
raise Exception(resp.text)
|
334
339
|
return resp.status_code == HTTPStatus.OK
|
335
340
|
|
336
|
-
def
|
337
|
-
"""Renew current token
|
341
|
+
def renew_token(self, timeout: Union[int, str] = DURATION_ONE_WEEK_ISO) -> str:
|
342
|
+
"""Renew the current token.
|
338
343
|
|
339
344
|
Args:
|
340
345
|
timeout_seconds (int | str, optional): token expire timeout of seconds. support ISO 8601 durations (e.g., 'P1Y2M3DT4H5M6S' 'P1W').
|
@@ -347,7 +352,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
347
352
|
AppMeshClient.Method.POST,
|
348
353
|
path="/appmesh/token/renew",
|
349
354
|
header={
|
350
|
-
"Expire-Seconds": self._parse_duration(
|
355
|
+
"Expire-Seconds": self._parse_duration(timeout),
|
351
356
|
},
|
352
357
|
)
|
353
358
|
if resp.status_code == HTTPStatus.OK:
|
@@ -356,8 +361,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
356
361
|
return self.jwt_token
|
357
362
|
raise Exception(resp.text)
|
358
363
|
|
359
|
-
def
|
360
|
-
"""Generate TOTP secret for current
|
364
|
+
def get_totp_secret(self) -> str:
|
365
|
+
"""Generate TOTP secret for the current user and return MFA URI.
|
361
366
|
|
362
367
|
Returns:
|
363
368
|
str: TOTP secret str
|
@@ -368,8 +373,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
368
373
|
return self._parse_totp_uri(totp_uri).get("secret")
|
369
374
|
raise Exception(resp.text)
|
370
375
|
|
371
|
-
def
|
372
|
-
"""
|
376
|
+
def setup_totp(self, totp_code: str) -> bool:
|
377
|
+
"""Set up 2FA for the current user.
|
373
378
|
|
374
379
|
Args:
|
375
380
|
totp_code (str): TOTP code
|
@@ -386,8 +391,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
386
391
|
raise Exception(resp.text)
|
387
392
|
return resp.status_code == HTTPStatus.OK
|
388
393
|
|
389
|
-
def
|
390
|
-
"""Disable 2FA for
|
394
|
+
def disable_totp(self, user: str = "self") -> bool:
|
395
|
+
"""Disable 2FA for the specified user.
|
391
396
|
|
392
397
|
Args:
|
393
398
|
user (str, optional): user name for disable TOTP.
|
@@ -428,8 +433,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
428
433
|
########################################
|
429
434
|
# Application view
|
430
435
|
########################################
|
431
|
-
def
|
432
|
-
"""Get
|
436
|
+
def view_app(self, app_name: str) -> App:
|
437
|
+
"""Get information about a specific application.
|
433
438
|
|
434
439
|
Args:
|
435
440
|
app_name (str): the application name.
|
@@ -445,8 +450,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
445
450
|
raise Exception(resp.text)
|
446
451
|
return App(resp.json())
|
447
452
|
|
448
|
-
def
|
449
|
-
"""Get all applications
|
453
|
+
def view_all_apps(self):
|
454
|
+
"""Get information about all applications.
|
450
455
|
|
451
456
|
Returns:
|
452
457
|
list: the application object both contain static configuration and runtime information, only return applications that the user has permissions.
|
@@ -462,8 +467,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
462
467
|
apps.append(App(app))
|
463
468
|
return apps
|
464
469
|
|
465
|
-
def
|
466
|
-
"""Get
|
470
|
+
def get_app_output(self, app_name: str, stdout_position: int = 0, stdout_index: int = 0, stdout_maxsize: int = 10240, process_uuid: str = "", timeout: int = 0) -> AppOutput:
|
471
|
+
"""Get the stdout/stderr of an application.
|
467
472
|
|
468
473
|
Args:
|
469
474
|
app_name (str): the application name
|
@@ -492,8 +497,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
492
497
|
exit_code = int(resp.headers["Exit-Code"]) if "Exit-Code" in resp.headers else None
|
493
498
|
return AppOutput(status_code=resp.status_code, output=resp.text, out_position=out_position, exit_code=exit_code)
|
494
499
|
|
495
|
-
def
|
496
|
-
"""
|
500
|
+
def check_app_health(self, app_name: str) -> bool:
|
501
|
+
"""Check the health status of an application.
|
497
502
|
|
498
503
|
Args:
|
499
504
|
app_name (str): the application name.
|
@@ -509,8 +514,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
509
514
|
########################################
|
510
515
|
# Application manage
|
511
516
|
########################################
|
512
|
-
def
|
513
|
-
"""Register
|
517
|
+
def add_app(self, app: App) -> App:
|
518
|
+
"""Register a new application.
|
514
519
|
|
515
520
|
Args:
|
516
521
|
app (App): the application definition.
|
@@ -526,7 +531,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
526
531
|
raise Exception(resp.text)
|
527
532
|
return App(resp.json())
|
528
533
|
|
529
|
-
def
|
534
|
+
def delete_app(self, app_name: str) -> bool:
|
530
535
|
"""Remove an application.
|
531
536
|
|
532
537
|
Args:
|
@@ -543,8 +548,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
543
548
|
else:
|
544
549
|
raise Exception(resp.text)
|
545
550
|
|
546
|
-
def
|
547
|
-
"""Enable an application
|
551
|
+
def enable_app(self, app_name: str) -> bool:
|
552
|
+
"""Enable an application.
|
548
553
|
|
549
554
|
Args:
|
550
555
|
app_name (str): the application name.
|
@@ -557,8 +562,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
557
562
|
raise Exception(resp.text)
|
558
563
|
return resp.status_code == HTTPStatus.OK
|
559
564
|
|
560
|
-
def
|
561
|
-
"""
|
565
|
+
def disable_app(self, app_name: str) -> bool:
|
566
|
+
"""Disable an application.
|
562
567
|
|
563
568
|
Args:
|
564
569
|
app_name (str): the application name.
|
@@ -574,8 +579,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
574
579
|
########################################
|
575
580
|
# Cloud management
|
576
581
|
########################################
|
577
|
-
def
|
578
|
-
"""Get all cloud applications
|
582
|
+
def view_all_cloud_apps(self) -> dict:
|
583
|
+
"""Get information about all cloud applications.
|
579
584
|
|
580
585
|
Returns:
|
581
586
|
dict: cloud applications in JSON format.
|
@@ -585,8 +590,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
585
590
|
raise Exception(resp.text)
|
586
591
|
return resp.json()
|
587
592
|
|
588
|
-
def
|
589
|
-
"""Get
|
593
|
+
def view_cloud_app(self, app_name: str) -> dict:
|
594
|
+
"""Get information about a specific cloud application.
|
590
595
|
|
591
596
|
Args:
|
592
597
|
app_name (str): the application name.
|
@@ -599,8 +604,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
599
604
|
raise Exception(resp.text)
|
600
605
|
return resp.json()
|
601
606
|
|
602
|
-
def
|
603
|
-
"""Get
|
607
|
+
def get_cloud_app_output(self, app_name: str, host_name: str, stdout_position: int = 0, stdout_index: int = 0, stdout_maxsize: int = 10240, process_uuid: str = ""):
|
608
|
+
"""Get the stdout/stderr of a cloud application.
|
604
609
|
|
605
610
|
Args:
|
606
611
|
app_name (str): the application name
|
@@ -631,8 +636,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
631
636
|
exit_code = int(resp.headers["Exit-Code"]) if "Exit-Code" in resp.headers else None
|
632
637
|
return (resp.status_code == HTTPStatus.OK), resp.text, out_position, exit_code
|
633
638
|
|
634
|
-
def
|
635
|
-
"""Delete a cloud application
|
639
|
+
def delete_cloud_app(self, app_name: str) -> bool:
|
640
|
+
"""Delete a cloud application.
|
636
641
|
|
637
642
|
Args:
|
638
643
|
app_name (str): The application name for cloud
|
@@ -645,8 +650,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
645
650
|
raise Exception(resp.text)
|
646
651
|
return resp.status_code == HTTPStatus.OK
|
647
652
|
|
648
|
-
def
|
649
|
-
"""Add a cloud application
|
653
|
+
def add_cloud_app(self, app_json: dict) -> dict:
|
654
|
+
"""Add a new cloud application.
|
650
655
|
|
651
656
|
Args:
|
652
657
|
app_json (dict): the cloud application definition with replication, condition and resource requirement
|
@@ -659,8 +664,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
659
664
|
raise Exception(resp.text)
|
660
665
|
return resp.json()
|
661
666
|
|
662
|
-
def
|
663
|
-
"""Get cluster
|
667
|
+
def view_cloud_nodes(self) -> dict:
|
668
|
+
"""Get a list of cluster nodes.
|
664
669
|
|
665
670
|
Returns:
|
666
671
|
dict: cluster node list json.
|
@@ -673,8 +678,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
673
678
|
########################################
|
674
679
|
# Configuration
|
675
680
|
########################################
|
676
|
-
def
|
677
|
-
"""Get
|
681
|
+
def view_host_resources(self) -> dict:
|
682
|
+
"""Get a report of host resources including CPU, memory, and disk.
|
678
683
|
|
679
684
|
Returns:
|
680
685
|
dict: the host resource json.
|
@@ -684,8 +689,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
684
689
|
raise Exception(resp.text)
|
685
690
|
return resp.json()
|
686
691
|
|
687
|
-
def
|
688
|
-
"""Get App Mesh configuration JSON
|
692
|
+
def view_config(self) -> dict:
|
693
|
+
"""Get the App Mesh configuration in JSON format.
|
689
694
|
|
690
695
|
Returns:
|
691
696
|
dict: the configuration json.
|
@@ -695,8 +700,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
695
700
|
raise Exception(resp.text)
|
696
701
|
return resp.json()
|
697
702
|
|
698
|
-
def
|
699
|
-
"""Update
|
703
|
+
def set_config(self, config_json: dict) -> dict:
|
704
|
+
"""Update the configuration.
|
700
705
|
|
701
706
|
Args:
|
702
707
|
cfg_json (dict): the new configuration json.
|
@@ -704,13 +709,13 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
704
709
|
Returns:
|
705
710
|
dict: the updated configuration json.
|
706
711
|
"""
|
707
|
-
resp = self._request_http(AppMeshClient.Method.POST, path="/appmesh/config", body=
|
712
|
+
resp = self._request_http(AppMeshClient.Method.POST, path="/appmesh/config", body=config_json)
|
708
713
|
if resp.status_code != HTTPStatus.OK:
|
709
714
|
raise Exception(resp.text)
|
710
715
|
return resp.json()
|
711
716
|
|
712
|
-
def
|
713
|
-
"""Update
|
717
|
+
def set_log_level(self, level: str = "DEBUG") -> str:
|
718
|
+
"""Update the log level.
|
714
719
|
|
715
720
|
Args:
|
716
721
|
level (str, optional): log level.
|
@@ -726,8 +731,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
726
731
|
########################################
|
727
732
|
# User Management
|
728
733
|
########################################
|
729
|
-
def
|
730
|
-
"""Change
|
734
|
+
def update_user_password(self, new_password: str, user_name: str = "self") -> bool:
|
735
|
+
"""Change the password of a user.
|
731
736
|
|
732
737
|
Args:
|
733
738
|
user_name (str): the user name.
|
@@ -745,8 +750,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
745
750
|
raise Exception(resp.text)
|
746
751
|
return True
|
747
752
|
|
748
|
-
def
|
749
|
-
"""Add a new user
|
753
|
+
def add_user(self, user_name: str, user_json: dict) -> bool:
|
754
|
+
"""Add a new user.
|
750
755
|
|
751
756
|
Args:
|
752
757
|
user_name (str): the user name.
|
@@ -762,8 +767,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
762
767
|
)
|
763
768
|
return resp.status_code == HTTPStatus.OK
|
764
769
|
|
765
|
-
def
|
766
|
-
"""Delete a user
|
770
|
+
def delete_user(self, user_name: str) -> bool:
|
771
|
+
"""Delete a user.
|
767
772
|
|
768
773
|
Args:
|
769
774
|
user_name (str): the user name.
|
@@ -777,8 +782,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
777
782
|
)
|
778
783
|
return resp.status_code == HTTPStatus.OK
|
779
784
|
|
780
|
-
def
|
781
|
-
"""Lock a user
|
785
|
+
def lock_user(self, user_name: str) -> bool:
|
786
|
+
"""Lock a user.
|
782
787
|
|
783
788
|
Args:
|
784
789
|
user_name (str): the user name.
|
@@ -794,8 +799,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
794
799
|
raise Exception(resp.text)
|
795
800
|
return resp.status_code == HTTPStatus.OK
|
796
801
|
|
797
|
-
def
|
798
|
-
"""Unlock a user
|
802
|
+
def unlock_user(self, user_name: str) -> bool:
|
803
|
+
"""Unlock a user.
|
799
804
|
|
800
805
|
Args:
|
801
806
|
user_name (str): the user name.
|
@@ -811,8 +816,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
811
816
|
raise Exception(resp.text)
|
812
817
|
return resp.status_code == HTTPStatus.OK
|
813
818
|
|
814
|
-
def
|
815
|
-
"""Get all users
|
819
|
+
def view_users(self) -> dict:
|
820
|
+
"""Get information about all users.
|
816
821
|
|
817
822
|
Returns:
|
818
823
|
dict: all user definition
|
@@ -823,7 +828,12 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
823
828
|
return resp.json()
|
824
829
|
|
825
830
|
def user_self(self) -> dict:
|
826
|
-
"""
|
831
|
+
"""Deprecated: Use view_self() instead."""
|
832
|
+
warnings.warn("user_self() is deprecated, use view_self() instead.", DeprecationWarning, stacklevel=2)
|
833
|
+
return self.view_self()
|
834
|
+
|
835
|
+
def view_self(self) -> dict:
|
836
|
+
"""Get information about the current user.
|
827
837
|
|
828
838
|
Returns:
|
829
839
|
dict: user definition.
|
@@ -833,8 +843,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
833
843
|
raise Exception(resp.text)
|
834
844
|
return resp.json()
|
835
845
|
|
836
|
-
def
|
837
|
-
"""Get all user groups
|
846
|
+
def view_groups(self) -> list:
|
847
|
+
"""Get information about all user groups.
|
838
848
|
|
839
849
|
Returns:
|
840
850
|
dict: user group array.
|
@@ -844,8 +854,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
844
854
|
raise Exception(resp.text)
|
845
855
|
return resp.json()
|
846
856
|
|
847
|
-
def
|
848
|
-
"""Get all available permissions
|
857
|
+
def view_permissions(self) -> list:
|
858
|
+
"""Get information about all available permissions.
|
849
859
|
|
850
860
|
Returns:
|
851
861
|
dict: permission array
|
@@ -855,8 +865,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
855
865
|
raise Exception(resp.text)
|
856
866
|
return resp.json()
|
857
867
|
|
858
|
-
def
|
859
|
-
"""Get current user
|
868
|
+
def view_user_permissions(self) -> list:
|
869
|
+
"""Get information about the permissions of the current user.
|
860
870
|
|
861
871
|
Returns:
|
862
872
|
dict: user permission array.
|
@@ -866,8 +876,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
866
876
|
raise Exception(resp.text)
|
867
877
|
return resp.json()
|
868
878
|
|
869
|
-
def
|
870
|
-
"""Get all roles with permission
|
879
|
+
def view_roles(self) -> list:
|
880
|
+
"""Get information about all roles with permission definitions.
|
871
881
|
|
872
882
|
Returns:
|
873
883
|
dict: all role definition.
|
@@ -877,8 +887,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
877
887
|
raise Exception(resp.text)
|
878
888
|
return resp.json()
|
879
889
|
|
880
|
-
def
|
881
|
-
"""Update
|
890
|
+
def update_role(self, role_name: str, role_permission_json: dict) -> bool:
|
891
|
+
"""Update or add a role with defined permissions.
|
882
892
|
|
883
893
|
Args:
|
884
894
|
role_name (str): the role name.
|
@@ -892,8 +902,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
892
902
|
raise Exception(resp.text)
|
893
903
|
return resp.status_code == HTTPStatus.OK
|
894
904
|
|
895
|
-
def
|
896
|
-
"""Delete a user role
|
905
|
+
def delete_role(self, role_name: str) -> bool:
|
906
|
+
"""Delete a user role.
|
897
907
|
|
898
908
|
Args:
|
899
909
|
role_name (str): the role name.
|
@@ -912,8 +922,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
912
922
|
########################################
|
913
923
|
# Tag management
|
914
924
|
########################################
|
915
|
-
def
|
916
|
-
"""Add a new label
|
925
|
+
def add_tag(self, tag_name: str, tag_value: str) -> bool:
|
926
|
+
"""Add a new label.
|
917
927
|
|
918
928
|
Args:
|
919
929
|
tag_name (str): the label name.
|
@@ -931,8 +941,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
931
941
|
raise Exception(resp.text)
|
932
942
|
return resp.status_code == HTTPStatus.OK
|
933
943
|
|
934
|
-
def
|
935
|
-
"""Delete a label
|
944
|
+
def delete_tag(self, tag_name: str) -> bool:
|
945
|
+
"""Delete a label.
|
936
946
|
|
937
947
|
Args:
|
938
948
|
tag_name (str): the label name.
|
@@ -945,8 +955,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
945
955
|
raise Exception(resp.text)
|
946
956
|
return resp.status_code == HTTPStatus.OK
|
947
957
|
|
948
|
-
def
|
949
|
-
"""Get
|
958
|
+
def view_tags(self) -> dict:
|
959
|
+
"""Get information about all labels.
|
950
960
|
|
951
961
|
Returns:
|
952
962
|
dict: label data.
|
@@ -960,7 +970,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
960
970
|
# Promethus metrics
|
961
971
|
########################################
|
962
972
|
def metrics(self):
|
963
|
-
"""
|
973
|
+
"""Get Prometheus metrics.
|
964
974
|
|
965
975
|
Returns:
|
966
976
|
str: prometheus metrics texts
|
@@ -973,8 +983,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
973
983
|
########################################
|
974
984
|
# File management
|
975
985
|
########################################
|
976
|
-
def
|
977
|
-
"""
|
986
|
+
def download_file(self, remote_file: str, local_file: str, apply_file_attributes: bool = True) -> None:
|
987
|
+
"""Download a remote file to the local system. Optionally, the local file will have the same permission as the remote file.
|
978
988
|
|
979
989
|
Args:
|
980
990
|
remote_file (str): the remote file path.
|
@@ -1002,7 +1012,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1002
1012
|
except PermissionError:
|
1003
1013
|
print(f"Warning: Unable to change owner/group of {local_file}. Operation requires elevated privileges.")
|
1004
1014
|
|
1005
|
-
def
|
1015
|
+
def upload_file(self, local_file: str, remote_file: str, apply_file_attributes: bool = True) -> None:
|
1006
1016
|
"""Upload a local file to the remote server. Optionally, the remote file will have the same permission as the local file.
|
1007
1017
|
|
1008
1018
|
Dependency:
|
@@ -1051,7 +1061,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1051
1061
|
else:
|
1052
1062
|
raise TypeError(f"Invalid timeout type: {str(timeout)}")
|
1053
1063
|
|
1054
|
-
def
|
1064
|
+
def run_app_async(
|
1055
1065
|
self,
|
1056
1066
|
app: Union[App, str],
|
1057
1067
|
max_time_seconds: Union[int, str] = DURATION_TWO_DAYS_ISO,
|
@@ -1093,8 +1103,8 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1093
1103
|
# Return an AppRun object with the application name and process UUID
|
1094
1104
|
return AppRun(self, resp.json()["name"], resp.json()["process_uuid"])
|
1095
1105
|
|
1096
|
-
def
|
1097
|
-
"""Wait for an
|
1106
|
+
def wait_for_async_run(self, run: AppRun, stdout_print: bool = True, timeout: int = 0) -> int:
|
1107
|
+
"""Wait for an asynchronous run to finish.
|
1098
1108
|
|
1099
1109
|
Args:
|
1100
1110
|
run (AppRun): asyncrized run result from run_async().
|
@@ -1109,14 +1119,14 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1109
1119
|
start = datetime.now()
|
1110
1120
|
interval = 1 if self.__class__.__name__ == "AppMeshClient" else 1000
|
1111
1121
|
while len(run.proc_uid) > 0:
|
1112
|
-
app_out = self.
|
1122
|
+
app_out = self.get_app_output(app_name=run.app_name, stdout_position=last_output_position, stdout_index=0, process_uuid=run.proc_uid, timeout=interval)
|
1113
1123
|
if app_out.output and stdout_print:
|
1114
1124
|
print(app_out.output, end="")
|
1115
1125
|
if app_out.out_position is not None:
|
1116
1126
|
last_output_position = app_out.out_position
|
1117
1127
|
if app_out.exit_code is not None:
|
1118
1128
|
# success
|
1119
|
-
self.
|
1129
|
+
self.delete_app(run.app_name)
|
1120
1130
|
return app_out.exit_code
|
1121
1131
|
if app_out.status_code != HTTPStatus.OK:
|
1122
1132
|
# failed
|
@@ -1132,6 +1142,17 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1132
1142
|
stdout_print: bool = True,
|
1133
1143
|
max_time_seconds: Union[int, str] = DURATION_TWO_DAYS_ISO,
|
1134
1144
|
life_cycle_seconds: Union[int, str] = DURATION_TWO_DAYS_HALF_ISO,
|
1145
|
+
) -> Tuple[Union[int, None], str]:
|
1146
|
+
"""Deprecated: Use run_app_sync() instead."""
|
1147
|
+
warnings.warn("run_sync() is deprecated, use run_app_sync() instead.", DeprecationWarning, stacklevel=2)
|
1148
|
+
return self.run_app_sync(app, stdout_print, max_time_seconds, life_cycle_seconds)
|
1149
|
+
|
1150
|
+
def run_app_sync(
|
1151
|
+
self,
|
1152
|
+
app: Union[App, str],
|
1153
|
+
stdout_print: bool = True,
|
1154
|
+
max_time_seconds: Union[int, str] = DURATION_TWO_DAYS_ISO,
|
1155
|
+
life_cycle_seconds: Union[int, str] = DURATION_TWO_DAYS_HALF_ISO,
|
1135
1156
|
) -> Tuple[Union[int, None], str]:
|
1136
1157
|
"""Synchronously run an application remotely, blocking until completion, and return the result.
|
1137
1158
|
|
@@ -1176,7 +1197,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1176
1197
|
return exit_code, resp.text
|
1177
1198
|
|
1178
1199
|
def _request_http(self, method: Method, path: str, query: dict = None, header: dict = None, body=None) -> requests.Response:
|
1179
|
-
"""
|
1200
|
+
"""Make an HTTP request.
|
1180
1201
|
|
1181
1202
|
Args:
|
1182
1203
|
method (Method): AppMeshClient.Method.
|
@@ -1193,11 +1214,11 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1193
1214
|
header = {} if header is None else header
|
1194
1215
|
if self.jwt_token:
|
1195
1216
|
header["Authorization"] = "Bearer " + self.jwt_token
|
1196
|
-
if self.
|
1197
|
-
if ":" in self.
|
1198
|
-
header[self.HTTP_HEADER_KEY_X_TARGET_HOST] = self.
|
1217
|
+
if self.forward_to and len(self.forward_to) > 0:
|
1218
|
+
if ":" in self.forward_to:
|
1219
|
+
header[self.HTTP_HEADER_KEY_X_TARGET_HOST] = self.forward_to
|
1199
1220
|
else:
|
1200
|
-
header[self.HTTP_HEADER_KEY_X_TARGET_HOST] = self.
|
1221
|
+
header[self.HTTP_HEADER_KEY_X_TARGET_HOST] = self.forward_to + ":" + str(parse.urlsplit(self.server_url).port)
|
1201
1222
|
header[self.HTTP_HEADER_KEY_USER_AGENT] = self.HTTP_USER_AGENT
|
1202
1223
|
|
1203
1224
|
if method is AppMeshClient.Method.GET:
|
appmesh/tcp_client.py
CHANGED
@@ -103,7 +103,7 @@ class AppMeshClientTCP(AppMeshClient):
|
|
103
103
|
appmesh_request = RequestMessage()
|
104
104
|
if super().jwt_token:
|
105
105
|
appmesh_request.headers["Authorization"] = "Bearer " + super().jwt_token
|
106
|
-
if super().
|
106
|
+
if super().forward_to and len(super().forward_to) > 0:
|
107
107
|
raise Exception("Not support forward request in TCP mode")
|
108
108
|
appmesh_request.headers[self.HTTP_HEADER_KEY_USER_AGENT] = self.HTTP_USER_AGENT_TCP
|
109
109
|
appmesh_request.uuid = str(uuid.uuid1())
|
@@ -145,7 +145,7 @@ class AppMeshClientTCP(AppMeshClient):
|
|
145
145
|
########################################
|
146
146
|
# File management
|
147
147
|
########################################
|
148
|
-
def
|
148
|
+
def download_file(self, remote_file: str, local_file: str, apply_file_attributes: bool = True) -> None:
|
149
149
|
"""Copy a remote file to local, the local file will have the same permission as the remote file
|
150
150
|
|
151
151
|
Args:
|
@@ -179,7 +179,7 @@ class AppMeshClientTCP(AppMeshClient):
|
|
179
179
|
except PermissionError:
|
180
180
|
print(f"Warning: Unable to change owner/group of {local_file}. Operation requires elevated privileges.")
|
181
181
|
|
182
|
-
def
|
182
|
+
def upload_file(self, local_file: str, remote_file: str, apply_file_attributes: bool = True) -> None:
|
183
183
|
"""Upload a local file to the remote server, the remote file will have the same permission as the local file
|
184
184
|
|
185
185
|
Dependency:
|
@@ -1,13 +1,13 @@
|
|
1
1
|
appmesh/__init__.py,sha256=vgiSdMzlzDwgHxBMDoFaKWb77g2nJVciRf4z_ssAlwE,431
|
2
2
|
appmesh/app.py,sha256=9Q-SOOej-MH13BU5Dv2iTa-p-sECCJQp6ZX9DjWWmwE,10526
|
3
3
|
appmesh/app_output.py,sha256=JK_TMKgjvaw4n_ys_vmN5S4MyWVZpmD7NlKz_UyMIM8,1015
|
4
|
-
appmesh/app_run.py,sha256=
|
4
|
+
appmesh/app_run.py,sha256=eJv7_hUVztolo_r6ljme2EkZSOtjm111BzeSdhmx9PA,1722
|
5
5
|
appmesh/appmesh_client.py,sha256=0ltkqHZUq094gKneYmC0bEZCP0X9kHTp9fccKdWFWP0,339
|
6
|
-
appmesh/http_client.py,sha256=
|
7
|
-
appmesh/tcp_client.py,sha256=
|
6
|
+
appmesh/http_client.py,sha256=mDMmZqvTUlfOJ6F_3LbS4t_uWzHTfizMUi_YouZVlQ8,48584
|
7
|
+
appmesh/tcp_client.py,sha256=RkHl5s8jE333BJOgxJqJ_fvjbdRQza7ciV49vLT6YO4,10923
|
8
8
|
appmesh/tcp_messages.py,sha256=w1Kehz_aX4X2CYAUsy9mFVJRhxnLQwwc6L58W4YkQqs,969
|
9
9
|
appmesh/tcp_transport.py,sha256=UMGby2oKV4k7lyXZUMSOe2Je34fb1w7nTkxEpatKLKg,7256
|
10
|
-
appmesh-1.4.
|
11
|
-
appmesh-1.4.
|
12
|
-
appmesh-1.4.
|
13
|
-
appmesh-1.4.
|
10
|
+
appmesh-1.4.1.dist-info/METADATA,sha256=GQ0frOLrIwU9DIh2bgh5_LMXOBkIaTMV9hXqNjHJFFg,11142
|
11
|
+
appmesh-1.4.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
12
|
+
appmesh-1.4.1.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
|
13
|
+
appmesh-1.4.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|