From e0f7da8644810d70f2104decc6ca996d8cdb9feb Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 18 Apr 2019 10:56:15 +0200 Subject: [PATCH] vici: Extract command wrappers in Python bindings This simplifies the interface and allows calling not yet wrapped commands more easily. --- .../vici/python/vici/command_wrappers.py | 206 +++++++++++++++ .../plugins/vici/python/vici/exception.py | 4 + .../plugins/vici/python/vici/session.py | 235 +----------------- 3 files changed, 217 insertions(+), 228 deletions(-) create mode 100644 src/libcharon/plugins/vici/python/vici/command_wrappers.py diff --git a/src/libcharon/plugins/vici/python/vici/command_wrappers.py b/src/libcharon/plugins/vici/python/vici/command_wrappers.py new file mode 100644 index 0000000000..75a7e50c40 --- /dev/null +++ b/src/libcharon/plugins/vici/python/vici/command_wrappers.py @@ -0,0 +1,206 @@ +class CommandWrappers(object): + def version(self): + """Retrieve daemon and system specific version information. + + :return: daemon and system specific version information + :rtype: dict + """ + return self.request("version") + + def stats(self): + """Retrieve IKE daemon statistics and load information. + + :return: IKE daemon statistics and load information + :rtype: dict + """ + return self.request("stats") + + def reload_settings(self): + """Reload strongswan.conf settings and any plugins supporting reload. + """ + self.request("reload-settings") + + def initiate(self, sa): + """Initiate an SA. + + :param sa: the SA to initiate + :type sa: dict + :return: generator for logs emitted as dict + :rtype: generator + """ + return self.streamed_request("initiate", "control-log", sa) + + def terminate(self, sa): + """Terminate an SA. + + :param sa: the SA to terminate + :type sa: dict + :return: generator for logs emitted as dict + :rtype: generator + """ + return self.streamed_request("terminate", "control-log", sa) + + def redirect(self, sa): + """Redirect an IKE_SA. + + :param sa: the SA to redirect + :type sa: dict + """ + self.request("redirect", sa) + + def install(self, policy): + """Install a trap, drop or bypass policy defined by a CHILD_SA config. + + :param policy: policy to install + :type policy: dict + """ + self.request("install", policy) + + def uninstall(self, policy): + """Uninstall a trap, drop or bypass policy defined by a CHILD_SA config. + + :param policy: policy to uninstall + :type policy: dict + """ + self.request("uninstall", policy) + + def list_sas(self, filters=None): + """Retrieve active IKE_SAs and associated CHILD_SAs. + + :param filters: retrieve only matching IKE_SAs (optional) + :type filters: dict + :return: generator for active IKE_SAs and associated CHILD_SAs as dict + :rtype: generator + """ + return self.streamed_request("list-sas", "list-sa", filters) + + def list_policies(self, filters=None): + """Retrieve installed trap, drop and bypass policies. + + :param filters: retrieve only matching policies (optional) + :type filters: dict + :return: generator for installed trap, drop and bypass policies as dict + :rtype: generator + """ + return self.streamed_request("list-policies", "list-policy", + filters) + + def list_conns(self, filters=None): + """Retrieve loaded connections. + + :param filters: retrieve only matching configuration names (optional) + :type filters: dict + :return: generator for loaded connections as dict + :rtype: generator + """ + return self.streamed_request("list-conns", "list-conn", + filters) + + def get_conns(self): + """Retrieve connection names loaded exclusively over vici. + + :return: connection names + :rtype: dict + """ + return self.request("get-conns") + + def list_certs(self, filters=None): + """Retrieve loaded certificates. + + :param filters: retrieve only matching certificates (optional) + :type filters: dict + :return: generator for loaded certificates as dict + :rtype: generator + """ + return self.streamed_request("list-certs", "list-cert", filters) + + def load_conn(self, connection): + """Load a connection definition into the daemon. + + :param connection: connection definition + :type connection: dict + """ + self.request("load-conn", connection) + + def unload_conn(self, name): + """Unload a connection definition. + + :param name: connection definition name + :type name: dict + """ + self.request("unload-conn", name) + + def load_cert(self, certificate): + """Load a certificate into the daemon. + + :param certificate: PEM or DER encoded certificate + :type certificate: dict + """ + self.request("load-cert", certificate) + + def load_key(self, private_key): + """Load a private key into the daemon. + + :param private_key: PEM or DER encoded key + """ + self.request("load-key", private_key) + + def load_shared(self, secret): + """Load a shared IKE PSK, EAP or XAuth secret into the daemon. + + :param secret: shared IKE PSK, EAP or XAuth secret + :type secret: dict + """ + self.request("load-shared", secret) + + def flush_certs(self, filter=None): + """Flush the volatile certificate cache. + + Flush the certificate stored temporarily in the cache. The filter + allows to flush only a certain type of certificates, e.g. CRLs. + + :param filter: flush only certificates of a given type (optional) + :type filter: dict + """ + self.request("flush-certs", filter) + + def clear_creds(self): + """Clear credentials loaded over vici. + + Clear all loaded certificate, private key and shared key credentials. + This affects only credentials loaded over vici, but additionally + flushes the credential cache. + """ + self.request("clear-creds") + + def load_pool(self, pool): + """Load a virtual IP pool. + + Load an in-memory virtual IP and configuration attribute pool. + Existing pools with the same name get updated, if possible. + + :param pool: virtual IP and configuration attribute pool + :type pool: dict + """ + return self.request("load-pool", pool) + + def unload_pool(self, pool_name): + """Unload a virtual IP pool. + + Unload a previously loaded virtual IP and configuration attribute pool. + Unloading fails for pools with leases currently online. + + :param pool_name: pool by name + :type pool_name: dict + """ + self.request("unload-pool", pool_name) + + def get_pools(self, options): + """Retrieve loaded pools. + + :param options: filter by name and/or retrieve leases (optional) + :type options: dict + :return: loaded pools + :rtype: dict + """ + return self.request("get-pools", options) diff --git a/src/libcharon/plugins/vici/python/vici/exception.py b/src/libcharon/plugins/vici/python/vici/exception.py index 757ac51a9d..9c6606bda0 100644 --- a/src/libcharon/plugins/vici/python/vici/exception.py +++ b/src/libcharon/plugins/vici/python/vici/exception.py @@ -1,13 +1,17 @@ """Exception types that may be thrown by this library.""" + class DeserializationException(Exception): """Encountered an unexpected byte sequence or missing element type.""" + class SessionException(Exception): """Session request exception.""" + class CommandException(Exception): """Command result exception.""" + class EventUnknownException(Exception): """Event unknown exception.""" diff --git a/src/libcharon/plugins/vici/python/vici/session.py b/src/libcharon/plugins/vici/python/vici/session.py index 1383fa7783..02b6067ba5 100644 --- a/src/libcharon/plugins/vici/python/vici/session.py +++ b/src/libcharon/plugins/vici/python/vici/session.py @@ -3,237 +3,15 @@ import socket from .exception import SessionException, CommandException, EventUnknownException from .protocol import Transport, Packet, Message +from .command_wrappers import CommandWrappers -class Session(object): +class Session(CommandWrappers, object): def __init__(self, sock=None): if sock is None: sock = socket.socket(socket.AF_UNIX) sock.connect("/var/run/charon.vici") - self.handler = SessionHandler(Transport(sock)) - - def version(self): - """Retrieve daemon and system specific version information. - - :return: daemon and system specific version information - :rtype: dict - """ - return self.handler.request("version") - - def stats(self): - """Retrieve IKE daemon statistics and load information. - - :return: IKE daemon statistics and load information - :rtype: dict - """ - return self.handler.request("stats") - - def reload_settings(self): - """Reload strongswan.conf settings and any plugins supporting reload. - """ - self.handler.request("reload-settings") - - def initiate(self, sa): - """Initiate an SA. - - :param sa: the SA to initiate - :type sa: dict - :return: generator for logs emitted as dict - :rtype: generator - """ - return self.handler.streamed_request("initiate", "control-log", sa) - - def terminate(self, sa): - """Terminate an SA. - - :param sa: the SA to terminate - :type sa: dict - :return: generator for logs emitted as dict - :rtype: generator - """ - return self.handler.streamed_request("terminate", "control-log", sa) - - def redirect(self, sa): - """Redirect an IKE_SA. - - :param sa: the SA to redirect - :type sa: dict - """ - self.handler.request("redirect", sa) - - def install(self, policy): - """Install a trap, drop or bypass policy defined by a CHILD_SA config. - - :param policy: policy to install - :type policy: dict - """ - self.handler.request("install", policy) - - def uninstall(self, policy): - """Uninstall a trap, drop or bypass policy defined by a CHILD_SA config. - - :param policy: policy to uninstall - :type policy: dict - """ - self.handler.request("uninstall", policy) - - def list_sas(self, filters=None): - """Retrieve active IKE_SAs and associated CHILD_SAs. - - :param filters: retrieve only matching IKE_SAs (optional) - :type filters: dict - :return: generator for active IKE_SAs and associated CHILD_SAs as dict - :rtype: generator - """ - return self.handler.streamed_request("list-sas", "list-sa", filters) - - def list_policies(self, filters=None): - """Retrieve installed trap, drop and bypass policies. - - :param filters: retrieve only matching policies (optional) - :type filters: dict - :return: generator for installed trap, drop and bypass policies as dict - :rtype: generator - """ - return self.handler.streamed_request("list-policies", "list-policy", - filters) - - def list_conns(self, filters=None): - """Retrieve loaded connections. - - :param filters: retrieve only matching configuration names (optional) - :type filters: dict - :return: generator for loaded connections as dict - :rtype: generator - """ - return self.handler.streamed_request("list-conns", "list-conn", - filters) - - def get_conns(self): - """Retrieve connection names loaded exclusively over vici. - - :return: connection names - :rtype: dict - """ - return self.handler.request("get-conns") - - def list_certs(self, filters=None): - """Retrieve loaded certificates. - - :param filters: retrieve only matching certificates (optional) - :type filters: dict - :return: generator for loaded certificates as dict - :rtype: generator - """ - return self.handler.streamed_request("list-certs", "list-cert", filters) - - def load_conn(self, connection): - """Load a connection definition into the daemon. - - :param connection: connection definition - :type connection: dict - """ - self.handler.request("load-conn", connection) - - def unload_conn(self, name): - """Unload a connection definition. - - :param name: connection definition name - :type name: dict - """ - self.handler.request("unload-conn", name) - - def load_cert(self, certificate): - """Load a certificate into the daemon. - - :param certificate: PEM or DER encoded certificate - :type certificate: dict - """ - self.handler.request("load-cert", certificate) - - def load_key(self, private_key): - """Load a private key into the daemon. - - :param private_key: PEM or DER encoded key - """ - self.handler.request("load-key", private_key) - - def load_shared(self, secret): - """Load a shared IKE PSK, EAP or XAuth secret into the daemon. - - :param secret: shared IKE PSK, EAP or XAuth secret - :type secret: dict - """ - self.handler.request("load-shared", secret) - - def flush_certs(self, filter=None): - """Flush the volatile certificate cache. - - Flush the certificate stored temporarily in the cache. The filter - allows to flush only a certain type of certificates, e.g. CRLs. - - :param filter: flush only certificates of a given type (optional) - :type filter: dict - """ - self.handler.request("flush-certs", filter) - - def clear_creds(self): - """Clear credentials loaded over vici. - - Clear all loaded certificate, private key and shared key credentials. - This affects only credentials loaded over vici, but additionally - flushes the credential cache. - """ - self.handler.request("clear-creds") - - def load_pool(self, pool): - """Load a virtual IP pool. - - Load an in-memory virtual IP and configuration attribute pool. - Existing pools with the same name get updated, if possible. - - :param pool: virtual IP and configuration attribute pool - :type pool: dict - """ - return self.handler.request("load-pool", pool) - - def unload_pool(self, pool_name): - """Unload a virtual IP pool. - - Unload a previously loaded virtual IP and configuration attribute pool. - Unloading fails for pools with leases currently online. - - :param pool_name: pool by name - :type pool_name: dict - """ - self.handler.request("unload-pool", pool_name) - - def get_pools(self, options): - """Retrieve loaded pools. - - :param options: filter by name and/or retrieve leases (optional) - :type options: dict - :return: loaded pools - :rtype: dict - """ - return self.handler.request("get-pools", options) - - def listen(self, event_types): - """Register and listen for the given events. - - :param event_types: event types to register - :type event_types: list - :return: generator for streamed event responses as (event_type, dict) - :rtype: generator - """ - return self.handler.listen(event_types) - - -class SessionHandler(object): - """Handles client command execution requests over vici.""" - - def __init__(self, transport): - self.transport = transport + self.transport = Transport(sock) def _communicate(self, packet): """Send packet over transport and parse response. @@ -322,7 +100,7 @@ class SessionHandler(object): if message is not None: message = Message.serialize(message) - self._register_unregister(event_stream_type, True); + self._register_unregister(event_stream_type, True) try: packet = Packet.request(command, message) @@ -352,7 +130,7 @@ class SessionHandler(object): ) finally: - self._register_unregister(event_stream_type, False); + self._register_unregister(event_stream_type, False) # evaluate command result, if any if "success" in command_response: @@ -379,7 +157,8 @@ class SessionHandler(object): response = Packet.parse(self.transport.receive()) if response.response_type == Packet.EVENT: try: - yield response.event_type, Message.deserialize(response.payload) + msg = Message.deserialize(response.payload) + yield response.event_type, msg except GeneratorExit: break -- 2.47.2