diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AwsRunTable.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AwsRunTable.js
deleted file mode 100644
index 8c7ccf490..000000000
--- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AwsRunTable.js
+++ /dev/null
@@ -1,109 +0,0 @@
-import React from 'react';
-import ReactTable from 'react-table'
-import checkboxHOC from 'react-table/lib/hoc/selectTable';
-
-const CheckboxTable = checkboxHOC(ReactTable);
-
-const columns = [
- {
- Header: 'Machines',
- columns: [
- {Header: 'Machine', accessor: 'name'},
- {Header: 'Instance ID', accessor: 'instance_id'},
- {Header: 'IP Address', accessor: 'ip_address'},
- {Header: 'OS', accessor: 'os'}
- ]
- }
-];
-
-const pageSize = 10;
-
-class AwsRunTableComponent extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- selection: [],
- selectAll: false,
- result: {}
- }
- }
-
- toggleSelection = (key) => {
- // start off with the existing state
- let selection = [...this.state.selection];
- const keyIndex = selection.indexOf(key);
- // check to see if the key exists
- if (keyIndex >= 0) {
- // it does exist so we will remove it using destructing
- selection = [
- ...selection.slice(0, keyIndex),
- ...selection.slice(keyIndex + 1)
- ];
- } else {
- // it does not exist so add it
- selection.push(key);
- }
- // update the state
- this.setState({selection});
- };
-
- isSelected = key => {
- return this.state.selection.includes(key);
- };
-
- toggleAll = () => {
- const selectAll = !this.state.selectAll;
- const selection = [];
- if (selectAll) {
- // we need to get at the internals of ReactTable
- const wrappedInstance = this.checkboxTable.getWrappedInstance();
- // the 'sortedData' property contains the currently accessible records based on the filter and sort
- const currentRecords = wrappedInstance.getResolvedState().sortedData;
- // we just push all the IDs onto the selection array
- currentRecords.forEach(item => {
- selection.push(item._original.instance_id);
- });
- }
- this.setState({selectAll, selection});
- };
-
- getTrProps = (_, r) => {
- let color = 'inherit';
- if (r) {
- let instId = r.original.instance_id;
- if (this.isSelected(instId)) {
- color = '#ffed9f';
- } else if (Object.prototype.hasOwnProperty.call(this.state.result, instId)) {
- color = this.state.result[instId] ? '#00f01b' : '#f00000'
- }
- }
-
- return {
- style: {backgroundColor: color}
- };
- };
-
- render() {
- return (
-
- (this.checkboxTable = r)}
- keyField="instance_id"
- columns={columns}
- data={this.props.data}
- showPagination={true}
- defaultPageSize={pageSize}
- className="-highlight"
- selectType="checkbox"
- toggleSelection={this.toggleSelection}
- isSelected={this.isSelected}
- toggleAll={this.toggleAll}
- selectAll={this.state.selectAll}
- getTrProps={this.getTrProps}
- />
-
- );
- }
-}
-
-export default AwsRunTableComponent;
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSInstanceTable.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSInstanceTable.js
new file mode 100644
index 000000000..cf792f7b8
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSInstanceTable.js
@@ -0,0 +1,119 @@
+import React, {useState} from 'react';
+import ReactTable from 'react-table'
+import checkboxHOC from 'react-table/lib/hoc/selectTable';
+import PropTypes from 'prop-types';
+
+
+const CheckboxTable = checkboxHOC(ReactTable);
+
+const columns = [
+ {
+ Header: 'Machines',
+ columns: [
+ {Header: 'Machine', accessor: 'name'},
+ {Header: 'Instance ID', accessor: 'instance_id'},
+ {Header: 'IP Address', accessor: 'ip_address'},
+ {Header: 'OS', accessor: 'os'}
+ ]
+ }
+];
+
+const pageSize = 10;
+
+function AWSInstanceTable(props) {
+
+ const [allToggled, setAllToggled] = useState(false);
+ let checkboxTable = null;
+
+ function toggleSelection(key) {
+ key = key.replace('select-', '');
+ // start off with the existing state
+ let modifiedSelection = [...props.selection];
+ const keyIndex = modifiedSelection.indexOf(key);
+ // check to see if the key exists
+ if (keyIndex >= 0) {
+ // it does exist so we will remove it using destructing
+ modifiedSelection = [
+ ...modifiedSelection.slice(0, keyIndex),
+ ...modifiedSelection.slice(keyIndex + 1)
+ ];
+ } else {
+ // it does not exist so add it
+ modifiedSelection.push(key);
+ }
+ // update the state
+ props.setSelection(modifiedSelection);
+ }
+
+ function isSelected(key) {
+ return props.selection.includes(key);
+ }
+
+ function toggleAll() {
+ const selectAll = !allToggled;
+ const selection = [];
+ if (selectAll) {
+ // we need to get at the internals of ReactTable
+ const wrappedInstance = checkboxTable.getWrappedInstance();
+ // the 'sortedData' property contains the currently accessible records based on the filter and sort
+ const currentRecords = wrappedInstance.getResolvedState().sortedData;
+ // we just push all the IDs onto the selection array
+ currentRecords.forEach(item => {
+ selection.push(item._original.instance_id);
+ });
+ }
+ setAllToggled(selectAll);
+ props.setSelection(selection);
+ }
+
+ function getTrProps(_, r) {
+ let color = 'inherit';
+ if (r) {
+ let instId = r.original.instance_id;
+ if (isSelected(instId)) {
+ color = '#ffed9f';
+ } else if (Object.prototype.hasOwnProperty.call(props.results, instId)) {
+ color = props.results[instId] ? '#00f01b' : '#f00000'
+ }
+ }
+
+ return {
+ style: {backgroundColor: color}
+ };
+ }
+
+ return (
+
+ (checkboxTable = r)}
+ keyField="instance_id"
+ columns={columns}
+ data={props.data}
+ showPagination={true}
+ defaultPageSize={pageSize}
+ className="-highlight"
+ selectType="checkbox"
+ toggleSelection={toggleSelection}
+ isSelected={isSelected}
+ toggleAll={toggleAll}
+ selectAll={allToggled}
+ getTrProps={getTrProps}
+ />
+
+ );
+
+}
+
+AWSInstanceTable.propTypes = {
+ data: PropTypes.arrayOf(PropTypes.exact({
+ instance_id: PropTypes.string,
+ name: PropTypes.string,
+ os: PropTypes.string,
+ ip_address: PropTypes.string
+ })),
+ results: PropTypes.arrayOf(PropTypes.string),
+ selection: PropTypes.arrayOf(PropTypes.string),
+ setSelection: PropTypes.func
+}
+
+export default AWSInstanceTable;
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AWSRunButton.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSRunButton.js
similarity index 86%
rename from monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AWSRunButton.js
rename to monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSRunButton.js
index 42f16c614..3903d2a8e 100644
--- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AWSRunButton.js
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSRunButton.js
@@ -1,11 +1,11 @@
import React, {useEffect, useState} from 'react';
-import AuthComponent from '../../AuthComponent';
-import '../../../styles/components/RunOnIslandButton.scss';
+import AuthComponent from '../../../AuthComponent';
+import '../../../../styles/components/RunOnIslandButton.scss';
import {faCloud} from '@fortawesome/free-solid-svg-icons';
-import AWSRunInstances from './AWSRunInstances';
-import NextSelectionButton from '../../ui-components/inline-selection/NextSelectionButton';
+import AWSRunOptions from './AWSRunOptions';
+import NextSelectionButton from '../../../ui-components/inline-selection/NextSelectionButton';
import {Alert, Button} from 'react-bootstrap';
-import LoadingIcon from '../../ui-components/LoadingIcon';
+import LoadingIcon from '../../../ui-components/LoadingIcon';
function AWSRunButton(props) {
@@ -49,7 +49,7 @@ function AWSRunButton(props) {
description={'Run on a chosen AWS instance in the cloud.'}
icon={faCloud}
onButtonClick={() => {
- props.setComponent(AWSRunInstances,
+ props.setComponent(AWSRunOptions,
{AWSInstances: AWSInstances, setComponent: props.setComponent})
}}/>
}
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AWSRunInstances.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSRunOptions.js
similarity index 75%
rename from monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AWSRunInstances.js
rename to monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSRunOptions.js
index 4cc4f4e88..4c75e0ae3 100644
--- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/AWSRunInstances.js
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOnAWS/AWSRunOptions.js
@@ -3,27 +3,36 @@ import {Button, Nav} from 'react-bootstrap';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faSync} from '@fortawesome/free-solid-svg-icons/faSync';
-import '../../../styles/components/RunOnIslandButton.scss';
import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle';
-import AwsRunTable from './AwsRunTable';
-import AuthComponent from '../../AuthComponent';
+import AwsRunTable from './AWSInstanceTable';
+import AuthComponent from '../../../AuthComponent';
+import InlineSelection from '../../../ui-components/inline-selection/InlineSelection';
-function AWSRunInstances(props) {
+const AWSRunOptions = (props) => {
+ return InlineSelection(getContents, {
+ ...props,
+ onBackButtonClick: () => {props.setComponent()}
+ })
+}
+
+
+const getContents = (props) => {
const authComponent = new AuthComponent({});
- let awsTable = null
let [allIPs, setAllIPs] = useState([]);
let [selectedIp, setSelectedIp] = useState(null);
let [AWSClicked, setAWSClicked] = useState(false);
+ let [runResults, setRunResults] = useState([]);
+ let [selectedInstances, setSelectedInstances] = useState([]);
useEffect(() => {
getIps();
- }, [allIPs]);
+ }, []);
function getIps() {
- this.authFetch('/api')
+ authComponent.authFetch('/api')
.then(res => res.json())
.then(res => {
setAllIPs(res['ip_addresses']);
@@ -33,7 +42,7 @@ function AWSRunInstances(props) {
function runOnAws() {
setAWSClicked(true);
- let instances = awsTable.state.selection.map(x => instanceIdToInstance(x));
+ let instances = selectedInstances.map(x => instanceIdToInstance(x));
authComponent.authFetch('/api/remote-monkey',
{
@@ -45,17 +54,14 @@ function AWSRunInstances(props) {
let result = res['result'];
// update existing state, not run-over
- let prevRes = awsTable.state.result;
+ let prevRes = result;
for (let key in result) {
if (result.hasOwnProperty(key)) {
prevRes[key] = result[key];
}
}
- awsTable.setState({
- result: prevRes,
- selection: [],
- selectAll: false
- });
+ setRunResults(prevRes);
+ setSelectedInstances([]);
setAWSClicked(false);
});
}
@@ -89,10 +95,13 @@ function AWSRunInstances(props) {
}
(awsTable = r)}
+ results={runResults}
+ selection={selectedInstances}
+ setSelection={setSelectedInstances}
/>
-
+