diff --git a/changelogs/fragments/httpapi-get_file.yaml b/changelogs/fragments/httpapi-get_file.yaml new file mode 100644 index 000000000..97dfffc2b --- /dev/null +++ b/changelogs/fragments/httpapi-get_file.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: + - httpapi - New method `get_file()` to download large files from the remote API. diff --git a/galaxy.yml b/galaxy.yml index 1d2a7a750..2465bcff8 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -13,4 +13,4 @@ readme: README.md repository: https://github.com/ansible-collections/ansible.netcommon issues: https://github.com/ansible-collections/ansible.netcommon/issues tags: [networking, security, cloud, network_cli, netconf, httpapi, grpc] -version: 5.1.1 +version: 5.2.0-dev diff --git a/plugins/connection/httpapi.py b/plugins/connection/httpapi.py index 46876e6ad..fa5ecd398 100644 --- a/plugins/connection/httpapi.py +++ b/plugins/connection/httpapi.py @@ -273,10 +273,7 @@ def close(self): super(Connection, self).close() @ensure_connect - def send(self, path, data, retries=None, **kwargs): - """ - Sends the command to the device over api - """ + def _open_url(self, path, data=None, retries=None, **kwargs): url_kwargs = dict( timeout=self.get_option("persistent_command_timeout"), validate_certs=self.get_option("validate_certs"), @@ -307,13 +304,13 @@ def send(self, path, data, retries=None, **kwargs): url_kwargs["url_username"] = self.get_option("remote_user") url_kwargs["url_password"] = self.get_option("password") + url = self._url + path + self._log_messages( + "send url '%s' with data '%s' and kwargs '%s'" + % (url, data, url_kwargs) + ) try: - url = self._url + path - self._log_messages( - "send url '%s' with data '%s' and kwargs '%s'" - % (url, data, url_kwargs) - ) - response = open_url(url, data=data, **url_kwargs) + return open_url(url, data=data, **url_kwargs) except HTTPError as exc: is_handled = self.handle_httperror(exc) if is_handled is True: @@ -325,7 +322,7 @@ def send(self, path, data, retries=None, **kwargs): raise if is_handled is False: raise - response = is_handled + return is_handled except URLError as exc: raise AnsibleConnectionFailure( "Could not connect to {0}: {1}".format( @@ -333,6 +330,13 @@ def send(self, path, data, retries=None, **kwargs): ) ) + @ensure_connect + def send(self, path, data, retries=None, **kwargs): + """ + Sends the command to the device over api + """ + response = self._open_url(path, data, retries, **kwargs) + response_buffer = BytesIO() resp_data = response.read() self._log_messages("received response: '%s'" % resp_data) @@ -345,6 +349,18 @@ def send(self, path, data, retries=None, **kwargs): return response, response_buffer + def get_file(self, path, dest, **kwargs): + """Download the contents of path to dest""" + response = self._open_url(path, **kwargs) + self._log_messages("writing response to '%s'" % dest) + + buffer_size = 65536 + data = response.read(buffer_size) + with open(dest, "wb") as output_file: + while data: + output_file.write(data) + data = response.read(buffer_size) + def transport_test(self, connect_timeout): """This method enables wait_for_connection to work.