diff --git a/src/lib/y2network/connection_config/bridge.rb b/src/lib/y2network/connection_config/bridge.rb new file mode 100644 index 000000000..75d2f5827 --- /dev/null +++ b/src/lib/y2network/connection_config/bridge.rb @@ -0,0 +1,46 @@ +# Copyright (c) [2019] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program 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 General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require "y2network/connection_config/base" + +module Y2Network + module ConnectionConfig + # Configuration for bridge connections + # + # @see https://www.kernel.org/doc/Documentation/networking/bridge.txt + class Bridge < Base + # @return [Array] + attr_accessor :ports + # @return [Boolean] whether spanning tree protocol is enabled or not + attr_accessor :stp + # @return [Integer] + attr_accessor :forward_delay + + def initialize + @ports = [] + @stp = false + @forward_delay = 0 + end + + def virtual? + true + end + end + end +end diff --git a/src/lib/y2network/sysconfig/connection_config_readers/bridge.rb b/src/lib/y2network/sysconfig/connection_config_readers/bridge.rb new file mode 100644 index 000000000..827e2d838 --- /dev/null +++ b/src/lib/y2network/sysconfig/connection_config_readers/bridge.rb @@ -0,0 +1,39 @@ +# Copyright (c) [2019] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program 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 General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require "y2network/sysconfig/connection_config_readers/base" + +module Y2Network + module Sysconfig + module ConnectionConfigReaders + # This class is able to build a ConnectionConfig::Bridge object given a + # SysconfigInterfaceFile object. + class Bridge < Base + private + + # @see Y2Network::Sysconfig::ConnectionConfigReaders::Base#update_connection_config + def update_connection_config(conn) + conn.ports = file.bridge_ports.split(" ") + conn.stp = file.bridge_stp + conn.forward_delay = file.bridge_forwarddelay + end + end + end + end +end diff --git a/src/lib/y2network/sysconfig/connection_config_writers/bridge.rb b/src/lib/y2network/sysconfig/connection_config_writers/bridge.rb new file mode 100644 index 000000000..37b41dd8d --- /dev/null +++ b/src/lib/y2network/sysconfig/connection_config_writers/bridge.rb @@ -0,0 +1,42 @@ +# Copyright (c) [2019] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program 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 General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require "y2network/sysconfig/connection_config_writers/base" + +module Y2Network + module Sysconfig + module ConnectionConfigWriters + # This class is responsible for writing the information from a + # ConnectionConfig::Bridge object to the underlying system. + class Bridge < Base + private + + # @see Y2Network::ConnectionConfigWriters::Base#update_file + # @param conn [Y2Network::ConnectionConfig::Bridge] Configuration to + # write + def update_file(conn) + file.bridge = "yes" + file.bridge_ports = conn.ports.join(" ") + file.bridge_forwarddelay = conn.forward_delay + file.bridge_stp = conn.stp ? "on" : "off" + end + end + end + end +end diff --git a/src/lib/y2network/sysconfig/interface_file.rb b/src/lib/y2network/sysconfig/interface_file.rb index 38c50aa35..bf1e829f6 100644 --- a/src/lib/y2network/sysconfig/interface_file.rb +++ b/src/lib/y2network/sysconfig/interface_file.rb @@ -254,6 +254,24 @@ def variable_name(param_name) # @return [String] VLAN ID define_variable(:vlan_id, :integer) + ## BRIDGE + + # @!attribute [r] bridge + # @return [String] whether the interface is a bridge or not + define_variable(:bridge) + + # @!attribute [r] bridge_ports + # @return [String] interfaces members of the bridge + define_variable(:bridge_ports) + + # @!attribute [r] bridge_stp + # @return [String] Spanning Tree Protocol ("off" or "on") + define_variable(:bridge_stp) + + # @!attribute [r] bridge_forwarddelay + # @return [Integer] + define_variable(:bridge_forwarddelay, :integer) + # Constructor # # @param interface [String] Interface interface @@ -302,8 +320,8 @@ def save # @return [Y2Network::InterfaceType] Interface's type depending on the file values def type return InterfaceType::DUMMY if @values["INTERFACETYPE"] == "dummy" + return InterfaceType::BRIDGE if @values["BRIDGE"] == "yes" return InterfaceType::BONDING if defined_variables.any? { |k| k.start_with?("BOND") } - return InterfaceType::BRIDGE if defined_variables.any? { |k| k.start_with?("BRIDGE") } return InterfaceType::WIRELESS if defined_variables.any? { |k| k.start_with?("WIRELESS") } return InterfaceType::VLAN if defined_variables.include? "ETHERDEVICE" return InterfaceType::INFINIBAND if defined_variables.include? "IPOIB_MODE" diff --git a/test/data/scr_read/etc/sysconfig/network/ifcfg-br0 b/test/data/scr_read/etc/sysconfig/network/ifcfg-br0 new file mode 100644 index 000000000..385fc11bd --- /dev/null +++ b/test/data/scr_read/etc/sysconfig/network/ifcfg-br0 @@ -0,0 +1,6 @@ +STARTMODE='auto' +BOOTPROTO='dhcp' +BRIDGE='yes' +BRIDGE_PORTS='eth0 eth1' +BRIDGE_STP='on' +BRIDGE_FORWARDDELAY='5' diff --git a/test/y2network/sysconfig/connection_config_readers/bridge_test.rb b/test/y2network/sysconfig/connection_config_readers/bridge_test.rb new file mode 100644 index 000000000..fe57a1536 --- /dev/null +++ b/test/y2network/sysconfig/connection_config_readers/bridge_test.rb @@ -0,0 +1,47 @@ +# Copyright (c) [2019] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program 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 General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require_relative "../../../test_helper" +require "y2network/sysconfig/connection_config_readers/bridge" +require "y2network/sysconfig/interface_file" + +describe Y2Network::Sysconfig::ConnectionConfigReaders::Bridge do + subject(:handler) { described_class.new(file) } + + let(:scr_root) { File.join(DATA_PATH, "scr_read") } + + around do |example| + change_scr_root(scr_root, &example) + end + + let(:interface_name) { "br0" } + let(:file) do + Y2Network::Sysconfig::InterfaceFile.find(interface_name).tap(&:load) + end + + describe "#connection_config" do + it "returns a bridge connection config object" do + bridge_conn = handler.connection_config + expect(bridge_conn.interface).to eq("br0") + expect(bridge_conn.ports).to eq(["eth0", "eth1"]) + expect(bridge_conn.stp).to eq("on") + expect(bridge_conn.forward_delay).to eq(5) + end + end +end diff --git a/test/y2network/sysconfig/connection_config_writers/bridge_test.rb b/test/y2network/sysconfig/connection_config_writers/bridge_test.rb new file mode 100644 index 000000000..fc1a9d0df --- /dev/null +++ b/test/y2network/sysconfig/connection_config_writers/bridge_test.rb @@ -0,0 +1,84 @@ +# Copyright (c) [2019] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program 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 General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require_relative "../../../test_helper" + +require "y2network/sysconfig/connection_config_writers/bridge" +require "y2network/sysconfig/interface_file" +require "y2network/startmode" +require "y2network/boot_protocol" +require "y2network/connection_config/bridge" + +describe Y2Network::Sysconfig::ConnectionConfigWriters::Bridge do + subject(:handler) { described_class.new(file) } + + def file_content(scr_root, file) + path = File.join(scr_root, file.path.to_s) + File.read(path) + end + + let(:scr_root) { Dir.mktmpdir } + + around do |example| + begin + FileUtils.cp_r(File.join(DATA_PATH, "scr_read", "etc"), scr_root) + change_scr_root(scr_root, &example) + ensure + FileUtils.remove_entry(scr_root) + end + end + + let(:conn) do + instance_double( + Y2Network::ConnectionConfig::Bridge, + name: "br1", + interface: "br1", + description: "", + startmode: Y2Network::Startmode.create("auto"), + bootproto: Y2Network::BootProtocol::DHCP, + ip_configs: [], + ports: ["eth0", "eth1"], + stp: false, + forward_delay: 5 + ) + end + + let(:file) { Y2Network::Sysconfig::InterfaceFile.new(conn.name) } + + describe "#write" do + it "writes common properties" do + handler.write(conn) + expect(file).to have_attributes( + name: conn.description, + startmode: "auto", + bootproto: "dhcp" + ) + end + + it "writes bridge properties" do + handler.write(conn) + expect(file).to have_attributes( + bridge: "yes", + bridge_ports: "eth0 eth1", + bridge_forwarddelay: 5, + bridge_stp: "off" + ) + end + end +end