Skip to content

Commit

Permalink
feat: add ssh tunneling to dynamic form for Database Connection UI (#…
Browse files Browse the repository at this point in the history
…22689)

Co-authored-by: Antonio Rivero Martinez <38889534+Antonio-RiveroMartnez@users.noreply.github.com>
Co-authored-by: Antonio Rivero <antonioriverocode@gmail.com>
Co-authored-by: Elizabeth Thompson <eschutho@gmail.com>
Co-authored-by: Lyndsi Kay Williams <55605634+lyndsiWilliams@users.noreply.github.com>
  • Loading branch information
5 people committed Jan 20, 2023
1 parent 13a186b commit b9686fe
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ const SSHTunnelForm = ({
db,
dbFetched,
isEditMode,
sshTunneling,
isSSHTunneling,
onSSHTunnelParametersChange,
setSSHTunnelLoginMethod,
removeSSHTunnelConfig,
}: {
db: DatabaseObject | null;
dbFetched: DatabaseObject | null;
isEditMode: boolean;
sshTunneling: boolean;
isSSHTunneling: boolean;
onSSHTunnelParametersChange: EventHandler<
ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
>;
Expand All @@ -81,7 +81,7 @@ const SSHTunnelForm = ({
<div css={(theme: SupersetTheme) => infoTooltip(theme)}>
<AntdSwitch
disabled={
!sshTunneling || (isEditMode && !isEmpty(dbFetched?.ssh_tunnel))
!isSSHTunneling || (isEditMode && !isEmpty(dbFetched?.ssh_tunnel))
}
checked={useSSHTunneling}
onChange={changed => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,41 @@ describe('DatabaseModal', () => {
});

describe('SSH Tunnel Form interaction', () => {
test('properly interacts with SSH Tunnel form textboxes for dynamic form', async () => {
userEvent.click(
screen.getByRole('button', {
name: /postgresql/i,
}),
);
expect(await screen.findByText(/step 2 of 3/i)).toBeInTheDocument();
const SSHTunnelingToggle = screen.getByTestId('ssh-tunnel-switch');
userEvent.click(SSHTunnelingToggle);
const SSHTunnelServerAddressInput = screen.getByTestId(
'ssh-tunnel-server_address-input',
);
expect(SSHTunnelServerAddressInput).toHaveValue('');
userEvent.type(SSHTunnelServerAddressInput, 'localhost');
expect(SSHTunnelServerAddressInput).toHaveValue('localhost');
const SSHTunnelServerPortInput = screen.getByTestId(
'ssh-tunnel-server_port-input',
);
expect(SSHTunnelServerPortInput).toHaveValue('');
userEvent.type(SSHTunnelServerPortInput, '22');
expect(SSHTunnelServerPortInput).toHaveValue('22');
const SSHTunnelUsernameInput = screen.getByTestId(
'ssh-tunnel-username-input',
);
expect(SSHTunnelUsernameInput).toHaveValue('');
userEvent.type(SSHTunnelUsernameInput, 'test');
expect(SSHTunnelUsernameInput).toHaveValue('test');
const SSHTunnelPasswordInput = screen.getByTestId(
'ssh-tunnel-password-input',
);
expect(SSHTunnelPasswordInput).toHaveValue('');
userEvent.type(SSHTunnelPasswordInput, 'pass');
expect(SSHTunnelPasswordInput).toHaveValue('pass');
});

test('properly interacts with SSH Tunnel form textboxes', async () => {
userEvent.click(
screen.getByRole('button', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ const ErrorAlertContainer = styled.div`
`};
`;

const SSHTunnelContainer = styled.div`
${({ theme }) => `
padding: 0px ${theme.gridUnit * 4}px;
`};
`;

interface DatabaseModalProps {
addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void;
Expand Down Expand Up @@ -549,7 +555,9 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
DB.backend === db?.engine || DB.engine === db?.engine,
) as DatabaseObject
)?.engine_information?.disable_ssh_tunneling;
const sshTunneling = isFeatureEnabled(FeatureFlag.SSH_TUNNELING);
const isSSHTunneling =
isFeatureEnabled(FeatureFlag.SSH_TUNNELING) &&
disableSSHTunnelingForEngine !== undefined;
const hasAlert =
connectionAlert || !!(db?.engine && engineSpecificAlertMapping[db.engine]);
const useSqlAlchemyForm =
Expand Down Expand Up @@ -1287,6 +1295,37 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
});
};

const renderSSHTunnelForm = () => (
<SSHTunnelForm
isEditMode={isEditMode}
isSSHTunneling={isSSHTunneling}
db={db as DatabaseObject}
dbFetched={dbFetched as DatabaseObject}
onSSHTunnelParametersChange={({
target,
}: {
target: HTMLInputElement | HTMLTextAreaElement;
}) =>
onChange(ActionType.parametersSSHTunnelChange, {
type: target.type,
name: target.name,
value: target.value,
})
}
setSSHTunnelLoginMethod={(method: AuthType) =>
setDB({
type: ActionType.setSSHTunnelLoginMethod,
payload: { login_method: method },
})
}
removeSSHTunnelConfig={() =>
setDB({
type: ActionType.removeSSHTunnelConfig,
})
}
/>
);

const renderCTABtns = () => (
<StyledBtns>
<Button
Expand Down Expand Up @@ -1493,36 +1532,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
testConnection={testConnection}
testInProgress={testInProgress}
>
{sshTunneling && !disableSSHTunnelingForEngine && (
<SSHTunnelForm
isEditMode={isEditMode}
sshTunneling={sshTunneling}
db={db as DatabaseObject}
dbFetched={dbFetched as DatabaseObject}
onSSHTunnelParametersChange={({
target,
}: {
target: HTMLInputElement | HTMLTextAreaElement;
}) =>
onChange(ActionType.parametersSSHTunnelChange, {
type: target.type,
name: target.name,
value: target.value,
})
}
setSSHTunnelLoginMethod={(method: AuthType) =>
setDB({
type: ActionType.setSSHTunnelLoginMethod,
payload: { login_method: method },
})
}
removeSSHTunnelConfig={() =>
setDB({
type: ActionType.removeSSHTunnelConfig,
})
}
/>
)}
{isSSHTunneling && renderSSHTunnelForm()}
</SqlAlchemyForm>
{isDynamic(db?.backend || db?.engine) && !isEditMode && (
<div css={(theme: SupersetTheme) => infoTooltip(theme)}>
Expand Down Expand Up @@ -1796,6 +1806,11 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
validationErrors={validationErrors}
getPlaceholder={getPlaceholder}
/>
{isSSHTunneling && (
<SSHTunnelContainer>
{renderSSHTunnelForm()}
</SSHTunnelContainer>
)}
<div css={(theme: SupersetTheme) => infoTooltip(theme)}>
{dbModel.engine !== Engines.GSheet && (
<>
Expand Down

0 comments on commit b9686fe

Please sign in to comment.