Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PoE] Add PoE CLI #3436

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please clarify if this CLIs will be available only in supported platforms

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLI will be available on all platforms. If the platform does not support PoE the user will get an error message when trying to configure anything on an interface.

)
@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 @@ -228,6 +228,9 @@
* [Banner Commands](#banner-commands)
* [Banner config commands](#banner-config-commands)
* [Banner show command](#banner-show-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 @@ -13921,3 +13924,114 @@ enabled Login You are on

Help: https://sonic-net.github.io/SONiC/
```

## 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
Loading