schema/notify: Message, VrrpMessage

The in-memory representation of a keepalived notify event.

Message is not strictly accurate for non VRRP events, but as we don't
care about IPVS events now this is fine for our purposes. We do
explicitly provide a VrrpMessage type however which is guaranteed to be
a VRRP event.
This commit is contained in:
Paul Stemmet 2022-12-09 12:00:18 +00:00
parent a44d541cb7
commit 69ceb4eab3
Signed by: Paul Stemmet
GPG Key ID: EDEA539F594E7E75
1 changed files with 99 additions and 0 deletions

99
schema/notify/message.go Normal file
View File

@ -0,0 +1,99 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package notify
import (
"fmt"
"strings"
"git.st8l.com/luxolus/kdnotify/schema/notify/prio"
"git.st8l.com/luxolus/kdnotify/schema/notify/state"
"git.st8l.com/luxolus/kdnotify/schema/notify/ty"
)
// Keepalived VRRP notify message
type VrrpMessage struct {
Message
}
// Parse the given line of text into a VrrpMessage if possible,
// erroring out if not.
func ParseVrrp(line string) (VrrpMessage, error) {
msg, err := ParseMessage(line)
if err != nil {
return VrrpMessage{}, fmt.Errorf("unable parse message from '%s': %w", line, err)
}
vrrp, err := NewVrrp(msg)
if err != nil {
return vrrp, fmt.Errorf("unable parse vrrp from '%s': %w", line, err)
}
return vrrp, nil
}
// Upgrade a Message into a VrrpMessage that is guaranteed to be a valid VRRP message
func NewVrrp(m Message) (VrrpMessage, error) {
var v VrrpMessage
if !m.Type.IsVRRP() {
return v, fmt.Errorf("'%s' is not a valid VRRP message type", m.Type.String())
}
if m.State == state.UNKNOWN {
return v, fmt.Errorf("unknown VRRP message state")
}
v.Type = m.Type
v.Instance = m.Instance
v.State = m.State
v.Priority = m.Priority
return v, nil
}
// Keepalived notify message
type Message struct {
Type ty.Type
Instance string
State state.State
Priority prio.Priority
}
// Create a new Message from its components
func New(t ty.Type, instance string, s state.State, p prio.Priority) Message {
return Message{
Type: t,
Instance: instance,
State: s,
Priority: p,
}
}
// Parse a line into a Message, erroring out if the line format is invalid
func ParseMessage(line string) (Message, error) {
var m Message
line = strings.TrimSpace(line)
// $TYPE $INSTANCE $STATE $PRIORITY $REST...
pt := strings.SplitN(line, " ", 5)
l := len(pt)
// Priority is optional
if l < 3 {
return m, fmt.Errorf("unable to parse message from '%s': not enough fields", line)
}
m.Type = ty.ParseType(pt[0])
m.Instance = pt[1]
m.State = state.ParseState(pt[2])
if l > 3 {
m.Priority = prio.ParsePriority(pt[3])
}
return m, nil
}