2023-07-04 16:38:22 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"strconv"
|
2023-07-04 17:54:42 +02:00
|
|
|
"strings"
|
2023-07-04 16:38:22 +02:00
|
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"go.uber.org/zap/zapcore"
|
|
|
|
)
|
|
|
|
|
|
|
|
type pluginConfig struct {
|
|
|
|
check_syntax bool
|
|
|
|
check bool
|
|
|
|
diff bool
|
|
|
|
verbosity int64
|
|
|
|
limit *string
|
|
|
|
tags *string
|
|
|
|
privateKey *string
|
|
|
|
vaultToken *string
|
|
|
|
galaxyFile *string
|
|
|
|
playbook *string
|
|
|
|
}
|
|
|
|
|
|
|
|
func runCommand(sugar *zap.SugaredLogger, args ...string) {
|
|
|
|
sugar.Infof("➡️ %s", args)
|
|
|
|
cmd := exec.Command(args[0], args[1:]...)
|
|
|
|
cmd.Env = os.Environ()
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
err := cmd.Run()
|
|
|
|
if err != nil {
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func getPluginConfig(sugar *zap.SugaredLogger) pluginConfig {
|
|
|
|
config := pluginConfig{}
|
|
|
|
|
|
|
|
check_syntax, present := os.LookupEnv("PLUGIN_CHECK_SYNTAX")
|
|
|
|
if !present {
|
|
|
|
config.check_syntax = false
|
|
|
|
} else {
|
|
|
|
converted, err := strconv.ParseBool(check_syntax)
|
|
|
|
if err != nil {
|
|
|
|
sugar.Fatal(err)
|
|
|
|
}
|
|
|
|
config.check_syntax = converted
|
|
|
|
}
|
|
|
|
|
|
|
|
check, present := os.LookupEnv("PLUGIN_CHECK")
|
|
|
|
if !present {
|
|
|
|
config.check = false
|
|
|
|
} else {
|
|
|
|
converted, err := strconv.ParseBool(check)
|
|
|
|
if err != nil {
|
|
|
|
sugar.Fatal(err)
|
|
|
|
}
|
|
|
|
config.check = converted
|
|
|
|
}
|
|
|
|
|
|
|
|
diff, present := os.LookupEnv("PLUGIN_DIFF")
|
|
|
|
if !present {
|
|
|
|
config.diff = false
|
|
|
|
} else {
|
|
|
|
converted, err := strconv.ParseBool(diff)
|
|
|
|
if err != nil {
|
|
|
|
sugar.Fatal(err)
|
|
|
|
}
|
|
|
|
config.diff = converted
|
|
|
|
}
|
|
|
|
|
|
|
|
verbosity, present := os.LookupEnv("PLUGIN_VERBOSITY")
|
|
|
|
if !present {
|
|
|
|
config.verbosity = 0
|
|
|
|
} else {
|
|
|
|
converted, err := strconv.ParseInt(verbosity, 10, 0)
|
|
|
|
if err != nil {
|
|
|
|
sugar.Fatal(err)
|
|
|
|
}
|
|
|
|
config.verbosity = converted
|
|
|
|
}
|
|
|
|
|
|
|
|
limit, present := os.LookupEnv("PLUGIN_LIMIT")
|
|
|
|
if !present {
|
|
|
|
config.limit = nil
|
|
|
|
} else {
|
|
|
|
config.limit = &limit
|
|
|
|
}
|
|
|
|
|
|
|
|
tags, present := os.LookupEnv("PLUGIN_TAGS")
|
|
|
|
if !present {
|
|
|
|
config.tags = nil
|
|
|
|
} else {
|
|
|
|
config.tags = &tags
|
|
|
|
}
|
|
|
|
|
|
|
|
privateKey, present := os.LookupEnv("PLUGIN_PRIVATE_KEY")
|
|
|
|
if !present {
|
|
|
|
sugar.Warn("⚠️ 'private_key' setting not defined !")
|
|
|
|
config.privateKey = nil
|
|
|
|
} else {
|
|
|
|
config.privateKey = &privateKey
|
|
|
|
}
|
|
|
|
|
|
|
|
vaultToken, present := os.LookupEnv("PLUGIN_VAULT_TOKEN")
|
|
|
|
if !present {
|
|
|
|
config.vaultToken = nil
|
|
|
|
} else {
|
|
|
|
config.vaultToken = &vaultToken
|
|
|
|
}
|
|
|
|
|
|
|
|
galaxyFile, present := os.LookupEnv("PLUGIN_GALAXY_FILE")
|
|
|
|
if !present {
|
|
|
|
config.galaxyFile = nil
|
|
|
|
} else {
|
|
|
|
config.galaxyFile = &galaxyFile
|
|
|
|
}
|
|
|
|
|
|
|
|
playbook, present := os.LookupEnv("PLUGIN_PLAYBOOK")
|
|
|
|
if !present {
|
|
|
|
sugar.Fatal("⚠️ 'playbook' setting not defined, ABORT!")
|
|
|
|
} else {
|
|
|
|
config.playbook = &playbook
|
|
|
|
}
|
|
|
|
|
|
|
|
return config
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
// encoderConfig := zapcore.EncoderConfig{
|
|
|
|
// MessageKey: "message",
|
|
|
|
// LevelKey: "level",
|
|
|
|
// EncodeLevel: zapcore.CapitalColorLevelEncoder,
|
|
|
|
// EncodeDuration: zapcore.StringDurationEncoder,
|
|
|
|
// EncodeCaller: zapcore.ShortCallerEncoder,
|
|
|
|
// }
|
|
|
|
// encoder := zapcore.NewConsoleEncoder(encoderConfig)
|
|
|
|
// core := zapcore.NewCore(encoder, os.Stdout, zapcore.InfoLevel)
|
|
|
|
config := zap.NewProductionConfig()
|
|
|
|
config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
|
|
|
config.EncoderConfig.TimeKey = ""
|
|
|
|
config.Encoding = "console"
|
|
|
|
config.DisableCaller = true
|
|
|
|
config.DisableStacktrace = true
|
|
|
|
logger, _ := config.Build()
|
|
|
|
defer logger.Sync()
|
|
|
|
sugar := logger.Sugar()
|
|
|
|
|
|
|
|
sugar.Info("Woodpecker Ansible Runner")
|
|
|
|
pluginConfig := getPluginConfig(sugar)
|
|
|
|
|
|
|
|
if pluginConfig.privateKey != nil {
|
2023-07-04 17:11:26 +02:00
|
|
|
sugar.Info("🔑 Adding ssh key to .ssh/id_ed25519")
|
|
|
|
os.MkdirAll("/root/.ssh", 0700)
|
2023-07-04 17:54:42 +02:00
|
|
|
if !strings.HasSuffix(*pluginConfig.privateKey, "\n") {
|
|
|
|
*pluginConfig.privateKey = *pluginConfig.privateKey + "\n"
|
|
|
|
}
|
2023-07-04 16:38:22 +02:00
|
|
|
err := os.WriteFile("/root/.ssh/id_ed25519", []byte(*pluginConfig.privateKey), 0400)
|
|
|
|
if err != nil {
|
|
|
|
sugar.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
args := []string{*pluginConfig.playbook}
|
|
|
|
|
|
|
|
if pluginConfig.vaultToken != nil {
|
|
|
|
sugar.Info("💼 Adding vault token to 'credentials/ci_vault_token'")
|
2023-07-04 17:11:26 +02:00
|
|
|
os.MkdirAll("credentials", 0755)
|
2023-07-04 16:38:22 +02:00
|
|
|
err := os.WriteFile("credentials/ci_vault_token", []byte(*pluginConfig.vaultToken), 0644)
|
|
|
|
if err != nil {
|
|
|
|
sugar.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
args = append(args, "--vault-password-file=credentials/ci_vault_token")
|
|
|
|
|
|
|
|
sugar.Info("⚙️ Clean ansible.cfg")
|
|
|
|
runCommand(sugar, "sed", "-i", "/vault_password_file.*/d", "./ansible.cfg")
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := os.Stat("ansible-ci.cfg"); err == nil {
|
|
|
|
sugar.Info("⚙️ ansible-ci.cfg is present, using it.")
|
|
|
|
os.Remove("ansible.cfg")
|
|
|
|
os.Rename("ansible-ci.cfg", "ansible.cfg")
|
|
|
|
}
|
|
|
|
|
|
|
|
if pluginConfig.galaxyFile != nil {
|
|
|
|
sugar.Infof("🚀 Installing Galaxy dependencies (%s)", *pluginConfig.galaxyFile)
|
|
|
|
runCommand(sugar, "ansible-galaxy", "install", "-r", *pluginConfig.galaxyFile, "--force")
|
|
|
|
}
|
|
|
|
|
|
|
|
if pluginConfig.check_syntax {
|
|
|
|
args = append(args, "--syntax-check")
|
|
|
|
}
|
|
|
|
|
|
|
|
if pluginConfig.check {
|
|
|
|
args = append(args, "--check")
|
|
|
|
}
|
|
|
|
|
|
|
|
if pluginConfig.diff {
|
|
|
|
args = append(args, "--diff")
|
|
|
|
}
|
|
|
|
|
|
|
|
if pluginConfig.verbosity != 0 {
|
|
|
|
verb := "-"
|
|
|
|
for i := 0; i < int(pluginConfig.verbosity); i++ {
|
|
|
|
verb += "v"
|
|
|
|
}
|
|
|
|
args = append(args, verb)
|
|
|
|
}
|
|
|
|
|
|
|
|
if pluginConfig.limit != nil {
|
|
|
|
args = append(args, "--limit", *pluginConfig.limit)
|
|
|
|
}
|
|
|
|
|
|
|
|
if pluginConfig.tags != nil {
|
|
|
|
args = append(args, "--tags", *pluginConfig.tags)
|
|
|
|
}
|
|
|
|
|
|
|
|
command := append([]string{"ansible-playbook"}, args...)
|
|
|
|
runCommand(sugar, command...)
|
|
|
|
}
|