diff --git a/README b/README index 07a82d7..66eb157 100644 --- a/README +++ b/README @@ -1,8 +1,145 @@ # ifxlookup ### A python command-line lookup client for infrastructure equipment. +## Usage + +``` +usage: ifxlookup [-h] [-c CONFIG] [-j] [-l] [-w] [-n] [-d] [-cg] [-r] [-fw] + [-a] [-v] + subjects [subjects ...] + +positional arguments: + subjects IPs or hostnames to look up. + +optional arguments: + -h, --help show this help message and exit + -c CONFIG, --config CONFIG + Specify a config file (~/.config/ifxlookup.yml by + default) + -j, --json Return results as a json object + -l, --link Return physical link information about the subject + -w, --wifi Return wireless connection information about the + subject + -n, --net Return network information about the subject + -d, --dns Return DNS resolution about the subject + -cg, --vip Return VIP information about the subject + -r, --vpn Return VPN information about the subject + -fw, --rules Return Firewall rules relating to the subject + -a, --all Return all searchable information about the subject + -v, --debug Include debug information in the output. Add 'v's for + more output. +``` + +IFXTool takes subjects in the form of IP addresses, hostnames, mac addresses, and other identifiers and performs +queries against various infrastruvture equipment to return datasets for those subjects. Information on some +subjects may be found across multiple services. For example, and IP address can have information in BlueCat and +information in the Aruba controller. Including -n and -w will retrieve information on the IP addres from both +services. + +IFXTool is extensible, so that anyone can write plugins for their specific service to be included in the lookup. +By default, five plugins are included. + ## Installation * Clone the repository * `pip install -r requirements.txt` +## Plugins + +IFXLookup works by loading plugins in the form of ServiceDelegate objects. Plugins are executed in alphabetical +order. ServiceDelegate objects are subclasses of the ServiceBase class, which includes the basic framework +for loading your plugin into IFXLookup. The ServiceDelegate subclass is concise enough to make writing simple +plugins straightforward and open enough to allow for complex implementations, such as multiprocessing. + +## Writing a Plugin + +### Template + +To write a new plugin, create a python file with the name of your plugin in the 'plugins' directory. The name of +the plugin will be the name that appears in teh plugin's report to the user. You can populate the file with the +following template: + +``` +from servicebase import ServiceBase + +class ServiceDelegate(ServiceBase) : + def get_arguments(cls) : + """Returns an array of information used to construct an argumentparser argument.""" + # [ ,,, ] + # Example return: [ '-nm', '--name', 'store_true', "Return the name of the subject" ] + pass + + def perform_lookup(self,host_tuple) : + """Given a host_tuple, return a dictionary or array of information about the subject.""" + # Example return: {'name' : host_tuple[0] ] + pass + +``` + +The function `get_arguments` is called when your plugin is loaded to verify that the plugin should be run, +based on the arguments the user supplied. Plugins are loaded whenever the script is run. + +The function `perform_lookup` is called for every subject the user submits. DNS resolution is attempted +by IFXLookup automatically for convenience, and the resulting socket triple `host_tuple` is provided. +host_tuple is a triple (hostname, aliaslist, ipaddrlist) where hostname is the subject name or primary host +name responding to the given ip_address, aliaslist is a (possibly empty) list of alternative host names for +the same address, and ipaddrlist is a list of IPv4 addresses for the same interface on the same host (usually +but not always a single address) + +Within the `perform_lookup` function, you should perform any lookups on the host and return a dictionary or +array of information about the subject. To make sure that the results are serializable, be sure that +dictionaries and arrays are the only data structures in your results. + +### Loading Configuration + +The config file for IFXLookup is loaded and parsed for all plugins. The config file is a yaml file that is +parsed into a python dictionary and available to your plugin as `self.confg`. You can specify whatever +configuration options you desire under your plugin's name in the config file, but it is up to your plugin +to check for mandatory or missing configuration options. See some of the default plugins for examples. + +### Convenience Functions + +Your plugin may need to do some setup before executing lookups, such as logging into an API service or +caching a dataset for use in lookups. The convenience functions `startup()` and `shutdown()` are called +on your plugin before and after lookups are called on your plugin. This allows you to do any setup your +plugin needs without overriding `__init__()`. It also allows you to perform any cleanup your plugin may +need, such as logging out any outstanding sessions. + +The `self.debug()` allows your plugin to print verbose output to the console if requested by the user. +This output is printed to `stderr` and not added to your plugin's report. + +Example: + +`self.debug("This message will be printed to the console when the user passes a -vv argument",2)` + +Your plugin can report errors and warnings by appending them to the list `self.error` and `self.warn`, +respectively. They will be appended to the report for your plugin (or removed from the report if the +user specifies). + +### Advanced Plugins + +Other functions and attributes are available to be used in your plugin if you require them. + +All arguments the user submitted to IFXLookup are available in the `self.namespace` object. If you need +to see which arguments were submitted (besides the argument that your plugin provides in `get_argument()`, +you may consult `self.namespace`. + +The method `__lookup_subjects()` dispatches the lookups for the hosts that are given to your plugin. If you +want to introduce a custom dispatching method, such as using a new thread for each lookup, you can override +this method. + +If you just want to access the array of hosts that the user submitted, you can get it by getting +`self.namespace.subjects`. For the list of `host_tuples`, `self._subjects` is available. + +## Contributing + +If you have a plugin for a piece of equipment that could be useful to others on the team, I'd love to add it +to the project. Submit a pull request and let's get it added! + +## Justification + +While reviewing reports from various network services I'd often find myself cross-referencing several sites to +get the information I was lookup for on a particular IP, mac address or host. What's more, the information I +gathered from each site had to be formatted by hand if I wanted to build a report of a particular host at a +particular time. I wrote this tool to keep from opening a bunch of tabs and copy-pasting information from +each into a text file for storage.