Merge branch 'discovery-dhcp' of https://github.com/marios/instack-undercloud into marios-discovery-dhcp

Conflicts:
	json-files/fedora-20-undercloud-delorean.json
	json-files/fedora-20-undercloud-source.json
This commit is contained in:
James Slagle 2014-09-18 18:21:11 -04:00
commit 54d3b73bab
8 changed files with 176 additions and 2 deletions

View File

@ -0,0 +1,33 @@
Adds a discovery-dhcp element
This element adds a systemd service that spawns a dnsmasq process
TODO: add configuration here (e.g. for bind interface).
This dnsmasq process is intended to serve only new and undiscovered
machines. Already enrolled hardware continues to be served by the
neutron-dhcp-agent spawned dnsmasq process(es) (and this/ese is/are
already explicitly told not to answer calls from unknown machines).
The element uses iptables to block dhcp/bootp requests from already
enrolled hardware (by querying ironic), in pretty much exactly the
same way as the older bm-dnsmasq element, with a cronjob setup to
periodically update the chain (to include for example recently
discovered machines). An alternative is to use a dhcp hostfile with
'MAC, ignore' entries (and then sighup dnsmasq).
The way we get a list of MAC addresses depends on if we are in a virt or
baremetal environment:
In the baremetal case, Ironic will create a new node entry without
populating (amongst most other fields) the MAC address for an associated
port. Thus all MAC addresses reported by 'ironic port-list' can be added to
the iptables chain with 'DROP'.
For the VM case we expect Ironic to set a MAC address for newly enrolled
but not yet discovered nodes (for matching returned data). In this case, we
cannot use the MAC addresses given by 'ironic port-list' as these will
include the yet undiscovered node MACs. Thus we must get a list of all
nodes that have 'maintenance' set to False (is the case for
known/discovered machines) and then blacklist only their MACs, which
requires a potentially large number of API calls (1/node).

View File

@ -0,0 +1,79 @@
#!/bin/bash
#
# Build an IPTables chain which will filter out any dhcp requests from 'known'
# MAC addresses (known to ironic/already registered).`
#
# The way we get a list of MAC addresses depends on if we are in a virt or
# baremetal environment:
#
# In the baremetal case, Ironic will create a new node entry without
# populating (amongst most other fields) the MAC address for an associated
# port. Thus all MAC addresses reported by 'ironic port-list' can be added to
# the iptables chain with 'DROP'.
#
# For the VM case we expect Ironic to set a MAC address for newly enrolled
# but not yet discovered nodes (for matching returned data). In this case, we
# cannot use the MAC addresses given by 'ironic port-list' as these will
# include the yet undiscovered node MACs. Thus we must get a list of all
# nodes that have 'maintenance' set to False (is the case for
# known/discovered machines) and then blacklist only their MACs, which
# requires a potentially large number of API calls (1/node).
set -e
INTERFACE=br-ctlplane
source ~/stackrc
CHAIN=DISCOVERY_DHCP
NEW_CHAIN=NEW_$CHAIN
VIRT_ENV=false
# TODO(marios): need better way to check if this is VM or baremetal
if [ -e /home/stack/.ssh/id_rsa_virt_power ]; then
VIRT_ENV=true
fi
function get_node_list() {
node_list=`ironic node-list --maintenance False | awk '/ .*-.* /{print $2}'`
}
function get_macs() {
macs=()
if [ "$VIRT_ENV" = true ]; then
get_node_list
for node in $node_list ; do
node_macs=`ironic node-port-list $node | awk '/..:..:..:/{print $4}'`
for mac in $node_macs ; do
macs+=("$mac")
done
done
else
macs=`ironic port-list | awk '/..:..:..:/{print $4}'`
fi
}
function delete_chain() {
sudo iptables -F $1 || true
sudo iptables -X $1 || true
}
function create_add_macs_to_chain() {
sudo iptables -N $NEW_CHAIN
for mac in "${macs[@]}"; do
sudo iptables -A $NEW_CHAIN -m mac --mac-source $mac -j DROP
done
# everything else (port 67,udp) through
sudo iptables -A $NEW_CHAIN -j ACCEPT
}
function install_new_chain() {
sudo iptables -I INPUT -i $INTERFACE -p udp --dport 67 -j $NEW_CHAIN
sudo iptables -D INPUT -i $INTERFACE -p udp --dport 67 -j $CHAIN || true
delete_chain $CHAIN
sudo iptables -E $NEW_CHAIN $CHAIN
}
get_macs
delete_chain $NEW_CHAIN
create_add_macs_to_chain
# first run, won't exist
sudo iptables -N $CHAIN || true
install_new_chain

View File

@ -0,0 +1 @@
os-svc-install

View File

@ -0,0 +1,15 @@
#!/bin/bash
set -ue
install -m 0755 -o root -g root $(dirname $0)/../../bin/discovery-mac-filter /usr/local/bin/discovery-mac-filter
cat > /etc/cron.d/discovery-mac-filter <<EOF
# Ensure we don't answer BOOTP for bare metal nodes that are already known and
# registered with Ironic (they are served by neutron-dhcp-agent).
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
* * * * * root discovery-mac-filter
EOF

View File

@ -0,0 +1,36 @@
#!/bin/bash
# just starts the discovery dnsmasq process
set -eux
# TODO(marios): add systemd Environment or EnvironmentFile and upstart
# env for IFACE and DISCOVERY_POOL
# IFACE=br-ctlplane
# DISCOVERY_POOL=192.0.2.100,192.0.2.120
install-packages dnsmasq dnsmasq-utils
# make sure tftpboot is labelled correctly
restorecon -R /tftpboot
cat > /lib/systemd/system/discovery-dhcp-dnsmasq.service << eof
[Unit]
Description=Discovery dhcp dnsmasq service
After=openvswitch.service
[Service]
Type=forking
ExecStart=/sbin/dnsmasq --conf-file= \\
--port=0 \\
--enable-tftp \\
--tftp-root=/tftpboot \\
--dhcp-boot=pxelinux.0,localhost.localdomain,192.0.2.1 \\
--bind-interfaces \\
--pid-file=/var/run/dnsmasq.pid \\
--interface=br-ctlplane \\
--dhcp-range=192.0.2.100,192.0.2.120,29
[Install]
WantedBy=multi-user.target
Alias=discovery-dhcp-dnsmasq.service
eof
# Enable the service
os-svc-enable -n discovery-dhcp-dnsmasq

View File

@ -0,0 +1,8 @@
#!/bin/bash
# (re)starts the discovery dnsmasq process. This is just for
# plumbing... there is currently no configuration (eventually use
# os-apply-config to get a dnsmasq.conf)
set -eux
os-svc-restart -n discovery-dhcp-dnsmasq

View File

@ -45,7 +45,8 @@
"ceilometer-delorean",
"tuskar-ui",
"glance-wsme",
"dib-run-parts-update"
"dib-run-parts-update",
"discovery-dhcp"
],
"hook": [
"extra-data",

View File

@ -41,7 +41,8 @@
"ceilometer-agent-notification",
"ceilometer-undercloud-config",
"tuskar-ui",
"dib-run-parts-update"
"dib-run-parts-update",
"discovery-dhcp"
],
"hook": [
"extra-data",