Deprecate XenAPI support
The configuration options are now marked as deprecated for removal in X release. Any related code is deleted. Neutron does not support XenAPI, same as Nova [1][2]. [1]https://review.opendev.org/#/c/749304/ [2]https://review.opendev.org/#/c/749309/ Change-Id: Ifdb2200a5dac3508fdf8907bdd1f4547dff35341 Story: #2007686 Task: #41269
This commit is contained in:
parent
8d6c301301
commit
a6dbf97242
@ -3,5 +3,4 @@ output_file = etc/neutron/plugins/ml2/openvswitch_agent.ini.sample
|
||||
wrap_width = 79
|
||||
|
||||
namespace = neutron.ml2.ovs.agent
|
||||
namespace = neutron.ml2.xenapi
|
||||
namespace = oslo.log
|
||||
|
@ -58,7 +58,6 @@ os-client-config==1.28.0
|
||||
os-ken==0.3.0
|
||||
os-service-types==1.7.0
|
||||
os-vif==1.15.1
|
||||
os-xenapi==0.3.4
|
||||
osc-lib==1.8.0
|
||||
oslo.cache==1.26.0
|
||||
oslo.concurrency==3.26.0
|
||||
|
@ -36,7 +36,6 @@ from oslo_utils import fileutils
|
||||
import psutil
|
||||
|
||||
from neutron._i18n import _
|
||||
from neutron.agent.linux import xenapi_root_helper
|
||||
from neutron.common import utils
|
||||
from neutron.conf.agent import common as config
|
||||
from neutron import wsgi
|
||||
@ -57,12 +56,8 @@ class RootwrapDaemonHelper(object):
|
||||
def get_client(cls):
|
||||
with cls.__lock:
|
||||
if cls.__client is None:
|
||||
if (xenapi_root_helper.ROOT_HELPER_DAEMON_TOKEN ==
|
||||
cfg.CONF.AGENT.root_helper_daemon):
|
||||
cls.__client = xenapi_root_helper.XenAPIClient()
|
||||
else:
|
||||
cls.__client = client.Client(
|
||||
shlex.split(cfg.CONF.AGENT.root_helper_daemon))
|
||||
cls.__client = client.Client(
|
||||
shlex.split(cfg.CONF.AGENT.root_helper_daemon))
|
||||
return cls.__client
|
||||
|
||||
|
||||
|
@ -1,92 +0,0 @@
|
||||
# Copyright (c) 2016 Citrix System.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""xenapi root helper
|
||||
|
||||
For xenapi, we may need to run some commands in dom0 with additional privilege.
|
||||
This xenapi root helper contains the class of XenAPIClient to support it:
|
||||
XenAPIClient will keep a XenAPI session to dom0 and allow to run commands
|
||||
in dom0 via calling XenAPI plugin. The XenAPI plugin is responsible to
|
||||
determine whether a command is safe to execute.
|
||||
"""
|
||||
|
||||
from os_xenapi.client import session
|
||||
from os_xenapi.client import XenAPI
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_rootwrap import cmd as oslo_rootwrap_cmd
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from neutron.conf.agent import xenapi_conf
|
||||
|
||||
|
||||
ROOT_HELPER_DAEMON_TOKEN = 'xenapi_root_helper' # nosec
|
||||
|
||||
RC_UNKNOWN_XENAPI_ERROR = 80
|
||||
MSG_UNAUTHORIZED = "Unauthorized command"
|
||||
MSG_NOT_FOUND = "Executable not found"
|
||||
XENAPI_PLUGIN_FAILURE_ID = "XENAPI_PLUGIN_FAILURE"
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
xenapi_conf.register_xenapi_opts(cfg.CONF)
|
||||
|
||||
|
||||
class XenAPIClient(object):
|
||||
def __init__(self):
|
||||
self._session = self._create_session(
|
||||
cfg.CONF.xenapi.connection_url,
|
||||
cfg.CONF.xenapi.connection_username,
|
||||
cfg.CONF.xenapi.connection_password)
|
||||
|
||||
def _call_plugin(self, plugin, fn, args):
|
||||
return self._session.call_plugin(plugin, fn, args)
|
||||
|
||||
def _create_session(self, url, username, password):
|
||||
return session.XenAPISession(url, username, password,
|
||||
originator="neutron")
|
||||
|
||||
def _get_return_code(self, failure_details):
|
||||
# The details will be as:
|
||||
# [XENAPI_PLUGIN_FAILURE_ID, methodname, except_class_name, message]
|
||||
# We can distinguish the error type by checking the message string.
|
||||
if (len(failure_details) == 4 and
|
||||
XENAPI_PLUGIN_FAILURE_ID == failure_details[0]):
|
||||
if (MSG_UNAUTHORIZED == failure_details[3]):
|
||||
return oslo_rootwrap_cmd.RC_UNAUTHORIZED
|
||||
elif (MSG_NOT_FOUND == failure_details[3]):
|
||||
return oslo_rootwrap_cmd.RC_NOEXECFOUND
|
||||
# otherwise we get unexpected exception.
|
||||
return RC_UNKNOWN_XENAPI_ERROR
|
||||
|
||||
def execute(self, cmd, stdin=None):
|
||||
out = ""
|
||||
err = ""
|
||||
if cmd is None or len(cmd) == 0:
|
||||
err = "No command specified."
|
||||
return oslo_rootwrap_cmd.RC_NOCOMMAND, out, err
|
||||
try:
|
||||
result_raw = self._call_plugin(
|
||||
'netwrap.py', 'run_command',
|
||||
{'cmd': jsonutils.dumps(cmd),
|
||||
'cmd_input': jsonutils.dumps(stdin)})
|
||||
result = jsonutils.loads(result_raw)
|
||||
returncode = result['returncode']
|
||||
out = result['out']
|
||||
err = result['err']
|
||||
return returncode, out, err
|
||||
except XenAPI.Failure as failure:
|
||||
LOG.exception('Failed to execute command: %s', cmd)
|
||||
returncode = self._get_return_code(failure.details)
|
||||
return returncode, out, err
|
@ -105,10 +105,6 @@ in "daemon mode" which has been reported to improve performance at scale. For
|
||||
more information on running rootwrap in "daemon mode", see:
|
||||
|
||||
https://docs.openstack.org/oslo.rootwrap/latest/user/usage.html#daemon-mode
|
||||
|
||||
For the agent which needs to execute commands in Dom0 in the hypervisor of
|
||||
XenServer, this option should be set to 'xenapi_root_helper', so that it will
|
||||
keep a XenAPI session to pass commands to Dom0.
|
||||
""")),
|
||||
]
|
||||
|
||||
|
@ -17,20 +17,26 @@ from oslo_config import cfg
|
||||
|
||||
from neutron._i18n import _
|
||||
|
||||
XENAPI_CONF_SECTION = 'xenapi'
|
||||
|
||||
XENAPI_DEPRECATION_REASON = ('XenAPI support has been removed from Nova, it '
|
||||
'will be removed in X.')
|
||||
XENAPI_OPTS = [
|
||||
cfg.StrOpt('connection_url',
|
||||
help=_("URL for connection to XenServer/Xen Cloud Platform.")),
|
||||
help=_("URL for connection to XenServer/Xen Cloud Platform."),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_since='Wallaby',
|
||||
deprecated_reason=XENAPI_DEPRECATION_REASON),
|
||||
cfg.StrOpt('connection_username',
|
||||
help=_("Username for connection to XenServer/Xen Cloud "
|
||||
"Platform.")),
|
||||
"Platform."),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_since='Wallaby',
|
||||
deprecated_reason=XENAPI_DEPRECATION_REASON),
|
||||
cfg.StrOpt('connection_password',
|
||||
help=_("Password for connection to XenServer/Xen Cloud "
|
||||
"Platform."),
|
||||
secret=True)
|
||||
secret=True,
|
||||
deprecated_for_removal=True,
|
||||
deprecated_since='Wallaby',
|
||||
deprecated_reason=XENAPI_DEPRECATION_REASON)
|
||||
]
|
||||
|
||||
|
||||
def register_xenapi_opts(cfg=cfg.CONF):
|
||||
cfg.register_opts(XENAPI_OPTS, group=XENAPI_CONF_SECTION)
|
||||
|
@ -31,7 +31,6 @@ import neutron.conf.agent.linux
|
||||
import neutron.conf.agent.metadata.config as meta_conf
|
||||
import neutron.conf.agent.ovs_conf
|
||||
import neutron.conf.agent.ovsdb_api
|
||||
import neutron.conf.agent.xenapi_conf
|
||||
import neutron.conf.common
|
||||
import neutron.conf.db.dvr_mac_db
|
||||
import neutron.conf.db.extraroute_db
|
||||
@ -341,10 +340,3 @@ def list_ironic_auth_opts():
|
||||
opt_list.append(plugin_option)
|
||||
opt_list.sort(key=operator.attrgetter('name'))
|
||||
return [(IRONIC_GROUP, opt_list)]
|
||||
|
||||
|
||||
def list_xenapi_opts():
|
||||
return [
|
||||
('xenapi',
|
||||
neutron.conf.agent.xenapi_conf.XENAPI_OPTS)
|
||||
]
|
||||
|
@ -53,7 +53,6 @@ from neutron.agent.common import ovs_lib
|
||||
from neutron.agent.common import polling
|
||||
from neutron.agent.common import utils
|
||||
from neutron.agent.l2 import l2_agent_extensions_manager as ext_manager
|
||||
from neutron.agent.linux import xenapi_root_helper
|
||||
from neutron.agent import rpc as agent_rpc
|
||||
from neutron.agent import securitygroups_rpc as agent_sg_rpc
|
||||
from neutron.api.rpc.callbacks import resources
|
||||
@ -62,7 +61,6 @@ from neutron.api.rpc.handlers import securitygroups_rpc as sg_rpc
|
||||
from neutron.common import config
|
||||
from neutron.common import utils as n_utils
|
||||
from neutron.conf.agent import common as agent_config
|
||||
from neutron.conf.agent import xenapi_conf
|
||||
from neutron.conf import service as service_conf
|
||||
from neutron.plugins.ml2.drivers.agent import capabilities
|
||||
from neutron.plugins.ml2.drivers.l2pop.rpc_manager import l2population_rpc
|
||||
@ -2769,20 +2767,7 @@ def validate_tunnel_config(tunnel_types, local_ip):
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
def prepare_xen_compute():
|
||||
is_xen_compute_host = 'rootwrap-xen-dom0' in cfg.CONF.AGENT.root_helper \
|
||||
or xenapi_root_helper.ROOT_HELPER_DAEMON_TOKEN == \
|
||||
cfg.CONF.AGENT.root_helper_daemon
|
||||
if is_xen_compute_host:
|
||||
xenapi_conf.register_xenapi_opts()
|
||||
# Force ip_lib to always use the root helper to ensure that ip
|
||||
# commands target xen dom0 rather than domU.
|
||||
cfg.CONF.register_opts(ip_lib.OPTS)
|
||||
cfg.CONF.set_default('ip_lib_force_root', True)
|
||||
|
||||
|
||||
def main(bridge_classes):
|
||||
prepare_xen_compute()
|
||||
ovs_capabilities.register()
|
||||
ext_manager.register_opts(cfg.CONF)
|
||||
agent_config.setup_privsep()
|
||||
|
@ -40,16 +40,6 @@ class AgentUtilsExecuteTest(base.BaseTestCase):
|
||||
self.process.return_value.returncode = 0
|
||||
self.mock_popen = self.process.return_value.communicate
|
||||
|
||||
def test_xenapi_root_helper(self):
|
||||
token = utils.xenapi_root_helper.ROOT_HELPER_DAEMON_TOKEN
|
||||
self.config(group='AGENT', root_helper_daemon=token)
|
||||
with mock.patch(
|
||||
'neutron.agent.linux.utils.xenapi_root_helper.XenAPIClient')\
|
||||
as mock_xenapi_class:
|
||||
mock_client = mock_xenapi_class.return_value
|
||||
cmd_client = utils.RootwrapDaemonHelper.get_client()
|
||||
self.assertEqual(cmd_client, mock_client)
|
||||
|
||||
def test_without_helper(self):
|
||||
expected = "%s\n" % self.test_file
|
||||
self.mock_popen.return_value = [expected, ""]
|
||||
|
@ -1,86 +0,0 @@
|
||||
# Copyright 2016 Citrix System.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_rootwrap import cmd as oslo_rootwrap_cmd
|
||||
|
||||
from neutron.agent.linux import xenapi_root_helper as helper
|
||||
from neutron.conf.agent import xenapi_conf
|
||||
from neutron.tests import base
|
||||
|
||||
|
||||
class TestXenapiRootHelper(base.BaseTestCase):
|
||||
def _get_fake_xenapi_client(self):
|
||||
class FakeXenapiClient(helper.XenAPIClient):
|
||||
def __init__(self):
|
||||
self._session = mock.MagicMock()
|
||||
|
||||
return FakeXenapiClient()
|
||||
|
||||
def setUp(self):
|
||||
super(TestXenapiRootHelper, self).setUp()
|
||||
conf = cfg.CONF
|
||||
xenapi_conf.register_xenapi_opts(conf)
|
||||
|
||||
def test_get_return_code_unauthourized(self):
|
||||
failure_details = [helper.XENAPI_PLUGIN_FAILURE_ID,
|
||||
'run_command',
|
||||
'PluginError',
|
||||
helper.MSG_UNAUTHORIZED]
|
||||
xenapi_client = self._get_fake_xenapi_client()
|
||||
rc = xenapi_client._get_return_code(failure_details)
|
||||
self.assertEqual(oslo_rootwrap_cmd.RC_UNAUTHORIZED, rc)
|
||||
|
||||
def test_get_return_code_noexecfound(self):
|
||||
failure_details = [helper.XENAPI_PLUGIN_FAILURE_ID,
|
||||
'run_command',
|
||||
'PluginError',
|
||||
helper.MSG_NOT_FOUND]
|
||||
xenapi_client = self._get_fake_xenapi_client()
|
||||
rc = xenapi_client._get_return_code(failure_details)
|
||||
self.assertEqual(oslo_rootwrap_cmd.RC_NOEXECFOUND, rc)
|
||||
|
||||
def test_get_return_code_unknown_error(self):
|
||||
failure_details = [helper.XENAPI_PLUGIN_FAILURE_ID,
|
||||
'run_command',
|
||||
'PluginError',
|
||||
'Any unknown error']
|
||||
xenapi_client = self._get_fake_xenapi_client()
|
||||
rc = xenapi_client._get_return_code(failure_details)
|
||||
self.assertEqual(helper.RC_UNKNOWN_XENAPI_ERROR, rc)
|
||||
|
||||
def test_execute(self):
|
||||
cmd = ["ovs-vsctl", "list-ports", "xapi2"]
|
||||
expect_cmd_args = {'cmd': '["ovs-vsctl", "list-ports", "xapi2"]',
|
||||
'cmd_input': 'null'}
|
||||
raw_result = '{"returncode": 0, "err": "", "out": "vif158.2"}'
|
||||
|
||||
with mock.patch.object(helper.XenAPIClient, "_call_plugin",
|
||||
return_value=raw_result) as mock_call_plugin:
|
||||
xenapi_client = self._get_fake_xenapi_client()
|
||||
rc, out, err = xenapi_client.execute(cmd)
|
||||
|
||||
mock_call_plugin.assert_called_once_with(
|
||||
'netwrap.py', 'run_command', expect_cmd_args)
|
||||
self.assertEqual(0, rc)
|
||||
self.assertEqual("vif158.2", out)
|
||||
self.assertEqual("", err)
|
||||
|
||||
def test_execute_nocommand(self):
|
||||
cmd = []
|
||||
xenapi_client = self._get_fake_xenapi_client()
|
||||
rc, out, err = xenapi_client.execute(cmd)
|
||||
self.assertEqual(oslo_rootwrap_cmd.RC_NOCOMMAND, rc)
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
deprecations:
|
||||
- |
|
||||
Removed ``XenAPI`` support in Neutron. This driver is no longer supported
|
||||
in Nova and Neutron.
|
||||
The configuration options have been marked as "deprecated for removal" and
|
||||
will be removed in X release.
|
@ -54,7 +54,6 @@ pyOpenSSL>=17.1.0 # Apache-2.0
|
||||
python-novaclient>=9.1.0 # Apache-2.0
|
||||
openstacksdk>=0.31.2 # Apache-2.0
|
||||
python-designateclient>=2.7.0 # Apache-2.0
|
||||
os-xenapi>=0.3.4 # Apache-2.0
|
||||
os-vif>=1.15.1 # Apache-2.0
|
||||
futurist>=1.2.0 # Apache-2.0
|
||||
tooz>=1.58.0 # Apache-2.0
|
||||
|
Loading…
Reference in New Issue
Block a user