1""" 2Util functions for the NXOS API modules. 3""" 4 5import json 6import logging 7 8import salt.utils.http 9from salt.exceptions import SaltException 10from salt.utils.args import clean_kwargs 11 12log = logging.getLogger(__name__) 13 14RPC_INIT_KWARGS = [ 15 "transport", 16 "host", 17 "username", 18 "password", 19 "port", 20 "timeout", 21 "verify", 22 "rpc_version", 23] 24 25 26def _prepare_connection(**nxos_api_kwargs): 27 """ 28 Prepare the connection with the remote network device, and clean up the key 29 value pairs, removing the args used for the connection init. 30 """ 31 nxos_api_kwargs = clean_kwargs(**nxos_api_kwargs) 32 init_kwargs = {} 33 # Clean up any arguments that are not required 34 for karg, warg in nxos_api_kwargs.items(): 35 if karg in RPC_INIT_KWARGS: 36 init_kwargs[karg] = warg 37 if "host" not in init_kwargs: 38 init_kwargs["host"] = "localhost" 39 if "transport" not in init_kwargs: 40 init_kwargs["transport"] = "https" 41 if "port" not in init_kwargs: 42 init_kwargs["port"] = 80 if init_kwargs["transport"] == "http" else 443 43 verify = init_kwargs.get("verify", True) 44 if isinstance(verify, bool): 45 init_kwargs["verify_ssl"] = verify 46 else: 47 init_kwargs["ca_bundle"] = verify 48 if "rpc_version" not in init_kwargs: 49 init_kwargs["rpc_version"] = "2.0" 50 if "timeout" not in init_kwargs: 51 init_kwargs["timeout"] = 60 52 return init_kwargs 53 54 55def rpc(commands, method="cli", **kwargs): 56 """ 57 Execute an arbitrary RPC request via the Nexus API. 58 59 commands 60 The commands to be executed. 61 62 method: ``cli`` 63 The type of the response, i.e., raw text (``cli_ascii``) or structured 64 document (``cli``). Defaults to ``cli`` (structured data). 65 66 transport: ``https`` 67 Specifies the type of connection transport to use. Valid values for the 68 connection are ``http``, and ``https``. 69 70 host: ``localhost`` 71 The IP address or DNS host name of the connection device. 72 73 username: ``admin`` 74 The username to pass to the device to authenticate the NX-API connection. 75 76 password 77 The password to pass to the device to authenticate the NX-API connection. 78 79 port 80 The TCP port of the endpoint for the NX-API connection. If this keyword is 81 not specified, the default value is automatically determined by the 82 transport type (``80`` for ``http``, or ``443`` for ``https``). 83 84 timeout: ``60`` 85 Time in seconds to wait for the device to respond. Default: 60 seconds. 86 87 verify: ``True`` 88 Either a boolean, in which case it controls whether we verify the NX-API 89 TLS certificate, or a string, in which case it must be a path to a CA bundle 90 to use. Defaults to ``True``. 91 """ 92 init_args = _prepare_connection(**kwargs) 93 log.error("These are the init args:") 94 log.error(init_args) 95 url = "{transport}://{host}:{port}/ins".format( 96 transport=init_args["transport"], host=init_args["host"], port=init_args["port"] 97 ) 98 headers = {"content-type": "application/json-rpc"} 99 payload = [] 100 if not isinstance(commands, (list, tuple)): 101 commands = [commands] 102 for index, command in enumerate(commands): 103 payload.append( 104 { 105 "jsonrpc": init_args["rpc_version"], 106 "method": method, 107 "params": {"cmd": command, "version": 1}, 108 "id": index + 1, 109 } 110 ) 111 opts = {"http_request_timeout": init_args["timeout"]} 112 response = salt.utils.http.query( 113 url, 114 method="POST", 115 opts=opts, 116 data=json.dumps(payload), 117 header_dict=headers, 118 decode=True, 119 decode_type="json", 120 **init_args 121 ) 122 if "error" in response: 123 raise SaltException(response["error"]) 124 response_list = response["dict"] 125 if isinstance(response_list, dict): 126 response_list = [response_list] 127 for index, command in enumerate(commands): 128 response_list[index]["command"] = command 129 return response_list 130