diff options
Diffstat (limited to 'lib/ansible/module_utils/network/skydive/api.py')
-rw-r--r-- | lib/ansible/module_utils/network/skydive/api.py | 366 |
1 files changed, 0 insertions, 366 deletions
diff --git a/lib/ansible/module_utils/network/skydive/api.py b/lib/ansible/module_utils/network/skydive/api.py deleted file mode 100644 index 951ec9498e..0000000000 --- a/lib/ansible/module_utils/network/skydive/api.py +++ /dev/null @@ -1,366 +0,0 @@ -# This code is part of Ansible, but is an independent component. -# This particular file snippet, and this file snippet only, is BSD licensed. -# Modules you write using this snippet, which is embedded dynamically by Ansible -# still belong to the author of the module, and may assign their own license -# to the complete work. -# -# (c) 2019 Red Hat Inc. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -import os -import uuid - -from ansible.module_utils.six import iteritems -from ansible.module_utils.six import iterkeys -from ansible.module_utils._text import to_text -from ansible.module_utils.basic import env_fallback - -try: - from skydive.graph import Node, Edge - from skydive.rest.client import RESTClient - from skydive.websocket.client import NodeAddedMsgType, NodeUpdatedMsgType, NodeDeletedMsgType - from skydive.websocket.client import EdgeAddedMsgType, EdgeUpdatedMsgType, EdgeDeletedMsgType - from skydive.websocket.client import WSClient, WSClientDefaultProtocol, WSMessage - HAS_SKYDIVE_CLIENT = True -except ImportError: - HAS_SKYDIVE_CLIENT = False - -# defining skydive constants -SKYDIVE_GREMLIN_QUERY = 'G.V().Has' -SKYDIVE_GREMLIN_EDGE_QUERY = 'G.E().Has' - -SKYDIVE_PROVIDER_SPEC = { - 'endpoint': dict(fallback=(env_fallback, ['SKYDIVE_ENDPOINT'])), - 'username': dict(fallback=(env_fallback, ['SKYDIVE_USERNAME'])), - 'password': dict(fallback=(env_fallback, ['SKYDIVE_PASSWORD']), no_log=True), - 'insecure': dict(type='bool', default=False, fallback=(env_fallback, ['SKYDIVE_INSECURE'])), - 'ssl': dict(type='bool', default=False, fallback=(env_fallback, ['SKYDIVE_SSL'])) -} - - -class skydive_client_check(object): - """ Base class for implementing Skydive Rest API """ - - provider_spec = {'provider': dict(type='dict', options=SKYDIVE_PROVIDER_SPEC)} - - def __init__(self, **kwargs): - ''' Base class for implementing Skydive Rest API ''' - if not HAS_SKYDIVE_CLIENT: - raise Exception('skydive-client is required but does not appear ' - 'to be installed. It can be installed using the ' - 'command `pip install skydive-client`') - - if not set(kwargs.keys()).issubset(SKYDIVE_PROVIDER_SPEC.keys()): - raise Exception('invalid or unsupported keyword argument for skydive_restclient connection.') - for key, value in iteritems(SKYDIVE_PROVIDER_SPEC): - if key not in kwargs: - # apply default values from SKYDIVE_PROVIDER_SPEC since we cannot just - # assume the provider values are coming from AnsibleModule - if 'default' in value: - kwargs[key] = value['default'] - # override any values with env variables unless they were - # explicitly set - env = ('SKYDIVE_%s' % key).upper() - if env in os.environ: - kwargs[key] = os.environ.get(env) - - -class skydive_inject_protocol(object): - """ Implements inject protocol for node and edge modules """ - - def onOpen(self): - module = self.factory.kwargs["module"] - params = self.factory.kwargs["params"] - result = self.factory.kwargs["result"] - if "node1" and "node2" in self.factory.kwargs: - node1 = self.factory.kwargs["node1"] - node2 = self.factory.kwargs["node2"] - - if module.check_mode: - self.stop() - return - try: - host = params["host"] - if params["metadata"]: - metadata = module._check_type_dict(params["metadata"]) - else: - metadata = {} - if "node_type" in params: - metadata["Name"] = params["name"] - metadata["Type"] = params["node_type"] - seed = params["seed"] - if not seed: - seed = "%s:%s" % (params["name"], params["node_type"]) - if module.params['state'] == 'present' or module.params['state'] == 'update': - uid = str(uuid.uuid5(uuid.NAMESPACE_OID, seed)) - node = Node(uid, host, metadata=metadata) - if module.params['state'] == 'present': - msg = WSMessage("Graph", NodeAddedMsgType, node) - else: - msg = WSMessage("Graph", NodeUpdatedMsgType, node) - else: - uid = params['id'] - node = Node(uid, host, metadata=metadata) - msg = WSMessage("Graph", NodeDeletedMsgType, node) - elif "relation_type" in params: - metadata["RelationType"] = params["relation_type"] - if module.params['state'] == 'present' or module.params['state'] == 'update': - uid = str(uuid.uuid5(uuid.NAMESPACE_OID, "%s:%s:%s" % - (node1, node2, params["relation_type"]))) - edge = Edge(uid, host, node1, node2, metadata=metadata) - if module.params['state'] == 'present': - msg = WSMessage("Graph", EdgeAddedMsgType, edge) - else: - msg = WSMessage("Graph", EdgeUpdatedMsgType, edge) - else: - uid = module.params['id'] - edge = Edge(uid, host, node1, node2, metadata=metadata) - msg = WSMessage("Graph", EdgeDeletedMsgType, edge) - - self.sendWSMessage(msg) - if uid: - result["UUID"] = uid - result["changed"] = True - except Exception as e: - module.fail_json( - msg='Error during topology update %s' % e, **result) - finally: - self.stop() - - -class skydive_wsclient(skydive_client_check): - """ Base class for implementing Skydive Websocket API """ - - def __init__(self, module, **kwargs): - super(skydive_wsclient, self).__init__(**kwargs) - - class skydive_full_inject_protocol(skydive_inject_protocol, WSClientDefaultProtocol): - pass - kwargs['scheme'] = "ws" - if 'ssl' in kwargs: - if kwargs['ssl']: - kwargs['scheme'] = "wss" - if 'insecure' not in kwargs: - kwargs['insecure'] = False - scheme = kwargs['scheme'] - self.result = dict(changed=False) - if "node_type" in module.params: - self.wsclient_object = WSClient("ansible-" + str(os.getpid()) + "-" + module.params['host'], - "%s://%s/ws/publisher" % (scheme, kwargs["endpoint"]), - protocol=type('skydive_full_inject_protocol', (skydive_inject_protocol, - WSClientDefaultProtocol), dict()), - persistent=True, - insecure=kwargs["insecure"], - username=kwargs["username"], - password=kwargs["password"], - module=module, - params=module.params, - result=self.result) - elif "relation_type" in module.params: - self.parent_node = self.get_node_id(module.params['parent_node']) - self.child_node = self.get_node_id(module.params['child_node']) - - self.wsclient_object = WSClient("ansible-" + str(os.getpid()) + "-" + module.params['host'], - "%s://%s/ws/publisher" % (scheme, kwargs["endpoint"]), - protocol=type('skydive_full_inject_protocol', (skydive_inject_protocol, - WSClientDefaultProtocol), dict()), - persistent=True, - insecure=kwargs["insecure"], - username=kwargs["username"], - password=kwargs["password"], - module=module, - params=module.params, - node1=self.parent_node, - node2=self.child_node, - result=self.result) - - def get_node_id(self, node_selector): - """ Checks if Gremlin expresssion is passed as input to get the nodes UUID """ - if node_selector.startswith("G.") or node_selector.startswith("g."): - nodes = self.restclient_object.lookup_nodes(node_selector) - if len(nodes) == 0: - raise self.module.fail_json(msg=to_text("Node not found: {0}".format(node_selector))) - elif len(nodes) > 1: - raise self.module.fail_json( - msg=to_text("Node selection should return only one node: {0}".format(node_selector))) - return str(nodes[0].id) - return node_selector - - -class skydive_restclient(skydive_client_check): - """ Base class for implementing Skydive Rest API """ - - def __init__(self, **kwargs): - super(skydive_restclient, self).__init__(**kwargs) - kwargs['scheme'] = "http" - if 'ssl' in kwargs: - if kwargs['ssl']: - kwargs['scheme'] = "https" - if 'insecure' not in kwargs: - kwargs['insecure'] = False - self.restclient_object = RESTClient(kwargs['endpoint'], - scheme=kwargs['scheme'], - insecure=kwargs['insecure'], - username=kwargs['username'], - password=kwargs['password']) - - -class skydive_lookup(skydive_restclient): - """ Implements Skydive Lookup queries """ - - provider_spec = {'provider': dict(type='dict', options=SKYDIVE_PROVIDER_SPEC)} - - def __init__(self, provider): - super(skydive_lookup, self).__init__(**provider) - self.query_str = "" - - def lookup_query(self, filter_data): - query_key = filter_data.keys()[0] - self.query_str = filter_data[query_key] - nodes = self.restclient_object.lookup_nodes(self.query_str) - result = [] - for each in nodes: - result.append(each.__dict__) - if len(result) == 0: - raise Exception("Cannot find any entry for the input Gremlin query!") - return result - - -class skydive_flow_capture(skydive_restclient): - """ Implements Skydive Flow capture modules """ - - def __init__(self, module): - self.module = module - provider = module.params['provider'] - - super(skydive_flow_capture, self).__init__(**provider) - - def run(self, ib_spec): - state = self.module.params['state'] - if state not in ('present', 'absent'): - self.module.fail_json(msg='state must be one of `present`, `absent`, got `%s`' % state) - - result = {'changed': False} - obj_filter = dict([(k, self.module.params[k]) for k, v in iteritems(ib_spec) if v.get('ib_req')]) - - proposed_object = {} - for key in iterkeys(ib_spec): - if self.module.params[key] is not None: - proposed_object[key] = self.module.params[key] - - if obj_filter['query']: - cature_query = obj_filter['query'] - elif obj_filter['interface_name'] and obj_filter['type']: - cature_query = SKYDIVE_GREMLIN_QUERY + "('Name', '{0}', 'Type', '{1}')".format(obj_filter['interface_name'], - obj_filter['type']) - else: - raise self.module.fail_json(msg="Interface name and Type is required if gremlin query is not defined!") - - # to check current object ref for idempotency - captured_list_objs = self.restclient_object.capture_list() - current_ref_uuid = None - for each_capture in captured_list_objs: - if cature_query == each_capture.__dict__['query']: - current_ref_uuid = each_capture.__dict__['uuid'] - break - if state == 'present': - if not current_ref_uuid: - try: - self.restclient_object.capture_create(cature_query, obj_filter['capture_name'], - obj_filter['description'], obj_filter['extra_tcp_metric'], - obj_filter['ip_defrag'], obj_filter['reassemble_tcp'], - obj_filter['layer_key_mode']) - except Exception as e: - self.module.fail_json(msg=to_text(e)) - result['changed'] = True - if state == 'absent': - if current_ref_uuid: - try: - self.restclient_object.capture_delete(current_ref_uuid) - except Exception as e: - self.module.fail_json(msg=to_text(e)) - result['changed'] = True - - return result - - -class skydive_node(skydive_wsclient, skydive_restclient): - """ Implements Skydive Node modules """ - - def __init__(self, module): - self.module = module - provider = module.params['provider'] - super(skydive_node, self).__init__(self.module, **provider) - - def run(self): - try: - lookup_query = SKYDIVE_GREMLIN_QUERY + "('Name', '{0}', 'Type', '{1}')".format(self.module.params['name'], - self.module.params['node_type']) - node_exists = self.restclient_object.lookup_nodes(lookup_query) - - if not node_exists and self.module.params['state'] == 'present': - self.wsclient_object.connect() - self.wsclient_object.start() - elif len(node_exists) > 0 and self.module.params['state'] == 'update': - self.wsclient_object.connect() - self.wsclient_object.start() - elif len(node_exists) > 0 and self.module.params['state'] == 'absent': - self.module.params['id'] = node_exists[0].__dict__['id'] - self.wsclient_object.connect() - self.wsclient_object.start() - except Exception as e: - self.module.fail_json(msg=to_text(e)) - return self.result - - -class skydive_edge(skydive_wsclient, skydive_restclient): - """ Implements Skydive Edge modules """ - - def __init__(self, module): - self.module = module - provider = module.params['provider'] - - super(skydive_edge, self).__init__(self.module, **provider) - - def run(self): - try: - edge_exists = False - edge_query = SKYDIVE_GREMLIN_EDGE_QUERY + "('Parent', '{0}', 'Child', '{1}')".format(self.parent_node, - self.child_node) - query_result = self.restclient_object.lookup_edges(edge_query) - if query_result: - query_result = query_result[0].__dict__ - edge_exists = True - - if not edge_exists and self.module.params['state'] == 'present': - self.wsclient_object.connect() - self.wsclient_object.start() - elif edge_exists and self.module.params['state'] == 'update': - self.wsclient_object.connect() - self.wsclient_object.start() - elif edge_exists and self.module.params['state'] == 'absent': - self.module.params['id'] = query_result['id'] - self.wsclient_object.connect() - self.wsclient_object.start() - except Exception as e: - self.module.fail_json(msg=to_text(e)) - return self.result |