configuration

dev
Philippe PITTOLI 2019-10-04 15:59:58 +02:00
parent 940b15a159
commit f441648d97
1 changed files with 146 additions and 83 deletions

View File

@ -6,11 +6,22 @@ require "./colors"
simulation = false simulation = false
file = nil file = nil
prefered_network_configuration_program = nil
prefered_dhcp_client = nil
OptionParser.parse! do |parser| OptionParser.parse! do |parser|
parser.on "-s", "--simulation", "Export the network configuration." do parser.on "-s", "--simulation", "Export the network configuration." do
simulation = true simulation = true
end end
parser.on "-n network-configuration-program", "--net-conf network-configuration-program", "ifconfig | ip" do |prog|
prefered_network_configuration_program = prog
end
parser.on "-d dhcp-client-program", "--dhcp-client dhcp-client-program", "udhcpc" do |prog|
prefered_dhcp_client = prog
end
parser.on "-f file", "--file file", "Parse a configuration file." do |optsn| parser.on "-f file", "--file file", "Parse a configuration file." do |optsn|
file = optsn file = optsn
end end
@ -39,10 +50,20 @@ class Do < Process
end end
end end
class NotSetup
def to_s(io : IO)
io << "not setup"
end
end
class NetworkCommands class NetworkCommands
class DHCPCommands class_property cmd_network_configuration : IfconfigCommand.class | IPCommand.class = IfconfigCommand
def self.dhcp(ifname : String) class_property cmd_dhcp_client : UDHCPCCommand.class | NotSetup.class = NotSetup
class UDHCPCCommand
def self.run(ifname : String)
# TODO: verify which dhcp client is installed on the system # TODO: verify which dhcp client is installed on the system
cmd = "udhcpc" cmd = "udhcpc"
unless Do.run(cmd, [ name ]).success? unless Do.run(cmd, [ name ]).success?
@ -51,14 +72,11 @@ class NetworkCommands
end end
end end
def self.which(cmd : String)
Do.run("which", [ cmd ]).success?
end
class IfconfigCommand class IfconfigCommand
def self.interface_exists?(name : String) def self.interface_exists(name : String)
Do.run("ifconfig", [ name ]).success? Do.run("ifconfig", [ name ]).success?
end end
def self.up_or_down(name : String, updown : String) def self.up_or_down(name : String, updown : String)
unless Do.run("ifconfig", [ name, updown ]).success? unless Do.run("ifconfig", [ name, updown ]).success?
raise "(ifconfig) Cannot set #{updown} link name #{name}" raise "(ifconfig) Cannot set #{updown} link name #{name}"
@ -72,14 +90,25 @@ class NetworkCommands
end end
def self.set_ip(name : String, ip : IPAddress) def self.set_ip(name : String, ip : IPAddress)
puts "(ip) setup static IP address" unless Do.run("ifconfig", [ name, "add", ip.to_string ]).success?
raise "(ifconfig) Cannot set ip address #{ip.to_string} for #{name}"
end
end
# currently, aliasses with ifconfig: ifconfig add ip/mask
# same command as the ip setup
def self.set_alias(name : String, ip : IPAddress)
unless Do.run("ifconfig", [ name, "add", ip.to_string ]).success?
raise "(ifconfig) Cannot set ip address alias #{ip.to_string} for #{name}"
end
end end
end end
class IPCommand class IPCommand
def self.interface_exists?(name : String) def self.interface_exists(name : String)
Do.run("ip", [ "link", "show", "dev", name ]).success? Do.run("ip", [ "link", "show", "dev", name ]).success?
end end
def self.up_or_down(name : String, updown : String) def self.up_or_down(name : String, updown : String)
unless Do.run("ip", [ "link", "set", updown, "dev", name ]).success? unless Do.run("ip", [ "link", "set", updown, "dev", name ]).success?
raise "(ip) Cannot set #{updown} link name #{name}" raise "(ip) Cannot set #{updown} link name #{name}"
@ -93,43 +122,47 @@ class NetworkCommands
end end
def self.set_ip(name : String, ip : IPAddress) def self.set_ip(name : String, ip : IPAddress)
puts "(ip) setup static IP address" unless Do.run("ip", [ "address", "add", ip.to_string, "dev", name ]).success?
raise "(ip) Cannot add ip address #{ip.to_string} to #{name}"
end
end
def self.set_alias(name : String, ip : IPAddress)
unless Do.run("ip", [ "address", "add", ip.to_string, "dev", name ]).success?
raise "(ip) Cannot add ip address alias #{ip.to_string} to #{name}"
end
end end
end end
def self.choose_command : IfconfigCommand.class | IPCommand.class def self.interface_exists(name : String)
if self.which("ifconfig") @@cmd_network_configuration.interface_exists(name)
IfconfigCommand
elsif self.which("ip")
IPCommand
else
raise "Neither ifconfig or ip commands exists on this system"
end
end
def self.interface_exists?(name : String)
cmd = self.choose_command
cmd.interface_exists?(name)
end end
def self.up(ifname : String) def self.up(ifname : String)
cmd = self.choose_command @@cmd_network_configuration.up(ifname)
cmd.up(ifname)
end end
def self.down(ifname : String) def self.down(ifname : String)
cmd = self.choose_command @@cmd_network_configuration.up(ifname)
cmd.up(ifname)
end end
def self.set_ip(name : String, ip : IPAddress) def self.set_ip(name : String, ip : IPAddress)
puts "(ip) setup static IP address" @@cmd_network_configuration.set_ip name, ip
end end
def self.dhcp(name : String) def self.dhcp(name : String)
puts "(ip) setup dynamic IP address" cmd = @@cmd_dhcp_client
DHCPCommands.dhcp name case cmd
when NotSetup
puts "no dhcp client: cannot perform dhcp on #{name}"
when UDHCPCCommand
cmd.run name
end
end
def self.set_alias(name : String, ip : IPAddress)
@@cmd_network_configuration.set_alias name, ip
end end
end end
@ -139,12 +172,6 @@ end
# #
class InterfaceConfiguration class InterfaceConfiguration
class NotSetup
def to_s(io : IO)
io << "not setup"
end
end
class DHCP class DHCP
def to_s(io : IO) def to_s(io : IO)
io << "dhcp" io << "dhcp"
@ -177,7 +204,7 @@ class InterfaceConfiguration
def to_string def to_string
String.build do |str| String.build do |str|
if NetworkCommands.interface_exists?(@name) if NetworkCommands.interface_exists(@name)
str << "#{CGREEN}#{@name}#{CRESET}\n" str << "#{CGREEN}#{@name}#{CRESET}\n"
else else
str << "#{CRED}#{@name}#{CRESET}\n" str << "#{CRED}#{@name}#{CRESET}\n"
@ -204,13 +231,10 @@ class InterfaceConfiguration
# configure the interface # configure the interface
def execute def execute
unless NetworkCommands.interface_exists?(@name) unless NetworkCommands.interface_exists(@name)
raise "The interface #{@name} doesn't exists, yet." raise "The interface #{@name} doesn't exists, yet."
end end
puts "OK on va configurer ça"
puts "#{self}"
if @up if @up
NetworkCommands.up @name NetworkCommands.up @name
else else
@ -218,50 +242,50 @@ class InterfaceConfiguration
return return
end end
# ipv4 configuration
@main_ip_v4.tap do |ip|
case ip
when IPAddress
NetworkCommands.set_ip @name, ip
when DHCP
NetworkCommands.dhcp @name
when NotSetup
puts "no ipv4"
else
raise "ipv4 configuration: neither static nor dynamic"
end
case main_ip_v4 = @main_ip_v4 # We wont setup aliasses unless there is an actual IP address
when IPAddress if ip != NotSetup
NetworkCommands.set_ip @name, main_ip_v4 @aliasses_v4.each do |ip_alias|
when DHCP NetworkCommands.set_alias @name, ip_alias
NetworkCommands.dhcp @name end
when NotSetup end
puts "no ipv4"
else
raise "ipv4 configuration: neither static nor dynamic"
end end
case main_ip_v6 = @main_ip_v6 # ipv6 configuration
when IPAddress @main_ip_v6.tap do |ip|
NetworkCommands.set_ip @name, main_ip_v6 case ip
# TODO when IPAddress
#when Autoconfiguration NetworkCommands.set_ip @name, ip
# NetworkCommands.autoconfiguration @name # TODO
#when DHCP #when Autoconfiguration
# NetworkCommands.dhcp6 @name # NetworkCommands.autoconfiguration @name
when NotSetup #when DHCP
puts "no ipv4" # NetworkCommands.dhcp6 @name
else when NotSetup
raise "ipv4 configuration: neither static nor dynamic" puts "no ipv6"
else
raise "ipv4 configuration: neither static nor dynamic"
end
# We wont setup aliasses unless there is an actual IP address
if ip != NotSetup
@aliasses_v6.each do |ip_alias|
NetworkCommands.set_alias @name, ip_alias
end
end
end end
# str << "\tinet #{@main_ip_v4}\n"
# str << "\t#{@up? "up" : "down"}\n"
# str << "\tinet #{@main_ip_v4}\n"
# unless @aliasses_v4.empty?
# @aliasses_v4.each do |a|
# str << "\talias #{a}\n"
# end
# end
# str << "\tinet6 #{@main_ip_v6}\n"
# @aliasses_v6.each do |a|
# str << "\talias6 #{a}\n"
# end
# alias execution: only when the main ip address is setup
end end
end end
@ -275,8 +299,8 @@ class NetworkConfigurationParser
def self.parse (ifname : String, data : String) : InterfaceConfiguration def self.parse (ifname : String, data : String) : InterfaceConfiguration
up = false up = false
main_ip_v4 = InterfaceConfiguration::NotSetup.new main_ip_v4 = NotSetup.new
main_ip_v6 = InterfaceConfiguration::NotSetup.new main_ip_v6 = NotSetup.new
aliasses = [] of IPAddress aliasses = [] of IPAddress
@ -320,6 +344,45 @@ end
Do.simulation = simulation Do.simulation = simulation
def which(cmd : String)
if Process.run("which", [ cmd ]).success?
puts "#{cmd} installed"
true
else
puts "#{cmd} not installed"
false
end
end
#
# discover available configuration commands
#
# ifconfig = *bsd and some linux
# ip = linux
possible_network_configuration_cmds = {
"ifconfig" => NetworkCommands::IfconfigCommand,
"ip" => NetworkCommands::IPCommand
}
# udhcpc = busybox dhcp client
possible_dhcp_clients = {
"udhcpc" => NetworkCommands::UDHCPCCommand
}
key = prefered_network_configuration_program
key = possible_network_configuration_cmds.keys.find { |key| which(key) } if key.nil?
# should crash if there is no network command installed
NetworkCommands.cmd_network_configuration = possible_network_configuration_cmds[key.not_nil!]
key = prefered_dhcp_client
key = possible_dhcp_clients.keys.find { |key| which(key) } if key.nil?
# should not crash if there is no
NetworkCommands.cmd_dhcp_client = possible_dhcp_clients[key] unless key.nil?
if file.nil? if file.nil?
raise "Cannot choose files yet" raise "Cannot choose files yet"
else else