-
-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Retain the error stack if checkIfCertShouldBeObtained
returns an error
#256
Retain the error stack if checkIfCertShouldBeObtained
returns an error
#256
Conversation
Example code illustrating what we do:
type BlockedHost struct {
name string
}
func (bh *BlockedHost) Error() string {
return fmt.Sprintf("%s is blocked", bh.name)
}
certmagicConfig.OnDemand = &certmagic.OnDemandConfig{
DecisionContextFunc: func(ctx context.Context, name string) error {
// ...
if (shouldBlockHost(name)) {
return &BlockedHost{name}
}
// ...
},
// ...
}
tlsConfig.GetCertificate = func(clientHelloInfo *tls.ClientHelloInfo) (*tls.Certificate, error) {
txn := newrelicApp.StartTransaction("TLS/GetCertificate")
defer txn.End()
// Add attributes related to the request
txn.AddAttribute("hostname", clientHelloInfo.ServerName)
// Get a certificate
ctx := newrelic.NewContext(clientHelloInfo.Context(), txn)
cert, err := certmagicConfig.GetCertificateWithContext(ctx, clientHelloInfo)
if err != nil {
var bhe *BlockedHost
if errors.As(err, &bhe) {
// Fine, happens once in while.
txn.NoticeExpectedError(err)
} else {
// Something else!
txn.NoticeError(err)
}
}
// ...
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is reasonable, thanks for the explanation!
My default is to not wrap errors because then they become part of the exported API but in this case I think it makes sense, since the function returning the error is one defined by the user/caller.
Edit: Oops, merge conflict -- @ankon do you want to tackle it, or I can if you're busy! :)
Will do it quickly. FWIW: Instead of wrapping we could also just let the error get passed through completely with modification, which seems to be the case in most other places? |
This allows a outside caller of `GetCertificate` to use `errors.As` to check for their own response, and react accordingly.
d1d90df
to
1d6f2bc
Compare
Do you mean without modification? i.e. Personally I'm happy with this as-is now, but am happy to approve another way if you'd prefer. |
Indeed, I meant that. But, for now this is great, too -- there's always room to iterate further here if needed :) |
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [github.com/caddyserver/certmagic](https://togithub.com/caddyserver/certmagic) | require | minor | `v0.19.2` -> `v0.20.0` | | [github.com/expr-lang/expr](https://togithub.com/expr-lang/expr) | require | patch | `v1.15.6` -> `v1.15.7` | | [github.com/google/uuid](https://togithub.com/google/uuid) | require | minor | `v1.4.0` -> `v1.5.0` | | [github.com/jellydator/ttlcache/v3](https://togithub.com/jellydator/ttlcache) | require | patch | `v3.1.0` -> `v3.1.1` | | [github.com/mattn/go-sqlite3](https://togithub.com/mattn/go-sqlite3) | require | patch | `v1.14.18` -> `v1.14.19` | | [github.com/xanzy/go-gitlab](https://togithub.com/xanzy/go-gitlab) | require | minor | `v0.94.0` -> `v0.95.2` | | [google.golang.org/grpc](https://togithub.com/grpc/grpc-go) | require | minor | `v1.59.0` -> `v1.60.0` | | [k8s.io/api](https://togithub.com/kubernetes/api) | require | minor | `v0.28.4` -> `v0.29.0` | | [k8s.io/apimachinery](https://togithub.com/kubernetes/apimachinery) | require | minor | `v0.28.4` -> `v0.29.0` | | [k8s.io/client-go](https://togithub.com/kubernetes/client-go) | require | minor | `v0.28.4` -> `v0.29.0` | --- ### Release Notes <details> <summary>caddyserver/certmagic (github.com/caddyserver/certmagic)</summary> ### [`v0.20.0`](https://togithub.com/caddyserver/certmagic/releases/tag/v0.20.0) [Compare Source](https://togithub.com/caddyserver/certmagic/compare/v0.19.2...v0.20.0) This release vastly improves storage cleaning as well improving a few smaller things. There is a minor breaking change as we get ever closer to v1.0. -⚠️ The `DecisionFunc` for On-Demand TLS now takes a `context.Context` value as its first argument. The context carries the `ClientHelloInfo` value (keyed by `ClientHelloInfoCtxKey`) for logging purposes. - Storage cleaning is now synchronized across the cluster, including process restarts. The state of cleaning expired certificates and OCSP staples is written to storage, and distributed locking is used to ensure that only 1 instance does it at a time. This greatly reduces costs for expensive storage backends! Cleaning is also done less often when the process is frequently restarted because the state is written to storage, so it is not forgotten after shutting down. - `.home.arpa` is now considered an internal suffix. - Backoff timings have been tuned based on real-world experience. #### What's Changed - README: Add hint about NextProtos for certmagic.TLS by [@​oliverpool](https://togithub.com/oliverpool) in [https://github.com/caddyserver/certmagic/pull/251](https://togithub.com/caddyserver/certmagic/pull/251) - Bump golang.org/x/net from 0.11.0 to 0.17.0 by [@​dependabot](https://togithub.com/dependabot) in [https://github.com/caddyserver/certmagic/pull/253](https://togithub.com/caddyserver/certmagic/pull/253) - Optionally pass the context argument down to the OnDemand decision func by [@​ankon](https://togithub.com/ankon) in [https://github.com/caddyserver/certmagic/pull/255](https://togithub.com/caddyserver/certmagic/pull/255) - Retain the error stack if `checkIfCertShouldBeObtained` returns an error by [@​ankon](https://togithub.com/ankon) in [https://github.com/caddyserver/certmagic/pull/256](https://togithub.com/caddyserver/certmagic/pull/256) - Add OCSP stapling unit tests by [@​kenjenkins](https://togithub.com/kenjenkins) in [https://github.com/caddyserver/certmagic/pull/259](https://togithub.com/caddyserver/certmagic/pull/259) #### New Contributors - [@​oliverpool](https://togithub.com/oliverpool) made their first contribution in [https://github.com/caddyserver/certmagic/pull/251](https://togithub.com/caddyserver/certmagic/pull/251) **Full Changelog**: caddyserver/certmagic@v0.19.2...v0.20.0 </details> <details> <summary>expr-lang/expr (github.com/expr-lang/expr)</summary> ### [`v1.15.7`](https://togithub.com/expr-lang/expr/releases/tag/v1.15.7) [Compare Source](https://togithub.com/expr-lang/expr/compare/v1.15.6...v1.15.7) **Expr** is a Go-centric expression language designed to deliver dynamic configurations with unparalleled accuracy, safety, and speed. ##### In this release: - Fixed commutative property for comparison between a value and a pointer. ([#​490](https://togithub.com/expr-lang/expr/issues/490)) - Checker: forbid accessing built-ins and custom functions from `$env`. ([#​495](https://togithub.com/expr-lang/expr/issues/495)) - Enhanced the number parser to include support for parsing hexadecimal, binary, and octal literals. ([#​483](https://togithub.com/expr-lang/expr/issues/483)) - Added `GetSource()` method to `vm.Program`. ([#​491](https://togithub.com/expr-lang/expr/issues/491)) </details> <details> <summary>google/uuid (github.com/google/uuid)</summary> ### [`v1.5.0`](https://togithub.com/google/uuid/releases/tag/v1.5.0) [Compare Source](https://togithub.com/google/uuid/compare/v1.4.0...v1.5.0) ##### Features - Validate UUID without creating new UUID ([#​141](https://togithub.com/google/uuid/issues/141)) ([9ee7366](https://togithub.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29)) </details> <details> <summary>jellydator/ttlcache (github.com/jellydator/ttlcache/v3)</summary> ### [`v3.1.1`](https://togithub.com/jellydator/ttlcache/releases/tag/v3.1.1) [Compare Source](https://togithub.com/jellydator/ttlcache/compare/v3.1.0...v3.1.1) Fix a bug in the `Range` method that causes a panic when the cache is empty </details> <details> <summary>mattn/go-sqlite3 (github.com/mattn/go-sqlite3)</summary> ### [`v1.14.19`](https://togithub.com/mattn/go-sqlite3/compare/v1.14.18...v1.14.19) [Compare Source](https://togithub.com/mattn/go-sqlite3/compare/v1.14.18...v1.14.19) </details> <details> <summary>xanzy/go-gitlab (github.com/xanzy/go-gitlab)</summary> ### [`v0.95.2`](https://togithub.com/xanzy/go-gitlab/compare/v0.95.1...v0.95.2) [Compare Source](https://togithub.com/xanzy/go-gitlab/compare/v0.95.1...v0.95.2) ### [`v0.95.1`](https://togithub.com/xanzy/go-gitlab/compare/v0.95.0...v0.95.1) [Compare Source](https://togithub.com/xanzy/go-gitlab/compare/v0.95.0...v0.95.1) ### [`v0.95.0`](https://togithub.com/xanzy/go-gitlab/compare/v0.94.0...v0.95.0) [Compare Source](https://togithub.com/xanzy/go-gitlab/compare/v0.94.0...v0.95.0) </details> <details> <summary>grpc/grpc-go (google.golang.org/grpc)</summary> ### [`v1.60.0`](https://togithub.com/grpc/grpc-go/releases/tag/v1.60.0): Release 1.60.0 [Compare Source](https://togithub.com/grpc/grpc-go/compare/v1.59.0...v1.60.0) ### Security - credentials/tls: if not set, set TLS MinVersion to 1.2 and CipherSuites according to supported suites not forbidden by RFC7540. - This is a behavior change to bring us into better alignment with RFC 7540. ### API Changes - resolver: remove deprecated and experimental `ClientConn.NewServiceConfig` ([#​6784](https://togithub.com/grpc/grpc-go/issues/6784)) - client: remove deprecated `grpc.WithServiceConfig` `DialOption` ([#​6800](https://togithub.com/grpc/grpc-go/issues/6800)) ### Bug Fixes - client: fix race that could cause a deadlock while entering idle mode and receiving a name resolver update ([#​6804](https://togithub.com/grpc/grpc-go/issues/6804)) - client: always enable TCP keepalives with OS defaults ([#​6834](https://togithub.com/grpc/grpc-go/issues/6834)) - credentials/alts: fix a bug preventing ALTS from connecting to the metadata server if the default scheme is overridden ([#​6686](https://togithub.com/grpc/grpc-go/issues/6686)) - Special Thanks: [@​mjamaloney](https://togithub.com/mjamaloney) ### Behavior Changes - server: Do not return from Stop() or GracefulStop() until all resources are released ([#​6489](https://togithub.com/grpc/grpc-go/issues/6489)) - Special Thanks: [@​fho](https://togithub.com/fho) ### Documentation - codes: clarify that only codes defined by this package are valid and that users should not cast other values to `codes.Code` ([#​6701](https://togithub.com/grpc/grpc-go/issues/6701)) </details> <details> <summary>kubernetes/api (k8s.io/api)</summary> ### [`v0.29.0`](https://togithub.com/kubernetes/api/compare/v0.28.4...v0.29.0) [Compare Source](https://togithub.com/kubernetes/api/compare/v0.28.4...v0.29.0) </details> <details> <summary>kubernetes/apimachinery (k8s.io/apimachinery)</summary> ### [`v0.29.0`](https://togithub.com/kubernetes/apimachinery/compare/v0.28.4...v0.29.0) [Compare Source](https://togithub.com/kubernetes/apimachinery/compare/v0.28.4...v0.29.0) </details> <details> <summary>kubernetes/client-go (k8s.io/client-go)</summary> ### [`v0.29.0`](https://togithub.com/kubernetes/client-go/compare/v0.28.4...v0.29.0) [Compare Source](https://togithub.com/kubernetes/client-go/compare/v0.28.4...v0.29.0) </details> --- ### Configuration 📅 **Schedule**: Branch creation - "before 4am" (UTC), Automerge - "before 4am" (UTC). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/woodpecker-ci/woodpecker). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy45My4xIiwidXBkYXRlZEluVmVyIjoiMzcuOTMuMSIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
This allows an outside caller of
GetCertificate
to useerrors.As
to check for their own response and react accordingly.In our case: The ondemand decision func checks a blocklist and might return something like
BlockedDomainError{message:"This is blocked"}
. This isn't an "error", it's just something that so happens to look like an error because that's what the decision func wants us to return.In the GetCertificate implementation we call certmagic, and check the error it returns. If the error is "expected", then we don't really care about it and might just count it. If it is something interesting, we might want to tell a human about it.
The way that works is by having the
GetCertificate
function in a NewRelic "Transaction", and when we receive an error from certmagic we check whether the error is of one of the "normal" types, and if so calltxn.NoticeExpectedError(err)
. If it is interesting, we callNoticeError(err)
.This doesn't work for the errors from the decision func, because those lose their causal trace. The PR fixes that by using
%w
instead of%v
to transmit the error outwards.