Module: Y2Firewall::Firewalld::Relations

Included in:
Service, Zone
Defined in:
library/network/src/lib/y2firewall/firewalld/relations.rb

Overview

Extends the base class with metaprogramming methods which defines some attributes common logic.

Instance Method Summary collapse

Instance Method Details

#enable_modifications_cacheObject



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'library/network/src/lib/y2firewall/firewalld/relations.rb', line 6

def enable_modifications_cache
  attr_writer :modified

  # Return an array with all the modified attributes/relations
  define_method "modified" do
    @modified ||= []
  end

  # Mark the given attribute as modified.
  define_method "modified!" do |item|
    @modified << item unless modified.include?(item)
  end

  # Return whether the object has been modified or not. If an argument is
  # given then it returns whether the given attribute or relation has
  # been modififed.
  define_method "modified?" do |*item|
    return !modified.empty? if item.empty?

    modified.include?(item.first)
  end

  # Reset all the modifications
  define_method "untouched!" do
    @modified = []
  end
end

#has_many(*relations, scope: nil, cache: false) ⇒ Object

Defines a set of methods to operate over array based firewalld attributes like services, interfaces, protocols, ports… Bang! methods applies the object modifications into the firewalld zone using the Firewalld API.

A modifications cache can be enable with the cache param. In that case it is important to initialize objects with the instance variable

Examples:


class Zone
  extend Relations

  has_many :services, cache: true

  def initialize
    @modified = []
  end
end

zone = Zone.new

# Return all the declared relations
zone.relations #=> [:services]
# Read all the relations initializing the object
zone.read_relations
# Adds the "ssh" service into the zone object if not present
zone.add_service("ssh")
# Removes the "ssh" service from the zone object
zone.remove_service("ssh")
# List of current firewalld configured services
zone.current_services
# Adds the service "ssh" definitely into the firewalld zone
zone.add_service!("ssh")
# Removes the service "ssh" definitely from firewalld zone
zone.remove_service!("ssh")
Loop through all the services were added to the zone object since
read adding them definitely to firewalld
zone.add_services!
Loop through all the services were removed from the zone object since
read adding them to firewalld
zone.remove_services!
# Returns the list of services added after read
zone.services_to_add
# Returns the list of services removed after read
zone.services_to_remove
# Apply the changes (remove_services! && add_services!)
zone.apply_services_changes!
# Apply all the relations changes
zone.apply_relations_changes!


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'library/network/src/lib/y2firewall/firewalld/relations.rb', line 87

def has_many(*relations, scope: nil, cache: false) # rubocop:disable Style/PredicateName
  scope = "#{scope}_" if scope
  enable_modifications_cache if cache

  define_method "relations" do
    relations
  end

  define_method "apply_relations_changes!" do
    relations.each { |r| public_send("apply_#{r}_changes!") }
    true
  end

  define_method "read_relations" do
    relations.each { |r| instance_variable_set("@#{r}", public_send("current_#{r}")) }
    true
  end

  relations.each do |relation|
    relation_singularized = relation.to_s.sub(/s$/, "")
    attr_reader relation

    define_method "#{relation}=" do |item|
      instance_variable_set("@#{relation}", item)

      modified!(relation) if cache
    end

    define_method "add_#{relation_singularized}" do |item|
      return public_send(relation) if public_send(relation).include?(item)
      modified!(relation) if cache
      public_send(relation) << item
    end

    define_method "remove_#{relation_singularized}" do |item|
      if public_send(relation).delete(item)
        modified!(relation) if cache
        return public_send(relation)
      end

      public_send(relation)
    end

    define_method "current_#{relation}" do
      if scope
        api.public_send("#{scope}#{relation}", name)
      else
        api.public_send("list_#{relation}", name)
      end
    end

    define_method "add_#{relation_singularized}!" do |item|
      api.public_send("add_#{scope}#{relation_singularized}", name, item)
    end

    define_method "remove_#{relation_singularized}!" do |item|
      api.public_send("remove_#{scope}#{relation_singularized}", name, item)
    end

    define_method "add_#{relation}!" do
      public_send("#{relation}_to_add").map { |i| public_send("add_#{relation_singularized}!", i) }
    end

    define_method "remove_#{relation}!" do
      public_send("#{relation}_to_remove").map { |i| public_send("remove_#{relation_singularized}!", i) }
    end

    define_method "#{relation}_to_add" do
      public_send(relation) - public_send("current_#{relation}")
    end

    define_method "#{relation}_to_remove" do
      public_send("current_#{relation}") - public_send(relation)
    end

    define_method "apply_#{relation}_changes!" do
      return if cache && !modified?(relation)
      public_send("remove_#{relation}!")
      public_send("add_#{relation}!")

      modified.delete(relation)
    end
  end
end