Skip to content

Commit 337565f

Browse files
committed
add missing SSH/SSL options in integration config forms
1 parent 3e5750d commit 337565f

File tree

18 files changed

+1207
-8
lines changed

18 files changed

+1207
-8
lines changed

src/messageTypes.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,15 @@ export type LocalizedMessages = {
313313
integrationsMongoDBConnectionStringLabel: string;
314314
integrationsMongoDBConnectionStringPlaceholder: string;
315315
integrationsMongoDBConnectionStringHelp: string;
316+
integrationsMongoDBOptionalFieldsNote: string;
317+
integrationsMongoDBRawConnectionStringLabel: string;
318+
integrationsMongoDBPrefixLabel: string;
319+
integrationsMongoDBHostLabel: string;
320+
integrationsMongoDBPortLabel: string;
321+
integrationsMongoDBUserLabel: string;
322+
integrationsMongoDBPasswordLabel: string;
323+
integrationsMongoDBDatabaseLabel: string;
324+
integrationsMongoDBOptionsLabel: string;
316325
// Redshift form strings
317326
integrationsRedshiftNameLabel: string;
318327
integrationsRedshiftNamePlaceholder: string;
@@ -416,6 +425,19 @@ export type LocalizedMessages = {
416425
integrationsTrinoUsernamePlaceholder: string;
417426
integrationsTrinoPasswordLabel: string;
418427
integrationsTrinoPasswordPlaceholder: string;
428+
// SSH options strings
429+
integrationsSshEnabled: string;
430+
integrationsSshHost: string;
431+
integrationsSshHostPlaceholder: string;
432+
integrationsSshPort: string;
433+
integrationsSshUser: string;
434+
integrationsSshUserPlaceholder: string;
435+
// SSL/CA certificate strings
436+
integrationsSslEnabled: string;
437+
integrationsCaCertificateName: string;
438+
integrationsCaCertificateNamePlaceholder: string;
439+
integrationsCaCertificateText: string;
440+
integrationsCaCertificateTextPlaceholder: string;
419441
// Common form strings
420442
integrationsRequiredField: string;
421443
integrationsOptionalField: string;

src/notebooks/deepnote/integrations/integrationWebview.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,15 @@ export class IntegrationWebviewProvider implements IIntegrationWebviewProvider {
256256
integrationsMongoDBConnectionStringLabel: localize.Integrations.mongoDBConnectionStringLabel,
257257
integrationsMongoDBConnectionStringPlaceholder: localize.Integrations.mongoDBConnectionStringPlaceholder,
258258
integrationsMongoDBConnectionStringHelp: localize.Integrations.mongoDBConnectionStringHelp,
259+
integrationsMongoDBOptionalFieldsNote: localize.Integrations.mongoDBOptionalFieldsNote,
260+
integrationsMongoDBRawConnectionStringLabel: localize.Integrations.mongoDBRawConnectionStringLabel,
261+
integrationsMongoDBPrefixLabel: localize.Integrations.mongoDBPrefixLabel,
262+
integrationsMongoDBHostLabel: localize.Integrations.mongoDBHostLabel,
263+
integrationsMongoDBPortLabel: localize.Integrations.mongoDBPortLabel,
264+
integrationsMongoDBUserLabel: localize.Integrations.mongoDBUserLabel,
265+
integrationsMongoDBPasswordLabel: localize.Integrations.mongoDBPasswordLabel,
266+
integrationsMongoDBDatabaseLabel: localize.Integrations.mongoDBDatabaseLabel,
267+
integrationsMongoDBOptionsLabel: localize.Integrations.mongoDBOptionsLabel,
259268
integrationsRedshiftNameLabel: localize.Integrations.redshiftNameLabel,
260269
integrationsRedshiftNamePlaceholder: localize.Integrations.redshiftNamePlaceholder,
261270
integrationsRedshiftAuthMethodLabel: localize.Integrations.redshiftAuthMethodLabel,
@@ -352,6 +361,17 @@ export class IntegrationWebviewProvider implements IIntegrationWebviewProvider {
352361
integrationsTrinoUsernamePlaceholder: localize.Integrations.trinoUsernamePlaceholder,
353362
integrationsTrinoPasswordLabel: localize.Integrations.trinoPasswordLabel,
354363
integrationsTrinoPasswordPlaceholder: localize.Integrations.trinoPasswordPlaceholder,
364+
integrationsSshEnabled: localize.Integrations.sshEnabled,
365+
integrationsSshHost: localize.Integrations.sshHost,
366+
integrationsSshHostPlaceholder: localize.Integrations.sshHostPlaceholder,
367+
integrationsSshPort: localize.Integrations.sshPort,
368+
integrationsSshUser: localize.Integrations.sshUser,
369+
integrationsSshUserPlaceholder: localize.Integrations.sshUserPlaceholder,
370+
integrationsSslEnabled: localize.Integrations.sslEnabled,
371+
integrationsCaCertificateName: localize.Integrations.caCertificateName,
372+
integrationsCaCertificateNamePlaceholder: localize.Integrations.caCertificateNamePlaceholder,
373+
integrationsCaCertificateText: localize.Integrations.caCertificateText,
374+
integrationsCaCertificateTextPlaceholder: localize.Integrations.caCertificateTextPlaceholder,
355375
integrationsUnnamedIntegration: localize.Integrations.unnamedIntegration('{0}'),
356376
integrationsUnsupportedIntegrationType: localize.Integrations.unsupportedIntegrationType('{0}')
357377
};

src/platform/common/utils/localize.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,17 @@ export namespace Integrations {
989989
export const mongoDBConnectionStringHelp = l10n.t(
990990
'Enter your MongoDB connection string. Example: mongodb://user:pass@host:27017/mydb or mongodb+srv://user:pass@cluster.mongodb.net/mydb'
991991
);
992+
export const mongoDBOptionalFieldsNote = l10n.t(
993+
'The following fields are optional and redundant with the connection string. They create environment variables for use in your code.'
994+
);
995+
export const mongoDBRawConnectionStringLabel = l10n.t('Raw Connection String (optional)');
996+
export const mongoDBPrefixLabel = l10n.t('Prefix (optional)');
997+
export const mongoDBHostLabel = l10n.t('Host (optional)');
998+
export const mongoDBPortLabel = l10n.t('Port (optional)');
999+
export const mongoDBUserLabel = l10n.t('User (optional)');
1000+
export const mongoDBPasswordLabel = l10n.t('Password (optional)');
1001+
export const mongoDBDatabaseLabel = l10n.t('Database (optional)');
1002+
export const mongoDBOptionsLabel = l10n.t('Options (optional)');
9921003

9931004
// Redshift form strings
9941005
export const redshiftNameLabel = l10n.t('Name (optional)');
@@ -1108,6 +1119,21 @@ export namespace Integrations {
11081119
export const trinoUsernamePlaceholder = l10n.t('username');
11091120
export const trinoPasswordLabel = l10n.t('Password');
11101121
export const trinoPasswordPlaceholder = l10n.t('••••••••');
1122+
1123+
// SSH options strings
1124+
export const sshEnabled = l10n.t('Enable SSH Tunnel');
1125+
export const sshHost = l10n.t('SSH Host');
1126+
export const sshHostPlaceholder = l10n.t('ssh.example.com');
1127+
export const sshPort = l10n.t('SSH Port');
1128+
export const sshUser = l10n.t('SSH User');
1129+
export const sshUserPlaceholder = l10n.t('ubuntu');
1130+
1131+
// SSL/CA certificate strings
1132+
export const sslEnabled = l10n.t('Enable SSL');
1133+
export const caCertificateName = l10n.t('CA Certificate Name');
1134+
export const caCertificateNamePlaceholder = l10n.t('my-ca-certificate');
1135+
export const caCertificateText = l10n.t('CA Certificate (PEM)');
1136+
export const caCertificateTextPlaceholder = l10n.t('-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----');
11111137
}
11121138

11131139
export namespace SelectInputSettings {

src/webviews/webview-side/integrations/AlloyDBForm.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as React from 'react';
22
import { format, getLocString } from '../react-common/locReactSide';
33
import { DatabaseIntegrationConfig } from '@deepnote/database-integrations';
4+
import { SshOptionsFields } from './SshOptionsFields';
5+
import { CaCertificateFields } from './CaCertificateFields';
46

57
export interface IAlloyDBFormProps {
68
integrationId: string;
@@ -94,6 +96,55 @@ export const AlloyDBForm: React.FC<IAlloyDBFormProps> = ({
9496
});
9597
};
9698

99+
const handleSshEnabledChange = (enabled: boolean) => {
100+
setPendingConfig({
101+
...pendingConfig,
102+
metadata: { ...pendingConfig.metadata, sshEnabled: enabled || undefined }
103+
});
104+
};
105+
106+
const handleSshHostChange = (host: string) => {
107+
setPendingConfig({
108+
...pendingConfig,
109+
metadata: { ...pendingConfig.metadata, sshHost: host || undefined }
110+
});
111+
};
112+
113+
const handleSshPortChange = (port: string) => {
114+
setPendingConfig({
115+
...pendingConfig,
116+
metadata: { ...pendingConfig.metadata, sshPort: port || undefined }
117+
});
118+
};
119+
120+
const handleSshUserChange = (user: string) => {
121+
setPendingConfig({
122+
...pendingConfig,
123+
metadata: { ...pendingConfig.metadata, sshUser: user || undefined }
124+
});
125+
};
126+
127+
const handleSslEnabledChange = (enabled: boolean) => {
128+
setPendingConfig({
129+
...pendingConfig,
130+
metadata: { ...pendingConfig.metadata, sslEnabled: enabled || undefined }
131+
});
132+
};
133+
134+
const handleCaCertificateNameChange = (name: string) => {
135+
setPendingConfig({
136+
...pendingConfig,
137+
metadata: { ...pendingConfig.metadata, caCertificateName: name || undefined }
138+
});
139+
};
140+
141+
const handleCaCertificateTextChange = (text: string) => {
142+
setPendingConfig({
143+
...pendingConfig,
144+
metadata: { ...pendingConfig.metadata, caCertificateText: text || undefined }
145+
});
146+
};
147+
97148
return (
98149
<form onSubmit={handleSubmit}>
99150
<div className="form-group">
@@ -184,6 +235,28 @@ export const AlloyDBForm: React.FC<IAlloyDBFormProps> = ({
184235
/>
185236
</div>
186237

238+
<SshOptionsFields
239+
sshEnabled={pendingConfig.metadata.sshEnabled}
240+
sshHost={pendingConfig.metadata.sshHost}
241+
sshPort={pendingConfig.metadata.sshPort}
242+
sshUser={pendingConfig.metadata.sshUser}
243+
onSshEnabledChange={handleSshEnabledChange}
244+
onSshHostChange={handleSshHostChange}
245+
onSshPortChange={handleSshPortChange}
246+
onSshUserChange={handleSshUserChange}
247+
/>
248+
249+
<CaCertificateFields
250+
sslEnabled={pendingConfig.metadata.sslEnabled}
251+
caCertificateName={pendingConfig.metadata.caCertificateName}
252+
caCertificateText={pendingConfig.metadata.caCertificateText}
253+
onSslEnabledChange={handleSslEnabledChange}
254+
onCaCertificateNameChange={handleCaCertificateNameChange}
255+
onCaCertificateTextChange={handleCaCertificateTextChange}
256+
showSslEnabled={true}
257+
showCertificateText={true}
258+
/>
259+
187260
<div className="form-actions">
188261
<button type="button" className="secondary" onClick={onCancel}>
189262
{getLocString('integrationsCancel', 'Cancel')}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import * as React from 'react';
2+
import { getLocString } from '../react-common/locReactSide';
3+
4+
export interface ICaCertificateFieldsProps {
5+
sslEnabled?: boolean;
6+
caCertificateName?: string;
7+
caCertificateText?: string;
8+
onSslEnabledChange?: (enabled: boolean) => void;
9+
onCaCertificateNameChange: (name: string) => void;
10+
onCaCertificateTextChange?: (text: string) => void;
11+
/** Whether to show the SSL enabled checkbox (default: true) */
12+
showSslEnabled?: boolean;
13+
/** Whether to show the certificate text field (default: true) */
14+
showCertificateText?: boolean;
15+
}
16+
17+
export const CaCertificateFields: React.FC<ICaCertificateFieldsProps> = ({
18+
sslEnabled,
19+
caCertificateName,
20+
caCertificateText,
21+
onSslEnabledChange,
22+
onCaCertificateNameChange,
23+
onCaCertificateTextChange,
24+
showSslEnabled = true,
25+
showCertificateText = true
26+
}) => {
27+
return (
28+
<>
29+
{showSslEnabled && onSslEnabledChange && (
30+
<div className="form-group">
31+
<label>
32+
<input
33+
type="checkbox"
34+
checked={sslEnabled || false}
35+
onChange={(e) => onSslEnabledChange(e.target.checked)}
36+
/>
37+
{' '}
38+
{getLocString('integrationsSslEnabled', 'Enable SSL')}
39+
</label>
40+
</div>
41+
)}
42+
43+
{(!showSslEnabled || sslEnabled) && (
44+
<>
45+
<div className="form-group">
46+
<label htmlFor="caCertificateName">
47+
{getLocString('integrationsCaCertificateName', 'CA Certificate Name')}
48+
</label>
49+
<input
50+
type="text"
51+
id="caCertificateName"
52+
value={caCertificateName || ''}
53+
onChange={(e) => onCaCertificateNameChange(e.target.value)}
54+
placeholder={getLocString(
55+
'integrationsCaCertificateNamePlaceholder',
56+
'my-ca-certificate'
57+
)}
58+
autoComplete="off"
59+
/>
60+
</div>
61+
62+
{showCertificateText && onCaCertificateTextChange && (
63+
<div className="form-group">
64+
<label htmlFor="caCertificateText">
65+
{getLocString('integrationsCaCertificateText', 'CA Certificate (PEM)')}
66+
</label>
67+
<textarea
68+
id="caCertificateText"
69+
value={caCertificateText || ''}
70+
onChange={(e) => onCaCertificateTextChange(e.target.value)}
71+
placeholder={getLocString(
72+
'integrationsCaCertificateTextPlaceholder',
73+
'-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----'
74+
)}
75+
rows={6}
76+
autoComplete="off"
77+
/>
78+
</div>
79+
)}
80+
</>
81+
)}
82+
</>
83+
);
84+
};
85+

src/webviews/webview-side/integrations/ClickHouseForm.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as React from 'react';
22
import { format, getLocString } from '../react-common/locReactSide';
33
import { DatabaseIntegrationConfig } from '@deepnote/database-integrations';
4+
import { SshOptionsFields } from './SshOptionsFields';
5+
import { CaCertificateFields } from './CaCertificateFields';
46

57
export interface IClickHouseFormProps {
68
integrationId: string;
@@ -95,6 +97,55 @@ export const ClickHouseForm: React.FC<IClickHouseFormProps> = ({
9597
});
9698
};
9799

100+
const handleSshEnabledChange = (enabled: boolean) => {
101+
setPendingConfig({
102+
...pendingConfig,
103+
metadata: { ...pendingConfig.metadata, sshEnabled: enabled || undefined }
104+
});
105+
};
106+
107+
const handleSshHostChange = (host: string) => {
108+
setPendingConfig({
109+
...pendingConfig,
110+
metadata: { ...pendingConfig.metadata, sshHost: host || undefined }
111+
});
112+
};
113+
114+
const handleSshPortChange = (port: string) => {
115+
setPendingConfig({
116+
...pendingConfig,
117+
metadata: { ...pendingConfig.metadata, sshPort: port || undefined }
118+
});
119+
};
120+
121+
const handleSshUserChange = (user: string) => {
122+
setPendingConfig({
123+
...pendingConfig,
124+
metadata: { ...pendingConfig.metadata, sshUser: user || undefined }
125+
});
126+
};
127+
128+
const handleSslEnabledChange = (enabled: boolean) => {
129+
setPendingConfig({
130+
...pendingConfig,
131+
metadata: { ...pendingConfig.metadata, sslEnabled: enabled || undefined }
132+
});
133+
};
134+
135+
const handleCaCertificateNameChange = (name: string) => {
136+
setPendingConfig({
137+
...pendingConfig,
138+
metadata: { ...pendingConfig.metadata, caCertificateName: name || undefined }
139+
});
140+
};
141+
142+
const handleCaCertificateTextChange = (text: string) => {
143+
setPendingConfig({
144+
...pendingConfig,
145+
metadata: { ...pendingConfig.metadata, caCertificateText: text || undefined }
146+
});
147+
};
148+
98149
return (
99150
<form onSubmit={handleSubmit}>
100151
<div className="form-group">
@@ -181,6 +232,28 @@ export const ClickHouseForm: React.FC<IClickHouseFormProps> = ({
181232
/>
182233
</div>
183234

235+
<SshOptionsFields
236+
sshEnabled={pendingConfig.metadata.sshEnabled}
237+
sshHost={pendingConfig.metadata.sshHost}
238+
sshPort={pendingConfig.metadata.sshPort}
239+
sshUser={pendingConfig.metadata.sshUser}
240+
onSshEnabledChange={handleSshEnabledChange}
241+
onSshHostChange={handleSshHostChange}
242+
onSshPortChange={handleSshPortChange}
243+
onSshUserChange={handleSshUserChange}
244+
/>
245+
246+
<CaCertificateFields
247+
sslEnabled={pendingConfig.metadata.sslEnabled}
248+
caCertificateName={pendingConfig.metadata.caCertificateName}
249+
caCertificateText={pendingConfig.metadata.caCertificateText}
250+
onSslEnabledChange={handleSslEnabledChange}
251+
onCaCertificateNameChange={handleCaCertificateNameChange}
252+
onCaCertificateTextChange={handleCaCertificateTextChange}
253+
showSslEnabled={true}
254+
showCertificateText={true}
255+
/>
256+
184257
<div className="form-actions">
185258
<button type="button" className="secondary" onClick={onCancel}>
186259
{getLocString('integrationsCancel', 'Cancel')}

0 commit comments

Comments
 (0)