Skip to content

Commit

Permalink
revive broken CLI commands
Browse files Browse the repository at this point in the history
Some commands broke when the lib was integrated into the OPNsense plugin:
opnsense/plugins@aa194e8

Now some functions are redundant (showServers,listServers), but that's acceptable for now.
  • Loading branch information
Frank Wall committed Dec 5, 2023
1 parent 38cc49f commit c86aed3
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 11 deletions.
24 changes: 18 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## v0.6.0

### Added
* new command: showServers (API, JSON output)
* new command: set/getServerWeight
* new output formats: json, bootstrap (API)

### Changed
* map commands disableServer and enableServer to `set server state maint|ready`
* print 'None' if no output is returned by HAProxy
* decode HAProxy socket output as UTF-8 instead of ASCII

## v0.5.0 - 2015-05-24

### Changed
Expand All @@ -13,30 +25,30 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## v0.4.0 - 2015-05-19

### Added
* Added support for specifying sockets as a TCP socket:
* Add support for specifying sockets as a TCP socket:
* support for -k tcp://1.2.3.4:port
* support for -k unix:///some/path

## v0.3.1 - 2013-11-04

### Fixed
* Fixed wrong self accidentally passed to self._getResult.
* Fix wrong self accidentally passed to self._getResult.

## v0.3.0 - 2013-10-31

### Added
* Added new commands (frontends, backends)
* Add new commands (frontends, backends)

## v0.2.0 - 2013-05-08

### Added
* Added new commands (get weight, set weight, servers)
* Add new commands (get weight, set weight, servers)

### Changed
* Restructured command execution and arguments in haproxyctl
* Restructure command execution and arguments in haproxyctl

### Fixed
* Fixed problems with the buffer size while reading from the socket.
* Fix problems with the buffer size while reading from the socket.

## v0.1.0 - 2013-05-07

Expand Down
2 changes: 1 addition & 1 deletion bin/haproxy-cli
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def main(args):
cmd_map = {"info" : cmds.showInfo,
"enable" : cmds.enableServer,
"disable" : cmds.disableServer,
"get-weight" : cmds.getWeight,
"get-weight" : cmds.getServerWeight,
"servers" : cmds.listServers,
"set-weight" : cmds.setWeight,
"frontends" : cmds.showFrontends,
Expand Down
86 changes: 83 additions & 3 deletions haproxy/cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ def getResult(self, res):
if res == '\n':
res = None

if self.args['output'] == 'json':
if 'output' in self.args and self.args['output'] == 'json':
return self.getJsonOutput(self.getResultObj(res))

if self.args['output'] == 'bootstrap':
if 'output' in self.args and self.args['output'] == 'bootstrap':
return self.getBootstrapOutput(self.getResultObj(res))

return res
Expand All @@ -106,6 +106,34 @@ def getResultObj(self, res):
return res


class disableServer(Cmd):
"""Disable backend/server command."""
cmdTxt = "set server %(backend)s/%(server)s state maint\r\n"
req_args = ["backend", "server"]
helpTxt = "Sets given backend/server state to maint"


class enableServer(Cmd):
"""Enable backend/server command."""
cmdTxt = "set server %(backend)s/%(server)s state ready\r\n"
req_args = ["backend", "server"]
helpTxt = "Sets given backend/server state to ready"


class setWeight(Cmd):
"""Set weight command."""
cmdTxt = "set weight %(backend)s/%(server)s %(weight)s\r\n"
req_args = ['backend', 'server', 'weight']
helpTxt = "Set weight for a given backend/server."


class getWeight(Cmd):
"""Get weight command."""
cmdTxt = "get weight %(backend)s/%(server)s\r\n"
req_args = ['backend', 'server']
helpTxt = "Get weight for a given backend/server."


class setServerAgent(Cmd):
cmdTxt = "set server %(backend)s/%(server)s agent %(value)s\r\n"
req_args = ['backend', 'server', 'value']
Expand All @@ -124,6 +152,12 @@ class setServerState(Cmd):
helpTxt = "Force a server's administrative state to a new state."


class getServerWeight(Cmd):
cmdTxt = "get weight %(backend)s/%(server)s\r\n"
req_args = ['backend', 'server']
helpTxt = "Get weight for a given backend/server."


class setServerWeight(Cmd):
cmdTxt = "set server %(backend)s/%(server)s weight %(value)s\r\n"
req_args = ['backend', 'server', 'value']
Expand Down Expand Up @@ -278,7 +312,6 @@ def _getResult(self, res):
for e in lines:
me = re.match(cl, e)
if me:
print(e)
result.append(e.split(",")[0])
return result

Expand All @@ -295,6 +328,15 @@ class showBackends(showFBEnds):
helpTxt = "List all Backends."


class showErrors(Cmd):
"""Show errors HAProxy command."""
cmdTxt = "show errors\r\n"
helpTxt = "Shows errors on HAProxy instance."

def getResultObj(self, res):
return res.split('\n')


class showInfo(Cmd):
"""Show info HAProxy command"""
cmdTxt = "show info\r\n"
Expand All @@ -321,6 +363,14 @@ def getResultObj(self, res):
class baseStat(Cmd):
"""Base class for stats commands."""

def getCols(self, res):
"""Get columns from stats output."""
mobj = re.match("^#(?P<columns>.*)$", res, re.MULTILINE)

if mobj:
return dict((a, i) for i, a in enumerate(mobj.groupdict()['columns'].split(',')))
raise Exception("Could not parse columns from HAProxy output")

def getDict(self, res):
# clean response
res = re.sub(r'^# ', '', res, re.MULTILINE)
Expand All @@ -331,6 +381,36 @@ def getDict(self, res):
return csv.DictReader(csv_string, delimiter=',')


class listServers(baseStat):
"""Show servers in the given backend"""

req_args = ['backend']
cmdTxt = "show stat\r\n"
helpTxt = "Lists servers in the given backend"

def getResult(self, res):
return "\n".join(self.getResultObj(res))

def getResultObj(self, res):
servers = []
cols = self.getCols(res)

for line in res.split('\n'):
if line.startswith(self.args['backend']):
# Lines for server start with the name of the
# backend.

outCols = line.split(',')
if outCols[cols['svname']] != 'BACKEND':
servers.append(" " .join(("Name: %s" % outCols[cols['svname']],
"Status: %s" % outCols[cols['status']],
"Weight: %s" % outCols[cols['weight']],
"bIn: %s" % outCols[cols['bin']],
"bOut: %s" % outCols[cols['bout']])))

return servers


class showServers(baseStat):
"""Show all servers. If backend is given, show only servers for this backend. """
cmdTxt = "show stat\r\n"
Expand Down
3 changes: 2 additions & 1 deletion haproxy/tests/test_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ def setUp(self):
"""

self.Resp = {
"disable": "disable server redis-ro/redis-ro0",
"enable": "set server server redis-ro/redis-ro0 state ready",
"disable": "set server server redis-ro/redis-ro0 state maint",
"set-server-agent": "set server redis-ro/redis-ro0 agent up",
"set-server-health": "set server redis-ro/redis-ro0 health stopping",
"set-server-state": "set server redis-ro/redis-ro0 state drain",
Expand Down

0 comments on commit c86aed3

Please sign in to comment.