Skip to content

Commit

Permalink
Add infrastructure to read NetworManager connections
Browse files Browse the repository at this point in the history
* It is a WIP.
* Many of the settings are not actually read yet.
  • Loading branch information
imobachgs committed Feb 4, 2021
1 parent a9fd945 commit c9e497f
Show file tree
Hide file tree
Showing 18 changed files with 834 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/lib/cfa/nm_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require "yast"
require "cfa/base_model"
require "y2network/interface_type"

Yast.import "Installation"

Expand Down Expand Up @@ -93,6 +95,20 @@ def add_collection(section, name, values)
end
end

TYPES_MAP = {
wifi: Y2Network::InterfaceType::WIRELESS,
ethernet: Y2Network::InterfaceType::ETHERNET
}.freeze
private_constant :TYPES_MAP

# Determines the interface type according to the content of the file
#
# @return [Y2Network::InterfaceType] Interface type
def type
TYPES_MAP[connection["type"]&.to_sym] ||
Y2Network::InterfaceType::UNKNOWN
end

KNOWN_SECTIONS.each { |s| define_method(s) { section_for(s) } }
end
end
48 changes: 48 additions & 0 deletions src/lib/y2network/network_manager/config_reader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright (c) [2021] 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 "yast"
require "y2network/config_reader"
require "y2network/backends"
require "y2network/network_manager/connection_configs_reader"

module Y2Network
module NetworkManager
# This class reads the current network configuration from NetworkManager
class ConfigReader < Y2Network::ConfigReader
SECTIONS = [
:interfaces, :connections
].freeze

def config
Y2Network::Config.new(
connections: connection_configs_reader.connections,
backend: Y2Network::Backends::NetworkManager.new,
source: :network_manager
)
end

private

def connection_configs_reader
@connection_configs_reader ||= Y2Network::NetworkManager::ConnectionConfigsReader.new
end
end
end
end
48 changes: 48 additions & 0 deletions src/lib/y2network/network_manager/connection_config_reader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright (c) [2021] 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.

module Y2Network
module NetworkManager
# Reads a connection configuration from a given file
class ConnectionConfigReader
# TODO: make this signature consistent with Wicked::ConnectionConfigReader
def read(file)
file.load
handler_class = find_handler_class(file.type)
return nil if handler_class.nil?

handler_class.new(file).connection_config
end

private

# Returns the class to handle a given interface type
#
# @param type [InterfaceType] interface type
# @return [Class] A class which belongs to the ConnectionConfigReaders module
def find_handler_class(type)
require "y2network/network_manager/connection_config_readers/#{type.file_name}"
ConnectionConfigReaders.const_get(type.class_name)
rescue LoadeError, NameError => e
log.info "Unknown connection type: '#{type}'. " \
"Connection handler could not be loaded: #{e.message}"
end
end
end
end
125 changes: 125 additions & 0 deletions src/lib/y2network/network_manager/connection_config_readers/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Copyright (c) [2021] 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.

module Y2Network
module NetworkManager
module ConnectionConfigReaders
# This is the base class for connection config readers.
#
# The derived classes should reimplement the {#update_connection_config}
# method.
class Base
# @return [CFA::NmConnection] Connection configuration file
attr_reader :file

# Constructor
#
# @return [CFA::NmConnection] Connection configuration file
def initialize(file)
@file = file
end

# Builds a connection configruation object from the file
#
# @return [Y2Network::ConnectionConfig::Base]
def connection_config
connection_class.new.tap do |conn|
conn.bootproto = bootproto
conn.name = file.connection["id"]
conn.description = conn.name.clone
conn.startmode = startmode
conn.firewall_zone = file.connection["zone"]
conn.ip = all_ips.first
conn.ip_aliases = all_ips[1..-1]
# TODO: hostnames (pending)
update_connection_config(conn)
end
end

protected

# Sets connection config settings from the given file.
#
# @note This method is expected to be redefined by derived classes.
#
# @param _conn [Y2Network::ConnectionConfig::Base]
def update_connection_config(_conn); end

private

# Returns the class of the connection configuration
#
# TODO: duplicated (see Y2Network::Wicked::ConnectionConfigReaders::Base)
#
# @return [Class]
def connection_class
class_name = self.class.to_s.split("::").last
file_name = class_name.gsub(/(\w)([A-Z])/, "\\1_\\2").downcase
require "y2network/connection_config/#{file_name}"
Y2Network::ConnectionConfig.const_get(class_name)
end

NM_DHCP = "auto".freeze

# Determines the value for the BOOTPROTO parameter
#
# @return [Y2Network::BootProtocol]
def bootproto
ipv4_method = file.ipv4["method"]
ipv6_method = file.ipv6["method"]

if ipv4_method == NM_DHCP && ipv6_method == NM_DHCP
Y2Network::BootProtocol::DHCP
elsif ipv4_method == NM_DHCP
Y2Network::BootProtocol::DHCP4
elsif ipv6_method == NM_DHCP
Y2Network::BootProtocol::DHCP6
elsif ipv4_method || ipv6_method
Y2Network::BootProtocol::STATIC
else
Y2Network::BootProtocol::NONE
end
end

# Determines the value for the STARTMODE parameter
#
# @return [Y2]
def startmode
return Y2Network::Startmode.create("off") if file.connection["autoconnect"] == "false"

Y2Network::Startmode.create("auto")
end

def all_ips
@all_ips = ips_from_section(file.ipv4) + ips_from_section(file.ipv6)
end

def ips_from_section(section)
address_items = section.data.select { |i| i[:key] =~ /\Aaddress\d+\Z/ }
address_items.map do |item|
addr, _gateway = item[:value].split(",")
ip_address = Y2Network::IPAddress.from_string(addr)
# TODO: handle the gateway too
Y2Network::ConnectionConfig::IPConfig.new(ip_address)
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) [2021] 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 "yast"
require "y2network/network_manager/connection_config_readers/base"

module Y2Network
module NetworkManager
module ConnectionConfigReaders
class Ethernet < Base
# @see Y2Network::NetworkManager::ConnectionConfigReaders::Base#update_connection_config
def update_connection_config(conn)
conn.mtu = file.ethernet["mtu"].to_i if file.ethernet["mtu"]
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright (c) [2021] 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 "yast"
require "y2network/network_manager/connection_config_readers/base"

module Y2Network
module NetworkManager
module ConnectionConfigReaders
class Wireless < Base
# FIXME: (somehow) duplicated in the writer
DEFAULT_MODE = "managed".freeze
MODE = { "adhoc" => "ad-hoc", "ap" => "master", "infrastructure" => "managed" }.freeze

# @see Y2Network::NetworkManager::ConnectionConfigReaders::Base#update_connection_config
def update_connection_config(conn)
conn.mtu = file.wifi["mtu"].to_i if file.wifi["mtu"]
conn.mode = MODE[file.wifi["mode"]] || DEFAULT_MODE
conn.essid = file.wifi["ssid"]
end
end
end
end
end
41 changes: 41 additions & 0 deletions src/lib/y2network/network_manager/connection_configs_reader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright (c) [2021] 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 "yast"
require "cfa/nm_connection"
require "y2network/connection_configs_collection"
require "y2network/network_manager/connection_config_reader"

module Y2Network
module NetworkManager
# This class reads connection configurations from NetworkManager
class ConnectionConfigsReader
# Returns the connection configurations from NetworkManager
#
# @return [Y2Network::ConnectionConfigsCollection]
def connections
empty_collection = ConnectionConfigsCollection.new
CFA::NmConnection.all.each_with_object(empty_collection) do |file, conns|
connection = ConnectionConfigReader.new.read(file)
conns << connection if connection
end
end
end
end
end

0 comments on commit c9e497f

Please sign in to comment.