fix(root-domain): Check certificate before trying to add on proxy#6420
Conversation
|
@tanmoysrt, thanks for the contribution, but we do not accept pull requests on a master. Please close this PR and raise PR on an develop branch. |
Codecov Report❌ Patch coverage is
❌ Your patch status has failed because the patch coverage (0.00%) is below the target coverage (75.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## master #6420 +/- ##
==========================================
- Coverage 56.07% 56.06% -0.01%
==========================================
Files 940 940
Lines 78091 78104 +13
Branches 510 511 +1
==========================================
Hits 43791 43791
- Misses 34276 34289 +13
Partials 24 24
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR improves proxy/root-domain wildcard TLS handling by preventing proxy setup when a domain lacks a usable certificate, and adjusts the TLS renewal playbook to reload NGINX instead of always restarting it.
Changes:
- Add TLS certificate presence/validity checks before allowing a Root Domain to be added to Proxy Servers.
- Skip wildcard-domain entries that don’t have all required TLS material when building the proxy wildcard configuration.
- Update TLS Ansible role to attempt
nginx -s reloadand only restart NGINX if reload fails.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| press/press/doctype/server/server.py | Adds certificate material checks when assembling wildcard domain payload for proxy setup. |
| press/press/doctype/root_domain/root_domain.py | Blocks adding a root domain to proxies unless a TLS certificate exists and is populated; avoids duplicate domain child rows. |
| press/playbooks/roles/tls/tasks/main.yml | Switches from unconditional NGINX restart to reload-first with fallback restart. |
Comments suppressed due to low confidence (1)
press/press/doctype/root_domain/root_domain.py:214
- Wildcard host setup uses
full_chain(e.g./home/frappe/agent/tls/fullchain.pem), but this validation only checkscertificate,private_key, andintermediate_chain. Update the check to also requirefull_chain(or ensurefull_chainis derived for custom certs) so proxies don't proceed with an incomplete cert payload.
tls_ceritificate: TLSCertificate = frappe.get_doc("TLS Certificate", {"domain": self.name})
if not (
tls_ceritificate.certificate
and tls_ceritificate.private_key
and tls_ceritificate.intermediate_chain
):
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
🎉 This PR is included in version 0.31.6 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
|
| Filename | Overview |
|---|---|
| press/press/doctype/root_domain/root_domain.py | Adds TLS certificate existence and field validity check to add_to_proxies, and prevents duplicate domain entries; typo in variable name and a field inconsistency with what setup_wildcard_hosts actually validates. |
| press/press/doctype/server/server.py | Adds a certificate field completeness guard in get_wildcard_domains, but misses the None case where frappe.db.get_value finds no wildcard cert, which will cause frappe.get_doc to crash before the new guard is reached. |
| press/playbooks/roles/tls/tasks/main.yml | Replaces unconditional systemctl restart nginx with nginx -s reload, falling back to a full service restart only when nginx is not running; logic is correct. |
Sequence Diagram
sequenceDiagram
participant UI as Whitelist Caller
participant RD as RootDomain.add_to_proxies
participant DB as Frappe DB
participant Proxy as ProxyServer
participant Agent as Agent (setup_wildcard_hosts)
UI->>RD: add_to_proxies()
RD->>DB: "exists(TLS Certificate, {domain})"
alt No certificate
DB-->>RD: False
RD-->>UI: frappe.throw(missing cert)
else Certificate exists
DB-->>RD: True
RD->>DB: "get_doc(TLS Certificate, {domain})"
DB-->>RD: tls_certificate
alt Missing fields
RD-->>UI: frappe.throw(invalid cert)
else Valid certificate
loop Each active proxy
RD->>Proxy: get_doc(proxy_name)
alt Domain already on proxy
RD-->>Proxy: skip append/save
else Domain not on proxy
RD->>Proxy: append domain + save()
end
Proxy->>Agent: setup_wildcard_hosts()
Agent->>DB: get_wildcard_domains()
DB-->>Agent: wildcard certs (skips missing full_chain)
end
end
end
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
press/press/doctype/server/server.py:2522-2528
**Potential crash when no wildcard certificate exists**
`frappe.db.get_value` returns `None` when no wildcard TLS certificate is found for a domain. Passing `None` directly to `frappe.get_doc("TLS Certificate", None)` will raise a `frappe.exceptions.MandatoryError` or similar before the new `if not (…)` guard is ever reached. Any proxy with a domain that lacks a wildcard cert will cause `get_wildcard_domains` to throw, breaking the entire `setup_wildcard_hosts` call for that proxy.
### Issue 2 of 3
press/press/doctype/root_domain/root_domain.py:210-214
**Inconsistent field check vs. what proxy setup actually requires**
The guard here validates `tls_certificate.certificate` (the domain-only cert PEM), but `get_wildcard_domains` in `server.py` (called via `proxy.setup_wildcard_hosts()` just below) checks `full_chain`, not `certificate`. A TLS Certificate doc that has `certificate` populated but an empty `full_chain` will pass this guard and successfully save the domain to the proxy, yet `setup_wildcard_hosts` will silently skip it, leaving the proxy with a domain entry but no working wildcard configuration.
### Issue 3 of 3
press/press/doctype/root_domain/root_domain.py:209-219
Typo in variable name: `tls_ceritificate` has a transposed `i` (`ceri` instead of `certi`). Python won't surface this at parse time since both the assignment and the attribute reads use the same misspelled name, but it makes the code harder to read and search.
```suggestion
tls_certificate: TLSCertificate = frappe.get_doc("TLS Certificate", {"domain": self.name})
if not (
tls_certificate.certificate
and tls_certificate.private_key
and tls_certificate.intermediate_chain
):
frappe.throw(
"Please obtain a valid TLS certificate for this domain before adding it to proxy servers."
)
proxies = frappe.get_all("Proxy Server", {"status": "Active"}, pluck="name")
```
Reviews (1): Last reviewed commit: "Merge branch 'master' into fix_tls_failu..." | Re-trigger Greptile
| certificate_name = frappe.db.get_value( | ||
| "TLS Certificate", {"wildcard": True, "domain": domain.domain}, "name" | ||
| ) | ||
| certificate = frappe.get_doc("TLS Certificate", certificate_name) | ||
|
|
||
| certificate: TLSCertificate = frappe.get_doc("TLS Certificate", certificate_name) | ||
| if not (certificate.private_key and certificate.full_chain and certificate.intermediate_chain): | ||
| continue |
There was a problem hiding this comment.
Potential crash when no wildcard certificate exists
frappe.db.get_value returns None when no wildcard TLS certificate is found for a domain. Passing None directly to frappe.get_doc("TLS Certificate", None) will raise a frappe.exceptions.MandatoryError or similar before the new if not (…) guard is ever reached. Any proxy with a domain that lacks a wildcard cert will cause get_wildcard_domains to throw, breaking the entire setup_wildcard_hosts call for that proxy.
Prompt To Fix With AI
This is a comment left during a code review.
Path: press/press/doctype/server/server.py
Line: 2522-2528
Comment:
**Potential crash when no wildcard certificate exists**
`frappe.db.get_value` returns `None` when no wildcard TLS certificate is found for a domain. Passing `None` directly to `frappe.get_doc("TLS Certificate", None)` will raise a `frappe.exceptions.MandatoryError` or similar before the new `if not (…)` guard is ever reached. Any proxy with a domain that lacks a wildcard cert will cause `get_wildcard_domains` to throw, breaking the entire `setup_wildcard_hosts` call for that proxy.
How can I resolve this? If you propose a fix, please make it concise.
TLS Certificate Renewalusenginx -s reloadinstead of systemctl restart