|
86 | 86 | vars: |
87 | 87 | - name: ansible_aws_ssm_bucket_endpoint_url |
88 | 88 | version_added: 5.3.0 |
| 89 | + host_port_number: |
| 90 | + description: |
| 91 | + - The Port number of the server on the instance when using Port Forwarding Using AWS System Manager Session Manager |
| 92 | + to transfer files from/to local host to/from remote host. |
| 93 | + - The port V(80) is used if not provided. |
| 94 | + - The C(nc) command should be installed in the remote host to use this option. |
| 95 | + - This is not supported for Windows hosts for now. |
| 96 | + type: integer |
| 97 | + default: 80 |
| 98 | + vars: |
| 99 | + - name: ansible_aws_ssm_host_port_number |
| 100 | + version_added: 9.3.0 |
| 101 | + local_port_number: |
| 102 | + description: |
| 103 | + - Port number on local machine to forward traffic to when using Port Forwarding Using AWS System Manager Session Manager |
| 104 | + to transfer files from/to local host to/from remote host. |
| 105 | + - An open port is chosen at run-time if not provided. |
| 106 | + - The C(nc) command should be installed in the remote host to use this option. |
| 107 | + - This is not supported for Windows hosts for now. |
| 108 | + type: integer |
| 109 | + vars: |
| 110 | + - name: ansible_aws_ssm_local_port_number |
| 111 | + version_added: 9.3.0 |
89 | 112 | plugin: |
90 | 113 | description: |
91 | 114 | - This defines the location of the session-manager-plugin binary. |
|
359 | 382 | from ansible.utils.display import Display |
360 | 383 |
|
361 | 384 | from ansible_collections.amazon.aws.plugins.module_utils.botocore import HAS_BOTO3 |
| 385 | +from ansible_collections.community.aws.plugins.plugin_utils.ssm_file_transfer import PortForwardingFileTransferManager |
362 | 386 |
|
363 | 387 | display = Display() |
364 | 388 |
|
@@ -469,6 +493,7 @@ class Connection(ConnectionBase): |
469 | 493 | _stdout = None |
470 | 494 | _session_id = "" |
471 | 495 | _timeout = False |
| 496 | + _filetransfer_mgr = None |
472 | 497 | MARK_LENGTH = 26 |
473 | 498 |
|
474 | 499 | def __init__(self, *args, **kwargs): |
@@ -517,8 +542,29 @@ def _init_clients(self) -> None: |
517 | 542 | # Initialize SSM client |
518 | 543 | self._initialize_ssm_client(region_name, profile_name) |
519 | 544 |
|
520 | | - # Initialize S3 client |
521 | | - self._initialize_s3_client(profile_name) |
| 545 | + if self._should_use_port_forwarding_for_file_transfer(): |
| 546 | + # Initialize S3 client |
| 547 | + self._initialize_s3_client(profile_name) |
| 548 | + else: |
| 549 | + self._initialize_file_transfer_manager() |
| 550 | + |
| 551 | + def _initialize_file_transfer_manager(self) -> None: |
| 552 | + ssm_timeout = self.get_option("ssm_timeout") |
| 553 | + region_name = self.get_option("region") |
| 554 | + profile_name = self.get_option("profile") or "" |
| 555 | + host_port = self.get_option("host_port_number") |
| 556 | + local_port = self.get_option("local_port_number") |
| 557 | + self._filetransfer_mgr = PortForwardingFileTransferManager( |
| 558 | + self.host, |
| 559 | + ssm_client=self._client, |
| 560 | + instance_id=self.instance_id, |
| 561 | + executable=self.get_executable(), |
| 562 | + ssm_timeout=ssm_timeout, |
| 563 | + region_name=region_name, |
| 564 | + profile_name=profile_name, |
| 565 | + host_port=host_port, |
| 566 | + local_port=local_port, |
| 567 | + ) |
522 | 568 |
|
523 | 569 | def _initialize_ssm_client(self, region_name: Optional[str], profile_name: str) -> None: |
524 | 570 | """ |
@@ -621,6 +667,10 @@ def reset(self): |
621 | 667 | self.close() |
622 | 668 | return self.start_session() |
623 | 669 |
|
| 670 | + def _should_use_port_forwarding_for_file_transfer(self) -> bool: |
| 671 | + """return true if the user has defined a bucket_name to be used for transport""" |
| 672 | + return (not self.is_windows and self.get_option("bucket_name") is not None) |
| 673 | + |
624 | 674 | @property |
625 | 675 | def instance_id(self) -> str: |
626 | 676 | if not self._instance_id: |
@@ -1159,15 +1209,21 @@ def put_file(self, in_path, out_path): |
1159 | 1209 | if not os.path.exists(to_bytes(in_path, errors="surrogate_or_strict")): |
1160 | 1210 | raise AnsibleFileNotFound(f"file or module does not exist: {in_path}") |
1161 | 1211 |
|
1162 | | - return self._file_transport_command(in_path, out_path, "put") |
| 1212 | + if self._should_use_port_forwarding_for_file_transfer(): |
| 1213 | + return self._file_transport_command(in_path, out_path, "put") |
| 1214 | + else: |
| 1215 | + return self._filetransfer_mgr.put_file(in_path, out_path) |
1163 | 1216 |
|
1164 | 1217 | def fetch_file(self, in_path, out_path): |
1165 | 1218 | """fetch a file from remote to local""" |
1166 | 1219 |
|
1167 | 1220 | super().fetch_file(in_path, out_path) |
1168 | 1221 |
|
1169 | 1222 | self._vvv(f"FETCH {in_path} TO {out_path}") |
1170 | | - return self._file_transport_command(in_path, out_path, "get") |
| 1223 | + if self._should_use_port_forwarding_for_file_transfer(): |
| 1224 | + return self._file_transport_command(in_path, out_path, "get") |
| 1225 | + else: |
| 1226 | + return self._filetransfer_mgr.fetch_file(in_path, out_path) |
1171 | 1227 |
|
1172 | 1228 | def close(self): |
1173 | 1229 | """terminate the connection""" |
|
0 commit comments