Skip to content
Merged
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
14 changes: 14 additions & 0 deletions example/xr1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: eos.netclab.dev/v1alpha1
kind: EosCommand
metadata:
name: eoscommand-2
spec:
endpoint: ceos01.default.svc.cluster.local
removeContainer: false
cmds:
no spanning-tree vlan-id 4093-4094: {}
ip prefix-list PL-Loopback0:
seq 10 permit 10.0.0.1/32 eq 32: {}
seq 20 permit 10.0.0.2/32 eq 32: {}
router bgp 65100:
no bgp default ipv4-unicast: {}
4 changes: 4 additions & 0 deletions example/xr.yaml → example/xr2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ metadata:
name: eoscommand-1
spec:
endpoint: ceos01.default.svc.cluster.local
removeContainer: true
cmds:
no spanning-tree vlan-id 4093-4094: {}
ip prefix-list PL-Loopback0:
seq 10 permit 10.0.0.1/32 eq 32: {}
seq 20 permit 10.0.0.2/32 eq 32: {}
router bgp 65100:
no bgp default ipv4-unicast: {}
2 changes: 1 addition & 1 deletion function/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
"""The version of the function."""

# This is set at build time, using "hatch version"
__version__ = "0.0.15"
__version__ = "0.0.16"
43 changes: 36 additions & 7 deletions function/fn.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ async def RunFunction(

rsp = response.to(req)

composite = req.observed.composite.resource
name_prefix = composite["metadata"]["name"]
fqdn = composite["spec"]["endpoint"]
cmds = composite["spec"]["cmds"]
composite = resource.struct_to_dict(req.observed.composite.resource)
name_prefix = composite.get("metadata").get("name")
composite_spec: dict = composite.get("spec")
fqdn = composite_spec.get("endpoint")
cmds = composite_spec.get("cmds")
remove_container = composite_spec.get("removeContainer")

environment = resource.struct_to_dict(
req.context["apiextensions.crossplane.io/environment"]
Expand Down Expand Up @@ -86,10 +88,13 @@ async def RunFunction(
}
jsonrpc_create = request_json("runCmds", params=jsonrpc_create_params)

remove_path = [*path[:-1], f"no {path[-1]}"]
jsonrpc_remove_params = {
**JSONRPC_BASE,
"cmds": ["enable", "configure", *remove_path],
"cmds": [
"enable",
"configure",
*build_remove_path(path, remove_container=remove_container),
],
}
jsonrpc_remove = request_json("runCmds", params=jsonrpc_remove_params)

Expand All @@ -113,6 +118,30 @@ async def RunFunction(
return rsp


def toggle_no(cmd: str) -> str:
"""To clarify intent of build_remove_path()."""
return cmd.removeprefix("no ") if cmd.startswith("no ") else f"no {cmd}"


def build_remove_path(path: list[str], *, remove_container: bool = False) -> list[str]:
"""Create cmd for remove op."""
head, *tail = path

# remove the container
if remove_container and tail:
return [f"no {head}"]

# remove nested items
if tail:
return [
head,
*(toggle_no(cmd) for cmd in tail),
]

# one line path
return [toggle_no(head)]


def jq_path(cmds: list[str]) -> str:
"""Create middle part of jq logic expression."""
return "".join([f".cmds[{json.dumps(c)}]" for c in cmds])
Expand Down Expand Up @@ -142,7 +171,7 @@ def walk_cmds(cmds: dict, path: list[str] | None = None) -> list[list[str]]:
next_path = [*path, cmd]

if subtree == {}:
# Leaf emit array
# Leaf -> emit array
results.append(next_path)
else:
# Recurse
Expand Down