|
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.
|
|
360 | 383 | from ansible.utils.display import Display
|
361 | 384 |
|
362 | 385 | from ansible_collections.amazon.aws.plugins.module_utils.botocore import HAS_BOTO3
|
| 386 | +from ansible_collections.community.aws.plugins.plugin_utils.ssm_file_transfer import PortForwardingFileTransferManager |
363 | 387 |
|
364 | 388 | from ansible_collections.community.aws.plugins.plugin_utils.s3clientmanager import S3ClientManager
|
365 | 389 |
|
@@ -472,6 +496,7 @@ class Connection(ConnectionBase):
|
472 | 496 | _stdout = None
|
473 | 497 | _session_id = ""
|
474 | 498 | _timeout = False
|
| 499 | + _filetransfer_mgr = None |
475 | 500 | MARK_LENGTH = 26
|
476 | 501 |
|
477 | 502 | def __init__(self, *args: Any, **kwargs: Any) -> None:
|
@@ -515,19 +540,39 @@ def _init_clients(self) -> None:
|
515 | 540 | profile_name = self.get_option("profile") or ""
|
516 | 541 | region_name = self.get_option("region")
|
517 | 542 |
|
518 |
| - # Initialize S3ClientManager |
519 |
| - self.s3_manager = S3ClientManager(self) |
520 |
| - |
521 |
| - # Initialize S3 client |
522 |
| - s3_endpoint_url, s3_region_name = self.s3_manager.get_bucket_endpoint() |
523 |
| - self._vvvv(f"SETUP BOTO3 CLIENTS: S3 {s3_endpoint_url}") |
524 |
| - self.s3_manager.initialize_client( |
525 |
| - region_name=s3_region_name, endpoint_url=s3_endpoint_url, profile_name=profile_name |
526 |
| - ) |
527 |
| - self._s3_client = self.s3_manager._s3_client |
528 |
| - |
529 | 543 | # Initialize SSM client
|
530 | 544 | self._initialize_ssm_client(region_name, profile_name)
|
| 545 | + if self._use_bucket(): |
| 546 | + # Initialize S3ClientManager |
| 547 | + self.s3_manager = S3ClientManager(self) |
| 548 | + |
| 549 | + # Initialize S3 client |
| 550 | + s3_endpoint_url, s3_region_name = self.s3_manager.get_bucket_endpoint() |
| 551 | + self._vvvv(f"SETUP BOTO3 CLIENTS: S3 {s3_endpoint_url}") |
| 552 | + self.s3_manager.initialize_client( |
| 553 | + region_name=s3_region_name, endpoint_url=s3_endpoint_url, profile_name=profile_name |
| 554 | + ) |
| 555 | + self._s3_client = self.s3_manager._s3_client |
| 556 | + else: |
| 557 | + self._initialize_file_transfer_manager() |
| 558 | + |
| 559 | + def _initialize_file_transfer_manager(self) -> None: |
| 560 | + ssm_timeout = self.get_option("ssm_timeout") |
| 561 | + region_name = self.get_option("region") |
| 562 | + profile_name = self.get_option("profile") or "" |
| 563 | + host_port = self.get_option("host_port_number") |
| 564 | + local_port = self.get_option("local_port_number") |
| 565 | + self._filetransfer_mgr = PortForwardingFileTransferManager( |
| 566 | + self.host, |
| 567 | + ssm_client=self._client, |
| 568 | + instance_id=self.instance_id, |
| 569 | + executable=self.get_executable(), |
| 570 | + ssm_timeout=ssm_timeout, |
| 571 | + region_name=region_name, |
| 572 | + profile_name=profile_name, |
| 573 | + host_port=host_port, |
| 574 | + local_port=local_port, |
| 575 | + ) |
531 | 576 |
|
532 | 577 | def _initialize_ssm_client(self, region_name: Optional[str], profile_name: str) -> None:
|
533 | 578 | """
|
@@ -572,6 +617,10 @@ def reset(self) -> Any:
|
572 | 617 | self.close()
|
573 | 618 | return self.start_session()
|
574 | 619 |
|
| 620 | + def _use_bucket(self) -> bool: |
| 621 | + """return true if the file transfer is performed using s3 bucket""" |
| 622 | + return self.is_windows or self.get_option("bucket_name") |
| 623 | + |
575 | 624 | @property
|
576 | 625 | def instance_id(self) -> str:
|
577 | 626 | if not self._instance_id:
|
@@ -1088,15 +1137,21 @@ def put_file(self, in_path: str, out_path: str) -> Tuple[int, str, str]:
|
1088 | 1137 | if not os.path.exists(to_bytes(in_path, errors="surrogate_or_strict")):
|
1089 | 1138 | raise AnsibleFileNotFound(f"file or module does not exist: {in_path}")
|
1090 | 1139 |
|
1091 |
| - return self._file_transport_command(in_path, out_path, "put") |
| 1140 | + if self._use_bucket(): |
| 1141 | + return self._file_transport_command(in_path, out_path, "put") |
| 1142 | + else: |
| 1143 | + return self._filetransfer_mgr.put_file(in_path, out_path) |
1092 | 1144 |
|
1093 | 1145 | def fetch_file(self, in_path: str, out_path: str) -> Tuple[int, str, str]:
|
1094 | 1146 | """fetch a file from remote to local"""
|
1095 | 1147 |
|
1096 | 1148 | super().fetch_file(in_path, out_path)
|
1097 | 1149 |
|
1098 | 1150 | self._vvv(f"FETCH {in_path} TO {out_path}")
|
1099 |
| - return self._file_transport_command(in_path, out_path, "get") |
| 1151 | + if self._use_bucket(): |
| 1152 | + return self._file_transport_command(in_path, out_path, "get") |
| 1153 | + else: |
| 1154 | + return self._filetransfer_mgr.fetch_file(in_path, out_path) |
1100 | 1155 |
|
1101 | 1156 | def close(self) -> None:
|
1102 | 1157 | """terminate the connection"""
|
|
0 commit comments