+ client: handle DHCP reset

This commit is contained in:
Ildar Kamalov 2019-10-15 17:14:24 +03:00 committed by Simon Zolin
parent df92941ae0
commit a4dedacf43
7 changed files with 109 additions and 36 deletions

View file

@ -17,7 +17,7 @@
"dhcp_leases": "DHCP leases", "dhcp_leases": "DHCP leases",
"dhcp_static_leases": "DHCP static leases", "dhcp_static_leases": "DHCP static leases",
"dhcp_leases_not_found": "No DHCP leases found", "dhcp_leases_not_found": "No DHCP leases found",
"dhcp_config_saved": "Saved DHCP server config", "dhcp_config_saved": "DHCP config successfully saved",
"form_error_required": "Required field", "form_error_required": "Required field",
"form_error_ip4_format": "Invalid IPv4 format", "form_error_ip4_format": "Invalid IPv4 format",
"form_error_ip6_format": "Invalid IPv6 format", "form_error_ip6_format": "Invalid IPv6 format",
@ -45,6 +45,7 @@
"dhcp_new_static_lease": "New static lease", "dhcp_new_static_lease": "New static lease",
"dhcp_static_leases_not_found": "No DHCP static leases found", "dhcp_static_leases_not_found": "No DHCP static leases found",
"dhcp_add_static_lease": "Add static lease", "dhcp_add_static_lease": "Add static lease",
"dhcp_reset": "Are you sure you want to reset DHCP config?",
"delete_confirm": "Are you sure you want to delete \"{{key}}\"?", "delete_confirm": "Are you sure you want to delete \"{{key}}\"?",
"form_enter_hostname": "Enter hostname", "form_enter_hostname": "Enter hostname",
"error_details": "Error details", "error_details": "Error details",

View file

@ -470,6 +470,22 @@ export const toggleDhcp = values => async (dispatch) => {
} }
}; };
export const resetDhcpRequest = createAction('RESET_DHCP_REQUEST');
export const resetDhcpSuccess = createAction('RESET_DHCP_SUCCESS');
export const resetDhcpFailure = createAction('RESET_DHCP_FAILURE');
export const resetDhcp = () => async (dispatch) => {
dispatch(resetDhcpRequest());
try {
const status = await apiClient.resetDhcp();
dispatch(resetDhcpSuccess(status));
dispatch(addSuccessToast('dhcp_config_saved'));
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(resetDhcpFailure());
}
};
export const toggleLeaseModal = createAction('TOGGLE_LEASE_MODAL'); export const toggleLeaseModal = createAction('TOGGLE_LEASE_MODAL');
export const addStaticLeaseRequest = createAction('ADD_STATIC_LEASE_REQUEST'); export const addStaticLeaseRequest = createAction('ADD_STATIC_LEASE_REQUEST');

View file

@ -248,6 +248,7 @@ class Api {
DHCP_INTERFACES = { path: 'dhcp/interfaces', method: 'GET' }; DHCP_INTERFACES = { path: 'dhcp/interfaces', method: 'GET' };
DHCP_ADD_STATIC_LEASE = { path: 'dhcp/add_static_lease', method: 'POST' }; DHCP_ADD_STATIC_LEASE = { path: 'dhcp/add_static_lease', method: 'POST' };
DHCP_REMOVE_STATIC_LEASE = { path: 'dhcp/remove_static_lease', method: 'POST' }; DHCP_REMOVE_STATIC_LEASE = { path: 'dhcp/remove_static_lease', method: 'POST' };
DHCP_RESET = { path: 'dhcp/reset', method: 'POST' };
getDhcpStatus() { getDhcpStatus() {
const { path, method } = this.DHCP_STATUS; const { path, method } = this.DHCP_STATUS;
@ -295,6 +296,11 @@ class Api {
return this.makeRequest(path, method, parameters); return this.makeRequest(path, method, parameters);
} }
resetDhcp() {
const { path, method } = this.DHCP_RESET;
return this.makeRequest(path, method);
}
// Installation // Installation
INSTALL_GET_ADDRESSES = { path: 'install/get_addresses', method: 'GET' }; INSTALL_GET_ADDRESSES = { path: 'install/get_addresses', method: 'GET' };
INSTALL_CONFIGURE = { path: 'install/configure', method: 'POST' }; INSTALL_CONFIGURE = { path: 'install/configure', method: 'POST' };

View file

@ -50,6 +50,23 @@ const renderInterfaceValues = (interfaceValues => (
</ul> </ul>
)); ));
const clearFields = (change, resetDhcp, t) => {
const fields = {
interface_name: '',
gateway_ip: '',
subnet_mask: '',
range_start: '',
range_end: '',
lease_duration: 86400,
};
// eslint-disable-next-line no-alert
if (window.confirm(t('dhcp_reset'))) {
Object.keys(fields).forEach(field => change(field, fields[field]));
resetDhcp();
}
};
let Form = (props) => { let Form = (props) => {
const { const {
t, t,
@ -61,6 +78,8 @@ let Form = (props) => {
interfaceValue, interfaceValue,
processingConfig, processingConfig,
processingInterfaces, processingInterfaces,
resetDhcp,
change,
} = props; } = props;
return ( return (
@ -160,6 +179,7 @@ let Form = (props) => {
</div> </div>
</div> </div>
<div className="btn-list">
<button <button
type="submit" type="submit"
className="btn btn-success btn-standard" className="btn btn-success btn-standard"
@ -167,24 +187,34 @@ let Form = (props) => {
> >
{t('save_config')} {t('save_config')}
</button> </button>
<button
type="button"
className="btn btn-secondary btn-standart"
disabled={submitting || processingConfig}
onClick={() => clearFields(change, resetDhcp, t)}
>
<Trans>reset_settings</Trans>
</button>
</div>
</form> </form>
); );
}; };
Form.propTypes = { Form.propTypes = {
handleSubmit: PropTypes.func, handleSubmit: PropTypes.func.isRequired,
submitting: PropTypes.bool, submitting: PropTypes.bool.isRequired,
invalid: PropTypes.bool, invalid: PropTypes.bool.isRequired,
interfaces: PropTypes.object, interfaces: PropTypes.object.isRequired,
interfaceValue: PropTypes.string, interfaceValue: PropTypes.string,
initialValues: PropTypes.object, initialValues: PropTypes.object.isRequired,
processingConfig: PropTypes.bool, processingConfig: PropTypes.bool.isRequired,
processingInterfaces: PropTypes.bool, processingInterfaces: PropTypes.bool.isRequired,
enabled: PropTypes.bool, enabled: PropTypes.bool.isRequired,
t: PropTypes.func, t: PropTypes.func.isRequired,
resetDhcp: PropTypes.func.isRequired,
change: PropTypes.func.isRequired,
}; };
const selector = formValueSelector('dhcpForm'); const selector = formValueSelector('dhcpForm');
Form = connect((state) => { Form = connect((state) => {

View file

@ -154,7 +154,15 @@ class Dhcp extends Component {
}; };
render() { render() {
const { t, dhcp } = this.props; const {
t,
dhcp,
resetDhcp,
findActiveDhcp,
addStaticLease,
removeStaticLease,
toggleLeaseModal,
} = this.props;
const statusButtonClass = classnames({ const statusButtonClass = classnames({
'btn btn-primary btn-standard': true, 'btn btn-primary btn-standard': true,
'btn btn-primary btn-standard btn-loading': dhcp.processingStatus, 'btn btn-primary btn-standard btn-loading': dhcp.processingStatus,
@ -184,6 +192,7 @@ class Dhcp extends Component {
processingConfig={dhcp.processingConfig} processingConfig={dhcp.processingConfig}
processingInterfaces={dhcp.processingInterfaces} processingInterfaces={dhcp.processingInterfaces}
enabled={enabled} enabled={enabled}
resetDhcp={resetDhcp}
/> />
<hr /> <hr />
<div className="card-actions mb-3"> <div className="card-actions mb-3">
@ -191,9 +200,7 @@ class Dhcp extends Component {
<button <button
type="button" type="button"
className={statusButtonClass} className={statusButtonClass}
onClick={() => onClick={() => findActiveDhcp(interface_name)}
this.props.findActiveDhcp(interface_name)
}
disabled={ disabled={
enabled || !interface_name || dhcp.processingConfig enabled || !interface_name || dhcp.processingConfig
} }
@ -232,9 +239,9 @@ class Dhcp extends Component {
<StaticLeases <StaticLeases
staticLeases={dhcp.staticLeases} staticLeases={dhcp.staticLeases}
isModalOpen={dhcp.isModalOpen} isModalOpen={dhcp.isModalOpen}
addStaticLease={this.props.addStaticLease} addStaticLease={addStaticLease}
removeStaticLease={this.props.removeStaticLease} removeStaticLease={removeStaticLease}
toggleLeaseModal={this.props.toggleLeaseModal} toggleLeaseModal={toggleLeaseModal}
processingAdding={dhcp.processingAdding} processingAdding={dhcp.processingAdding}
processingDeleting={dhcp.processingDeleting} processingDeleting={dhcp.processingDeleting}
/> />
@ -243,7 +250,7 @@ class Dhcp extends Component {
<button <button
type="button" type="button"
className="btn btn-success btn-standard mt-3" className="btn btn-success btn-standard mt-3"
onClick={() => this.props.toggleLeaseModal()} onClick={() => toggleLeaseModal()}
> >
<Trans>dhcp_add_static_lease</Trans> <Trans>dhcp_add_static_lease</Trans>
</button> </button>
@ -260,16 +267,17 @@ class Dhcp extends Component {
} }
Dhcp.propTypes = { Dhcp.propTypes = {
dhcp: PropTypes.object, dhcp: PropTypes.object.isRequired,
toggleDhcp: PropTypes.func, toggleDhcp: PropTypes.func.isRequired,
getDhcpStatus: PropTypes.func, getDhcpStatus: PropTypes.func.isRequired,
setDhcpConfig: PropTypes.func, setDhcpConfig: PropTypes.func.isRequired,
findActiveDhcp: PropTypes.func, findActiveDhcp: PropTypes.func.isRequired,
addStaticLease: PropTypes.func, addStaticLease: PropTypes.func.isRequired,
removeStaticLease: PropTypes.func, removeStaticLease: PropTypes.func.isRequired,
toggleLeaseModal: PropTypes.func, toggleLeaseModal: PropTypes.func.isRequired,
getDhcpInterfaces: PropTypes.func, getDhcpInterfaces: PropTypes.func.isRequired,
t: PropTypes.func, t: PropTypes.func.isRequired,
resetDhcp: PropTypes.func.isRequired,
}; };
export default withNamespaces()(Dhcp); export default withNamespaces()(Dhcp);

View file

@ -8,6 +8,7 @@ import {
toggleLeaseModal, toggleLeaseModal,
addStaticLease, addStaticLease,
removeStaticLease, removeStaticLease,
resetDhcp,
} from '../actions'; } from '../actions';
import Dhcp from '../components/Settings/Dhcp'; import Dhcp from '../components/Settings/Dhcp';
@ -28,6 +29,7 @@ const mapDispatchToProps = {
toggleLeaseModal, toggleLeaseModal,
addStaticLease, addStaticLease,
removeStaticLease, removeStaticLease,
resetDhcp,
}; };
export default connect( export default connect(

View file

@ -289,6 +289,16 @@ const dhcp = handleActions(
return newState; return newState;
}, },
[actions.resetDhcpRequest]: state => ({ ...state, processingReset: true }),
[actions.resetDhcpFailure]: state => ({ ...state, processingReset: false }),
[actions.resetDhcpSuccess]: state => ({
...state,
processingReset: false,
config: {
enabled: false,
},
}),
[actions.toggleLeaseModal]: (state) => { [actions.toggleLeaseModal]: (state) => {
const newState = { const newState = {
...state, ...state,