2016-09-30 21 views
0

PythonリクエストライブラリでSRVレコードを使用して領事ドメイン名を解決し、リクエスト時に正しいIPアドレスとポートを使用することはできますか?SRV DNSレコードをPythonリクエストライブラリで使用する

たとえば、serviceAをポート8080のIPアドレス172.18.0.5で実行している場合、このサービスはconsulに登録されています。ホストのDNSがconsulを使用してクエリを解決するように設定されていることを考えれば、私のような要求を行うことができます。

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

と、それは要求と同等であることがあります。

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

答えて

0

私は、this answerを使ってこれを行う要求のためのパッチを書きました。私は、リクエストライブラリの更新によっていくつかの変更を加えなければなりませんでした。このパッチは、バージョン2.11.1のリクエストで動作します。

私はSRVレコードを解決するためにdnspythonライブラリを使用し、consulが環境変数CONSUL_DNS_IP_PORTとして利用できるようにDNSリクエストをリスンしているIPアドレスとポートを想定しています。パッチを使用するには、パッチが入っているモジュールからrequests_use_srv_records関数をインポートしてから呼び出します。 .service.consulで終わるホストに対してのみCONVAL 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を使用するよう指示しています。クライアントはserviceA.service.consulのAレコードまたはAAAAレコードのみを照会します。

関連する問題