From f6242655581c676e97e91b059b43bbff693790a7 Mon Sep 17 00:00:00 2001 From: Shachar Snapiri Date: Thu, 19 Jul 2018 10:50:00 +0300 Subject: [PATCH] Move metadata_service deployment out of DF code The deployment should be done via deployment scripts and not in the code (nor in plugin.sh directly, as to allow production deployment). Moved the deployment to a script located in the tools directory, which is now called from the plugin.sh, and may be called from any production deployment mechanism. Partial-Bug: #1781376 Change-Id: I90a7e8a87764354ab9e2a8ab149f00f2eaea94f5 --- devstack/plugin.sh | 9 +++- .../cmd/eventlet/df_metadata_service.py | 50 ------------------- .../tests/fullstack/test_metadata_service.py | 43 +--------------- tools/ovs_metadata_service_deployment.sh | 40 +++++++++++++++ 4 files changed, 49 insertions(+), 93 deletions(-) create mode 100755 tools/ovs_metadata_service_deployment.sh diff --git a/devstack/plugin.sh b/devstack/plugin.sh index c18a56465..badd2cb85 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -184,6 +184,10 @@ function configure_df_metadata_service { iniset $DRAGONFLOW_CONF df_metadata ip "$DF_METADATA_SERVICE_IP" iniset $DRAGONFLOW_CONF df_metadata port "$DF_METADATA_SERVICE_PORT" iniset $DRAGONFLOW_CONF df_metadata metadata_interface "$DF_METADATA_SERVICE_INTERFACE" + pushd $DRAGONFLOW_DIR + # TODO(snapiri) When we add more switch backends, this should be conditional + tools/ovs_metadata_service_deployment.sh install $INTEGRATION_BRIDGE $DF_METADATA_SERVICE_INTERFACE $DF_METADATA_SERVICE_IP + popd fi } @@ -503,7 +507,10 @@ function stop_df_metadata_agent { if is_service_enabled df-metadata ; then echo "Stopping Dragonflow metadata service" stop_process df-metadata - sudo ovs-vsctl del-port br-int $DF_METADATA_SERVICE_INTERFACE + pushd $DRAGONFLOW_DIR + # TODO(snapiri) When we add more switch backends, this should be conditional + tools/ovs_metadata_service_deployment.sh remove $INTEGRATION_BRIDGE $DF_METADATA_SERVICE_INTERFACE + popd fi } diff --git a/dragonflow/cmd/eventlet/df_metadata_service.py b/dragonflow/cmd/eventlet/df_metadata_service.py index 575079b61..5358d4eb6 100644 --- a/dragonflow/cmd/eventlet/df_metadata_service.py +++ b/dragonflow/cmd/eventlet/df_metadata_service.py @@ -12,8 +12,6 @@ from oslo_log import log -from neutron.agent.common import utils -from neutron.agent.linux import ip_lib from neutron.common import config from neutron.conf.agent.metadata import config as metadata_conf from neutron import wsgi @@ -28,59 +26,12 @@ import sys LOG = log.getLogger(__name__) -METADATA_ROUTE_TABLE_ID = '2' - - -def environment_setup(): - bridge = cfg.CONF.df.integration_bridge - interface = cfg.CONF.df_metadata.metadata_interface - port = cfg.CONF.df_metadata.port - if ip_lib.device_exists(interface): - LOG.info("Device %s already exists", interface) - # Destroy the environment when the device exists. - # We can re-initialize the environment correctly. - environment_destroy() - - cmd = ["ovs-vsctl", "add-port", bridge, interface, - "--", "set", "Interface", interface, "type=internal"] - utils.execute(cmd, run_as_root=True) - - ip = cfg.CONF.df_metadata.ip - cmd = ["ip", "addr", "add", "dev", interface, "{}/0".format(ip)] - utils.execute(cmd, run_as_root=True) - - cmd = ["ip", "link", "set", "dev", interface, "up"] - utils.execute(cmd, run_as_root=True) - - cmd = ["ip", "route", "add", "0.0.0.0/0", "dev", interface, - "table", METADATA_ROUTE_TABLE_ID] - utils.execute(cmd, run_as_root=True) - - cmd = ["ip", "rule", "add", "from", ip, "table", METADATA_ROUTE_TABLE_ID] - utils.execute(cmd, run_as_root=True) - - cmd = ["iptables", '-I', 'INPUT', '-i', interface, '-p', 'tcp', '--dport', - str(port), '-j', 'ACCEPT'] - utils.execute(cmd, run_as_root=True) - - -def environment_destroy(): - bridge = cfg.CONF.df.integration_bridge - interface = cfg.CONF.df_metadata.metadata_interface - cmd = ["ovs-vsctl", "del-port", bridge, interface] - utils.execute(cmd, run_as_root=True, check_exit_code=[0]) - - ip = cfg.CONF.df_metadata.ip - cmd = ["ip", "rule", "del", "from", ip, "table", METADATA_ROUTE_TABLE_ID] - utils.execute(cmd, run_as_root=True) - def main(): metadata_conf.register_meta_conf_opts( metadata_conf.METADATA_PROXY_HANDLER_OPTS) config.init(sys.argv[1:]) config.setup_logging() - environment_setup() nb_api = api_nb.NbApi.get_instance() service_instance = metadata_service.DFMetadataProxyHandler( cfg.CONF, nb_api) @@ -92,4 +43,3 @@ def main(): port=cfg.CONF.df_metadata.port, ) service.wait() - environment_destroy() diff --git a/dragonflow/tests/fullstack/test_metadata_service.py b/dragonflow/tests/fullstack/test_metadata_service.py index dc6b5c78a..332d87291 100644 --- a/dragonflow/tests/fullstack/test_metadata_service.py +++ b/dragonflow/tests/fullstack/test_metadata_service.py @@ -10,12 +10,8 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron.agent.common import utils -from neutron.agent.linux import ip_lib -from oslo_config import cfg from oslo_log import log -from dragonflow.cmd.eventlet import df_metadata_service from dragonflow.conf import df_metadata_service as df_metadata_service_conf from dragonflow.tests.fullstack import test_base @@ -28,42 +24,5 @@ class TestMetadataService(test_base.DFTestBase): def setUp(self): super(TestMetadataService, self).setUp() df_metadata_service_conf.register_opts() - # Override defaults to avoid collision with existing metadata service - cfg.CONF.df_metadata.ip = '1.1.1.1' - cfg.CONF.df_metadata.metadata_interface = 'tap-md-test' - df_metadata_service.METADATA_ROUTE_TABLE_ID = '3' - self.metadata_ip = cfg.CONF.df_metadata.ip - self.isTornDown = False - def test_metadata_proxy_exit_clear_ip_rule(self): - df_metadata_service.environment_setup() - ip_rule = ip_lib.IPRule().rule - rules = ip_rule.list_rules(4) - rules_source = [r['from'] for r in rules if 'from' in r] - self.assertIn(self.metadata_ip, rules_source) - - df_metadata_service.environment_destroy() - self.isTornDown = True - rules = ip_rule.list_rules(4) - rules_source = [r['from'] for r in rules if 'from' in r] - self.assertNotIn(self.metadata_ip, rules_source) - - def tearDown(self): - if not self.isTornDown: - bridge = cfg.CONF.df.integration_bridge - interface = cfg.CONF.df_metadata.metadata_interface - cmd = ["ovs-vsctl", "del-port", bridge, interface] - try: - utils.execute(cmd, run_as_root=True, check_exit_code=[0]) - except Exception: - LOG.exception("Failed to delete metadata test port") - - ip = cfg.CONF.df_metadata.ip - cmd = ["ip", "rule", "del", "from", ip, "table", - df_metadata_service.METADATA_ROUTE_TABLE_ID] - try: - utils.execute(cmd, run_as_root=True) - except Exception: - LOG.exception( - "Failed to delete metadata test routing rule") - super(TestMetadataService, self).tearDown() + # TODO(snapiri) Add some tests for the actual metadata service logic diff --git a/tools/ovs_metadata_service_deployment.sh b/tools/ovs_metadata_service_deployment.sh new file mode 100755 index 000000000..2365d99a5 --- /dev/null +++ b/tools/ovs_metadata_service_deployment.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +ACTION=$1; shift +INTEGRATION_BRIDGE=${1:-"br-int"}; shift +DF_METADATA_SERVICE_INTERFACE=${1:-"tap-metadata"}; shift + +function usage { + cat>&2< [] [] [] + action - install / remove + integration-bridge - name of the integration bridge (br-int) + interface - name of the interface to add to the bridge (tap-metadata) + IP - address to assign to the interface (169.254.169.254) +EOF +} + +if [ -z "$ACTION" ]; then + usage + exit 1 +fi + +case $ACTION in + install) + DF_METADATA_SERVICE_IP=${1:-"169.254.169.254"}; shift + + sudo ovs-vsctl add-port $INTEGRATION_BRIDGE $DF_METADATA_SERVICE_INTERFACE -- set Interface $DF_METADATA_SERVICE_INTERFACE type=internal + sudo ip addr add dev $DF_METADATA_SERVICE_INTERFACE $DF_METADATA_SERVICE_IP/0 + sudo ip link set dev $DF_METADATA_SERVICE_INTERFACE up + sudo ip route add 0.0.0.0/0 dev $DF_METADATA_SERVICE_INTERFACE table 2 + sudo ip rule add from $DF_METADATA_SERVICE_IP table 2 + ;; + remove) + sudo ovs-vsctl del-port $INTEGRATION_BRIDGE $DF_METADATA_SERVICE_INTERFACE + ;; + *) + usage + exit 1 + ;; +esac +