update database schema to avoid bool confusion
Some checks are pending
CI / Lint (push) Waiting to run
CI / Test (push) Waiting to run
CI / End-to-End (push) Waiting to run
CI / Publish Docker (push) Blocked by required conditions
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-09-27 11:07:51 +10:00
parent b371e28469
commit c691763430
8 changed files with 214 additions and 72 deletions

View File

@@ -0,0 +1,56 @@
-- +goose Up
-- +goose StatementBegin
ALTER TABLE "Inventory" RENAME COLUMN IsTemplate TO IsTemplate_old;
ALTER TABLE "Inventory" RENAME COLUMN PowerState TO PowerState_old;
ALTER TABLE "Inventory" RENAME COLUMN SrmPlaceholder TO SrmPlaceholder_old;
ALTER TABLE "Inventory" ADD COLUMN IsTemplate TEXT NOT NULL DEFAULT "FALSE";
ALTER TABLE "Inventory" ADD COLUMN PoweredOn TEXT NOT NULL DEFAULT "FALSE";
ALTER TABLE "Inventory" ADD COLUMN SrmPlaceholder TEXT NOT NULL DEFAULT "FALSE";
UPDATE Inventory
SET IsTemplate = CASE
WHEN IsTemplate_old = 1 THEN 'TRUE'
ELSE 'FALSE'
END;
UPDATE Inventory
SET PoweredOn = CASE
WHEN PowerState_old = 1 THEN 'TRUE'
ELSE 'FALSE'
END;
UPDATE Inventory
SET SrmPlaceholder = CASE
WHEN SrmPlaceholder_old = 1 THEN 'TRUE'
ELSE 'FALSE'
END;
ALTER TABLE "Inventory" DROP COLUMN IsTemplate_old;
ALTER TABLE "Inventory" DROP COLUMN PowerState_old;
ALTER TABLE "Inventory" DROP COLUMN SrmPlaceholder_old;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
ALTER TABLE "Inventory" RENAME COLUMN IsTemplate TO IsTemplate_old;
ALTER TABLE "Inventory" RENAME COLUMN PoweredOn TO PoweredOn_old;
ALTER TABLE "Inventory" RENAME COLUMN SrmPlaceholder TO SrmPlaceholder_old;
ALTER TABLE "Inventory" ADD COLUMN IsTemplate INTEGER;
ALTER TABLE "Inventory" ADD COLUMN PowerState INTEGER;
ALTER TABLE "Inventory" ADD COLUMN SrmPlaceholder INTEGER;
UPDATE Inventory
SET IsTemplate = CASE
WHEN IsTemplate_old = 'TRUE' THEN 1
ELSE 0
END;
UPDATE Inventory
SET PowerState = CASE
WHEN PoweredOn_old = 'TRUE' THEN 1
ELSE 0
END;
UPDATE Inventory
SET SrmPlaceholder = CASE
WHEN SrmPlaceholder_old = 'TRUE' THEN 1
ELSE 0
END;
ALTER TABLE "Inventory" DROP COLUMN IsTemplate_old;
ALTER TABLE "Inventory" DROP COLUMN PoweredOn_old;
ALTER TABLE "Inventory" DROP COLUMN SrmPlaceholder_old;
-- +goose StatementEnd

View File

@@ -43,9 +43,9 @@ type Inventory struct {
ProvisionedDisk sql.NullFloat64 ProvisionedDisk sql.NullFloat64
InitialVcpus sql.NullInt64 InitialVcpus sql.NullInt64
InitialRam sql.NullInt64 InitialRam sql.NullInt64
SrmPlaceholder sql.NullInt64 IsTemplate interface{}
IsTemplate sql.NullInt64 PoweredOn interface{}
PowerState sql.NullInt64 SrmPlaceholder interface{}
} }
type Updates struct { type Updates struct {

View File

@@ -2,6 +2,10 @@
SELECT * FROM "Inventory" SELECT * FROM "Inventory"
ORDER BY "Name"; ORDER BY "Name";
-- name: GetReportInventory :many
SELECT * FROM "Inventory"
ORDER BY "CreationTime";
-- name: GetInventoryByName :many -- name: GetInventoryByName :many
SELECT * FROM "Inventory" SELECT * FROM "Inventory"
WHERE "Name" = ?; WHERE "Name" = ?;
@@ -16,7 +20,7 @@ WHERE "CloudId" = ? LIMIT 1;
-- name: CreateInventory :one -- name: CreateInventory :one
INSERT INTO "Inventory" ( INSERT INTO "Inventory" (
"Name", "Vcenter", "VmId", "EventKey", "CloudId", "CreationTime", "ResourcePool", "VmType", "IsTemplate", "Datacenter", "Cluster", "Folder", "ProvisionedDisk", "InitialVcpus", "InitialRam", "SrmPlaceholder", "PowerState" "Name", "Vcenter", "VmId", "EventKey", "CloudId", "CreationTime", "ResourcePool", "VmType", "IsTemplate", "Datacenter", "Cluster", "Folder", "ProvisionedDisk", "InitialVcpus", "InitialRam", "SrmPlaceholder", "PoweredOn"
) VALUES( ) VALUES(
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
) )

View File

@@ -90,11 +90,11 @@ func (q *Queries) CreateEvent(ctx context.Context, arg CreateEventParams) (Event
const createInventory = `-- name: CreateInventory :one const createInventory = `-- name: CreateInventory :one
INSERT INTO "Inventory" ( INSERT INTO "Inventory" (
"Name", "Vcenter", "VmId", "EventKey", "CloudId", "CreationTime", "ResourcePool", "VmType", "IsTemplate", "Datacenter", "Cluster", "Folder", "ProvisionedDisk", "InitialVcpus", "InitialRam", "SrmPlaceholder", "PowerState" "Name", "Vcenter", "VmId", "EventKey", "CloudId", "CreationTime", "ResourcePool", "VmType", "IsTemplate", "Datacenter", "Cluster", "Folder", "ProvisionedDisk", "InitialVcpus", "InitialRam", "SrmPlaceholder", "PoweredOn"
) VALUES( ) VALUES(
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
) )
RETURNING Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, SrmPlaceholder, IsTemplate, PowerState RETURNING Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, IsTemplate, PoweredOn, SrmPlaceholder
` `
type CreateInventoryParams struct { type CreateInventoryParams struct {
@@ -106,15 +106,15 @@ type CreateInventoryParams struct {
CreationTime sql.NullInt64 CreationTime sql.NullInt64
ResourcePool sql.NullString ResourcePool sql.NullString
VmType sql.NullString VmType sql.NullString
IsTemplate sql.NullInt64 IsTemplate interface{}
Datacenter sql.NullString Datacenter sql.NullString
Cluster sql.NullString Cluster sql.NullString
Folder sql.NullString Folder sql.NullString
ProvisionedDisk sql.NullFloat64 ProvisionedDisk sql.NullFloat64
InitialVcpus sql.NullInt64 InitialVcpus sql.NullInt64
InitialRam sql.NullInt64 InitialRam sql.NullInt64
SrmPlaceholder sql.NullInt64 SrmPlaceholder interface{}
PowerState sql.NullInt64 PoweredOn interface{}
} }
func (q *Queries) CreateInventory(ctx context.Context, arg CreateInventoryParams) (Inventory, error) { func (q *Queries) CreateInventory(ctx context.Context, arg CreateInventoryParams) (Inventory, error) {
@@ -135,7 +135,7 @@ func (q *Queries) CreateInventory(ctx context.Context, arg CreateInventoryParams
arg.InitialVcpus, arg.InitialVcpus,
arg.InitialRam, arg.InitialRam,
arg.SrmPlaceholder, arg.SrmPlaceholder,
arg.PowerState, arg.PoweredOn,
) )
var i Inventory var i Inventory
err := row.Scan( err := row.Scan(
@@ -155,9 +155,9 @@ func (q *Queries) CreateInventory(ctx context.Context, arg CreateInventoryParams
&i.ProvisionedDisk, &i.ProvisionedDisk,
&i.InitialVcpus, &i.InitialVcpus,
&i.InitialRam, &i.InitialRam,
&i.SrmPlaceholder,
&i.IsTemplate, &i.IsTemplate,
&i.PowerState, &i.PoweredOn,
&i.SrmPlaceholder,
) )
return i, err return i, err
} }
@@ -215,7 +215,7 @@ func (q *Queries) CreateUpdate(ctx context.Context, arg CreateUpdateParams) (Upd
} }
const getInventoryByName = `-- name: GetInventoryByName :many const getInventoryByName = `-- name: GetInventoryByName :many
SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, SrmPlaceholder, IsTemplate, PowerState FROM "Inventory" SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, IsTemplate, PoweredOn, SrmPlaceholder FROM "Inventory"
WHERE "Name" = ? WHERE "Name" = ?
` `
@@ -245,9 +245,9 @@ func (q *Queries) GetInventoryByName(ctx context.Context, name string) ([]Invent
&i.ProvisionedDisk, &i.ProvisionedDisk,
&i.InitialVcpus, &i.InitialVcpus,
&i.InitialRam, &i.InitialRam,
&i.SrmPlaceholder,
&i.IsTemplate, &i.IsTemplate,
&i.PowerState, &i.PoweredOn,
&i.SrmPlaceholder,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@@ -263,7 +263,7 @@ func (q *Queries) GetInventoryByName(ctx context.Context, name string) ([]Invent
} }
const getInventoryEventId = `-- name: GetInventoryEventId :one const getInventoryEventId = `-- name: GetInventoryEventId :one
SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, SrmPlaceholder, IsTemplate, PowerState FROM "Inventory" SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, IsTemplate, PoweredOn, SrmPlaceholder FROM "Inventory"
WHERE "CloudId" = ? LIMIT 1 WHERE "CloudId" = ? LIMIT 1
` `
@@ -287,15 +287,15 @@ func (q *Queries) GetInventoryEventId(ctx context.Context, cloudid sql.NullStrin
&i.ProvisionedDisk, &i.ProvisionedDisk,
&i.InitialVcpus, &i.InitialVcpus,
&i.InitialRam, &i.InitialRam,
&i.SrmPlaceholder,
&i.IsTemplate, &i.IsTemplate,
&i.PowerState, &i.PoweredOn,
&i.SrmPlaceholder,
) )
return i, err return i, err
} }
const getInventoryVmId = `-- name: GetInventoryVmId :one const getInventoryVmId = `-- name: GetInventoryVmId :one
SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, SrmPlaceholder, IsTemplate, PowerState FROM "Inventory" SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, IsTemplate, PoweredOn, SrmPlaceholder FROM "Inventory"
WHERE "VmId" = ?1 AND "Datacenter" = ?2 WHERE "VmId" = ?1 AND "Datacenter" = ?2
` `
@@ -324,17 +324,65 @@ func (q *Queries) GetInventoryVmId(ctx context.Context, arg GetInventoryVmIdPara
&i.ProvisionedDisk, &i.ProvisionedDisk,
&i.InitialVcpus, &i.InitialVcpus,
&i.InitialRam, &i.InitialRam,
&i.SrmPlaceholder,
&i.IsTemplate, &i.IsTemplate,
&i.PowerState, &i.PoweredOn,
&i.SrmPlaceholder,
) )
return i, err return i, err
} }
const getReportInventory = `-- name: GetReportInventory :many
SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, IsTemplate, PoweredOn, SrmPlaceholder FROM "Inventory"
ORDER BY "CreationTime"
`
func (q *Queries) GetReportInventory(ctx context.Context) ([]Inventory, error) {
rows, err := q.db.QueryContext(ctx, getReportInventory)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Inventory
for rows.Next() {
var i Inventory
if err := rows.Scan(
&i.Iid,
&i.Name,
&i.Vcenter,
&i.VmId,
&i.EventKey,
&i.CloudId,
&i.CreationTime,
&i.DeletionTime,
&i.ResourcePool,
&i.VmType,
&i.Datacenter,
&i.Cluster,
&i.Folder,
&i.ProvisionedDisk,
&i.InitialVcpus,
&i.InitialRam,
&i.IsTemplate,
&i.PoweredOn,
&i.SrmPlaceholder,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const inventoryCleanup = `-- name: InventoryCleanup :exec const inventoryCleanup = `-- name: InventoryCleanup :exec
DELETE FROM "Inventory" DELETE FROM "Inventory"
WHERE "VmId" = ?1 AND "Datacenter" = ?2 WHERE "VmId" = ?1 AND "Datacenter" = ?2
RETURNING Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, SrmPlaceholder, IsTemplate, PowerState RETURNING Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, IsTemplate, PoweredOn, SrmPlaceholder
` `
type InventoryCleanupParams struct { type InventoryCleanupParams struct {
@@ -409,7 +457,7 @@ func (q *Queries) ListEvents(ctx context.Context) ([]Events, error) {
} }
const listInventory = `-- name: ListInventory :many const listInventory = `-- name: ListInventory :many
SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, SrmPlaceholder, IsTemplate, PowerState FROM "Inventory" SELECT Iid, Name, Vcenter, VmId, EventKey, CloudId, CreationTime, DeletionTime, ResourcePool, VmType, Datacenter, Cluster, Folder, ProvisionedDisk, InitialVcpus, InitialRam, IsTemplate, PoweredOn, SrmPlaceholder FROM "Inventory"
ORDER BY "Name" ORDER BY "Name"
` `
@@ -439,9 +487,9 @@ func (q *Queries) ListInventory(ctx context.Context) ([]Inventory, error) {
&i.ProvisionedDisk, &i.ProvisionedDisk,
&i.InitialVcpus, &i.InitialVcpus,
&i.InitialRam, &i.InitialRam,
&i.SrmPlaceholder,
&i.IsTemplate, &i.IsTemplate,
&i.PowerState, &i.PoweredOn,
&i.SrmPlaceholder,
); err != nil { ); err != nil {
return nil, err return nil, err
} }

View File

@@ -20,7 +20,7 @@ func CreateReport(logger *slog.Logger, Database db.Database, ctx context.Context
var buffer bytes.Buffer var buffer bytes.Buffer
logger.Debug("Querying inventory table") logger.Debug("Querying inventory table")
results, err := Database.Queries().ListInventory(ctx) results, err := Database.Queries().GetReportInventory(ctx)
if err != nil { if err != nil {
logger.Error("Unable to query inventory table", "error", err) logger.Error("Unable to query inventory table", "error", err)
return nil, err return nil, err

View File

@@ -26,10 +26,10 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
numVcpus int32 numVcpus int32
numRam int32 numRam int32
totalDiskGB float64 totalDiskGB float64
srmPlaceholder int srmPlaceholder string
foundVm bool foundVm bool
isTemplate int isTemplate string
poweredOn int poweredOn string
folderPath string folderPath string
) )
@@ -64,11 +64,11 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
numRam = 0 numRam = 0
numVcpus = 0 numVcpus = 0
totalDiskGB = 0 totalDiskGB = 0
isTemplate = 0 isTemplate = "FALSE"
folderPath = "" folderPath = ""
} else { } else {
c.Logger.Debug("found VM") c.Logger.Debug("found VM")
srmPlaceholder = 0 // Default assumption srmPlaceholder = "FALSE" // Default assumption
//prettyPrint(vmObject) //prettyPrint(vmObject)
// calculate VM properties we want to store // calculate VM properties we want to store
@@ -79,6 +79,14 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
// Calculate the total disk allocated in GB // Calculate the total disk allocated in GB
for _, device := range vmObject.Vm.Config.Hardware.Device { for _, device := range vmObject.Vm.Config.Hardware.Device {
if disk, ok := device.(*types.VirtualDisk); ok { if disk, ok := device.(*types.VirtualDisk); ok {
// Print the filename of the backing device
if backing, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok {
c.Logger.Debug("Adding disk", "size_bytes", disk.CapacityInBytes, "backing_file", backing.FileName)
} else {
c.Logger.Debug("Adding disk, unknown backing type", "size_bytes", disk.CapacityInBytes)
}
totalDiskGB += float64(disk.CapacityInBytes / 1024 / 1024 / 1024) // Convert from bytes to GB totalDiskGB += float64(disk.CapacityInBytes / 1024 / 1024 / 1024) // Convert from bytes to GB
} }
} }
@@ -86,13 +94,13 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
// Determine if the VM is a normal VM or an SRM placeholder // Determine if the VM is a normal VM or an SRM placeholder
if vmObject.Vm.Config.ManagedBy != nil && vmObject.Vm.Config.ManagedBy.Type == "com.vmware.vcDr" { if vmObject.Vm.Config.ManagedBy != nil && vmObject.Vm.Config.ManagedBy.Type == "com.vmware.vcDr" {
c.Logger.Debug("VM ManagedBy indicates managed by SRM") c.Logger.Debug("VM ManagedBy indicates managed by SRM")
srmPlaceholder = 1 srmPlaceholder = "TRUE"
} }
if vmObject.Vm.Config.Template { if vmObject.Vm.Config.Template {
isTemplate = 1 isTemplate = "TRUE"
} else { } else {
isTemplate = 0 isTemplate = "FALSE"
} }
// Retrieve the full folder path of the VM // Retrieve the full folder path of the VM
@@ -109,15 +117,12 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
c.Logger.Error("Empty VM config") c.Logger.Error("Empty VM config")
} }
//if (types.VirtualMachineRuntimeInfo{}) != vmObject.Vm.Runtime {
//if runtime, ok := vmObject.Vm.Runtime.(types.VirtualMachineRuntimeInfo); ok {
c.Logger.Debug("VM has runtime data", "power_state", vmObject.Vm.Runtime.PowerState) c.Logger.Debug("VM has runtime data", "power_state", vmObject.Vm.Runtime.PowerState)
if vmObject.Vm.Runtime.PowerState == "" { if vmObject.Vm.Runtime.PowerState == "poweredOff" {
poweredOn = 0 poweredOn = "FALSE"
} else { } else {
poweredOn = 1 poweredOn = "TRUE"
} }
//}
} }
err = vc.Logout() err = vc.Logout()
@@ -142,9 +147,9 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
ProvisionedDisk: sql.NullFloat64{Float64: totalDiskGB, Valid: totalDiskGB > 0}, ProvisionedDisk: sql.NullFloat64{Float64: totalDiskGB, Valid: totalDiskGB > 0},
Folder: sql.NullString{String: folderPath, Valid: folderPath != ""}, Folder: sql.NullString{String: folderPath, Valid: folderPath != ""},
ResourcePool: sql.NullString{String: vmObject.ResourcePool, Valid: vmObject.ResourcePool != ""}, ResourcePool: sql.NullString{String: vmObject.ResourcePool, Valid: vmObject.ResourcePool != ""},
SrmPlaceholder: sql.NullInt64{Int64: int64(srmPlaceholder), Valid: true}, SrmPlaceholder: srmPlaceholder,
IsTemplate: sql.NullInt64{Int64: int64(isTemplate), Valid: true}, IsTemplate: isTemplate,
PowerState: sql.NullInt64{Int64: int64(poweredOn), Valid: true}, PoweredOn: poweredOn,
} }
c.Logger.Debug("database params", "params", params) c.Logger.Debug("database params", "params", params)

38
main.go
View File

@@ -25,6 +25,7 @@ var (
sha1ver string // sha1 revision used to build the program sha1ver string // sha1 revision used to build the program
buildTime string // when the executable was built buildTime string // when the executable was built
cronFrequency time.Duration cronFrequency time.Duration
cronInvFrequency time.Duration
) )
func main() { func main() {
@@ -125,17 +126,29 @@ func main() {
Settings: s, Settings: s,
} }
cronFrequencyString := os.Getenv("VCENTER_POLLING_SECONDS") cronFrequencyString := os.Getenv("VCENTER_EVENT_POLLING_SECONDS")
if cronFrequencyString != "" { if cronFrequencyString != "" {
cronFrequency, err = time.ParseDuration(cronFrequencyString) cronFrequency, err = time.ParseDuration(cronFrequencyString)
if err != nil { if err != nil {
slog.Error("Can't convert VCENTER_POLLING_SECONDS value to time duration. Defaulting to 60s", "value", cronFrequencyString, "error", err) slog.Error("Can't convert VCENTER_EVENT_POLLING_SECONDS value to time duration. Defaulting to 60s", "value", cronFrequencyString, "error", err)
cronFrequency = time.Second * 60 cronFrequency = time.Second * 60
} }
} else { } else {
cronFrequency = time.Second * 60 cronFrequency = time.Second * 60
} }
logger.Debug("Setting VM polling cronjob frequency to", "frequency", cronFrequency) logger.Debug("Setting VM event polling cronjob frequency to", "frequency", cronFrequency)
cronInventoryFrequencyString := os.Getenv("VCENTER_INVENTORY_POLLING_SECONDS")
if cronInventoryFrequencyString != "" {
cronInvFrequency, err = time.ParseDuration(cronInventoryFrequencyString)
if err != nil {
slog.Error("Can't convert VCENTER_INVENTORY_POLLING_SECONDS value to time duration. Defaulting to 3600s", "value", cronInventoryFrequencyString, "error", err)
cronInvFrequency = time.Second * 3600
}
} else {
cronInvFrequency = time.Second * 3600
}
logger.Debug("Setting VM inventory polling cronjob frequency to", "frequency", cronInvFrequency)
// start background processing for events stored in events table // start background processing for events stored in events table
startsAt := time.Now().Add(time.Second * 10) startsAt := time.Now().Add(time.Second * 10)
@@ -147,24 +160,25 @@ func main() {
gocron.WithStartAt(gocron.WithStartDateTime(startsAt)), gocron.WithStartAt(gocron.WithStartDateTime(startsAt)),
) )
if err != nil { if err != nil {
logger.Error("failed to start cron jobs", "error", err) logger.Error("failed to start event processing cron job", "error", err)
os.Exit(1) os.Exit(1)
} }
logger.Debug("Created event processing cron job", "job", job.ID()) logger.Debug("Created event processing cron job", "job", job.ID())
startsAt2 := time.Now().Add(time.Second * 10) // start background checks of vcenter inventory
startsAt2 := time.Now().Add(time.Second * 300)
job2, err := c.NewJob( job2, err := c.NewJob(
gocron.DurationJob(cronFrequency), gocron.DurationJob(cronInvFrequency),
gocron.NewTask(func() { gocron.NewTask(func() {
ct.RunVcenterPoll(ctx, logger) ct.RunVcenterPoll(ctx, logger)
}), gocron.WithSingletonMode(gocron.LimitModeReschedule), }), gocron.WithSingletonMode(gocron.LimitModeReschedule),
gocron.WithStartAt(gocron.WithStartDateTime(startsAt2)), gocron.WithStartAt(gocron.WithStartDateTime(startsAt2)),
) )
if err != nil { if err != nil {
logger.Error("failed to start cron jobs", "error", err) logger.Error("failed to start vcenter inventory cron job", "error", err)
os.Exit(1) os.Exit(1)
} }
logger.Debug("Created vcenter polling cron job", "job", job2.ID()) logger.Debug("Created vcenter inventory cron job", "job", job2.ID())
// start cron scheduler // start cron scheduler
c.Start() c.Start()
@@ -176,11 +190,11 @@ func main() {
cancel, cancel,
bindAddress, bindAddress,
server.WithRouter(router.New(logger, database, buildTime, sha1ver, runtime.Version())), server.WithRouter(router.New(logger, database, buildTime, sha1ver, runtime.Version())),
server.SetTls(bindDisableTls),
server.SetCertificate(tlsCertFilename),
server.SetPrivateKey(tlsKeyFilename),
) )
//logger.Debug("Server configured", "object", svr)
svr.DisableTls(bindDisableTls)
svr.SetCertificate(tlsCertFilename)
svr.SetPrivateKey(tlsKeyFilename)
svr.StartAndWait() svr.StartAndWait()

View File

@@ -3,6 +3,7 @@ package server
import ( import (
"context" "context"
"crypto/tls" "crypto/tls"
"fmt"
"log/slog" "log/slog"
"net/http" "net/http"
"os" "os"
@@ -47,16 +48,21 @@ func New(logger *slog.Logger, cron gocron.Scheduler, cancel context.CancelFunc,
TLSConfig: tlsConfig, TLSConfig: tlsConfig,
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)), TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
} }
for _, opt := range opts {
opt(&Server{srv: srv})
}
return &Server{ // Set the initial server values
server := &Server{
srv: srv, srv: srv,
logger: logger, logger: logger,
cron: cron, cron: cron,
cancel: cancel, cancel: cancel,
} }
// Apply any options
for _, opt := range opts {
opt(server)
}
return server
} }
// Option represents a server option. // Option represents a server option.
@@ -83,19 +89,26 @@ func WithRouter(handler http.Handler) Option {
} }
} }
// DisableTls sets the disable tls value // SetTls sets the disable tls value
func (s *Server) DisableTls(disableTls bool) { func SetTls(disableTls bool) Option {
return func(s *Server) {
s.disableTls = disableTls s.disableTls = disableTls
}
} }
// SetCertificate sets the path to the certificate used for TLS, in PEM format // SetCertificate sets the path to the certificate used for TLS, in PEM format
func (s *Server) SetCertificate(tlsCertFilename string) { func SetCertificate(tlsCertFilename string) Option {
return func(s *Server) {
fmt.Printf("Setting tlsCertFilename to '%s'\n", tlsCertFilename)
s.tlsCertFilename = tlsCertFilename s.tlsCertFilename = tlsCertFilename
}
} }
// SetPrivateKey sets the path to the private key used for TLS, in PEM format // SetPrivateKey sets the path to the private key used for TLS, in PEM format
func (s *Server) SetPrivateKey(tlsKeyFilename string) { func SetPrivateKey(tlsKeyFilename string) Option {
return func(s *Server) {
s.tlsKeyFilename = tlsKeyFilename s.tlsKeyFilename = tlsKeyFilename
}
} }
// StartAndWait starts the server and waits for a signal to shut down. // StartAndWait starts the server and waits for a signal to shut down.
@@ -111,12 +124,14 @@ func (s *Server) Start() {
if s.disableTls { if s.disableTls {
s.logger.Info("starting server", "port", s.srv.Addr) s.logger.Info("starting server", "port", s.srv.Addr)
if err := s.srv.ListenAndServe(); err != nil { if err := s.srv.ListenAndServe(); err != nil {
s.logger.Warn("failed to start server", "error", err) s.logger.Error("failed to start server", "error", err)
os.Exit(1)
} }
} else { } else {
s.logger.Info("starting TLS server", "port", s.srv.Addr, "cert", s.tlsCertFilename, "key", s.tlsKeyFilename) s.logger.Info("starting TLS server", "port", s.srv.Addr, "cert", s.tlsCertFilename, "key", s.tlsKeyFilename)
if err := s.srv.ListenAndServeTLS(s.tlsCertFilename, s.tlsKeyFilename); err != nil && err != http.ErrServerClosed { if err := s.srv.ListenAndServeTLS(s.tlsCertFilename, s.tlsKeyFilename); err != nil && err != http.ErrServerClosed {
s.logger.Warn("failed to start server", "error", err) s.logger.Error("failed to start server", "error", err)
os.Exit(1)
} }
} }
}() }()