Skip to content

Commit

Permalink
Merge pull request vyos#4155 from HollyGurza/T4583
Browse files Browse the repository at this point in the history
T4583: Rewrite VRRP op-mode to vyos.opmode format
  • Loading branch information
c-po authored Oct 24, 2024
2 parents 3710c58 + a5a484a commit ceb64f3
Show file tree
Hide file tree
Showing 3 changed files with 380 additions and 68 deletions.
25 changes: 22 additions & 3 deletions op-mode-definitions/vrrp.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,42 @@
<interfaceDefinition>
<node name="show">
<children>
<tagNode name="vrrp">
<properties>
<help>Show specified VRRP (Virtual Router Redundancy Protocol) group information</help>
</properties>
<children>
<node name="statistics">
<properties>
<help>Show VRRP statistics</help>
</properties>
<command>sudo ${vyos_op_scripts_dir}/vrrp.py show_statistics --group-name="$3"</command>
</node>
<node name="detail">
<properties>
<help>Show detailed VRRP state information</help>
</properties>
<command>sudo ${vyos_op_scripts_dir}/vrrp.py show_detail --group-name="$3"</command>
</node>
</children>
</tagNode>
<node name="vrrp">
<properties>
<help>Show VRRP (Virtual Router Redundancy Protocol) information</help>
</properties>
<command>sudo ${vyos_op_scripts_dir}/vrrp.py --summary</command>
<command>sudo ${vyos_op_scripts_dir}/vrrp.py show_summary</command>
<children>
<node name="statistics">
<properties>
<help>Show VRRP statistics</help>
</properties>
<command>sudo ${vyos_op_scripts_dir}/vrrp.py --statistics</command>
<command>sudo ${vyos_op_scripts_dir}/vrrp.py show_statistics</command>
</node>
<node name="detail">
<properties>
<help>Show detailed VRRP state information</help>
</properties>
<command>sudo ${vyos_op_scripts_dir}/vrrp.py --data</command>
<command>sudo ${vyos_op_scripts_dir}/vrrp.py show_detail</command>
</node>
</children>
</node>
Expand Down
68 changes: 42 additions & 26 deletions python/vyos/ifconfig/vrrp.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,37 @@
from vyos.utils.file import wait_for_file_write_complete
from vyos.utils.process import process_running


class VRRPError(Exception):
pass


class VRRPNoData(VRRPError):
pass


class VRRP(object):
_vrrp_prefix = '00:00:5E:00:01:'
location = {
'pid': '/run/keepalived/keepalived.pid',
'fifo': '/run/keepalived/keepalived_notify_fifo',
'state': '/tmp/keepalived.data',
'stats': '/tmp/keepalived.stats',
'json': '/tmp/keepalived.json',
'daemon': '/etc/default/keepalived',
'config': '/run/keepalived/keepalived.conf',
'pid': '/run/keepalived/keepalived.pid',
'fifo': '/run/keepalived/keepalived_notify_fifo',
'state': '/tmp/keepalived.data',
'stats': '/tmp/keepalived.stats',
'json': '/tmp/keepalived.json',
'daemon': '/etc/default/keepalived',
'config': '/run/keepalived/keepalived.conf',
}

_signal = {
'state': signal.SIGUSR1,
'stats': signal.SIGUSR2,
'json': signal.SIGRTMIN + 2,
'state': signal.SIGUSR1,
'stats': signal.SIGUSR2,
'json': signal.SIGRTMIN + 2,
}

_name = {
'state': 'information',
'stats': 'statistics',
'json': 'data',
'json': 'data',
}

state = {
Expand All @@ -64,7 +67,7 @@ class VRRP(object):
# UNKNOWN
}

def __init__(self,ifname):
def __init__(self, ifname):
self.ifname = ifname

def enabled(self):
Expand All @@ -79,7 +82,7 @@ def active_interfaces(cls):

@classmethod
def decode_state(cls, code):
return cls.state.get(code,'UNKNOWN')
return cls.state.get(code, 'UNKNOWN')

# used in conf mode
@classmethod
Expand All @@ -94,16 +97,20 @@ def collect(cls, what):
try:
# send signal to generate the configuration file
pid = read_file(cls.location['pid'])
wait_for_file_write_complete(fname,
pre_hook=(lambda: os.kill(int(pid), cls._signal[what])),
timeout=30)
wait_for_file_write_complete(
fname,
pre_hook=(lambda: os.kill(int(pid), cls._signal[what])),
timeout=30,
)

return read_file(fname)
except FileNotFoundError:
raise VRRPNoData(
'VRRP data is not available (process not running or no active groups)'
)
except OSError:
# raised by vyos.utils.file.read_file
raise VRRPNoData("VRRP data is not available (wait time exceeded)")
except FileNotFoundError:
raise VRRPNoData("VRRP data is not available (process not running or no active groups)")
raise VRRPNoData('VRRP data is not available (wait time exceeded)')
except Exception:
name = cls._name[what]
raise VRRPError(f'VRRP {name} is not available')
Expand All @@ -118,32 +125,41 @@ def disabled(cls):
conf = ConfigTreeQuery()
if conf.exists(base):
# Read VRRP configuration directly from CLI
vrrp_config_dict = conf.get_config_dict(base, key_mangling=('-', '_'),
get_first_key=True)
vrrp_config_dict = conf.get_config_dict(
base, key_mangling=('-', '_'), get_first_key=True
)

# add disabled groups to the list
if 'group' in vrrp_config_dict:
for group, group_config in vrrp_config_dict['group'].items():
if 'disable' not in group_config:
continue
disabled.append([group, group_config['interface'], group_config['vrid'], 'DISABLED', ''])
disabled.append(
[
group,
group_config['interface'],
group_config['vrid'],
'DISABLED',
'',
]
)

# return list with disabled instances
return disabled

@classmethod
def format(cls, data):
headers = ["Name", "Interface", "VRID", "State", "Priority", "Last Transition"]
headers = ['Name', 'Interface', 'VRID', 'State', 'Priority', 'Last Transition']
groups = []

data = json.loads(data)
data = json.loads(data) if isinstance(data, str) else data
for group in data:
data = group['data']

name = data['iname']
intf = data['ifp_ifname']
vrid = data['vrid']
state = cls.decode_state(data["state"])
state = cls.decode_state(data['state'])
priority = data['effective_priority']

since = int(time() - float(data['last_transition']))
Expand All @@ -153,4 +169,4 @@ def format(cls, data):

# add to the active list disabled instances
groups.extend(cls.disabled())
return(tabulate(groups, headers))
return tabulate(groups, headers)
Loading

0 comments on commit ceb64f3

Please sign in to comment.