},
WebDAVDownload: {
ExternalURL: string
+ },
+ WebShell: {
+ ExternalURL: string
}
};
Workbench: {
FileViewersConfigURL: string;
WelcomePageHTML: string;
InactivePageHTML: string;
+ SSHHelpPageHTML: string;
SiteName: string;
};
Login: {
Websocket: { ExternalURL: "" },
WebDAV: { ExternalURL: "" },
WebDAVDownload: { ExternalURL: "" },
+ WebShell: { ExternalURL: "" },
},
Workbench: {
ArvadosDocsite: "",
FileViewersConfigURL: "",
WelcomePageHTML: "",
InactivePageHTML: "",
+ SSHHelpPageHTML: "",
SiteName: "",
},
Login: {
}
export const WarningComponent = ({ text, rules, message }: WarningComponentProps) =>
- rules.find(aRule => text.match(aRule) !== null)
- ? message
- ? <Tooltip title={message}><ErrorIcon /></Tooltip>
- : <ErrorIcon />
- : null;
+ !text ? <Tooltip title={"No name"}><ErrorIcon /></Tooltip>
+ : (rules.find(aRule => text.match(aRule) !== null)
+ ? message
+ ? <Tooltip title={message}><ErrorIcon /></Tooltip>
+ : <ErrorIcon />
+ : null);
interface IllegalNamingWarningProps {
name: string;
groupVirtualMachine: string;
}
+export interface SetupShellAccountFormDialogData {
+ email: string;
+ virtualMachineName: string;
+ groupVirtualMachine: string;
+}
+
export const openUserAttributes = (uuid: string) =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
const { resources } = getState();
}
};
+
+export const setupUserVM = (setupData: SetupShellAccountFormDialogData) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ dispatch(startSubmit(USER_CREATE_FORM_NAME));
+ try {
+ // TODO: make correct API call
+ // const setupResult = await services.userService.setup({ ...setupData });
+ dispatch(dialogActions.CLOSE_DIALOG({ id: SETUP_SHELL_ACCOUNT_DIALOG }));
+ dispatch(reset(SETUP_SHELL_ACCOUNT_DIALOG));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: "User has been added to VM.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
+ dispatch<any>(loadUsersPanel());
+ dispatch(userBindedActions.REQUEST_ITEMS());
+ } catch (e) {
+ return;
+ }
+ };
+
export const openUserPanel = () =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
const user = getState().auth.user;
export const SITE_MANAGER_REMOTE_HOST_VALIDATION = [require, isRemoteHost, maxLength(255)];
export const MY_ACCOUNT_VALIDATION = [require];
+
+export const CHOOSE_VM_VALIDATION = [require];
// SPDX-License-Identifier: AGPL-3.0
import { ContextMenuActionSet } from "~/views-components/context-menu/context-menu-action-set";
-import { AdvancedIcon, ProjectIcon, AttributesIcon, UserPanelIcon } from "~/components/icon/icon";
+import { AdvancedIcon, ProjectIcon, AttributesIcon } from "~/components/icon/icon";
import { openAdvancedTabDialog } from '~/store/advanced-tab/advanced-tab';
-import { openUserAttributes, openUserProjects, openUserManagement } from "~/store/users/users-actions";
+import { openUserAttributes, openUserProjects } from "~/store/users/users-actions";
export const userActionSet: ContextMenuActionSet = [[{
name: "Attributes",
execute: (dispatch, { uuid }) => {
dispatch<any>(openAdvancedTabDialog(uuid));
}
-}, {
+}, /*
+ // Neither of the buttons on this dialog work correctly (bugs #16114 and #16124) so hide it for now.
+ {
name: "Manage",
icon: UserPanelIcon,
execute: (dispatch, { uuid }) => {
dispatch<any>(openUserManagement(uuid));
}
-}]];
+} */
+]];
import { FormDialog } from '~/components/form-dialog/form-dialog';
import { TextField } from '~/components/text-field/text-field';
import { VirtualMachinesResource } from '~/models/virtual-machines';
-import { USER_LENGTH_VALIDATION } from '~/validators/validators';
+import { USER_LENGTH_VALIDATION, CHOOSE_VM_VALIDATION } from '~/validators/validators';
import { InputLabel } from '@material-ui/core';
import { NativeSelectField } from '~/components/select-field/select-field';
-import { SETUP_SHELL_ACCOUNT_DIALOG, createUser } from '~/store/users/users-actions';
+import { SetupShellAccountFormDialogData, SETUP_SHELL_ACCOUNT_DIALOG, setupUserVM } from '~/store/users/users-actions';
import { UserResource } from '~/models/user';
-interface SetupShellAccountFormDialogData {
- email: string;
- virtualMachineName: string;
- groupVirtualMachine: string;
-}
-
export const SetupShellAccountDialog = compose(
withDialog(SETUP_SHELL_ACCOUNT_DIALOG),
reduxForm<SetupShellAccountFormDialogData>({
form: SETUP_SHELL_ACCOUNT_DIALOG,
onSubmit: (data, dispatch) => {
- dispatch(createUser(data));
+ dispatch(setupUserVM(data));
}
})
)(
<Field
name='virtualMachine'
component={NativeSelectField}
- validate={USER_LENGTH_VALIDATION}
+ validate={CHOOSE_VM_VALIDATION}
items={getVirtualMachinesList(data.items)} />
</div>;
label="Groups for virtual machine (comma separated list)" />;
const getVirtualMachinesList = (virtualMachines: VirtualMachinesResource[]) =>
- virtualMachines.map(it => ({ key: it.hostname, value: it.hostname }));
+ [{ key: "", value: "" }].concat(virtualMachines.map(it => ({ key: it.hostname, value: it.hostname })));
type SetupShellAccountDialogComponentProps = WithDialogProps<{}> & InjectedFormProps<SetupShellAccountFormDialogData>;
<UserVirtualMachineField data={props.data as DataProps} />
<UserGroupsVirtualMachineField />
</>;
-
-
-
import { Grid, Typography, Button, Card, CardContent, TableBody, TableCell, TableHead, TableRow, Table, Tooltip } from '@material-ui/core';
import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
import { ArvadosTheme } from '~/common/custom-theme';
-import { DefaultCodeSnippet } from '~/components/default-code-snippet/default-code-snippet';
-import { Link } from 'react-router-dom';
import { compose, Dispatch } from 'redux';
import { saveRequestedDate, loadVirtualMachinesUserData } from '~/store/virtual-machines/virtual-machines-actions';
import { RootState } from '~/store/store';
import { ListResults } from '~/services/common-service/common-service';
import { HelpIcon } from '~/components/icon/icon';
-import { Routes } from '~/routes/routes';
type CssRules = 'button' | 'codeSnippet' | 'link' | 'linkIcon' | 'rightAlign' | 'cardWithoutMachines' | 'icon';
return {
requestedDate: state.virtualMachines.date,
userUuid: state.auth.user!.uuid,
+ helpText: state.auth.config.clusterConfig.Workbench.SSHHelpPageHTML,
+ webShell: state.auth.config.clusterConfig.Services.WebShell.ExternalURL,
...state.virtualMachines
};
};
virtualMachines: ListResults<any>;
userUuid: string;
links: ListResults<any>;
+ helpText: string;
+ webShell: string;
}
interface VirtualMachinesPanelActionProps {
<TableCell>Host name</TableCell>
<TableCell>Login name</TableCell>
<TableCell>Command line</TableCell>
- <TableCell>Web shell</TableCell>
+ {props.webShell !== "" && <TableCell>Web shell</TableCell>}
</TableRow>
</TableHead>
<TableBody>
<TableRow key={index}>
<TableCell>{it.hostname}</TableCell>
<TableCell>{getUsername(props.links, props.userUuid)}</TableCell>
- <TableCell>ssh {getUsername(props.links, props.userUuid)}@{it.hostname}.arvados</TableCell>
- <TableCell>
- <a href={`https://workbench.c97qk.arvadosapi.com${it.href}/webshell/${getUsername(props.links, props.userUuid)}`} target="_blank" className={props.classes.link}>
+ <TableCell>ssh {getUsername(props.links, props.userUuid)}@{it.hostname}</TableCell>
+ {props.webShell !== "" && <TableCell>
+ <a href={`${props.webShell}${it.href}/webshell/${getUsername(props.links, props.userUuid)}`} target="_blank" className={props.classes.link}>
Log in as {getUsername(props.links, props.userUuid)}
</a>
- </TableCell>
+ </TableCell>}
</TableRow>
)}
</TableBody>
<Grid item xs={12}>
<Card>
<CardContent>
- <Typography variant='body1'>
- In order to access virtual machines using SSH, <Link to={Routes.SSH_KEYS_USER} className={props.classes.link}>add an SSH key to your account</Link> and add a section like this to your SSH configuration file ( ~/.ssh/config):
+ <Typography>
+ <div dangerouslySetInnerHTML={{ __html: props.helpText }} style={{ margin: "1em" }} />
</Typography>
- <DefaultCodeSnippet
- className={props.classes.codeSnippet}
- lines={[textSSH]} />
</CardContent>
</Card>
</Grid>;
-
-const textSSH = `Host *.arvados
- TCPKeepAlive yes
- ServerAliveInterval 60
- ProxyCommand ssh -p2222 turnout@switchyard.api.ardev.roche.com -x -a $SSH_PROXY_FLAGS %h`;
\ No newline at end of file