11"""A Crossplane composition function."""
22
33import hashlib
4+ import json
45
56import grpc
67from crossplane .function import logging , request , resource , response
78from crossplane .function .proto .v1 import run_function_pb2 as fnv1
89from crossplane .function .proto .v1 import run_function_pb2_grpc as grpcv1
910from jsonrpcclient import request_json
1011
12+ JSONRPC_BASE = {"version" : 1 , "format" : "json" }
13+
1114
1215class FunctionRunner (grpcv1 .FunctionRunnerService ):
1316 """A FunctionRunner handles gRPC RunFunctionRequests."""
@@ -47,29 +50,29 @@ async def RunFunction(
4750 }
4851
4952 jsonrpc_observe_params = {
50- "version" : 1 ,
51- "format" : "json" ,
53+ ** JSONRPC_BASE ,
5254 "cmds" : ["enable" , "show running-config" ],
5355 }
5456 jsonrpc_observe = request_json ("runCmds" , params = jsonrpc_observe_params )
5557
56- command_paths = walk_cmds (cmds )
58+ command_paths = sorted ( walk_cmds (cmds ) )
5759 log .info ("Generated command paths" , count = len (command_paths ))
5860
5961 for path in command_paths :
6062 name = name_prefix + "-" + name_from_path (path )
6163
64+ path_log = log .bind (resource = name , path = " | " .join (path ))
65+ path_log .debug ("Creating resource" )
66+
6267 jsonrpc_create_params = {
63- "version" : 1 ,
64- "format" : "json" ,
68+ ** JSONRPC_BASE ,
6569 "cmds" : ["enable" , "configure" , * path ],
6670 }
6771 jsonrpc_create = request_json ("runCmds" , params = jsonrpc_create_params )
6872
6973 remove_path = [* path [:- 1 ], f"no { path [- 1 ]} " ]
7074 jsonrpc_remove_params = {
71- "version" : 1 ,
72- "format" : "json" ,
75+ ** JSONRPC_BASE ,
7376 "cmds" : ["enable" , "configure" , * remove_path ],
7477 }
7578 jsonrpc_remove = request_json ("runCmds" , params = jsonrpc_remove_params )
@@ -94,19 +97,25 @@ async def RunFunction(
9497 return rsp
9598
9699
100+ def jq_path (cmds : list [str ]) -> str :
101+ """Create middle part of jq logic expression."""
102+ return "" .join ([f".cmds[{ json .dumps (c )} ]" for c in cmds ])
103+
104+
97105def create_jq_logic_expressions (path : list [str ]) -> tuple [str , str ]:
98- """Create jq logic exp for Request."""
99- logic = ".response.body.error == null and ("
100- for cmd in path [:- 1 ]:
101- logic = logic + f'.response.body.result[1].cmds."{ cmd } ".cmds'
102- logic1 = logic + f' | has("{ path [- 1 ]} ")' + ")"
103- logic2 = logic + f' | has("{ path [- 1 ]} ")' + " | not)"
106+ """Compose jq logic expressions."""
107+ base = ".response.body"
108+ tree = f"{ base } .result[1]{ jq_path (path [:- 1 ])} .cmds"
109+ check = f"has({ json .dumps (path [- 1 ])} )"
110+
111+ expected = f"{ base } .error == null and ({ tree } | { check } )"
112+ removed = f"{ base } .error == null and ({ tree } | { check } | not)"
104113
105- return logic1 , logic2
114+ return expected , removed
106115
107116
108117def walk_cmds (cmds : dict , path : list [str ] | None = None ) -> list [list [str ]]:
109- """walk_cmds function ."""
118+ """Make command paths from nested command tree ."""
110119 if path is None :
111120 path = []
112121
0 commit comments