Fetch manual configuration
Collect and apply manual ipv4 interface configuration and update the model. Signed-off-by: Ryan Harper <ryan.harper@canonical.com>
This commit is contained in:
parent
c6b3298f84
commit
5086b00263
|
@ -208,7 +208,7 @@ class NetworkModel(ModelPolicy):
|
||||||
return False
|
return False
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def configure_iface(self, ifname):
|
def configure_iface_from_info(self, ifname):
|
||||||
iface_info = self.network[ifname]
|
iface_info = self.network[ifname]
|
||||||
log.debug('iface_info of {}:\n{}'.format(ifname, iface_info))
|
log.debug('iface_info of {}:\n{}'.format(ifname, iface_info))
|
||||||
mac_address = iface_info['hardware']['attrs'].get('address')
|
mac_address = iface_info['hardware']['attrs'].get('address')
|
||||||
|
@ -243,7 +243,7 @@ class NetworkModel(ModelPolicy):
|
||||||
for ifname in self.network.keys():
|
for ifname in self.network.keys():
|
||||||
if self.network[ifname]['type'] not in ignored and \
|
if self.network[ifname]['type'] not in ignored and \
|
||||||
self.iface_is_up(ifname):
|
self.iface_is_up(ifname):
|
||||||
self.configure_iface(ifname)
|
self.configure_iface_from_info(ifname)
|
||||||
|
|
||||||
return self.configured_interfaces
|
return self.configured_interfaces
|
||||||
|
|
||||||
|
@ -260,15 +260,73 @@ class NetworkModel(ModelPolicy):
|
||||||
log.debug("add_bond: {} as BondAction({})".format(
|
log.debug("add_bond: {} as BondAction({})".format(
|
||||||
ifname, action))
|
ifname, action))
|
||||||
|
|
||||||
def add_subnet(self, ifname, subnet):
|
def valid_ipv4_address(self, addr):
|
||||||
if ifname not in self.configured_interfaces:
|
try:
|
||||||
raise Exception('No such configured interface: {}'.format(ifname))
|
ip = ipaddress.IPv4Address(addr)
|
||||||
|
except ipaddress.AddressValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return ip
|
||||||
|
|
||||||
|
def valid_ipv4_network(self, subnet):
|
||||||
|
try:
|
||||||
|
nw = ipaddress.IPv4Network(subnet)
|
||||||
|
except (ipaddress.AddressValueError,
|
||||||
|
ipaddress.NetmaskValueError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return nw
|
||||||
|
|
||||||
|
def add_subnet(self, ifname, subnet_type, network=None, address=None,
|
||||||
|
gateway=None, nameserver=None, searchpath=None):
|
||||||
|
if ifname not in self.configured_interfaces:
|
||||||
|
raise ValueError('No such configured interface: {}'.format(ifname))
|
||||||
|
|
||||||
|
if subnet_type not in ['static', 'dhcp', 'dhcp6']:
|
||||||
|
raise ValueError(('Invalid subnet type ') + subnet_type)
|
||||||
|
|
||||||
|
# network = 192.168.9.0/24
|
||||||
|
# address = 192.168.9.212
|
||||||
|
subnet = {
|
||||||
|
'type': subnet_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
if subnet_type == 'static':
|
||||||
|
ipaddr = self.valid_ipv4_address(address)
|
||||||
|
if ipaddr is False:
|
||||||
|
raise ValueError(('Invalid IP address ') + address)
|
||||||
|
|
||||||
|
ipnet = self.valid_ipv4_network(network)
|
||||||
|
if ipnet is False:
|
||||||
|
raise ValueError(('Invalid IP network ') + network)
|
||||||
|
|
||||||
|
ip_network = ipaddress.IPv4Interface("{}/{}".format(
|
||||||
|
ipaddr.compressed, ipnet.prefixlen))
|
||||||
|
subnet.update({'address': ip_network.with_prefixlen})
|
||||||
|
|
||||||
|
if gateway:
|
||||||
|
gw = self.valid_ipv4_address(gateway)
|
||||||
|
if gw is False:
|
||||||
|
raise ValueError(('Invalid gateway IP ') + gateway)
|
||||||
|
subnet.update({'gateway': gw.compressed})
|
||||||
|
|
||||||
|
if nameserver:
|
||||||
|
subnet.update({'dns_nameserver': nameserver})
|
||||||
|
|
||||||
|
if searchpath:
|
||||||
|
subnet.update({'dns_search': searchpath})
|
||||||
|
|
||||||
|
log.debug('Adding subnet:{}'.format(subnet))
|
||||||
action = self.configured_interfaces[ifname]
|
action = self.configured_interfaces[ifname]
|
||||||
if 'subnets' in action:
|
action.subnets.extend([subnet])
|
||||||
action['subnets'].extend([subnet])
|
|
||||||
else:
|
def remove_subnets(self, ifname):
|
||||||
action['subnets'] = [subnet]
|
if ifname not in self.configured_interfaces:
|
||||||
|
raise ValueError('No such configured interface: {}'.format(ifname))
|
||||||
|
|
||||||
|
log.debug('Removing subnets on iface: {}'.format(ifname))
|
||||||
|
action = self.configured_interfaces[ifname]
|
||||||
|
action.subnets = []
|
||||||
|
|
||||||
def get_default_route(self):
|
def get_default_route(self):
|
||||||
if self.default_gateway:
|
if self.default_gateway:
|
||||||
|
@ -318,5 +376,13 @@ class NetworkModel(ModelPolicy):
|
||||||
return 'Unknown Model'
|
return 'Unknown Model'
|
||||||
|
|
||||||
def get_iface_info(self, iface):
|
def get_iface_info(self, iface):
|
||||||
ipinfo = SimpleInterface(self.network[iface]['ip'])
|
info = {
|
||||||
return (ipinfo, self.get_vendor(iface), self.get_model(iface))
|
'bonded': self.iface_is_bonded(iface),
|
||||||
|
'bridged': self.iface_is_bridge_member(iface),
|
||||||
|
'speed': self.iface_get_speed(iface),
|
||||||
|
'vendor': self.get_vendor(iface),
|
||||||
|
'model': self.get_mode(iface),
|
||||||
|
'ip': SimpleInterface(self.network[iface]['ip'])
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
|
@ -75,18 +75,7 @@ class NetworkView(ViewPolicy):
|
||||||
|
|
||||||
col_2 = []
|
col_2 = []
|
||||||
for iface in ifaces:
|
for iface in ifaces:
|
||||||
ifinfo, iface_vendor, iface_model = self.model.get_iface_info(
|
info = self.model.get_iface_info(iface)
|
||||||
iface)
|
|
||||||
bonded = self.model.iface_is_bonded(iface)
|
|
||||||
bridged = self.model.iface_is_bridge_member(iface)
|
|
||||||
speed = self.model.iface_get_speed(iface)
|
|
||||||
info = {
|
|
||||||
'bonded': bonded,
|
|
||||||
'bridged': bridged,
|
|
||||||
'speed': speed,
|
|
||||||
'vendor': iface_vendor,
|
|
||||||
'model': iface_model,
|
|
||||||
}
|
|
||||||
log.debug('iface info:{}'.format(info))
|
log.debug('iface info:{}'.format(info))
|
||||||
template = ''
|
template = ''
|
||||||
if info['bonded']:
|
if info['bonded']:
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
from urwid import Text, Pile, ListBox, Columns
|
from urwid import Text, Pile, ListBox, Columns
|
||||||
from subiquity.view import ViewPolicy
|
from subiquity.view import ViewPolicy
|
||||||
from subiquity.ui.buttons import done_btn, confirm_btn, cancel_btn
|
from subiquity.ui.buttons import done_btn, menu_btn, cancel_btn
|
||||||
from subiquity.ui.utils import Color, Padding
|
from subiquity.ui.utils import Color, Padding
|
||||||
from subiquity.ui.interactive import StringEditor
|
from subiquity.ui.interactive import StringEditor
|
||||||
import logging
|
import logging
|
||||||
|
@ -28,9 +28,11 @@ class NetworkConfigureIPv4InterfaceView(ViewPolicy):
|
||||||
self.model = model
|
self.model = model
|
||||||
self.signal = signal
|
self.signal = signal
|
||||||
self.iface = iface
|
self.iface = iface
|
||||||
self.gateway_input = StringEditor(caption="")
|
self.gateway_input = StringEditor(caption="") # FIXME: ipaddr_editor
|
||||||
self.address_input = StringEditor(caption="")
|
self.address_input = StringEditor(caption="") # FIXME: ipaddr_editor
|
||||||
self.subnet_input = StringEditor(caption="")
|
self.subnet_input = StringEditor(caption="") # FIXME: ipaddr_editor
|
||||||
|
self.nameserver_input = StringEditor(caption="") # FIXME: ipaddr_editor
|
||||||
|
self.searchpath_input = StringEditor(caption="") # FIXME: ipaddr_editor
|
||||||
body = [
|
body = [
|
||||||
Padding.center_79(self._build_iface_inputs()),
|
Padding.center_79(self._build_iface_inputs()),
|
||||||
Padding.line_break(""),
|
Padding.line_break(""),
|
||||||
|
@ -74,8 +76,8 @@ class NetworkConfigureIPv4InterfaceView(ViewPolicy):
|
||||||
def _build_set_as_default_gw_button(self):
|
def _build_set_as_default_gw_button(self):
|
||||||
ifaces = self.model.get_interfaces()
|
ifaces = self.model.get_interfaces()
|
||||||
if len(ifaces) > 1:
|
if len(ifaces) > 1:
|
||||||
btn = confirm_btn(label="Set this as default gateway",
|
btn = menu_btn(label="Set this as default gateway",
|
||||||
on_press=self.set_default_gateway)
|
on_press=self.set_default_gateway)
|
||||||
else:
|
else:
|
||||||
btn = Text("This will be your default gateway")
|
btn = Text("This will be your default gateway")
|
||||||
return Pile([btn])
|
return Pile([btn])
|
||||||
|
@ -94,8 +96,26 @@ class NetworkConfigureIPv4InterfaceView(ViewPolicy):
|
||||||
]
|
]
|
||||||
return Pile(buttons)
|
return Pile(buttons)
|
||||||
|
|
||||||
def done(self, result):
|
def done(self, btn):
|
||||||
self.signal.emit_signal('menu:network:main')
|
result = {
|
||||||
|
'subnet_type': 'static',
|
||||||
|
'network': self.subnet_input.value,
|
||||||
|
'address': self.address_input.value,
|
||||||
|
'gateway': self.gateway_input.value,
|
||||||
|
'nameserver': self.nameserver_input.value,
|
||||||
|
'searchpath': self.searchpath_input.value,
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
self.model.remove_subnets(self.iface)
|
||||||
|
self.model.add_subnet(self.iface, **result)
|
||||||
|
except ValueError:
|
||||||
|
log.exception('Failed to manually configure interface')
|
||||||
|
self.model.configure_iface_from_info(self.iface)
|
||||||
|
# FIXME: set error message in UX ala identity
|
||||||
|
return
|
||||||
|
|
||||||
|
# return
|
||||||
|
self.signal.prev_signal()
|
||||||
|
|
||||||
def cancel(self, button):
|
def cancel(self, button):
|
||||||
self.model.default_gateway = None
|
self.model.default_gateway = None
|
||||||
|
|
Loading…
Reference in New Issue