Merge branch 'git-datasource2' into git-datasource

This commit is contained in:
Arthur Hanson 2024-09-30 11:52:16 -07:00
commit e2dd4e26fb
3 changed files with 36 additions and 11 deletions

View File

@ -8,10 +8,12 @@ from urllib.parse import urlparse
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from netbox.data_backends import DataBackend from netbox.data_backends import DataBackend
from netbox.utils import register_data_backend from netbox.utils import register_data_backend
from utilities.constants import DATA_SOURCE_SUPPORTED_SCHEMAS, DATA_SOURCE_SUPPORTED_SOCK_SCHEMAS
from utilities.socks import ProxyPoolManager from utilities.socks import ProxyPoolManager
from .exceptions import SyncError from .exceptions import SyncError
@ -71,11 +73,15 @@ class GitBackend(DataBackend):
self.use_socks = False 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:
if proxy := settings.HTTP_PROXIES.get(self.url_scheme): if proxy := settings.HTTP_PROXIES.get(self.url_scheme, None):
config.set("http", "proxy", proxy) if urlparse(proxy).scheme not in DATA_SOURCE_SUPPORTED_SCHEMAS:
if urlparse(proxy).scheme in ['socks4', 'socks4a', 'socks4h', 'socks5', 'socks5a', 'socks5h']: raise ImproperlyConfigured(f"Unsupported Git DataSource proxy scheme: {urlparse(proxy).scheme}")
self.use_socks = True
if self.url_scheme in ('http', 'https'):
config.set("http", "proxy", proxy)
if urlparse(proxy).scheme in DATA_SOURCE_SUPPORTED_SOCK_SCHEMAS:
self.use_socks = True
return config return config

View File

@ -93,3 +93,7 @@ HTML_ALLOWED_ATTRIBUTES = {
"td": {"align"}, "td": {"align"},
"th": {"align"}, "th": {"align"},
} }
DATA_SOURCE_SUPPORTED_SOCK_SCHEMAS = ['socks4', 'socks4a', 'socks4h', 'socks5', 'socks5a', 'socks5h']
DATA_SOURCE_SOCK_RDNS_SCHEMAS = ['socks4h', 'socks4a', 'socks5h', 'socks5a']
DATA_SOURCE_SUPPORTED_SCHEMAS = ['http', 'https', 'socks4', 'socks4a', 'socks4h', 'socks5', 'socks5a', 'socks5h']

View File

@ -1,10 +1,15 @@
from urllib.parse import urlparse from urllib.parse import urlparse
from urllib3 import PoolManager, HTTPConnectionPool, HTTPSConnectionPool from urllib3 import PoolManager, HTTPConnectionPool, HTTPSConnectionPool
from urllib3.connection import HTTPConnection, HTTPSConnection from urllib3.connection import HTTPConnection, HTTPSConnection
from .constants import DATA_SOURCE_SOCK_RDNS_SCHEMAS
# These Proxy Methods are for handling SOCKS connection proxy
class ProxyHTTPConnection(HTTPConnection): class ProxyHTTPConnection(HTTPConnection):
"""
A Proxy connection class that uses a SOCK proxy - used to create
a urllib3 PoolManager that routes connections via the proxy.
This is for an HTTP (not HTTPS) connection
"""
use_rdns = False use_rdns = False
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -23,14 +28,25 @@ class ProxyHTTPConnection(HTTPConnection):
class ProxyHTTPSConnection(ProxyHTTPConnection, HTTPSConnection): class ProxyHTTPSConnection(ProxyHTTPConnection, HTTPSConnection):
"""
A Proxy connection class for an HTTPS (not HTTP) connection.
"""
pass pass
class RdnsProxyHTTPConnection(ProxyHTTPConnection): class RdnsProxyHTTPConnection(ProxyHTTPConnection):
"""
A Proxy connection class for an HTTP remote-dns connection.
I.E. socks4a, socks4h, socks5a, socks5h
"""
use_rdns = True use_rdns = True
class RdnsProxyHTTPSConnection(ProxyHTTPSConnection): class RdnsProxyHTTPSConnection(ProxyHTTPSConnection):
"""
A Proxy connection class for an HTTPS remote-dns connection.
I.E. socks4a, socks4h, socks5a, socks5h
"""
use_rdns = True use_rdns = True
@ -54,12 +70,11 @@ class ProxyPoolManager(PoolManager):
def __init__(self, proxy_url, timeout=5, num_pools=10, headers=None, **connection_pool_kw): 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 # python_socks uses rdns param to denote remote DNS parsing and
# doesn't accept the 'h' or 'a' in the proxy URL # doesn't accept the 'h' or 'a' in the proxy URL
cleaned_proxy_url = proxy_url if use_rdns := urlparse(proxy_url).scheme in DATA_SOURCE_SOCK_RDNS_SCHEMAS:
if use_rdns := urlparse(cleaned_proxy_url).scheme in ['socks4h', 'socks4a', 'socks5h', 'socks5a']: proxy_url = proxy_url.replace('socks5h:', 'socks5:').replace('socks5a:', 'socks5:')
cleaned_proxy_url = cleaned_proxy_url.replace('socks5h:', 'socks5:').replace('socks5a:', 'socks5:') proxy_url = proxy_url.replace('socks4h:', 'socks4:').replace('socks4a:', 'socks4:')
cleaned_proxy_url = cleaned_proxy_url.replace('socks4h:', 'socks4:').replace('socks4a:', 'socks4:')
connection_pool_kw['_socks_options'] = {'proxy_url': cleaned_proxy_url} connection_pool_kw['_socks_options'] = {'proxy_url': proxy_url}
connection_pool_kw['timeout'] = timeout connection_pool_kw['timeout'] = timeout
super().__init__(num_pools, headers, **connection_pool_kw) super().__init__(num_pools, headers, **connection_pool_kw)