def whois_async(query, fields=None): """ Perform whois request :param query: :param fields: :return: """ logger.debug("whois %s", query) # Get appropriate whois server if is_fqdn(query): # Use TLD.whois-servers.net for domain lookup tld = query.split(".")[-1] server = "%s.whois-servers.net" % tld else: server = DEFAULT_WHOIS_SERVER # Perform query try: client = TCPClient() stream = yield client.connect(server, DEFAULT_WHOIS_PORT) except IOError as e: logger.error("Cannot resolve host '%s': %s", server, e) raise tornado.gen.Return() try: yield stream.write(str(query) + "\r\n") data = yield stream.read_until_close() finally: yield stream.close() data = parse_response(data) if fields: data = [(k, v) for k, v in data if k in fields] raise tornado.gen.Return(data)
def get_fqdn(self, object): if self.fqdn_template: # Render template ctx = Context({"object": object}) f = Template(self.fqdn_template).render(ctx) # Remove spaces f = "".join(f.split()) else: f = object.name # Check resulting fqdn if not is_fqdn(f): raise ValueError("Invalid FQDN: %s" % f) return f
def clean(self, data): data = super(AddressRangeApplication, self).clean(data) afi = data["afi"] from_address = data["from_address"] to_address = data["to_address"] # Check AFI address_validator = is_ipv4 if afi == "4" else is_ipv6 if not address_validator(from_address): raise ValueError("Invalid IPv%(afi)s 'From Address'" % {"afi": afi}) if not address_validator(to_address): raise ValueError("Invalid IPv%(afi)s 'To Address'" % {"afi": afi}) # Check from address not greater than to address if IP.prefix(from_address) > IP.prefix(to_address): raise ValueError( "'To Address' must be greater or equal than 'From Address'") # Check for valid "action" combination if "fqdn_template" in data and data[ "fqdn_template"] and data["action"] != "G": raise ValueError( "'FQDN Template' must be clean for selected 'Action'") if "reverse_nses" in data and data[ "reverse_nses"] and data["action"] != "D": raise ValueError( "'Reverse NSes' must be clean for selected 'Action'") # Set range as locked for "G" and "D" actions if data["action"] != "N": data["is_locked"] = True # @todo: check FQDN template # Check reverse_nses is a list of FQDNs or IPs if "reverse_nses" in data and data["reverse_nses"]: reverse_nses = data["reverse_nses"] for ns in reverse_nses.split(","): ns = ns.strip() if not is_ipv4(ns) and not is_ipv6(ns) and not is_fqdn(ns): raise ValueError("%s is invalid nameserver" % ns) # Check no locked range overlaps another locked range if data["is_locked"]: r = [ r for r in AddressRange.get_overlapping_ranges( data["vrf"], data["afi"], data["from_address"], data["to_address"]) if r.is_locked is True and r.name != data["name"] ] if r: raise ValueError( "Locked range overlaps with ahother locked range: %s" % unicode(r[0])) return data
def get_address_fqdn(self, address): """ Render address name :param address: DiscoveredAddress instance :return: Rendered name or None """ if address.profile.fqdn_template: fqdn = address.profile.fqdn_template.render_subject( **self.get_template_context(address)) fqdn = self.strip(fqdn) if is_fqdn(fqdn): return fqdn self.logger.error( "Address %s renders to invalid FQDN '%s'. " "Ignoring FQDN", address.address, fqdn) return None
def __init__(self, factory, query, callback=None, fields=None): # Find suitable whois server if is_fqdn(query): # Use TLD.whois-servers.net for domain lookup tld = query.split(".")[-1] server = "%s.whois-servers.net" % tld else: server = WHOIS_SERVER # Try to resolve server try: server = socket.gethostbyname(server) except: logging.error("Cannot resolve host %s" % server) return ConnectedTCPSocket.__init__(self, factory, server, WHOIS_PORT) self.query = query.strip() self.output = [] self.callback = callback self.fields = set(fields) if fields else None logging.debug("whois(%s)" % self.query)
def test_is_fqdn(): assert is_fqdn("test.example.com") is True assert is_fqdn("test") is False
def test_is_fqdn(raw, expected): assert is_fqdn(raw) is expected