228 lines
5.1 KiB
Go
228 lines
5.1 KiB
Go
package virtbuf
|
|
|
|
import (
|
|
// "reflect"
|
|
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"google.golang.org/protobuf/types/known/anypb"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
|
|
|
"go.wit.com/log"
|
|
)
|
|
|
|
func convertToAnypb(x any) *anypb.Any {
|
|
switch v := x.(type) {
|
|
case int64:
|
|
var a *anypb.Any
|
|
a, _ = anypb.New(wrapperspb.Int64(x.(int64)))
|
|
return a
|
|
case string:
|
|
var a *anypb.Any
|
|
a, _ = anypb.New(wrapperspb.String(x.(string)))
|
|
return a
|
|
case int:
|
|
var a *anypb.Any
|
|
a, _ = anypb.New(wrapperspb.Int64(x.(int64)))
|
|
return a
|
|
case bool:
|
|
var a *anypb.Any
|
|
a, _ = anypb.New(wrapperspb.Bool(x.(bool)))
|
|
return a
|
|
default:
|
|
log.Error(errors.New("convertToAnypb() unknown type"), "v =", v, "x =", x)
|
|
return nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func convertToString(x any) string {
|
|
switch v := x.(type) {
|
|
case int64:
|
|
return fmt.Sprintf("%d", x.(int64))
|
|
case string:
|
|
return x.(string)
|
|
case int:
|
|
return fmt.Sprintf("%d", x.(int))
|
|
case uint:
|
|
return fmt.Sprintf("%d", x.(uint))
|
|
case *DropletState:
|
|
var s *DropletState
|
|
s = x.(*DropletState)
|
|
return s.String()
|
|
case DropletState:
|
|
var s DropletState
|
|
s = x.(DropletState)
|
|
return s.String()
|
|
case bool:
|
|
if x.(bool) {
|
|
return "true"
|
|
}
|
|
return "false"
|
|
default:
|
|
log.Info("convertToSTring() unknown type", v)
|
|
log.Error(errors.New("convertToSTring() unknown type"), "v =", v, "x =", x)
|
|
return ""
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Wrapping the int into a protobuf message
|
|
func (d *Droplet) NewChangeEvent(fname string, origval any, newval any) *Event {
|
|
var e *Event
|
|
e = new(Event)
|
|
|
|
e.Droplet = d.Hostname
|
|
e.OrigVal = convertToString(origval)
|
|
e.NewVal = convertToString(newval)
|
|
e.FieldName = fname
|
|
|
|
now := time.Now()
|
|
e.Start = timestamppb.New(now)
|
|
|
|
// this also works, but it's a bit overkill
|
|
// e.NewAny = convertToAnypb(newval)
|
|
|
|
// me.events.Events = append(me.events.Events, e)
|
|
// stuff := me.events.FormatJSON()
|
|
// log.Info("events:", stuff)
|
|
return e
|
|
}
|
|
|
|
// work in progress
|
|
func NewAddEvent(a any, fname string, newval any) *Event {
|
|
var e *Event
|
|
e = new(Event)
|
|
|
|
switch v := a.(type) {
|
|
case *Droplet:
|
|
var d *Droplet
|
|
d = a.(*Droplet)
|
|
e.Droplet = d.Hostname
|
|
case nil:
|
|
e.Droplet = "<nil>"
|
|
default:
|
|
log.Info("newAddEvent() unknown type", v)
|
|
e.Droplet = "on something somewhere"
|
|
}
|
|
|
|
e.NewVal = convertToString(newval)
|
|
e.FieldName = fname
|
|
|
|
now := time.Now()
|
|
e.Start = timestamppb.New(now)
|
|
|
|
return e
|
|
}
|
|
|
|
// update the droplet memory
|
|
func (d *Droplet) SetMemory(b int64) *Event {
|
|
oldm := HumanFormatBytes(d.Memory)
|
|
newm := HumanFormatBytes(b)
|
|
if d.Memory == b {
|
|
// log.Info("droplet", d.Hostname, "memory unchanged", oldm, "to", newm)
|
|
return nil
|
|
}
|
|
log.Info("droplet", d.Hostname, "memory change from", oldm, "to", newm)
|
|
|
|
return d.NewChangeEvent("Droplet.Memory", d.Memory, b)
|
|
}
|
|
|
|
// update the droplet memory
|
|
func (d *Droplet) SetCpus(b int64) {
|
|
log.Info("Set the number of cpus for the droplet", b)
|
|
}
|
|
|
|
// update the droplet memory
|
|
func (d *Droplet) SetState(newState DropletState) {
|
|
if d.Current == nil {
|
|
d.Current = new(Current)
|
|
}
|
|
if d.Current.State == newState {
|
|
// nothing has changed
|
|
return
|
|
}
|
|
switch newState {
|
|
case DropletState_ON:
|
|
d.Current.OnSince = timestamppb.New(time.Now())
|
|
d.Current.OffSince = nil
|
|
case DropletState_OFF:
|
|
d.Current.OffSince = timestamppb.New(time.Now())
|
|
d.Current.OnSince = nil
|
|
default:
|
|
// zero on OnSince to indicate something hickup'd?
|
|
// not sure if this should be done here. probably trust qemu dom0 instead
|
|
// but I can't do that right now so for now this will work
|
|
d.Current.OnSince = timestamppb.New(time.Now())
|
|
d.Current.OffSince = timestamppb.New(time.Now())
|
|
}
|
|
d.Current.State = newState
|
|
d.NewChangeEvent("STATE", d.Current.State, newState)
|
|
log.Info("Droplet", d.Hostname, "changed state from", d.Current.State, "to", newState)
|
|
}
|
|
|
|
// records an event that the droplet changed state (aka turned on, turned off, etc)
|
|
func (c *NewCluster) ChangeDropletState(d *Droplet, newState DropletState) error {
|
|
if c == nil {
|
|
return errors.New("cluster is nil")
|
|
}
|
|
if d == nil {
|
|
return errors.New("droplet is nil")
|
|
}
|
|
if d.Current.State == newState {
|
|
// droplet status didn't change
|
|
return nil
|
|
}
|
|
var e *Event
|
|
e = new(Event)
|
|
|
|
e.Droplet = d.Hostname
|
|
e.OrigVal = convertToString(d.Current.State)
|
|
e.NewVal = convertToString(newState)
|
|
e.FieldName = "status"
|
|
|
|
now := time.Now()
|
|
e.Start = timestamppb.New(now)
|
|
|
|
c.e.Events = append(c.e.Events, e)
|
|
return nil
|
|
}
|
|
|
|
// records an event that the droplet migrated to another hypervisor
|
|
func (c *NewCluster) DropletMoved(d *Droplet, newh *Hypervisor) error {
|
|
if c == nil {
|
|
return errors.New("cluster is nil")
|
|
}
|
|
if d == nil {
|
|
return errors.New("droplet is nil")
|
|
}
|
|
if newh == nil {
|
|
return errors.New("hypervisor is nil")
|
|
}
|
|
if d.Current.Hypervisor == newh.Hostname {
|
|
// droplet didn't move
|
|
return nil
|
|
}
|
|
|
|
// make a change event
|
|
var e *Event
|
|
e = new(Event)
|
|
|
|
e.Droplet = d.Hostname
|
|
e.OrigVal = d.Current.Hypervisor
|
|
e.NewVal = newh.Hostname
|
|
e.FieldName = "droplet migrate"
|
|
|
|
now := time.Now()
|
|
e.Start = timestamppb.New(now)
|
|
|
|
c.e.Events = append(c.e.Events, e)
|
|
|
|
// update the droplet record
|
|
d.Current.Hypervisor = newh.Hostname
|
|
return nil
|
|
}
|