-
Notifications
You must be signed in to change notification settings - Fork 75
allow web UI to be configured when using mTLS in API #138
Conversation
cmd/temporalite/ui.go
Outdated
func newUIConfig(frontendAddr string, uiIP string, uiPort int, configDir string) (*uiconfig.Config, error) { | ||
cfg := &uiconfig.Config{} | ||
if configDir != "" { | ||
if err := config.Load("temporalite-ui", configDir, "", cfg); err != nil { |
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.
Even though it appears to basically be the same thing, I wonder if you would rather use https://pkg.go.dev/github.com/temporalio/ui-server/v2/plugins/fs_config_provider#Load to match what the UI server project does
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.
Sure.
cmd/temporalite/ui.go
Outdated
} | ||
cfg.TemporalGRPCAddress = frontendAddr | ||
cfg.Host = uiIP |
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.
Wonder if this should only overwrite if not set from the config file
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.
Sure, I guess the only non-negotiable settings are TemporalGRPCAddress
and EnableUI
. The others can be overridden by the config file.
EnableUI: true, | ||
func newUIConfig(frontendAddr string, uiIP string, uiPort int, configDir string) (*uiconfig.Config, error) { | ||
cfg := &uiconfig.Config{} | ||
if configDir != "" { |
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.
one caveat: if a config directory is present, the new version will look for a "temporalite-ui.yaml" config file and the app will die with a "no config files found" error if a config file cannot be found.
Not the biggest fan of this caveat. It seems reasonable for some people to only want a Temporal config and still get the UI. A file check here is proably fine for now since we don't have a bunch of environments to configure.
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.
Ok, that makes sense.
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.
Update pushed, caveat removed.
caFile: dist/rootCA.pem | ||
certFile: dist/client.pem | ||
keyFile: dist/client-key.pem | ||
serverName: local.dev |
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.
Allow temporal web/ui to be configured from a yaml file so that the web UI does not break when the API is configured for mTLS.
I'm wondering if it would be possible to be smarter about this specific use case in Temporalite so that users don't have to create a UI specific config file as soon as they enable mTLS.
Would there be a way to detect that mTLS is enabled in Temporal's server config and then automatically configure the UI server connection options appropriately?
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.
Possibly, and that might be a thing for another PR. Enabling temporalite for mTLS is something that already requires a config file, so this feels like nothing new.
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.
Also, even though temporal-ui is run by this process, do we really want to have it use the same certificate to talk to the frontend? This is what we would have to do if we wanted to reuse the mTLS configuration from the temporal server. While that is technically possible, it feels weird & odd to have to set up mTLS for internode
and frontend
and then just have the UI reuse either one. That feels like a decision beyond 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.
👍 not a blocker; we still should be able to pass in a UI config file anyway. One day maybe we'll be able to do away with all ports in Temporalite other than frontend and the ui-server, which will make "internode" communication less weird since it's all a single process already.
I'm not too concerned about reuse as long as we add an easy readonly mode toggle for the UI.
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.
Approved, but want @jlegrone's approval too before merge
} | ||
if configDir != "" { | ||
if err := provider.Load(configDir, cfg, "temporalite-ui"); err != nil { | ||
if !strings.HasPrefix(err.Error(), "no config files found") { |
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.
Hrmm, would have liked to see if we could prevent the error instead of baking in expectations around its English message. I forget the config file loading whether it's easy to know what files to check for existence eagerly. But I guess it's not that bad since you have a unit test that confirms this conditional works.
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.
Ideally it would be great if the Load
function returned an error we can check for with errors.Is
since that is the best way of avoiding tedious string comparisons. I also wanted to avoid having to duplicate the file resolution algorithm applied by Load
. I reckon for now the unit test check will at least blow up if the algorithm changes or the error changes.
This could be done in a followup PR, but I'd love to add some documentation around enabling TLS and the web UI together. Perhaps in the internal/examples/mtls directory. |
@jlegrone I've not created any extra documentation, but this directory is used by |
@cretz the failed macos headless test passes locally on my mac. Not sure how to fix it for the PR since none of the code changed in the PR should have any effect on the test that broke. What am I missing?
|
What changed?
Two changes:
Why?
Temporalite is great, and I want to use it safely in situations where I'm experimenting with mTLS in temporal, especially while implementing mTLS in workers, without the UI being broken.
How did you test it?
Ran temporalite locally without any TLS, and with TLS certificates created by a self-signed root CA. The latter required the creation of temporalite.yaml and temporalite-ui.yaml files in a configuration directory, to allow mTLS to be set up for temporal API components, and allow the UI to make requests to the API via mTLS.
Updated the ui unit test to verify that it can still create a valid configuration when the temporalite-ui.yaml file is absent even though a config directory has been provided, and that it loads the file when it is present.
Updated the mtls test to verify proper integration between the UI and the API when mtls is enabled.
temporalite.yaml
temporalite-ui.yaml
Potential risks
Applications with existing command line configuration will still work as advertised.
Is hotfix candidate?
No.