Skip to content

docs: Better documentation of trusting SSL certs#215

Merged
bmingles merged 4 commits intomainfrom
DH-18191-2_logs-and-docs
Feb 6, 2025
Merged

docs: Better documentation of trusting SSL certs#215
bmingles merged 4 commits intomainfrom
DH-18191-2_logs-and-docs

Conversation

@bmingles
Copy link
Collaborator

@bmingles bmingles commented Feb 4, 2025

DH-18191: Better documentation of trusting SSL certs

NodeJS doesn't use the OS cert store to determine which signing certificates it trusts. Instead, it has a static list of trusted certs included in the install. For certificates not in this list, there is a NODE_EXTRA_CA_CERTS environment variable that can be set to tell NodeJS about additional certs to trust. This PR updates the docs with instructions of how to set this.

Note there is some indication that extensions may eventually allow using Chrome's fetch. If / when that happens, it might be possible to use that for Deephaven extension instead of our current grpc transport implementation that uses node:http2 module. This could allow extensions to use the OS cert store instead of this env variable.
microsoft/vscode#12588 (comment)

@github-actions
Copy link

github-actions bot commented Feb 4, 2025

End-to-end Test Summary

Tests 📝Passed ✅Failed ❌Skipped ⏭️Pending ⏳Other ❓Flaky 🍂Duration ⏱️
660000004:58:34
A ctrf plugin

Detailed Test Results

NameStatusmsFlaky 🍂
should default to the correct settingspassed ✅1948
should return custom settings: Empty configspassed ✅475
should return custom settings: Populated configspassed ✅117
should be able to load VSCodepassed ✅1004
should only be visible when a supported file type is active: test.groovypassed ✅2775
should only be visible when a supported file type is active: test.pypassed ✅955
A ctrf plugin

Failed Test Summary

No failed tests ✨

Flaky Test Summary

No flaky tests detected. ✨

@github-actions
Copy link

github-actions bot commented Feb 4, 2025

Unit Test Summary

Tests 📝Passed ✅Failed ❌Skipped ⏭️Pending ⏳Other ❓Flaky 🍂Duration ⏱️
1191190000000:00:00
A ctrf plugin

Detailed Test Results

NameStatusmsFlaky 🍂
src/services/ConfigService.spec.ts: getCoreServers > should return core servers: Empty configpassed ✅2
src/services/ConfigService.spec.ts: getCoreServers > should return core servers: String configpassed ✅0
src/services/ConfigService.spec.ts: getCoreServers > should return core servers: No labelpassed ✅1
src/services/ConfigService.spec.ts: getCoreServers > should return core servers: Full configpassed ✅0
src/services/ConfigService.spec.ts: getEnterpriseServers > should return enterprise servers: Empty configpassed ✅0
src/services/ConfigService.spec.ts: getEnterpriseServers > should return enterprise servers: String configpassed ✅1
src/services/PollingService.spec.ts: pollUntilTrue > should resolve when poll function returns truepassed ✅7
src/services/PollingService.spec.ts: pollUntilTrue > should cancel polling if timeout exceededpassed ✅3
src/services/PollingService.spec.ts: pollUntilTrue > should cancel polling if cancel explicitly calledpassed ✅0
src/services/SerializedKeyMap.spec.ts: SerializedKeyMap > should key data by value equalitypassed ✅2
src/services/SerializedKeyMap.spec.ts: SerializedKeyMap > entries > should provide value equality entriespassed ✅2
src/services/SerializedKeyMap.spec.ts: SerializedKeyMap > keys > should provide value equality keyspassed ✅0
src/services/SerializedKeyMap.spec.ts: SerializedKeyMap > forEach > should pass value equality keys to callback: undefinedpassed ✅1
src/services/SerializedKeyMap.spec.ts: SerializedKeyMap > forEach > should pass value equality keys to callback: {}passed ✅1
src/services/SerializedKeyMap.spec.ts: SerializedKeyMap > values > should provide valuespassed ✅1
src/util/assertUtil.spec.ts: assertDefined > should not throw if value is defined: {}passed ✅1
src/util/assertUtil.spec.ts: assertDefined > should not throw if value is defined: testpassed ✅1
src/util/assertUtil.spec.ts: assertDefined > should not throw if value is defined: 999passed ✅0
src/util/assertUtil.spec.ts: assertDefined > should not throw if value is defined: truepassed ✅0
src/util/assertUtil.spec.ts: assertDefined > should not throw if value is defined: falsepassed ✅0
src/util/assertUtil.spec.ts: assertDefined > should not throw if value is defined: 2025-02-04T23:38:46.474Zpassed ✅0
src/util/assertUtil.spec.ts: assertDefined > should throw an error for null or undefined values: nullpassed ✅1
src/util/assertUtil.spec.ts: assertDefined > should throw an error for null or undefined values: undefinedpassed ✅0
src/util/promiseUtils.spec.ts: waitFor > should return a Promise that resolves after a given timeoutpassed ✅4
src/util/promiseUtils.spec.ts: withResolvers > should return a promise that resolves when resolve function is calledpassed ✅2
src/util/promiseUtils.spec.ts: withResolvers > should return a promise that rejects when reject function is calledpassed ✅1
src/util/serverUtils.spec.ts: getInitialServerStates > should derive server states from configpassed ✅4
src/util/serverUtils.spec.ts: getPipServerUrl > should return a localhost url based on given portpassed ✅1
src/util/serverUtils.spec.ts: parsePort > should parse port from stringpassed ✅0
src/util/serverUtils.spec.ts: parsePort > should throw error when port is not a numberpassed ✅1
src/util/tmpUtils.spec.ts: getTempDir > should create temp directory if it does not already exist: true, undefinedpassed ✅3
src/util/tmpUtils.spec.ts: getTempDir > should create temp directory if it does not already exist: true, subDirectorypassed ✅0
src/util/tmpUtils.spec.ts: getTempDir > should create temp directory if it does not already exist: false, undefinedpassed ✅1
src/util/tmpUtils.spec.ts: getTempDir > should create temp directory if it does not already exist: false, subDirectorypassed ✅0
src/util/tmpUtils.spec.ts: getTempDir > should remove directory if recreate is true: true, undefined, /home/runner/work/vscode-deephaven/vscode-deephaven/src/common/tmppassed ✅1
src/util/tmpUtils.spec.ts: getTempDir > should remove directory if recreate is true: true, subDirectory, /home/runner/work/vscode-deephaven/vscode-deephaven/src/common/tmp/subDirectorypassed ✅1
src/util/tmpUtils.spec.ts: getTempDir > should remove directory if recreate is true: false, undefined, /home/runner/work/vscode-deephaven/vscode-deephaven/src/common/tmppassed ✅0
src/util/tmpUtils.spec.ts: getTempDir > should remove directory if recreate is true: false, subDirectory, /home/runner/work/vscode-deephaven/vscode-deephaven/src/common/tmp/subDirectorypassed ✅1
src/util/treeViewUtils.spec.ts: getPanelConnectionTreeItem > should return panel connection tree item: isConnected:true, isInitialized:truepassed ✅3
src/util/treeViewUtils.spec.ts: getPanelConnectionTreeItem > should return panel connection tree item: isConnected:true, isInitialized:falsepassed ✅0
src/util/treeViewUtils.spec.ts: getPanelConnectionTreeItem > should return panel connection tree item: isConnected:false, isInitialized:truepassed ✅0
src/util/treeViewUtils.spec.ts: getPanelConnectionTreeItem > should return panel connection tree item: isConnected:false, isInitialized:falsepassed ✅0
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:deephaven.plot.express.DeephavenFigurepassed ✅0
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:deephaven.ui.Elementpassed ✅1
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:Figurepassed ✅0
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:HierarchicalTablepassed ✅0
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:OtherWidgetpassed ✅1
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:pandas.DataFramepassed ✅0
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:PartitionedTablepassed ✅0
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:Tablepassed ✅1
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:TableMappassed ✅0
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:Treemappassed ✅0
src/util/treeViewUtils.spec.ts: getPanelVariableTreeItem > should return panel variable tree item: type:TreeTablepassed ✅0
src/util/treeViewUtils.spec.ts: getServerContextValue > should return contextValue based on server state: isConnected=true, isManaged=true, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerContextValue > should return contextValue based on server state: isConnected=true, isManaged=true, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerContextValue > should return contextValue based on server state: isConnected=true, isManaged=false, isRunning=truepassed ✅1
src/util/treeViewUtils.spec.ts: getServerContextValue > should return contextValue based on server state: isConnected=true, isManaged=false, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerContextValue > should return contextValue based on server state: isConnected=false, isManaged=true, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerContextValue > should return contextValue based on server state: isConnected=false, isManaged=true, isRunning=falsepassed ✅1
src/util/treeViewUtils.spec.ts: getServerContextValue > should return contextValue based on server state: isConnected=false, isManaged=false, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerContextValue > should return contextValue based on server state: isConnected=false, isManaged=false, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerDescription > should return server description based on parameters: connectionCount=0, isManaged=true, label=some labelpassed ✅0
src/util/treeViewUtils.spec.ts: getServerDescription > should return server description based on parameters: connectionCount=0, isManaged=true, label=undefinedpassed ✅1
src/util/treeViewUtils.spec.ts: getServerDescription > should return server description based on parameters: connectionCount=0, isManaged=false, label=some labelpassed ✅0
src/util/treeViewUtils.spec.ts: getServerDescription > should return server description based on parameters: connectionCount=0, isManaged=false, label=undefinedpassed ✅0
src/util/treeViewUtils.spec.ts: getServerDescription > should return server description based on parameters: connectionCount=1, isManaged=true, label=some labelpassed ✅0
src/util/treeViewUtils.spec.ts: getServerDescription > should return server description based on parameters: connectionCount=1, isManaged=true, label=undefinedpassed ✅0
src/util/treeViewUtils.spec.ts: getServerDescription > should return server description based on parameters: connectionCount=1, isManaged=false, label=some labelpassed ✅0
src/util/treeViewUtils.spec.ts: getServerDescription > should return server description based on parameters: connectionCount=1, isManaged=false, label=undefinedpassed ✅0
src/util/treeViewUtils.spec.ts: getServerGroupContextValue > should return context value when servers can be managed: group=Managed, canStartServer=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerGroupContextValue > should return context value when servers can be managed: group=Managed, canStartServer=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerGroupContextValue > should return context value when servers can be managed: group=Running, canStartServer=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerGroupContextValue > should return context value when servers can be managed: group=Running, canStartServer=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerGroupTreeItem > should return server group tree item: group=Managed, canStartServer=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerGroupTreeItem > should return server group tree item: group=Managed, canStartServer=falsepassed ✅1
src/util/treeViewUtils.spec.ts: getServerGroupTreeItem > should return server group tree item: group=Running, canStartServer=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerGroupTreeItem > should return server group tree item: group=Running, canStartServer=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerIconID > should return icon id based on server state: isConnected=true, isManaged=true, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerIconID > should return icon id based on server state: isConnected=true, isManaged=true, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerIconID > should return icon id based on server state: isConnected=true, isManaged=false, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerIconID > should return icon id based on server state: isConnected=true, isManaged=false, isRunning=falsepassed ✅1
src/util/treeViewUtils.spec.ts: getServerIconID > should return icon id based on server state: isConnected=false, isManaged=true, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerIconID > should return icon id based on server state: isConnected=false, isManaged=true, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerIconID > should return icon id based on server state: isConnected=false, isManaged=false, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerIconID > should return icon id based on server state: isConnected=false, isManaged=false, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHC, isConnected=true, isManaged=true, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHC, isConnected=true, isManaged=true, isRunning=falsepassed ✅1
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHC, isConnected=true, isManaged=false, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHC, isConnected=true, isManaged=false, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHC, isConnected=false, isManaged=true, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHC, isConnected=false, isManaged=true, isRunning=falsepassed ✅1
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHC, isConnected=false, isManaged=false, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHC, isConnected=false, isManaged=false, isRunning=falsepassed ✅2
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHE, isConnected=true, isManaged=true, isRunning=truepassed ✅1
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHE, isConnected=true, isManaged=true, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHE, isConnected=true, isManaged=false, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHE, isConnected=true, isManaged=false, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHE, isConnected=false, isManaged=true, isRunning=truepassed ✅1
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHE, isConnected=false, isManaged=true, isRunning=falsepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHE, isConnected=false, isManaged=false, isRunning=truepassed ✅0
src/util/treeViewUtils.spec.ts: getServerTreeItem > should return server tree item: type=DHE, isConnected=false, isManaged=false, isRunning=falsepassed ✅1
src/util/treeViewUtils.spec.ts: getVariableIconPath > should return icon path for variableTypepassed ✅0
src/util/treeViewUtils.spec.ts: groupServers > should group servers by statepassed ✅1
src/util/uiUtils.spec.ts: createConnectionOption > should return connection option: 'DHC', { label: 'python', url: URL{} }passed ✅3
src/util/uiUtils.spec.ts: createConnectionOption > should return connection option: 'DHC', { label: 'groovy', url: URL{} }passed ✅1
src/util/uiUtils.spec.ts: createConnectionQuickPickOptions > should return quick pick options: editorActiveConnectionUrl=No activepassed ✅13
src/util/uiUtils.spec.ts: createConnectionQuickPickOptions > should return quick pick options: editorActiveConnectionUrl=Active Apassed ✅1
src/util/uiUtils.spec.ts: createConnectionQuickPickOptions > should throw if no servers or connectionspassed ✅1
src/util/uiUtils.spec.ts: createConnectText > should return text and tooltip: 'connecting'passed ✅0
src/util/uiUtils.spec.ts: createConnectText > should return text and tooltip: 'connected'passed ✅0
src/util/uiUtils.spec.ts: createConnectText > should return text and tooltip: 'disconnected'passed ✅1
src/util/uiUtils.spec.ts: updateConnectionStatusBarItem > should update connection status bar item: 'connecting'passed ✅0
src/util/uiUtils.spec.ts: updateConnectionStatusBarItem > should update connection status bar item: 'connected'passed ✅1
src/util/uiUtils.spec.ts: updateConnectionStatusBarItem > should update connection status bar item: 'disconnected'passed ✅0
src/util/uiUtils.spec.ts: createSeparatorPickItem > should create a separator quick pick item with labelpassed ✅2
src/util/urlUtils.spec.ts: urlUtils > should convert url to host_port string: http://localhost:4000, localhost_4000passed ✅2
src/util/urlUtils.spec.ts: urlUtils > should convert url to host_port string: https://localhost:5000, localhost_5000passed ✅0
src/util/urlUtils.spec.ts: urlUtils > should convert url to host_port string: http://www.acme.com:6000, www_acme_com_6000passed ✅0
src/util/urlUtils.spec.ts: urlUtils > should convert url to host_port string: https://www.acme.com:7000, www_acme_com_7000passed ✅0
A ctrf plugin

Failed Test Summary

No failed tests ✨

Flaky Test Summary

No flaky tests detected. ✨

@bmingles bmingles requested a review from mofojed February 4, 2025 23:09
Copy link
Member

@mofojed mofojed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a little more context to the PR description.

In particular, I think it's important we put the ticket number for VS Code tracking this.

In their documentation: https://code.visualstudio.com/docs/setup/network#_legacy-proxy-server-support

Extensions don't benefit yet from the same proxy support that VS Code supports. You can follow this issue's development in GitHub.

And the issue itself has some information on their efforts: microsoft/vscode#12588

Deephaven servers using self-signed certificates or internal CA's will require configuring VS Code to trust the signing certificate.

1. Save the signing certificate in PEM format somewhere on the machine running VS Code. Multiple certificates can be concatenated together in the same file if there are multiple certs that need to be configured.
1. Set the `NODE_EXTRA_CA_CERTS` environment variable to the path of the signing certificate.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Set the `NODE_EXTRA_CA_CERTS` environment variable to the path of the signing certificate.
2. Set the `NODE_EXTRA_CA_CERTS` environment variable to the path of the signing certificate.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mofojed Is this change necessary? Markdown rendererer "should" auto number these.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does auto number them, was a nitpick.

setx NODE_EXTRA_CA_CERTS C:\Path\To\cert.pem
```
> Note that paths in env variables should not be wrapped in quotes on Windows.
1. Start VS Code in a shell that has the `NODE_EXTRA_CA_CERTS` variable set.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Start VS Code in a shell that has the `NODE_EXTRA_CA_CERTS` variable set.
3. Start VS Code in a shell that has the `NODE_EXTRA_CA_CERTS` variable set.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, Markdown supports numbering as 1. 1. 1. ... and auto increments. Makes it easier to insert / re-order in the future without modifying every line.

@bmingles
Copy link
Collaborator Author

bmingles commented Feb 5, 2025

Add a little more context to the PR description.

In particular, I think it's important we put the ticket number for VS Code tracking this.

In their documentation: https://code.visualstudio.com/docs/setup/network#_legacy-proxy-server-support

Extensions don't benefit yet from the same proxy support that VS Code supports. You can follow this issue's development in GitHub.

And the issue itself has some information on their efforts: microsoft/vscode#12588

@mofojed I'm not sure this is directly related to proxy support. It's a NodeJs nuance of trusting SSL certificates. Even if there is no proxy involved, a signing cert that is not included in the NodeJS install won't be trusted without this config.

I've updated the PR description with some more context.

@mofojed
Copy link
Member

mofojed commented Feb 5, 2025

@bmingles Okay I found one comment on that linked issue though that seems interesting: microsoft/vscode#12588 (comment)

Work is under way to make Chromium's implementation of fetch available to extensions. This issue is unlikely to be closed soon though, as many extensions are using Node's https module for which we have only partial support for proxies. Only proxies without auth and with Kerberos auth are supported at the moment.

Sounds like if they provided that fetch, we could just use that and be good

@bmingles
Copy link
Collaborator Author

bmingles commented Feb 5, 2025

@mofojed I've added a reference to that comment in the PR description. I also added a comment to that issue to see if anyone can provide a more direct link to Chrome fetch support. I'll update the PR description if / when I get a response.

@bmingles bmingles requested a review from mofojed February 5, 2025 16:36
@bmingles bmingles requested a review from arman-ddl February 5, 2025 19:16
@bmingles bmingles merged commit 75c2e15 into main Feb 6, 2025
6 checks passed
@bmingles bmingles deleted the DH-18191-2_logs-and-docs branch February 6, 2025 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants