Skip to content

Commit

Permalink
Merge 3725aec into 83464ab
Browse files Browse the repository at this point in the history
  • Loading branch information
jreidinger committed Jan 16, 2019
2 parents 83464ab + 3725aec commit a72ee51
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 87 deletions.
7 changes: 7 additions & 0 deletions package/yast2-firewall.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Wed Jan 16 12:02:14 UTC 2019 - jreidinger@suse.com

- Autoyast: remove unused options, move export to own class,
add support for custom zones in autoyast profile (fate#324662)
- 4.1.8

-------------------------------------------------------------------
Fri Jan 11 16:25:41 UTC 2019 - lslezak@suse.cz

Expand Down
10 changes: 5 additions & 5 deletions package/yast2-firewall.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


Name: yast2-firewall
Version: 4.1.7
Version: 4.1.8
Release: 0

BuildRoot: %{_tmppath}/%{name}-%{version}-build
Expand All @@ -28,13 +28,13 @@ License: GPL-2.0-only
BuildRequires: perl-XML-Writer update-desktop-files yast2-testsuite
BuildRequires: yast2-devtools >= 3.1.10

# Y2Firewall::Firewalld#reset
BuildRequires: yast2 >= 4.1.21
# reduced relations
BuildRequires: yast2 >= 4.1.51
BuildRequires: rubygem(%rb_default_ruby_abi:yast-rake)
BuildRequires: rubygem(%rb_default_ruby_abi:rspec)

# Y2Firewall::Firewalld#reset
Requires: yast2 >= 4.1.21
# reduced relations
Requires: yast2 >= 4.1.51

# ButtonBox widget
Conflicts: yast2-ycp-ui-bindings < 2.17.3
Expand Down
28 changes: 0 additions & 28 deletions src/autoyast-rnc/firewall.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,10 @@ zones =
zone_short? &
zone_description? &
zone_target? &
fwd_forward_ports? &
fwd_interfaces? &
fwd_ports? &
fwd_protocols? &
fwd_rich_rules? &
fwd_services? &
fwd_source_ports? &
fwd_sources? &
masquerade?
}*
}
Expand Down Expand Up @@ -165,30 +161,6 @@ fwd_protocols =
element (protocol | listentry) {text}*
}

fwd_sources =
element sources {
LIST,
element (source | listentry) {text}*
}

fwd_rich_rules =
element rich_rules {
LIST,
element (rich_rule | litentry) {text}*
}

fwd_source_ports =
element source_ports {
LIST,
element (souce_port | litentry) {text}*
}

fwd_forward_ports =
element forward_ports {
LIST,
element (forward_port | litentry) {text}*
}

zone_name = element name { text }
zone_short = element short { text }
zone_description = element description { text }
Expand Down
46 changes: 34 additions & 12 deletions src/lib/y2firewall/importer.rb → src/lib/y2firewall/autoyast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
require "y2firewall/importer_strategies/firewalld"

module Y2Firewall
# This class is responsible for importing firewalld AutoYaST configuration
# supporting the new firewalld schema but also the SuSEFirewall one.
class Importer
# This class is responsible for exporting/importing firewalld AutoYaST configuration
# supporting the new firewalld schema but also the SuSEFirewall one (for import).
class Autoyast
include Yast::Logger
# Import the given configuration
#
Expand All @@ -42,6 +42,37 @@ def import(profile)
true
end

# Return a map with current firewalld settings.
#
# @return [Hash] dump firewalld settings
def export
return {} unless firewalld.installed?

{
"enable_firewall" => firewalld.enabled?,
"start_firewall" => firewalld.running?,
"default_zone" => firewalld.default_zone,
"log_denied_packets" => firewalld.log_denied_packets,
"zones" => firewalld.zones.map { |z| export_zone(z) }
}
end

private

def export_zone(zone)
(zone.attributes + zone.relations)
.each_with_object({}) do |field, profile|
profile[field.to_s] = zone.public_send(field) unless zone.public_send(field).nil?
end
end

# Return an instance of Y2Firewall::Firewalld
#
# @return [Y2Firewall::Firewalld] a firewalld instance
def firewalld
Y2Firewall::Firewalld.instance
end

# Given a profile defines the importer stragegy to be used.
#
# @example Given SuSEFirewall's profile format
Expand Down Expand Up @@ -69,14 +100,5 @@ def strategy_for(profile)

ImporterStrategies::Firewalld
end

private

# Return an instance of Y2Firewall::Firewalld
#
# @return [Y2Firewall::Firewalld] a firewalld instance
def firewalld
Y2Firewall::Firewalld.instance
end
end
end
16 changes: 8 additions & 8 deletions src/lib/y2firewall/clients/auto.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

require "yast"
require "y2firewall/firewalld"
require "y2firewall/importer"
require "y2firewall/autoyast"
require "y2firewall/proposal_settings"
require "y2firewall/summary_presenter"
require "y2firewall/dialogs/main"
Expand Down Expand Up @@ -85,7 +85,7 @@ def import(profile, merge = !Yast::Mode.config)
# Obtains the default from the control file (settings) if not present.
enable if profile.fetch("enable_firewall", settings.enable_firewall)
start if profile.fetch("start_firewall", false)
importer.import(profile)
autoyast.import(profile)
check_profile_for_errors
imported
end
Expand All @@ -94,7 +94,7 @@ def import(profile, merge = !Yast::Mode.config)
#
# @return [Hash] with the current firewalld configuration
def export
firewalld.export
autoyast.export
end

# Reset the current firewalld configuration.
Expand Down Expand Up @@ -180,7 +180,7 @@ def ay_config?
# Problems will be stored in AutoInstall.issues_list.
def check_profile_for_errors
# Checking if an interface has been defined for different zones
zones = firewalld.export["zones"] || []
zones = export["zones"] || []
all_interfaces = zones.flat_map { |zone| zone["interfaces"] || [] }
double_entries = all_interfaces.select { |i| all_interfaces.count(i) > 1 }.uniq
unless double_entries.empty?
Expand All @@ -197,11 +197,11 @@ def activate_service
start? ? firewalld.start : firewalld.stop
end

# Return a firewall importer
# Return a firewall autoyast object
#
# @return [Y2Firewall::Importer]
def importer
@importer ||= Importer.new
# @return [Y2Firewall::Autoyast]
def autoyast
@autoyast ||= Autoyast.new
end

# Return a firewalld singleton instance
Expand Down
24 changes: 17 additions & 7 deletions src/lib/y2firewall/importer_strategies/firewalld.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,30 @@ def import

private

ZONE_ATTRIBUTES = ["services", "interfaces", "protocols", "ports", "masquerade"].freeze
IGNORED_ATTRIBUTES = ["name", "short", "description"].freeze

# Configures Y2Firewall::Firewalld::Zone that correspond with the
# profile's firewall zone definition
#
# @param zone_definition [Hash] AutoYaST profile firewall's section
# @return [Boolean] true if the zone exist; nil otherwise
def process_zone(zone_definition)
zone = firewalld.find_zone(zone_definition["name"])
return unless zone
ZONE_ATTRIBUTES.each do |attr|
zone.public_send("#{attr}=", zone_definition[attr]) if zone_definition[attr]
name = zone_definition["name"]
zone = firewalld.find_zone(name)
zone = create_zone(zone_definition) if !zone
(zone.attributes + zone.relations).each do |key|
next if IGNORED_ATTRIBUTES.include?(key.to_s)
zone.public_send("#{key}=", zone_definition[key.to_s]) if zone_definition[key.to_s]
end
true
end

def create_zone(definition)
name = definition["name"]
zone = Y2Firewall::Firewalld::Zone.new(name: name)
zone.short = definition["short"] || name
zone.description = definition["description"] || name
firewalld.zones << zone

zone
end

# Convenience method which return an instance of Y2Firewall::Firewalld
Expand Down
17 changes: 0 additions & 17 deletions src/lib/y2firewall/widgets/zone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@ def validate
def store
@zone.name = value
end

# Sets the focus into this widget
def focus
Yast::UI.SetFocus(Id(widget_id))
end
end

# short name of zone.
Expand Down Expand Up @@ -96,12 +91,6 @@ def validate
def store
@zone.short = value
end

# Sets the focus into this widget
# TODO: move to CWM itself
def focus
Yast::UI.SetFocus(Id(widget_id))
end
end

# textual description of widget
Expand Down Expand Up @@ -133,12 +122,6 @@ def validate
def store
@zone.description = value
end

# Sets the focus into this widget
# TODO: move to CWM itself
def focus
Yast::UI.SetFocus(Id(widget_id))
end
end

# target of zone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
# ------------------------------------------------------------------------------

require_relative "../../test_helper.rb"
require "y2firewall/importer"
require "y2firewall/autoyast"

describe Y2Firewall::Importer do
describe Y2Firewall::Autoyast do
let(:profile) { { "FW_DEV_EXT" => "eth0" } }

describe "#import" do
Expand All @@ -48,18 +48,85 @@

end

describe "#export" do
let(:zones_definition) do
["dmz",
" target: default",
" interfaces: ",
" ports: ",
" protocols:",
" sources:",
"",
"external (active)",
" target: default",
" interfaces: eth0",
" services: ssh samba",
" ports: 5901/tcp 5901/udp",
" protocols: esp",
" sources:"]
end

let(:known_zones) { %w(dmz drop external home internal public trusted work) }
let(:known_services) { %w(http https samba ssh) }

let(:api) do
instance_double(Y2Firewall::Firewalld::Api,
log_denied_packets: "all",
default_zone: "work",
list_all_zones: zones_definition,
zones: known_zones,
services: known_services)
end

let(:firewalld) { Y2Firewall::Firewalld.instance }

before do
firewalld.reset
allow(firewalld).to receive("api").and_return api
allow(firewalld).to receive("running?").and_return true
allow(firewalld).to receive("enabled?").and_return false
allow(firewalld).to receive("installed?").and_return true
firewalld.read
end

it "returns a hash with the current firewalld config" do
config = subject.export

expect(config).to be_a(Hash)
expect(config["enable_firewall"]).to eq(false)
expect(config["start_firewall"]).to eq(true)
expect(config["log_denied_packets"]).to eq("all")
expect(config["default_zone"]).to eq("work")

external = config["zones"].find { |z| z["name"] == "external" }

expect(external["interfaces"]).to eq(["eth0"])
expect(external["ports"]).to eq(["5901/tcp", "5901/udp"])
expect(external["protocols"]).to eq(["esp"])
end

it "returned hash is valid for later import" do
config = subject.export
expect { subject.import(config) }.to_not raise_error
end
end

describe "#strategy_for" do
context "when the given profile uses a SuSEFirewall2 schema" do
it "returns Y2Firewall::ImporterStrategies::SuSEFirewall" do
expect(subject.strategy_for(profile)).to eq(Y2Firewall::ImporterStrategies::SuseFirewall)
expect(subject.send(:strategy_for, profile)).to(
eq(Y2Firewall::ImporterStrategies::SuseFirewall)
)
end
end

context "when the given profile does not use a SuSEFirewall2 schema" do
let(:profile) { { "zones" => [{ "name" => "public", "interfaces" => "eth0" }] } }

it "returns Y2Firewall::ImporterStrategies::Firewalld" do
expect(subject.strategy_for(profile)).to eq(Y2Firewall::ImporterStrategies::Firewalld)
expect(subject.send(:strategy_for, profile)).to(
eq(Y2Firewall::ImporterStrategies::Firewalld)
)
end
end
end
Expand Down

0 comments on commit a72ee51

Please sign in to comment.