mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-09 05:59:50 +00:00
feat: support ssh key passphrase
This commit is contained in:
parent
79dce124a7
commit
71f43c5bd4
@ -18,11 +18,12 @@ type ssh struct {
|
||||
}
|
||||
|
||||
type sshAccess struct {
|
||||
Host string `json:"host"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Key string `json:"key"`
|
||||
Port string `json:"port"`
|
||||
Host string `json:"host"`
|
||||
Port string `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Key string `json:"key"`
|
||||
KeyPassphrase string `json:"keyPassphrase"`
|
||||
}
|
||||
|
||||
func NewSSH(option *DeployerOption) (Deployer, error) {
|
||||
@ -45,6 +46,7 @@ func (s *ssh) Deploy(ctx context.Context) error {
|
||||
if err := json.Unmarshal([]byte(s.option.Access), access); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 连接
|
||||
client, err := s.getClient(access)
|
||||
if err != nil {
|
||||
@ -57,7 +59,7 @@ func (s *ssh) Deploy(ctx context.Context) error {
|
||||
// 执行前置命令
|
||||
preCommand := getDeployString(s.option.DeployConfig, "preCommand")
|
||||
if preCommand != "" {
|
||||
err, stdout, stderr := s.sshExecCommand(client, preCommand)
|
||||
stdout, stderr, err := s.sshExecCommand(client, preCommand)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to run pre-command: %w, stdout: %s, stderr: %s", err, stdout, stderr)
|
||||
}
|
||||
@ -78,7 +80,7 @@ func (s *ssh) Deploy(ctx context.Context) error {
|
||||
s.infos = append(s.infos, toStr("ssh上传私钥成功", nil))
|
||||
|
||||
// 执行命令
|
||||
err, stdout, stderr := s.sshExecCommand(client, getDeployString(s.option.DeployConfig, "command"))
|
||||
stdout, stderr, err := s.sshExecCommand(client, getDeployString(s.option.DeployConfig, "command"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to run command: %w, stdout: %s, stderr: %s", err, stdout, stderr)
|
||||
}
|
||||
@ -88,18 +90,19 @@ func (s *ssh) Deploy(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ssh) sshExecCommand(client *sshPkg.Client, command string) (error, string, string) {
|
||||
func (s *ssh) sshExecCommand(client *sshPkg.Client, command string) (string, string, error) {
|
||||
session, err := client.NewSession()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create ssh session: %w", err), "", ""
|
||||
return "", "", fmt.Errorf("failed to create ssh session: %w", err)
|
||||
}
|
||||
|
||||
defer session.Close()
|
||||
var stdoutBuf bytes.Buffer
|
||||
session.Stdout = &stdoutBuf
|
||||
var stderrBuf bytes.Buffer
|
||||
session.Stderr = &stderrBuf
|
||||
err = session.Run(command)
|
||||
return err, stdoutBuf.String(), stderrBuf.String()
|
||||
return stdoutBuf.String(), stderrBuf.String(), err
|
||||
}
|
||||
|
||||
func (s *ssh) upload(client *sshPkg.Client, content, path string) error {
|
||||
@ -131,7 +134,15 @@ func (s *ssh) getClient(access *sshAccess) (*sshPkg.Client, error) {
|
||||
var authMethod sshPkg.AuthMethod
|
||||
|
||||
if access.Key != "" {
|
||||
signer, err := sshPkg.ParsePrivateKey([]byte(access.Key))
|
||||
var signer sshPkg.Signer
|
||||
var err error
|
||||
|
||||
if access.KeyPassphrase != "" {
|
||||
signer, err = sshPkg.ParsePrivateKeyWithPassphrase([]byte(access.Key), []byte(access.KeyPassphrase))
|
||||
} else {
|
||||
signer, err = sshPkg.ParsePrivateKey([]byte(access.Key))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
324
ui/dist/assets/index-DipHpsma.js
vendored
324
ui/dist/assets/index-DipHpsma.js
vendored
File diff suppressed because one or more lines are too long
6
ui/dist/index.html
vendored
6
ui/dist/index.html
vendored
@ -5,10 +5,10 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Certimate - Your Trusted SSL Automation Partner</title>
|
||||
<script type="module" crossorigin src="/assets/index-DipHpsma.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CV_7sKTK.css">
|
||||
<script type="module" crossorigin src="/assets/index-DIhd7QG6.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CV_7sKTK.css">
|
||||
</head>
|
||||
<body class="bg-background">
|
||||
<div id="root"></div>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -66,17 +66,21 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
.max(5, t("common.errmsg.string_max", { max: 5 })),
|
||||
username: z
|
||||
.string()
|
||||
.min(1, "username.not.empty")
|
||||
.min(1, "access.authorization.form.ssh_username.placeholder")
|
||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
||||
password: z
|
||||
.string()
|
||||
.min(0, "password.not.empty")
|
||||
.min(0, "access.authorization.form.ssh_password.placeholder")
|
||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
||||
key: z
|
||||
.string()
|
||||
.min(0, "access.authorization.form.ssh_key.placeholder")
|
||||
.max(20480, t("common.errmsg.string_max", { max: 20480 })),
|
||||
keyFile: z.any().optional(),
|
||||
keyPassphrase: z
|
||||
.string()
|
||||
.min(0, "access.authorization.form.ssh_key_passphrase.placeholder")
|
||||
.max(2048, t("common.errmsg.string_max", { max: 2048 })),
|
||||
});
|
||||
|
||||
let config: SSHConfig = {
|
||||
@ -86,6 +90,7 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
password: "",
|
||||
key: "",
|
||||
keyFile: "",
|
||||
keyPassphrase: "",
|
||||
};
|
||||
if (data) config = data.config as SSHConfig;
|
||||
|
||||
@ -102,6 +107,7 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
password: config.password,
|
||||
key: config.key,
|
||||
keyFile: config.keyFile,
|
||||
keyPassphrase: config.keyPassphrase,
|
||||
},
|
||||
});
|
||||
|
||||
@ -121,6 +127,7 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
username: data.username,
|
||||
password: data.password,
|
||||
key: data.key,
|
||||
keyPassphrase: data.keyPassphrase,
|
||||
},
|
||||
};
|
||||
|
||||
@ -322,9 +329,9 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("access.authorization.form.username.label")}</FormLabel>
|
||||
<FormLabel>{t("access.authorization.form.ssh_username.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder={t("access.authorization.form.username.placeholder")} {...field} />
|
||||
<Input placeholder={t("access.authorization.form.ssh_username.placeholder")} {...field} />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
@ -337,9 +344,9 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
name="password"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("access.authorization.form.password.label")}</FormLabel>
|
||||
<FormLabel>{t("access.authorization.form.ssh_password.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder={t("access.authorization.form.password.placeholder")} {...field} type="password" />
|
||||
<Input placeholder={t("access.authorization.form.ssh_password.placeholder")} {...field} type="password" />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
@ -390,6 +397,21 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="keyPassphrase"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("access.authorization.form.ssh_key_passphrase.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder={t("access.authorization.form.ssh_key_passphrase.placeholder")} {...field} type="password" />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormMessage />
|
||||
|
||||
<div className="flex justify-end">
|
||||
|
@ -100,6 +100,7 @@ export type SSHConfig = {
|
||||
password?: string;
|
||||
key?: string;
|
||||
keyFile?: string;
|
||||
keyPassphrase?: string;
|
||||
};
|
||||
|
||||
export type WebhookConfig = {
|
||||
|
@ -46,9 +46,15 @@
|
||||
"access.authorization.form.ssh_host.placeholder": "Please enter Host",
|
||||
"access.authorization.form.ssh_port.label": "SSH Port",
|
||||
"access.authorization.form.ssh_port.placeholder": "Please enter Port",
|
||||
"access.authorization.form.ssh_key.label": "Key (Log in using private key)",
|
||||
"access.authorization.form.ssh_username.label": "Username",
|
||||
"access.authorization.form.ssh_username.placeholder": "Please enter username",
|
||||
"access.authorization.form.ssh_password.label": "Password (Log-in using password)",
|
||||
"access.authorization.form.ssh_password.placeholder": "Please enter password",
|
||||
"access.authorization.form.ssh_key.label": "Key (Log-in using private key)",
|
||||
"access.authorization.form.ssh_key.placeholder": "Please enter Key",
|
||||
"access.authorization.form.ssh_key_file.placeholder": "Please select file",
|
||||
"access.authorization.form.ssh_key_passphrase.label": "Key Passphrase (Log-in using private key)",
|
||||
"access.authorization.form.ssh_key_passphrase.placeholder": "Please enter Key Passphrase",
|
||||
"access.authorization.form.ssh_key_path.label": "Private Key Save Path",
|
||||
"access.authorization.form.ssh_key_path.placeholder": "Please enter private key save path",
|
||||
"access.authorization.form.ssh_cert_path.label": "Certificate Save Path",
|
||||
|
@ -46,10 +46,15 @@
|
||||
"access.authorization.form.ssh_host.placeholder": "请输入 Host",
|
||||
"access.authorization.form.ssh_port.label": "SSH 端口",
|
||||
"access.authorization.form.ssh_port.placeholder": "请输入 Port",
|
||||
"access.authorization.form.ssh_username.label": "用户名",
|
||||
"access.authorization.form.ssh_username.placeholder": "请输入用户名",
|
||||
"access.authorization.form.ssh_password.label": "密码(使用密码登录)",
|
||||
"access.authorization.form.ssh_password.placeholder": "请输入密码",
|
||||
"access.authorization.form.ssh_key.label": "Key(使用私钥登录)",
|
||||
"access.authorization.form.ssh_key.placeholder": "请输入 Key",
|
||||
"access.authorization.form.ssh_key_file.placeholder": "请选择文件",
|
||||
"access.authorization.form.ssh_key.label.passphrase": "私钥密码",
|
||||
"access.authorization.form.ssh_key_passphrase.label": "Key 口令(使用私钥登录)",
|
||||
"access.authorization.form.ssh_key_passphrase.placeholder": "请输入 Key 口令",
|
||||
"access.authorization.form.ssh_key_path.label": "私钥保存路径",
|
||||
"access.authorization.form.ssh_key_path.placeholder": "请输入私钥保存路径",
|
||||
"access.authorization.form.ssh_cert_path.label": "证书保存路径",
|
||||
|
Loading…
x
Reference in New Issue
Block a user