mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-08 13:39:53 +00:00
164 lines
4.2 KiB
Go
164 lines
4.2 KiB
Go
package deployer
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os/exec"
|
|
"runtime"
|
|
|
|
"github.com/usual2970/certimate/internal/domain"
|
|
"github.com/usual2970/certimate/internal/pkg/utils/fs"
|
|
)
|
|
|
|
type LocalDeployer struct {
|
|
option *DeployerOption
|
|
infos []string
|
|
}
|
|
|
|
const (
|
|
certFormatPEM = "pem"
|
|
certFormatPFX = "pfx"
|
|
certFormatJKS = "jks"
|
|
)
|
|
|
|
const (
|
|
shellEnvSh = "sh"
|
|
shellEnvCmd = "cmd"
|
|
shellEnvPowershell = "powershell"
|
|
)
|
|
|
|
func NewLocalDeployer(option *DeployerOption) (Deployer, error) {
|
|
return &LocalDeployer{
|
|
option: option,
|
|
infos: make([]string, 0),
|
|
}, nil
|
|
}
|
|
|
|
func (d *LocalDeployer) GetID() string {
|
|
return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
|
|
}
|
|
|
|
func (d *LocalDeployer) GetInfo() []string {
|
|
return []string{}
|
|
}
|
|
|
|
func (d *LocalDeployer) Deploy(ctx context.Context) error {
|
|
access := &domain.LocalAccess{}
|
|
if err := json.Unmarshal([]byte(d.option.Access), access); err != nil {
|
|
return err
|
|
}
|
|
|
|
// 执行前置命令
|
|
preCommand := d.option.DeployConfig.GetConfigAsString("preCommand")
|
|
if preCommand != "" {
|
|
stdout, stderr, err := d.execCommand(preCommand)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to run pre-command: %w, stdout: %s, stderr: %s", err, stdout, stderr)
|
|
}
|
|
|
|
d.infos = append(d.infos, toStr("执行前置命令成功", stdout))
|
|
}
|
|
|
|
// 写入证书和私钥文件
|
|
switch d.option.DeployConfig.GetConfigOrDefaultAsString("format", certFormatPEM) {
|
|
case certFormatPEM:
|
|
if err := fs.WriteFileString(d.option.DeployConfig.GetConfigAsString("certPath"), d.option.Certificate.Certificate); err != nil {
|
|
return fmt.Errorf("failed to save certificate file: %w", err)
|
|
}
|
|
|
|
d.infos = append(d.infos, toStr("保存证书成功", nil))
|
|
|
|
if err := fs.WriteFileString(d.option.DeployConfig.GetConfigAsString("keyPath"), d.option.Certificate.PrivateKey); err != nil {
|
|
return fmt.Errorf("failed to save private key file: %w", err)
|
|
}
|
|
|
|
d.infos = append(d.infos, toStr("保存私钥成功", nil))
|
|
|
|
case certFormatPFX:
|
|
pfxData, err := convertPEMToPFX(
|
|
d.option.Certificate.Certificate,
|
|
d.option.Certificate.PrivateKey,
|
|
d.option.DeployConfig.GetConfigAsString("pfxPassword"),
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to convert pem to pfx %w", err)
|
|
}
|
|
|
|
if err := fs.WriteFile(d.option.DeployConfig.GetConfigAsString("certPath"), pfxData); err != nil {
|
|
return fmt.Errorf("failed to save certificate file: %w", err)
|
|
}
|
|
|
|
d.infos = append(d.infos, toStr("保存证书成功", nil))
|
|
|
|
case certFormatJKS:
|
|
jksData, err := convertPEMToJKS(
|
|
d.option.Certificate.Certificate,
|
|
d.option.Certificate.PrivateKey,
|
|
d.option.DeployConfig.GetConfigAsString("jksAlias"),
|
|
d.option.DeployConfig.GetConfigAsString("jksKeypass"),
|
|
d.option.DeployConfig.GetConfigAsString("jksStorepass"),
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to convert pem to pfx %w", err)
|
|
}
|
|
|
|
if err := fs.WriteFile(d.option.DeployConfig.GetConfigAsString("certPath"), jksData); err != nil {
|
|
return fmt.Errorf("failed to save certificate file: %w", err)
|
|
}
|
|
|
|
d.infos = append(d.infos, toStr("保存证书成功", nil))
|
|
}
|
|
|
|
// 执行命令
|
|
command := d.option.DeployConfig.GetConfigAsString("command")
|
|
if command != "" {
|
|
stdout, stderr, err := d.execCommand(command)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to run command: %w, stdout: %s, stderr: %s", err, stdout, stderr)
|
|
}
|
|
|
|
d.infos = append(d.infos, toStr("执行命令成功", stdout))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *LocalDeployer) execCommand(command string) (string, string, error) {
|
|
var cmd *exec.Cmd
|
|
|
|
switch d.option.DeployConfig.GetConfigAsString("shell") {
|
|
case shellEnvSh:
|
|
cmd = exec.Command("sh", "-c", command)
|
|
|
|
case shellEnvCmd:
|
|
cmd = exec.Command("cmd", "/C", command)
|
|
|
|
case shellEnvPowershell:
|
|
cmd = exec.Command("powershell", "-Command", command)
|
|
|
|
case "":
|
|
if runtime.GOOS == "windows" {
|
|
cmd = exec.Command("cmd", "/C", command)
|
|
} else {
|
|
cmd = exec.Command("sh", "-c", command)
|
|
}
|
|
|
|
default:
|
|
return "", "", fmt.Errorf("unsupported shell")
|
|
}
|
|
|
|
var stdoutBuf bytes.Buffer
|
|
cmd.Stdout = &stdoutBuf
|
|
var stderrBuf bytes.Buffer
|
|
cmd.Stderr = &stderrBuf
|
|
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
return "", "", fmt.Errorf("failed to execute script: %w", err)
|
|
}
|
|
|
|
return stdoutBuf.String(), stderrBuf.String(), err
|
|
}
|