kdnotify/schema/notify/message.go

106 lines
2.4 KiB
Go
Raw Permalink Normal View History

/*
* 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 = cleanInstance(pt[1])
m.State = state.ParseState(pt[2])
if l > 3 {
m.Priority = prio.ParsePriority(pt[3])
}
return m, nil
}
// Cleans up messy INSTANCE fields, which can contain many quotes when
// Keepalived sends them
func cleanInstance(instance string) string {
return strings.TrimSpace(strings.Trim(instance, `"'`))
}