aws-ssh-utils 0.2.4__tar.gz → 0.2.5__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.
- {aws_ssh_utils-0.2.4 → aws_ssh_utils-0.2.5}/PKG-INFO +45 -13
- {aws_ssh_utils-0.2.4 → aws_ssh_utils-0.2.5}/README.md +114 -79
- aws_ssh_utils-0.2.5/aws_ssh_utils/__init__.py +1 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/cli_utils.py +165 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/commands/app.py +364 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/commands/ec2.py +65 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/commands/emr.py +85 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/commands/emr_all.py +105 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/commands/healthcheck.py +265 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/connection.py +385 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/ec2_utils.py +68 -0
- {aws_ssh_utils-0.2.4 → aws_ssh_utils-0.2.5}/aws_ssh_utils/emr_utils.py +215 -189
- aws_ssh_utils-0.2.5/aws_ssh_utils/py.typed +0 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/ssh.py +61 -0
- aws_ssh_utils-0.2.5/aws_ssh_utils/terminal.py +302 -0
- {aws_ssh_utils-0.2.4 → aws_ssh_utils-0.2.5}/pyproject.toml +19 -15
- aws_ssh_utils-0.2.4/aws_ssh_utils/__init__.py +0 -1
- aws_ssh_utils-0.2.4/aws_ssh_utils/interactive_ssh.py +0 -282
- aws_ssh_utils-0.2.4/aws_ssh_utils/ssh.py +0 -651
- {aws_ssh_utils-0.2.4 → aws_ssh_utils-0.2.5}/.gitignore +0 -0
- {aws_ssh_utils-0.2.4 → aws_ssh_utils-0.2.5}/LICENSE +0 -0
- /aws_ssh_utils-0.2.4/aws_ssh_utils/py.typed → /aws_ssh_utils-0.2.5/aws_ssh_utils/commands/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: aws-ssh-utils
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Easy AWS SSHing
|
|
5
5
|
Project-URL: Homepage, https://github.com/mvanderlee/aws-ssh-utils
|
|
6
6
|
Author-email: Michiel Vanderlee <jmt.vanderlee@gmail.com>
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
20
|
Classifier: Topic :: Software Development
|
|
20
21
|
Classifier: Topic :: Software Development :: Libraries
|
|
21
22
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@@ -23,18 +24,14 @@ Classifier: Typing :: Typed
|
|
|
23
24
|
Requires-Python: >=3.11
|
|
24
25
|
Requires-Dist: boto3
|
|
25
26
|
Requires-Dist: click
|
|
26
|
-
Requires-Dist: click-spinner
|
|
27
|
-
Requires-Dist: coloredlogs
|
|
28
|
-
Requires-Dist: environs
|
|
29
27
|
Requires-Dist: loguru
|
|
30
28
|
Requires-Dist: paramiko
|
|
29
|
+
Requires-Dist: pyte>=0.8.2
|
|
31
30
|
Requires-Dist: questionary
|
|
31
|
+
Requires-Dist: requests>=2.34.2
|
|
32
|
+
Requires-Dist: rich>=15.0.0
|
|
33
|
+
Requires-Dist: textual>=8.2.8
|
|
32
34
|
Requires-Dist: typing-extensions
|
|
33
|
-
Provides-Extra: dev
|
|
34
|
-
Requires-Dist: boto3-stubs[ec2,emr]; extra == 'dev'
|
|
35
|
-
Provides-Extra: publish
|
|
36
|
-
Requires-Dist: hatch>=1.7.0; extra == 'publish'
|
|
37
|
-
Provides-Extra: test
|
|
38
35
|
Description-Content-Type: text/markdown
|
|
39
36
|
|
|
40
37
|
# AWS SSH Utils
|
|
@@ -51,12 +48,41 @@ aws_ssh ec2
|
|
|
51
48
|
aws_ssh emr
|
|
52
49
|
|
|
53
50
|
aws_ssh emr-all
|
|
51
|
+
|
|
52
|
+
aws_ssh app
|
|
54
53
|
```
|
|
55
54
|
|
|
56
55
|
This allows you to interactively SSH to an EC2 instance, EMR instance, or all EMR instances with TMUX.
|
|
57
56
|
|
|
58
57
|
It utilizes [questionary](https://pypi.org/project/questionary/) to ask you which instance you want to connect to.
|
|
59
58
|
|
|
59
|
+
## App
|
|
60
|
+
|
|
61
|
+
Terminal UI to browse EC2 instances and EMR clusters, with SSH shells in tabs.
|
|
62
|
+
It's the default command, so `aws_ssh` and `aws_ssh -p my-profile` launch it too.
|
|
63
|
+
Each connection tries, in order: `~/.ssh/config`, SSH over AWS SSM (`session-manager-plugin`), opkssh (via instance/cluster tags),
|
|
64
|
+
the instance's EC2 key found in `~/.ssh`, then your default keys/ssh-agent.
|
|
65
|
+
Unknown host keys are accepted and appended to `~/.ssh/known_hosts`; changed host keys are rejected.
|
|
66
|
+
|
|
67
|
+
```shell
|
|
68
|
+
$ aws_ssh app --help
|
|
69
|
+
Usage: aws_ssh app [OPTIONS]
|
|
70
|
+
|
|
71
|
+
Browse EC2 instances and EMR clusters, and open SSH shells in tabs.
|
|
72
|
+
|
|
73
|
+
Options:
|
|
74
|
+
-p, --profile TEXT Which AWS profile to use
|
|
75
|
+
-r, --region TEXT Which AWS region to use
|
|
76
|
+
--scrollback INTEGER RANGE Lines of scrollback per shell. Defaults to your
|
|
77
|
+
tmux or Windows Terminal setting, else 1000.
|
|
78
|
+
[x>=0]
|
|
79
|
+
--help Show this message and exit.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Scroll back with the mouse wheel or `shift+PgUp`/`shift+PgDn`; typing jumps back to the prompt.
|
|
83
|
+
`F12` shows/hides the sidebar, `ctrl+w` closes a failed tab, `ctrl+q` quits. Every other key goes to the focused shell.
|
|
84
|
+
Logs are viewable with `textual console`.
|
|
85
|
+
|
|
60
86
|
## EC2
|
|
61
87
|
|
|
62
88
|
Select an instance from an interactive list. You can filter the instances by name.
|
|
@@ -73,7 +99,10 @@ Options:
|
|
|
73
99
|
-r, --region TEXT Which AWS region to use
|
|
74
100
|
-u, --user TEXT Which user to connect as
|
|
75
101
|
--private / --public Connect to the instance's private or public IP
|
|
76
|
-
-k, --key-file
|
|
102
|
+
-k, --key-file FILE Which key file to use to connect
|
|
103
|
+
--scrollback INTEGER RANGE
|
|
104
|
+
Lines of scrollback per shell. Defaults to your tmux or
|
|
105
|
+
Windows Terminal setting, else 1000. [x>=0]
|
|
77
106
|
--help Show this message and exit.
|
|
78
107
|
```
|
|
79
108
|
|
|
@@ -92,7 +121,10 @@ Options:
|
|
|
92
121
|
-r, --region TEXT Which AWS region to use
|
|
93
122
|
-u, --user TEXT Which user to connect as
|
|
94
123
|
--private / --public Connect to the instance's private or public IP
|
|
95
|
-
-k, --key-file
|
|
124
|
+
-k, --key-file FILE Which key file to use to connect
|
|
125
|
+
--scrollback INTEGER RANGE
|
|
126
|
+
Lines of scrollback per shell. Defaults to your tmux or
|
|
127
|
+
Windows Terminal setting, else 1000. [x>=0]
|
|
96
128
|
--help Show this message and exit.
|
|
97
129
|
```
|
|
98
130
|
|
|
@@ -113,6 +145,6 @@ Options:
|
|
|
113
145
|
-r, --region TEXT Which AWS region to use
|
|
114
146
|
-u, --user TEXT Which user to connect as
|
|
115
147
|
--private / --public Connect to the instance's private or public IP
|
|
116
|
-
-k, --key-file
|
|
148
|
+
-k, --key-file FILE Which key file to use to connect
|
|
117
149
|
--help Show this message and exit.
|
|
118
150
|
```
|
|
@@ -1,79 +1,114 @@
|
|
|
1
|
-
# AWS SSH Utils
|
|
2
|
-
|
|
3
|
-
[](https://pypi.org/project/aws-ssh-utils/)
|
|
4
|
-
[](#)
|
|
5
|
-
[](https://pypi.org/project/aws-ssh-utils/)
|
|
6
|
-
|
|
7
|
-
```shell
|
|
8
|
-
pip install aws-ssh-utils
|
|
9
|
-
|
|
10
|
-
aws_ssh ec2
|
|
11
|
-
|
|
12
|
-
aws_ssh emr
|
|
13
|
-
|
|
14
|
-
aws_ssh emr-all
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
--
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
1
|
+
# AWS SSH Utils
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/aws-ssh-utils/)
|
|
4
|
+
[](#)
|
|
5
|
+
[](https://pypi.org/project/aws-ssh-utils/)
|
|
6
|
+
|
|
7
|
+
```shell
|
|
8
|
+
pip install aws-ssh-utils
|
|
9
|
+
|
|
10
|
+
aws_ssh ec2
|
|
11
|
+
|
|
12
|
+
aws_ssh emr
|
|
13
|
+
|
|
14
|
+
aws_ssh emr-all
|
|
15
|
+
|
|
16
|
+
aws_ssh app
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This allows you to interactively SSH to an EC2 instance, EMR instance, or all EMR instances with TMUX.
|
|
20
|
+
|
|
21
|
+
It utilizes [questionary](https://pypi.org/project/questionary/) to ask you which instance you want to connect to.
|
|
22
|
+
|
|
23
|
+
## App
|
|
24
|
+
|
|
25
|
+
Terminal UI to browse EC2 instances and EMR clusters, with SSH shells in tabs.
|
|
26
|
+
It's the default command, so `aws_ssh` and `aws_ssh -p my-profile` launch it too.
|
|
27
|
+
Each connection tries, in order: `~/.ssh/config`, SSH over AWS SSM (`session-manager-plugin`), opkssh (via instance/cluster tags),
|
|
28
|
+
the instance's EC2 key found in `~/.ssh`, then your default keys/ssh-agent.
|
|
29
|
+
Unknown host keys are accepted and appended to `~/.ssh/known_hosts`; changed host keys are rejected.
|
|
30
|
+
|
|
31
|
+
```shell
|
|
32
|
+
$ aws_ssh app --help
|
|
33
|
+
Usage: aws_ssh app [OPTIONS]
|
|
34
|
+
|
|
35
|
+
Browse EC2 instances and EMR clusters, and open SSH shells in tabs.
|
|
36
|
+
|
|
37
|
+
Options:
|
|
38
|
+
-p, --profile TEXT Which AWS profile to use
|
|
39
|
+
-r, --region TEXT Which AWS region to use
|
|
40
|
+
--scrollback INTEGER RANGE Lines of scrollback per shell. Defaults to your
|
|
41
|
+
tmux or Windows Terminal setting, else 1000.
|
|
42
|
+
[x>=0]
|
|
43
|
+
--help Show this message and exit.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Scroll back with the mouse wheel or `shift+PgUp`/`shift+PgDn`; typing jumps back to the prompt.
|
|
47
|
+
`F12` shows/hides the sidebar, `ctrl+w` closes a failed tab, `ctrl+q` quits. Every other key goes to the focused shell.
|
|
48
|
+
Logs are viewable with `textual console`.
|
|
49
|
+
|
|
50
|
+
## EC2
|
|
51
|
+
|
|
52
|
+
Select an instance from an interactive list. You can filter the instances by name.
|
|
53
|
+
|
|
54
|
+
```shell
|
|
55
|
+
$ aws_auth ec2 --help
|
|
56
|
+
Usage: aws_ssh ec2 [OPTIONS]
|
|
57
|
+
|
|
58
|
+
Asks user which EC2 instance they want to connect to, then opens an
|
|
59
|
+
interactive SSH session to the instance
|
|
60
|
+
|
|
61
|
+
Options:
|
|
62
|
+
-p, --profile TEXT Which AWS profile to use
|
|
63
|
+
-r, --region TEXT Which AWS region to use
|
|
64
|
+
-u, --user TEXT Which user to connect as
|
|
65
|
+
--private / --public Connect to the instance's private or public IP
|
|
66
|
+
-k, --key-file FILE Which key file to use to connect
|
|
67
|
+
--scrollback INTEGER RANGE
|
|
68
|
+
Lines of scrollback per shell. Defaults to your tmux or
|
|
69
|
+
Windows Terminal setting, else 1000. [x>=0]
|
|
70
|
+
--help Show this message and exit.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## EMR
|
|
74
|
+
|
|
75
|
+
Select the EMR cluster, instance group, and instance to connect to.
|
|
76
|
+
|
|
77
|
+
```shell
|
|
78
|
+
$ aws_ssh emr --help
|
|
79
|
+
Usage: aws_ssh emr [OPTIONS]
|
|
80
|
+
|
|
81
|
+
Asks user which Cluster and EC2 instance they want to connect to, then opens an interactive SSH session to the instance
|
|
82
|
+
|
|
83
|
+
Options:
|
|
84
|
+
-p, --profile TEXT Which AWS profile to use
|
|
85
|
+
-r, --region TEXT Which AWS region to use
|
|
86
|
+
-u, --user TEXT Which user to connect as
|
|
87
|
+
--private / --public Connect to the instance's private or public IP
|
|
88
|
+
-k, --key-file FILE Which key file to use to connect
|
|
89
|
+
--scrollback INTEGER RANGE
|
|
90
|
+
Lines of scrollback per shell. Defaults to your tmux or
|
|
91
|
+
Windows Terminal setting, else 1000. [x>=0]
|
|
92
|
+
--help Show this message and exit.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## EMR All
|
|
96
|
+
|
|
97
|
+
Select the EMR cluster to connect to. Then creates a new TMUX session with a window per instance. Each window will have an SSH connection to that instance open.
|
|
98
|
+
|
|
99
|
+
```shell
|
|
100
|
+
$ aws_ssh emr-all --help
|
|
101
|
+
Usage: aws_ssh emr-all [OPTIONS]
|
|
102
|
+
|
|
103
|
+
Asks user which Cluster and EC2 instance they want to connect to, Then
|
|
104
|
+
prints a tmux cli statement that will open a new session with a window per
|
|
105
|
+
ec2 instance with ssh shell already opened.
|
|
106
|
+
|
|
107
|
+
Options:
|
|
108
|
+
-p, --profile TEXT Which AWS profile to use
|
|
109
|
+
-r, --region TEXT Which AWS region to use
|
|
110
|
+
-u, --user TEXT Which user to connect as
|
|
111
|
+
--private / --public Connect to the instance's private or public IP
|
|
112
|
+
-k, --key-file FILE Which key file to use to connect
|
|
113
|
+
--help Show this message and exit.
|
|
114
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.5"
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""Shared helpers for the interactive (questionary based) commands."""
|
|
2
|
+
|
|
3
|
+
import ctypes
|
|
4
|
+
import functools
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from shutil import which
|
|
12
|
+
from typing import ParamSpec, TypeVar
|
|
13
|
+
|
|
14
|
+
import click
|
|
15
|
+
import paramiko
|
|
16
|
+
import questionary
|
|
17
|
+
from botocore.exceptions import ClientError
|
|
18
|
+
from loguru import logger
|
|
19
|
+
from rich.console import Console
|
|
20
|
+
from rich.markup import escape
|
|
21
|
+
from rich.status import Status
|
|
22
|
+
|
|
23
|
+
from aws_ssh_utils.commands.healthcheck import is_aws_ssm_installed, is_opkssh_installed
|
|
24
|
+
from aws_ssh_utils.connection import Environment, Target, connect, open_shell_channel
|
|
25
|
+
from aws_ssh_utils.terminal import ShellApp
|
|
26
|
+
|
|
27
|
+
P = ParamSpec('P')
|
|
28
|
+
R = TypeVar('R')
|
|
29
|
+
|
|
30
|
+
DEFAULT_SCROLLBACK = 1000
|
|
31
|
+
WINDOWS_TERMINAL_DEFAULT_SCROLLBACK = 9001
|
|
32
|
+
WINDOWS_TERMINAL_SETTINGS = (
|
|
33
|
+
'Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json',
|
|
34
|
+
'Packages/Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe/LocalState/settings.json',
|
|
35
|
+
'Microsoft/Windows Terminal/settings.json',
|
|
36
|
+
)
|
|
37
|
+
"""Relative to %LOCALAPPDATA%: Store, Store preview, and unpackaged installs."""
|
|
38
|
+
|
|
39
|
+
console = Console(stderr=True)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ShellError(Exception):
|
|
43
|
+
def __init__(self, message: str, exit_code: int = 1):
|
|
44
|
+
super().__init__(message, exit_code)
|
|
45
|
+
self.message: str = message
|
|
46
|
+
self.exit_code: int = exit_code
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def spinner(message: str = '') -> Status:
|
|
50
|
+
return console.status(message, spinner='dots')
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def handle_errors(func: Callable[P, R]) -> Callable[P, R]:
|
|
54
|
+
"""Log ShellErrors and AWS errors, and exit, instead of printing a traceback."""
|
|
55
|
+
|
|
56
|
+
@functools.wraps(func)
|
|
57
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
58
|
+
try:
|
|
59
|
+
return func(*args, **kwargs)
|
|
60
|
+
except ShellError as e:
|
|
61
|
+
logger.error(e.message)
|
|
62
|
+
sys.exit(e.exit_code)
|
|
63
|
+
except ClientError as e:
|
|
64
|
+
if e.response.get('Error', {}).get('Code') == 'ExpiredTokenException':
|
|
65
|
+
logger.critical('Your AWS Token has expired. Please update and try again.')
|
|
66
|
+
else:
|
|
67
|
+
logger.error(e)
|
|
68
|
+
sys.exit(1)
|
|
69
|
+
|
|
70
|
+
return wrapper
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def set_terminal_title(title: str = ''):
|
|
74
|
+
if os.name == 'nt':
|
|
75
|
+
ctypes.windll.kernel32.SetConsoleTitleW(title) # pyright: ignore[reportAttributeAccessIssue]
|
|
76
|
+
elif os.getenv('TMUX'):
|
|
77
|
+
sys.stdout.write(f"\33k{title}\33")
|
|
78
|
+
sys.stdout.flush()
|
|
79
|
+
else:
|
|
80
|
+
sys.stdout.write(f"\33]0;{title}\a")
|
|
81
|
+
sys.stdout.flush()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def detect_environment(profile: str | None, region: str | None) -> Environment:
|
|
85
|
+
return Environment(
|
|
86
|
+
ssm_installed=is_aws_ssm_installed() and which('aws') is not None,
|
|
87
|
+
opkssh_installed=is_opkssh_installed(),
|
|
88
|
+
profile=profile,
|
|
89
|
+
region=region,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def detect_scrollback() -> int:
|
|
94
|
+
"""The scrollback of the terminal we run in, when it can be read (tmux, Windows Terminal)."""
|
|
95
|
+
if os.getenv('TMUX'):
|
|
96
|
+
try:
|
|
97
|
+
result = subprocess.run(
|
|
98
|
+
['tmux', 'show-options', '-gv', 'history-limit'], # noqa: S607
|
|
99
|
+
capture_output=True,
|
|
100
|
+
text=True,
|
|
101
|
+
check=True,
|
|
102
|
+
timeout=5,
|
|
103
|
+
)
|
|
104
|
+
return int(result.stdout)
|
|
105
|
+
except (OSError, subprocess.SubprocessError, ValueError) as e:
|
|
106
|
+
logger.debug(f"Could not read tmux history-limit: {e}")
|
|
107
|
+
if os.getenv('WT_SESSION'):
|
|
108
|
+
return windows_terminal_history_size()
|
|
109
|
+
return DEFAULT_SCROLLBACK
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def windows_terminal_history_size() -> int:
|
|
113
|
+
"""`historySize` of the current Windows Terminal profile, falling back to the profile defaults."""
|
|
114
|
+
local_app_data = Path(os.getenv('LOCALAPPDATA', ''))
|
|
115
|
+
for settings_file in WINDOWS_TERMINAL_SETTINGS:
|
|
116
|
+
try:
|
|
117
|
+
settings = json.loads((local_app_data / settings_file).read_text(encoding='utf-8'))
|
|
118
|
+
except (OSError, ValueError):
|
|
119
|
+
continue
|
|
120
|
+
profiles = settings.get('profiles', {})
|
|
121
|
+
# Older settings files have a plain list of profiles
|
|
122
|
+
profile_list = profiles.get('list', []) if isinstance(profiles, dict) else profiles
|
|
123
|
+
defaults = profiles.get('defaults', {}) if isinstance(profiles, dict) else {}
|
|
124
|
+
profile_id = os.getenv('WT_PROFILE_ID', '').lower()
|
|
125
|
+
profile = next((p for p in profile_list if p.get('guid', '').lower() == profile_id), {})
|
|
126
|
+
return int(profile.get('historySize', defaults.get('historySize', WINDOWS_TERMINAL_DEFAULT_SCROLLBACK)))
|
|
127
|
+
return WINDOWS_TERMINAL_DEFAULT_SCROLLBACK
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
scrollback_option = click.option(
|
|
131
|
+
'--scrollback',
|
|
132
|
+
type=click.IntRange(min=0),
|
|
133
|
+
default=None,
|
|
134
|
+
help="Lines of scrollback per shell. Defaults to your tmux or Windows Terminal setting, else 1000.",
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def confirm_host_key(hostname: str, key: paramiko.PKey) -> bool:
|
|
139
|
+
logger.warning(f"Unknown {key.get_name()} host key for {hostname}: {key.fingerprint}")
|
|
140
|
+
return questionary.confirm("Continue and add host key?").unsafe_ask()
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def open_shell(target: Target, env: Environment, title: str, scrollback: int | None, initial_input: bytes = b''):
|
|
144
|
+
"""Connect to the target, then show the shell full-screen until it closes.
|
|
145
|
+
|
|
146
|
+
`scrollback` defaults to the terminal's own setting, see `detect_scrollback`.
|
|
147
|
+
"""
|
|
148
|
+
result = connect(target, env, on_output=logger.info, on_waiting=lambda: None, confirm_host_key=confirm_host_key)
|
|
149
|
+
if isinstance(result, list):
|
|
150
|
+
for line in result:
|
|
151
|
+
console.print(escape(line))
|
|
152
|
+
raise ShellError(f'Failed to connect to {target.user}@{target.ip}')
|
|
153
|
+
|
|
154
|
+
channel = open_shell_channel(result.client)
|
|
155
|
+
if initial_input:
|
|
156
|
+
channel.send(initial_input)
|
|
157
|
+
|
|
158
|
+
set_terminal_title(title)
|
|
159
|
+
# Logs, e.g. AWS SSM's stderr, would draw over the full-screen shell.
|
|
160
|
+
logger.disable('aws_ssh_utils')
|
|
161
|
+
try:
|
|
162
|
+
ShellApp(result.via, result.client, channel, detect_scrollback() if scrollback is None else scrollback).run()
|
|
163
|
+
finally:
|
|
164
|
+
logger.enable('aws_ssh_utils')
|
|
165
|
+
set_terminal_title()
|