Skip to content

Commit

Permalink
[PoE] Add PoE CLI
Browse files Browse the repository at this point in the history
Add show/config commands
Add UT
Update command reference

Signed-off-by: vadym-hlushko <[email protected]>
Signed-off-by: Serhiy Boiko <[email protected]>
  • Loading branch information
vadym-hlushko authored and SerhiyBoikoPLV committed Jul 29, 2024
1 parent 84cb00a commit e520782
Show file tree
Hide file tree
Showing 7 changed files with 1,016 additions and 0 deletions.
213 changes: 213 additions & 0 deletions config/plugins/poe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
"""
Config CLI plugin for the SONiC Power over Ethernet feature.
This file is auto-generated by sonic-cli-gen tool but adjusted to meet PoE HLD requirenments.
"""

import copy
import click
import utilities_common.cli as clicommon
import utilities_common.general as general
from config import config_mgmt


# Load sonic-cfggen from source since /usr/local/bin/sonic-cfggen does not have .py extension.
sonic_cfggen = general.load_module_from_source('sonic_cfggen', '/usr/local/bin/sonic-cfggen')


POE_PORT = 'POE_PORT'


def _exit_with_error(*args, **kwargs):
""" Print a message with click.secho and abort CLI.
Args:
args: Positional arguments to pass to click.secho
kwargs: Keyword arguments to pass to click.secho
"""

click.secho(*args, **kwargs)
raise click.Abort()


def _validate_config_or_raise(cfg):
""" Validate config db data using ConfigMgmt.
Args:
cfg (Dict): Config DB data to validate.
Raises:
Exception: when cfg does not satisfy YANG schema.
"""

try:
cfg = sonic_cfggen.FormatConverter.to_serialized(copy.deepcopy(cfg))
config_mgmt.ConfigMgmt().loadData(cfg)
except Exception as err:
raise Exception('Failed to validate configuration: {}'.format(err))


def _update_entry_validated(db, table, key, data, create_if_not_exists=False):
""" Update entry in table and validate configuration.
If attribute value in data is None, the attribute is deleted.
Args:
db (swsscommon.ConfigDBConnector): Config DB connector obect.
table (str): Table name to add new entry to.
key (Union[str, Tuple]): Key name in the table.
data (Dict): Entry data.
create_if_not_exists (bool):
In case entry does not exists already a new entry
is not created if this flag is set to False and
creates a new entry if flag is set to True.
Raises:
Exception: when cfg does not satisfy YANG schema.
"""

cfg = db.get_config()
cfg.setdefault(table, {})

if not data:
raise Exception(f"No field/values to update {key}")

if create_if_not_exists:
cfg[table].setdefault(key, {})

if key not in cfg[table]:
raise Exception(f"{key} does not have PoE configuration")

entry_changed = False
for attr, value in data.items():
if value == cfg[table][key].get(attr):
continue
entry_changed = True
if value is None:
cfg[table][key].pop(attr, None)
else:
cfg[table][key][attr] = value

if not entry_changed:
return

_validate_config_or_raise(cfg)
db.set_entry(table, key, cfg[table][key])


# 'poe' subcommand ("config poe ...")
@click.group(
name="poe",
cls=clicommon.AliasedGroup,
)
def poe():
""" Configure PoE (Power over Ethernet) feature """
pass


# 'interface' subcommand ("config poe interface ...")
@poe.group(
name="interface",
cls=clicommon.AliasedGroup,
)
def poe_interface():
""" Configure PoE interface """
pass


# 'status' subcommand ("config poe interface status ...")
@poe_interface.command(
name="status"
)
@click.argument(
"ifname",
nargs=1,
required=True,
)
@click.argument(
"enabled",
nargs=1,
required=True,
type=click.Choice(["enable", "disable"])
)
@clicommon.pass_db
def poe_intf_status(db, ifname, enabled):
""" Enable or disable PoE on interface """

data = {}
if enabled is not None:
data["enabled"] = enabled

try:
_update_entry_validated(db.cfgdb, POE_PORT, ifname, data)
except Exception as err:
_exit_with_error(f"Error: {err}", fg="red")


# 'power-limit' subcommand ("config poe interface power-limit ...")
@poe_interface.command(
name="power-limit"
)
@click.argument(
"ifname",
nargs=1,
required=True,
)
@click.argument(
"power_limit",
nargs=1,
required=True,
type=click.INT
)
@clicommon.pass_db
def poe_intf_power_limit(db, ifname, power_limit):
""" Configure PoE interface power limit """

data = {}
if power_limit is not None:
data["pwr_limit"] = power_limit

try:
_update_entry_validated(db.cfgdb, POE_PORT, ifname, data)
except Exception as err:
_exit_with_error(f"Error: {err}", fg="red")


# 'priority' subcommand ("config poe interface priority ...")
@poe_interface.command(
name="priority"
)
@click.argument(
"ifname",
nargs=1,
required=True,
)
@click.argument(
"priority",
nargs=1,
required=True,
type=click.Choice(["low", "high", "crit"])
)
@clicommon.pass_db
def poe_intf_priority(db, ifname, priority):
""" Configure PoE interface priority """

data = {}
if priority is not None:
data["priority"] = priority

try:
_update_entry_validated(db.cfgdb, POE_PORT, ifname, data)
except Exception as err:
_exit_with_error(f"Error: {err}", fg="red")


def register(cli):
""" Register new CLI nodes in root CLI.
Args:
cli: Root CLI node.
Raises:
Exception: when root CLI already has a command
we are trying to register.
"""
cli_node = poe
if cli_node.name in cli.commands:
raise Exception(f"{cli_node.name} already exists in CLI")
cli.add_command(poe)
114 changes: 114 additions & 0 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@
* [Static DNS show command](#static-dns-show-command)
* [Wake-on-LAN Commands](#wake-on-lan-commands)
* [Send Wake-on-LAN Magic Packet command](#send-wake-on-lan-magic-packet-command)
* [Power over Ethernet](#power-over-ethernet)
* [PoE show commands](#poe-show-commands)
* [PoE config commands](#poe-config-commands)

## Document History

Expand Down Expand Up @@ -13701,3 +13704,114 @@ Sending 3 magic packet to 11:33:55:77:99:bb via interface Vlan1000
```
For the 4th example, it specifise 2 target MAC addresses and `count` is 3. So it'll send 6 magic packets in total.
## Power over Ethernet
This section explains all the PoE commands that are supported in SONiC.
### PoE show commands
This sub-section contains the show commands.
- Show status of all PoE devices:
```
show poe status
```
```
admin@sonic:~$ show poe status
Id PoE ports Total power Power consump Power available Power limit mode HW info Version
---- ----------- ------------- --------------- ----------------- ------------------ --------- ---------
0 16 100.000 W 10.000 W 90.000 W port mcu1 0.1.2.3
1 16 100.000 W 10.000 W 90.000 W class mcu2 0.1.2.3
```
- Show status of all PoE PSEs:
```
show poe pse status
```
```
admin@sonic:~$ show poe pse status
Id Status Temperature SW ver HW ver
---- -------- ------------- ---------------- ----------------
0 active 25.000 C 0.1.2.3 4.5.6.7
1 active 25.000 C 0.1.2.3 4.5.6.7
2 active 25.000 C 0.1.2.3 4.5.6.7
3 active 25.000 C 0.1.2.3 4.5.6.7
```
- Show status of all PoE interfaces:
```
show poe interface status
```
```
admin@sonic:~$ show poe interface status
Port Status En/Dis Priority Protocol Class A Class B PWR Consump PWR limit Voltage Current
----------- ---------- -------- ---------- -------------- --------- --------- ------------- ----------- --------- ---------
Ethernet0 delivering enable crit 802.3bt Type 3 2 4 10.000 W 50.000 W 50.000 V 0.200 A
Ethernet1 delivering enable crit 802.3bt Type 3 2 4 10.000 W 50.000 W 50.000 V 0.200 A
Ethernet2 delivering enable low 802.3bt Type 3 2 4 10.000 W 50.000 W 50.000 V 0.200 A
Ethernet3 delivering enable low 802.3bt Type 3 2 4 10.000 W 50.000 W 50.000 V 0.200 A
```
- Show current configuration of all PoE interfaces:
```
show poe interface configuration
```
```
admin@sonic:~$ show poe interface configuration
Port En/Dis Power limit Priority
----------- -------- ------------- ----------
Ethernet0 enable 50 crit
Ethernet1 enable 50 crit
Ethernet2 enable 50 low
Ethernet3 enable 50 low
```
### PoE config commands
This sub-section contains the config commands.
- Enable PoE:
```
admin@sonic:~$ sudo config poe interface status --help
Usage: config poe interface status [OPTIONS] IFNAME [enable|disable]
Enable or disable PoE on interface
Options:
-h, -?, --help Show this message and exit.
```
```
admin@sonic:~$ sudo config poe interface status Ethernet0 enable
```
- Configure power limit:
```
admin@sonic:~$ sudo config poe interface power-limit --help
Usage: config poe interface power-limit [OPTIONS] IFNAME POWER_LIMIT
Configure PoE interface power limit
Options:
-h, -?, --help Show this message and exit.
```
```
admin@sonic:~$ sudo config poe interface power-limit Ethernet0 25
```
- Configure priority:
```
admin@sonic:~$ sudo config poe interface priority --help
Usage: config poe interface priority [OPTIONS] IFNAME [low|high|crit]
Configure PoE interface priority
Options:
-?, -h, --help Show this message and exit.
```
```
admin@sonic:~$ sudo config poe interface priority Ethernet0 crit
```
Go Back To [Beginning of the document](#) or [Beginning of this section](#power-over-ethernet)
Loading

0 comments on commit e520782

Please sign in to comment.