Merge "Added ability to update PXE DHCP parameters after deploy"
This commit is contained in:
commit
c13fde0abd
@ -33,8 +33,8 @@ def inSameSubnet(ip1, ip2, netmask_or_cidr):
|
|||||||
cidr1 = netaddr.IPNetwork("%s/%s" % (ip1, netmask_or_cidr))
|
cidr1 = netaddr.IPNetwork("%s/%s" % (ip1, netmask_or_cidr))
|
||||||
cidr2 = netaddr.IPNetwork("%s/%s" % (ip2, netmask_or_cidr))
|
cidr2 = netaddr.IPNetwork("%s/%s" % (ip2, netmask_or_cidr))
|
||||||
return cidr1 == cidr2
|
return cidr1 == cidr2
|
||||||
except netaddr.AddrFormatError:
|
except netaddr.AddrFormatError as e:
|
||||||
log.exception('Invalid address specified: {0}'.format(cidr1))
|
log.exception(e.message)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ def puppetApply(classes):
|
|||||||
log.error("Exit code: %d. Error: %s Stdout: %s",
|
log.error("Exit code: %d. Error: %s Stdout: %s",
|
||||||
code, err, out)
|
code, err, out)
|
||||||
return False
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def puppetApplyManifest(manifest):
|
def puppetApplyManifest(manifest):
|
||||||
|
@ -19,9 +19,11 @@ LOGFILE = "/var/log/fuelmenu.log"
|
|||||||
PUPPET_LOGFILE = "/var/log/puppet/fuelmenu-puppet.log"
|
PUPPET_LOGFILE = "/var/log/puppet/fuelmenu-puppet.log"
|
||||||
PUPPET_NAILGUN = "/etc/puppet/modules/fuel/examples/nailgun.pp"
|
PUPPET_NAILGUN = "/etc/puppet/modules/fuel/examples/nailgun.pp"
|
||||||
PUPPET_FUEL_MASTER = "/etc/puppet/modules/fuel/examples/host.pp"
|
PUPPET_FUEL_MASTER = "/etc/puppet/modules/fuel/examples/host.pp"
|
||||||
|
PUPPET_DHCP_RANGES = "/etc/puppet/modules/fuel/examples/dhcp-ranges.pp"
|
||||||
|
|
||||||
SETTINGS_FILE = "/etc/fuel/astute.yaml"
|
SETTINGS_FILE = "/etc/fuel/astute.yaml"
|
||||||
RELEASE_FILE = "/etc/fuel_release"
|
RELEASE_FILE = "/etc/fuel_release"
|
||||||
|
HIERA_NET_SETTINGS = "/etc/hiera/networks.yaml"
|
||||||
|
|
||||||
DEFAULT_LOCK_FILE = "/var/run/fuelmenu.lock"
|
DEFAULT_LOCK_FILE = "/var/run/fuelmenu.lock"
|
||||||
|
|
||||||
@ -31,3 +33,5 @@ POST_DEPLOYMENT_MODE = "post"
|
|||||||
PUPPET_TYPE_LITERAL = "literal"
|
PUPPET_TYPE_LITERAL = "literal"
|
||||||
PUPPET_TYPE_RESOURCE = "resource"
|
PUPPET_TYPE_RESOURCE = "resource"
|
||||||
PUPPET_TYPE_CLASS = "class"
|
PUPPET_TYPE_CLASS = "class"
|
||||||
|
|
||||||
|
ADMIN_NETWORK_ID = 1
|
||||||
|
@ -13,18 +13,26 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
from fuelclient.cli import error
|
||||||
|
from fuelclient.objects import NetworkGroup
|
||||||
|
import netaddr
|
||||||
|
import urwid
|
||||||
|
import urwid.raw_display
|
||||||
|
import urwid.web_display
|
||||||
|
import yaml
|
||||||
|
|
||||||
from fuelmenu.common import dialog
|
from fuelmenu.common import dialog
|
||||||
from fuelmenu.common.errors import BadIPException
|
from fuelmenu.common.errors import BadIPException
|
||||||
from fuelmenu.common.modulehelper import ModuleHelper
|
from fuelmenu.common.modulehelper import ModuleHelper
|
||||||
from fuelmenu.common.modulehelper import WidgetType
|
from fuelmenu.common.modulehelper import WidgetType
|
||||||
from fuelmenu.common import network
|
from fuelmenu.common import network
|
||||||
|
from fuelmenu.common import puppet
|
||||||
import fuelmenu.common.urwidwrapper as widget
|
import fuelmenu.common.urwidwrapper as widget
|
||||||
from fuelmenu.common import utils
|
from fuelmenu.common import utils
|
||||||
import logging
|
from fuelmenu import consts
|
||||||
import netaddr
|
|
||||||
import urwid
|
|
||||||
import urwid.raw_display
|
|
||||||
import urwid.web_display
|
|
||||||
log = logging.getLogger('fuelmenu.pxe_setup')
|
log = logging.getLogger('fuelmenu.pxe_setup')
|
||||||
blank = urwid.Divider()
|
blank = urwid.Divider()
|
||||||
|
|
||||||
@ -78,6 +86,10 @@ to advertise via DHCP to nodes",
|
|||||||
self.load()
|
self.load()
|
||||||
self.extdhcp = True
|
self.extdhcp = True
|
||||||
self.screen = None
|
self.screen = None
|
||||||
|
self.apply_dialog_message = {
|
||||||
|
'title': "Apply failed in module {0}".format(self.name),
|
||||||
|
"message": "Error applying changes. Check logs for details."
|
||||||
|
}
|
||||||
|
|
||||||
def check(self, args):
|
def check(self, args):
|
||||||
"""Validates all fields have valid values and some sanity checks."""
|
"""Validates all fields have valid values and some sanity checks."""
|
||||||
@ -276,10 +288,110 @@ interface first.")
|
|||||||
log.error("Check failed. Not applying")
|
log.error("Check failed. Not applying")
|
||||||
log.error("%s" % (responses))
|
log.error("%s" % (responses))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.save(responses)
|
self.save(responses)
|
||||||
|
if utils.is_post_deployment():
|
||||||
|
self.parent.apply_tasks.add(self.update_dhcp)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def update_dhcp(self):
|
||||||
|
settings = self.parent.settings.get("ADMIN_NETWORK")
|
||||||
|
if not self._update_nailgun(settings):
|
||||||
|
return False
|
||||||
|
if os.path.exists(consts.HIERA_NET_SETTINGS):
|
||||||
|
result, msg = self._update_hiera_dnsmasq(settings)
|
||||||
|
else:
|
||||||
|
result = self._update_dnsmasq(settings)
|
||||||
|
if not result:
|
||||||
|
ModuleHelper.display_dialog(
|
||||||
|
self, error_msg=self.apply_dialog_message["message"],
|
||||||
|
title=self.apply_dialog_message["title"])
|
||||||
|
return False
|
||||||
|
cobbler_sync = ["cobbler", "sync"]
|
||||||
|
code, out, err = utils.execute(cobbler_sync)
|
||||||
|
if code != 0:
|
||||||
|
log.error(err)
|
||||||
|
ModuleHelper.display_dialog(
|
||||||
|
self, error_msg=self.apply_dialog_message["message"],
|
||||||
|
title=self.apply_dialog_message["title"])
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _update_nailgun(self, settings):
|
||||||
|
msg = "Apply changes to Nailgun"
|
||||||
|
log.info(msg)
|
||||||
|
self.parent.footer.set_text(msg)
|
||||||
|
self.parent.refreshScreen()
|
||||||
|
|
||||||
|
# TODO(mzhnichkov) this manifest apply twice(here and in feature
|
||||||
|
# groups). Need to combine this calls
|
||||||
|
result, msg = puppet.puppetApplyManifest(consts.PUPPET_NAILGUN)
|
||||||
|
if not result:
|
||||||
|
ModuleHelper.display_dialog(
|
||||||
|
self, error_msg=self.apply_dialog_message["message"],
|
||||||
|
title=self.apply_dialog_message["title"])
|
||||||
|
return False
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"gateway": settings["dhcp_gateway"],
|
||||||
|
"ip_ranges": [
|
||||||
|
[settings["dhcp_pool_start"], settings["dhcp_pool_end"]]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
NetworkGroup(consts.ADMIN_NETWORK_ID).set(data)
|
||||||
|
except error.HTTPError as e:
|
||||||
|
log.error(e.message)
|
||||||
|
ModuleHelper.display_dialog(
|
||||||
|
self, error_msg=self.apply_dialog_message["message"],
|
||||||
|
title=self.apply_dialog_message["title"])
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _update_hiera_dnsmasq(self, settings):
|
||||||
|
"""Update Hiera and dnsmasq
|
||||||
|
|
||||||
|
PXE related configuration should be written in separate
|
||||||
|
configuration file when you create additional admin
|
||||||
|
network(this behavior was introduced in nailgun's
|
||||||
|
DnsmasqUpdateTask class)
|
||||||
|
"""
|
||||||
|
|
||||||
|
msg = "Apply changes to Hiera and Dnsmasq"
|
||||||
|
log.info(msg)
|
||||||
|
self.parent.footer.set_text(msg)
|
||||||
|
self.parent.refreshScreen()
|
||||||
|
with open(consts.HIERA_NET_SETTINGS, "r") as hiera_settings:
|
||||||
|
networks = yaml.safe_load(hiera_settings)
|
||||||
|
net = netaddr.IPNetwork(
|
||||||
|
"{0}/{1}".format(settings["ipaddress"],
|
||||||
|
settings["netmask"]))
|
||||||
|
for admin_net in networks["admin_networks"]:
|
||||||
|
if str(net.cidr) == admin_net["cidr"]:
|
||||||
|
admin_net["ip_ranges"] = [
|
||||||
|
[settings["dhcp_pool_start"],
|
||||||
|
settings["dhcp_pool_end"]]
|
||||||
|
]
|
||||||
|
admin_net["gateway"] = settings["dhcp_gateway"]
|
||||||
|
with open(consts.HIERA_NET_SETTINGS, "w") as hiera_settings:
|
||||||
|
yaml.safe_dump(networks, hiera_settings)
|
||||||
|
return puppet.puppetApplyManifest(consts.PUPPET_DHCP_RANGES)
|
||||||
|
|
||||||
|
def _update_dnsmasq(self, settings):
|
||||||
|
puppet_classes = [{
|
||||||
|
"type": "resource",
|
||||||
|
"class": "fuel::dnsmasq::dhcp_range",
|
||||||
|
"name": "default",
|
||||||
|
"params": {
|
||||||
|
"dhcp_start_address": settings["dhcp_pool_start"],
|
||||||
|
"dhcp_end_address": settings["dhcp_pool_end"],
|
||||||
|
"dhcp_netmask": settings["netmask"],
|
||||||
|
"dhcp_gateway": settings["dhcp_gateway"],
|
||||||
|
"next_server": settings["ipaddress"]
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
log.debug("Start puppet with data {0}".format(puppet_classes))
|
||||||
|
return puppet.puppetApply(puppet_classes)
|
||||||
|
|
||||||
def cancel(self, button):
|
def cancel(self, button):
|
||||||
ModuleHelper.cancel(self, button)
|
ModuleHelper.cancel(self, button)
|
||||||
self.setNetworkDetails()
|
self.setNetworkDetails()
|
||||||
|
@ -306,7 +306,7 @@ class Interfaces(urwid.WidgetWrap):
|
|||||||
try:
|
try:
|
||||||
self.parent.refreshScreen()
|
self.parent.refreshScreen()
|
||||||
result = puppet.puppetApply(puppetclasses)
|
result = puppet.puppetApply(puppetclasses)
|
||||||
if result is False:
|
if not result:
|
||||||
raise Exception("Puppet apply failed")
|
raise Exception("Puppet apply failed")
|
||||||
ModuleHelper.getNetwork(self)
|
ModuleHelper.getNetwork(self)
|
||||||
gateway = self.get_default_gateway_linux()
|
gateway = self.get_default_gateway_linux()
|
||||||
|
@ -58,7 +58,7 @@ class TestPuppetApply(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def test_puppet_apply(self, m_execute, m_log):
|
def test_puppet_apply(self, m_execute, m_log):
|
||||||
self.assertEqual(puppet.puppetApply(self.classes), None)
|
self.assertEqual(puppet.puppetApply(self.classes), True)
|
||||||
m_execute.assert_called_once_with(self.command, stdin=self.input)
|
m_execute.assert_called_once_with(self.command, stdin=self.input)
|
||||||
m_log.info.assert_called_once_with('Puppet start')
|
m_log.info.assert_called_once_with('Puppet start')
|
||||||
self.assertFalse(m_log.error.called)
|
self.assertFalse(m_log.error.called)
|
||||||
|
1
setup.py
1
setup.py
@ -23,6 +23,7 @@ requirements = [
|
|||||||
'netifaces>=0.5',
|
'netifaces>=0.5',
|
||||||
'urwid>=1.1.1',
|
'urwid>=1.1.1',
|
||||||
'requests>=2.5.2,!=2.8.0,!=2.9.0',
|
'requests>=2.5.2,!=2.8.0,!=2.9.0',
|
||||||
|
'python-fuelclient>=9.0.0'
|
||||||
]
|
]
|
||||||
|
|
||||||
if sys.version_info[0:2] == (2, 6):
|
if sys.version_info[0:2] == (2, 6):
|
||||||
|
@ -26,6 +26,7 @@ Requires: python-urwid >= 1.1.0
|
|||||||
Requires: PyYAML
|
Requires: PyYAML
|
||||||
Requires: screen
|
Requires: screen
|
||||||
Requires: python-six
|
Requires: python-six
|
||||||
|
Requires: python-fuelclient
|
||||||
%if 0%{?rhel} == 6
|
%if 0%{?rhel} == 6
|
||||||
Requires: python-ordereddict
|
Requires: python-ordereddict
|
||||||
%endif
|
%endif
|
||||||
|
Loading…
Reference in New Issue
Block a user