add ability to store/create encrypted vcenter password
This commit is contained in:
80
internal/secrets/secrets.go
Normal file
80
internal/secrets/secrets.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
type Secrets struct {
|
||||
Logger *slog.Logger
|
||||
EncryptionKey []byte
|
||||
}
|
||||
|
||||
func New(logger *slog.Logger, key []byte) *Secrets {
|
||||
return &Secrets{
|
||||
Logger: logger,
|
||||
EncryptionKey: key,
|
||||
}
|
||||
}
|
||||
|
||||
// Encrypt function that encrypts data using AES256-GCM and returns base64 encoded ciphertext
|
||||
func (s *Secrets) Encrypt(plainText []byte) (string, error) {
|
||||
block, err := aes.NewCipher(s.EncryptionKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Create a new GCM cipher
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Create a nonce
|
||||
nonce := make([]byte, gcm.NonceSize())
|
||||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Encrypt the plaintext using AES256-GCM
|
||||
cipherText := gcm.Seal(nonce, nonce, plainText, nil)
|
||||
|
||||
// Return the base64 encoded ciphertext
|
||||
return base64.StdEncoding.EncodeToString(cipherText), nil
|
||||
}
|
||||
|
||||
// Decrypt function that decrypts base64 encoded AES256-GCM ciphertext
|
||||
func (s *Secrets) Decrypt(base64CipherText string) ([]byte, error) {
|
||||
// Decode the base64 ciphertext
|
||||
cipherText, err := base64.StdEncoding.DecodeString(base64CipherText)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(s.EncryptionKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create a new GCM cipher
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Extract the nonce from the ciphertext
|
||||
nonceSize := gcm.NonceSize()
|
||||
nonce, cipherText := cipherText[:nonceSize], cipherText[nonceSize:]
|
||||
|
||||
// Decrypt the ciphertext
|
||||
plainText, err := gcm.Open(nil, nonce, cipherText, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plainText, nil
|
||||
}
|
@@ -11,17 +11,6 @@ import (
|
||||
// SettingsYML struct holds various runtime data that is too cumbersome to specify via command line, eg replacement properties
|
||||
type SettingsYML struct {
|
||||
Settings struct {
|
||||
/*
|
||||
Replacements []struct {
|
||||
Key string `yaml:"Key"`
|
||||
Value string `yaml:"Value"`
|
||||
} `yaml:"replacements"`
|
||||
|
||||
Omapi struct {
|
||||
KeyName string `yaml:"key_name"`
|
||||
KeySecret string `yaml:"key_secret"`
|
||||
} `yaml:"omapi"`
|
||||
*/
|
||||
TenantsToFilter []string `yaml:"tenants_to_filter"`
|
||||
NodeChargeClusters []string `yaml:"node_charge_clusters"`
|
||||
SrmActiveActiveVms []string `yaml:"srm_activeactive_vms"`
|
||||
|
@@ -5,21 +5,12 @@ import (
|
||||
"database/sql"
|
||||
"log/slog"
|
||||
"time"
|
||||
"vctp/db"
|
||||
"vctp/db/queries"
|
||||
"vctp/internal/settings"
|
||||
"vctp/internal/vcenter"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
// Handler handles requests.
|
||||
type CronTask struct {
|
||||
Logger *slog.Logger
|
||||
Database db.Database
|
||||
Settings settings.SettingsYML
|
||||
}
|
||||
|
||||
// use gocron to check events in the Events table
|
||||
func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
|
||||
var (
|
||||
@@ -42,6 +33,8 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
|
||||
if err != nil {
|
||||
logger.Error("Unable to query for unprocessed events", "error", err)
|
||||
return nil // TODO - what to do with this error?
|
||||
} else {
|
||||
logger.Debug("Successfully queried for unprocessed events", "count", len(events))
|
||||
}
|
||||
|
||||
for _, evt := range events {
|
||||
@@ -51,7 +44,7 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
|
||||
// to avoid doing unnecessary login/logout of vcenter
|
||||
|
||||
c.Logger.Debug("connecting to vcenter")
|
||||
vc := vcenter.New(c.Logger)
|
||||
vc := vcenter.New(c.Logger, c.VcCreds)
|
||||
vc.Login(evt.Source)
|
||||
|
||||
//datacenter = evt.DatacenterName.String
|
||||
|
16
internal/tasks/tasks.go
Normal file
16
internal/tasks/tasks.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"vctp/db"
|
||||
"vctp/internal/settings"
|
||||
"vctp/internal/vcenter"
|
||||
)
|
||||
|
||||
// CronTask stores runtime information to be used by tasks
|
||||
type CronTask struct {
|
||||
Logger *slog.Logger
|
||||
Database db.Database
|
||||
Settings settings.SettingsYML
|
||||
VcCreds *vcenter.VcenterLogin
|
||||
}
|
@@ -19,9 +19,15 @@ import (
|
||||
)
|
||||
|
||||
type Vcenter struct {
|
||||
Logger *slog.Logger
|
||||
ctx context.Context
|
||||
client *govmomi.Client
|
||||
Logger *slog.Logger
|
||||
ctx context.Context
|
||||
client *govmomi.Client
|
||||
credentials *VcenterLogin
|
||||
}
|
||||
|
||||
type VcenterLogin struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type VmProperties struct {
|
||||
@@ -30,23 +36,25 @@ type VmProperties struct {
|
||||
}
|
||||
|
||||
// New creates a new Vcenter with the given logger
|
||||
func New(logger *slog.Logger) *Vcenter {
|
||||
func New(logger *slog.Logger, creds *VcenterLogin) *Vcenter {
|
||||
|
||||
//ctx, cancel := context.WithCancel(context.Background())
|
||||
//defer cancel()
|
||||
|
||||
return &Vcenter{
|
||||
Logger: logger,
|
||||
ctx: context.Background(),
|
||||
Logger: logger,
|
||||
ctx: context.Background(),
|
||||
credentials: creds,
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Vcenter) Login(vUrl string) error {
|
||||
var insecure bool
|
||||
|
||||
// TODO - fix this
|
||||
insecureString := os.Getenv("VCENTER_INSECURE")
|
||||
username := os.Getenv("VCENTER_USERNAME")
|
||||
password := os.Getenv("VCENTER_PASSWORD")
|
||||
//username := os.Getenv("VCENTER_USERNAME")
|
||||
//password := os.Getenv("VCENTER_PASSWORD")
|
||||
|
||||
// Connect to vCenter
|
||||
u, err := soap.ParseURL(vUrl)
|
||||
@@ -54,7 +62,7 @@ func (v *Vcenter) Login(vUrl string) error {
|
||||
log.Fatalf("Error parsing vCenter URL: %s", err)
|
||||
}
|
||||
|
||||
u.User = url.UserPassword(username, password)
|
||||
u.User = url.UserPassword(v.credentials.Username, v.credentials.Password)
|
||||
|
||||
/*
|
||||
c, err := govmomi.NewClient(ctx, u, insecure)
|
||||
@@ -77,7 +85,7 @@ func (v *Vcenter) Login(vUrl string) error {
|
||||
|
||||
v.client = c
|
||||
|
||||
v.Logger.Debug("successfully connected to vCenter", "url", vUrl, "username", username)
|
||||
v.Logger.Debug("successfully connected to vCenter", "url", vUrl, "username", v.credentials.Username)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user