Skip to content

Commit 5e4ce73

Browse files
committed
refactor
1 parent eb9e00b commit 5e4ce73

File tree

5 files changed

+61
-67
lines changed

5 files changed

+61
-67
lines changed

custom-domain/dstack-ingress/DNS_PROVIDERS.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,13 @@ NAMECHEAP_CLIENT_IP=your-client-ip
6565

6666
**Required Credentials:**
6767
- `NAMECHEAP_USERNAME` - Your Namecheap account username
68-
- `NAMECHEAP_API_KEY` - Your Namecheap API key (from https://ap.www.namecheap.com/settings/tools/api-access/)
69-
- `NAMECHEAP_CLIENT_IP` - Your public IP address (required for Namecheap API authentication)
68+
- `NAMECHEAP_API_KEY` - Your Namecheap API key (from https://ap.www.namecheap.com/settings/tools/apiaccess/)
69+
- `NAMECHEAP_CLIENT_IP` - The IP address of the node (required for Namecheap API authentication)
7070

7171
**Important Notes for Namecheap:**
72-
- Namecheap API requires your client IP address for authentication
73-
- You can find your public IP at https://www.whatismyip.com/
72+
- Namecheap API requires node IP address for authentication, and you need add it to whitelist IP first.
7473
- Namecheap doesn't support CAA records through their API currently
7574
- The certbot plugin uses the format `certbot-dns-namecheap` package
76-
- DNS propagation time is set to 120 seconds by default
7775

7876
## Docker Compose Examples
7977

custom-domain/dstack-ingress/scripts/certman.py

Lines changed: 54 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
#!/usr/bin/env python3
22

3-
from dns_providers import DNSProviderFactory
43
import argparse
54
import os
65
import subprocess
76
import sys
7+
import pkg_resources
88
from typing import List, Optional, Tuple
99

1010
# Add script directory to path to import dns_providers
1111
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
1212

13+
from dns_providers import DNSProviderFactory
14+
1315

1416
class CertManager:
1517
"""Certificate management using DNS provider infrastructure."""
@@ -35,10 +37,9 @@ def install_plugin(self) -> bool:
3537

3638
# Check if plugin is already installed
3739
try:
38-
if self.provider.CERTBOT_PLUGIN == "dns-namecheap":
39-
import certbot_dns_namecheap.dns_namecheap
40-
print(f"Plugin {self.provider.CERTBOT_PACKAGE} is already installed")
41-
return True
40+
__import__(self.provider.CERTBOT_PLUGIN_MODULE)
41+
print(f"Plugin {self.provider.CERTBOT_PACKAGE} is already installed")
42+
return True
4243
except ImportError:
4344
pass # Plugin not installed, continue with installation
4445

@@ -48,7 +49,6 @@ def install_plugin(self) -> bool:
4849
install_methods = []
4950

5051
# Method 1: Use the same python executable that's running this script
51-
import sys
5252
install_methods.append([sys.executable, "-m", "pip", "install", self.provider.CERTBOT_PACKAGE])
5353

5454
# Method 2: Use virtual environment pip if available
@@ -86,16 +86,14 @@ def install_plugin(self) -> bool:
8686

8787
# Diagnostic information for troubleshooting
8888
try:
89-
import sys
90-
import pkg_resources
9189
print(f"Installed to Python: {sys.executable}")
9290

9391
# Show certbot command
9492
certbot_cmd = self._get_certbot_command()
9593
print(f"Using certbot: {' '.join(certbot_cmd)}")
9694

9795
try:
98-
dist = pkg_resources.get_distribution("certbot-dns-namecheap")
96+
dist = pkg_resources.get_distribution(self.provider.CERTBOT_PACKAGE)
9997
print(f"Package version: {dist.version} at {dist.location}")
10098
except pkg_resources.DistributionNotFound:
10199
print("Warning: Package not found in current environment")
@@ -104,52 +102,50 @@ def install_plugin(self) -> bool:
104102

105103
# Verify plugin installation
106104
try:
107-
if self.provider.CERTBOT_PLUGIN == "dns-namecheap":
108-
import certbot_dns_namecheap.dns_namecheap
109-
print(f"Plugin {self.provider.CERTBOT_PLUGIN} successfully imported")
105+
imported_module = __import__(self.provider.CERTBOT_PLUGIN_MODULE)
106+
print(f"Plugin {self.provider.CERTBOT_PLUGIN} successfully imported")
107+
108+
# Test if plugin is recognized by certbot
109+
certbot_cmd = self._get_certbot_command()
110+
test_cmd = certbot_cmd + ["plugins"]
111+
test_result = subprocess.run(test_cmd, capture_output=True, text=True, timeout=10)
112+
113+
if test_result.returncode == 0 and self.provider.CERTBOT_PLUGIN in test_result.stdout:
114+
print(f"✓ Plugin {self.provider.CERTBOT_PLUGIN} is available in certbot")
115+
return True
116+
else:
117+
print(f"Warning: {self.provider.CERTBOT_PLUGIN} plugin not found in certbot plugins list")
118+
if test_result.stderr:
119+
print(f"Plugin test stderr: {test_result.stderr}")
110120

111-
# Test if plugin is recognized by certbot
112-
certbot_cmd = self._get_certbot_command()
113-
test_cmd = certbot_cmd + ["plugins"]
114-
test_result = subprocess.run(test_cmd, capture_output=True, text=True, timeout=10)
121+
# Debug plugin registration
122+
self._debug_plugin_registration()
115123

116-
if test_result.returncode == 0 and "dns-namecheap" in test_result.stdout:
117-
print(f"✓ Plugin {self.provider.CERTBOT_PLUGIN} is available in certbot")
118-
return True
119-
else:
120-
print(f"Warning: dns-namecheap plugin not found in certbot plugins list")
121-
if test_result.stderr:
122-
print(f"Plugin test stderr: {test_result.stderr}")
124+
# Try force reinstall to fix plugin registration
125+
print("Attempting to fix plugin registration...")
126+
try:
127+
force_cmd = [sys.executable, "-m", "pip", "install", "--force-reinstall",
128+
"--no-deps", self.provider.CERTBOT_PACKAGE]
129+
print(f"Running: {' '.join(force_cmd)}")
130+
force_result = subprocess.run(force_cmd, capture_output=True, text=True)
123131

124-
# Debug plugin registration
125-
self._debug_plugin_registration()
126-
127-
# Try force reinstall to fix plugin registration
128-
print("Attempting to fix plugin registration...")
129-
try:
130-
import sys
131-
force_cmd = [sys.executable, "-m", "pip", "install", "--force-reinstall",
132-
"--no-deps", self.provider.CERTBOT_PACKAGE]
133-
print(f"Running: {' '.join(force_cmd)}")
134-
force_result = subprocess.run(force_cmd, capture_output=True, text=True)
135-
136-
if force_result.returncode == 0:
137-
# Test again after reinstall
138-
retest_cmd = certbot_cmd + ["plugins"]
139-
retest_result = subprocess.run(retest_cmd, capture_output=True, text=True, timeout=10)
140-
if retest_result.returncode == 0 and "dns-namecheap" in retest_result.stdout:
141-
print(f"✓ Plugin registration fixed after reinstall")
142-
return True
143-
else:
144-
print(f"Plugin still not registered, may work anyway")
132+
if force_result.returncode == 0:
133+
# Test again after reinstall
134+
retest_cmd = certbot_cmd + ["plugins"]
135+
retest_result = subprocess.run(retest_cmd, capture_output=True, text=True, timeout=10)
136+
if retest_result.returncode == 0 and self.provider.CERTBOT_PLUGIN in retest_result.stdout:
137+
print(f"✓ Plugin registration fixed after reinstall")
138+
return True
145139
else:
146-
print(f"Force reinstall failed: {force_result.stderr}")
147-
except Exception as fix_error:
148-
print(f"Plugin fix attempt failed: {fix_error}")
149-
150-
# Continue anyway - may work in Docker environments
151-
return True
152-
140+
print(f"Plugin still not registered, may work anyway")
141+
else:
142+
print(f"Force reinstall failed: {force_result.stderr}")
143+
except Exception as fix_error:
144+
print(f"Plugin fix attempt failed: {fix_error}")
145+
146+
# Continue anyway - may work in Docker environments
147+
return True
148+
153149
except Exception as e:
154150
print(f"Plugin verification warning: {e}")
155151
return True
@@ -158,7 +154,6 @@ def install_plugin(self) -> bool:
158154

159155
def _ensure_certbot_in_env(self) -> None:
160156
"""Ensure certbot is installed in the current Python environment."""
161-
import sys
162157

163158
# Try to import certbot to check if it's installed
164159
try:
@@ -185,8 +180,6 @@ def _ensure_certbot_in_env(self) -> None:
185180

186181
def _get_certbot_command(self) -> List[str]:
187182
"""Get the correct certbot command that uses the same Python environment."""
188-
import sys
189-
import os
190183

191184
# Always use certbot from the same Python environment
192185
python_dir = os.path.dirname(sys.executable)
@@ -221,22 +214,22 @@ def _debug_plugin_registration(self) -> None:
221214
for ep in entry_points:
222215
print(f" - {ep.name}: {ep.module_name}")
223216

224-
# Look specifically for dns-namecheap
225-
namecheap_eps = [ep for ep in entry_points if ep.name == 'dns-namecheap']
226-
if namecheap_eps:
227-
print(f"✓ Found dns-namecheap entry point: {namecheap_eps[0]}")
217+
# Look specifically for our plugin
218+
plugin_eps = [ep for ep in entry_points if ep.name == self.provider.CERTBOT_PLUGIN]
219+
if plugin_eps:
220+
print(f"✓ Found {self.provider.CERTBOT_PLUGIN} entry point: {plugin_eps[0]}")
228221
else:
229-
print(f"✗ dns-namecheap entry point not found")
222+
print(f"✗ {self.provider.CERTBOT_PLUGIN} entry point not found")
230223
except Exception as ep_error:
231224
print(f"Entry point check failed: {ep_error}")
232225

233226
# Check if certbot can import the plugin module
234227
try:
235-
from certbot_dns_namecheap import dns_namecheap
228+
imported_module = __import__(self.provider.CERTBOT_PLUGIN_MODULE)
236229
print(f"✓ Plugin module can be imported")
237230

238231
# Check if it has the right class
239-
if hasattr(dns_namecheap, 'Authenticator'):
232+
if hasattr(imported_module, 'Authenticator'):
240233
print(f"✓ Authenticator class found")
241234
else:
242235
print(f"✗ Authenticator class not found")

custom-domain/dstack-ingress/scripts/dns_providers/cloudflare.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class CloudflareDNSProvider(DNSProvider):
1515

1616
# Certbot configuration
1717
CERTBOT_PLUGIN = "dns-cloudflare"
18+
CERTBOT_PLUGIN_MODULE = "certbot_dns_cloudflare"
1819
CERTBOT_PACKAGE = "certbot-dns-cloudflare==4.0.0"
1920
CERTBOT_PROPAGATION_SECONDS = 120
2021
CERTBOT_CREDENTIALS_FILE = "~/.cloudflare/cloudflare.ini"

custom-domain/dstack-ingress/scripts/dns_providers/linode.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class LinodeDNSProvider(DNSProvider):
1616

1717
# Certbot configuration
1818
CERTBOT_PLUGIN = "dns-linode"
19+
CERTBOT_PLUGIN_MODULE = "certbot_dns_linode"
1920
CERTBOT_PACKAGE = "certbot-dns-linode"
2021
CERTBOT_PROPAGATION_SECONDS = 300
2122
CERTBOT_CREDENTIALS_FILE = "~/.linode/credentials.ini"

custom-domain/dstack-ingress/scripts/dns_providers/namecheap.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ class NamecheapDNSProvider(DNSProvider):
1212

1313
DETECT_ENV = "NAMECHEAP_API_KEY"
1414
CERTBOT_PLUGIN = "dns-namecheap"
15-
CERTBOT_PACKAGE = "certbot-dns-namecheap"
15+
CERTBOT_PLUGIN_MODULE = "certbot_dns_namecheap"
16+
CERTBOT_PACKAGE = "certbot-dns-namecheap==1.0.0"
1617
CERTBOT_PROPAGATION_SECONDS = 120
1718
CERTBOT_CREDENTIALS_FILE = "~/.namecheap/namecheap.ini"
1819

0 commit comments

Comments
 (0)