Paul Stemmet
c277b1e813
Keepalived returns dirty instance names, containing any and all quotes from the declaration in keepalived.conf, plus an additional pair of double quotes. Here we strip those out, as they will just cause confusion and make it difficult to properly match of instances in WatchRules. As an demonstration observed from keepalived (v2.2.7): | .conf line | notify INSTANCE | | - | - | | my_instance | "my_instance" | | 'my.instance' | "'my.instance'" | | "my.instance" | ""my.instance"" | After this commit, each will have all of its quotes stripped Closes: #1
106 lines
2.4 KiB
Go
106 lines
2.4 KiB
Go
/*
|
|
* 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, `"'`))
|
|
}
|