Python

PythonでローカルデータをEC2インスタンスにコピーする方法

概要

EC2インスタンスにファイルやフォルダをごとコピーしたい時のプログラムを作りました。

sftp_to_ec2.py
import os
import paramiko

def _path_join(path, paths):
    """
    パスのジョイン対応(Windows対応版)
    :param path:
    :param paths:
    :return:
    """
    return os.path.join(path, paths).replace(os.sep, '/')


def put_data_to_ec2(local_path, remote_dir,  host, port, user, private_key):
    """
    EC2へデータを格納する処理
    :param local_path:ローカルデータ(転送したいデータ)
    :param remote_dir:リモート保存先パス(ディレクトリ名)
    :param host: ホスト
    :param port: サーバポート
    :param user: リモートユーザ
    :param private_key: pemファイルパス
    :return:
    """
    if local_path[-1]==os.sep or local_path[-1]=="/" :
        local_path = local_path[:-1]

    is_dir = os.path.isdir(local_path)
    is_file = os.path.isfile(local_path)

    if not is_file and not is_dir:
        raise FileNotFoundError

    if not os.path.isfile(private_key) :
        raise FileNotFoundError

    pk = paramiko.RSAKey.from_private_key_file(private_key)
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(host, port=port, username=user, pkey=pk)

    sftp = ssh.open_sftp()
    local_dir_name = os.path.dirname(local_path) + "/"

    if is_dir:
        for file_path in get_file_path(local_path):
            file_name = os.path.basename(file_path)
            dir_name = os.path.dirname(file_path)
            dir_name = dir_name.split(local_dir_name)[1]
            remote_dir_tmp = _path_join(remote_dir, dir_name)
            remote_file_path = _path_join(remote_dir_tmp, file_name)
            # サーバのディレクトリ作成
            print("mkdir -p {}".format(remote_dir_tmp))
            ssh.exec_command("mkdir -p {}".format(remote_dir_tmp))
            # サーバにデータをコピー
            print("sftp {} {}".format(file_path, remote_file_path))
            sftp.put(file_path, remote_file_path)
    elif is_file:
        remote_file_path = _path_join(remote_dir, os.path.basename(local_path))
        sftp.put(local_path, remote_file_path)
    sftp.close()
    ssh.close()