From 8b6e9ef5f9fe0ca27131128a8ebd4bec1a0e25af Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Wed, 3 Apr 2019 15:49:55 +0300 Subject: [PATCH 01/14] * /control/dhcp/find_active_dhcp: new JSON response format --- dhcp.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/dhcp.go b/dhcp.go index ac9c36c5..dc91a10c 100644 --- a/dhcp.go +++ b/dhcp.go @@ -147,13 +147,22 @@ func handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) { http.Error(w, errorText, http.StatusBadRequest) return } + found, err := dhcpd.CheckIfOtherDHCPServersPresent(interfaceName) - result := map[string]interface{}{} - if err != nil { - result["error"] = err.Error() - } else { - result["found"] = found + + othSrv := map[string]interface{}{} + foundVal := "no" + if found { + foundVal = "yes" + } else if err != nil { + foundVal = "error" + othSrv["error"] = err.Error() } + othSrv["found"] = foundVal + + result := map[string]interface{}{} + result["other-server"] = othSrv + w.Header().Set("Content-Type", "application/json") err = json.NewEncoder(w).Encode(result) if err != nil { From 0ed619c9c86402ae8188ab2e00a0bd717aa0cbee Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Wed, 3 Apr 2019 17:45:39 +0300 Subject: [PATCH 02/14] + /control/dhcp/find_active_dhcp: detect static IP on Linux --- dhcp.go | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/dhcp.go b/dhcp.go index dc91a10c..3b77a855 100644 --- a/dhcp.go +++ b/dhcp.go @@ -2,10 +2,13 @@ package main import ( "encoding/json" + "errors" "fmt" "io/ioutil" "net" "net/http" + "os/exec" + "runtime" "strings" "time" @@ -130,6 +133,10 @@ func handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) { } } +// Perform the following tasks: +// . Search for another DHCP server running +// . Check if a static IP is configured for the network interface +// Respond with results func handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) { log.Tracef("%s %v", r.Method, r.URL) body, err := ioutil.ReadAll(r.Body) @@ -160,8 +167,21 @@ func handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) { } othSrv["found"] = foundVal + staticIP := map[string]interface{}{} + isStaticIP, err := hasStaticIP(interfaceName) + staticIPStatus := "yes" + if err != nil { + staticIPStatus = "error" + staticIP["error"] = err.Error() + } else if !isStaticIP { + staticIPStatus = "no" + staticIP["ip"] = getFullIP(interfaceName) + } + staticIP["static"] = staticIPStatus + result := map[string]interface{}{} - result["other-server"] = othSrv + result["other_server"] = othSrv + result["static_ip"] = staticIP w.Header().Set("Content-Type", "application/json") err = json.NewEncoder(w).Encode(result) @@ -171,6 +191,73 @@ func handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) { } } +// Check if network interface has a static IP configured +func hasStaticIP(ifaceName string) (bool, error) { + if runtime.GOOS == "windows" { + return false, errors.New("Can't detect static IP: not supported on Windows") + } + + body, err := ioutil.ReadFile("/etc/dhcpcd.conf") + if err != nil { + return false, err + } + lines := strings.Split(string(body), "\n") + nameLine := fmt.Sprintf("interface %s", ifaceName) + state := 0 + + for _, line := range lines { + line = strings.TrimSpace(line) + + if state == 1 && len(line) == 0 { + // an empty line resets our state + state = 0 + } + + if len(line) == 0 || line[0] == '#' { + continue + } + line = strings.TrimSpace(line) + + if state == 0 { + if line == nameLine { + state = 1 + } + + } else if state == 1 { + if strings.HasPrefix(line, "interface ") { + state = 0 + continue + } + if strings.HasPrefix(line, "static ip_address=") { + return true, nil + } + } + } + + return false, nil +} + +// Get IP address with netmask +func getFullIP(ifaceName string) string { + cmd := exec.Command("ip", "-oneline", "-family", "inet", "address", "show", ifaceName) + log.Tracef("executing %s %v", cmd.Path, cmd.Args) + d, err := cmd.Output() + if err != nil || cmd.ProcessState.ExitCode() != 0 { + return "" + } + + fields := strings.Fields(string(d)) + if len(fields) < 4 { + return "" + } + _, _, err = net.ParseCIDR(fields[3]) + if err != nil { + return "" + } + + return fields[3] +} + func startDHCPServer() error { if !config.DHCP.Enabled { // not enabled, don't do anything From ef22a31a932852d51b9cbed6f1c51c5e8e8ac2fd Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Wed, 3 Apr 2019 19:36:20 +0300 Subject: [PATCH 03/14] + /control/dhcp/set_config: set static IP --- dhcp.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/dhcp.go b/dhcp.go index 3b77a855..2d28ae9c 100644 --- a/dhcp.go +++ b/dhcp.go @@ -13,6 +13,7 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/dhcpd" + "github.com/AdguardTeam/golibs/file" "github.com/AdguardTeam/golibs/log" "github.com/joomcode/errorx" ) @@ -61,7 +62,17 @@ func handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) { } if newconfig.Enabled { - err := dhcpServer.Start(&newconfig) + + staticIP, err := hasStaticIP(newconfig.InterfaceName) + if !staticIP && err == nil { + err = setStaticIP(newconfig.InterfaceName) + if err != nil { + httpError(w, http.StatusInternalServerError, "Failed to configure static IP: %s", err) + return + } + } + + err = dhcpServer.Start(&newconfig) if err != nil { httpError(w, http.StatusBadRequest, "Failed to start DHCP server: %s", err) return @@ -258,6 +269,68 @@ func getFullIP(ifaceName string) string { return fields[3] } +// Get gateway IP address +func getGatewayIP(ifaceName string) string { + cmd := exec.Command("ip", "route", "show", "dev", ifaceName) + log.Tracef("executing %s %v", cmd.Path, cmd.Args) + d, err := cmd.Output() + if err != nil || cmd.ProcessState.ExitCode() != 0 { + return "" + } + + fields := strings.Fields(string(d)) + if len(fields) < 3 || fields[0] != "default" { + return "" + } + + ip := net.ParseIP(fields[2]) + if ip == nil { + return "" + } + + return fields[2] +} + +// Set a static IP for network interface +func setStaticIP(ifaceName string) error { + ip := getFullIP(ifaceName) + if len(ip) == 0 { + return errors.New("Can't get IP address") + } + + body, err := ioutil.ReadFile("/etc/dhcpcd.conf") + if err != nil { + return err + } + + ip4, _, err := net.ParseCIDR(ip) + if err != nil { + return err + } + + add := fmt.Sprintf("\ninterface %s\nstatic ip_address=%s\n", + ifaceName, ip) + body = append(body, []byte(add)...) + + gatewayIP := getGatewayIP(ifaceName) + if len(gatewayIP) != 0 { + add = fmt.Sprintf("static routers=%s\n", + gatewayIP) + body = append(body, []byte(add)...) + } + + add = fmt.Sprintf("static domain_name_servers=%s\n\n", + ip4) + body = append(body, []byte(add)...) + + err = file.SafeWrite("/etc/dhcpcd.conf", body) + if err != nil { + return err + } + + return nil +} + func startDHCPServer() error { if !config.DHCP.Enabled { // not enabled, don't do anything From d43290fe316ff47fd2a6ad0b6f7ebe0655cd104e Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Thu, 28 Mar 2019 16:27:24 +0300 Subject: [PATCH 04/14] + config: set default parameters for DHCP server --- config.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config.go b/config.go index 07466925..4e63bfb6 100644 --- a/config.go +++ b/config.go @@ -134,6 +134,10 @@ var config = configuration{ {Filter: dnsfilter.Filter{ID: 3}, Enabled: false, URL: "https://hosts-file.net/ad_servers.txt", Name: "hpHosts - Ad and Tracking servers only"}, {Filter: dnsfilter.Filter{ID: 4}, Enabled: false, URL: "https://www.malwaredomainlist.com/hostslist/hosts.txt", Name: "MalwareDomainList.com Hosts List"}, }, + DHCP: dhcpd.ServerConfig{ + LeaseDuration: 86400, + ICMPTimeout: 1000, + }, SchemaVersion: currentSchemaVersion, } From ffd9f1aaa9f2c0c8007c40e27c03f48d4a97697e Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Thu, 28 Mar 2019 16:30:22 +0300 Subject: [PATCH 05/14] * client: fix DHCP error message --- client/src/__locales/en.json | 4 +- client/src/components/Settings/Dhcp/index.js | 30 ++++++++++---- client/src/components/ui/Accordion.css | 29 ++++++++++++++ client/src/components/ui/Accordion.js | 41 ++++++++++++++++++++ 4 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 client/src/components/ui/Accordion.css create mode 100644 client/src/components/ui/Accordion.js diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index f8eecedb..b2f4850c 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -32,7 +32,9 @@ "dhcp_ip_addresses": "IP addresses", "dhcp_table_hostname": "Hostname", "dhcp_table_expires": "Expires", - "dhcp_warning": "If you want to enable the built-in DHCP server, make sure that there is no other active DHCP server. Otherwise, it can break the internet for connected devices!", + "dhcp_warning": "If you want to enable DHCP server anyway, make sure that there is no other active DHCP server in your network. Otherwise, it can break the Internet for connected devices!", + "dhcp_error": "We couldn't determine whether an another DHCP server exists in the network.", + "error_details": "Error details", "back": "Back", "dashboard": "Dashboard", "settings": "Settings", diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index 5335586b..af74b8d7 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -7,6 +7,7 @@ import Form from './Form'; import Leases from './Leases'; import Interface from './Interface'; import Card from '../../ui/Card'; +import Accordion from '../../ui/Accordion'; class Dhcp extends Component { handleFormSubmit = (values) => { @@ -60,14 +61,17 @@ class Dhcp extends Component { ); } - getActiveDhcpMessage = () => { - const { active } = this.props.dhcp; - + getActiveDhcpMessage = (t, active) => { if (active) { if (active.error) { return (
- {active.error} + dhcp_error +
+ + {active.error} + +
); } @@ -90,6 +94,18 @@ class Dhcp extends Component { return ''; } + getDhcpWarning = (active) => { + if (active && active.found === false) { + return ''; + } + + return ( +
+ dhcp_warning +
+ ); + } + render() { const { t, dhcp } = this.props; const statusButtonClass = classnames({ @@ -138,10 +154,8 @@ class Dhcp extends Component { check_dhcp_servers - {this.getActiveDhcpMessage()} -
- dhcp_warning -
+ {this.getActiveDhcpMessage(t, dhcp.active)} + {this.getDhcpWarning(dhcp.active)} } diff --git a/client/src/components/ui/Accordion.css b/client/src/components/ui/Accordion.css new file mode 100644 index 00000000..8644f08a --- /dev/null +++ b/client/src/components/ui/Accordion.css @@ -0,0 +1,29 @@ +.accordion__label { + position: relative; + display: inline-block; + padding-left: 25px; + color: #495057; + cursor: pointer; +} + +.accordion__label:after { + content: ""; + position: absolute; + top: 7px; + left: 0; + width: 17px; + height: 10px; + background-image: url("./svg/chevron-down.svg"); + background-repeat: no-repeat; + background-position: center; + background-size: 100%; +} + +.accordion__label--open:after { + transform: rotate(180deg); +} + +.accordion__content { + padding-top: 5px; + color: #495057; +} diff --git a/client/src/components/ui/Accordion.js b/client/src/components/ui/Accordion.js new file mode 100644 index 00000000..df94b179 --- /dev/null +++ b/client/src/components/ui/Accordion.js @@ -0,0 +1,41 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import './Accordion.css'; + +class Accordion extends Component { + state = { + isOpen: false, + } + + handleClick = () => { + this.setState(prevState => ({ isOpen: !prevState.isOpen })); + }; + + render() { + const accordionClass = this.state.isOpen ? 'accordion__label--open' : ''; + + return ( +
+
+ {this.props.label} +
+ {this.state.isOpen && ( +
+ {this.props.children} +
+ )} +
+ ); + } +} + +Accordion.propTypes = { + children: PropTypes.node.isRequired, + label: PropTypes.string.isRequired, +}; + +export default Accordion; From b92fb34f373ef8a378fa8547ced3d3512eaeeeb3 Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Thu, 28 Mar 2019 16:32:22 +0300 Subject: [PATCH 06/14] - client: fix DHCP fields validation --- client/src/components/Settings/Dhcp/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index af74b8d7..8480a5b5 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -24,7 +24,7 @@ class Dhcp extends Component { } = this.props.dhcp; const activeDhcpFound = active && active.found; const filledConfig = Object.keys(config).every((key) => { - if (key === 'enabled') { + if (key === 'enabled' || key === 'icmp_timeout_msec') { return true; } From 6ba0e4686abfe4407ac009ed39726f08bf63ac8c Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Thu, 28 Mar 2019 16:40:46 +0300 Subject: [PATCH 07/14] * client: accordion styles --- client/src/components/ui/Accordion.css | 7 +++++-- client/src/components/ui/Accordion.js | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/client/src/components/ui/Accordion.css b/client/src/components/ui/Accordion.css index 8644f08a..d62695aa 100644 --- a/client/src/components/ui/Accordion.css +++ b/client/src/components/ui/Accordion.css @@ -1,9 +1,13 @@ +.accordion { + color: #495057; +} + .accordion__label { position: relative; display: inline-block; padding-left: 25px; - color: #495057; cursor: pointer; + user-select: none; } .accordion__label:after { @@ -25,5 +29,4 @@ .accordion__content { padding-top: 5px; - color: #495057; } diff --git a/client/src/components/ui/Accordion.js b/client/src/components/ui/Accordion.js index df94b179..90fa25f9 100644 --- a/client/src/components/ui/Accordion.js +++ b/client/src/components/ui/Accordion.js @@ -13,12 +13,14 @@ class Accordion extends Component { }; render() { - const accordionClass = this.state.isOpen ? 'accordion__label--open' : ''; + const accordionClass = this.state.isOpen + ? 'accordion__label accordion__label--open' + : 'accordion__label'; return (
{this.props.label} From 24fc2957c59206b76d3268ca817d16a06aa223bd Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Thu, 28 Mar 2019 17:53:02 +0300 Subject: [PATCH 08/14] * client: hide error if DHCP enabled and require check DHCP before enabling --- client/src/components/Settings/Dhcp/index.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index 8480a5b5..4621011d 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -51,6 +51,7 @@ class Dhcp extends Component { onClick={() => this.handleToggle(config)} disabled={ !filledConfig + || !active || activeDhcpFound || processingDhcp || processingConfig @@ -95,7 +96,7 @@ class Dhcp extends Component { } getDhcpWarning = (active) => { - if (active && active.found === false) { + if (!active || (active && active.found === false)) { return ''; } @@ -154,8 +155,12 @@ class Dhcp extends Component { check_dhcp_servers
- {this.getActiveDhcpMessage(t, dhcp.active)} - {this.getDhcpWarning(dhcp.active)} + {!enabled && + + {this.getActiveDhcpMessage(t, dhcp.active)} + {this.getDhcpWarning(dhcp.active)} + + } }
From 4b821d67f5af119f5e4ea06880e390261f2af7dc Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Thu, 28 Mar 2019 19:08:24 +0300 Subject: [PATCH 09/14] * client: disable DHCP check if server enabled and hide errors on disable --- client/src/components/Settings/Dhcp/index.js | 3 ++- client/src/reducers/index.js | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index 4621011d..1de64f14 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -148,7 +148,8 @@ class Dhcp extends Component { this.props.findActiveDhcp(dhcp.config.interface_name) } disabled={ - !dhcp.config.interface_name + dhcp.config.enabled + || !dhcp.config.interface_name || dhcp.processingConfig } > diff --git a/client/src/reducers/index.js b/client/src/reducers/index.js index 404679eb..0b415702 100644 --- a/client/src/reducers/index.js +++ b/client/src/reducers/index.js @@ -303,7 +303,9 @@ const dhcp = handleActions({ [actions.toggleDhcpSuccess]: (state) => { const { config } = state; const newConfig = { ...config, enabled: !config.enabled }; - const newState = { ...state, config: newConfig, processingDhcp: false }; + const newState = { + ...state, config: newConfig, active: null, processingDhcp: false, + }; return newState; }, From 472dc0b77d74277e8b097dcbe0e5c68bd9b44874 Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Fri, 29 Mar 2019 12:42:15 +0300 Subject: [PATCH 10/14] * client: error text --- client/src/__locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index b2f4850c..bad60842 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -33,7 +33,7 @@ "dhcp_table_hostname": "Hostname", "dhcp_table_expires": "Expires", "dhcp_warning": "If you want to enable DHCP server anyway, make sure that there is no other active DHCP server in your network. Otherwise, it can break the Internet for connected devices!", - "dhcp_error": "We couldn't determine whether an another DHCP server exists in the network.", + "dhcp_error": "We could not determine whether there is another DHCP server in the network.", "error_details": "Error details", "back": "Back", "dashboard": "Dashboard", From 6bf57ae84ee259f96ec07d9ebe49be5a93cf3da5 Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Thu, 4 Apr 2019 16:34:46 +0300 Subject: [PATCH 11/14] + client: static_ip warnings --- client/src/__locales/en.json | 2 + client/src/components/Settings/Dhcp/index.js | 112 +++++++++++++------ client/src/helpers/constants.js | 6 + client/src/reducers/index.js | 25 +++-- 4 files changed, 104 insertions(+), 41 deletions(-) diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index bad60842..aa95a923 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -34,6 +34,8 @@ "dhcp_table_expires": "Expires", "dhcp_warning": "If you want to enable DHCP server anyway, make sure that there is no other active DHCP server in your network. Otherwise, it can break the Internet for connected devices!", "dhcp_error": "We could not determine whether there is another DHCP server in the network.", + "dhcp_static_ip_error": "In order to use DHCP server a static IP address must be set. We failed to determine if this network interface is configured using static IP address. Please set a static IP address manually.", + "dhcp_dynamic_ip_found": "Your system uses dynamic IP address configuration for interface <0>{{interfaceName}}. In order to use DHCP server a static IP address must be set. Your current IP address is <0>{{ipAddress}}. We will automatically set this IP address as static if you press Enable DHCP button.", "error_details": "Error details", "back": "Back", "dashboard": "Dashboard", diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index 1de64f14..c152b7f0 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import classnames from 'classnames'; import { Trans, withNamespaces } from 'react-i18next'; +import { RESPONSE_STATUS } from '../../../helpers/constants'; import Form from './Form'; import Leases from './Leases'; import Interface from './Interface'; @@ -20,9 +21,10 @@ class Dhcp extends Component { getToggleDhcpButton = () => { const { - config, active, processingDhcp, processingConfig, + config, check, processingDhcp, processingConfig, } = this.props.dhcp; - const activeDhcpFound = active && active.found; + const otherDhcpFound = + check && check.otherServer && check.otherServer.found === RESPONSE_STATUS.YES; const filledConfig = Object.keys(config).every((key) => { if (key === 'enabled' || key === 'icmp_timeout_msec') { return true; @@ -51,8 +53,8 @@ class Dhcp extends Component { onClick={() => this.handleToggle(config)} disabled={ !filledConfig - || !active - || activeDhcpFound + || !check + || otherDhcpFound || processingDhcp || processingConfig } @@ -62,41 +64,39 @@ class Dhcp extends Component { ); } - getActiveDhcpMessage = (t, active) => { - if (active) { - if (active.error) { - return ( -
- dhcp_error -
- - {active.error} - -
-
- ); - } + getActiveDhcpMessage = (t, check) => { + const { found } = check.otherServer; + if (found === RESPONSE_STATUS.ERROR) { return ( -
- {active.found ? ( -
- dhcp_found -
- ) : ( -
- dhcp_not_found -
- )} +
+ dhcp_error +
+ + {check.otherServer.error} + +
); } - return ''; + return ( +
+ {found === RESPONSE_STATUS.YES ? ( +
+ dhcp_found +
+ ) : ( +
+ dhcp_not_found +
+ )} +
+ ); } - getDhcpWarning = (active) => { - if (!active || (active && active.found === false)) { + getDhcpWarning = (check) => { + if (check.otherServer.found === RESPONSE_STATUS.NO) { return ''; } @@ -107,6 +107,49 @@ class Dhcp extends Component { ); } + getStaticIpWarning = (t, check, interfaceName) => { + if (check.staticIP.static === RESPONSE_STATUS.ERROR) { + return ( + +
+ dhcp_static_ip_error +
+ + {check.staticIP.error} + +
+
+
+
+ ); + } else if ( + check.staticIP.static === RESPONSE_STATUS.YES + && check.staticIP.ip + && interfaceName + ) { + return ( + +
+ example, + ]} + values={{ + interfaceName, + ipAddress: check.staticIP.ip, + }} + > + dhcp_dynamic_ip_found + +
+
+
+ ); + } + + return ''; + } + render() { const { t, dhcp } = this.props; const statusButtonClass = classnames({ @@ -156,10 +199,11 @@ class Dhcp extends Component { check_dhcp_servers
- {!enabled && + {!enabled && dhcp.check && - {this.getActiveDhcpMessage(t, dhcp.active)} - {this.getDhcpWarning(dhcp.active)} + {this.getStaticIpWarning(t, dhcp.check, interface_name)} + {this.getActiveDhcpMessage(t, dhcp.check)} + {this.getDhcpWarning(dhcp.check)} } diff --git a/client/src/helpers/constants.js b/client/src/helpers/constants.js index 79deabdb..bbe5a5fc 100644 --- a/client/src/helpers/constants.js +++ b/client/src/helpers/constants.js @@ -157,3 +157,9 @@ export const UNSAFE_PORTS = [ ]; export const ALL_INTERFACES_IP = '0.0.0.0'; + +export const RESPONSE_STATUS = { + YES: 'yes', + NO: 'no', + ERROR: 'error', +}; diff --git a/client/src/reducers/index.js b/client/src/reducers/index.js index 0b415702..25156688 100644 --- a/client/src/reducers/index.js +++ b/client/src/reducers/index.js @@ -292,11 +292,22 @@ const dhcp = handleActions({ [actions.findActiveDhcpRequest]: state => ({ ...state, processingStatus: true }), [actions.findActiveDhcpFailure]: state => ({ ...state, processingStatus: false }), - [actions.findActiveDhcpSuccess]: (state, { payload }) => ({ - ...state, - active: payload, - processingStatus: false, - }), + [actions.findActiveDhcpSuccess]: (state, { payload }) => { + const { + other_server: otherServer, + static_ip: staticIP, + } = payload; + + const newState = { + ...state, + check: { + otherServer, + staticIP, + }, + processingStatus: false, + }; + return newState; + }, [actions.toggleDhcpRequest]: state => ({ ...state, processingDhcp: true }), [actions.toggleDhcpFailure]: state => ({ ...state, processingDhcp: false }), @@ -304,7 +315,7 @@ const dhcp = handleActions({ const { config } = state; const newConfig = { ...config, enabled: !config.enabled }; const newState = { - ...state, config: newConfig, active: null, processingDhcp: false, + ...state, config: newConfig, check: null, processingDhcp: false, }; return newState; }, @@ -326,7 +337,7 @@ const dhcp = handleActions({ config: { enabled: false, }, - active: null, + check: null, leases: [], }); From fa5ff053b761a223ead943a492b1d89700317fff Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Fri, 5 Apr 2019 12:47:26 +0300 Subject: [PATCH 12/14] * hasStaticIP: use properly named boolean variable --- dhcp.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dhcp.go b/dhcp.go index 2d28ae9c..4bd0c463 100644 --- a/dhcp.go +++ b/dhcp.go @@ -214,14 +214,14 @@ func hasStaticIP(ifaceName string) (bool, error) { } lines := strings.Split(string(body), "\n") nameLine := fmt.Sprintf("interface %s", ifaceName) - state := 0 + withinInterfaceCtx := false for _, line := range lines { line = strings.TrimSpace(line) - if state == 1 && len(line) == 0 { + if withinInterfaceCtx && len(line) == 0 { // an empty line resets our state - state = 0 + withinInterfaceCtx = false } if len(line) == 0 || line[0] == '#' { @@ -229,14 +229,16 @@ func hasStaticIP(ifaceName string) (bool, error) { } line = strings.TrimSpace(line) - if state == 0 { + if !withinInterfaceCtx { if line == nameLine { - state = 1 + // we found our interface + withinInterfaceCtx = true } - } else if state == 1 { + } else { if strings.HasPrefix(line, "interface ") { - state = 0 + // we found another interface - reset our state + withinInterfaceCtx = false continue } if strings.HasPrefix(line, "static ip_address=") { From b6ae539c364e65f2777be68e9d00f708e2fcda89 Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Fri, 5 Apr 2019 14:32:56 +0300 Subject: [PATCH 13/14] * client: rename constant --- client/src/components/Settings/Dhcp/index.js | 14 +++++++------- client/src/helpers/constants.js | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index c152b7f0..18dd4901 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import classnames from 'classnames'; import { Trans, withNamespaces } from 'react-i18next'; -import { RESPONSE_STATUS } from '../../../helpers/constants'; +import { DHCP_STATUS_RESPONSE } from '../../../helpers/constants'; import Form from './Form'; import Leases from './Leases'; import Interface from './Interface'; @@ -24,7 +24,7 @@ class Dhcp extends Component { config, check, processingDhcp, processingConfig, } = this.props.dhcp; const otherDhcpFound = - check && check.otherServer && check.otherServer.found === RESPONSE_STATUS.YES; + check && check.otherServer && check.otherServer.found === DHCP_STATUS_RESPONSE.YES; const filledConfig = Object.keys(config).every((key) => { if (key === 'enabled' || key === 'icmp_timeout_msec') { return true; @@ -67,7 +67,7 @@ class Dhcp extends Component { getActiveDhcpMessage = (t, check) => { const { found } = check.otherServer; - if (found === RESPONSE_STATUS.ERROR) { + if (found === DHCP_STATUS_RESPONSE.ERROR) { return (
dhcp_error @@ -82,7 +82,7 @@ class Dhcp extends Component { return (
- {found === RESPONSE_STATUS.YES ? ( + {found === DHCP_STATUS_RESPONSE.YES ? (
dhcp_found
@@ -96,7 +96,7 @@ class Dhcp extends Component { } getDhcpWarning = (check) => { - if (check.otherServer.found === RESPONSE_STATUS.NO) { + if (check.otherServer.found === DHCP_STATUS_RESPONSE.NO) { return ''; } @@ -108,7 +108,7 @@ class Dhcp extends Component { } getStaticIpWarning = (t, check, interfaceName) => { - if (check.staticIP.static === RESPONSE_STATUS.ERROR) { + if (check.staticIP.static === DHCP_STATUS_RESPONSE.ERROR) { return (
@@ -123,7 +123,7 @@ class Dhcp extends Component { ); } else if ( - check.staticIP.static === RESPONSE_STATUS.YES + check.staticIP.static === DHCP_STATUS_RESPONSE.YES && check.staticIP.ip && interfaceName ) { diff --git a/client/src/helpers/constants.js b/client/src/helpers/constants.js index bbe5a5fc..703a8dff 100644 --- a/client/src/helpers/constants.js +++ b/client/src/helpers/constants.js @@ -158,7 +158,7 @@ export const UNSAFE_PORTS = [ export const ALL_INTERFACES_IP = '0.0.0.0'; -export const RESPONSE_STATUS = { +export const DHCP_STATUS_RESPONSE = { YES: 'yes', NO: 'no', ERROR: 'error', From 828d3121be807daa8f839dfa7a7ac4ba8a6e7cd8 Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Fri, 5 Apr 2019 15:15:56 +0300 Subject: [PATCH 14/14] * client: show message if there is no static ip --- client/src/components/Settings/Dhcp/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index 18dd4901..437f9265 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -123,7 +123,7 @@ class Dhcp extends Component { ); } else if ( - check.staticIP.static === DHCP_STATUS_RESPONSE.YES + check.staticIP.static === DHCP_STATUS_RESPONSE.NO && check.staticIP.ip && interfaceName ) {