Simon Marsh
6117bcd7bf
All checks were successful
continuous-integration/drone/push Build is passing
161 lines
3.5 KiB
Go
161 lines
3.5 KiB
Go
//////////////////////////////////////////////////////////////////////////
|
|
|
|
package main
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
import (
|
|
// log "github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
|
|
"encoding/json"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"os"
|
|
|
|
vault "git.burble.dn42/burble.dn42/libvault"
|
|
)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
var (
|
|
TLSCertPEM string
|
|
TLSKeyPEM string
|
|
TLSCAPEM string
|
|
TLSRequest string
|
|
TLSRenewToken bool
|
|
)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// helper funcs
|
|
|
|
func loadRequest(filename string) *vault.TLSRequest {
|
|
|
|
content, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: failed to read request file (%s): %s\n",
|
|
filename, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
request := &vault.TLSRequest{}
|
|
if err := json.Unmarshal(content, request); err != nil {
|
|
fmt.Printf("ERROR: failed to parse request file (%s): %s\n",
|
|
filename, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
return request
|
|
}
|
|
|
|
func writePEM(filename string, blocks []*pem.Block) {
|
|
|
|
file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0600)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: failed to create PEM file (%s): %s\n",
|
|
filename, err)
|
|
os.Exit(1)
|
|
}
|
|
defer file.Close()
|
|
|
|
for _, block := range blocks {
|
|
if err := pem.Encode(file, block); err != nil {
|
|
fmt.Printf("ERROR: failed to write PEM block (%s): %s\n",
|
|
filename, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
func CmdTLSRenew(cmd *cobra.Command, args []string) {
|
|
|
|
// load token and TLS request parameters
|
|
token := loadToken()
|
|
request := loadRequest(TLSRequest)
|
|
|
|
if TLSRenewToken {
|
|
err := token.Renew(vault.VAULT_TTL)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: failed to renew token: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// load existing cert if it existed
|
|
if info, err := os.Stat(TLSCertPEM); err == nil && info.Size() > 0 {
|
|
fmt.Printf("Loading existing certificate: %s\n", TLSCertPEM)
|
|
|
|
data, err := os.ReadFile(TLSCertPEM)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: failed to read existing certificate: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
block, _ := pem.Decode(data)
|
|
if block == nil || block.Type != "CERTIFICATE" {
|
|
fmt.Println("ERROR: failed to parse PEM block")
|
|
os.Exit(1)
|
|
}
|
|
|
|
// check if certificate needed renewing
|
|
renew, err := request.CheckRenew(block.Bytes)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: failed to check existing certificate: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if !renew {
|
|
// nothing to do
|
|
fmt.Println("Renewal not required, no action")
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
|
|
// issue the cert
|
|
kc, err := request.Issue(token)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: failed to issue TLS cert: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// write out the certs
|
|
fmt.Println("Success ! updating certs")
|
|
|
|
fmt.Printf(" - Certificate: %s\n", TLSCertPEM)
|
|
if err := os.WriteFile(
|
|
TLSCertPEM,
|
|
[]byte(kc.Certificate+"\n"+kc.IssuingCA+"\n"),
|
|
0600,
|
|
); err != nil {
|
|
fmt.Printf("ERROR: failed to write certificate: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Printf(" - Private Key: %s\n", TLSKeyPEM)
|
|
if err := os.WriteFile(
|
|
TLSKeyPEM,
|
|
[]byte(kc.PrivateKey+"\n"),
|
|
0600,
|
|
); err != nil {
|
|
fmt.Printf("ERROR: failed to write key: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Printf(" - CA: %s\n", TLSCAPEM)
|
|
if err := os.WriteFile(
|
|
TLSCAPEM,
|
|
[]byte(kc.IssuingCA+"\n"),
|
|
0600,
|
|
); err != nil {
|
|
fmt.Printf("ERROR: failed to write CA: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
os.Exit(0)
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// end of code
|