mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-04 06:38:16 -06:00
Add support for socks connection to Git backend
This commit is contained in:
parent
85396866bc
commit
4198f77855
@ -4,6 +4,8 @@ import re
|
|||||||
import tempfile
|
import tempfile
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from urllib3 import PoolManager, HTTPConnectionPool, HTTPSConnectionPool
|
||||||
|
from urllib3.connection import HTTPConnection, HTTPSConnection
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
@ -23,6 +25,81 @@ __all__ = (
|
|||||||
logger = logging.getLogger('netbox.data_backends')
|
logger = logging.getLogger('netbox.data_backends')
|
||||||
|
|
||||||
|
|
||||||
|
# These Proxy Methods are for handling socks connection proxy
|
||||||
|
class ProxyHTTPConnection(HTTPConnection):
|
||||||
|
use_rdns = False
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
socks_options = kwargs.pop('_socks_options')
|
||||||
|
self._proxy_url = socks_options['proxy_url']
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def _new_conn(self):
|
||||||
|
from python_socks.sync import Proxy
|
||||||
|
proxy = Proxy.from_url(self._proxy_url, rdns=self.use_rdns)
|
||||||
|
return proxy.connect(
|
||||||
|
dest_host=self.host,
|
||||||
|
dest_port=self.port,
|
||||||
|
timeout=self.timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyHTTPSConnection(ProxyHTTPConnection, HTTPSConnection):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class rdnsProxyHTTPConnection(ProxyHTTPConnection):
|
||||||
|
use_rdns = True
|
||||||
|
|
||||||
|
|
||||||
|
class rdnsProxyHTTPSConnection(ProxyHTTPSConnection):
|
||||||
|
use_rdns = True
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyHTTPConnectionPool(HTTPConnectionPool):
|
||||||
|
ConnectionCls = ProxyHTTPConnection
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyHTTPSConnectionPool(HTTPSConnectionPool):
|
||||||
|
ConnectionCls = ProxyHTTPSConnection
|
||||||
|
|
||||||
|
|
||||||
|
class rdnsProxyHTTPConnectionPool(HTTPConnectionPool):
|
||||||
|
ConnectionCls = rdnsProxyHTTPConnection
|
||||||
|
|
||||||
|
|
||||||
|
class rdnsProxyHTTPSConnectionPool(HTTPSConnectionPool):
|
||||||
|
ConnectionCls = rdnsProxyHTTPSConnection
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyPoolManager(PoolManager):
|
||||||
|
def __init__(self, proxy_url, timeout=5, num_pools=10, headers=None,
|
||||||
|
**connection_pool_kw):
|
||||||
|
|
||||||
|
# python_socks uses rdns param to denote remote DNS parsing and
|
||||||
|
# doesn't accept the 'h' or 'a' in the proxy URL
|
||||||
|
cleaned_proxy_url = proxy_url
|
||||||
|
if use_rdns := cleaned_proxy_url.startswith(('socks5h:', 'socks5a:')):
|
||||||
|
cleaned_proxy_url = cleaned_proxy_url.replace('socks5h:', 'socks5:')
|
||||||
|
cleaned_proxy_url = cleaned_proxy_url.replace('socks5a:', 'socks5:')
|
||||||
|
|
||||||
|
connection_pool_kw['_socks_options'] = {'proxy_url': cleaned_proxy_url}
|
||||||
|
connection_pool_kw['timeout'] = timeout
|
||||||
|
|
||||||
|
super().__init__(num_pools, headers, **connection_pool_kw)
|
||||||
|
|
||||||
|
if use_rdns:
|
||||||
|
self.pool_classes_by_scheme = {
|
||||||
|
'http': rdnsProxyHTTPConnectionPool,
|
||||||
|
'https': rdnsProxyHTTPSConnectionPool,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
self.pool_classes_by_scheme = {
|
||||||
|
'http': ProxyHTTPConnectionPool,
|
||||||
|
'https': ProxyHTTPSConnectionPool,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@register_data_backend()
|
@register_data_backend()
|
||||||
class LocalBackend(DataBackend):
|
class LocalBackend(DataBackend):
|
||||||
name = 'local'
|
name = 'local'
|
||||||
@ -67,11 +144,14 @@ class GitBackend(DataBackend):
|
|||||||
|
|
||||||
# Initialize backend config
|
# Initialize backend config
|
||||||
config = ConfigDict()
|
config = ConfigDict()
|
||||||
|
self.use_socks = False
|
||||||
|
|
||||||
# Apply HTTP proxy (if configured)
|
# Apply HTTP proxy (if configured)
|
||||||
if settings.HTTP_PROXIES and self.url_scheme in ('http', 'https'):
|
if settings.HTTP_PROXIES and self.url_scheme in ('http', 'https'):
|
||||||
if proxy := settings.HTTP_PROXIES.get(self.url_scheme):
|
if proxy := settings.HTTP_PROXIES.get(self.url_scheme):
|
||||||
config.set("http", "proxy", proxy)
|
config.set("http", "proxy", proxy)
|
||||||
|
if proxy.startswith('socks'):
|
||||||
|
self.use_socks = True
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
@ -87,6 +167,10 @@ class GitBackend(DataBackend):
|
|||||||
"errstream": porcelain.NoneStream(),
|
"errstream": porcelain.NoneStream(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# check if using socks for proxy - if so need to use custom pool_manager
|
||||||
|
if self.use_socks:
|
||||||
|
clone_args['pool_manager'] = ProxyPoolManager(settings.HTTP_PROXIES.get(self.url_scheme))
|
||||||
|
|
||||||
if self.url_scheme in ('http', 'https'):
|
if self.url_scheme in ('http', 'https'):
|
||||||
if self.params.get('username'):
|
if self.params.get('username'):
|
||||||
clone_args.update(
|
clone_args.update(
|
||||||
|
Loading…
Reference in New Issue
Block a user