From 90a4827284acd3cb072cdfeef323c522802c6449 Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Wed, 9 Oct 2024 14:55:11 +0200
Subject: haproxy: T6745: Rename `reverse-proxy` to `haproxy`
---
src/op_mode/load-balancing_haproxy.py | 237 ++++++++++++++++++++++++++++++++++
src/op_mode/restart.py | 10 +-
src/op_mode/reverseproxy.py | 237 ----------------------------------
3 files changed, 242 insertions(+), 242 deletions(-)
create mode 100755 src/op_mode/load-balancing_haproxy.py
delete mode 100755 src/op_mode/reverseproxy.py
(limited to 'src/op_mode')
diff --git a/src/op_mode/load-balancing_haproxy.py b/src/op_mode/load-balancing_haproxy.py
new file mode 100755
index 000000000..ae6734e16
--- /dev/null
+++ b/src/op_mode/load-balancing_haproxy.py
@@ -0,0 +1,237 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023-2024 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import json
+import socket
+import sys
+
+from tabulate import tabulate
+from vyos.configquery import ConfigTreeQuery
+
+import vyos.opmode
+
+socket_path = '/run/haproxy/admin.sock'
+timeout = 5
+
+
+def _execute_haproxy_command(command):
+ """Execute a command on the HAProxy UNIX socket and retrieve the response.
+
+ Args:
+ command (str): The command to be executed.
+
+ Returns:
+ str: The response received from the HAProxy UNIX socket.
+
+ Raises:
+ socket.error: If there is an error while connecting or communicating with the socket.
+
+ Finally:
+ Closes the socket connection.
+
+ Notes:
+ - HAProxy expects a newline character at the end of the command.
+ - The socket connection is established using the HAProxy UNIX socket.
+ - The response from the socket is received and decoded.
+
+ Example:
+ response = _execute_haproxy_command('show stat')
+ print(response)
+ """
+ try:
+ # HAProxy expects new line for command
+ command = f'{command}\n'
+
+ # Connect to the HAProxy UNIX socket
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ sock.connect(socket_path)
+
+ # Set the socket timeout
+ sock.settimeout(timeout)
+
+ # Send the command
+ sock.sendall(command.encode())
+
+ # Receive and decode the response
+ response = b''
+ while True:
+ data = sock.recv(4096)
+ if not data:
+ break
+ response += data
+ response = response.decode()
+
+ return (response)
+
+ except socket.error as e:
+ print(f"Error: {e}")
+
+ finally:
+ # Close the socket
+ sock.close()
+
+
+def _convert_seconds(seconds):
+ """Convert seconds to days, hours, minutes, and seconds.
+
+ Args:
+ seconds (int): The number of seconds to convert.
+
+ Returns:
+ tuple: A tuple containing the number of days, hours, minutes, and seconds.
+ """
+ minutes = seconds // 60
+ hours = minutes // 60
+ days = hours // 24
+
+ return days, hours % 24, minutes % 60, seconds % 60
+
+
+def _last_change_format(seconds):
+ """Format the time components into a string representation.
+
+ Args:
+ seconds (int): The total number of seconds.
+
+ Returns:
+ str: The formatted time string with days, hours, minutes, and seconds.
+
+ Examples:
+ >>> _last_change_format(1434)
+ '23m54s'
+ >>> _last_change_format(93734)
+ '1d0h23m54s'
+ >>> _last_change_format(85434)
+ '23h23m54s'
+ """
+ days, hours, minutes, seconds = _convert_seconds(seconds)
+ time_format = ""
+
+ if days:
+ time_format += f"{days}d"
+ if hours:
+ time_format += f"{hours}h"
+ if minutes:
+ time_format += f"{minutes}m"
+ if seconds:
+ time_format += f"{seconds}s"
+
+ return time_format
+
+
+def _get_json_data():
+ """Get haproxy data format JSON"""
+ return _execute_haproxy_command('show stat json')
+
+
+def _get_raw_data():
+ """Retrieve raw data from JSON and organize it into a dictionary.
+
+ Returns:
+ dict: A dictionary containing the organized data categorized
+ into frontend, backend, and server.
+ """
+
+ data = json.loads(_get_json_data())
+ lb_dict = {'frontend': [], 'backend': [], 'server': []}
+
+ for key in data:
+ frontend = []
+ backend = []
+ server = []
+ for entry in key:
+ obj_type = entry['objType'].lower()
+ position = entry['field']['pos']
+ name = entry['field']['name']
+ value = entry['value']['value']
+
+ dict_entry = {'pos': position, 'name': {name: value}}
+
+ if obj_type == 'frontend':
+ frontend.append(dict_entry)
+ elif obj_type == 'backend':
+ backend.append(dict_entry)
+ elif obj_type == 'server':
+ server.append(dict_entry)
+
+ if len(frontend) > 0:
+ lb_dict['frontend'].append(frontend)
+ if len(backend) > 0:
+ lb_dict['backend'].append(backend)
+ if len(server) > 0:
+ lb_dict['server'].append(server)
+
+ return lb_dict
+
+
+def _get_formatted_output(data):
+ """
+ Format the data into a tabulated output.
+
+ Args:
+ data (dict): The data to be formatted.
+
+ Returns:
+ str: The tabulated output representing the formatted data.
+ """
+ table = []
+ headers = [
+ "Proxy name", "Role", "Status", "Req rate", "Resp time", "Last change"
+ ]
+
+ for key in data:
+ for item in data[key]:
+ row = [None] * len(headers)
+
+ for element in item:
+ if 'pxname' in element['name']:
+ row[0] = element['name']['pxname']
+ elif 'svname' in element['name']:
+ row[1] = element['name']['svname']
+ elif 'status' in element['name']:
+ row[2] = element['name']['status']
+ elif 'req_rate' in element['name']:
+ row[3] = element['name']['req_rate']
+ elif 'rtime' in element['name']:
+ row[4] = f"{element['name']['rtime']} ms"
+ elif 'lastchg' in element['name']:
+ row[5] = _last_change_format(element['name']['lastchg'])
+ table.append(row)
+
+ out = tabulate(table, headers, numalign="left")
+ return out
+
+
+def show(raw: bool):
+ config = ConfigTreeQuery()
+ if not config.exists('load-balancing haproxy'):
+ raise vyos.opmode.UnconfiguredSubsystem('Haproxy is not configured')
+
+ data = _get_raw_data()
+ if raw:
+ return data
+ else:
+ return _get_formatted_output(data)
+
+
+if __name__ == '__main__':
+ try:
+ res = vyos.opmode.run(sys.modules[__name__])
+ if res:
+ print(res)
+ except (ValueError, vyos.opmode.Error) as e:
+ print(e)
+ sys.exit(1)
diff --git a/src/op_mode/restart.py b/src/op_mode/restart.py
index a83c8b9d8..3b0031f34 100755
--- a/src/op_mode/restart.py
+++ b/src/op_mode/restart.py
@@ -41,6 +41,10 @@ service_map = {
'systemd_service': 'pdns-recursor',
'path': ['service', 'dns', 'forwarding'],
},
+ 'haproxy': {
+ 'systemd_service': 'haproxy',
+ 'path': ['load-balancing', 'haproxy'],
+ },
'igmp_proxy': {
'systemd_service': 'igmpproxy',
'path': ['protocols', 'igmp-proxy'],
@@ -53,10 +57,6 @@ service_map = {
'systemd_service': 'avahi-daemon',
'path': ['service', 'mdns', 'repeater'],
},
- 'reverse_proxy': {
- 'systemd_service': 'haproxy',
- 'path': ['load-balancing', 'reverse-proxy'],
- },
'router_advert': {
'systemd_service': 'radvd',
'path': ['service', 'router-advert'],
@@ -83,10 +83,10 @@ services = typing.Literal[
'dhcpv6',
'dns_dynamic',
'dns_forwarding',
+ 'haproxy',
'igmp_proxy',
'ipsec',
'mdns_repeater',
- 'reverse_proxy',
'router_advert',
'snmp',
'ssh',
diff --git a/src/op_mode/reverseproxy.py b/src/op_mode/reverseproxy.py
deleted file mode 100755
index 19704182a..000000000
--- a/src/op_mode/reverseproxy.py
+++ /dev/null
@@ -1,237 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-import json
-import socket
-import sys
-
-from tabulate import tabulate
-from vyos.configquery import ConfigTreeQuery
-
-import vyos.opmode
-
-socket_path = '/run/haproxy/admin.sock'
-timeout = 5
-
-
-def _execute_haproxy_command(command):
- """Execute a command on the HAProxy UNIX socket and retrieve the response.
-
- Args:
- command (str): The command to be executed.
-
- Returns:
- str: The response received from the HAProxy UNIX socket.
-
- Raises:
- socket.error: If there is an error while connecting or communicating with the socket.
-
- Finally:
- Closes the socket connection.
-
- Notes:
- - HAProxy expects a newline character at the end of the command.
- - The socket connection is established using the HAProxy UNIX socket.
- - The response from the socket is received and decoded.
-
- Example:
- response = _execute_haproxy_command('show stat')
- print(response)
- """
- try:
- # HAProxy expects new line for command
- command = f'{command}\n'
-
- # Connect to the HAProxy UNIX socket
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- sock.connect(socket_path)
-
- # Set the socket timeout
- sock.settimeout(timeout)
-
- # Send the command
- sock.sendall(command.encode())
-
- # Receive and decode the response
- response = b''
- while True:
- data = sock.recv(4096)
- if not data:
- break
- response += data
- response = response.decode()
-
- return (response)
-
- except socket.error as e:
- print(f"Error: {e}")
-
- finally:
- # Close the socket
- sock.close()
-
-
-def _convert_seconds(seconds):
- """Convert seconds to days, hours, minutes, and seconds.
-
- Args:
- seconds (int): The number of seconds to convert.
-
- Returns:
- tuple: A tuple containing the number of days, hours, minutes, and seconds.
- """
- minutes = seconds // 60
- hours = minutes // 60
- days = hours // 24
-
- return days, hours % 24, minutes % 60, seconds % 60
-
-
-def _last_change_format(seconds):
- """Format the time components into a string representation.
-
- Args:
- seconds (int): The total number of seconds.
-
- Returns:
- str: The formatted time string with days, hours, minutes, and seconds.
-
- Examples:
- >>> _last_change_format(1434)
- '23m54s'
- >>> _last_change_format(93734)
- '1d0h23m54s'
- >>> _last_change_format(85434)
- '23h23m54s'
- """
- days, hours, minutes, seconds = _convert_seconds(seconds)
- time_format = ""
-
- if days:
- time_format += f"{days}d"
- if hours:
- time_format += f"{hours}h"
- if minutes:
- time_format += f"{minutes}m"
- if seconds:
- time_format += f"{seconds}s"
-
- return time_format
-
-
-def _get_json_data():
- """Get haproxy data format JSON"""
- return _execute_haproxy_command('show stat json')
-
-
-def _get_raw_data():
- """Retrieve raw data from JSON and organize it into a dictionary.
-
- Returns:
- dict: A dictionary containing the organized data categorized
- into frontend, backend, and server.
- """
-
- data = json.loads(_get_json_data())
- lb_dict = {'frontend': [], 'backend': [], 'server': []}
-
- for key in data:
- frontend = []
- backend = []
- server = []
- for entry in key:
- obj_type = entry['objType'].lower()
- position = entry['field']['pos']
- name = entry['field']['name']
- value = entry['value']['value']
-
- dict_entry = {'pos': position, 'name': {name: value}}
-
- if obj_type == 'frontend':
- frontend.append(dict_entry)
- elif obj_type == 'backend':
- backend.append(dict_entry)
- elif obj_type == 'server':
- server.append(dict_entry)
-
- if len(frontend) > 0:
- lb_dict['frontend'].append(frontend)
- if len(backend) > 0:
- lb_dict['backend'].append(backend)
- if len(server) > 0:
- lb_dict['server'].append(server)
-
- return lb_dict
-
-
-def _get_formatted_output(data):
- """
- Format the data into a tabulated output.
-
- Args:
- data (dict): The data to be formatted.
-
- Returns:
- str: The tabulated output representing the formatted data.
- """
- table = []
- headers = [
- "Proxy name", "Role", "Status", "Req rate", "Resp time", "Last change"
- ]
-
- for key in data:
- for item in data[key]:
- row = [None] * len(headers)
-
- for element in item:
- if 'pxname' in element['name']:
- row[0] = element['name']['pxname']
- elif 'svname' in element['name']:
- row[1] = element['name']['svname']
- elif 'status' in element['name']:
- row[2] = element['name']['status']
- elif 'req_rate' in element['name']:
- row[3] = element['name']['req_rate']
- elif 'rtime' in element['name']:
- row[4] = f"{element['name']['rtime']} ms"
- elif 'lastchg' in element['name']:
- row[5] = _last_change_format(element['name']['lastchg'])
- table.append(row)
-
- out = tabulate(table, headers, numalign="left")
- return out
-
-
-def show(raw: bool):
- config = ConfigTreeQuery()
- if not config.exists('load-balancing reverse-proxy'):
- raise vyos.opmode.UnconfiguredSubsystem('Reverse-proxy is not configured')
-
- data = _get_raw_data()
- if raw:
- return data
- else:
- return _get_formatted_output(data)
-
-
-if __name__ == '__main__':
- try:
- res = vyos.opmode.run(sys.modules[__name__])
- if res:
- print(res)
- except (ValueError, vyos.opmode.Error) as e:
- print(e)
- sys.exit(1)
--
cgit v1.2.3