2016-09-30 183 views
0

是否有可能有Python的请求库决心领事域名与SRV记录,并发出请求时使用正确的IP地址和端口?使用与蟒蛇请求库SRV DNS记录

例如,假设我有serviceA与IP地址172.18.0.5端口8080上运行,此服务与领事注册。并且假设主机的DNS设置为使用consul来解析查询。我能做出这样的请求:

requests.get('http://serviceA.service.consul') 

,并把它等同于要求:

requests.get('http://172.18.0.5:8080') 

回答

0

我最后写一个补丁,将使用this answer做到这一点的请求。由于请求库的更新,我必须做出一些更改。该补丁适用于请求版本2.11.1。

我使用dnspython库来解析SRV记录,并且它希望consul侦听DNS请求的IP地址和端口可用作环境变量CONSUL_DNS_IP_PORT。要使用该补丁,请从该补丁所在的任何模块导入requests_use_srv_records函数,然后调用它。它只会尝试对以.service.consul结尾的主机使用consul SRV记录,其他主机将定期解析。

这里的补丁:

# Python Imports 
import os 
from socket import error as SocketError, timeout as SocketTimeout 

# 3rd Party Imports 
from dns import resolver 
from requests.packages.urllib3.connection import HTTPConnection 
from requests.packages.urllib3.exceptions import (NewConnectionError, 
                ConnectTimeoutError) 
from requests.packages.urllib3.util import connection 

def resolve_srv_record(host): 

    consul_dns_ip_port = os.environ.get('CONSUL_DNS_IP_PORT', 
             '172.17.0.1:53') 
    consul_dns_ip, consul_dns_port = consul_dns_ip_port.split(':') 

    res = resolver.Resolver() 
    res.port = consul_dns_port 
    res.nameservers = [consul_dns_ip] 

    ans = resolver.query(host, 'SRV') 

    return ans.response.additional[0].items[0].address, ans[0].port 

def patched_new_conn(self): 

    if self.host.endswith('.service.consul'): 
     hostname, port = resolve_srv_record(self.host) 
    else: 
     hostname = self.host 
     port = self.port 

    extra_kw = {} 

    if self.source_address: 
     extra_kw['source_address'] = self.source_address 

    if self.socket_options: 
     extra_kw['socket_options'] = self.socket_options 

    try: 
     conn = connection.create_connection((hostname, port), 
              self.timeout, 
              **extra_kw) 

    except SocketTimeout as e: 
     raise ConnectTimeoutError(
      self, "Connection to %s timed out. (connect timeout=%s)" % 
      (self.host, self.timeout)) 

    except SocketError as e: 
     raise NewConnectionError(
      self, "Failed to establish a new connection: %s" % e) 

    return conn 

def requests_use_srv_records(): 
    HTTPConnection._new_conn = patched_new_conn 
0

不,你不能,除非你重写requests

SRV记录是为了找到服务而设计的。
在这种情况下,您已经指示使用http。因此客户只会查询A或AAAA记录serviceA.service.consul