/* * Copyright (C) 2021 Red Hat, Inc. * SPDX-License-Identifier: LGPL-2.1-or-later */ import cockpit from "cockpit"; import React from 'react'; import { useEvent } from "hooks"; import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js"; import { Label } from "@patternfly/react-core/dist/esm/components/Label/index.js"; import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core/dist/esm/components/Card/index.js'; import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex/index.js"; import { Gallery } from "@patternfly/react-core/dist/esm/layouts/Gallery/index.js"; import { Page, PageSection, } from "@patternfly/react-core/dist/esm/components/Page/index.js"; import { ConnectedIcon } from "@patternfly/react-icons"; import { FirewallSwitch } from "./firewall-switch.jsx"; import { ListingTable } from "cockpit-components-table.jsx"; import { NetworkAction } from "./dialogs-common.jsx"; import { LogsPanel } from "cockpit-components-logs-panel.jsx"; import { NetworkPlots } from "./plots"; import firewall from './firewall-client.js'; import { device_state_text, has_group, is_loopback, is_managed, render_active_connection, } from './interfaces.js'; const _ = cockpit.gettext; export const NetworkPage = ({ privileged, operationInProgress, usage_monitor, plot_state, interfaces }) => { useEvent(firewall, "changed"); useEvent(usage_monitor.grid, "notify"); const managed = []; const unmanaged = []; const plot_ifaces = []; let hasDetails = false; interfaces.forEach(iface => { // Skip loopback if (is_loopback(iface)) { return; } // Skip members if (has_group(iface)) { return; } const dev = iface.Device; const show_traffic = (dev && (dev.State === 100 || dev.State === 10) && dev.Carrier === true); plot_ifaces.push(iface.Name); usage_monitor.add(iface.Name); const activeConnection = render_active_connection(dev, false, true); const row = { columns: [ { title: (!dev || is_managed(dev)) ? : iface.Name }, { title: activeConnection }, ], props: { key: iface.Name, "data-interface": encodeURIComponent(iface.Name), "data-sample-id": show_traffic ? encodeURIComponent(iface.Name) : null, "data-row-id": iface.Name, } }; if (show_traffic) { const samples = usage_monitor.samples[iface.Name]; row.columns.push({ title: samples ? cockpit.format_bits_per_sec(samples[1][0] * 8) : "" }); row.columns.push({ title: samples ? cockpit.format_bits_per_sec(samples[0][0] * 8) : "" }); } else { row.columns.push({ title: device_state_text(dev), props: { colSpan: 2 } }); } // Details column: show type-specific information let detailsColumn = null; if (dev?.DeviceType === '802-11-wireless') { const networkCount = dev.visibleSsids.length; if (networkCount > 0 || dev.ActiveAccessPoint?.Ssid) { hasDetails = true; detailsColumn = ( {networkCount > 0 && ( )} {dev.ActiveAccessPoint?.Ssid && ( )} ); } } row.columns.push({ title: detailsColumn }); if (!dev || is_managed(dev)) { managed.push(row); } else { unmanaged.push(row); } }); const rx_plot_data = { direct: "network.interface.in.bytes", internal: "network.interface.rx", units: "bytes", derive: "rate", threshold: 200, factor: 8 }; const tx_plot_data = { direct: "network.interface.out.bytes", internal: "network.interface.tx", units: "bytes", derive: "rate", threshold: 200, factor: 8 }; plot_state.plot_instances('rx', rx_plot_data, plot_ifaces); plot_state.plot_instances('tx', tx_plot_data, plot_ifaces); /* Start of properties for the LogsPanel component */ const match = [ "_SYSTEMD_UNIT=NetworkManager.service", "+", "_SYSTEMD_UNIT=firewalld.service" ]; const search_options = { prio: "debug", _SYSTEMD_UNIT: "NetworkManager.service,firewalld.service" }; const url = "/system/logs/#/?prio=debug&_SYSTEMD_UNIT=NetworkManager.service,firewalld.service"; /* End of properties for the LogsPanel component */ const actions = privileged && ( <> ); return ( {firewall.installed && cockpit.jump("/network/firewall", cockpit.transport.host)}> {_("Edit rules and zones")} , }}> {_("Firewall")} } {_("Interfaces")} {unmanaged.length > 0 && {_("Unmanaged interfaces")} } ); };