/* * Copyright (C) 2021 Red Hat, Inc. * SPDX-License-Identifier: LGPL-2.1-or-later */ import React, { useState, useContext } from 'react'; import cockpit from 'cockpit'; import { FormGroup } from "@patternfly/react-core/dist/esm/components/Form/index.js"; import { FormSelect, FormSelectOption } from "@patternfly/react-core/dist/esm/components/FormSelect/index.js"; import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput/index.js"; import { MemberInterfaceChoices, NetworkModal, Name, dialogSave } from './dialogs-common.jsx'; import { ModelContext } from './model-context.jsx'; import { useDialogs } from "dialogs.jsx"; import { v4 as uuidv4 } from 'uuid'; import { member_connection_for_interface, member_interface_choices, } from './interfaces.js'; const _ = cockpit.gettext; export const team_runner_choices = [ { choice: 'roundrobin', title: _("Round robin") }, { choice: 'activebackup', title: _("Active backup") }, { choice: 'loadbalance', title: _("Load balancing") }, { choice: 'broadcast', title: _("Broadcast") }, { choice: 'lacp', title: _("802.3ad LACP") }, ]; export const team_balancer_choices = [ { choice: 'none', title: _("Passive") }, { choice: 'basic', title: _("Active") } ]; export const team_watch_choices = [ { choice: 'ethtool', title: _("Ethtool") }, { choice: 'arp-ping', title: _("ARP ping") }, { choice: 'nsna-ping', title: _("NSNA ping") } ]; export const TeamDialog = ({ connection, dev, settings }) => { const Dialogs = useDialogs(); const idPrefix = "network-team-settings"; const model = useContext(ModelContext); const config = settings.team.config || {}; if (!config.runner) config.runner = { }; if (!config.runner.name) config.runner.name = "activebackup"; if (!config.link_watch) config.link_watch = { }; if (!config.link_watch.name) config.link_watch.name = "ethtool"; if (config.link_watch.interval === undefined) config.link_watch.interval = 100; if (config.link_watch.delay_up === undefined) config.link_watch.delay_up = 0; if (config.link_watch.delay_down === undefined) config.link_watch.delay_down = 0; const memberChoicesInit = {}; member_interface_choices(model, connection).forEach((iface) => { memberChoicesInit[iface.Name] = !!member_connection_for_interface(connection, iface); }); const [balancer, setBalancer] = useState(config.balancer); const [dialogError, setDialogError] = useState(undefined); const [iface, setIface] = useState(settings.connection.interface_name); const [linkDownDelay, setLinkDownDelay] = useState(config.link_watch.delay_down); const [linkWatch, setLinkWatch] = useState(config.link_watch.name); const [linkUpDelay, setLinkUpDelay] = useState(config.link_watch.delay_up); const [memberChoices, setMemberChoices] = useState(memberChoicesInit); const [runner, setRunner] = useState(config.runner.name); const [pingTarget, setPingTarget] = useState(config.link_watch.target_host); const [pingInterval, setPingInterval] = useState(config.link_watch.interval); const [primary, setPrimary] = useState(undefined); const onSubmit = (ev) => { const createSettingsObj = () => ({ ...settings, connection: { ...settings.connection, id: iface, interface_name: iface, }, team: { ...settings.team, interface_name: iface, config: { ...settings.team.config, link_watch: { name: linkWatch, ...(linkWatch === 'ethtool' && { delay_up: linkUpDelay, delay_down: linkDownDelay, }), ...(linkWatch !== 'ethtool' && { interval: pingInterval, target_host: pingTarget, }), }, runner: { ...config.runner, name: runner, ...((runner === "loadbalance" || runner === "lacp") && { tx_balancer: balancer === 'none' ? {} : balancer }) } } } }); dialogSave({ model, dev, connection, members: memberChoices, membersInit: memberChoicesInit, settings: createSettingsObj(), setDialogError, onClose: Dialogs.close, }); // Prevent dialog from closing because of