Hello community, here is the log from the commit of package yast2-network for openSUSE:Factory checked in at 2019-02-15 09:53:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-network (Old) and /work/SRC/openSUSE:Factory/.yast2-network.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-network" Fri Feb 15 09:53:27 2019 rev:402 rq:674412 version:4.1.39 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-network/yast2-network.changes 2019-02-11 21:17:05.299346748 +0100 +++ /work/SRC/openSUSE:Factory/.yast2-network.new.28833/yast2-network.changes 2019-02-15 09:53:27.607796768 +0100 @@ -1,0 +2,17 @@ +Tue Feb 12 13:21:39 CET 2019 - [email protected] + +- AutoYaST in running system: Do not reset /etc/hosts (bsc#1122658) +- 4.1.39 + +------------------------------------------------------------------- +Thu Feb 7 13:13:21 UTC 2019 - [email protected] + +- fate#324662 + - Drop SuSEFirewall2 code completely. + - Permits to choose not only default firewalld zones but also + custom ones. + - Allow the user to select the "DEFAULT" zone or disable the + interface zone mapping through ifcfg files per interface. +- 4.1.38 + +------------------------------------------------------------------- Old: ---- yast2-network-4.1.37.tar.bz2 New: ---- yast2-network-4.1.39.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-network.spec ++++++ --- /var/tmp/diff_new_pack.CfzHGq/_old 2019-02-15 09:53:28.011796641 +0100 +++ /var/tmp/diff_new_pack.CfzHGq/_new 2019-02-15 09:53:28.019796639 +0100 @@ -17,7 +17,7 @@ Name: yast2-network -Version: 4.1.37 +Version: 4.1.39 Release: 0 BuildArch: noarch @@ -31,9 +31,9 @@ #for install task BuildRequires: rubygem(%rb_default_ruby_abi:yast-rake) -# Yast::Execute.stdout.on_target! -BuildRequires: yast2 >= 4.1.42 -Requires: yast2 >= 4.1.42 +# Y2Firewall interface zone mapping methods +BuildRequires: yast2 >= 4.1.53 +Requires: yast2 >= 4.1.53 # Product control need xml agent BuildRequires: yast2-xml @@ -100,6 +100,7 @@ %{yast_schemadir}/autoyast/rnc/networking.rnc %{yast_schemadir}/autoyast/rnc/host.rnc %{yast_libdir}/network +%{yast_libdir}/y2network %{yast_libdir}/y2remote %{yast_libdir}/cfa/ %{yast_ydatadir}/network ++++++ yast2-network-4.1.37.tar.bz2 -> yast2-network-4.1.39.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/package/yast2-network.changes new/yast2-network-4.1.39/package/yast2-network.changes --- old/yast2-network-4.1.37/package/yast2-network.changes 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/package/yast2-network.changes 2019-02-13 09:23:15.000000000 +0100 @@ -1,4 +1,21 @@ ------------------------------------------------------------------- +Tue Feb 12 13:21:39 CET 2019 - [email protected] + +- AutoYaST in running system: Do not reset /etc/hosts (bsc#1122658) +- 4.1.39 + +------------------------------------------------------------------- +Thu Feb 7 13:13:21 UTC 2019 - [email protected] + +- fate#324662 + - Drop SuSEFirewall2 code completely. + - Permits to choose not only default firewalld zones but also + custom ones. + - Allow the user to select the "DEFAULT" zone or disable the + interface zone mapping through ifcfg files per interface. +- 4.1.38 + +------------------------------------------------------------------- Wed Feb 6 14:16:54 UTC 2019 - [email protected] - bsc#1124002 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/package/yast2-network.spec new/yast2-network-4.1.39/package/yast2-network.spec --- old/yast2-network-4.1.37/package/yast2-network.spec 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/package/yast2-network.spec 2019-02-13 09:23:15.000000000 +0100 @@ -17,7 +17,7 @@ Name: yast2-network -Version: 4.1.37 +Version: 4.1.39 Release: 0 BuildArch: noarch @@ -31,9 +31,9 @@ #for install task BuildRequires: rubygem(%rb_default_ruby_abi:yast-rake) -# Yast::Execute.stdout.on_target! -BuildRequires: yast2 >= 4.1.42 -Requires: yast2 >= 4.1.42 +# Y2Firewall interface zone mapping methods +BuildRequires: yast2 >= 4.1.53 +Requires: yast2 >= 4.1.53 # Product control need xml agent BuildRequires: yast2-xml @@ -100,6 +100,7 @@ %{yast_schemadir}/autoyast/rnc/networking.rnc %{yast_schemadir}/autoyast/rnc/host.rnc %{yast_libdir}/network +%{yast_libdir}/y2network %{yast_libdir}/y2remote %{yast_libdir}/cfa/ %{yast_ydatadir}/network diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/data/network/sysconfig_defaults.yml new/yast2-network-4.1.39/src/data/network/sysconfig_defaults.yml --- old/yast2-network-4.1.37/src/data/network/sysconfig_defaults.yml 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/src/data/network/sysconfig_defaults.yml 2019-02-13 09:23:15.000000000 +0100 @@ -42,4 +42,3 @@ TUNNEL_SET_OWNER: '' TUNNEL_SET_GROUP: '' BRIDGE_PORTS: '' -ZONE: '' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/include/network/lan/address.rb new/yast2-network-4.1.39/src/include/network/lan/address.rb --- old/yast2-network-4.1.37/src/include/network/lan/address.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/src/include/network/lan/address.rb 2019-02-13 09:23:15.000000000 +0100 @@ -27,10 +27,12 @@ # Authors: Michal Svec <[email protected]> # require "ui/text_helpers" -require "y2firewall/firewalld" +require "y2firewall/helpers/interfaces" +require "y2network/widgets/firewall_zone" module Yast module NetworkLanAddressInclude + include Y2Firewall::Helpers::Interfaces include Yast::Logger include ::UI::TextHelpers @@ -54,7 +56,6 @@ Yast.import "ProductFeatures" Yast.import "Routing" Yast.import "String" - Yast.import "SuSEFirewall4Network" Yast.import "Wizard" Yast.import "Map" @@ -132,14 +133,6 @@ "opt" => [:hstretch], "help" => _("<p>TODO kind of vague!</p>") }, - "FWZONE" => { - "widget" => :combobox, - # Combo Box label - "label" => _("Assign Interface to Firewall &Zone"), - "opt" => [:hstretch], - "help" => Ops.get_string(@help, "fwzone", ""), - "init" => fun_ref(method(:InitFwZone), "void (string)") - }, "MANDATORY" => { "widget" => :checkbox, # check box label @@ -1046,23 +1039,6 @@ true end - # Initialize value of firewall zone widget - # (disables it when SuSEFirewall is not installed) - # @param _key [String] id of the widget - def InitFwZone(_key) - if SuSEFirewall4Network.IsInstalled - UI.ChangeWidget( - Id("FWZONE"), - :Value, - Ops.get_string(@settings, "FWZONE", "") - ) - else - UI.ChangeWidget(Id("FWZONE"), :Enabled, false) - end - - nil - end - # @param [Array<String>] types network card types # @return their descriptions for CWM def BuildTypesListCWM(types) @@ -1280,8 +1256,6 @@ ] ) - wd["FWZONE"]["items"] = firewall_zones - if LanItems.GetCurrentType == "ib" wd["IPOIB_MODE"] = ipoib_mode_widget wd["MTU"]["items"] = ipoib_mtu_items @@ -1290,6 +1264,9 @@ end @settings["IFCFG"] = LanItems.device if LanItems.operation != :add + firewall_zone = Y2Network::Widgets::FirewallZone.new(LanItems.device) + wd["FWZONE"] = firewall_zone.cwm_definition + firewall_zone.value = @settings["FWZONE"] if firewalld.installed? functions = { "init" => fun_ref(method(:InitAddrWidget), "void (string)"), @@ -1358,8 +1335,8 @@ if ret != :back && ret != :abort # general tab LanItems.startmode = Ops.get_string(@settings, "STARTMODE", "") - LanItems.firewall_zone = @settings.fetch("FWZONE", "") LanItems.mtu = Ops.get_string(@settings, "MTU", "") + LanItems.firewall_zone = firewall_zone.store_permanent if firewalld.installed? # address tab bootproto = @settings.fetch("BOOTPROTO", "") @@ -1427,8 +1404,8 @@ "STARTMODE" => LanItems.startmode, "IFPLUGD_PRIORITY" => LanItems.ifplugd_priority, # problems when renaming the interface? - "FWZONE" => LanItems.firewall_zone, "MTU" => LanItems.mtu, + "FWZONE" => LanItems.firewall_zone, # address tab: "BOOTPROTO" => LanItems.bootproto, "IPADDR" => LanItems.ipaddr, @@ -1549,30 +1526,5 @@ String.FirstChunk(Ops.get(host_list, 0, ""), " \t") end - - # Return a list of items for ComboBox with all the known firewalld zones - # and also an empty string option for the default zone. - # - # @return [Array <Array <String, String>>] list of names an description of - # known zones - def firewall_zones - zones = [["", _("Automatically Assigned Zone")]] - if firewalld.installed? - Y2Firewall::Firewalld::Zone.known_zones.map do |name, full_name| - zones << [name, Builtins.dgettext("base", full_name)] - end - else - zones = [["", _("Firewall is not installed.")]] - end - - zones - end - - # Convenience method which returns an instance of Y2Firewall::Firewalld - # - # @return [Y2Firewall::Firewalld] instance - def firewalld - @firewalld ||= Y2Firewall::Firewalld.instance - end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/include/network/lan/help.rb new/yast2-network-4.1.39/src/include/network/lan/help.rb --- old/yast2-network-4.1.37/src/include/network/lan/help.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/src/include/network/lan/help.rb 2019-02-13 09:23:15.000000000 +0100 @@ -223,16 +223,6 @@ _( "<p>DHCP configuration is not recommended for this product.\nComponents of this product might not work with DHCP.</p>" ), - "fwzone" => - _( - "<p><b><big>Firewall Zone</big></b></p>\n" \ - "<p>Select the firewall zone to put the interface into. If you\n" \ - "select a zone, the firewall will be enabled. If you do not and other \n" \ - "firewalled interfaces exist, the firewall\n" \ - "will stay enabled but all traffic will be blocked for this\n" \ - "interface. If you do not select a zone and no others exist, \n" \ - "the firewall will be disabled.</p>" - ), "mandatory" => _( "<p><b>Mandatory Interface</b> specifies whether the network service reports failure if the interface fails to start at boot time.</p>" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/include/network/widgets.rb new/yast2-network-4.1.39/src/include/network/widgets.rb --- old/yast2-network-4.1.37/src/include/network/widgets.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/src/include/network/widgets.rb 2019-02-13 09:23:15.000000000 +0100 @@ -248,14 +248,6 @@ } end - def firewall_widget - if SuSEFirewall4Network.IsInstalled - SuSEFirewall4Network.FirewallZonesComboBoxItems - else - [["", _("Firewall is not installed.")]] - end - end - def common_mtu_items [ # translators: MTU value description (size in bytes, desc) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/lib/y2network/widgets/firewall_zone.rb new/yast2-network-4.1.39/src/lib/y2network/widgets/firewall_zone.rb --- old/yast2-network-4.1.37/src/lib/y2network/widgets/firewall_zone.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-network-4.1.39/src/lib/y2network/widgets/firewall_zone.rb 2019-02-13 09:23:15.000000000 +0100 @@ -0,0 +1,217 @@ +# encoding: utf-8 +# +# 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 "cwm" +require "y2firewall/firewalld" +require "y2firewall/helpers/interfaces" +require "y2firewall/firewalld/interface" + +module Y2Network + module Widgets + # This widget offers a checkbox for enabling the firewalld interface ZONE + # mapping through the ifcfg file and a selection list for choose the ZONE + # to be used. + class FirewallZone < ::CWM::CustomWidget + include Y2Firewall::Helpers::Interfaces + + # Constructor + # + # @param name [String] + def initialize(name) + textdomain "network" + @value = nil + @interface = Y2Firewall::Firewalld::Interface.new(name) + end + + # @see CWM::AbstractWidget + # @return [String] + def label + # TRANSLATORS: label for Firewall ZONE assignment + _("Assign Interface to Firewall &Zone") + end + + # @see CWM::AbstractWidget + def init + return unless installed? + + populate_select(firewall_zones) + self.value = @value + end + + # @see CWM::AbstractWidget + def contents + # TRANSLATORS: firewall is not installed label + return Label(_("Firewall is not installed.")) unless installed? + + Left(zones_widget) + end + + # Stores the given name and when it is enabled to configure the + # interface ZONE through the ifcfg file. It also selects the given zone + # in the select list + # + # @see CWM::AbstractWidget + # @param name [String,nil] zone name + def value=(name) + @value = name + return unless installed? + select_zone(name) + end + + # It returns the current ZONE selection or nil in case of not enabled + # the management through the ifcfg files. + # + # @return [String, nil] current zone or nil when not managed + def value + return @value unless Yast::UI.WidgetExists(Id(:zones)) + selected_zone + end + + # Stores the current value + # + # @see CWM::AbstractWidget + # @return [String, nil] + def store + @value = value + end + + # Stores the selected zone permanently when it has change and it is + # enabled to be managed through the ifcfg files + # + # @return [String, nil] the current zone selection + def store_permanent + return @value unless installed? + + @interface.zone = @value if zone_changed? + @value + end + + # @see CWM::AbstractWidget + def help + help_text = + # TRANSLATORS: Firewall ZONE widget help description + _("<p><b><big>FIREWALL ZONE</big></b></p>" \ + "<p>A network zone defines the level of trust for network connections. " \ + "The selected ZONE will be added to the ifcfg as well as the firewalld " \ + "permanent configuration.</p>") + + help_text << zones_help if installed? + help_text + end + + private + + # Return whether the permanent ZONE match or not the selected one. + # + # @return [Boolean] + def zone_changed? + @value && (current_zone.to_s != @value) + end + + # @return [String] + def default_label + # TRANSLATORS: List item describing an assigment of the interface + # to the default ZONE + _("Assign to the default ZONE") + end + + # @return [String] + def no_zone_label + # TRANSLATORS: List item to no interface ZONE assignment + _("Do not assign ZONE") + end + + # Current {Y2Firewall::Firewalld::Interface} name + # @return [String, nil] + def current_zone + return unless @interface.zone + @interface.zone.name + end + + # @return [Yast::Term] zones select list + def zones_widget + ComboBox(Id(:zones), Opt(:notify, :hstretch), label) + end + + # Convenince method to select an specific zone from the zones list + # + # @param zone [String] + def select_zone(zone) + Yast::UI.ChangeWidget(Id(:zones), :Value, zone) + end + + # Convenince method which returns the selected zone from the zones list + # + # @return [String, nil] + def selected_zone + Yast::UI.QueryWidget(Id(:zones), :Value) + end + + # @param zones [Array <Array <String, String>>] list of available zones + # names + def populate_select(zones) + items = zones.map { |z| Item(Id(z[0]), z[1]) } + Yast::UI.ChangeWidget(Id(:zones), :Items, items) + end + + # Return a list of items for ComboBox with all the known firewalld zones + # and also an empty string option for the default zone. + # + # @return [Array <Array <String, String>>] list of names an description of + # available zones + def firewall_zones + zones = [[nil, no_zone_label], ["", default_label]] + firewalld.zones.each { |z| zones << [z.name, z.name] } + zones + end + + # Convenience method to check whether firewalld is installed or not + # + # @return [Boolean] whether firewalld is installed or not + def installed? + @installed ||= firewalld.installed? + end + + # Help text with the description of the available zones + # + # @return [String] zones help description + def zones_help + description = firewalld.zones.map { |z| zone_description(z) } + return "" if description.empty? + + # TRANSLATORS: Firewall zones description (%s are list element with + # each of the zones decription) + _("<p>Find below the available zones description: <ul>%s</ul></p>") % description.join + end + + # Return the description of the given zone as a HTML list entry + # + # @param zone [Y2Firewall::Firewalld::Zone] + # @return [String] zone description + def zone_description(zone) + "<li><b>#{zone.short}: </b>" \ + "#{zone.description} " \ + "(Masquerade: #{zone.masquerade? ? "yes" : "no"})" \ + "</li>" + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/modules/Host.rb new/yast2-network-4.1.39/src/modules/Host.rb --- old/yast2-network-4.1.37/src/modules/Host.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/src/modules/Host.rb 2019-02-13 09:23:15.000000000 +0100 @@ -45,6 +45,8 @@ @initialized = false @hosts = CFA::Hosts.new + + @configuration_imported = false end # Remove all entries from the host table. @@ -52,6 +54,7 @@ @hosts.hosts.keys.each do |ip| @hosts.delete_by_ip(ip) end + @configuration_imported = false end # @return [hash] address->list of names @@ -142,6 +145,12 @@ @hosts.save + # Reset that the configuration has been taken from AY file because the settings + # are now on the target system. + @configuration_imported = false + # Syncing after the settings have been written. + @initial_hosts = @hosts.clone + Progress.NextStage if gui true @@ -156,6 +165,7 @@ # @return true if success def Import(settings) @initialized = true # don't let Read discard our data + @configuration_imported = true if settings.key?("hosts") load_hosts(load_only: true) @@ -298,10 +308,8 @@ # Function which returns if the settings were modified # @return [Boolean] settings were modified def GetModified - # when importing AY profile @initial_hosts is not initialized - # bcs it would be the same as @hosts and modification would not be detected - return true if @hosts && @initial_hosts.nil? - @hosts.hosts != @initial_hosts.hosts + return true if @configuration_imported # hosts section has been imported. + @initial_hosts && (@hosts.hosts != @initial_hosts.hosts) end publish function: :NeedDummyIP, type: "boolean ()" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/modules/Lan.rb new/yast2-network-4.1.39/src/modules/Lan.rb --- old/yast2-network-4.1.37/src/modules/Lan.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/src/modules/Lan.rb 2019-02-13 09:23:15.000000000 +0100 @@ -32,6 +32,7 @@ require "yast" require "network/confirm_virt_proposal" require "ui/text_helpers" +require "y2firewall/firewalld" require "shellwords" @@ -226,6 +227,30 @@ ipv6 end + def read_step_labels + steps = [ + # Progress stage 1/8 + _("Detect network devices"), + # Progress stage 2/8 + _("Read driver information"), + # Progress stage 3/8 - multiple devices may be present, really plural + _("Read device configuration"), + # Progress stage 4/8 + _("Read network configuration"), + # Progress stage 5/8 + _("Read hostname and DNS configuration"), + # Progress stage 6/8 + _("Read installation information"), + # Progress stage 7/8 + _("Read routing configuration"), + # Progress stage 8/8 + _("Detect current status") + ] + + steps << _("Read firewall configuration") if firewalld.installed? + steps + end + # Read all network settings from the SCR # @param cache [Symbol] :cache=use cached data, :nocache=reread from disk TODO pass to submodules # @return true on success @@ -237,7 +262,6 @@ # Read dialog caption caption = _("Initializing Network Configuration") - steps = 9 sl = 0 # 1000; /* TESTING Builtins.sleep(sl) @@ -246,25 +270,8 @@ Progress.New( caption, " ", - steps, - [ - # Progress stage 1/8 - _("Detect network devices"), - # Progress stage 2/8 - _("Read driver information"), - # Progress stage 3/8 - multiple devices may be present, really plural - _("Read device configuration"), - # Progress stage 4/8 - _("Read network configuration"), - # Progress stage 5/8 - _("Read hostname and DNS configuration"), - # Progress stage 6/8 - _("Read installation information"), - # Progress stage 8/8 - _("Read routing configuration"), - # Progress stage 9/8 - _("Detect current status") - ], + read_step_labels.size, + read_step_labels, [], "" ) @@ -349,6 +356,13 @@ Builtins.sleep(sl) return false if Abort() + if firewalld.installed? && !firewalld.read? + ProgressNextStage(_("Reading firewall configuration...")) if @gui + firewalld.read + Builtins.sleep(sl) + end + + return false if Abort() rescue IOError, SystemCallError, RuntimeError => error msg = format(_("Network configuration is corrupted.\n"\ "If you continue resulting configuration can be malformed."\ @@ -393,6 +407,7 @@ end def writeIPv6 + log.info("writeIPv6: IPv6 is #{@ipv6 ? "enabled" : "disabled"}") filename = "/etc/sysctl.conf" sysctl = Convert.to_string(SCR.Read(path(".target.string"), filename)) sysctl_row = Builtins.sformat( @@ -468,6 +483,9 @@ _("Set up network services") ] + # Progress stage 8 + step_labels << _("Writing firewall configuration") if firewalld.installed? + # Progress stage 9 if !@write_only step_labels = Builtins.add(step_labels, _("Activate network services")) @@ -528,6 +546,14 @@ writeIPv6 Builtins.sleep(sl) + if firewalld.installed? + return false if Abort() + # Progress step 7 + ProgressNextStage(_("Writing firewall configuration...")) + firewalld.write + Builtins.sleep(sl) + end + if !@write_only return false if Abort() # Progress step 9 @@ -1061,6 +1087,10 @@ # cache was edited directly, LanItems is not aware of changes. LanItems.SetModified end + + def firewalld + Y2Firewall::Firewalld.instance + end end Lan = LanClass.new diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/modules/LanItems.rb new/yast2-network-4.1.39/src/modules/LanItems.rb --- old/yast2-network-4.1.37/src/modules/LanItems.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/src/modules/LanItems.rb 2019-02-13 09:23:15.000000000 +0100 @@ -125,6 +125,7 @@ @wl_key = [] @wl_default_key = 0 @wl_nick = "" + @firewall_zone = nil # FIXME: We should unify bridge_ports and bond_slaves variables @@ -2142,8 +2143,10 @@ newdev["INTERFACETYPE"] = @type end - current_map = (GetCurrentMap() || {}).select { |_, v| !v.nil? && !v.empty? } - new_map = newdev.select { |_, v| !v.nil? && !v.empty? } + # ZONE uses an empty string as the default ZONE which means that is not + # the same than not defining the attribute + current_map = (GetCurrentMap() || {}).select { |k, v| !v.nil? && (k == "ZONE" || !v.empty?) } + new_map = newdev.select { |k, v| !v.nil? && (k == "ZONE" || !v.empty?) } # CanonicalizeIP is called to get new device map into the same shape as # NetworkInterfaces provides the current one. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/src/modules/SuSEFirewall4Network.rb new/yast2-network-4.1.39/src/modules/SuSEFirewall4Network.rb --- old/yast2-network-4.1.37/src/modules/SuSEFirewall4Network.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/src/modules/SuSEFirewall4Network.rb 1970-01-01 01:00:00.000000000 +0100 @@ -1,360 +0,0 @@ -# encoding: utf-8 - -# *************************************************************************** -# -# Copyright (c) 2012 Novell, Inc. -# 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 Novell, Inc. -# -# To contact Novell about this file by physical or electronic mail, -# you may find current contact information at www.novell.com -# -# ************************************************************************** -# Copyright 2004, Novell, Inc. All rights reserved. -# -# File: modules/SuSEFirewall4Network.ycp -# Package: Network Configuration -# Summary: Module for handling interfaces in SuSEfirewall2 -# Authors: Lukas Ocilka <[email protected]> -# -# -# Module for handling network interfaces in SuSEfirewall2 using SuSEFirewall -# module. -require "yast" - -module Yast - class SuSEFirewall4NetworkClass < Module - include Yast::Logger - - SSH_PACKAGE = "openssh".freeze - SSH_SERVICES = ["service:sshd"].freeze - VNC_SERVICES = ["service:vnc-httpd", "service:vnc-server"].freeze - - def main - textdomain "network" - - Yast.import "SuSEFirewall" - Yast.import "SuSEFirewallProposal" - Yast.import "Stage" - Yast.import "ServicesProposal" - Yast.import "Linuxrc" - Yast.import "ProductFeatures" - Yast.import "Pkg" - - @firewall_enabled_1st_stage = false - @ssh_enabled_1st_stage = false - @sshd_enabled = false - @vnc_enabled_1st_stage = false - end - - # Function reads configuration of SuSEFirewall. - # - # @return [Boolean] if successful - def Read - Builtins.y2milestone("Reading the firewall configuration") - SuSEFirewall.Read - end - - # Function writes configuration of SuSEFirewall. - # - # @return [Boolean] if successful - def Write - Builtins.y2milestone("Writing the firewall configuration") - SuSEFirewall.Write - end - - # @return [Boolean] whether enabled and started - def IsOn - SuSEFirewall.GetEnableService && SuSEFirewall.GetStartService - end - - # Sets the values of the initial proposal based on the product features, - # the packages selected for installation and the installation method - def prepare_proposal - # variables from control file - default_firewall = ProductFeatures.GetBooleanFeature("globals", "enable_firewall") - default_fw_ssh = ProductFeatures.GetBooleanFeature("globals", "firewall_enable_ssh") - default_sshd = ProductFeatures.GetBooleanFeature("globals", "enable_sshd") - - log.info "Default firewall values: enable_firewall=#{default_firewall}, "\ - "enable_ssh=#{default_fw_ssh}, enable_sshd=#{default_sshd}" - - # Enabling SuSEFirewall only makes sense if it's going to be - # installed (bnc#881250) - if Pkg.IsSelected(SuSEFirewall.FIREWALL_PACKAGE) - SuSEFirewall4Network.SetEnabled1stStage(default_firewall) - else - SuSEFirewall4Network.SetEnabled1stStage(false) - end - - # we're installing over SSH, propose opening SSH port (bnc#535206) - if Linuxrc.usessh - SuSEFirewall4Network.SetSshEnabled1stStage(true) - SuSEFirewall4Network.SetSshdEnabled(true) - else - SuSEFirewall4Network.SetSshEnabled1stStage(default_fw_ssh) - SuSEFirewall4Network.SetSshdEnabled(default_sshd) - end - - # we're installing over VNC, propose opening VNC port (bnc#734264) - SuSEFirewall4Network.SetVncEnabled1stStage(true) if Linuxrc.vnc - end - - # Function returns list of items for combo box with all known - # firewall zones. - # There's also an item for "" (no zone or fw off). - # - # @return item list for CWM - def FirewallZonesComboBoxItems - list_items = [] - protected_from_internal = SuSEFirewall.GetProtectFromInternalZone - nozone = if IsOn() - # item in combo box Firewall Zone - _("Automatically Assigned Zone") - else - # item in combo box Firewall Zone - _("Firewall Disabled") - end - list_items = Builtins.add(list_items, ["", nozone]) - - # Listing all known zones - Builtins.foreach(SuSEFirewall.GetKnownFirewallZones) do |zone_shortname| - # Getting zone name for zone - # Informing user about Unprotected inetrnal zone - zone_name = Ops.add( - SuSEFirewall.GetZoneFullName(zone_shortname), - if zone_shortname == "INT" && !protected_from_internal - # TRANSLATORS: Part of combo box item -> "Internal Zone (Unprotected)" - " " + _("(Unprotected)") - else - "" - end - ) - list_items = Builtins.add(list_items, [zone_shortname, zone_name]) - end - - deep_copy(list_items) - end - - # Function returns if interface is protected by firewall. - # It means: Firewall is Running and Enabled. Interface is included - # in any protected firewall zone (means EXT, DMZ or INT). - # - # @param [String] interface - # @return [Boolean] if it is protected - def IsProtectedByFirewall(interface) - interface_zone = SuSEFirewall.GetZoneOfInterface(interface) - - # interface is mentioned in uprotected zone - if interface_zone == "INT" && !SuSEFirewall.GetProtectFromInternalZone - Builtins.y2warning( - "Interface '%1' is mentioned in uprotected zone '%2'", - interface, - "INT" - ) - end - - # firewall must be running and enabled, interface must be in any zone - IsOn() && !interface_zone.nil? - end - - # Function returns the firewall zone of interface, "" if no zone includes - # the interface. Error is reported when interface is found in multiple - # firewall zones, then the first appearance is returned. - # If firewall is off, "" is returned. - # - # @param [String] interface - # @return [String] zone - def GetZoneOfInterface(interface) - return "" if !IsOn() - zoi = SuSEFirewall.GetZoneOfInterface(interface) - zoi.nil? ? "" : zoi - end - - # Returns whether any network interfaces are handled firewall either - # explicitly mentioning them in any firewall zone or implicitly - # by using string 'any' in firewall zones that would assign any interface - # unassigned to any zone to that zone as a fallback. - # - # @return [Boolean] if any interface is handled by firewall - def AnyInterfacesHandledByFirewall - interfaces = [] - - Builtins.foreach(SuSEFirewall.GetKnownFirewallZones) do |zone| - interfaces = Convert.convert( - Builtins.union( - interfaces, - SuSEFirewall.GetInterfacesInZoneSupportingAnyFeature(zone) - ), - from: "list", - to: "list <string>" - ) - end - - Ops.greater_than(Builtins.size(interfaces), 0) - end - - # Checks if interface of given name is assigned to given FW zone - def iface_in_zone?(interface, zone) - SuSEFirewall.GetInterfacesInZone(zone).include?(interface) - end - - # Enables and starts fw service - def start_fw_service - SuSEFirewall.SetEnableService(true) - SuSEFirewall.SetStartService(true) - end - - # Disables and stops fw service - def stop_fw_service - SuSEFirewall.SetEnableService(false) - SuSEFirewall.SetStartService(false) - end - - # Functions sets protection of interface by the protect-status.<br> - # protect==true -> add interface into selected firewall zone, sets firewall - # to be started and enabled when booting.<br> - # protect==false -> removes interface from all firewall zones, if there - # are no other interfaces protected by firewall, stops it - # and removes it from boot process. - # - # @param [String] interface - # @param [String] zone (makes sense for protect_status==true) - # @param [Boolean] protect_status - # @return [Boolean] if successful - def ProtectByFirewall(interface, zone, protect_status) - # Adding protection - if protect_status - log.info("Enabling firewall because of '#{interface}' interface") - - SuSEFirewall.AddInterfaceIntoZone(interface, zone) if !iface_in_zone?(interface, zone) - - start_fw_service - # Removing protection - else - # removing from all known zones - zones = SuSEFirewall.GetKnownFirewallZones.select { |fw_zone| iface_in_zone?(interface, fw_zone) } - zones.each do |remove_from_zone| - SuSEFirewall.RemoveInterfaceFromZone(interface, remove_from_zone) - end - # if there are no other interfaces in configuration, stop firewall - # and remove it from boot process - if !AnyInterfacesHandledByFirewall() - log.info("Disabling firewall, no interfaces are protected.") - stop_fw_service - end - end - - true - end - - # Function sets that a firewall proposal was changed by user - # by editing firewall zone of network interface - # (applicable during 2nd stage of installation only) - # @param changed [Boolean] whether proposal was changed by user - def ChangedByUser(changed) - SuSEFirewallProposal.SetChangedByUser(changed) if Stage.cont - - nil - end - - # Returns whether the firewall package is installed - # @return [Boolean] if installed - def IsInstalled - SuSEFirewall.SuSEFirewallIsInstalled - end - - # Sets whether firewall should be enabled - # @param enabled [Boolean] new state - def SetEnabled1stStage(enabled) - @firewall_enabled_1st_stage = enabled - - nil - end - - # Returns whether firewall is supposed to be enabled - # @return [Boolean] whether enabled - def Enabled1stStage - @firewall_enabled_1st_stage - end - - # Sets whether SSH port should be opened in firewall - # @param enabled [Boolean] new state - def SetSshEnabled1stStage(enabled) - @ssh_enabled_1st_stage = enabled - - nil - end - - # Returns whether SSH port is supposed to be open in firewall - def EnabledSsh1stStage - @ssh_enabled_1st_stage - end - - # Sets whether start sshd - # @param enabled [Boolean] new state - def SetSshdEnabled(enabled) - @sshd_enabled = enabled - - # bnc#887688 Needed for AutoYast export functionality at the end - # of installation (clone_finish) - if enabled - ServicesProposal.enable_service("sshd") - else - ServicesProposal.disable_service("sshd") - end - - nil - end - - # Returns whether sshd will be enabled - def EnabledSshd - @sshd_enabled - end - - # Sets whether VNC ports should be opened in firewall - # @param enabled [Boolean] new state - def SetVncEnabled1stStage(enabled) - @vnc_enabled_1st_stage = enabled - - nil - end - - # Returns whether VNC ports are supposed to be open in firewall - def EnabledVnc1stStage - @vnc_enabled_1st_stage - end - - publish function: :Read, type: "boolean ()" - publish function: :Write, type: "boolean ()" - publish function: :IsOn, type: "boolean ()" - publish function: :FirewallZonesComboBoxItems, type: "list <list <string>> ()" - publish function: :IsProtectedByFirewall, type: "boolean (string)" - publish function: :GetZoneOfInterface, type: "string (string)" - publish function: :ProtectByFirewall, type: "boolean (string, string, boolean)" - publish function: :ChangedByUser, type: "void (boolean)" - publish function: :IsInstalled, type: "boolean ()" - publish function: :SetEnabled1stStage, type: "void (boolean)" - publish function: :Enabled1stStage, type: "boolean ()" - publish function: :SetSshEnabled1stStage, type: "void (boolean)" - publish function: :EnabledSsh1stStage, type: "boolean ()" - publish function: :SetSshdEnabled, type: "void (boolean)" - publish function: :EnabledSshd, type: "boolean ()" - publish function: :SetVncEnabled1stStage, type: "void (boolean)" - publish function: :EnabledVnc1stStage, type: "boolean ()" - end - - SuSEFirewall4Network = SuSEFirewall4NetworkClass.new - SuSEFirewall4Network.main -end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/test/host_test.rb new/yast2-network-4.1.39/test/host_test.rb --- old/yast2-network-4.1.37/test/host_test.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/test/host_test.rb 2019-02-13 09:23:15.000000000 +0100 @@ -94,10 +94,17 @@ end describe ".Write" do - it "do nothing if not modified" do - expect(file).to_not receive(:write) - Yast::Host.Read - Yast::Host.Write + context "settings have not been modified" do + it "does nothing" do + expect(file).to_not receive(:write) + Yast::Host.Write + end + + it "does nothing although system settings have been read" do + expect(file).to_not receive(:write) + Yast::Host.Read + Yast::Host.Write + end end it "writes content of file" do @@ -167,6 +174,21 @@ expect(Yast::Host.name_map["10.20.1.29"]).to eql([holder_entries.join(" ")]) end end + + context "import an emtpy host section" do + let(:org_etx_hosts) { file.content } + + before do + Yast::Host.Import("hosts" => {}) + end + + it "does not reset /etc/hosts" do + expect(file).to receive(:write).with( + "/etc/hosts", file.content + ) + Yast::Host.Write + end + end end describe ".Export" do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/test/lib/y2network/widgets/firewall_zone_test.rb new/yast2-network-4.1.39/test/lib/y2network/widgets/firewall_zone_test.rb --- old/yast2-network-4.1.37/test/lib/y2network/widgets/firewall_zone_test.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-network-4.1.39/test/lib/y2network/widgets/firewall_zone_test.rb 2019-02-13 09:23:15.000000000 +0100 @@ -0,0 +1,109 @@ +#!/usr/bin/env rspec + +require_relative "../../../test_helper.rb" +require "y2network/widgets/firewall_zone" + +require "cwm/rspec" + +describe Y2Network::Widgets::FirewallZone do + let(:subject) { described_class.new("eth0") } + let(:firewalld) { Y2Firewall::Firewalld.instance } + let(:firewall_zones) { [["", "Default"], ["custom", "custom"]] } + let(:installed?) { true } + + before do + allow(firewalld).to receive(:installed?).and_return(installed?) + allow(subject).to receive(:firewall_zones).and_return(firewall_zones) + end + + include_examples "CWM::CustomWidget" + + describe "#init" do + it "populates the zones list with the firewalld zones" do + expect(subject).to receive(:populate_select).with(firewall_zones) + subject.init + end + + it "selects the current zone from the list if it was cached" do + subject.value = "custom" + expect(subject).to receive(:select_zone).with("custom") + subject.init + end + end + + describe "#value" do + before do + allow(Yast::UI).to receive(:WidgetExists).and_return(true) + end + + it "returns the selected element" do + expect(subject).to receive(:selected_zone).and_return("") + expect(subject.value).to eql("") + end + + context "when the select zone widget does not exist" do + before do + allow(Yast::UI).to receive(:WidgetExists).and_return(false) + end + + it "returns the cached value" do + expect(subject.value).to eql(nil) + subject.value = "external" + expect(subject.value).to eql("external") + end + end + end + + describe "#store" do + before do + allow(Yast::UI).to receive(:WidgetExists).and_return(true, false) + end + + it "caches the current value" do + expect(subject).to receive(:selected_zone).and_return("external") + subject.store + expect(subject).to_not receive(:selected_zone?) + expect(subject.store).to eql("external") + end + end + + describe "#store_permanent" do + before do + subject.value = "custom" + end + + context "when firewalld is not installed" do + let(:installed?) { false } + + it "returns the cached value" do + expect(subject.store_permanent).to eql("custom") + end + end + + context "when firewalld is installed" do + context "but the firewall zone will not be managed by the ifcfg file" do + let(:managed?) { false } + + it "returns the cached value" do + expect(subject.store_permanent).to eql("custom") + end + end + + context "and the cached value is not equal to the firewalld interface zone" do + it "modifies the interface permanent ZONE" do + allow(subject).to receive(:current_zone).and_return("external") + expect_any_instance_of(Y2Firewall::Firewalld::Interface).to receive(:zone=).with("custom") + subject.store_permanent + end + end + + context "and the cached value is the same than the firewalld interface zone" do + it "does not touch the interface permanent ZONE" do + allow(subject).to receive(:current_zone).and_return("custom") + expect_any_instance_of(Y2Firewall::Firewalld::Interface).to_not receive(:zone=) + subject.store_permanent + end + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-4.1.37/test/suse_firewall_4_network_test.rb new/yast2-network-4.1.39/test/suse_firewall_4_network_test.rb --- old/yast2-network-4.1.37/test/suse_firewall_4_network_test.rb 2019-02-06 16:19:48.000000000 +0100 +++ new/yast2-network-4.1.39/test/suse_firewall_4_network_test.rb 1970-01-01 01:00:00.000000000 +0100 @@ -1,103 +0,0 @@ -#!/usr/bin/env rspec - -require_relative "test_helper" - -require "yast" - -module Yast - import "SuSEFirewall4Network" - import "ServicesProposal" - import "Pkg" - - describe SuSEFirewall4Network do - before(:each) do - # By default, activate firewall and block ssh - allow(ProductFeatures).to receive(:GetBooleanFeature) do |*args| - case args[1] - when "enable_firewall" - true - when "firewall_enable_ssh" - false - when "enable_sshd" - true - end - end - end - - describe "#SetSshdEnabled" do - it "sets whether sshd service should be started and caches the information in ServicesProposal" do - SuSEFirewall4Network.SetSshdEnabled(true) - expect(SuSEFirewall4Network.EnabledSshd).to be true - expect(ServicesProposal.enabled_services.include?("sshd")).to be true - expect(ServicesProposal.disabled_services.include?("sshd")).to be false - - SuSEFirewall4Network.SetSshdEnabled(false) - expect(SuSEFirewall4Network.EnabledSshd).to be false - expect(ServicesProposal.enabled_services.include?("sshd")).to be false - expect(ServicesProposal.disabled_services.include?("sshd")).to be true - end - end - - describe "#prepare_proposal" do - context "when firewall package is selected for installation" do - before(:each) do - allow(Pkg).to receive(:IsSelected).and_return true - end - - it "proposes firewall and ssh port according to control file" do - SuSEFirewall4Network.prepare_proposal - expect(SuSEFirewall4Network.Enabled1stStage).to be true - expect(SuSEFirewall4Network.EnabledSsh1stStage).to be false - end - end - - context "when firewall package is not selected for installation" do - before(:each) do - allow(Pkg).to receive(:IsSelected).and_return false - end - - it "proposes disabled firewall and proposes ssh port according to control file" do - SuSEFirewall4Network.prepare_proposal - expect(SuSEFirewall4Network.Enabled1stStage).to be false - expect(SuSEFirewall4Network.EnabledSsh1stStage).to be false - end - end - end - - describe "ProtectByFirewall" do - Yast.import "SuSEFirewall" - - context "when interface is not in fw zone" do - before(:each) do - allow(SuSEFirewall) - .to receive(:SetEnableService) - allow(SuSEFirewall) - .to receive(:SetStartService) - end - - it "doesn't cause modification flag to be set when protect status is true" do - allow(SuSEFirewall) - .to receive(:GetInterfacesInZone) - .and_return(["eth0"]) - - SuSEFirewall4Network.ProtectByFirewall("eth0", "INT", true) - - # interface is in the zone already => no adding / modification needed - expect(SuSEFirewall.GetModified).to be false - end - - it "doesn't cause modification flag to be set when protect status is false" do - allow(SuSEFirewall) - .to receive(:GetInterfacesInZone) - .and_return([]) - - # Note: zone is not important in this case - SuSEFirewall4Network.ProtectByFirewall("eth0", "INT", false) - - # every zone is empty => no removal / modification needed - expect(SuSEFirewall.GetModified).to be false - end - end - end - end -end
