Re-design plugin to support Fuel-9.0

This implementation uses a task-based deployment,
all tasks fully idempotent.

TODO:
- use existing etcd
- use existing bird on nodes
- flags for BGP peers on UI (import/export first)
- field for custom import/export filters on UI for bird on RR
- IPv6 support

Change-Id: If82a14dd4ab3bfa53018654970f27ef44571b22e
This commit is contained in:
Sergey Vasilenko 2016-07-13 16:59:22 +02:00
parent 618c9cbadc
commit 52a3bb920d
56 changed files with 1985 additions and 825 deletions

25
.gitignore vendored
View File

@ -1,2 +1,27 @@
.build/
calico-fuel-plugin-*.rpm
*~
*.swp
*.gem
*.rbc
.idea
.bundle
.config
*.lock
*.diff
coverage
InstalledFiles
lib/bundler/man
pkg
rdoc
spec/reports
spec/fixtures/modules
spec/fixtures/manifests
test/tmp
test/version_tmp
tmp
# YARD artifacts
.yardoc
_yardoc
doc/

108
README.md
View File

@ -31,7 +31,7 @@ None.
Compatible versions:
--------------------
Mirantis Fuel 7.0
Mirantis Fuel 9.0
To build the plugin:
--------------------
@ -39,18 +39,15 @@ To build the plugin:
- Install the fuel plugin builder, fpb:
easy_install pip
pip install fuel-plugin-builder
- Clone the calico plugin repository and run the plugin builder:
git clone https://github.com/openstack/fuel-plugin-calico
cd fuel-plugin-calico/
fpb --build .
- Check that the file calico-fuel-plugin-2.0-2.0.0-0.noarch.rpm was created.
- Check that the file fuel-plugin-calico-VERSION.noarch.rpm was created.
To install the plugin:
@ -60,13 +57,16 @@ To install the plugin:
- Copy the plugin onto the fuel master node:
scp calico-fuel-plugin-2.0-2.0.0-0.noarch.rpm root@<Fuel_Master_Node_IP>:/tmp
scp fuel-plugin-calico-VERSION.noarch.rpm root@<Fuel_Master_Node_IP>:/tmp
- Install the `patch` utility:
yum install -y patch
- Install the plugin on the fuel master node:
cd /tmp
fuel plugins --install calico-fuel-plugin-2.0-2.0.0-0.noarch.rpm
fuel plugins --install fuel-plugin-calico-VERSION.noarch.rpm
- Check the plugin was installed:
@ -81,27 +81,85 @@ OpenStack cluster in the usual way, with the following guidelines:
- Create a new OpenStack environment, selecting:
Kilo on Ubuntu Trusty
Mitaka on Ubuntu 14.04
"Calico networking" as the networking setup
"Neutron with VLAN segmentation" as the networking setup
- Under the settings tab, make sure the following options are checked:
"Assign public network to all nodes"
"Use Calico Virtual Networking"
- Under the network tab, configure the 'Public' settings (leaving all of the
other sections with their default values). For example (exact values will
- Under the network tab, configure the `Public` settings to reduce
Floating-IP addresses pool to one address,
because Calico does not support Floating IPs use-case.
For example (exact values will
depend on your setup):
- IP Range: 172.18.203.60 - 172.18.203.69
- CIDR: 172.18.203.0/24
- Use VLAN tagging: No
- Gateway: 172.18.203.1
- Floating IP range: 172.18.203.70 - 172.18.203.79
Node Network Group
default:
CIDR: 172.18.203.0/24
IP Range: 172.18.203.2 - 172.18.203.253
Gateway: 172.18.203.1
Use VLAN tagging: No
Settings
Neutron L3:
Floating IP range: 172.18.203.254 - 172.18.203.254
- Under the network tab, configure the `Private` network settings
(this network will be used for BGP peering between custer nodes, route
reflectors and external peers, configured by UI). Do not forget to exclude
Your BGP peers and gateway from the IP range!
For example (exact values will depend on your setup):
IP Range: 172.100.203.33 - 172.100.203.254
CIDR: 172.100.203.0/24
Use VLAN tagging: No
- Under Fuel CLI, configure gateway for `Private` network.
This gateway will be used for pass outgoing external traffic from instances.
In most cases the same gateway node should be also an external BGB peer
(see below, external BGB peer-1).
[root@nailgun ~]# fuel2 network-group list
+----+---------+------------+---------------+---------+----------+
| id | name | vlan_start | cidr | gateway | group_id |
+----+---------+------------+---------------+---------+----------+
| 5 | private | None | 10.88.12.0/24 | None | 1 |
+----+---------+------------+---------------+---------+----------+
[root@nailgun ~]# fuel2 network-group update -g 10.88.12.1 5
+------------+---------------+
| Field | Value |
+------------+---------------+
| id | 5 |
| name | private |
| vlan_start | None |
| cidr | 10.88.12.0/24 |
| gateway | 10.88.12.1 |
| group_id | 1 |
+------------+---------------+
- Under the network tab, configure IP pool for Calico network fabric.
Ip addresses from this pool will be assigned to VM instances:
Settings
Neutron L3:
Admin Tenant network CIDR: 10.10.0.0/16
Admin Tenant network gateway: 10.10.0.1
- Under the network tab, in the `other/Calico_networking` section setup
AS number, external BGP peering and another Calico networking options.
AS Number: 64513
[X] Allow external BGP peering
External BGP peers:
peer-1:65000:10.88.12.1
peer-2:65002:172.100.203.13
- Add nodes (for meaningful testing, you will need at least two compute nodes
in addition to the controller).
in addition to the controller). Calico-RR (route-reflector) and Calico-ETCD
node roles may be co-located on Controller nodes or deployed separately.
- Under the nodes tab, configure networks to NICs mapping
(exact positions will depend on your setup)
- Deploy changes
- Do not forget to configure BGP peering session on you infrastructure
BGP peers.

12
components.yaml Normal file
View File

@ -0,0 +1,12 @@
- name: 'network:neutron:calico'
label: 'Calico'
description: 'Calico networking'
bind: !!pairs
- "cluster:net_provider": "neutron"
- "cluster:net_segment_type": "tun"
compatible:
- name: 'hypervisor:kvm'
- name: 'hypervisor:qemu'
incompatible:
- name: 'hypervisor:vmware'
description: 'Calico plugin is not compatible with VMware for now'

View File

@ -1,66 +0,0 @@
#!/usr/bin/env python
import pyinotify
import subprocess
import yaml
from pluginutils import NODES_CONFIG
SCRIPTS_LOCATION="##REPLACE_ON_INSTALL##/"
RECONFIGURE_ROUTE_REFLECTOR = SCRIPTS_LOCATION + "calico_route_reflector.sh"
UPDATE_ETCD_CLUSTER = SCRIPTS_LOCATION + "update_etcd_cluster.sh"
def _get_configured_nodes(roles):
with open(NODES_CONFIG, "r") as f:
config = yaml.safe_load(f)
return [node for node in config["nodes"] if node["role"] in roles]
def _get_compute_nodes():
return _get_configured_nodes(["compute"])
def _get_control_nodes():
nodes = _get_configured_nodes(["controller", "primary-controller"])
for node in nodes:
# Note this does not change the node role in the Fuel deployment, just
# in the list of nodes internal to this script (where we are only
# concerned with the distinction between compute/control nodes, not
# whether a given control node is primary or not).
if node["role"] == "primary-controller":
node["role"] = "controller"
return nodes
class DeploymentChangeHandler(pyinotify.ProcessEvent):
def __init__(self):
super(DeploymentChangeHandler, self).__init__()
self.compute_nodes = _get_compute_nodes()
self.control_nodes = _get_control_nodes()
def process_IN_MODIFY(self, event):
current_compute_nodes = _get_compute_nodes()
current_control_nodes = _get_control_nodes()
if current_control_nodes != self.control_nodes:
subprocess.call(RECONFIGURE_ROUTE_REFLECTOR)
subprocess.call(UPDATE_ETCD_CLUSTER)
elif current_compute_nodes != self.compute_nodes:
subprocess.call(RECONFIGURE_ROUTE_REFLECTOR)
self.compute_nodes = current_compute_nodes
self.control_nodes = current_control_nodes
if __name__ == "__main__":
handler = DeploymentChangeHandler()
watch_manager = pyinotify.WatchManager()
notifier = pyinotify.Notifier(watch_manager, handler)
watch_manager.add_watch(NODES_CONFIG, pyinotify.IN_MODIFY)
notifier.loop()

View File

@ -1,173 +0,0 @@
#!/bin/bash
# Copyright 2015 Metaswitch Networks
export DEBIAN_FRONTEND=noninteractive
exec > /tmp/calico_compute.log 2>&1
set -x
echo "Hi, I'm a compute node!"
this_node_address=$(python get_node_ip.py `hostname`)
controller_node_addresses=$(python get_node_ips_by_role.py controller)
# Get APT key for binaries.projectcalico.org.
curl -L http://binaries.projectcalico.org/repo/key | apt-key add -
# Add source for binaries.projectcalico.org, removing the priority files that
# were automatically created by the fuel plugin installer (the version number
# in the file names causes problems as it contains full stops, and the file
# contents aren't what we want).
rm -f /etc/apt/preferences.d/calico-fuel-plugin-2.0.0 /etc/apt/sources.list.d/calico-fuel-plugin-2.0.0.list
cat > /etc/apt/sources.list.d/calico.list <<EOF
deb http://binaries.projectcalico.org/fuel7.0 ./
EOF
cat << PREFS >> /etc/apt/preferences.d/calico-fuel
Package: *
Pin: origin binaries.projectcalico.org
Pin-Priority: 1200
PREFS
# Add PPA for the etcd packages, and ensure that it has lower priority than
# binaries.projectcalico.org so that we get the fuel versions of the calico
# packages.
apt-add-repository -y ppa:project-calico/kilo
cat > /etc/apt/preferences.d/calico-etcd <<EOF
Package: *
Pin: release o=LP-PPA-project-calico-kilo
Pin-Priority: 1175
EOF
# Pick up package details from new sources.
apt-get update
# Install etcd and configure it for a compute node.
apt-get -y install etcd
for controller_address in ${controller_node_addresses[@]}
do
initial_cluster+="${controller_address}=http://${controller_address}:2380,"
done
initial_cluster=${initial_cluster::-1} # remove trailing comma
service etcd stop
rm -rf /var/lib/etcd/*
awk '/exec \/usr\/bin\/etcd/{while(getline && $0 != ""){}}1' /etc/init/etcd.conf > tmp
mv tmp /etc/init/etcd.conf
cat << EXEC_CMD >> /etc/init/etcd.conf
exec /usr/bin/etcd -proxy on \\
-listen-client-urls http://127.0.0.1:4001 \\
-advertise-client-urls http://127.0.0.1:7001 \\
-initial-cluster ${initial_cluster}
EXEC_CMD
service etcd start
# Run apt-get upgrade and apt-get dist-upgrade. These commands will
# bring in Calico-specific updates to the OpenStack packages and to
# dnsmasq.
apt-get -y upgrade
apt-get -y dist-upgrade
# Open /etc/nova/nova.conf and remove the linuxnet_interface_driver line.
cp /etc/nova/nova.conf /etc/nova/nova.conf.pre-calico
sed -i "/^linuxnet_interface_driver/d" /etc/nova/nova.conf
service nova-compute restart
# Install some extra packages.
apt-get -y install neutron-common neutron-dhcp-agent nova-api
# Open /etc/neutron/dhcp_agent.ini in your preferred text editor. In
# the [DEFAULT] section, add the following line:
#
# interface_driver = neutron.agent.linux.interface.RoutedInterfaceDriver
cp /etc/neutron/dhcp_agent.ini /etc/neutron/dhcp_agent.ini.pre-calico
sed -i "/^interface_driver/d" /etc/neutron/dhcp_agent.ini
sed -i "/^\[DEFAULT\]/a\
interface_driver = neutron.agent.linux.interface.RoutedInterfaceDriver
" /etc/neutron/dhcp_agent.ini
# Allow BGP connections through the Fuel firewall. We do this before
# installing calico-compute, so that they will be included when the
# calico-compute install script does iptables-save.
iptables -I INPUT 1 -p tcp --dport 179 -j ACCEPT
# Add sources for BIRD and Ubuntu Precise.
gpg --keyserver keyserver.ubuntu.com --recv-keys F9C59A45
gpg -a --export F9C59A45 | apt-key add -
cat > /etc/apt/sources.list.d/bird.list <<EOF
deb http://ppa.launchpad.net/cz.nic-labs/bird/ubuntu trusty main
EOF
cat > /etc/apt/sources.list.d/trusty.list <<EOF
deb http://gb.archive.ubuntu.com/ubuntu/ trusty main
deb http://gb.archive.ubuntu.com/ubuntu/ trusty universe
EOF
apt-get update
# Install BIRD and calico-compute packages.
# Note that this will trigger the installation of iptables-persistent which
# will attempt to bring up a dialog box. We use debconf-set-selections to set
# the value beforehand to avoid this (so not to interrupt the automated
# installation process).
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | debconf-set-selections
apt-get -y install calico-compute bird
# Configure BIRD. By default Calico assumes that you'll be deploying
# a route reflector to avoid the need for a full BGP mesh. To this
# end, it includes useful configuration scripts that will prepare a
# BIRD config file with a single peering to the route reflector. If
# that's correct for your network, you can run the following command
# for IPv4 connectivity between compute hosts.
#
# The calico_route_reflector.sh script will set up the required BGP
# Route Reflctor configuration on the controller to allow connections
# from the compute nodes.
#
# If you are configuring a full BGP mesh you'll need to handle the BGP
# configuration appropriately - by editing this script/the Route Reflector
# script. You should consult the relevant documentation for your chosen BGP
# stack.
calico-gen-bird-mesh-conf.sh $this_node_address 64511 ${controller_node_addresses[@]}
# Edit the /etc/calico/felix.cfg file:
# Change the MetadataAddr setting to 127.0.0.1.
# Change the MetadataPort setting to 8775.
cp /etc/calico/felix.cfg.example /etc/calico/felix.cfg
sed -i "/^MetadataAddr/d" /etc/calico/felix.cfg
sed -i "/^\[global\]/a\
MetadataAddr = 127.0.0.1
" /etc/calico/felix.cfg
sed -i "/^MetadataPort/d" /etc/calico/felix.cfg
sed -i "/^\[global\]/a\
MetadataPort = 8775
" /etc/calico/felix.cfg
# Restart the Felix service:
service calico-felix restart
exit 0

View File

@ -1,231 +0,0 @@
#!/bin/bash
# Copyright 2015 Metaswitch Networks
export DEBIAN_FRONTEND=noninteractive
exec > /tmp/calico_controller.log 2>&1
set -x
echo "Hi, I'm a controller node!"
this_node_address=$(python get_node_ip.py `hostname`)
controller_node_addresses=$(python get_node_ips_by_role.py controller)
# Get APT key for binaries.projectcalico.org.
curl -L http://binaries.projectcalico.org/repo/key | apt-key add -
# Add source for binaries.projectcalico.org, removing the priority files that
# were automatically created by the fuel plugin installer (the version number
# in the file names causes problems as it contains full stops, and the file
# contents aren't what we want).
rm -f /etc/apt/preferences.d/calico-fuel-plugin-2.0.0 /etc/apt/sources.list.d/calico-fuel-plugin-2.0.0.list
cat > /etc/apt/sources.list.d/calico.list <<EOF
deb http://binaries.projectcalico.org/fuel7.0 ./
EOF
cat << PREFS >> /etc/apt/preferences.d/calico-fuel
Package: *
Pin: origin binaries.projectcalico.org
Pin-Priority: 1200
PREFS
# Add PPA for the etcd packages, and ensure that it has lower priority than
# binaries.projectcalico.org so that we get the fuel versions of the calico
# packages.
apt-add-repository -y ppa:project-calico/kilo
cat > /etc/apt/preferences.d/calico-etcd <<EOF
Package: *
Pin: release o=LP-PPA-project-calico-kilo
Pin-Priority: 1175
EOF
# Pick up package details from new sources.
apt-get update
# Install etcd and configure it for a controller node.
apt-get -y install etcd
for controller_address in ${controller_node_addresses[@]}
do
initial_cluster+="${controller_address}=http://${controller_address}:2380,"
done
initial_cluster=${initial_cluster::-1} # remove trailing comma
service etcd stop
rm -rf /var/lib/etcd/*
awk '/exec \/usr\/bin\/etcd/{while(getline && $0 != ""){}}1' /etc/init/etcd.conf > tmp
mv tmp /etc/init/etcd.conf
cat << EXEC_CMD >> /etc/init/etcd.conf
exec /usr/bin/etcd -name ${this_node_address} \\
-advertise-client-urls "http://${this_node_address}:2379,http://${this_node_address}:4001" \\
-listen-client-urls "http://0.0.0.0:2379,http://0.0.0.0:4001" \\
-listen-peer-urls "http://0.0.0.0:2380" \\
-initial-advertise-peer-urls "http://${this_node_address}:2380" \\
-initial-cluster-token fuel-cluster-1 \\
-initial-cluster ${initial_cluster} \\
-initial-cluster-state new
EXEC_CMD
service etcd start
# Ensure that the firewall isn't dropping traffic to the ports used by etcd.
iptables -I INPUT 1 -p tcp --dport 2379 -j ACCEPT
iptables -I INPUT 2 -p tcp --dport 2380 -j ACCEPT
iptables -I INPUT 3 -p tcp --dport 4001 -j ACCEPT
iptables-save > /etc/iptables.local
/sbin/iptables-restore < /etc/iptables.local
# Run apt-get upgrade and apt-get dist-upgrade. These commands will
# bring in Calico-specific updates to the OpenStack packages and to
# dnsmasq.
apt-get -y upgrade
apt-get -y dist-upgrade
# Install the calico-control package:
apt-get -y install calico-control
# Edit the /etc/neutron/plugins/ml2/ml2_conf.ini file:
#
# Find the line beginning with type_drivers, and change it to
# read type_drivers = local, flat.
cp /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugins/ml2/ml2_conf.ini.pre-calico
sed -i "/^type_drivers/d" /etc/neutron/plugins/ml2/ml2_conf.ini
sed -i "/^\[ml2\]/a\
type_drivers = local, flat
" /etc/neutron/plugins/ml2/ml2_conf.ini
# Find the line beginning with mechanism_drivers, and change it
# to read mechanism_drivers = calico.
sed -i "/^mechanism_drivers/d" /etc/neutron/plugins/ml2/ml2_conf.ini
sed -i "/^\[ml2\]/a\
mechanism_drivers = calico
" /etc/neutron/plugins/ml2/ml2_conf.ini
# Find the line beginning with tenant_network_types, and change it
# to read tenant_network_types = local.
sed -i "/^tenant_network_types/d" /etc/neutron/plugins/ml2/ml2_conf.ini
sed -i "/^\[ml2\]/a\
tenant_network_types = local
" /etc/neutron/plugins/ml2/ml2_conf.ini
# Edit the /etc/neutron/neutron.conf file:
#
# Find the line for the dhcp_agents_per_network setting,
# uncomment it, and set its value to the number of compute nodes
# that you will have (or any number larger than that). This
# allows a DHCP agent to run on every compute node, which Calico
# requires because the networks on different compute nodes are
# not bridged together.
cp /etc/neutron/neutron.conf /etc/neutron/neutron.conf.pre-calico
sed -i "/^dhcp_agents_per_network/d" /etc/neutron/neutron.conf
sed -i "/^\[DEFAULT\]/a\
dhcp_agents_per_network = 1000
" /etc/neutron/neutron.conf
# Remove api_workers and rpc_workers config, so that these default to
# 0. The Calico/OpenStack plugin doesn't currently work if the
# Neutron server is split across multiple OS processes.
sed -i "/^api_workers/d" /etc/neutron/neutron.conf
sed -i "/^rpc_workers/d" /etc/neutron/neutron.conf
# Set agent_down_time to 60, instead of Fuel's default setting of 15.
# The Calico/OpenStack plugin reports Felix agent status every 30
# seconds, based on the HEARTBEAT exchange between the plugin and each
# Felix; and it is recommended that agent_down_time should be double
# the expected reporting interval.
sed -i "/^agent_down_time/d" /etc/neutron/neutron.conf
sed -i "/^\[DEFAULT\]/a\
agent_down_time = 60
" /etc/neutron/neutron.conf
# If dnspython is installed, eventlet replaces socket.getaddrinfo() with its
# own version that cannot handle IPv6 addresses. As a workaround, we comment
# out the '::1 localhost' line from /etc/hosts.
sed -i "s/^::1\(.*\)/#::1\1 #commented out due to dnspython IPv6 issue/" /etc/hosts
# Restart the neutron server process:
service neutron-server restart
# BIRD installation
gpg --keyserver keyserver.ubuntu.com --recv-keys F9C59A45
gpg -a --export F9C59A45 | apt-key add -
cat > /etc/apt/sources.list.d/bird.list <<EOF
deb http://ppa.launchpad.net/cz.nic-labs/bird/ubuntu trusty main
EOF
apt-get update
apt-get -y install bird
# Allow BGP through the Fuel firewall
iptables -I INPUT 1 -p tcp --dport 179 -j ACCEPT
# Save the current iptables so that they will be restored if the
# controller is rebooted.
iptables-save > /etc/iptables/rules.v4
# Set up a service, calico-fuel-monitor, that will detect changes to the
# deployment and reconfigure the calico components on the controller as
# needed. For example, updating the route reflector configuration after
# compute nodes are added/removed from the deployment.
SERVICE_NAME=calico-fuel-monitor
# Install the service's dependencies.
apt-get -y install python-pip
pip install pyinotify pyaml
# During node deployment, the plugin deployment scripts are copied into
# /etc/fuel/plugins/<plugin_name>-<plugin_version> on the node, and this
# script is run from that directory.
SERVICE_DIR=$(pwd)
sed -i "s@##REPLACE_ON_INSTALL##@${SERVICE_DIR}@" $SERVICE_NAME
chmod +x $SERVICE_NAME
cat << SERVICE_CFG >> /etc/init/calico-fuel-monitor.conf
# calico-fuel-monitor - daemon to monitor for fuel deployment changes and
# reconfigure the calico components accordingly
description "Calico daemon to monitor fuel deployment changes"
author "Emma Gordon <emma@projectcalico.org>"
start on runlevel [2345]
stop on runlevel [016]
respawn
script
cd ${SERVICE_DIR}
exec ./${SERVICE_NAME}
end script
SERVICE_CFG
service $SERVICE_NAME start
exit 0

View File

@ -1,75 +0,0 @@
#!/bin/bash
# Copyright 2015 Metaswitch Networks
exec > /tmp/calico_route_reflector.log 2>&1
set -x
echo "Hi, I'm a route_reflector node!"
this_node_address=$(python get_node_ip.py `hostname`)
controller_node_addresses=$(python get_node_ips_by_role.py controller)
client_peers=$(python get_node_ips_by_role.py compute)
route_reflector_peers=("${controller_node_addresses[@]/$this_node_address}")
# Generate basic config for a BIRD BGP route reflector.
cat > /etc/bird/bird.conf <<EOF
# Configure logging
log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };
log stderr all;
#log "tmp" all;
# Override router ID
router id $this_node_address;
filter import_kernel {
if ( net != 0.0.0.0/0 ) then {
accept;
}
reject;
}
# Turn on global debugging of all protocols
debug protocols all;
# This pseudo-protocol watches all interface up/down events.
protocol device {
scan time 2; # Scan interfaces every 10 seconds
}
EOF
# Add a BGP protocol stanza for all peers.
for node in ${client_peers[@]} ${route_reflector_peers[@]}; do
cat >> /etc/bird/bird.conf <<EOF
protocol bgp {
local as 64511;
neighbor $node as 64511;
multihop;
EOF
if [[ "${client_peers[@]}" =~ "${node}" ]]; then
cat >> /etc/bird/bird.conf <<EOF
description "Client $node";
rr client;
EOF
else
cat >> /etc/bird/bird.conf <<EOF
description "Route Reflector $node";
EOF
fi
cat >> /etc/bird/bird.conf <<EOF
rr cluster id 1.2.3.4;
import all;
export all;
source address ${this_node_address};
}
EOF
done
# Restart BIRD with the new config.
service bird restart
exit 0

View File

@ -1,32 +0,0 @@
#!/usr/bin/env python
# Copyright 2015 Metaswitch Networks
import sys
import yaml
from pluginutils import get_config_file_for_node_type
usage = "./get_node_ip.py <hostname>"
def main(hostname):
config_file = get_config_file_for_node_type()
with open(config_file, "r") as f:
config = yaml.safe_load(f)
for node in config["nodes"]:
if node["fqdn"] == hostname:
# Get the IP address that other OpenStack nodes can use to address
# services on this node, rather than the node's public IP address.
this_node_ip = node["internal_address"]
break
else:
this_node_ip = None
print this_node_ip
if __name__ == "__main__":
if len(sys.argv) != 2:
print usage
sys.exit(1)
main(sys.argv[1])

View File

@ -1,32 +0,0 @@
#!/usr/bin/env python
# Copyright 2015 Metaswitch Networks
import argparse
import yaml
from pluginutils import NODES_CONFIG
def main(node_roles):
with open(NODES_CONFIG, "r") as f:
config = yaml.safe_load(f)
node_ips = [node["internal_address"] for node in config["nodes"]
if node["role"] in node_roles]
return node_ips
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("node_role", choices=["compute", "controller"])
args = parser.parse_args()
args.node_role = [args.node_role]
if args.node_role == ["controller"]:
args.node_role.append("primary-controller")
node_ips = main(args.node_role)
if node_ips:
print " ".join(node_ips)

View File

@ -1,32 +0,0 @@
#!/usr/bin/env python
# Copyright 2015 Metaswitch Networks
import os
# This config file is updated with the latest node details as the deployment
# evolves. It only contains node details, not other config settings.
NODES_CONFIG = "/etc/hiera/astute.yaml"
# These config files contain details of the nodes at initial deployment, but
# they are not subsequently updated with node changes. However, they contain
# a greater range of information, including settings and network config. They
# are also created on the system earlier in the deployment process, so are
# good sources of initial node information during Calico setup.
PRIMARY_CONTROLLER_CFG = "/etc/primary-controller.yaml"
CONTROLLER_CFG = "/etc/controller.yaml"
COMPUTE_CFG = "/etc/compute.yaml"
def get_config_file_for_node_type():
if os.path.isfile(PRIMARY_CONTROLLER_CFG):
config_file = PRIMARY_CONTROLLER_CFG
elif os.path.isfile(CONTROLLER_CFG):
config_file = CONTROLLER_CFG
elif os.path.isfile(COMPUTE_CFG):
config_file = COMPUTE_CFG
else:
raise Exception("Unrecognised node type - can't obtain config")
return config_file

View File

@ -0,0 +1,78 @@
notice('MODULAR: calico/compute_alt_gateway.pp')
$network_scheme = hiera_hash('network_scheme')
prepare_network_config($network_scheme)
$network_metadata = hiera_hash('network_metadata', {})
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$calico_mark = '0xCA'
$neutron_config = hiera_hash('neutron_config')
$private_net_name = try_get_value($neutron_config, 'default_private_net', 'admin_internal_net')
$neutron_networks = try_get_value($neutron_config, 'predefined_networks', {})
$private_net = try_get_value($neutron_networks, $private_net_name, {'L3'=>{}})
$subnet_cidr = pick($private_net['L3']['subnet'], '10.20.0.0/16')
$calico_alt_gateway_br = get_network_role_property('neutron/mesh','interface')
$calico_alt_gateway = try_get_value($network_scheme,"endpoints/${calico_alt_gateway_br}/vendor_specific/provider_gateway")
# Firewall initials
class { '::firewall':}
Class['::firewall'] -> Firewall<||>
Class['::firewall'] -> Firewallchain<||>
# iptables -t mangle -N calico-alt-gw-MARK
firewallchain { 'calico-alt-gw-MARK:mangle:IPv4':
ensure => present,
}->
# iptables -t mangle -A PREROUTING -i tap+ -j calico-alt-gw-MARK
firewall { '010 process traffic from VM instances to outside':
ensure => present,
table => 'mangle',
chain => 'PREROUTING',
iniface => 'tap+',
proto => 'all',
jump => 'calico-alt-gw-MARK',
} ->
#iptables -t mangle -A calico-alt-gw-MARK -d 192.168.111.0/24 -j RETURN
firewall { '011 skip internal traffic':
ensure => present,
table => 'mangle',
chain => 'calico-alt-gw-MARK',
destination => $subnet_cidr,
proto => 'all',
jump => 'RETURN',
} ->
#iptables -t mangle -A calico-alt-gw-MARK -j MARK --set-mark 0x222
firewall { '012 mark traffic from VM instances to outside':
ensure => present,
table => 'mangle',
chain => 'calico-alt-gw-MARK',
jump => 'MARK',
proto => 'all',
set_mark => $calico_mark
}
file { '/etc/init/calico-alt-gateway.conf':
ensure => present,
mode => '0644',
owner => 'root',
group => 'root',
content => template('calico/calico-alt-gateway.conf.erb'),
} ~>
service {'calico-alt-gateway':
ensure => running,
enable => true,
hasrestart => false,
}
# Without such settings source-routing works wrong. For more details
# read the https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
# Value '2' may be better, but Calico Felix agent is not compotible with '2'
sysctl::value {
'net.ipv4.conf.all.rp_filter': value => "0";
"net.ipv4.conf.${calico_alt_gateway_br}.rp_filter": value => "0";
}
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,36 @@
notice('MODULAR: calico/compute_bird.pp')
prepare_network_config(hiera_hash('network_scheme'))
$network_metadata = hiera_hash('network_metadata', {})
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
$enable_ipv4 = try_get_value($plugin_settings, 'enable_ipv4', true)
$enable_ipv6 = try_get_value($plugin_settings, 'enable_ipv6', false)
$as_number = try_get_value($plugin_settings, 'as_number', 65001)
$local_ip = get_network_role_property('neutron/mesh', 'ipaddr')
$rr_nodes = get_nodes_hash_by_roles($network_metadata, ['calico-rr'])
$rr_nodes_ip = get_node_to_ipaddr_map_by_network_role($rr_nodes, 'neutron/mesh')
# Firewall initials
class { '::firewall':}
Class['::firewall'] -> Firewall<||>
Class['::firewall'] -> Firewallchain<||>
firewall { '410 bird':
dport => '179',
proto => 'tcp',
action => 'accept',
} ->
class { 'calico::bird':
template => 'compute',
as_number => $as_number,
enable_ipv4 => $enable_ipv4,
enable_ipv6 => $enable_ipv6,
src_addr => $local_ip,
rr_servers => $rr_nodes_ip,
}

View File

@ -0,0 +1,50 @@
notice('MODULAR: calico/compute_dhcp_agent.pp')
# stub for task-based deployment
# class neutron { }
# class { 'neutron' : }
$debug = hiera('debug', true)
$resync_interval = '30'
# class { '::neutron::agents::dhcp':
# debug => $debug,
# resync_interval => $resync_interval,
# manage_service => false,
# enable_isolated_metadata => true,
# enabled => false,
# }
# # stub package for 'neutron::agents::dhcp' class
# package { 'neutron':
# name => 'binutils',
# ensure => 'installed',
# }
package { 'neutron-dhcp-agent':
ensure => 'installed',
} ->
service { 'neutron-dhcp-agent':
ensure => 'stopped',
enable => false
}
tweaks::ubuntu_service_override { 'neutron-dhcp-agent':
package_name => 'neutron-dhcp-agent',
}
Package['neutron-dhcp-agent'] ->
package { 'calico-dhcp-agent':
ensure => 'installed',
} ->
service { 'calico-dhcp-agent':
ensure => 'running',
enable => true
}
tweaks::ubuntu_service_override { 'calico-dhcp-agent':
package_name => 'calico-dhcp-agent',
}
neutron_config { 'DEFAULT/use_namespaces': value => false }
Neutron_config<||> ~> Service['calico-dhcp-agent']
Neutron_dhcp_agent_config<||> ~> Service['calico-dhcp-agent']

View File

@ -0,0 +1,41 @@
notice('MODULAR: calico/compute_felix.pp')
include calico
# required, because neutron-dhcp-agent one of dependency of calico-compute
package { 'neutron-dhcp-agent':
ensure => 'installed',
} ->
service { 'neutron-dhcp-agent':
ensure => 'stopped',
enable => false
}
tweaks::ubuntu_service_override { 'neutron-dhcp-agent':
package_name => 'neutron-dhcp-agent',
}
package { 'calico-felix':
ensure => 'installed',
} ->
package { 'calico-compute':
ensure => 'installed',
} ->
service { 'calico-felix':
ensure => 'running',
enable => true
}
tweaks::ubuntu_service_override { 'calico-felix':
package_name => 'calico-felix',
}
$etcd_host = '127.0.0.1'
$etcd_port = $calico::params::etcd_port
$metadata_host = '127.0.0.1'
$metadata_port = 8775
Package['calico-felix'] ->
file { '/etc/calico/felix.cfg':
ensure => present,
content => template('calico/felix.cfg.erb'),
} ~>
Service['calico-felix']

View File

@ -0,0 +1,20 @@
notice('MODULAR: calico/compute_metadata_api.pp')
# $network_scheme = hiera_hash('network_scheme', {})
# prepare_network_config($network_scheme)
# $network_metadata = hiera_hash('network_metadata', {})
package { 'nova-api-metadata':
name => 'nova-api-metadata',
ensure => 'installed',
} ->
service { 'nova-api-metadata':
enable => true,
ensure => running
}
# Package['nova-api-metadata'] -> Nova_config<||>
# tweaks::ubuntu_service_override { 'nova-api-metadata':
# package_name => 'nova-api-metadata'
# }
# Nova_config<||> -> Service['nova-api-metadata']

View File

@ -0,0 +1,114 @@
notice('MODULAR: calico/compute_neutron_nova.pp')
$network_scheme = hiera_hash('network_scheme', {})
prepare_network_config($network_scheme)
$network_metadata = hiera_hash('network_metadata', {})
include calico
include ::nova::params
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
$neutron_config = hiera_hash('neutron_config')
$management_vip = hiera('management_vip')
$service_endpoint = hiera('service_endpoint', $management_vip)
# # LP#1526938 - python-mysqldb supports this, python-pymysql does not
# if $::os_package_type == 'debian' {
# $extra_params = { 'charset' => 'utf8', 'read_timeout' => 60 }
# } else {
# $extra_params = { 'charset' => 'utf8' }
# }
# $net_role_property = 'neutron/mesh'
# $iface = get_network_role_property($net_role_property, 'phys_dev')
# $physical_net_mtu = pick(get_transformation_property('mtu', $iface[0]), '1500')
$nova_hash = hiera_hash('nova', {})
$libvirt_vif_driver = pick($nova_hash['libvirt_vif_driver'], 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver')
$region_name = hiera('region', 'RegionOne')
$admin_password = try_get_value($neutron_config, 'keystone/admin_password')
$admin_tenant_name = try_get_value($neutron_config, 'keystone/admin_tenant', 'services')
$admin_username = try_get_value($neutron_config, 'keystone/admin_user', 'neutron')
$auth_api_version = 'v3'
$ssl_hash = hiera_hash('use_ssl', {})
$admin_identity_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'protocol', 'http')
$admin_identity_address = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'hostname', [$service_endpoint, $management_vip])
$neutron_internal_protocol = get_ssl_property($ssl_hash, {}, 'neutron', 'internal', 'protocol', 'http')
$neutron_internal_endpoint = get_ssl_property($ssl_hash, {}, 'neutron', 'internal', 'hostname', [hiera('neutron_endpoint', ''), $management_vip])
$neutron_auth_url = "${admin_identity_protocol}://${admin_identity_address}:35357/${auth_api_version}"
$neutron_url = "${neutron_internal_protocol}://${neutron_internal_endpoint}:9696"
$nova_migration_ip = get_network_role_property('nova/migration', 'ipaddr')
service { 'libvirt' :
ensure => 'running',
enable => true,
name => $::nova::params::libvirt_service_name,
provider => $::nova::params::special_service_provider,
} ->
exec { 'destroy_libvirt_default_network':
command => 'virsh net-destroy default',
onlyif => "virsh net-list | grep -qE '^\s*default\s'",
path => [ '/bin', '/sbin', '/usr/bin', '/usr/sbin' ],
tries => 3,
} ->
exec { 'undefine_libvirt_default_network':
command => 'virsh net-undefine default',
onlyif => "virsh net-list --all | grep -qE '^\s*default\s'",
path => [ '/bin', '/sbin', '/usr/bin', '/usr/sbin' ],
tries => 3,
}
Service['libvirt'] ~> Exec['destroy_libvirt_default_network']
Service['libvirt'] ~> Exec['undefine_libvirt_default_network']
# script called by qemu needs to manipulate the tap device
file_line { 'clear_emulator_capabilities':
path => '/etc/libvirt/qemu.conf',
line => 'clear_emulator_capabilities = 0',
notify => Service['libvirt']
}
class { '::nova::compute::neutron':
libvirt_vif_driver => undef,
force_snat_range => undef,
}
nova_config {
'DEFAULT/linuxnet_interface_driver': ensure => absent;
'DEFAULT/my_ip': value => $nova_migration_ip;
}
class { '::nova::network::neutron' :
neutron_password => $admin_password,
neutron_project_name => $admin_tenant_name,
neutron_region_name => $region_name,
neutron_username => $admin_username,
neutron_auth_url => $neutron_auth_url,
neutron_url => $neutron_url,
neutron_ovs_bridge => '',
}
augeas { 'sysctl-net.bridge.bridge-nf-call-arptables':
context => '/files/etc/sysctl.conf',
changes => "set net.bridge.bridge-nf-call-arptables '1'",
before => Service['libvirt'],
}
augeas { 'sysctl-net.bridge.bridge-nf-call-iptables':
context => '/files/etc/sysctl.conf',
changes => "set net.bridge.bridge-nf-call-iptables '1'",
before => Service['libvirt'],
}
augeas { 'sysctl-net.bridge.bridge-nf-call-ip6tables':
context => '/files/etc/sysctl.conf',
changes => "set net.bridge.bridge-nf-call-ip6tables '1'",
before => Service['libvirt'],
}

View File

@ -0,0 +1,30 @@
notice('MODULAR: calico/etcd_proxy.pp')
prepare_network_config(hiera_hash('network_scheme'))
$network_metadata = hiera_hash('network_metadata', {})
include calico
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
# Firewall initials
class { '::firewall':}
Class['::firewall'] -> Firewall<||>
Class['::firewall'] -> Firewallchain<||>
firewall { '400 etcd':
dport => [
$calico::params::etcd_port
],
proto => 'tcp',
action => 'accept',
} ->
# Deploy etcd cluster member
class { 'calico::etcd':
node_role => 'proxy',
bind_host => $calico::params::mgmt_ip,
bind_port => $calico::params::etcd_port,
cluster_nodes => $calico::params::etcd_servers_named_list,
}

View File

@ -0,0 +1,22 @@
# Manifest that creates hiera config overrride
notice('MODULAR: calico/hiera_override.pp')
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
$network_scheme = hiera_hash("network_scheme", {})
# Mangle network_scheme for setup new gateway
if $plugin_settings['metadata']['enabled'] {
if $plugin_settings['network_name'] == 'another' {
$network_name = $plugin_settings['another_network_name']
} else {
$network_name = $plugin_settings['network_name']
}
$overrides = remove_ovs_usage($network_scheme)
file {"/etc/hiera/plugins/${plugin_name}.yaml":
ensure => file,
content => inline_template("<%= @overrides %>")
}
}
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,39 @@
notice('MODULAR: calico/neutron_networks.pp')
#include calico
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
$access_hash = hiera_hash('access', {})
$tenant_name = try_get_value($access_hash, 'tenant', 'admin')
# From docs:
# neutron net-create --shared --provider:network_type local calico
# neutron subnet-create --gateway 10.65.0.1 --enable-dhcp --ip-version 4 --name calico-v4 calico 10.65.0/24
$net = 'calico'
$subnet = 'calico-v4'
$neutron_config = hiera_hash('neutron_config')
$private_net_name = try_get_value($neutron_config, 'default_private_net', 'admin_internal_net')
$neutron_networks = try_get_value($neutron_config, 'predefined_networks', {})
$private_net = try_get_value($neutron_networks, $private_net_name, {'L3'=>{}})
$subnet_cidr = pick($private_net['L3']['subnet'], '10.20.0.0/16')
$subnet_gw = pick($private_net['L3']['gateway'], '10.20.0.1')
neutron_network { $net :
ensure => 'present',
provider_network_type => 'local',
shared => true,
tenant_name => $tenant_name,
} ->
neutron_subnet { $subnet :
ensure => 'present',
cidr => $subnet_cidr,
network_name => $net,
gateway_ip => $subnet_gw,
enable_dhcp => true,
ip_version => '4',
tenant_name => $tenant_name,
}

View File

@ -0,0 +1,192 @@
notice('MODULAR: calico/neutron_server_config.pp')
# stub for task-based deployment
class neutron { }
class { 'neutron' : }
$network_scheme = hiera_hash('network_scheme', {})
prepare_network_config($network_scheme)
$network_metadata = hiera_hash('network_metadata', {})
include calico
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
# override neutron options
$override_configuration = hiera_hash('configuration', {})
override_resources { 'neutron_api_config':
data => $override_configuration['neutron_api_config']
} ~> Service['neutron-server']
override_resources { 'neutron_config':
data => $override_configuration['neutron_config']
} ~> Service['neutron-server']
override_resources { 'neutron_plugin_ml2':
data => $override_configuration['neutron_plugin_ml2']
} ~> Service['neutron-server']
$neutron_config = hiera_hash('neutron_config')
$neutron_server_enable = pick($neutron_config['neutron_server_enable'], true)
$database_vip = hiera('database_vip')
$management_vip = hiera('management_vip')
$service_endpoint = hiera('service_endpoint', $management_vip)
$nova_endpoint = hiera('nova_endpoint', $management_vip)
$nova_hash = hiera_hash('nova', { })
$neutron_primary_controller_roles = hiera('neutron_primary_controller_roles', ['primary-controller'])
$neutron_compute_roles = hiera('neutron_compute_nodes', ['compute'])
$primary_controller = roles_include($neutron_primary_controller_roles)
$compute = roles_include($neutron_compute_roles)
$db_type = 'mysql'
$db_password = $neutron_config['database']['passwd']
$db_user = try_get_value($neutron_config, 'database/user', 'neutron')
$db_name = try_get_value($neutron_config, 'database/name', 'neutron')
$db_host = try_get_value($neutron_config, 'database/host', $database_vip)
# LP#1526938 - python-mysqldb supports this, python-pymysql does not
if $::os_package_type == 'debian' {
$extra_params = { 'charset' => 'utf8', 'read_timeout' => 60 }
} else {
$extra_params = { 'charset' => 'utf8' }
}
$db_connection = os_database_connection({
'dialect' => $db_type,
'host' => $db_host,
'database' => $db_name,
'username' => $db_user,
'password' => $db_password,
'extra' => $extra_params
})
$password = $neutron_config['keystone']['admin_password']
$username = pick($neutron_config['keystone']['admin_user'], 'neutron')
$project_name = pick($neutron_config['keystone']['admin_tenant'], 'services')
$region_name = hiera('region', 'RegionOne')
$auth_endpoint_type = 'internalURL'
$ssl_hash = hiera_hash('use_ssl', {})
$internal_auth_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'protocol', 'http')
$internal_auth_endpoint = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'hostname', [$service_endpoint, $management_vip])
$admin_auth_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'protocol', 'http')
$admin_auth_endpoint = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'hostname', [$service_endpoint, $management_vip])
$nova_internal_protocol = get_ssl_property($ssl_hash, {}, 'nova', 'internal', 'protocol', 'http')
$nova_internal_endpoint = get_ssl_property($ssl_hash, {}, 'nova', 'internal', 'hostname', [$nova_endpoint])
$auth_api_version = 'v2.0'
$auth_uri = "${internal_auth_protocol}://${internal_auth_endpoint}:5000/"
$auth_url = "${internal_auth_protocol}://${internal_auth_endpoint}:35357/"
$nova_admin_auth_url = "${admin_auth_protocol}://${admin_auth_endpoint}:35357/"
$nova_url = "${nova_internal_protocol}://${nova_internal_endpoint}:8774/v2"
$workers_max = hiera('workers_max', 16)
$service_workers = pick($neutron_config['workers'], min(max($::processorcount, 1), $workers_max))
$neutron_advanced_config = hiera_hash('neutron_advanced_configuration', { })
$enable_qos = pick($neutron_advanced_config['neutron_qos'], false)
if $enable_qos {
$qos_notification_drivers = 'message_queue'
$extension_drivers = ['port_security', 'qos']
} else {
$qos_notification_drivers = undef
$extension_drivers = ['port_security']
}
$nova_auth_user = pick($nova_hash['user'], 'nova')
$nova_auth_password = $nova_hash['user_password']
$nova_auth_tenant = pick($nova_hash['tenant'], 'services')
$net_role_property = 'neutron/mesh'
$iface = get_network_role_property($net_role_property, 'phys_dev')
$physical_net_mtu = pick(get_transformation_property('mtu', $iface[0]), '1500')
Package['neutron'] ~>
package { 'calico-control':
ensure => 'installed',
}
Package['calico-control'] -> Class['::neutron::server']
Package['calico-control'] -> Class['::neutron::plugins::ml2']
class { '::neutron::plugins::ml2':
type_drivers => ['local', 'flat'],
tenant_network_types => 'local',
mechanism_drivers => ['calico'],
flat_networks => ['*'],
#network_vlan_ranges => $network_vlan_ranges,
#tunnel_id_ranges => [],
#vxlan_group => $vxlan_group,
#vni_ranges => $tunnel_id_ranges,
path_mtu => $physical_net_mtu,
extension_drivers => $extension_drivers,
#supported_pci_vendor_devs => $pci_vendor_devs,
sriov_agent_required => false,
enable_security_group => true,
firewall_driver => 'neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver',
}
class { '::neutron::server':
sync_db => $primary_controller,
username => $username,
password => $password,
project_name => $project_name,
region_name => $region_name,
auth_url => $auth_url,
auth_uri => $auth_uri,
database_connection => $db_connection,
database_max_retries => hiera('max_retries'),
database_idle_timeout => hiera('idle_timeout'),
database_max_pool_size => hiera('max_pool_size'),
database_max_overflow => hiera('max_overflow'),
database_retry_interval => '2',
agent_down_time => 60, # it's a requirements of calico-plugin
allow_automatic_l3agent_failover => false,
l3_ha => false,
api_workers => 0, # it's a requirements of
rpc_workers => 0, # calico-plugin
router_distributed => false,
qos_notification_drivers => $qos_notification_drivers,
enabled => true,
manage_service => true,
}
Package['neutron'] ~>
augeas { "dhcp_agents_per_network":
#context => "/files/etc/neutron/neutron.conf",
incl => "/etc/neutron/neutron.conf",
lens => 'Puppet.lns',
changes => [
"set DEFAULT/dhcp_agents_per_network ${calico::params::compute_nodes_count}",
],
} ~> Service['neutron-server']
include ::neutron::params
tweaks::ubuntu_service_override { $::neutron::params::server_service:
package_name => $neutron::params::server_package ? {
false => $neutron::params::package_name,
default => $neutron::params::server_package
}
}
class { '::neutron::server::notifications':
nova_url => $nova_url,
auth_url => $nova_admin_auth_url,
username => $nova_auth_user,
project_name => $nova_auth_tenant,
password => $nova_auth_password,
region_name => $region_name,
}
# Stub for Nuetron package
package { 'neutron':
name => 'binutils',
ensure => 'installed',
}

View File

@ -0,0 +1,12 @@
notice('MODULAR: calico/private_gateway_check.pp')
$network_scheme = hiera_hash('network_scheme')
prepare_network_config($network_scheme)
$calico_alt_gateway_br = get_network_role_property('neutron/mesh','interface')
$calico_alt_gateway = try_get_value($network_scheme,"endpoints/${calico_alt_gateway_br}/vendor_specific/provider_gateway")
if ! is_ip_address($calico_alt_gateway) {
fail("Gateway for Private network does not specified or wrong !!!")
}
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,25 @@
notice('MODULAR: calico/repo_setup.pp')
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
# Bird PPA
apt::source { 'bird-repo':
location => 'http://ppa.launchpad.net/cz.nic-labs/bird/ubuntu',
repos => 'main',
#release => 'trusty',
include => { 'src' => false },
}
# Calico PPA
apt::source { 'calico-repo':
#location => "http://ppa.launchpad.net/project-calico/stable/ubuntu",
location => "http://ppa.launchpad.net/project-calico/calico-1.4/ubuntu",
repos => 'main',
#release => 'trusty',
include => { 'src' => false },
}
Apt::Source<||> ~> Exec<| title == 'apt_update' |>
Exec<| title == 'apt_update' |> -> Package<||>

View File

@ -0,0 +1,36 @@
notice('MODULAR: calico/etcd.pp')
prepare_network_config(hiera_hash('network_scheme'))
$network_metadata = hiera_hash('network_metadata', {})
include calico
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
$cluster_info = hiera_hash('cluster', {})
$cluster_token = try_get_value($cluster_info, 'name', 'openstack-calico-cluster')
# Firewall initials
class { '::firewall':}
Class['::firewall'] -> Firewall<||>
Class['::firewall'] -> Firewallchain<||>
firewall { '400 etcd':
dport => [
$calico::params::etcd_port,
$calico::params::etcd_peer_port
],
proto => 'tcp',
action => 'accept',
} ->
# Deploy etcd cluster member
class { 'calico::etcd':
node_role => 'server',
bind_host => $calico::params::mgmt_ip,
bind_port => $calico::params::etcd_port,
peer_host => $calico::params::mgmt_ip,
peer_port => $calico::params::etcd_peer_port,
cluster_nodes => $calico::params::etcd_servers_named_list,
cluster_token => $cluster_token
}

View File

@ -0,0 +1,43 @@
notice('MODULAR: calico/rr_bird.pp')
prepare_network_config(hiera_hash('network_scheme'))
$network_metadata = hiera_hash('network_metadata', {})
# Initial constants
$plugin_name = 'fuel-plugin-calico'
$plugin_settings = hiera_hash("${plugin_name}", {})
$enable_ipv4 = try_get_value($plugin_settings, 'enable_ipv4', true)
$enable_ipv6 = try_get_value($plugin_settings, 'enable_ipv6', false)
$as_number = try_get_value($plugin_settings, 'as_number', 65001)
if try_get_value($plugin_settings, 'enable_external_peering', false) {
$ext_peers = convert_external_peers(try_get_value($plugin_settings, 'external_peers', ''))
} else {
$ext_peers = {}
}
$local_ip = get_network_role_property('neutron/mesh', 'ipaddr')
$compute_nodes = get_nodes_hash_by_roles($network_metadata, ['compute'])
$compute_nodes_ip = get_node_to_ipaddr_map_by_network_role($compute_nodes, 'neutron/mesh')
# Firewall initials
class { '::firewall':}
Class['::firewall'] -> Firewall<||>
Class['::firewall'] -> Firewallchain<||>
firewall { '410 bird':
dport => '179',
proto => 'tcp',
action => 'accept',
} ->
class { 'calico::bird':
template => 'rr',
as_number => $as_number,
enable_ipv4 => $enable_ipv4,
enable_ipv6 => $enable_ipv6,
src_addr => $local_ip,
rr_clients => $compute_nodes_ip,
rr_servers => {},
ext_peers => $ext_peers,
}

View File

@ -0,0 +1,12 @@
name 'calico'
version '0.1.0'
source 'UNKNOWN'
author 'mirantis'
license 'Apache License, Version 2.0'
summary 'UNKNOWN'
description 'UNKNOWN'
project_page 'UNKNOWN'
## Add dependencies, if any:
# dependency 'username/name', '>= 1.2.0'
dependency 'puppetlabs/stdlib', '>=4.6.0'

View File

@ -0,0 +1,28 @@
Puppet::Parser::Functions::newfunction( :convert_external_peers,
:type => :rvalue, :doc => <<-EOS
This function get text in format
name:asnum:ipaddr:flags...
and convert to hash, used into generate_bgp_peers()
{
peer_name => {
ipaddr => '1.2.3.4',
as_number => '64646'
}
}
EOS
) do |argv|
if argv.size != 1
raise(
Puppet::ParseError,
"convert_external_peers(): Wrong number of arguments. Should be one."
)
end
peers = argv[0]
as_number = argv[1]
Hash[*peers.split(/\n/).map{|v| v.gsub(/\s+/, "")}.reject{|c| c.empty?}.map{|v| v.split(':')}.reject{|v| v.size<3}.map{|l| [l[0],{'as_number'=>l[1],'ipaddr'=> l[2]}]}.flatten]
end
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,51 @@
Puppet::Parser::Functions::newfunction( :convert_internal_peers,
:type => :rvalue, :doc => <<-EOS
This function get peers name-to-ipaddr map, as_number
and convert to hassh, used into generate_bgp_peers()
Usage:
convert_internal_peers(
$peers_hash,
$local_as_number,
)
Hash
{
peer_name -> '1.2.3.4'
}
will be converted to
{
peer_name => {
ipaddr => '1.2.3.4',
as_number => '64646'
}
}
EOS
) do |argv|
if argv.size != 2
raise(
Puppet::ParseError,
"convert_internal_peers(): Wrong number of arguments. Should be two."
)
end
if !argv[0].is_a?(Hash)
raise(
Puppet::ParseError,
"convert_internal_peers(): Wrong peers map."
)
end
peers = argv[0]
as_number = argv[1]
rv = {}
peers.each do |name, ipaddr|
rv[name] = {
'ipaddr' => ipaddr,
'as_number' => as_number,
}
end
return rv
end
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,55 @@
Puppet::Parser::Functions::newfunction( :generate_bgp_peers,
:type => :statement, :doc => <<-EOS
This function get internal peers map, connectivity options
and create corresponded resources.
Usage:
generate_bgp_peers(
$peers_hash,
$template_name,
$local_ipaddr,
$local_as_number,
)
Peers_hash should be in format:
{
peer_name => {
ipaddr => '1.2.3.4',
as_number => '64646'
}
}
EOS
) do |argv|
if argv.size != 4
raise(
Puppet::ParseError,
"generate_bgp_peers(): Wrong number of arguments. Should be four."
)
end
if !argv[0].is_a?(Hash)
raise(
Puppet::ParseError,
"generate_bgp_peers(): Wrong peers map."
)
end
peers = argv[0]
template = argv[1]
local_ipaddr = argv[2]
local_as_number = argv[3]
resources = {}
peers.each do |name, peer_hash|
#file_name = "/etc/bird/peers/#{template}__#{name}.conf"
resources[name] = {
'template' => template,
'local_ipaddr' => local_ipaddr,
'remote_ipaddr' => peer_hash['ipaddr'],
'local_as_number' => local_as_number,
'remote_as_number' => peer_hash['as_number'],
}
end
function_create_resources(['calico::bird::bgp_peer_record', resources])
return true
end
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,65 @@
require 'yaml'
Puppet::Parser::Functions::newfunction( :remove_ovs_usage,
:type => :rvalue, :doc => <<-EOS
This function get network_scheme and returns mangled
network scheme without ovs-based elements.
EOS
) do |argv|
def bridge_name_max_len
15
end
if argv.size != 1
raise(
Puppet::ParseError,
"remove_ovs_usage(): Wrong number of arguments. Should be two."
)
end
if !argv[0].is_a?(Hash)
raise(
Puppet::ParseError,
"remove_ovs_usage(): Wrong network_scheme. Should be non-empty Hash."
)
end
if argv[0]['version'].to_s.to_f < 1.1
raise(
Puppet::ParseError,
"remove_ovs_usage(): You network_scheme hash has wrong format.\nThis parser can work with v1.1 format, please convert you config."
)
end
network_scheme = argv[0]
rv = {
'use_ovs' => false
}
overrides = []
network_scheme['transformations'].each do |tr|
if tr['provider'] == 'ovs'
if tr['action'] == 'add-patch'
overrides << {
'action' => 'override',
'override' => "patch-#{tr['bridges'][0]}:#{tr['bridges'][1]}",
'provider' => 'lnx'
}
else
overrides << {
'action' => 'override',
'override' => tr['name'],
'provider' => 'lnx'
}
end
end
end
if ! overrides.empty?
rv['network_scheme'] = {
'transformations' => overrides
}
end
return rv.to_yaml() + "\n"
end
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,95 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
class calico::bird (
$template,
$src_addr,
$as_number = '64511',
$enable_ipv4 = true,
$enable_ipv6 = false,
$rr_clients = {},
$rr_servers = {},
$ext_peers = {},
) {
include ::calico
tweaks::ubuntu_service_override { 'bird':
package_name => 'bird',
}
tweaks::ubuntu_service_override { 'bird6':
package_name => 'bird',
}
package { 'bird':
ensure => installed,
} ->
file { '/etc/bird':
ensure => directory,
} ->
file { '/etc/bird/peers':
ensure => directory,
} ->
file { '/etc/bird/custom.conf':
ensure => present,
} ->
file { '/etc/bird/calico_os_filters.conf':
ensure => present,
mode => '0644',
owner => 'root',
group => 'root',
content => template("calico/bird-calico_os-filters.conf.erb"),
} ->
file { '/etc/bird/bird.conf':
ensure => present,
mode => '0644',
owner => 'root',
group => 'root',
content => template("calico/bird-${template}.conf.erb"),
}
# generate peer-config-files
generate_bgp_peers(convert_internal_peers($rr_servers, $as_number), 'rr', $src_addr, $as_number)
generate_bgp_peers(convert_internal_peers($rr_clients, $as_number), 'compute', $src_addr, $as_number)
generate_bgp_peers($ext_peers, 'ext', $src_addr, $as_number)
if $enable_ipv4 {
Package['bird'] ~>
service { 'bird':
ensure => running,
enable => true,
hasrestart => false,
restart => '/usr/sbin/birdc configure'
}
File['/etc/bird/calico_os_filters.conf'] ~> Service['bird']
File['/etc/bird/custom.conf'] ~> Service['bird']
File['/etc/bird/bird.conf'] ~> Service['bird']
}
if $enable_ipv6 {
Package['bird'] ~>
service { 'bird6':
ensure => running,
enable => true,
hasrestart => false,
restart => '/usr/sbin/birdc6 configure'
}
File['/etc/bird/calico_os_filters.conf'] ~> Service['bird6']
File['/etc/bird/custom.conf'] ~> Service['bird6']
File['/etc/bird/bird6.conf'] ~> Service['bird6']
}
}
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,35 @@
define calico::bird::bgp_peer_record (
$local_ipaddr,
$remote_ipaddr,
$local_as_number,
$remote_as_number,
$include = false,
$ensure = 'present',
$template = 'ext',
) {
include ::calico::params
$peer_config_path = "/etc/bird/peers/${template}__${name}.conf"
file { "${peer_config_path}":
ensure => $ensure,
require => File['/etc/bird/peers'],
before => File['/etc/bird/bird.conf'],
notify => Service['bird'],
content => template("calico/bird-peer-${template}.conf.erb"),
}
if $include {
file_line {"":
line => "include ${peer_config_path};",
path => '/etc/bird/bird.conf',
#after => undef,
#ensure => 'present',
#match => undef, # /.*match/
#multiple => undef, # 'true' or 'false'
#name => undef,
#replace => true, # 'true' or 'false'
require => File['/etc/bird/bird.conf'],
notify => Service['bird']
}
}
}
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,77 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
class calico::etcd (
$node_name = $::hostname,
$node_role,
$bind_host = $::ipaddress,
$bind_port = '4001',
$peer_host = $::ipaddress,
$peer_port = '2380',
$cluster_nodes = undef,
$cluster_token = 'fuel-cluster-1'
) {
case $node_role {
'proxy': {
$etcd_cmd_opts = "--proxy on \
--initial-cluster=${cluster_nodes} \
>>/var/log/etcd.log 2>&1"
}
'server': {
$etcd_cmd_opts = "--name=${node_name} \
--advertise-client-urls=http://${bind_host}:${bind_port} \
--listen-client-urls=http://127.0.0.1:${bind_port},http://${bind_host}:${bind_port} \
--listen-peer-urls=http://127.0.0.1:${peer_port},http://${peer_host}:${peer_port} \
--initial-cluster-token='${cluster_token}' \
--initial-cluster=${cluster_nodes} \
--initial-cluster-state=new \
--initial-advertise-peer-urls=http://${peer_host}:${peer_port} \
>>/var/log/etcd.log 2>&1"
}
default: {
}
}
tweaks::ubuntu_service_override { 'etcd':
package_name => 'etcd',
}
package { ['etcd','python-etcd']:
ensure => installed,
} ->
file { '/var/log/etcd.log':
ensure => present,
mode => '0644',
owner => 'etcd',
group => 'etcd',
} ->
file { '/etc/init/etcd.conf':
ensure => present,
mode => '0644',
owner => 'root',
group => 'root',
content => template('calico/etcd.conf.erb'),
} ~>
service { 'etcd':
ensure => 'running',
enable => true,
provider => 'upstart'
}
}
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,20 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
class calico {
include calico::params
}
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,43 @@
# Copyright 2016 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
class calico::params {
# Network
$network_scheme = hiera_hash('network_scheme', {})
$network_metadata = hiera_hash('network_metadata', {})
prepare_network_config($network_scheme)
# current node params
$node = hiera('node')
$roles = hiera('roles')
$mgmt_ip = get_network_role_property('mgmt/vip', 'ipaddr')
# computes
$compute_nodes = get_nodes_hash_by_roles($network_metadata, ['compute'])
$compute_nodes_count = size($compute_nodes)
# etcd nodes
$etcd_nodes = get_nodes_hash_by_roles($network_metadata, ['calico-etcd'])
$etcd_nodes_map = get_node_to_ipaddr_map_by_network_role($etcd_nodes, 'mgmt/vip')
$etcd_nodes_ips = ipsort(values($etcd_nodes_map))
# etcd daemon settings
$etcd_port = '4001'
$etcd_peer_port = '2380'
$etcd_servers = suffix(prefix($etcd_nodes_ips, 'http://'), ":${etcd_port}")
$etcd_servers_list = join($etcd_servers, ',')
$etcd_servers_named_list = join(suffix(join_keys_to_values($etcd_nodes_map,"=http://"), ":${etcd_peer_port}"), ',')
}
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,17 @@
dir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift File.join(dir, 'lib')
require 'mocha'
require 'puppet'
require 'rspec'
require 'spec/autorun'
Spec::Runner.configure do |config|
config.mock_with :mocha
end
# We need this because the RAL uses 'should' as a method. This
# allows us the same behaviour but with a different method name.
class Object
alias :must :should
end

View File

@ -0,0 +1,18 @@
# We are only going to export routes from Calico interfaces.
# Currently, 'tap*' is used by the OpenStack implimentation
# and 'cali*' is used by the docker implimentation.
# dummy1 is the interface that bare metal "service" addresses
# should be bound to if they should be exported.
# This will need to be updated as we add new interface names.
#
# Also filter out default, just in case.
#
# We should automate the build of this out of variables when
# we have time.
filter calico_openstack__export_bgp {
if ( (ifname ~ "tap*") || (ifname ~ "cali*") || (ifname ~ "dummy1") ) then {
if net != 0.0.0.0/0 then accept;
}
reject;
}

View File

@ -0,0 +1,29 @@
router id <%= @src_addr %>;
listen bgp address <%= @src_addr %>;
include "/etc/bird/calico_os_filters.conf";
# Configure synchronization between BIRD's routing tables and the
# kernel.
protocol kernel {
learn; # Learn all alien routes from the kernel
persist; # Don't remove routes on bird shutdown
scan time 2; # Scan kernel routing table every 2 seconds
import all;
graceful restart;
export all; # Default is export none
}
# Watch interface up/down events.
protocol device {
scan time 2; # Scan interfaces every 2 seconds
}
protocol direct {
debug all;
interface "br-mesh";
}
<%- @rr_servers.each do |name, ipaddr| -%>
include "/etc/bird/peers/rr__<%= name %>.conf";
<%- end -%>

View File

@ -0,0 +1,10 @@
protocol bgp '<%= @name %>' {
local as <%= @local_as_number %>;
neighbor <%= @remote_ipaddr %> as <%= @remote_as_number %>;
description "RR-client <%= @name %>";
multihop;
rr client;
import all;
export all;
source address <%= @local_ipaddr %>;
}

View File

@ -0,0 +1,10 @@
protocol bgp '<%= @name %>' {
local as <%= @local_as_number %>;
neighbor <%= @remote_ipaddr %> as <%= @remote_as_number %>;
description "Ext. peer <%= @name %>";
multihop;
import none;
export all;
next hop keep;
source address <%= @local_ipaddr %>;
}

View File

@ -0,0 +1,11 @@
protocol bgp '<%= @name %>' {
local as <%= @local_as_number %>;
neighbor <%= @remote_ipaddr %> as <%= @remote_as_number %>;
description "Route Reflector <%= @name %>";
multihop;
import all;
export filter calico_openstack__export_bgp;
next hop self; # Disable next hop processing and always advertise our
# local address as nexthop
source address <%= @local_ipaddr %>;
}

View File

@ -0,0 +1,26 @@
# Configure logging
log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };
log stderr all;
#log "tmp" all;
# Override router ID
router id <%= @src_addr %>;
include "/etc/bird/calico_os_filters.conf";
# Turn on global debugging of all protocols
debug protocols all;
# This pseudo-protocol watches all interface up/down events.
protocol device {
scan time 2; # Scan interfaces every 2 seconds
}
# Include custom config
include "/etc/bird/custom.conf";
<%- @rr_clients.each do |name, ipaddr| -%>
include "/etc/bird/peers/compute__<%= name %>.conf";
<%- end -%>
<%- @ext_peers.each do |name, peer| -%>
include "/etc/bird/peers/ext__<%= name %>.conf";
<%- end -%>

View File

@ -0,0 +1,13 @@
description "calico-alt-gateway"
author "Alternative default gateway for Calico network"
#start on stopped rc RUNLEVEL=[2345]
start on (net-device-up and started etcd)
#stop on runlevel [!2345]
#respawn
script
ip r add default via <%= @calico_alt_gateway %> table <%= @calico_mark %>
ip rule add fwmark <%= @calico_mark %> table <%= @calico_mark %>
end script

View File

@ -0,0 +1,15 @@
# vim:set ft=upstart ts=2 et:
description "etcd"
author "etcd maintainers"
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
setuid etcd
env ETCD_DATA_DIR=/var/lib/etcd
export ETCD_DATA_DIR
exec /usr/bin/etcd <%=@etcd_cmd_opts %>

View File

@ -0,0 +1,6 @@
[global]
EtcdAddr = <%= @etcd_host %>:<%= @etcd_port %>
#FelixHostname = hostname
MetadataAddr = <%= @metadata_host %>
MetadataPort = <%= @metadata_port %>
InterfacePrefix = tap

View File

@ -0,0 +1,12 @@
# The baseline for module testing used by Puppet Labs is that each manifest
# should have a corresponding test manifest that declares that class or defined
# type.
#
# Tests are then run by using puppet apply --noop (to check for compilation
# errors and view a log of events) or by fully applying the test in a virtual
# environment (to compare the resulting system state to the desired state).
#
# Learn more about module testing here:
# http://docs.puppetlabs.com/guides/tests_smoke.html
#
include calico

View File

@ -1,45 +0,0 @@
#!/bin/bash
# This script removes default network config created in OpenStack as part of a
# Fuel deployment. These networks do not work for instance creation with
# Calico, so need to be removed.
# OpenStack authentication and authorization requires environment variables
# contained in the openrc file, this will allow us to issue commands via the
# neutron API.
source /root/openrc
# Details of the default networks/routers created on Fuel deployment of a
# Mirantis OpenStack environment.
DEFAULT_NET=net04
DEFAULT_NET_EXT=net04_ext
DEFAULT_ROUTER=router04
# DEFAULT_NET_EXT is set as the gateway for DEFAULT_ROUTER, we must clear that
# before we can delete the network.
neutron router-gateway-clear $DEFAULT_ROUTER
neutron net-delete $DEFAULT_NET_EXT
# DEFAULT_NET cannot be deleted until all ports configured on the network have
# been removed. We get details of the configured ports from the "neutron port-list"
# command, whose output is of the form:
# +-----+------+-------------------+-----------------------------------------------+
# | id | name | mac_address | fixed_ips |
# +-----+------+-------------------+-----------------------------------------------+
# | foo | | fa:16:3e:ae:70:4e | {"subnet_id": "bar", "ip_address": "a.b.c.d"} |
# +-----+------+-------------------+-----------------------------------------------+
port_ids=$(neutron port-list | grep "|" | grep -v "fixed_ips" | cut -d " " -f 2)
for port_id in "${port_ids[@]}"
do
neutron port-delete $port_id
if [[ $? != 0 ]]; then
# One of the ports is associated with the interface for the default router.
# This causes port deletion to fail. So we delete the interface on the
# router (this also removes the port).
neutron router-interface-delete $DEFAULT_ROUTER port=$port_id
fi
done
# We can now delete the default router and the default network.
neutron router-delete $DEFAULT_ROUTER
neutron net-delete $DEFAULT_NET

View File

@ -1,42 +0,0 @@
#!/bin/bash
# Copyright 2015 Metaswitch Networks
this_node_address=$(python get_node_ip.py `hostname`)
controller_node_addresses=$(python get_node_ips_by_role.py controller)
for node_address in ${controller_node_addresses[@]}
do
initial_cluster+="${node_address}=http://${node_address}:2380,"
done
initial_cluster=${initial_cluster::-1} # remove trailing comma
service etcd stop
rm -rf /var/lib/etcd/*
awk '/exec \/usr\/bin\/etcd/{while(getline && $0 != ""){}}1' /etc/init/etcd.conf > tmp
mv tmp /etc/init/etcd.conf
cat << EXEC_CMD >> /etc/init/etcd.conf
exec /usr/bin/etcd -name ${this_node_address} \\
-advertise-client-urls "http://${this_node_address}:2379,http://${this_node_address}:4001" \\
-listen-client-urls "http://0.0.0.0:2379,http://0.0.0.0:4001" \\
-listen-peer-urls "http://0.0.0.0:2380" \\
-initial-advertise-peer-urls "http://${this_node_address}:2380" \\
-initial-cluster-token fuel-cluster-1 \\
-initial-cluster ${initial_cluster} \\
-initial-cluster-state new
EXEC_CMD
service etcd start
retry_count=0
while [[ $retry_count < 5 ]]; do
etcdctl cluster-health
if [[ $? == 0 ]]; then
break
else
((retry_count++))
service etcd restart
sleep 2
fi
done

340
deployment_tasks.yaml Normal file
View File

@ -0,0 +1,340 @@
# Groups
- id: calico-rrs
type: group
version: 2.1.0
role:
- calico-rr
tasks: [hiera, globals, setup_repositories, tools, logging, netconfig, hosts, deploy_start]
requires:
- deploy_start
required_for:
- deploy_end
parameters:
strategy:
type: one_by_one
- id: calico-etcds
type: group
version: 2.1.0
role:
- calico-etcd
tasks: [hiera, globals, setup_repositories, tools, logging, netconfig, hosts, deploy_start]
requires:
- deploy_start
required_for:
- deploy_end
parameters:
strategy:
type: one_by_one
# Plugin tasks
- id: hiera_override
type: puppet
version: 2.1.0
groups: ["/.*/"]
requires:
- hiera
required_for:
- globals
parameters:
puppet_manifest: puppet/manifests/hiera_override.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 3600
- id: calico-private-gateway-check
groups: ["/.*/"]
version: 2.1.0
requires:
- globals
required_for:
- deploy_end
- netconfig
- hosts
type: puppet
parameters:
timeout: 180
puppet_manifest: puppet/manifests/private_gateway_check.pp
puppet_modules: puppet/modules:/etc/puppet/modules
- id: calico-repo-setup
role:
- calico-rr
- calico-etcd
- primary-controller
- controller
- compute
version: 2.1.0
requires:
- netconfig
- hosts
required_for:
- deploy_end
- openstack-network-start
type: puppet
parameters:
timeout: 180
puppet_manifest: puppet/manifests/repo_setup.pp
puppet_modules: puppet/modules:/etc/puppet/modules
- id: calico-rr
role:
- calico-rr
version: 2.1.0
requires:
- netconfig
- hosts
- firewall
- calico-repo-setup
required_for:
- deploy_end
- openstack-network-start
condition:
yaql_exp: >
changedAny($.configuration, $.debug, $.network_metadata, $.network_scheme, $['fuel-plugin-calico'])
type: puppet
parameters:
timeout: 180
puppet_manifest: puppet/manifests/role_rr.pp
puppet_modules: puppet/modules:/etc/puppet/modules
- id: calico-etcd
role:
- calico-etcd
version: 2.1.0
requires:
- netconfig
- hosts
- firewall
- calico-repo-setup
required_for:
- deploy_end
- openstack-network-start
condition:
yaql_exp: >
changedAny($.configuration, $.debug, $.network_metadata, $.network_scheme, $['fuel-plugin-calico'])
type: puppet
parameters:
timeout: 180
puppet_manifest: puppet/manifests/role_etcd.pp
puppet_modules: puppet/modules:/etc/puppet/modules
- id: calico-etcd-proxy
role:
- primary-controller
- controller
- compute
version: 2.1.0
requires:
- netconfig
- hosts
- firewall
- calico-repo-setup
required_for:
- deploy_end
- openstack-network-start
cross-depends:
- name: primary-calico-etcd
role: ["/(primary-)?calico-etcd/"]
- name: calico-etcd
role: ["/(primary-)?calico-etcd/"]
condition:
yaql_exp: not ('calico-etcd' in $.roles)
type: puppet
parameters:
timeout: 180
puppet_manifest: puppet/manifests/etcd_proxy.pp
puppet_modules: puppet/modules:/etc/puppet/modules
- id: openstack-network-server-config
type: puppet
version: 2.1.0
groups:
- primary-controller
- controller
requires:
- calico-repo-setup
- calico-etcd-proxy
- openstack-network-start
- openstack-network-common-config
required_for:
- openstack-network-end
cross-depends:
- name: /(primary-)?calico-rr/
role: ["/(primary-)?calico-rr/"]
- name: /(primary-)?calico-etcd/
role: ["/(primary-)?calico-etcd/"]
condition:
yaql_exp: >
changedAny($.quantum, $.configuration, $.quantum_settings,
$.get('database_vip'), $.network_metadata.vips, $.nova,
$.get('neutron_primary_controller_roles'),
$.get('neutron_compute_nodes'), $.get('region', 'RegionOne'),
$.get('use_ssl'), $.neutron_advanced_configuration, $.network_scheme)
refresh_on:
- neutron_plugin_ml2
- neutron_config
- neutron_api_config
parameters:
puppet_manifest: puppet/manifests/neutron_server_config.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 1800
- id: openstack-network-networks
type: puppet
version: 2.1.0
groups:
- primary-controller
requires:
- openstack-network-start
- openstack-network-common-config
- openstack-network-server-config
required_for:
- openstack-network-end
condition:
yaql_exp: "changedAny($.access, $.quantum_settings, $.quantum)"
parameters:
puppet_manifest: puppet/manifests/neutron_networks.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 1800
- id: calico-compute-bird
role:
- compute
version: 2.1.0
requires:
- netconfig
- hosts
- firewall
- calico-repo-setup
required_for:
- deploy_end
- openstack-network-start
cross-depends:
- name: /(primary-)?calico-rr/
role: ["/(primary-)?calico-rr/"]
condition:
yaql_exp: >
changedAny($.configuration, $.debug, $.network_metadata, $.network_scheme, $['fuel-plugin-calico'])
type: puppet
parameters:
timeout: 180
puppet_manifest: puppet/manifests/compute_bird.pp
puppet_modules: puppet/modules:/etc/puppet/modules
- id: openstack-network-compute-nova
type: puppet
version: 2.1.0
groups: [compute]
requires: [openstack-network-start, calico-etcd-proxy]
required_for: [openstack-network-end]
condition:
yaql_exp: >
changedAny($.network_scheme, $.quantum, $.quantum_settings, $.nova,
$.network_metadata.vips, $.get('region'), $.get('use_ssl'), $['fuel-plugin-calico'])
parameters:
puppet_manifest: puppet/manifests/compute_neutron_nova.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 1800
- id: calico-compute-metadata-api
type: puppet
version: 2.1.0
groups: [compute]
requires: [openstack-network-end, calico-etcd-proxy, top-role-compute]
required_for: [enable_nova_compute_service]
condition:
yaql_exp: >
changedAny($.quantum, $.configuration, $.debug,
$.neutron_advanced_configuration, $['fuel-plugin-calico'])
parameters:
puppet_manifest: puppet/manifests/compute_metadata_api.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 1800
- id: calico-compute-alt-gateway
type: puppet
version: 2.1.0
groups: [compute]
requires: [openstack-network-end, calico-etcd-proxy, top-role-compute]
required_for: [enable_nova_compute_service, calico-compute-felix]
condition:
yaql_exp: >
changedAny($.quantum, $.configuration,
$.neutron_advanced_configuration, $['fuel-plugin-calico'])
parameters:
puppet_manifest: puppet/manifests/compute_alt_gateway.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 1800
- id: calico-compute-felix
type: puppet
version: 2.1.0
groups: [compute]
requires: [openstack-network-end, calico-etcd-proxy, top-role-compute]
required_for: [enable_nova_compute_service]
condition:
yaql_exp: >
changedAny($.quantum, $.configuration, $.debug,
$.neutron_advanced_configuration, $['fuel-plugin-calico'])
parameters:
puppet_manifest: puppet/manifests/compute_felix.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 1800
- id: openstack-network-agents-dhcp
type: puppet
version: 2.1.0
groups: [compute]
requires: [openstack-network-end, calico-etcd-proxy, calico-compute-felix, top-role-compute]
required_for: [enable_nova_compute_service]
condition:
yaql_exp: >
changedAny($.quantum, $.configuration, $.debug,
$.neutron_advanced_configuration, $['fuel-plugin-calico'])
refresh_on: [neutron_dhcp_agent_config]
parameters:
puppet_manifest: puppet/manifests/compute_dhcp_agent.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 1800
# Disable Neutron tasks, not required for Calice setup
- id: openstack-network-routers
groups: ["/.*/"]
version: 2.1.0
type: skipped
- id: primary-openstack-network-agents-dhcp
groups: ["/.*/"]
version: 2.1.0
type: skipped
# Task with id:openstack-network-agents-dhcp was redefined above
- id: primary-openstack-network-plugins-l2
groups: ["/.*/"]
version: 2.1.0
type: skipped
- id: openstack-network-plugins-l2
groups: ["/.*/"]
version: 2.1.0
type: skipped
- id: primary-openstack-network-agents-l3
groups: ["/.*/"]
version: 2.1.0
type: skipped
- id: openstack-network-agents-l3
groups: ["/.*/"]
version: 2.1.0
type: skipped
- id: primary-openstack-network-agents-metadata
groups: ["/.*/"]
version: 2.1.0
type: skipped
- id: openstack-network-agents-metadata
groups: ["/.*/"]
version: 2.1.0
type: skipped

View File

@ -1 +1,45 @@
attributes: {}
attributes:
metadata:
label: Calico networking
description: Deploy OpenStack with Calico L3 fabric instead of Neutron L2 isolation
weight: 28400
group: network
as_number:
value: '64512'
label: AS Number
description: AS number for BGP communication
weight: 20
type: "text"
regex:
source: '^([1-9]|[0-9]{2,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-4])$'
error: "Invalid AS number"
enable_ipv4:
type: checkbox
weight: 60
value: true
label: Enable IPv4
description: Operate with bird4 BGP daemon
enable_ipv6:
type: checkbox
weight: 62
value: false
label: Enable IPv6
description: Operate with bird6 BGP daemon
restrictions:
- condition: "settings:fuel-plugin-calico.metadata.enabled == true" # disable, because in TODO
strict: false
enable_external_peering:
type: checkbox
weight: 70
value: false
label: Allow external BGP peering
external_peers:
label: External BGP peers
description: One BGP peer per line in format 'name:as_number:ipaddr:optional_flags...'
weight: 71
type: "textarea"
value: ''
restrictions:
- condition: "settings:fuel-plugin-calico.enable_external_peering.value != true"
strict: false

View File

@ -1,15 +1,19 @@
# Plugin name
name: calico-fuel-plugin
name: fuel-plugin-calico
# Human-readable name for your plugin
title: Use Calico Virtual Networking
# Plugin version
version: 2.0.0
version: 3.0.1
# Description
description: Layer 3 Virtual Networking for Highly Scalable Data Centers
# Required fuel version
fuel_version: ['7.0']
fuel_version: ['9.0','9.1']
# Plugin authors
authors: ['Emma Gordon']
authors:
- Emma Gordon <emma@projectcalico.org>
- Alexander Didenko <adidenko@mirantis.com>
- Oleksandr Martsyniuk <omartsyniuk@mirantis.com>
- Sergey Vasilenko <svasilenko@mirantis.com>
# Plugin license
licenses: [Apache License Version 2.0]
# Plugin project homepage
@ -20,10 +24,16 @@ groups: ['network']
# The plugin is compatible with releases in the list
releases:
- os: ubuntu
version: 2015.1-7.0
mode: ['ha', 'multinode']
version: mitaka-9.0
mode: ['ha']
deployment_scripts_path: deployment_scripts/
repository_path: repositories/ubuntu
- os: ubuntu
version: mitaka-9.1
mode: ['ha']
deployment_scripts_path: deployment_scripts/
repository_path: repositories/ubuntu
# Version of plugin package
package_version: '2.0.0'
package_version: '4.0.0'
is_hotpluggable: false

20
node_roles.yaml Normal file
View File

@ -0,0 +1,20 @@
calico-rr:
name: Calico - RR
description: Calico route-reflector role
has_primary: false
limits:
min: 1
recommended: 2
public_ip_required: false
weight: 100
conflicts:
- compute
calico-etcd:
name: Calico - etcd
description: Calico etcd instance.
has_primary: false
limits:
min: 1
recommended: 3
public_ip_required: false
weight: 100

View File

@ -1,18 +0,0 @@
#!/bin/bash
# Add here any the actions which are required before plugin build
# like packages building, packages downloading from mirrors and so on.
# The script should return 0 if there were no errors.
#!/bin/bash
set -eux
ROOT="$(dirname `readlink -f $0`)"
MODULES="${ROOT}"/deployment_scripts/puppet/modules
mkdir -p "${MODULES}"
REPO_PATH='https://github.com/openstack/fuel-library/tarball/f43d885914d74fbd062096763222f350f47480e1'
RPM_REPO="${ROOT}"/repositories/centos/
DEB_REPO="${ROOT}"/repositories/ubuntu/
wget -qO- "${REPO_PATH}" | \
tar -C "${MODULES}" --strip-components=3 -zxvf - \
openstack-fuel-library-f43d885/deployment/puppet/{inifile,stdlib}

45
pre_install.sh Normal file
View File

@ -0,0 +1,45 @@
#!/bin/sh
PWD=`pwd`
FUEL_VERSION=`rpm -q --info fuel | tr -s \[:space:\] | grep 'Version :' | awk -F': ' '{print $2}'`
if [ $FUEL_VERSION == '9.0.0' ] ; then
# Implement minor patch to l23network (included into 9.1, but not present in 9.0)
# For additional information see Openstack Bug #1590735
# or Change-Id: I89ef5630ab2dfd373b8cd4b7db481278c659db75
cd /etc/puppet/modules/l23network
patch -N -p4 <<EOF
diff --git a/deployment/puppet/l23network/lib/puppetx/l23_network_scheme.rb b/deployment/puppet/l23network/lib/puppetx/l23_network_scheme.rb
index 4f80daf..a2c1049 100644
--- a/deployment/puppet/l23network/lib/puppetx/l23_network_scheme.rb
+++ b/deployment/puppet/l23network/lib/puppetx/l23_network_scheme.rb
@@ -101,7 +101,13 @@
transformations = org_tranformations.reject{|x| x[:action]=='override'}
org_tranformations.select{|x| x[:action]=='override'}.each do |ov|
next if ov[:override].nil?
- tr_index = transformations.index{|x| x[:name]==ov[:override]}
+ pm = ov[:override].match(/patch-([\w\-]+)\:([\w\-]+)/)
+ if !pm.nil? and pm.size == 3
+ # we should override patch, to search patch use bridge names
+ tr_index = transformations.index{|x| x[:action]=='add-patch' and (x[:bridges]==[pm[1],pm[2]] or x[:bridges]==[pm[2],pm[1]])}
+ else
+ tr_index = transformations.index{|x| x[:name]==ov[:override]}
+ end
next if tr_index.nil?
ov.reject{|k,v| [:override, :action].include? k}.each do |k,v|
if k == :'override-action' and v.to_s!=''
EOF
rc=$?
if [ $rc -gt 1 ] ; then
echo
echo "Can't patch l23network module. Chech whether 'patch' utility installed."
echo "rc=$rc"
echo
echo "Use 'yum install -y patch' if not found"
echo
exit $rc
fi
fi
cd $PWD

View File

@ -1,4 +1,4 @@
Copyright 2015 Metaswitch Networks
Copyright 2016 Mirantis
Fuel Plugin for Project Calico
==============================
@ -6,7 +6,7 @@ Fuel Plugin for Project Calico
The Calico plugin provides the ability to use Calico as a networking backend
for Mirantis OpenStack.
Compatible with Fuel version 7.0.
Compatible with Fuel version 9.0.
Problem description
===================
@ -22,8 +22,9 @@ and destination workloads.
Proposed change
===============
Update the Calico plugin for Fuel version 6.1 to support version 7.0. This will
involve moving from the Juno to the Kilo release of Mirantis OpenStack.
Re-design the Calico plugin for Fuel version 6.1 to support version 9.0.
This will involve moving from the Juno to the Mitaka release of
Mirantis OpenStack.
Support for HA deployments with multiple controllers will also be added.
@ -45,7 +46,7 @@ None.
Upgrade impact
--------------
When upgrading the Fuel Master node to Fuel Version higher than 7.0, plugin
When upgrading the Fuel Master node to Fuel Version higher than 9.0, plugin
compatibility should be checked, and a new plugin installed if necessary.
Security impact
@ -62,7 +63,7 @@ Other end user impact
---------------------
Once the plugin is installed, the user can enable Calico networking on the
Settings tab of the Fuel Web UI, and customize the network settings.
Wizard while create Openstack Env, and customize the network settings.
Performance Impact
------------------
@ -96,15 +97,16 @@ Assignee(s)
-----------
Primary assignee:
Emma Gordon <emma@projectcalico.org> (developer)
Sergey Vasilenko <svasilenko@mirantis.com>
Other contributors:
Neil Jerram <neil@projectcalico.org> (developer, reviewer)
Alexander Didenko <adidenko@mirantis.com>
Oleksandr Martsyniuk <omartsyniuk@mirantis.com>
Work Items
----------
* Integrate Calico with Fuel 7.0.
* Integrate Calico with Fuel 9.0.
* Update the Calico plugin.
@ -115,7 +117,7 @@ Work Items
Dependencies
============
* Fuel 7.0.
* Fuel 9.0.
Testing
=======
@ -142,7 +144,4 @@ References
* Calico Documentation - http://docs.projectcalico.org/en/latest/index.html
* Subscribe to the Calico Technical Mailing List -
http://lists.projectcalico.org/listinfo/calico-tech
* Calico IRC - freenode IRC: #calico

View File

@ -1,33 +0,0 @@
# Copyright 2015 Metaswitch Networks
# Install/configure calico on the controller after cluster deployment
# but before starting the BGP Route Reflector.
- role: ['controller', 'primary-controller']
stage: post_deployment/50
type: shell
parameters:
cmd: ./calico_controller.sh
timeout: 600
- role: ['controller', 'primary-controller']
stage: post_deployment/100
type: shell
parameters:
cmd: ./calico_route_reflector.sh
timeout: 60
# Remove default OpenStack network configuration which doesn't work with Calico.
#- role: ['primary-controller']
# stage: post_deployment/150
# type: shell
# parameters:
# cmd: ./remove_default_networks.sh
# timeout: 60
# Install/configure calico on the compute nodes after cluster deployment.
- role: ['compute']
stage: post_deployment
type: shell
parameters:
cmd: ./calico_compute.sh
timeout: 600