Get details for specified IP address as a Details object.
777517
def getDetails(self, ip_address=None):
        """"""
        raw_details = self._requestDetails(ip_address)
        raw_details['country_name'] = self.countries.get(raw_details.get('country'))
        raw_details['ip_address'] = ipaddress.ip_address(raw_details.get('ip'))
        raw_details['latitude'], raw_details['longitude'] = self._read_coords(raw_details.get('loc'))
        return Details(raw_details)
269578
def get_or_create_from_ip(ip):
        
        data = ip_api_handler.get(ip)
        if data and any(v for v in data.values()):
            if data.get('ip_address', None) is None or not data['ip_address']:
                data['ip_address'] = ip
            return IPInfo.objects.get_or_create(**data)
        return None, False
903338
def get_ip(request):
    
    if config.BEHIND_REVERSE_PROXY:
        ip_address = request.META.get(config.REVERSE_PROXY_HEADER, '')
        ip_address = ip_address.split(",", 1)[0].strip()
        if ip_address == '':
            ip_address = get_ip_address_from_request(request)
    else:
        ip_address = get_ip_address_from_request(request)
    return ip_address
668894
def ip_lookup(self, ip_address):
        
        obj = self.client['Network_Subnet_IpAddress']
        return obj.getByIpAddress(ip_address, mask='hardware, virtualGuest')
908692
def _get_ids_from_ip(self, ip_address):  # pylint: disable=inconsistent-return-statements
        """"""
        try:
            # Does it look like an ip address?
            socket.inet_aton(ip_address)
        except socket.error:
            return []

        # Find the VS via ip address. First try public ip, then private
        results = self.list_instances(public_ip=ip_address, mask="id")
        if results:
            return [result['id'] for result in results]

        results = self.list_instances(private_ip=ip_address, mask="id")
        if results:
            return [result['id'] for result in results]
617686
def get_details(exc):
    """"""
    detail = None
    fields = collections.OrderedDict()

    if exc.detail:
        detail = exc.detail

    if exc.fields:
        for k, v in six.iteritems(exc.fields):
            try:
                field_detail = v["detail"]
            except (TypeError, KeyError):
                field_detail = v

            if isinstance(field_detail, (list, tuple)):
                field_detail = " ".join(field_detail)

            if k == "non_field_errors":
                if detail:
                    detail += " " + field_detail
                else:
                    detail = field_detail
                continue

            fields[k] = field_detail

    return detail, fields
65883
def network_details():
        
        # Get IPv4 details
        ipv4_addresses = [
            info[4][0]
            for info in socket.getaddrinfo(
                socket.gethostname(), None, socket.AF_INET
            )
        ]

        # Add localhost
        ipv4_addresses.extend(
            info[4][0]
            for info in socket.getaddrinfo("localhost", None, socket.AF_INET)
        )

        # Filter addresses
        ipv4_addresses = sorted(set(ipv4_addresses))

        try:
            # Get IPv6 details
            ipv6_addresses = [
                info[4][0]
                for info in socket.getaddrinfo(
                    socket.gethostname(), None, socket.AF_INET6
                )
            ]

            # Add localhost
            ipv6_addresses.extend(
                info[4][0]
                for info in socket.getaddrinfo(
                    "localhost", None, socket.AF_INET6
                )
            )

            # Filter addresses
            ipv6_addresses = sorted(set(ipv6_addresses))
        except (socket.gaierror, AttributeError):
            # AttributeError: AF_INET6 is missing in some versions of Python
            ipv6_addresses = None

        return {
            "IPv4": ipv4_addresses,
            "IPv6": ipv6_addresses,
            "host.name": socket.gethostname(),
            "host.fqdn": socket.getfqdn(),
        }
463940
def getIPaddresses(self):
        """"""
        if not self.ipAddress:
            self.ipAddress = ipAddresses.getAll() # update with IP address
        return self.ipAddress
940452
def _get_tcpip_interface_info(interface):
    '''
    
    '''
    base_information = _get_base_interface_info(interface)
    if base_information['ipv4']['requestmode'] == 'static':
        settings = _load_config(interface.name, ['IP_Address', 'Subnet_Mask', 'Gateway', 'DNS_Address'])
        base_information['ipv4']['address'] = settings['IP_Address']
        base_information['ipv4']['netmask'] = settings['Subnet_Mask']
        base_information['ipv4']['gateway'] = settings['Gateway']
        base_information['ipv4']['dns'] = [settings['DNS_Address']]
    elif base_information['up']:
        base_information['ipv4']['address'] = interface.sockaddrToStr(interface.addr)
        base_information['ipv4']['netmask'] = interface.sockaddrToStr(interface.netmask)
        base_information['ipv4']['gateway'] = '0.0.0.0'
        base_information['ipv4']['dns'] = _get_dns_info()
        with salt.utils.files.fopen('/proc/net/route', 'r') as route_file:
            pattern = re.compile(r'^{interface}\t[0]{{8}}\t([0-9A-Z]{{8}})'.format(interface=interface.name),
                                 re.MULTILINE)
            match = pattern.search(route_file.read())
            iface_gateway_hex = None if not match else match.group(1)
        if iface_gateway_hex is not None and len(iface_gateway_hex) == 8:
            base_information['ipv4']['gateway'] = '.'.join([str(int(iface_gateway_hex[i:i + 2], 16))
                                                            for i in range(6, -1, -2)])
    return base_information
993589
def cli(env, ip_address):
    """"""

    mgr = SoftLayer.NetworkManager(env.client)

    addr_info = mgr.ip_lookup(ip_address)

    if not addr_info:
        raise exceptions.CLIAbort('Not found')

    table = formatting.KeyValueTable(['name', 'value'])
    table.align['name'] = 'r'
    table.align['value'] = 'l'

    table.add_row(['id', addr_info['id']])
    table.add_row(['ip', addr_info['ipAddress']])

    subnet_table = formatting.KeyValueTable(['name', 'value'])
    subnet_table.align['name'] = 'r'
    subnet_table.align['value'] = 'l'
    subnet_table.add_row(['id', addr_info['subnet']['id']])
    subnet_table.add_row(['identifier',
                          '%s/%s' % (addr_info['subnet']['networkIdentifier'],
                                     str(addr_info['subnet']['cidr']))])
    subnet_table.add_row(['netmask', addr_info['subnet']['netmask']])
    if addr_info['subnet'].get('gateway'):
        subnet_table.add_row(['gateway', addr_info['subnet']['gateway']])
    subnet_table.add_row(['type', addr_info['subnet'].get('subnetType')])

    table.add_row(['subnet', subnet_table])

    if addr_info.get('virtualGuest') or addr_info.get('hardware'):
        device_table = formatting.KeyValueTable(['name', 'value'])
        device_table.align['name'] = 'r'
        device_table.align['value'] = 'l'
        if addr_info.get('virtualGuest'):
            device = addr_info['virtualGuest']
            device_type = 'vs'
        else:
            device = addr_info['hardware']
            device_type = 'server'
        device_table.add_row(['id', device['id']])
        device_table.add_row(['name', device['fullyQualifiedDomainName']])
        device_table.add_row(['type', device_type])
        table.add_row(['device', device_table])
    env.fout(table)
653707
def _get_esxi_proxy_details():
    '''
    
    '''
    det = __proxy__['esxi.get_details']()
    host = det.get('host')
    if det.get('vcenter'):
        host = det['vcenter']
    esxi_hosts = None
    if det.get('esxi_host'):
        esxi_hosts = [det['esxi_host']]
    return host, det.get('username'), det.get('password'), \
            det.get('protocol'), det.get('port'), det.get('mechanism'), \
            det.get('principal'), det.get('domain'), esxi_hosts
161154
def get_by_ip(cls, ip):
        ''
        ret = cls.hosts_by_ip.get(ip)
        if ret is None:
            ret = cls.hosts_by_ip[ip] = [Host(ip)]
        return ret
673962
def find_active_ip_address():
        """"""
        import netifaces
        # Interface of the default gateway
        gateway_itf = netifaces.gateways()['default'][netifaces.AF_INET][1]
        # IP address for the interface
        return netifaces.ifaddresses(gateway_itf)[netifaces.AF_INET][0]['addr']
237608
def whois(ip_address):
    """"""
    whois_ip = str(ip_address)
    try:
        query = socket.gethostbyname(whois_ip)
    except Exception:
        query = whois_ip
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("whois.ripe.net", 43))
    s.send(query.encode("utf8") + b"\r\n")
    answer = b""
    while True:
        d = s.recv(4096)
        answer += d
        if not d:
            break
    s.close()
    ignore_tag = b"remarks:"
    # ignore all lines starting with the ignore_tag
    lines = [line for line in answer.split(b"\n") if not line or (line and not line.startswith(ignore_tag))]  # noqa: E501
    # remove empty lines at the bottom
    for i in range(1, len(lines)):
        if not lines[-i].strip():
            del lines[-i]
        else:
            break
    return b"\n".join(lines[3:])
448959
def interfaces_info():
    
    def replace(value):
        if value == netifaces.AF_LINK:
            return 'link'
        if value == netifaces.AF_INET:
            return 'ipv4'
        if value == netifaces.AF_INET6:
            return 'ipv6'
        return value

    results = {}
    for iface in netifaces.interfaces():
        addrs = netifaces.ifaddresses(iface)
        results[iface] = {replace(k): v for k, v in addrs.items()}

    return results
190709
function Node(details) {

		// If we got a string
		if(is.string(details)) {
			details = {"__type__": details};
		}

		// If the details are not an Object
		if(!is.object(details)) {
			throw 'details must be an Object';
		}

		// If the type is not found
		if(!('__type__' in details)) {
			throw 'missing "__type__" in details';
		}

		// If the type is not valid
		if(_validNode.indexOf(details['__type__']) == -1) {
			throw 'invalid "__type__" in details';
		}

		// Store the type and remove it from the details
		this._type	= details['__type__'];
		delete details['__type__'];

		// Init the value types
		this._regex = null;
		this._options = null;
		this._minimum = null;
		this._maximum = null;

		/**
		 * Compare IPs
		 *
		 * Compares two IPs and returns a status based on which is greater
		 * If first is less than second: -1
		 * If first is equal to second: 0
		 * If first is greater than second: 1
		 *
		 * @name compareIPs
		 * @access private
		 * @param String first			A string representing an IP address
		 * @param String second			A string representing an IP address
		 * @return int					-1, 0, 1
		 */
		var compareIPs = function compareIPs(first, second) {

			// If the two IPs are the same, return 0
			if(first == second) {
				return 0;
			}

			// Create lists from the split of each IP, store them as ints
			var aFirst = first.split('.');
			for(var i in aFirst) { aFirst[i] = parseInt(aFirst[i]); }
			var aSecond = second.split('.');
			for(var i in aSecond) { aSecond[i] = parseInt(aSecond[i]); }

			// Go through each part from left to right until we find the
			// 	difference
			for(var i = 0; i < 4; ++i) {

				// If the part of x is greater than the part of y
				if(aFirst[i] > aSecond[i]) {
					return 1;
				}

				// Else if the part of x is less than the part of y
				else if(aFirst[i] < aSecond[i]) {
					return -1;
				}
			}
		}

		/**
		 * Clean
		 *
		 * Cleans and returns the new value
		 *
		 * @name clean
		 * @access protected
		 * @param mixed value			The value to validate
		 * @return mixed
		 */
		this.clean = function clean(value) {

			// If the value is null and it's optional, return as is
			if(value == null && this._optional) {
				return null;
			}

			// If it's an ANY, there is no reasonable expectation that we know
			//	what the value should be, so we return it as is
			if(this._type == 'any') {
				//pass
			}

			// Else if it's a basic string type
			else if(['base64', 'ip', 'string', 'uuid'].indexOf(this._type) != -1) {

				// And not already a string
				if(!is.string(value)) {
					value = String(value);
				}
			}

			// Else if it's a BOOL just check if the value flags as positive
			else if(this._type == 'bool') {

				// If it's specifically a string, it needs to match a specific
				//	pattern to be true
				if(is.string(value)) {
					value = (['true', 'True', 'TRUE', 't', 'T', 'yes', 'Yes', 'YES', 'y', 'Y', 'x', '1'].indexOf(value) == -1) ? false : true;
				}
				else {
					value = value ? true : false;
				}
			}

			// Else if it's a date type
			else if(this._type == 'date') {

				// If it's a JavaScript type, convert it to a string
				if(value instanceof Date) {
					value = DateToStr(value);
				}

				// Else if it's already a string
				else if(is.string(value)) {
					//pass
				}

				// Else convert it to a string
				else {
					value = String(value);
				}
			}

			// Else if it's a datetime type
			else if(this._type == 'datetime') {

				// If it's a JavaScript type, convert it to a string
				if(value instanceof Date) {
					value = DateTimeToStr(value);
				}

				// Else if it's already a string
				else if(is.string(value)) {
					//pass
				}

				// Else convert it to a string
				else {
					value = String(value);
				}
			}

			// Else if it's a decimal
			else if(this._type == 'decimal') {

				// And not already a string
				if(!is.string(value)) {
					value = String(value);
				}
			}

			// Else if it's a float
			else if(this._type == 'float') {
				value = parseFloat(value);
			}

			// Else if it's an int type
			else if(['int', 'timestamp', 'uint'].indexOf(this._type) != -1) {

				// If it's a string
				if(is.string(value)) {

					// If it starts with 0
					if(value.charAt(0) == '0' && value.length > 1) {

						// If it's followed by X or x, it's hex
						if(['x', 'X'].indexOf(value.charAt(1)) != -1 && value.length > 2) {
							value = parseInt(value, 16)
						}

						// Else it's octal
						else {
							value = parseInt(value, 8)
						}
					}

					// Else it's base 10
					else {
						value = parseInt(value, 10);
					}
				}

				// Else if it's not an int already
				else if(!is.integer(value)) {
					value = parseInt(value);
				}
			}

			// Else if it's a JSON type
			else if(this._type == 'json') {

				// If it's already a string
				if(is.string(value)) {
					//pass
				}

				// Else, encode it
				else {
					value = JSON.stringify(value);
				}
			}

			// Else if it's an md5 type
			else if(this._type == 'md5') {

				// If it's a string
				if(is.string(value)) {
					//pass
				}

				// Else, try to convert it to a string
				else {
					value = String(value);
				}
			}

			// Else if it's a price type
			else if(this._type == 'price') {
				value = new Number(value).toFixed(2);
			}

			// Else if it's a time type
			else if(this._type == 'time') {

				// If it's a JavaScript type, get the time part
				if(value instanceof Date) {
					value = value.toTimeString().substr(0,8);
				}

				// Else if it's already a string
				else if(is.string(value)) {
					//pass
				}

				// Else convert it to a string
				else {
					value = String(value);
				}
			}

			// Else we probably forgot to add a new type
			else {
				throw '"' + this._type + '" has not been added to .clean()';
			}

			// Return the cleaned value
			return value;
		};

		/**
		 * Min/Max
		 *
		 * Sets or gets the minimum and/or maximum values for the Node. For
		 * getting, returns {"minimum":mixed,"maximum":mixed}
		 *
		 * @name minmax
		 * @access public
		 * @param mixed minimum			The minimum value
		 * @param mixed maximum			The maximum value
		 * @return void|Object
		 */
		this.minmax = function minmax(minimum, maximum) {

			// If neither min or max is set, this is a getter
			if(typeof minimum === 'undefined' && typeof maximum === 'undefined') {
				return {"minimum":this._minimum,"maximum":this._maximum};
			}

			// If the minimum is set
			if(minimum !== null) {

				// If the current type is a date, datetime, ip, or time
				if(['base64', 'date', 'datetime', 'ip', 'time'].indexOf(this._type) != -1) {

					// Make sure the value is valid for the type
					if(!is.string(minimum) || !_typeToRegex[this._type].test(minimum)) {
						throw '"__minimum__" is not valid for the current type: "' + this._type + '"';
					}
				}

				// Else if the type is an int (unsigned, timestamp), or a string
				//	in which the minimum/maximum are lengths
				else if(['int', 'string', 'timestamp', 'uint'].indexOf(this._type) != -1) {

					// If the value is not a valid int or long
					if(!is.integer(minimum)) {

						// If it's a valid representation of an integer
						if(is.string(minimum) && _typeToRegex['int'].test(minimum)) {

							// Convert it
							minimum = parseInt(minimum, 0);
						}

						// Else, raise an error
						else {
							throw '"__minimum__" must be an integer';
						}

						// If the type is meant to be unsigned
						if(['base64', 'string', 'timestamp', 'uint'].indexOf(this._type) != -1) {

							// And it's below zero
							if(minimum < 0) {
								throw '"__minimum__" must be an unsigned integer';
							}
						}
					}
				}

				// Else if the type is a decimal
				else if(this._type == 'decimal') {

					// If it's a not valid representation of a decimal
					if(!is.string(minimum) || !_typeToRegex['decimal'].test(minimum)) {

						// Throw an error
						throw '"__minimum__" not a valid decimal';
					}
				}

				// Else if the type is float
				else if(this._type == 'float') {

					// If it's not a float
					if(!is.float(minimum)) {

						// If we can't convert it to a float
						f	= parseFloat(minimum);
						if(isNaN(f)) {
							throw '"__minimum__" not a valid float';
						}

						// Store the parsed value
						minimum	= f;
					}
				}

				// Else if the type is price
				else if(this._type == 'price') {

					// If it's a not valid representation of a price
					if(!is.string(minimum) || !_typeToRegex['price'].test(minimum)) {

						// Throw an error
						throw '"__minimum__" not a valid price';
					}

				}

				// Else we can't have a minimum
				else {
					throw 'can not set __minimum__ for "' + this._type + '"';
				}

				// Store the minimum
				this._minimum = minimum;
			}

			// If the maximum is set
			if(maximum !== null) {

				// If the current type is a date, datetime, ip, or time
				if(['base64', 'date', 'datetime', 'ip', 'time'].indexOf(this._type) != -1) {

					// Make sure the value is valid for the type
					if(!is.string(maximum) || !_typeToRegex[this._type].test(maximum)) {
						throw '"__maximum__" is not valid for the current type: "' + this._type + '"';
					}
				}

				// Else if the type is an int (unsigned, timestamp), or a string
				//	in which the minimum/maximum are lengths
				else if(['int', 'string', 'timestamp', 'uint'].indexOf(this._type) != -1) {

					// If the value is not a valid int or long
					if(!is.integer(maximum)) {

						// If it's a valid representation of an integer
						if(is.string(maximum) && _typeToRegex['int'].test(maximum)) {

							// Convert it
							maximum	= parseInt(maximum, 0);
						}

						// Else, raise an error
						else {
							throw '"__maximum__" must be an integer';
						}

						// If the type is meant to be unsigned
						if(['base64', 'string', 'timestamp', 'uint'].indexOf(this._type) != -1) {

							// And it's below zero
							if(maximum < 0) {
								throw '"__maximum__" must be an unsigned integer';
							}
						}
					}
				}

				// Else if the type is decimal
				else if(this._type == 'decimal') {

					// If it's a not valid representation of a decimal
					if(!is.string(maximum) || !_typeToRegex['decimal'].test(maximum)) {

						// Throw an error
						throw '"__maximum__" not a valid decimal';
					}
				}

				// Else if the type is float
				else if(this._type == 'float') {

					// If it's not a float
					if(!is.float(maximum)) {

						// If we can't convert it to a float
						f	= parseFloat(maximum);
						if(isNaN(f)) {
							throw '"__maximum__" not a valid float';
						}

						// Store the parsed value
						maximum = f;
					}
				}

				// Else if the type is price
				else if(this._type == 'price') {

					// If it's a not valid representation of a price
					if(!is.string(maximum) || !_typeToRegex['price'].test(maximum)) {

						// Throw an error
						throw '"__maximum__" not a valid price';
					}
				}

				// Else we can't have a minimum
				else {
					throw 'can not set __maximum__ for "' + this._type + '"';
				}

				// If we also have a minimum
				if(this._minimum != null) {

					// If the type is an IP
					if(this._type == 'ip') {

						// If the min is above the maximum, we have a problem
						if(compareIPs(this._minimum, maximum) == 1) {
							throw '"__maximum__" can not be below "__minimum__"';
						}
					}

					// Else any other data type
					else {

						// If the min is above the maximum, we have a problem
						if(this._minimum > maximum) {
							throw '"__maximum__" can not be below "__minimum__"';
						}
					}
				}

				// Store the maximum
				this._maximum = maximum;
			}
		};

		/**
		 * Options
		 *
		 * Sets or gets the list of acceptable values for the Node
		 *
		 * @name options
		 * @access protected
		 * @param array opts			An array of valid values for the node when setting
		 * @return void|Array
		 */
		this.options = function options(opts) {

			// If opts aren't set, this is a getter
			if(typeof opts == 'undefined') {
				return this._options;
			}

			// Else this is a setter
			else {

				// If the options are not an Array
				if(!is.array(opts)) {
					throw '"__options__" must be an array';
				}

				// If the type is not one that can have options
				if(['any', 'base64', 'date', 'datetime', 'decimal',
						'float', 'int', 'ip', 'md5', 'price', 'string',
						'time', 'timestamp', 'uint', 'uuid'].indexOf(this._type) == -1) {
					throw 'can not set __options__ for "' + this._type + '"';
				}

				// Init the array of options to be saved
				var aOpts = [];

				// Go through each item and make sure it's unique and valid
				for(var i = 0; i < opts.length; ++i) {

					// Convert the value based on the type
					// If the type is a string one that we can validate
					if(['base64', 'date', 'datetime', 'ip', 'md5', 'time'].indexOf(this._type) != -1) {

						// If the value is not a string or doesn't match its regex,
						//	throw an error
						if(!is.string(opts[i]) || !_typeToRegex[this._type].test(opts[i])) {
							throw '"__options__[' + i + ']" is not valid for "' + this._type + '"';
						}
					}

					//	Else if it's decimal
					else if(this._type == 'decimal') {

						// And it's not a valid decimal representation
						if(is.string(opts[i]) || !_typeToRegex['decimal'].test(opts[i])) {

							// Throw an error
							throw '"__options__[' + i + ']" not a valid decimal';
						}
					}

					// Else if it's a float
					else if(this._type == 'float') {

						// If it's not a float
						if(!is.float(opts[i])) {

							// If we can't convert it to a float
							f = parseFloat(opts[i]);
							if(isNaN(f)) {
								throw '"__options__[' + i + ']" not a valid float';
							}

							// Store the parsed value
							opts[i]	= f;
						}
					}

					// Else if it's an integer
					else if(['int', 'timestamp', 'uint'].indexOf(this._type) != -1) {

						// If we don't already have an int
						if(!is.integer(opts[i])) {

							// If it's a valid representation of an integer
							if(is.string(opts[i]) && _typeToRegex['int'].test(opts[i])) {

								// Convert it
								opts[i]	= parseInt(opts[i], 0);
							}

							// Else, raise an error
							else {
								throw '"__options__[' + i + ']" must be an integer';
							}
						}

						// If the type is unsigned and negative, raise an error
						if(['timestamp', 'uint'].indexOf(this._type) != -1 && opts[i] < 0) {
							throw '"__options__[' + i + ']" must be an unsigned integer';
						}
					}

					//	Else if it's a price
					else if(this._type == 'price') {

						// And it's not a valid price representation
						if(!is.string(opts[i]) || !_typeToRegex['price'].test(opts[i])) {

							// Throw an error
							throw '"__options__[' + i + ']" not a valid price';
						}
					}

					// Else if the type is a string
					else if(this._type == 'string') {

						// If the value is not a string
						if(!is.string(opts[i])) {

							// Convert it
							opts[i]	= String(opts[i]);
						}
					}

					// If it's already in the list, raise an error
					if(aOpts.indexOf(opts[i]) != -1) {
						throw '"__options__[' + i + '] is a duplicate'
					}

					// Store the option
					else {
						aOpts.push(opts[i]);
					}
				}

				// Store the list of options
				this._options = aOpts;
			}
		};

		/**
		 * Regex
		 *
		 * Sets or gets the regular expression used to validate the Node
		 *
		 * @name regex
		 * @access protected
		 * @param str|RegExp regex		A regular expression string or object
		 * @return void|RegExp
		 */
		this.regex = function regex(regex) {

			// If regex was not set, this is a getter
			if(typeof regex === 'undefined') {
				return this._regex;
			}

			// Else this is a setter
			else {

				// If the type is not a string
				if(['decimal', 'int', 'price', 'string', 'timestamp', 'uint'].indexOf(this._type) == -1) {
					throw 'can not set __regex__ for "' + this._type + '"';
				}

				// If it's not a valid regex
				if(!(regex instanceof RegExp)) {

					// And it's not a string
					if(!is.string(regex)) {
						throw '"__regex__" must be a valid string or RegExp';
					}

					// Turn the string into a RegExp
					regex = new RegExp(regex);
				}

				// Store the regex
				this._regex = regex;
			}
		};

		/**
		 * To Object
		 *
		 * Returns the Node as an Object in the same format as is used in
		 * constructing it
		 *
		 * @name toObject
		 * @return Object
		 */
		this.toObject = function toObject() {

			// Init the Object we will return
			var oRet = {
				"__type__": this._type
			}

			// If there is a regex associated, add it
			if(this._regex) {
				oRet['__regex__'] = String(this._regex);
			}

			// Else if there were options associated, add them
			else if(this._options) {
				oRet['__options__'] = this._options;
			}

			// Else check for min and max and add if either are found
			else {
				if(this._minimum) {
					oRet['__minimum__'] = this._minimum;
				}
				if(this._maximum) {
					oRet['__maximum__'] = this._maximum;
				}
			}

			// Get the parents Object and add it to the return
			var oBasic = BasicNode.prototype.toObject.call(this);
			for(var k in oBasic) {
				oRet[k] = oBasic[k];
			}

			// Return
			return oRet;
		}

		/**
		 * Type
		 *
		 * Returns the type of Node this is
		 *
		 * @name type
		 * @return String
		 */
		this.type = function type() {
			return 'Node.' + this._type;
		};

		/**
		 * Valid
		 *
		 * Checks if a value is valid based on the instance's values
		 *
		 * @name valid
		 * @param mixed value			The value to validate
		 * @param array level			Names of parents to this node
		 * @return bool
		 */
		this.valid = function valid(value, level) {

			// Reset validation failures
			this.validation_failures = [];

			// If the value is None and it's optional, we're good
			if(value == null && this._optional) {
				return true;
			}

			// If level is not passed
			if(typeof level == 'undefined') {
				level = [];
			}

			// If we are validating an ANY field, immediately return true
			if(this._type == 'any') {

				// If there's a list of options
				if(this._options) {

					// Returns based on the option's existance
					if(this._options.indexOf(value) == -1) {
						this.validation_failures.push([level.join('.'), 'not in options']);
						return false;
					} else {
						return true;
					}
				}

				// Else, just return true
				return true;
			}

			// If we are validating a DATE, DATETIME, IP or TIME data point
			else if(['base64', 'date', 'datetime', 'ip', 'md5', 'time', 'uuid'].indexOf(this._type) != -1) {

				// If it's a date, datetime, or time type and the value is a
				//	JavaScript Date
				if(['date', 'datetime', 'time'].indexOf(this._type) != -1 &&
					value instanceof Date) {
					return true;
				}

				// If the value is not a string
				if(!is.string(value)) {
					this.validation_failures.push([level.join('.'), 'not a string'])
					return false;
				}

				// If there's no match
				if(!_typeToRegex[this._type].test(value)) {
					this.validation_failures.push([level.join('.'), 'failed regex (internal)'])
					return false;
				}

				// Else if there's a list of options
				else if(this._options) {

					// Returns based on the option's existance
					if(this._options.indexOf(value) == -1) {
						this.validation_failures.push([level.join('.'), 'not in options'])
						return false;
					} else {
						return true;
					}
				}
			}

			// Else if we are validating some sort of integer
			else if(['int', 'timestamp', 'uint'].indexOf(this._type) != -1) {

				// If the type is a bool, fail immediately
				if(typeof value == 'boolean') {
					this.validation_failures.push([level.join('.'), 'is a bool'])
					return false;
				}

				// If it's not an int
				if(!is.integer(value)) {

					// And it's a valid representation of an int
					if(is.string(value) && _typeToRegex['int'].test(value)) {

						// If it starts with 0
						if(value.charAt(0) == '0' && value.length > 1) {

							// If it's followed by X or x, it's hex
							if(['X', 'x'].indexOf(value.charAt(1)) != -1 && value.length > 2) {
								value = parseInt(value, 16);
							}

							// Else it's octal
							else {
								value = parseInt(value, 8);
							}
						}

						// Else it's base 10
						else {
							value = parseInt(value, 10);
						}
					}

					// Else, return false
					else {
						this.validation_failures.push([level.join('.'), 'not an integer'])
						return false;
					}
				}

				// If it's not signed
				if(['timestamp', 'uint'].indexOf(this._type) != -1) {

					// If the value is below 0
					if(value < 0) {
						this.validation_failures.push([level.join('.'), 'signed'])
						return false;
					}
				}

				// If there is a regex
				if(this._regex) {

					// And it doesn't match the regex
					if(!this._regex.test(String(value))) {
						this.validation_failures.push([level.join('.'), 'failed regex (custom)'])
						return false;
					}
				}

				// If there's a list of options
				if(this._options) {

					// Returns based on the option's existance
					if(this._options.indexOf(value) == -1) {
						this.validation_failures.push([level.join('.'), 'not in options'])
						return false;
					} else {
						return true;
					}
				}
			}

			// Else if we are validating a bool
			else if(this._type == 'bool') {

				// If it's already a bool
				if(typeof value == 'boolean') {
					return true;
				}

				// If it's an int or long at 0 or 1
				if(is.integer(value) && [0, 1].indexOf(value) != -1) {
					return true;
				}

				// Else if it's a string
				else if(is.string(value)) {

					// If it's t, T, 1, f, F, or 0
					if(['true', 'true', 'TRUE', 't', 'T', '1', 'false', 'false', 'FALSE', 'f', 'F', '0'].indexOf(value) != -1) {
						return true;
					} else {
						this.validation_failures.push([level.join('.'), 'not a valid string representation of a bool'])
						return false;
					}
				}

				// Else it's no valid type
				else {
					this.validation_failures.push([level.join('.'), 'not valid bool replacement'])
					return false;
				}
			}

			// Else if we are validating a decimal value
			else if(this._type == 'decimal') {

				// If the type is a bool, fail immediately
				if(typeof value == 'boolean') {
					this.validation_failures.push([level.join('.'), 'is a bool'])
					return false;
				}

				// If it's not a string or doesn't match the regex
				if(!is.string(value) || !_typeToRegex['decimal'].test(value)) {
					this.validation_failures.push([level.join('.'), 'failed regex (internal)'])
					return false;
				}

				// Else if there's a list of options
				else if(this._options) {

					// Returns based on the option's existance
					if(this._options.indexOf(value) == -1) {
						this.validation_failures.push([level.join('.'), 'not in options'])
						return false;
					} else {
						return true;
					}
				}
			}

			// Else if we are validating a floating point value
			else if(this._type == 'float') {

				// If the type is a bool, fail immediately
				if(typeof value == 'boolean') {
					this.validation_failures.push([level.join('.'), 'is a bool'])
					return false;
				}

				// If it's not a string or doesn't match the regex
				if(is.string(value) && !_typeToRegex['decimal'].test(value)) {
					this.validation_failures.push([level.join('.'), 'failed regex (internal)'])
					return false;
				}

				// If we fail to convert the value
				value = parseFloat(value);
				if(isNaN(value)) {
					this.validation_failures.push([level.join('.'), 'can not be converted to float'])
					return false;
				}

				// If there's a list of options
				if(this._options) {

					// Returns based on the option's existance
					if(this._options.indexOf(value) == -1) {
						this.validation_failures.push([level.join('.'), 'not in options'])
						return false;
					} else {
						return true;
					}
				}
			}

			// Else if we are validating a JSON string
			else if(this._type == 'json') {

				// If it's already a string
				if(is.string(value)) {

					// Try to decode it
					try {
						JSON.parse(value);
						return true;
					}
					catch(err) {
						this.validation_failures.push([level.join('.'), 'Can not be decoded from JSON'])
						return false;
					}
				}

				// Else
				else {

					// Try to encode it
					try {
						value = JSON.stringify(value);
						return true;
					}
					catch(err) {
						this.validation_failures.push([level.join('.'), 'Can not be encoded to JSON'])
						return false;
					}
				}
			}

			// Else if we are validating a price value
			else if(this._type == 'price') {

				// If the type is a bool, fail immediately
				if(typeof value == 'boolean') {
					this.validation_failures.push([level.join('.'), 'is a bool'])
					return false;
				}

				// If it's not a string
				if(!is.string(value)) {

					// If it's a number
					if(typeof value == 'number') {
						value = String(value);
					} else {
						return false;
					}
				}

				// If it doesn't match the regex
				if(!_typeToRegex['price'].test(value)) {
					this.validation_failures.push([level.join('.'), 'failed regex (internal)'])
					return false;
				}

				// If there's a regex
				if(this._regex) {

					// And it doesn't match
					if(!this._regex.test(value)) {
						this.validation_failures.push([level.join('.'), 'failed regex (custom)'])
						return false;
					}
				}

				// Else if there's a list of options
				else if(this._options) {

					// Returns based on the option's existance
					if(this._options.indexOf(value) == -1) {
						this.validation_failures.push([level.join('.'), 'not in options'])
						return false;
					} else {
						return true;
					}
				}
			}

			// Else if we are validating a string value
			else if(this._type == 'string') {

				// If the value is not some form of string
				if(!is.string(value)) {
					this.validation_failures.push([level.join('.'), 'is not a string'])
					return false;
				}

				// If we have a regex
				if(this._regex) {

					// If it doesn't match the regex
					if(!this._regex.test(value)) {
						this.validation_failures.push([level.join('.'), 'failed regex (custom)'])
						return false;
					}
				}

				// If there's a list of options
				else if(this._options) {

					// Returns based on the option's existance
					if(this._options.indexOf(value) == -1) {
						this.validation_failures.push([level.join('.'), 'not in options'])
						return false;
					} else {
						return true;
					}
				}

				// Else
				else {

					// If there's a minimum length and we don't reach it
					if(this._minimum && value.length < this._minimum) {
						this.validation_failures.push([level.join('.'), 'not long enough'])
						return false;
					}

					// If there's a maximum length and we surpass it
					if(this._maximum && value.length > this._maximum) {
						this.validation_failures.push([level.join('.'), 'too long'])
						return false;
					}
				}

				// Return ok
				return true;
			}

			// If there is a minimum value (for non bools and strings)
			if(this._minimum) {

				// If we are checking an IP
				if(this._type == 'ip') {

					// If the IP is less than the minimum
					if(compareIPs(value, this._minimum) == -1) {
						this.validation_failures.push([level.join('.'), 'did not meet minimum'])
						return false;
					}
				}

				// Else
				else {

					// If the value is less than the minimum
					if(value < this._minimum) {
						this.validation_failures.push([level.join('.'), 'did not meet minimum'])
						return false;
					}
				}
			}

			// If there is a maximum value (for non bools and strings)
			if(this._maximum) {

				// If we are checking an IP
				if(this._type == 'ip') {

					// If the IP is greater than the maximum
					if(compareIPs(value, this._maximum) == 1) {
						this.validation_failures.push([level.join('.'), 'exceeds maximum'])
						return false;
					}
				}

				// Else
				else {

					// If the value is greater than the maximum
					if(value > this._maximum) {
						this.validation_failures.push([level.join('.'), 'exceeds maximum'])
						return false;
					}
				}
			}

			// Value has no issues
			return true;
		};
		// END public methods
		// CONTINUE constructor

		// If there's a regex string available
		if('__regex__' in details) {
			this.regex(details['__regex__']);
			delete details['__regex__'];
		}

		// Else if there's a list of options
		else if('__options__' in details) {
			this.options(details['__options__']);
			delete details['__options__'];
		}

		// Else
		else {

			// If there's a min or max
			var bMin = '__minimum__' in details;
			var bMax = '__maximum__' in details;

			if(bMin || bMax) {
				this.minmax(
					(bMin ? details['__minimum__'] : null),
					(bMax ? details['__maximum__'] : null)
				);
			}

			if(bMin) {
				delete details['__minimum__'];
			}
			if(bMax) {
				delete details['__maximum__'];
			}
		}

		// Call the parent constructor
		BasicNode.call(this, details);
	}
899819
public ArrayList<OvhIpDetails> serviceName_ip_network_details_GET(String serviceName, String network) throws IOException {
		String qPath = "/dedicatedCloud/{serviceName}/ip/{network}/details";
		StringBuilder sb = path(qPath, serviceName, network);
		String resp = exec(qPath, "GET", sb.toString(), null);
		return convertTo(resp, t3);
	}