From ac74c122e0399c1c47580c72c9de994d36950e55 Mon Sep 17 00:00:00 2001
From: Mike Cousins
Date: Wed, 6 Nov 2019 12:46:54 -0500
Subject: [PATCH] feat(app): parse subnest out of CIDR-notation IP address
(#4372)
Closes #4075
---
app/package.json | 1 +
.../components/RobotSettings/connection.js | 11 +++--
.../__tests__/networking.test.js | 6 ++-
app/src/http-api-client/networking.js | 40 +++++++++++++++++--
yarn.lock | 5 +++
5 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/app/package.json b/app/package.json
index 1923029759e..59e5bdcc711 100644
--- a/app/package.json
+++ b/app/package.json
@@ -34,6 +34,7 @@
"lodash": "^4.17.4",
"mixpanel-browser": "^2.22.1",
"moment": "^2.19.1",
+ "netmask": "^1.0.6",
"path-to-regexp": "^3.0.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
diff --git a/app/src/components/RobotSettings/connection.js b/app/src/components/RobotSettings/connection.js
index 4e41152daba..0744d5601fb 100644
--- a/app/src/components/RobotSettings/connection.js
+++ b/app/src/components/RobotSettings/connection.js
@@ -77,8 +77,9 @@ type NetworkAddressProps = {
function NetworkAddresses(props: NetworkAddressProps) {
const type = props.wired ? 'Wired' : 'Wireless'
- const ip = (props.connection && props.connection.ipAddress) || 'Unknown'
- const mac = (props.connection && props.connection.macAddress) || 'Unknown'
+ const ip = props.connection?.ipAddress || 'Unknown'
+ const subnet = props.connection?.subnetMask || 'Unknown'
+ const mac = props.connection?.macAddress || 'Unknown'
const labelStyles = cx(styles.connection_label, {
[styles.disabled]: props.disabled,
})
@@ -90,7 +91,11 @@ function NetworkAddresses(props: NetworkAddressProps) {
{ip}
- {type} MAC address:
+ {type} Subnet Mask:
+ {subnet}
+
+
+ {type} MAC Address:
{mac}
diff --git a/app/src/http-api-client/__tests__/networking.test.js b/app/src/http-api-client/__tests__/networking.test.js
index 3354d0aa682..8db5f46b02a 100644
--- a/app/src/http-api-client/__tests__/networking.test.js
+++ b/app/src/http-api-client/__tests__/networking.test.js
@@ -22,13 +22,15 @@ describe('networking', () => {
api: {
api: {
someName: {
- 'networking/status': { response: { status: 'full' } },
+ 'networking/status': {
+ response: { status: 'full', interfaces: {} },
+ },
},
},
},
},
props: { name: 'someName' },
- expected: { response: { status: 'full' } },
+ expected: { response: { status: 'full', interfaces: {} } },
},
{
name: 'makeGetRobotWifiList',
diff --git a/app/src/http-api-client/networking.js b/app/src/http-api-client/networking.js
index 53650ae43b4..7cf7bf16a00 100644
--- a/app/src/http-api-client/networking.js
+++ b/app/src/http-api-client/networking.js
@@ -1,9 +1,11 @@
// @flow
// networking http api module
import { createSelector } from 'reselect'
+import mapValues from 'lodash/mapValues'
import orderBy from 'lodash/orderBy'
import partition from 'lodash/partition'
import uniqBy from 'lodash/uniqBy'
+import { Netmask } from 'netmask'
import {
apiRequest,
@@ -32,13 +34,17 @@ export type InternetStatus = 'none' | 'portal' | 'limited' | 'full' | 'unknown'
export type WifiSecurityType = 'none' | 'wpa-psk' | 'wpa-eap'
-export type NetworkInterface = {
+// TODO(mc, 2019-11-5): this does not match the response shape
+// the shape change happens in the selector, but should be happening
+// in the reducer. THis will be fixed when http-api-client is gone
+export type NetworkInterface = {|
ipAddress: ?string,
+ subnetMask: ?string,
macAddress: string,
gatewayAddress: ?string,
state: string,
type: 'wifi' | 'ethernet',
-}
+|}
export type WifiNetwork = {
ssid: string,
@@ -198,8 +204,34 @@ type GetConfigureWifiCall = Sel
export const makeGetRobotNetworkingStatus = (): GetNetworkingStatusCall =>
createSelector(
getRobotApiState,
- // $FlowFixMe: (mc, 2019-04-18) http-api-client types need to be redone
- state => state[STATUS] || { inProgress: false }
+ state => {
+ // $FlowFixMe: (mc, 2019-04-18) http-api-client types need to be redone
+ const statusCall = state[STATUS] || { inProgress: false }
+ if (!statusCall.response) return statusCall
+
+ return {
+ ...statusCall,
+ response: {
+ ...statusCall.response,
+ interfaces: mapValues(statusCall.response.interfaces, iface => {
+ let ipAddress = null
+ let subnetMask = null
+ if (iface.ipAddress != null) {
+ try {
+ const block = new Netmask(iface.ipAddress)
+ ipAddress = block.base
+ subnetMask = block.mask
+ } catch (e) {
+ // just use what was passed if unable to parse
+ ipAddress = iface.ipAddress
+ }
+ }
+
+ return { ...iface, ipAddress, subnetMask }
+ }),
+ },
+ }
+ }
)
export const makeGetRobotWifiList = (): GetWifiListCall =>
diff --git a/yarn.lock b/yarn.lock
index 7596fcb16ac..c3c7c913f25 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11493,6 +11493,11 @@ neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
+netmask@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35"
+ integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=
+
nice-try@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"