1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Use dulwich as Git client

This commit is contained in:
Tobias Genannt
2023-04-01 15:35:11 +02:00
committed by Jeremy Stretch
parent 7ecf3be33c
commit 9ef1fb1e3a
3 changed files with 18 additions and 26 deletions

View File

@ -74,6 +74,10 @@ drf-spectacular
# https://github.com/tfranzel/drf-spectacular-sidecar # https://github.com/tfranzel/drf-spectacular-sidecar
drf-spectacular-sidecar drf-spectacular-sidecar
# Git client for file sync
# https://github.com/jelmer/dulwich/releases
dulwich
# RSS feed parser # RSS feed parser
# https://github.com/kurtmckee/feedparser/blob/develop/CHANGELOG.rst # https://github.com/kurtmckee/feedparser/blob/develop/CHANGELOG.rst
feedparser feedparser

View File

@ -1,17 +1,18 @@
import logging import logging
import os import os
import re import re
import subprocess
import tempfile import tempfile
from contextlib import contextmanager from contextlib import contextmanager
from pathlib import Path from pathlib import Path
from urllib.parse import quote, urlunparse, urlparse from urllib.parse import urlparse
import boto3 import boto3
from botocore.config import Config as Boto3Config from botocore.config import Config as Boto3Config
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from dulwich import porcelain
from dulwich.config import StackedConfig
from netbox.registry import registry from netbox.registry import registry
from .choices import DataSourceTypeChoices from .choices import DataSourceTypeChoices
@ -88,37 +89,23 @@ class GitBackend(DataBackend):
def fetch(self): def fetch(self):
local_path = tempfile.TemporaryDirectory() local_path = tempfile.TemporaryDirectory()
# Add authentication credentials to URL (if specified)
username = self.params.get('username') username = self.params.get('username')
password = self.params.get('password') password = self.params.get('password')
if username and password: branch = self.params.get('branch')
# Add username & password to URL config = StackedConfig.default()
parsed = urlparse(self.url)
url = f'{parsed.scheme}://{quote(username)}:{quote(password)}@{parsed.netloc}{parsed.path}'
else:
url = self.url
# Compile git arguments
args = [settings.GIT_PATH, 'clone', '--depth', '1']
if branch := self.params.get('branch'):
args.extend(['--branch', branch])
args.extend([url, local_path.name])
# Prep environment variables
env_vars = {}
if settings.HTTP_PROXIES and self.url_scheme in ('http', 'https'): if settings.HTTP_PROXIES and self.url_scheme in ('http', 'https'):
env_vars['http_proxy'] = settings.HTTP_PROXIES.get(self.url_scheme) if proxy := settings.HTTP_PROXIES.get(self.url_scheme):
config.set("http", "proxy", proxy)
logger.debug(f"Cloning git repo: {' '.join(args)}") logger.debug(f"Cloning git repo: {self.url}")
try: try:
subprocess.run(args, check=True, capture_output=True, env=env_vars) porcelain.clone(
except FileNotFoundError as e: self.url, local_path.name, depth=1, branch=branch, username=username, password=password,
raise SyncError( config=config, quiet=True, errstream=porcelain.NoneStream()
f"Unable to fetch: git executable not found. Check that the git executable exists at the "
f"configured path: {settings.GIT_PATH}"
) )
except subprocess.CalledProcessError as e: except BaseException as e:
raise SyncError(f"Fetching remote data failed: {e.stderr}") raise SyncError(f"Fetching remote data failed ({type(e).__name__}): {e}")
yield local_path.name yield local_path.name

View File

@ -17,6 +17,7 @@ django-timezone-field==5.0
djangorestframework==3.14.0 djangorestframework==3.14.0
drf-spectacular==0.26.1 drf-spectacular==0.26.1
drf-spectacular-sidecar==2023.4.1 drf-spectacular-sidecar==2023.4.1
dulwich==0.21.3
feedparser==6.0.10 feedparser==6.0.10
graphene-django==3.0.0 graphene-django==3.0.0
gunicorn==20.1.0 gunicorn==20.1.0