feat: allow fallback to use scp on deployment to ssh

This commit is contained in:
Fu Diwei
2025-01-23 23:47:37 +08:00
parent 5ee5460612
commit 9f7cffce21
9 changed files with 69 additions and 10 deletions

View File

@@ -10,6 +10,7 @@ import (
xerrors "github.com/pkg/errors"
"github.com/pkg/sftp"
"github.com/povsister/scp"
"golang.org/x/crypto/ssh"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
@@ -32,6 +33,8 @@ type SshDeployerConfig struct {
SshKey string `json:"sshKey,omitempty"`
// SSH 登录私钥口令。
SshKeyPassphrase string `json:"sshKeyPassphrase,omitempty"`
// 是否回退使用 SCP。
UseSCP bool `json:"useSCP,omitempty"`
// 前置命令。
PreCommand string `json:"preCommand,omitempty"`
// 后置命令。
@@ -112,13 +115,13 @@ func (d *SshDeployer) Deploy(ctx context.Context, certPem string, privkeyPem str
// 上传证书和私钥文件
switch d.config.OutputFormat {
case OUTPUT_FORMAT_PEM:
if err := writeSftpFileString(client, d.config.OutputCertPath, certPem); err != nil {
if err := writeFileString(client, d.config.UseSCP, d.config.OutputCertPath, certPem); err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
}
d.logger.Logt("certificate file uploaded")
if err := writeSftpFileString(client, d.config.OutputKeyPath, privkeyPem); err != nil {
if err := writeFileString(client, d.config.UseSCP, d.config.OutputKeyPath, privkeyPem); err != nil {
return nil, xerrors.Wrap(err, "failed to upload private key file")
}
@@ -132,7 +135,7 @@ func (d *SshDeployer) Deploy(ctx context.Context, certPem string, privkeyPem str
d.logger.Logt("certificate transformed to PFX")
if err := writeSftpFile(client, d.config.OutputCertPath, pfxData); err != nil {
if err := writeFile(client, d.config.UseSCP, d.config.OutputCertPath, pfxData); err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
}
@@ -146,7 +149,7 @@ func (d *SshDeployer) Deploy(ctx context.Context, certPem string, privkeyPem str
d.logger.Logt("certificate transformed to JKS")
if err := writeSftpFile(client, d.config.OutputCertPath, jksData); err != nil {
if err := writeFile(client, d.config.UseSCP, d.config.OutputCertPath, jksData); err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
}
@@ -223,11 +226,47 @@ func execSshCommand(sshCli *ssh.Client, command string) (string, string, error)
return stdoutBuf.String(), stderrBuf.String(), nil
}
func writeSftpFileString(sshCli *ssh.Client, path string, content string) error {
return writeSftpFile(sshCli, path, []byte(content))
func writeFileString(sshCli *ssh.Client, useSCP bool, path string, content string) error {
if useSCP {
return writeFileStringWithSCP(sshCli, path, content)
}
return writeFileStringWithSFTP(sshCli, path, content)
}
func writeSftpFile(sshCli *ssh.Client, path string, data []byte) error {
func writeFile(sshCli *ssh.Client, useSCP bool, path string, data []byte) error {
if useSCP {
return writeFileWithSCP(sshCli, path, data)
}
return writeFileWithSFTP(sshCli, path, data)
}
func writeFileStringWithSCP(sshCli *ssh.Client, path string, content string) error {
return writeFileWithSCP(sshCli, path, []byte(content))
}
func writeFileWithSCP(sshCli *ssh.Client, path string, data []byte) error {
scpCli, err := scp.NewClientFromExistingSSH(sshCli, &scp.ClientOption{})
if err != nil {
return xerrors.Wrap(err, "failed to create scp client")
}
defer scpCli.Close()
reader := bytes.NewReader(data)
err = scpCli.CopyToRemote(reader, path, &scp.FileTransferOption{})
if err != nil {
return xerrors.Wrap(err, "failed to write to remote file")
}
return nil
}
func writeFileStringWithSFTP(sshCli *ssh.Client, path string, content string) error {
return writeFileWithSFTP(sshCli, path, []byte(content))
}
func writeFileWithSFTP(sshCli *ssh.Client, path string, data []byte) error {
sftpCli, err := sftp.NewClient(sshCli)
if err != nil {
return xerrors.Wrap(err, "failed to create sftp client")