Skip to content

Commit

Permalink
[unconfig] Adjust device discovery (#51)
Browse files Browse the repository at this point in the history
* [unconfig] Adjust device discovery

Signed-off-by: Jakub Boguščiak <[email protected]>

* Formatting (mypy, ruff)

Signed-off-by: Jakub Boguščiak <[email protected]>

* Formatting (pyright)

Signed-off-by: Jakub Boguščiak <[email protected]>

* Add input container to input data

Signed-off-by: Jakub Boguščiak <[email protected]>

* Formatting (ruff)

Signed-off-by: Jakub Boguščiak <[email protected]>

* Adjust install worker

Signed-off-by: Jakub Boguščiak <[email protected]>

* Fix credentials

Signed-off-by: Jakub Boguščiak <[email protected]>

* Adjust install params

Signed-off-by: Jakub Boguščiak <[email protected]>

* Add comment and remove redundant use

Signed-off-by: Jakub Boguščiak <[email protected]>

* Formatting (ruff)

Signed-off-by: Jakub Boguščiak <[email protected]>

* Update install params

Signed-off-by: Jakub Boguščiak <[email protected]>

* Update python SDK

Signed-off-by: Jakub Boguščiak <[email protected]>

* Update Connection Manager

Signed-off-by: Jakub Boguščiak <[email protected]>

* Formatting (ruff)

Signed-off-by: Jakub Boguščiak <[email protected]>

* Update frinx python sdk

Signed-off-by: Jakub Boguščiak <[email protected]>

* Bump frinx python SDK

Signed-off-by: Jakub Boguščiak <[email protected]>

* Review changes

Signed-off-by: Jakub Boguščiak <[email protected]>

---------

Signed-off-by: Jakub Boguščiak <[email protected]>
  • Loading branch information
jbogusciak authored Jun 14, 2024
1 parent 6acc9d1 commit c7aac0c
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 33 deletions.
5 changes: 4 additions & 1 deletion uniconfig/python/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@
- Update Inventory properties and bump Uniconfig API.

# 2.3.3
- Fix Device Discovery RPC based on new OpenAPI model.
- Fix Device Discovery RPC based on new OpenAPI model.

# 2.3.4
- Device Discovery RPC workaround caused by choice-nodes in UniConfig Yang models.
76 changes: 56 additions & 20 deletions uniconfig/python/frinx_worker/uniconfig/connection_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@

from . import class_to_json
from . import handle_response
from . import snake_to_kebab_case


class ConnectionManager(ServiceWorkersImpl):
class InstallNode(WorkerImpl):
from frinx_api.uniconfig.connection.manager.installnode import Cli
from frinx_api.uniconfig.connection.manager.installnode import Gnmi
from frinx_api.uniconfig.connection.manager.installnode import Input
from frinx_api.uniconfig.connection.manager.installnode import Netconf
from frinx_api.uniconfig.rest_api import InstallNode as UniconfigApi
# from frinx_api.uniconfig.connection.manager.installnode import Cli
# from frinx_api.uniconfig.connection.manager.installnode import Gnmi
# from frinx_api.uniconfig.connection.manager.installnode import Netconf

class ExecutionProperties(TaskExecutionProperties):
exclude_empty_inputs: bool = True
Expand All @@ -48,31 +48,67 @@ def execute(self, worker_input: WorkerInput) -> TaskResult[WorkerOutput]:
if self.UniconfigApi.request is None:
raise Exception(f"Failed to create request {self.UniconfigApi.request}")

import json
response = requests.request(
url=worker_input.uniconfig_url_base + self.UniconfigApi.uri,
method=self.UniconfigApi.method,
data=class_to_json(
self.UniconfigApi.request(
input=self.Input(
node_id=worker_input.node_id,
cli=self.Cli(**worker_input.install_params)
if worker_input.connection_type == "cli"
else None,
netconf=self.Netconf(**worker_input.install_params)
if worker_input.connection_type == "netconf"
else None,
gnmi=self.Gnmi(**worker_input.install_params)
if worker_input.connection_type == "gnmi"
else None,
),
),
),
# FIXME prepare input with credentials (TEMPORARY SOLUTION)
data=json.dumps(snake_to_kebab_case(self._prepare_input(worker_input))),
# data=class_to_json(
# self.UniconfigApi.request(
# input=self.Input(
# node_id=worker_input.node_id,
# cli=self.Cli(**worker_input.install_params)
# if worker_input.connection_type == "cli"
# else None,
# netconf=self.Netconf(**worker_input.install_params)
# if worker_input.connection_type == "netconf"
# else None,
# gnmi=self.Gnmi(**worker_input.install_params)
# if worker_input.connection_type == "gnmi"
# else None,
# ),
# ),
# ),
headers=dict(UNICONFIG_HEADERS),
params=UNICONFIG_REQUEST_PARAMS,
)

return handle_response(response, self.WorkerOutput)

def _prepare_input(self, worker_input: WorkerInput) -> DictAny:
"""
The input now contains multiple choice nodes (keepalive, credentials and other). Until UniConfig can parse
choice nodes, this is a workaround to prepare the input for the installation request correctly.
https://frinxhelpdesk.atlassian.net/browse/UNIC-1764
:param worker_input: Worker input.
:return: Request input data as dict.
"""
if worker_input.connection_type == "cli":
return {
"input": {
"node_id": worker_input.node_id,
"cli": worker_input.install_params
}
}
elif worker_input.connection_type == "netconf":
return {
"input": {
"node_id": worker_input.node_id,
"netconf": worker_input.install_params
}
}
elif worker_input.connection_type == "gnmi":
return {
"input": {
"node_id": worker_input.node_id,
"gnmi": worker_input.install_params
}
}
else:
raise ValueError(f"Unknown connection type '{worker_input.connection_type}'")


class UninstallNode(WorkerImpl):
from frinx_api.uniconfig.connection.manager import ConnectionType
from frinx_api.uniconfig.connection.manager.uninstallnode import Input
Expand Down
35 changes: 34 additions & 1 deletion uniconfig/python/frinx_worker/uniconfig/device_discovery.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ipaddress import IPv4Address
from ipaddress import IPv6Address
from typing import Any

import pydantic
import requests
Expand Down Expand Up @@ -36,6 +37,37 @@
from .util import parse_ranges


def _unwrap_data(discovery_input: Input) -> dict[str, Any]:
"""
Unwrapping is necessary because of the input now containing choice wrapper nodes which cannot be parsed by
UniConfig yet. https://frinxhelpdesk.atlassian.net/browse/UNIC-1764
:param discovery_input: Device Discovery input.
:return: Unwrapped data as dict.
"""
tcp_port: list[dict[str, Any]] = []
udp_port: list[dict[str, Any]] = []
address: list[dict[str, Any]] = []
if discovery_input.tcp_port is not None:
for tcp_port_item in discovery_input.tcp_port:
if tcp_port_item.type_of_port is not None:
tcp_port.append(tcp_port_item.type_of_port.model_dump())
if discovery_input.udp_port is not None:
for udp_port_item in discovery_input.udp_port:
if udp_port_item.type_of_port is not None:
udp_port.append(udp_port_item.type_of_port.model_dump())
if discovery_input.address is not None:
for address_item in discovery_input.address:
if address_item.type_of_address is not None:
address.append(address_item.type_of_address.model_dump())
return {
"input": {
"address": None if not address else address,
"tcp_port": None if not tcp_port else tcp_port,
"udp_port": None if not udp_port else udp_port
}
}


class DeviceDiscoveryWorkers(ServiceWorkersImpl):
class DeviceDiscoveryWorker(WorkerImpl):
class ExecutionProperties(TaskExecutionProperties):
Expand Down Expand Up @@ -129,8 +161,9 @@ def execute(self, worker_input: WorkerInput) -> TaskResult[WorkerOutput]:
headers=dict(UNICONFIG_HEADERS),
params=UNICONFIG_REQUEST_PARAMS,
method=Discover.method,
# temporary workaround until UC adds possibility to accept choice nodes
data=class_to_json(
Discover.request(input=template),
_unwrap_data(template),
),
)

Expand Down
20 changes: 10 additions & 10 deletions uniconfig/python/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion uniconfig/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ packages = [{ include = "frinx_worker" }]
name = "frinx-uniconfig-worker"
description = "Conductor worker for Frinx Uniconfig"
authors = ["Jozef Volak <[email protected]>"]
version = "2.3.3"
version = "2.3.4"
readme = ["README.md", "CHANGELOG.md", "RELEASE.md"]
keywords = ["frinx-machine", "uniconfig", "worker"]
license = "Apache 2.0"
Expand Down

0 comments on commit c7aac0c

Please sign in to comment.