# lib/nfp # functions - functions specific to nfp implementation # Dependencies: # ``functions`` file # ``DEST`` must be defined # ``stack.sh`` calls the entry points in this order: # # - prepare_nfp_image_builder # - install_nfpgbpservice # - init_nfpgbpservice # - assign_user_role_credential # - create_nfp_gbp_resources # - create_nfp_image # - launch_configuratorVM # - copy_nfp_files_and_start_process # # ``unstack.sh`` calls the entry points in this order: # Set up default directories DEVSTACK_DIR=$PWD NFPSERVICE_DIR=$DEST/gbp NEUTRON_CONF_DIR=/etc/neutron NEUTRON_CONF=$NEUTRON_CONF_DIR/neutron.conf NFP_CONF_DIR=/etc/nfp DISKIMAGE_CREATE_DIR=$NFPSERVICE_DIR/gbpservice/contrib/nfp/tools/image_builder NEUTRON_SRC_BRANCH_FOR_NFP_CONTROLLER=stable/mitaka # Save trace setting XTRACE=$(set +o | grep xtrace) set +o xtrace # Functions # --------- # prepare_nfp_image_builder() - Install the requirements for dib function prepare_nfp_image_builder { sudo -H -E pip install -r $DISKIMAGE_CREATE_DIR/requirements.txt sudo apt-get install -y --force-yes qemu-utils sudo apt-get install -y --force-yes dpkg-dev if [[ $NFP_DEVSTACK_MODE = advanced ]]; then sudo wget -qO- https://get.docker.com/ | bash fi } # install_nfpgbpservice() - Collect source and prepare function install_nfpgbpservice { git_clone $GBPSERVICE_REPO $NFPSERVICE_DIR $GBPSERVICE_BRANCH mv $NFPSERVICE_DIR/test-requirements.txt $NFPSERVICE_DIR/_test-requirements.txt setup_develop $NFPSERVICE_DIR mv -f $NEUTRON_CONF_DIR/policy.json $NEUTRON_CONF_DIR/policy.json.original 2>/dev/null; true cp -f $NFPSERVICE_DIR/etc/policy.json $NEUTRON_CONF_DIR/policy.json mv $NFPSERVICE_DIR/_test-requirements.txt $NFPSERVICE_DIR/test-requirements.txt } # init_nfpgbpservice() - Initialize databases, etc. function init_nfpgbpservice { # Run GBP db migrations gbp-db-manage --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE upgrade head iniset $NEUTRON_CONF DEFAULT policy_dirs $NFP_CONF_DIR } # assign_user_role_credential() - Assign Service role to the users function assign_user_role_credential { source $DEVSTACK_DIR/openrc admin admin serviceTenantID=`keystone tenant-list | grep "service" | awk '{print $2}'` serviceRoleID=`keystone role-list | grep "service" | awk '{print $2}'` adminRoleID=`keystone role-list | grep "admin" | awk '{print $2}'` keystone user-role-add\ --user nova\ --tenant $serviceTenantID\ --role $serviceRoleID keystone user-role-add\ --user neutron\ --tenant $serviceTenantID\ --role $adminRoleID } # create_ext_net() - Create an external network function create_ext_net { source $DEVSTACK_DIR/stackrc EXT_NET_NAME=ext-net EXT_NET_SUBNET_NAME=ext-net-subnet EXT_NET_GATEWAY=$EXT_NET_GATEWAY EXT_NET_ALLOCATION_POOL_START=$EXT_NET_ALLOCATION_POOL_START EXT_NET_ALLOCATION_POOL_END=$EXT_NET_ALLOCATION_POOL_END EXT_NET_CIDR=$EXT_NET_CIDR neutron net-create\ --router:external=true\ --shared\ $EXT_NET_NAME neutron subnet-create\ --ip_version 4\ --gateway $EXT_NET_GATEWAY\ --name $EXT_NET_SUBNET_NAME\ --allocation-pool start=$EXT_NET_ALLOCATION_POOL_START,end=$EXT_NET_ALLOCATION_POOL_END\ $EXT_NET_NAME\ $EXT_NET_CIDR } # create_ep_and_nsp() - Create GBP resources for the external netwrok function create_ep_and_nsp { subnet_id=`neutron net-list | grep "$EXT_NET_NAME" | awk '{print $6}'` gbp external-segment-create\ --ip-version 4\ --cidr $EXT_NET_CIDR\ --external-route destination=0.0.0.0/0,nexthop=\ --shared True\ --subnet_id=$subnet_id\ default gbp nat-pool-create\ --ip-version 4\ --ip-pool $EXT_NET_CIDR\ --external-segment default\ --shared True\ default gbp nsp-create\ --network-service-params type=ip_pool,name=vip_ip,value=nat_pool\ svc_mgmt_fip_policy } # create_nfp_gbp_resources() - Create various GBP resources function create_nfp_gbp_resources { source $DEVSTACK_DIR/openrc neutron service unset OS_USER_DOMAIN_ID unset OS_PROJECT_DOMAIN_ID if [[ $NFP_DEVSTACK_MODE = base ]]; then IMAGE_NAME="reference_configurator_image" FLAVOR=m1.nfp-tiny gbp service-profile-create\ --servicetype LOADBALANCER\ --insertion-mode l3\ --shared True\ --service-flavor service_vendor=haproxy,device_type=None\ --vendor NFP\ base_mode_lb gbp service-profile-create\ --servicetype FIREWALL\ --insertion-mode l3\ --shared True\ --service-flavor service_vendor=nfp,device_type=nova,image_name=$IMAGE_NAME,flavor=$FLAVOR\ --vendor NFP\ base_mode_fw_vm else gbp service-profile-create\ --servicetype LOADBALANCER\ --insertion-mode l3\ --shared True\ --service-flavor service_vendor=haproxy,device_type=nova\ --vendor NFP\ lb_profile gbp service-profile-create\ --servicetype LOADBALANCERV2\ --insertion-mode l3\ --shared True\ --service-flavor service_vendor=haproxy_lbaasv2,device_type=nova,flavor=m1.small\ --vendor NFP\ lbv2_profile gbp service-profile-create\ --servicetype FIREWALL\ --insertion-mode l3\ --shared True\ --service-flavor service_vendor=vyos,device_type=nova\ --vendor NFP\ vyos_fw_profile gbp service-profile-create\ --servicetype VPN\ --insertion-mode l3\ --shared True\ --service-flavor service_vendor=vyos,device_type=nova\ --vendor NFP\ vpn_profile create_ext_net create_ep_and_nsp fi gbp l3policy-create\ --ip-version 4\ --ip-pool 172.16.0.0/16\ --subnet-prefix-length 20\ --proxy-ip-pool=172.17.0.0/16\ service_management gbp l2policy-create\ --l3-policy service_management\ svc_management_ptg gbp group-create\ svc_management_ptg\ --service_management True\ --l2-policy\ svc_management_ptg neutron router-gateway-clear\ l3p_service_management gbp l3policy-update\ --external-segment ""\ service_management } # create_port_for_vm() - Create a port, and get its details # Args: # $1 - image_name # $2 - instance name function create_port_for_vm { GROUP="svc_management_ptg" PortId=$(gbp policy-target-create --policy-target-group $GROUP $2 | grep port_id | awk '{print $4}') IpAddr_extractor=`neutron port-list --format value | grep $PortId | awk '{print $7}'` IpAddr_purge_last=${IpAddr_extractor::-1} IpAddr=${IpAddr_purge_last//\"/} echo "IpAddr of port($PortId): $IpAddr" configurator_image_name=$1 configurator_port_id=$PortId configurator_ip=$IpAddr } # create_nfp_image() - Create and upload the service images function create_nfp_image { source $DEVSTACK_DIR/openrc neutron service unset OS_USER_DOMAIN_ID unset OS_PROJECT_DOMAIN_ID if [[ $NFP_DEVSTACK_MODE = base ]]; then RefConfiguratorQcow2ImageName=reference_configurator_image echo "Building Image: $RefConfiguratorQcow2ImageName" sudo python -c\ 'from gbpservice.contrib.nfp.tools.image_builder import disk_image_create as DIB;\ DIB.cur_dir = "'$DISKIMAGE_CREATE_DIR'";\ DIB.conf["ubuntu_release"] = {"release": "wily"};\ DIB.conf["dib"] = {"image_size": 3, "elements": ["nfp-reference-configurator", "dhcp-all-interfaces", "devuser"], "offline": True, "cache_dir": "'$HOME'/.cache/image-create"};\ DIB.dib()' RefConfiguratorQcow2Image=$(cat $DISKIMAGE_CREATE_DIR/output/last_built_image_path) echo "Uploading Image: $RefConfiguratorQcow2ImageName" glance image-create --name $RefConfiguratorQcow2ImageName --disk-format qcow2 --container-format bare --visibility public --file $RefConfiguratorQcow2Image openstack --os-cloud=devstack-admin flavor create --ram 512 --disk 3 --vcpus 1 m1.nfp-tiny else ConfiguratorQcow2ImageName=configurator ConfiguratorInstanceName="configuratorVM_instance" create_port_for_vm $ConfiguratorQcow2ImageName $ConfiguratorInstanceName if [[ $ConfiguratorQcow2Image = build ]]; then echo "Building Image: $ConfiguratorQcow2ImageName" # Prepare source for configurator git_clone $GBPSERVICE_REPO $DEVSTACK_DIR/group-based-policy $GBPSERVICE_BRANCH cp -r $DEVSTACK_DIR/group-based-policy/gbpservice $DISKIMAGE_CREATE_DIR/gbpservice rm -rf $DEVSTACK_DIR/group-based-policy git clone -b $NEUTRON_SRC_BRANCH_FOR_NFP_CONTROLLER https://github.com/openstack/neutron.git cp -r neutron/neutron $DISKIMAGE_CREATE_DIR/neutron rm -rf neutron git clone -b $NEUTRON_SRC_BRANCH_FOR_NFP_CONTROLLER https://github.com/openstack/neutron-lbaas.git cp -r neutron-lbaas/neutron_lbaas $DISKIMAGE_CREATE_DIR/neutron_lbaas rm -rf neutron-lbaas sudo python -c\ 'from gbpservice.contrib.nfp.tools.image_builder import disk_image_create as DIB;\ DIB.cur_dir = "'$DISKIMAGE_CREATE_DIR'";\ DIB.conf["ubuntu_release"] = {"release": "trusty"};\ DIB.conf["dib"] = {"image_size": 10, "elements": ["configurator"], "offline": True, "cache_dir": "'$HOME'/.cache/image-create"};\ DIB.dib()' rm -rf $DISKIMAGE_CREATE_DIR/gbpservice $DISKIMAGE_CREATE_DIR/neutron $DISKIMAGE_CREATE_DIR/neutron_lbaas ConfiguratorQcow2Image=$(cat $DISKIMAGE_CREATE_DIR/output/last_built_image_path) fi echo "Uploading Image: $ConfiguratorQcow2ImageName" glance image-create --name $ConfiguratorQcow2ImageName --disk-format qcow2 --container-format bare --visibility public --file $ConfiguratorQcow2Image VyosQcow2ImageName=vyos if ! [[ -z $VyosQcow2Image ]]; then echo "Uploading Image: $VyosQcow2ImageName" glance image-create --name $VyosQcow2ImageName --disk-format qcow2 --container-format bare --visibility public --file $VyosQcow2Image fi HaproxyQcow2ImageName=haproxy if ! [[ -z $HaproxyQcow2Image ]]; then echo "Uploading Image: $HaproxyQcow2ImageName" glance image-create --name $HaproxyQcow2ImageName --disk-format qcow2 --container-format bare --visibility public --file $HaproxyQcow2Image fi fi } # launch_configuratorVM() - Launch the Configurator VM function launch_configuratorVM { echo "Collecting ImageId : for $configurator_image_name" ImageId=`glance image-list | grep $configurator_image_name | awk '{print $2}'` if [ ! -z "$ImageId" -a "$ImageId" != " " ]; then echo $ImageId else echo "No image found with name $configurator_image_name" exit fi nova keypair-add configurator_key > $HOME/configurator_key.pem chmod 600 $HOME/configurator_key.pem nova boot\ --flavor m1.medium\ --key-name configurator_key\ --user-data $DISKIMAGE_CREATE_DIR/configurator_user_data\ --image $ImageId\ --nic port-id=$configurator_port_id\ $ConfiguratorInstanceName sleep 10 } # namespace_delete() - Utility for namespace management function namespace_delete { source $DEVSTACK_DIR/openrc neutron service #Deletion namespace NFP_P=`sudo ip netns | grep "nfp-proxy"` if [ ${#NFP_P} -ne 0 ]; then sudo ip netns delete nfp-proxy echo "namespace removed" fi #Delete veth peer PEER=`ip a | grep pt1` if [ ${#PEER} -ne 0 ]; then echo "veth peer removed" sudo ip link delete pt1 fi #pt1 port removing from ovs PORT=`sudo ovs-vsctl show | grep "pt1"` if [ ${#PORT} -ne 0 ]; then sudo ovs-vsctl del-port br-int pt1 echo "ovs port ptr1 is removed" fi echo "nfp-proxy cleaning success." } # namespace_create() - Utility for namespace management function namespace_create { SERVICE_MGMT_NET="l2p_svc_management_ptg" echo "Creating new namespace nfp-proxy...." #new namespace with name proxy NFP_P=`sudo ip netns add nfp-proxy` if [ ${#NFP_P} -eq 0 ]; then echo "New namepace nfp-proxy created" else echo "New namespace nfp-proxy creation failed" exit 0 fi #Create veth peer PEER=`sudo ip link add pt0 type veth peer name pt1` if [ ${#PEER} -eq 0 ]; then echo "New veth pair created" else echo "veth pair creation failed" exit 0 fi sleep 1 #move one side of veth into namesape sudo ip link set pt0 netns nfp-proxy #create new neutron port in service mgmt network new_ip=`neutron port-create $SERVICE_MGMT_NET | grep "fixed_ips" | awk '{print $7}' | sed 's/^\"\(.*\)\"}$/\1/'` if [ ${#new_ip} -lt 5 ]; then echo "new_ip =$new_ip" echo "Neutron port creation failed (check source) " exit 0 else echo "New Neutron Port Created on Service management network with ip =$new_ip" fi new_ip_cidr+="$new_ip/24" sleep 2 #get the ip address of new port eg : 11.0.0.6 and asign to namespace sudo ip netns exec nfp-proxy ip addr add $new_ip_cidr dev pt0 #move other side of veth into ovs : br-int sudo ovs-vsctl add-port br-int pt1 #get id of service management network smn_id=`neutron net-list | grep "$SERVICE_MGMT_NET" | awk '{print $2}'` #get the dhcp namespace of service management network nm_space=`sudo ip netns | grep "$smn_id"` #get port id from router nampace port=`sudo ip netns exec $nm_space ip a | grep "tap" | tail -n 1 | awk '{print $7}'` #get tag_id form port in ovs-bridge tag_id=`sudo ovs-vsctl list port $port | grep "tag" | tail -n 1 | awk '{print $3}'` sudo ovs-vsctl set port pt1 tag=$tag_id #up the both ports sudo ip netns exec nfp-proxy ip link set pt0 up sudo ip netns exec nfp-proxy ip link set lo up sudo ip link set pt1 up PING=`sudo ip netns exec nfp-proxy ping $configurator_ip -q -c 2 > /dev/null` if [ ${#PING} -eq 0 ]; then echo "nfp-proxy namespcace creation success and reaching to $configurator_ip" else echo "Fails reaching to $configurator_ip" fi sudo ip netns exec nfp-proxy /usr/bin/nfp_proxy --config-file=/etc/nfp_proxy.ini } # copy_nfp_files_and_start_process() - Setup configuration and start processes function copy_nfp_files_and_start_process { cd $NFPSERVICE_DIR/gbpservice/nfp sudo cp -r bin/nfp /usr/bin/ sudo chmod +x /usr/bin/nfp sudo rm -rf /etc/nfp_* sudo cp -r bin/nfp_orchestrator.ini /etc/ sudo cp -r bin/nfp_proxy_agent.ini /etc/ [[ $NFP_DEVSTACK_MODE = advanced ]] && sudo cp -r ../contrib/nfp/bin/nfp_config_orch.ini /etc/ sudo cp -r bin/nfp_proxy.ini /etc/nfp_proxy.ini sudo cp -r bin/nfp_proxy /usr/bin/ if [[ $NFP_DEVSTACK_MODE = base ]]; then configurator_ip=127.0.0.1 configurator_port=8080 else configurator_ip=$configurator_ip configurator_port=8070 fi echo "Configuring proxy.ini .... with rest_server_address as $configurator_ip:$configurator_port" sudo sed -i "s/rest_server_address=*.*/rest_server_address=$configurator_ip/g" /etc/nfp_proxy.ini sudo sed -i "s/rest_server_port= *.*/rest_server_port=$configurator_port/g" /etc/nfp_proxy.ini sed -i 's#source.*#source '$DEVSTACK_DIR'/openrc demo demo#g' $NFPSERVICE_DIR/devstack/exercises/nfp_service/*.sh source $DEVSTACK_DIR/functions-common echo "Starting nfp_orchestrator under screen named nfp_orchestrator" run_process nfp_orchestrator "sudo /usr/bin/nfp --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini --config-file /etc/nfp_orchestrator.ini --log-file $DEST/logs/nfp_orchestrator.log" sleep 4 echo "Starting nfp_proxy_agent under screen named nfp_proxy_agent" run_process nfp_proxy_agent "sudo /usr/bin/nfp --config-file /etc/nfp_proxy_agent.ini --log-file $DEST/logs/nfp_proxy_agent.log" sleep 4 echo "Starting nfp_proxy inside namespace named nfp-proxy, under screen named nfp_proxy" run_process nfp_proxy "source $NFPSERVICE_DIR/devstack/lib/nfp; namespace_delete; namespace_create" sleep 10 if [[ $NFP_DEVSTACK_MODE = advanced ]]; then echo "Starting nfp_config_orchestrator under screen named nfp_config_orchestrator" run_process nfp_config_orchestrator "sudo /usr/bin/nfp --config-file /etc/nfp_config_orch.ini --config-file /etc/neutron/neutron.conf --log-file $DEST/logs/nfp_config_orchestrator.log" else cd pecan/api sudo python setup.py develop echo "Starting nfp_base_configurator under screen named nfp_base_configurator" run_process nfp_base_configurator "cd $NFPSERVICE_DIR/gbpservice/nfp/pecan/api; sudo ip netns exec nfp-proxy pecan configurator_decider config.py --mode base" fi sleep 1 echo "Upgrading DB to HEAD" source $DEVSTACK_DIR/openrc neutron service gbp-db-manage --config-file /etc/neutron/neutron.conf upgrade head sleep 2 echo "NFP configuration done." }