satori/satori/discovery.py

108 lines
3.5 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Discovery Module.
TODO(zns): testing, refactoring, etc... just using this to demonstrate
functionality
Example usage:
from satori import discovery
discovery.run(address="foo.com")
"""
from __future__ import print_function
import socket
from novaclient.v1_1 import client
import six
from satori import dns
from satori import utils
def is_valid_ipv4_address(address):
"""Check if the address supplied is a valid IPv4 address."""
try:
socket.inet_pton(socket.AF_INET, address)
except AttributeError: # no inet_pton here, sorry
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count('.') == 3
except socket.error: # not a valid address
return False
return True
def is_valid_ipv6_address(address):
"""Check if the address supplied is a valid IPv6 address."""
try:
socket.inet_pton(socket.AF_INET6, address)
except socket.error: # not a valid address
return False
return True
def is_valid_ip_address(address):
"""Check if the address supplied is a valid IP address."""
return is_valid_ipv4_address(address) or is_valid_ipv6_address(address)
def run(address, config, interactive=False):
"""Run discovery and return results."""
results = {}
if is_valid_ip_address(address):
ipaddress = address
else:
ipaddress = dns.resolve_hostname(address)
results['domain'] = dns.domain_info(address)
results['address'] = ipaddress
results['host'] = host = {'type': 'Undetermined'}
if config.username is not None:
server = find_nova_host(ipaddress, config)
if server:
host['type'] = 'Nova instance'
host['uri'] = [l['href'] for l in server.links
if l['rel'] == 'self'][0]
host['name'] = server.name
host['id'] = server.id
host['addresses'] = server.addresses
if config.system_info:
module_name = config.system_info.replace("-", "_")
if '.' not in module_name:
module_name = 'satori.sysinfo.%s' % module_name
system_info_module = utils.import_object(module_name)
result = system_info_module.get_systeminfo(ipaddress, config,
interactive=interactive)
host['system_info'] = result
return results
def find_nova_host(address, config):
"""See if a nova instance has the supplied address."""
nova = client.Client(config.username,
config.password,
config.tenant_id,
config.authurl,
region_name=config.region,
service_type="compute")
for server in nova.servers.list():
for network_addresses in six.itervalues(server.addresses):
for ipaddress in network_addresses:
if ipaddress['addr'] == address:
return server