-
Notifications
You must be signed in to change notification settings - Fork 77
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
tlsconfig trace implementation #150
Conversation
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.
Thanks for this PoC, @joewilliams. I wonder, if instead of requiring a parameter at the end of the tlsconfig.*Config()
methods how this would look if we adopted the Options
pattern used in other packages? Thoughts?
I assume that would work something like That said, I don't have a strong preference here. @aybabtme what do you think? |
I have integrated @aybabtme's suggestions, the important part is in go-spiffe/v2/spiffetls/tlsconfig/config.go Line 177 in 2415008
|
@azdagron @aybabtme graciously implemented the
|
Awesome. I'll take a detailed look as soon as I can. |
My opinion is that the above approach is too granular? I don't think we need separate options for Authorizer,GetCertificate,VerifyPeerCertificate. I also don't anticipate that we'll need per-method options. I think an option type for the whole package is probably sufficient? How does the following look?
|
Sounds good, I'll collapse the options into 1 type.
|
@azdagron PTAL |
👍 |
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.
Thanks, folks! I appreciate your patience with the back-and-forth on this.
As I reviewed the Start/End structs, I wondered if we could get away with not doing the measurement of elapsed time itself in the library by having the *Start callbacks return an interface{}
that is given to the *End callback. Maybe something like:
type Trace struct {
GetCertificate() interface{}
GotCertificate(interface{}, GotCertificateInfo)
An implementation could be:
trace.GetCertificate = func() interface{} {
// ... log or do whatever with your metrics to start recording elapsed time ...
return time.Now()
}
trace.GotCertificate = func(value interface{}, info GotCertificateInfo) {
elapsed := time.Since(value.(*time.Time))
// ... do something with `elapsed` and `info` ...
}
I'm not even sure how I feel about the above to be honest, but it came to mind.
Pros:
- it keeps all assumptions about how the trace is going to be used out of the library, providing only the barebones, but allowing for trace implementors to provide context between start/stop events when needed.
Cons:
- type assertions, woof!
- increases the boilerplate on trace implementations
Thoughts??
v2/spiffetls/tlsconfig/config.go
Outdated
@@ -26,63 +27,86 @@ func HookTLSClientConfig(config *tls.Config, bundle x509bundle.Source, authorize | |||
config.VerifyPeerCertificate = WrapVerifyPeerCertificate(config.VerifyPeerCertificate, bundle, authorizer) | |||
} | |||
|
|||
// A Option changes the defaults used to by mTLS ClientConfig functions. | |||
type Option func(*options) |
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.
We should probably use the same pattern we have for other options:
type Option func(*options) | |
type Option interface { | |
apply(*options) | |
} | |
type option func(*options) | |
func (fn option) apply(o *option) { | |
fn(o) | |
} |
Then the options can be implemented in terms of option
we get the flexibility later if we do end up needing to have per-method options mixed in with common options.
func WithSomeOption() Option {
return option(func(o *options) {
// modify `o`
})
}
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.
Makes sense, I'd never seen what the purpose of these interface-based options were, so always used the simpler func-based pattern. I see now that this makes it possible to reuse options and still have scoped down option types for narrower use-cases, which obviates the need for the N option types I had included in this PR initially!
Nice! The more you know!
v2/spiffetls/tlsconfig/trace.go
Outdated
End time.Time | ||
Cert *tls.Certificate | ||
Err error |
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.
These fields aren't used.
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.
Oups! Bad copy-pasta!
v2/go.sum
Outdated
@@ -17,6 +17,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a | |||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | |||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | |||
github.com/spiffe/go-spiffe v1.0.0 h1:zP+DNibBYpALBw597lwikzhriUhMqSUU3zCjBAD+BFw= |
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.
Hmm, where did this come from? What is pulling in go-spiffe v1?
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.
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.
not sure where this came from but it's cleaned up now
I like your idea, I was thinking of something similar initially using |
@azdagron PTAL |
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 a great improvement. Thank you for this contribution!
I have some minor suggestions around the testing. I think that it would also be good to update some of our example code to show how this capability can be leveraged (not necessarily as part of this PR).
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.
Just a few small changes so the interface is future proof (i.e. some functions in tlsconfig
don't take options). I think we're good to go after that.
@azdagron thanks for the quick review! I addressed your comments, PTAL. |
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.
\o/! Would you mind squashing this? (to preserve DCO). I'm happy to merge after that.
Signed-off-by: Joe Williams <[email protected]> add time to function call typo forgotten imports aybabtme's suggestions function name change clean up use two structs Signed-off-by: Antoine Grondin <[email protected]> introduce func. opts. pattern and convert GetCertificate tracing to it Signed-off-by: Antoine Grondin <[email protected]> adjust trickle down occurences of tlsconfig.Trace Signed-off-by: Antoine Grondin <[email protected]> collapse all option types into 1 for whole tlsconfig package Signed-off-by: Antoine Grondin <[email protected]> rework option type and trace mechanism Signed-off-by: Antoine Grondin <[email protected]> remove weird go-sum addition Signed-off-by: Antoine Grondin <[email protected]> test clean up Signed-off-by: Antoine Grondin <[email protected]> Update v2 to beta Signed-off-by: Andrew Harding <[email protected]> Signed-off-by: Antoine Grondin <[email protected]> Print out the expected peer and domains when encountering mismatches Signed-off-by: Kyle Anderson <[email protected]> Signed-off-by: Antoine Grondin <[email protected]> assert that GetCertificate gets called as expected Signed-off-by: Antoine Grondin <[email protected]> pass config.Option to every func Signed-off-by: Antoine Grondin <[email protected]> pluralize options funcs Signed-off-by: Antoine Grondin <[email protected]>
2ec467b
to
0ca6ea6
Compare
@azdagron things are green, should be good to go. |
\o/ thanks folks! I'll have a follow-up PR with some additional events. |
This is an implementation of TLSConfig hooks scoped just to
getTLSCertificate
.cc #149