Merge branch 'fixup/remove-client-mac-for-vbss-creation' into 'master'

Remove STA MAC requirement for VBSS creation

See merge request prpl-foundation/prplmesh/topologyviewer!36
This commit is contained in:
Tucker Polomik
2024-09-05 18:19:21 +00:00
3 changed files with 11 additions and 20 deletions

21
main.py
View File

@@ -690,14 +690,6 @@ def update_prplmesh_ssid(_):
""" """
return get_topology().get_ssid() return get_topology().get_ssid()
@app.callback(Output('vbss-creation-client-mac', 'options'),
Input('vbss-creation-interval', 'n_intervals')
)
def update_stations(_):
"""Populates the available station list for the client MAC field of a VBSS creation request.
"""
return [sta.get_mac() for sta in get_topology().get_stations()]
@app.callback(Output('transition_station', 'options'), @app.callback(Output('transition_station', 'options'),
Output('transition_bssid', 'options'), Output('transition_bssid', 'options'),
Output('transition_bssid', 'placeholder'), Output('transition_bssid', 'placeholder'),
@@ -715,6 +707,7 @@ def update_transition_dropdown_menus(_, _type):
""" """
placeholder = 'Select a new BSSID' placeholder = 'Select a new BSSID'
avail_stations = [sta.get_mac() for sta in get_topology().get_stations()] avail_stations = [sta.get_mac() for sta in get_topology().get_stations()]
avail_targets = []
if _type is None or _type == 'Client Steering': if _type is None or _type == 'Client Steering':
avail_targets = [bss.get_bssid() for bss in get_topology().get_bsses()] avail_targets = [bss.get_bssid() for bss in get_topology().get_bsses()]
elif _type == 'VBSS': elif _type == 'VBSS':
@@ -867,18 +860,16 @@ def vbss_move_callback(n_clicks: int, ssid: str, password: str, dest_ruid: str,
Input('vbss-creation-submit', 'n_clicks'), Input('vbss-creation-submit', 'n_clicks'),
State('vbss-ssid', 'value'), State('vbss-ssid', 'value'),
State('vbss-pw', 'value'), State('vbss-pw', 'value'),
State('vbss-creation-client-mac', 'value'),
State('vbss-creation-vbssid', 'value'), State('vbss-creation-vbssid', 'value'),
State('vbss-creation-ruid', 'value') State('vbss-creation-ruid', 'value')
) )
def vbss_creation_click(n_clicks: int, ssid: str, password: str, client_mac: str, vbssid: str, ruid: str): def vbss_creation_click(n_clicks: int, ssid: str, password: str, vbssid: str, ruid: str):
"""Callback for VBSS Creation Button click """Callback for VBSS Creation Button click
Args: Args:
n_clicks (int): How many clicks? Binary, 1 or 0. If 0, just bail. n_clicks (int): How many clicks? Binary, 1 or 0. If 0, just bail.
ssid (str): SSID of the VBSS to create. ssid (str): SSID of the VBSS to create.
password (str): Password for the VBSS. password (str): Password for the VBSS.
client_mac (str): The Client (STA) that this VBSS is meant for.
vbssid (str): The VBSSID to use for the newly created VBSS. vbssid (str): The VBSSID to use for the newly created VBSS.
Returns: Returns:
@@ -892,23 +883,18 @@ def vbss_creation_click(n_clicks: int, ssid: str, password: str, client_mac: str
return "Enter a password" return "Enter a password"
if vbssid is None: if vbssid is None:
return "Enter a VBSSID" return "Enter a VBSSID"
if client_mac is None:
return "Select a station"
if ruid is None: if ruid is None:
return "Select a Radio to create the VBSS on." return "Select a Radio to create the VBSS on."
is_password_valid, password_error = validation.validate_vbss_password_for_creation(password) is_password_valid, password_error = validation.validate_vbss_password_for_creation(password)
if not is_password_valid: if not is_password_valid:
return f"Invalid password: {password_error}" return f"Invalid password: {password_error}"
is_client_mac_valid, client_mac_error = validation.validate_vbss_client_mac(client_mac, get_topology())
if not is_client_mac_valid:
return f"Client MAC invalid: {client_mac_error}"
is_vbssid_valid, vbssid_error = validation.validate_vbss_vbssid(vbssid, get_topology()) is_vbssid_valid, vbssid_error = validation.validate_vbss_vbssid(vbssid, get_topology())
if not is_vbssid_valid: if not is_vbssid_valid:
return f"VBSSID invalid: {vbssid_error}" return f"VBSSID invalid: {vbssid_error}"
radio = get_topology().get_radio_by_ruid(ruid) radio = get_topology().get_radio_by_ruid(ruid)
if radio is None: if radio is None:
return "Radio is unknown" return "Radio is unknown"
send_vbss_creation_request(g_ControllerConnectionCtx, vbssid, client_mac, ssid, password, radio) send_vbss_creation_request(g_ControllerConnectionCtx, vbssid, ssid, password, radio)
return "Sent a VBSS creation request." return "Sent a VBSS creation request."
@@ -1090,7 +1076,6 @@ def gen_app_layout(config: configparser.ConfigParser):
dcc.Input(id="vbss-ssid", type="text", placeholder="VBSS SSID"), dcc.Input(id="vbss-ssid", type="text", placeholder="VBSS SSID"),
dcc.Input(id="vbss-pw", type="password", placeholder="VBSS Password"), dcc.Input(id="vbss-pw", type="password", placeholder="VBSS Password"),
dcc.Input(id='vbss-creation-vbssid', type='text', placeholder='VBSSID'), dcc.Input(id='vbss-creation-vbssid', type='text', placeholder='VBSSID'),
dcc.Dropdown(options=[], id='vbss-creation-client-mac', placeholder='Select a station.'),
dcc.Dropdown(options=[], id='vbss-creation-ruid', placeholder='Select a RUID.'), dcc.Dropdown(options=[], id='vbss-creation-ruid', placeholder='Select a RUID.'),
dcc.Interval(id='vbss-creation-interval', interval=300, n_intervals=0), dcc.Interval(id='vbss-creation-interval', interval=300, n_intervals=0),
html.Div(id="vbss-creation-output", children='Press Transition to begin station transition.'), html.Div(id="vbss-creation-output", children='Press Transition to begin station transition.'),

View File

@@ -36,6 +36,7 @@ def marshall_nbapi_blob(nbapi_json) -> Topology:
agent_dict: Dict[str, Agent] = {} agent_dict: Dict[str, Agent] = {}
iface_dict: Dict[str, Interface] = {} iface_dict: Dict[str, Interface] = {}
controller_id: str = ''
for entry in nbapi_json: for entry in nbapi_json:
path = entry['path'] path = entry['path']

View File

@@ -53,7 +53,7 @@ def send_vbss_move_request(conn_ctx: ControllerConnectionCtx, client_mac: str, d
} }
send_nbapi_command(conn_ctx, json_payload) send_nbapi_command(conn_ctx, json_payload)
def send_vbss_creation_request(conn_ctx: ControllerConnectionCtx, vbssid: str, client_mac: str, ssid: str, password: str, radio: Radio): def send_vbss_creation_request(conn_ctx: ControllerConnectionCtx, vbssid: str, ssid: str, password: str, radio: Radio):
"""Sends a VBSS creation request to an NBAPI Radio endpoint. """Sends a VBSS creation request to an NBAPI Radio endpoint.
Args: Args:
@@ -70,12 +70,17 @@ def send_vbss_creation_request(conn_ctx: ControllerConnectionCtx, vbssid: str, c
""" """
if not conn_ctx: if not conn_ctx:
raise ValueError() raise ValueError()
# There is no need to include a client MAC addr in a VBSS creation
# request, but it's required by the prpl NBAPI, so we just pass an empty
# string.
# See: prplmesh:controller/on_action.cpp
null_client_mac = ""
device_idx = parse_index_from_path_by_key(radio.path, 'Device') device_idx = parse_index_from_path_by_key(radio.path, 'Device')
radio_idx = parse_index_from_path_by_key(radio.path, 'Radio') radio_idx = parse_index_from_path_by_key(radio.path, 'Radio')
json_payload = {"sendresp": True, json_payload = {"sendresp": True,
"commandKey": "", "commandKey": "",
"command": f"Device.WiFi.DataElements.Network.Device.{device_idx}.Radio.{radio_idx}.TriggerVBSSCreation", "command": f"Device.WiFi.DataElements.Network.Device.{device_idx}.Radio.{radio_idx}.TriggerVBSSCreation",
"inputArgs": {"vbssid": vbssid, "client_mac": client_mac, "ssid": ssid, "pass": password}} "inputArgs": {"vbssid": vbssid, "client_mac": null_client_mac, "ssid": ssid, "pass": password}}
send_nbapi_command(conn_ctx, json_payload) send_nbapi_command(conn_ctx, json_payload)
def send_vbss_destruction_request(conn_ctx: ControllerConnectionCtx, client_mac: str, should_disassociate: bool, bss: BSS): def send_vbss_destruction_request(conn_ctx: ControllerConnectionCtx, client_mac: str, should_disassociate: bool, bss: BSS):