Merge branch 'sgpublic-forks-feat/pre_command'

This commit is contained in:
yoan 2024-09-28 07:05:02 +08:00
commit 9797a0835d
6 changed files with 78 additions and 47 deletions

View File

@ -19,14 +19,15 @@ type ssh struct {
} }
type sshAccess struct { type sshAccess struct {
Host string `json:"host"` Host string `json:"host"`
Username string `json:"username"` Username string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
Key string `json:"key"` Key string `json:"key"`
Port string `json:"port"` Port string `json:"port"`
Command string `json:"command"` PreCommand string `json:"preCommand"`
CertPath string `json:"certPath"` Command string `json:"command"`
KeyPath string `json:"keyPath"` CertPath string `json:"certPath"`
KeyPath string `json:"keyPath"`
} }
func NewSSH(option *DeployerOption) (Deployer, error) { func NewSSH(option *DeployerOption) (Deployer, error) {
@ -56,6 +57,7 @@ func (s *ssh) Deploy(ctx context.Context) error {
access.CertPath = strings.ReplaceAll(access.CertPath, key, v) access.CertPath = strings.ReplaceAll(access.CertPath, key, v)
access.KeyPath = strings.ReplaceAll(access.KeyPath, key, v) access.KeyPath = strings.ReplaceAll(access.KeyPath, key, v)
access.Command = strings.ReplaceAll(access.Command, key, v) access.Command = strings.ReplaceAll(access.Command, key, v)
access.PreCommand = strings.ReplaceAll(access.PreCommand, key, v)
} }
// 连接 // 连接
@ -67,14 +69,13 @@ func (s *ssh) Deploy(ctx context.Context) error {
s.infos = append(s.infos, toStr("ssh连接成功", nil)) s.infos = append(s.infos, toStr("ssh连接成功", nil))
// 上传 // 执行前置命令
session, err := client.NewSession() if access.PreCommand != "" {
if err != nil { err, stdout, stderr := s.sshExecCommand(client, access.Command)
return fmt.Errorf("failed to create session: %w", err) if err != nil {
return fmt.Errorf("failed to run pre-command: %w, stdout: %s, stderr: %s", err, stdout, stderr)
}
} }
defer session.Close()
s.infos = append(s.infos, toStr("ssh创建session成功", nil))
// 上传证书 // 上传证书
if err := s.upload(client, s.option.Certificate.Certificate, access.CertPath); err != nil { if err := s.upload(client, s.option.Certificate.Certificate, access.CertPath); err != nil {
@ -91,18 +92,28 @@ func (s *ssh) Deploy(ctx context.Context) error {
s.infos = append(s.infos, toStr("ssh上传私钥成功", nil)) s.infos = append(s.infos, toStr("ssh上传私钥成功", nil))
// 执行命令 // 执行命令
err, stdout, stderr := s.sshExecCommand(client, access.Command)
if err != nil {
return fmt.Errorf("failed to run command: %w, stdout: %s, stderr: %s", err, stdout, stderr)
}
s.infos = append(s.infos, toStr("ssh执行命令成功", stdout))
return nil
}
func (s *ssh) sshExecCommand(client *sshPkg.Client, command string) (error, string, string) {
session, err := client.NewSession()
if err != nil {
return fmt.Errorf("failed to create ssh session: %w", err), "", ""
}
defer session.Close()
var stdoutBuf bytes.Buffer var stdoutBuf bytes.Buffer
session.Stdout = &stdoutBuf session.Stdout = &stdoutBuf
var stderrBuf bytes.Buffer var stderrBuf bytes.Buffer
session.Stderr = &stderrBuf session.Stderr = &stderrBuf
err = session.Run(command)
if err := session.Run(access.Command); err != nil { return err, stdoutBuf.String(), stderrBuf.String()
return fmt.Errorf("failed to run command: %w, stdout: %s, stderr: %s", err, stdoutBuf.String(), stderrBuf.String())
}
s.infos = append(s.infos, toStr("ssh执行命令成功", []string{stdoutBuf.String()}))
return nil
} }
func (s *ssh) upload(client *sshPkg.Client, content, path string) error { func (s *ssh) upload(client *sshPkg.Client, content, path string) error {

File diff suppressed because one or more lines are too long

2
ui/dist/index.html vendored
View File

@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Certimate - Your Trusted SSL Automation Partner</title> <title>Certimate - Your Trusted SSL Automation Partner</title>
<script type="module" crossorigin src="/assets/index-BnLdUh-0.js"></script> <script type="module" crossorigin src="/assets/index-CQVPrK_Y.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Djc_JtNf.css"> <link rel="stylesheet" crossorigin href="/assets/index-Djc_JtNf.css">
</head> </head>
<body class="bg-background"> <body class="bg-background">

View File

@ -4,7 +4,7 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite --host",
"build": "tsc -b && vite build", "build": "tsc -b && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview" "preview": "vite preview"

View File

@ -79,6 +79,7 @@ const AccessSSHForm = ({
key: z.string().min(0).max(20480), key: z.string().min(0).max(20480),
keyFile: z.any().optional(), keyFile: z.any().optional(),
command: z.string().min(1).max(2048), command: z.string().min(1).max(2048),
preCommand: z.string().min(0).max(2048).optional(),
certPath: z.string().min(0).max(2048), certPath: z.string().min(0).max(2048),
keyPath: z.string().min(0).max(2048), keyPath: z.string().min(0).max(2048),
}); });
@ -90,6 +91,7 @@ const AccessSSHForm = ({
password: "", password: "",
key: "", key: "",
keyFile: "", keyFile: "",
preCommand: "",
command: "sudo service nginx restart", command: "sudo service nginx restart",
certPath: "/etc/nginx/ssl/certificate.crt", certPath: "/etc/nginx/ssl/certificate.crt",
keyPath: "/etc/nginx/ssl/private.key", keyPath: "/etc/nginx/ssl/private.key",
@ -112,6 +114,7 @@ const AccessSSHForm = ({
certPath: config.certPath, certPath: config.certPath,
keyPath: config.keyPath, keyPath: config.keyPath,
command: config.command, command: config.command,
preCommand: config.preCommand,
}, },
}); });
@ -133,6 +136,7 @@ const AccessSSHForm = ({
password: data.password, password: data.password,
key: data.key, key: data.key,
command: data.command, command: data.command,
preCommand: data.preCommand,
certPath: data.certPath, certPath: data.certPath,
keyPath: data.keyPath, keyPath: data.keyPath,
}, },
@ -468,6 +472,21 @@ const AccessSSHForm = ({
)} )}
/> />
<FormField
control={form.control}
name="preCommand"
render={({ field }) => (
<FormItem>
<FormLabel> Command</FormLabel>
<FormControl>
<Textarea placeholder="请输入要在部署证书前执行的前置命令" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField <FormField
control={form.control} control={form.control}
name="command" name="command"

View File

@ -89,6 +89,7 @@ export type GodaddyConfig = {
export type SSHConfig = { export type SSHConfig = {
host: string; host: string;
port: string; port: string;
preCommand?: string;
command: string; command: string;
username: string; username: string;
password?: string; password?: string;