<commit_before>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2021 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */
import cockpit from "cockpit";
import React, { useContext } from "react";
import {
    Breadcrumb, BreadcrumbItem,
    Button,
    Card, CardActions, CardBody, CardTitle, CardHeader,
    Checkbox,
    DescriptionList, DescriptionListTerm, DescriptionListGroup, DescriptionListDescription,
    Gallery,
    Page, PageSection, PageSectionVariants,
    Switch,
} from "@patternfly/react-core";

import { ModelContext } from './model-context.jsx';
import { NetworkInterfaceMembers } from "./network-interface-members.jsx";
import { NetworkAction } from './dialogs-common.jsx';
import { NetworkPlots } from "./plots";
import { fmt_to_fragments } from 'utils.jsx';

import {
    array_join,
    choice_title,
    complete_settings,
    connection_settings,
    free_member_connection,
    is_managed,
    render_active_connection,
    settings_applier,
    show_unexpected_error,
    syn_click,
    with_checkpoint,
} from './interfaces.js';
import {
    team_runner_choices,
    team_watch_choices,
} from './team.jsx';
import {
    bond_mode_choices,
} from './bond.jsx';
import {
    ipv4_method_choices, ipv6_method_choices,
} from './ip-settings.jsx';

const _ = cockpit.gettext;

export const NetworkInterfacePage = ({
    privileged,
    operationInProgress,
    usage_monitor,
    plot_state,
    interfaces,
    iface
}) => {
    const model = useContext(ModelContext);

    const dev_name = iface.Name;
    const dev = iface.Device;
    const isManaged = iface && (!dev || is_managed(dev));

    let ghostSettings = null;
    let connectionSettings = null;

    if (iface) {
        if (iface.MainConnection) {
            connectionSettings = iface.MainConnection.Settings;
        } else {
            ghostSettings = createGhostConnectionSettings();
            connectionSettings = ghostSettings;
        }
    }

    function deleteConnections() {
        function deleteConnectionAndMembers(con) {
            return Promise.all(con.Members.map(s => free_member_connection(s))).then(() => con.delete_());
        }

        function deleteConnections(cons) {
            return Promise.all(cons.map(deleteConnectionAndMembers));
        }

        function deleteIfaceConnections(iface) {
            return deleteConnections(iface.Connections);
        }

        const location = cockpit.location;

        function modify() {
            return deleteIfaceConnections(iface)
                    .then(function () {
                        location.go("/");
                    })
                    .catch(show_unexpected_error);
        }

        if (iface) {
            with_checkpoint(model, modify,
                            {
                                devices: dev ? [dev] : [],
                                fail_text: fmt_to_fragments(_("Deleting $0 will break the connection to the server, and will make the administration UI unavailable."), <b>{dev_name}</b>),
                                anyway_text: cockpit.format(_("Delete $0"), dev_name),
                                hack_does_add_or_remove: true,
                                rollback_on_failure: true
                            });
        }
    }

    function connect() {
        if (!(iface.MainConnection || (dev && ghostSettings)))
            return;

        function fail(error) {
            show_unexpected_error(error);
        }

        function modify() {
            if (iface.MainConnection) {
                return iface.MainConnection.activate(dev, null).fail(fail);
            } else {
                return dev.activate_with_settings(ghostSettings, null).fail(fail);
            }
        }

        with_checkpoint(model, modify,
                        {
                            devices: dev ? [dev] : [],
                            fail_text: fmt_to_fragments(_("Switching on $0 will break the connection to the server, and will make the administration UI unavailable."), <b>{dev_name}</b>),
                            anyway_text: cockpit.format(_("Switch on $0"), dev_name)
                        });
    }

    function disconnect() {
        if (!dev) {
            console.log("Trying to switch off without a device?");
            return;
        }

        function modify () {
            return dev.disconnect()
                    .fail(function (error) {
                        show_unexpected_error(error);
                    });
        }

        with_checkpoint(model, modify,
                        {
                            devices: [dev],
                            fail_text: fmt_to_fragments(_("Switching off $0 will break the connection to the server, and will make the administration UI unavailable."), <b>{dev_name}</b>),
                            anyway_text: cockpit.format(_("Switch off $0"), dev_name)
                        });
    }

    function renderDesc() {
        let desc, cs;
        if (dev) {
            if (dev.DeviceType == 'ethernet' || dev.IdVendor || dev.IdModel) {
                desc = cockpit.format("$IdVendor $IdModel $Driver", dev);
            } else if (dev.DeviceType == 'bond') {
                desc = _("Bond");
            } else if (dev.DeviceType == 'team') {
                desc = _("Team");
            } else if (dev.DeviceType == 'vlan') {
                desc = _("VLAN");
            } else if (dev.DeviceType == 'bridge') {
                desc = _("Bridge");
            } else
                desc = cockpit.format(_("Unknown \"$0\""), dev.DeviceType);
        } else if (iface) {
            cs = connection_settings(iface.Connections[0]);
            if (cs.type == "bond")
                desc = _("Bond");
            else if (cs.type == "team")
                desc = _("Team");
            else if (cs.type == "vlan")
                desc = _("VLAN");
            else if (cs.type == "bridge")
                desc = _("Bridge");
            else if (cs.type)
                desc = cockpit.format(_("Unknown \"$0\""), cs.type);
            else
                desc = _("Unknown");
        } else
            desc = _("Unknown");
<commit_msg>networkmanager: show Wireguard device type<commit_after>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2021 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */
import cockpit from "cockpit";
import React, { useContext } from "react";
import {
    Breadcrumb, BreadcrumbItem,
    Button,
    Card, CardActions, CardBody, CardTitle, CardHeader,
    Checkbox,
    DescriptionList, DescriptionListTerm, DescriptionListGroup, DescriptionListDescription,
    Gallery,
    Page, PageSection, PageSectionVariants,
    Switch,
} from "@patternfly/react-core";

import { ModelContext } from './model-context.jsx';
import { NetworkInterfaceMembers } from "./network-interface-members.jsx";
import { NetworkAction } from './dialogs-common.jsx';
import { NetworkPlots } from "./plots";
import { fmt_to_fragments } from 'utils.jsx';

import {
    array_join,
    choice_title,
    complete_settings,
    connection_settings,
    free_member_connection,
    is_managed,
    render_active_connection,
    settings_applier,
    show_unexpected_error,
    syn_click,
    with_checkpoint,
} from './interfaces.js';
import {
    team_runner_choices,
    team_watch_choices,
} from './team.jsx';
import {
    bond_mode_choices,
} from './bond.jsx';
import {
    ipv4_method_choices, ipv6_method_choices,
} from './ip-settings.jsx';

const _ = cockpit.gettext;

export const NetworkInterfacePage = ({
    privileged,
    operationInProgress,
    usage_monitor,
    plot_state,
    interfaces,
    iface
}) => {
    const model = useContext(ModelContext);

    const dev_name = iface.Name;
    const dev = iface.Device;
    const isManaged = iface && (!dev || is_managed(dev));

    let ghostSettings = null;
    let connectionSettings = null;

    if (iface) {
        if (iface.MainConnection) {
            connectionSettings = iface.MainConnection.Settings;
        } else {
            ghostSettings = createGhostConnectionSettings();
            connectionSettings = ghostSettings;
        }
    }

    function deleteConnections() {
        function deleteConnectionAndMembers(con) {
            return Promise.all(con.Members.map(s => free_member_connection(s))).then(() => con.delete_());
        }

        function deleteConnections(cons) {
            return Promise.all(cons.map(deleteConnectionAndMembers));
        }

        function deleteIfaceConnections(iface) {
            return deleteConnections(iface.Connections);
        }

        const location = cockpit.location;

        function modify() {
            return deleteIfaceConnections(iface)
                    .then(function () {
                        location.go("/");
                    })
                    .catch(show_unexpected_error);
        }

        if (iface) {
            with_checkpoint(model, modify,
                            {
                                devices: dev ? [dev] : [],
                                fail_text: fmt_to_fragments(_("Deleting $0 will break the connection to the server, and will make the administration UI unavailable."), <b>{dev_name}</b>),
                                anyway_text: cockpit.format(_("Delete $0"), dev_name),
                                hack_does_add_or_remove: true,
                                rollback_on_failure: true
                            });
        }
    }

    function connect() {
        if (!(iface.MainConnection || (dev && ghostSettings)))
            return;

        function fail(error) {
            show_unexpected_error(error);
        }

        function modify() {
            if (iface.MainConnection) {
                return iface.MainConnection.activate(dev, null).fail(fail);
            } else {
                return dev.activate_with_settings(ghostSettings, null).fail(fail);
            }
        }

        with_checkpoint(model, modify,
                        {
                            devices: dev ? [dev] : [],
                            fail_text: fmt_to_fragments(_("Switching on $0 will break the connection to the server, and will make the administration UI unavailable."), <b>{dev_name}</b>),
                            anyway_text: cockpit.format(_("Switch on $0"), dev_name)
                        });
    }

    function disconnect() {
        if (!dev) {
            console.log("Trying to switch off without a device?");
            return;
        }

        function modify () {
            return dev.disconnect()
                    .fail(function (error) {
                        show_unexpected_error(error);
                    });
        }

        with_checkpoint(model, modify,
                        {
                            devices: [dev],
                            fail_text: fmt_to_fragments(_("Switching off $0 will break the connection to the server, and will make the administration UI unavailable."), <b>{dev_name}</b>),
                            anyway_text: cockpit.format(_("Switch off $0"), dev_name)
                        });
    }

    function renderDesc() {
        let desc, cs;
        if (dev) {
            if (dev.DeviceType == 'ethernet' || dev.IdVendor || dev.IdModel) {
                desc = cockpit.format("$IdVendor $IdModel $Driver", dev);
            } else if (dev.DeviceType == 'bond') {
                desc = _("Bond");
            } else if (dev.DeviceType == 'team') {
                desc = _("Team");
            } else if (dev.DeviceType == 'vlan') {
                desc = _("VLAN");
            } else if (dev.DeviceType == 'bridge') {
                desc = _("Bridge");
            } else if (dev.Driver == 'wireguard') {
                desc = "WireGuard";
            } else
                desc = cockpit.format(_("Unknown \"$0\""), dev.DeviceType);
        } else if (iface) {
            cs = connection_settings(iface.Connections[0]);
            if (cs.type == "bond")
                desc = _("Bond");
            else if (cs.type == "team")
                desc = _("Team");
            else if (cs.type == "vlan")
                desc = _("VLAN");
            else if (cs.type == "bridge")
                desc = _("Bridge");
            else if (cs.type == "wireguard")
                desc = "WireGuard";
            else if (cs.type)
                desc = cockpit.format(_("Unknown \"$0\""), cs.type);
            else
                desc = _("Unknown");
        } else
            desc = _("Unknown");

{'fraction_non_alphanumeric': 0.10923944476576056, 'fraction_numerical': 0.0024580682475419317, 'mean_word_length': 1.8410351201478743, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5513173', 'n_tokens_mistral': 3748, 'n_tokens_neox': 3617, 'n_words': 966}