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:
Ryan Harper 2015-11-04 09:50:58 -06:00
parent c6b3298f84
commit 5086b00263
3 changed files with 106 additions and 31 deletions

View File

@ -208,7 +208,7 @@ class NetworkModel(ModelPolicy):
return False
raise
def configure_iface(self, ifname):
def configure_iface_from_info(self, ifname):
iface_info = self.network[ifname]
log.debug('iface_info of {}:\n{}'.format(ifname, iface_info))
mac_address = iface_info['hardware']['attrs'].get('address')
@ -243,7 +243,7 @@ class NetworkModel(ModelPolicy):
for ifname in self.network.keys():
if self.network[ifname]['type'] not in ignored and \
self.iface_is_up(ifname):
self.configure_iface(ifname)
self.configure_iface_from_info(ifname)
return self.configured_interfaces
@ -260,15 +260,73 @@ class NetworkModel(ModelPolicy):
log.debug("add_bond: {} as BondAction({})".format(
ifname, action))
def add_subnet(self, ifname, subnet):
if ifname not in self.configured_interfaces:
raise Exception('No such configured interface: {}'.format(ifname))
def valid_ipv4_address(self, addr):
try:
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]
if 'subnets' in action:
action['subnets'].extend([subnet])
else:
action['subnets'] = [subnet]
action.subnets.extend([subnet])
def remove_subnets(self, ifname):
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):
if self.default_gateway:
@ -318,5 +376,13 @@ class NetworkModel(ModelPolicy):
return 'Unknown Model'
def get_iface_info(self, iface):
ipinfo = SimpleInterface(self.network[iface]['ip'])
return (ipinfo, self.get_vendor(iface), self.get_model(iface))
info = {
'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

View File

@ -75,18 +75,7 @@ class NetworkView(ViewPolicy):
col_2 = []
for iface in ifaces:
ifinfo, iface_vendor, iface_model = self.model.get_iface_info(
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,
}
info = self.model.get_iface_info(iface)
log.debug('iface info:{}'.format(info))
template = ''
if info['bonded']:

View File

@ -15,7 +15,7 @@
from urwid import Text, Pile, ListBox, Columns
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.interactive import StringEditor
import logging
@ -28,9 +28,11 @@ class NetworkConfigureIPv4InterfaceView(ViewPolicy):
self.model = model
self.signal = signal
self.iface = iface
self.gateway_input = StringEditor(caption="")
self.address_input = StringEditor(caption="")
self.subnet_input = StringEditor(caption="")
self.gateway_input = StringEditor(caption="") # FIXME: ipaddr_editor
self.address_input = StringEditor(caption="") # FIXME: ipaddr_editor
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 = [
Padding.center_79(self._build_iface_inputs()),
Padding.line_break(""),
@ -74,8 +76,8 @@ class NetworkConfigureIPv4InterfaceView(ViewPolicy):
def _build_set_as_default_gw_button(self):
ifaces = self.model.get_interfaces()
if len(ifaces) > 1:
btn = confirm_btn(label="Set this as default gateway",
on_press=self.set_default_gateway)
btn = menu_btn(label="Set this as default gateway",
on_press=self.set_default_gateway)
else:
btn = Text("This will be your default gateway")
return Pile([btn])
@ -94,8 +96,26 @@ class NetworkConfigureIPv4InterfaceView(ViewPolicy):
]
return Pile(buttons)
def done(self, result):
self.signal.emit_signal('menu:network:main')
def done(self, btn):
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):
self.model.default_gateway = None