Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possibility to add more options to the SSH and SCP commands #16

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions charms/osm/sshproxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import io
import ipaddress
from typing import List
from packaging import version
import subprocess
import os
Expand Down Expand Up @@ -359,7 +360,7 @@ def get_ssh_private_key():
def has_ssh_key():
return True if os.path.exists(SSHProxy.private_key_path) else False

def run(self, cmd: str) -> (str, str):
def run(self, cmd: str, ssh_options: List[str] = None) -> (str, str):
"""Run a command remotely via SSH.

Note: The previous behavior was to run the command locally if SSH wasn't
Expand All @@ -368,6 +369,8 @@ def run(self, cmd: str) -> (str, str):
"""
if isinstance(cmd, str):
cmd = shlex.split(cmd)
if isinstance(ssh_options, str):
ssh_options = shlex.split(ssh_options)

host = self._get_hostname()
user = self.username
Expand All @@ -376,20 +379,23 @@ def run(self, cmd: str) -> (str, str):

# Make sure we have everything we need to connect
if host and user:
return self.ssh(cmd)
return self.ssh(cmd, ssh_options)

raise Exception("Invalid SSH credentials.")

def scp(self, source_file, destination_file):
def scp(self, source_file, destination_file, ssh_options: List[str] = None):
"""Execute an scp command. Requires a fully qualified source and
destination.

:param str source_file: Path to the source file
:param str destination_file: Path to the destination file
:param list(str) ssh_options: The options to pass to the SCP command
:raises: :class:`CalledProcessError` if the command fails
"""
if which("sshpass") is None:
SSHProxy.install()
if ssh_options is None:
oEscal marked this conversation as resolved.
Show resolved Hide resolved
ssh_options = []
cmd = [
"sshpass",
"-p",
Expand All @@ -398,23 +404,27 @@ def scp(self, source_file, destination_file):
"-i",
os.path.expanduser(self.private_key_path),
"-o",
*[p for opt in zip(['-o'] * len(ssh_options), ssh_options) for p in opt],
"StrictHostKeyChecking=no",
"-q",
]
destination = "{}@{}:{}".format(self.username, self.hostname, destination_file)
cmd.extend([source_file, destination])
subprocess.run(cmd, check=True)

def ssh(self, command):
def ssh(self, command, ssh_options: List[str] = None):
"""Run a command remotely via SSH.

:param list(str) command: The command to execute
:param list(str) ssh_options: The options to pass to the SSH command
:return: tuple: The stdout and stderr of the command execution
:raises: :class:`CalledProcessError` if the command fails
"""

if which("sshpass") is None:
SSHProxy.install()
if ssh_options is None:
ssh_options = []
destination = "{}@{}".format(self.username, self.hostname)
cmd = [
"sshpass",
Expand All @@ -425,6 +435,7 @@ def ssh(self, command):
os.path.expanduser(self.private_key_path),
"-o",
"StrictHostKeyChecking=no",
*[p for opt in zip(['-o']*len(ssh_options), ssh_options) for p in opt],
"-q",
destination,
]
Expand Down