diff --git a/api-ref/source/index.rst b/api-ref/source/index.rst index 3e651881b2..f7679f7cab 100644 --- a/api-ref/source/index.rst +++ b/api-ref/source/index.rst @@ -65,7 +65,6 @@ the `API guide `_. .. include:: os-floating-ip-pools.inc .. include:: os-floating-ips.inc .. include:: os-floating-ips-bulk.inc -.. include:: os-fping.inc .. include:: os-security-groups.inc .. include:: os-security-group-default-rules.inc .. include:: os-security-group-rules.inc @@ -81,3 +80,4 @@ Compute API in the past, but no longer exist. .. include:: os-certificates.inc .. include:: os-cloudpipe.inc +.. include:: os-fping.inc diff --git a/api-ref/source/os-fping.inc b/api-ref/source/os-fping.inc index 46b2a0c3d7..22425e4d91 100644 --- a/api-ref/source/os-fping.inc +++ b/api-ref/source/os-fping.inc @@ -9,6 +9,7 @@ This API only works with ``nova-network`` which is deprecated. It should be avoided in any new applications. These will fail with a 404 starting from microversion 2.36. + It was removed in the 18.0.0 Rocky release. Pings instances and reports which instances are alive. @@ -37,7 +38,8 @@ change these permissions through the ``policy.json`` file. Normal response codes: 200 -Error response codes: serviceUnavailable(503), unauthorized(401), forbidden(403) +Error response codes: serviceUnavailable(503), unauthorized(401), forbidden(403), +itemNotFound(404), gone(410) Request ------- @@ -80,7 +82,7 @@ change these permissions through the ``policy.json`` file. Normal response codes: 200 Error response codes: serviceUnavailable(503), unauthorized(401), forbidden(403), -itemNotFound(404) +itemNotFound(404), gone(410) Request ------- diff --git a/nova/api/openstack/compute/fping.py b/nova/api/openstack/compute/fping.py index 540300f7cf..0714ae51b4 100644 --- a/nova/api/openstack/compute/fping.py +++ b/nova/api/openstack/compute/fping.py @@ -14,126 +14,17 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools -import os - - from webob import exc -from oslo_concurrency import processutils - -from nova.api.openstack.api_version_request \ - import MAX_PROXY_API_SUPPORT_VERSION -from nova.api.openstack import common -from nova.api.openstack.compute.schemas import fping as schema from nova.api.openstack import wsgi -from nova.api import validation -from nova import compute -import nova.conf -from nova.i18n import _ -from nova.policies import fping as fping_policies - -CONF = nova.conf.CONF class FpingController(wsgi.Controller): - def __init__(self, network_api=None): - self.compute_api = compute.API() - self.last_call = {} - - def check_fping(self): - if not os.access(CONF.api.fping_path, os.X_OK): - raise exc.HTTPServiceUnavailable( - explanation=_("fping utility is not found.")) - - @staticmethod - def fping(ips): - fping_ret = processutils.execute(CONF.api.fping_path, *ips, - check_exit_code=False) - if not fping_ret: - return set() - alive_ips = set() - for line in fping_ret[0].split("\n"): - ip = line.split(" ", 1)[0] - if "alive" in line: - alive_ips.add(ip) - return alive_ips - - @staticmethod - def _get_instance_ips(context, instance): - ret = [] - for network in common.get_networks_for_instance( - context, instance).values(): - all_ips = itertools.chain(network["ips"], network["floating_ips"]) - ret += [ip["address"] for ip in all_ips] - return ret - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @validation.query_schema(schema.index_query) - @wsgi.expected_errors(503) + @wsgi.expected_errors(410) def index(self, req): - context = req.environ["nova.context"] - search_opts = dict(deleted=False) - if "all_tenants" in req.GET: - context.can(fping_policies.POLICY_ROOT % 'all_tenants') - else: - context.can(fping_policies.BASE_POLICY_NAME) - if context.project_id: - search_opts["project_id"] = context.project_id - else: - search_opts["user_id"] = context.user_id - self.check_fping() - include = req.GET.get("include", None) - if include: - include = set(include.split(",")) - exclude = set() - else: - include = None - exclude = req.GET.get("exclude", None) - if exclude: - exclude = set(exclude.split(",")) - else: - exclude = set() + raise exc.HTTPGone() - instance_list = self.compute_api.get_all( - context, search_opts=search_opts) - ip_list = [] - instance_ips = {} - instance_projects = {} - - for instance in instance_list: - uuid = instance.uuid - if uuid in exclude or (include is not None and - uuid not in include): - continue - ips = [str(ip) for ip in self._get_instance_ips(context, instance)] - instance_ips[uuid] = ips - instance_projects[uuid] = instance.project_id - ip_list += ips - alive_ips = self.fping(ip_list) - res = [] - for instance_uuid, ips in instance_ips.items(): - res.append({ - "id": instance_uuid, - "project_id": instance_projects[instance_uuid], - "alive": bool(set(ips) & alive_ips), - }) - return {"servers": res} - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors((404, 503)) + @wsgi.expected_errors(410) def show(self, req, id): - context = req.environ["nova.context"] - context.can(fping_policies.BASE_POLICY_NAME) - self.check_fping() - instance = common.get_instance(self.compute_api, context, id) - ips = [str(ip) for ip in self._get_instance_ips(context, instance)] - alive_ips = self.fping(ips) - return { - "server": { - "id": instance.uuid, - "project_id": instance.project_id, - "alive": bool(set(ips) & alive_ips), - } - } + raise exc.HTTPGone() diff --git a/nova/api/openstack/compute/schemas/fping.py b/nova/api/openstack/compute/schemas/fping.py deleted file mode 100644 index be3f6ec388..0000000000 --- a/nova/api/openstack/compute/schemas/fping.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2017 NEC Corporation. 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. -from nova.api.validation import parameter_types - -index_query = { - 'type': 'object', - 'properties': { - 'all_tenants': parameter_types.multi_params({'type': 'string'}), - 'include': parameter_types.multi_params({'type': 'string'}), - 'exclude': parameter_types.multi_params({'type': 'string'}) - }, - # NOTE(gmann): This is kept True to keep backward compatibility. - # As of now Schema validation stripped out the additional parameters and - # does not raise 400. In the future, we may block the additional parameters - # by bump in Microversion. - 'additionalProperties': True -} diff --git a/nova/conf/api.py b/nova/conf/api.py index 04bd0ae01c..d1cc8db74a 100644 --- a/nova/conf/api.py +++ b/nova/conf/api.py @@ -297,20 +297,6 @@ Possible values: """) ] -fping_path_opts = [ - cfg.StrOpt("fping_path", - default="/usr/sbin/fping", - deprecated_group="DEFAULT", - deprecated_for_removal=True, - deprecated_since="18.0.0", - deprecated_reason=""" -This option only used in /os-fping API and the API itself was deprecated -at version 2.36 (Newton release), also, the API itself is based on nova-network -and nova-network is deprecated as well. -""", - help="The full path to the fping binary.") -] - os_network_opts = [ cfg.BoolOpt("use_neutron_default_nets", default=False, @@ -353,7 +339,6 @@ API_OPTS = (auth_opts + file_opts + osapi_opts + osapi_hide_opts + - fping_path_opts + os_network_opts + enable_inst_pw_opts) diff --git a/nova/policies/__init__.py b/nova/policies/__init__.py index ff351e58c6..01ba14606e 100644 --- a/nova/policies/__init__.py +++ b/nova/policies/__init__.py @@ -46,7 +46,6 @@ from nova.policies import floating_ip_dns from nova.policies import floating_ip_pools from nova.policies import floating_ips from nova.policies import floating_ips_bulk -from nova.policies import fping from nova.policies import hide_server_addresses from nova.policies import hosts from nova.policies import hypervisors @@ -124,7 +123,6 @@ def list_rules(): floating_ip_pools.list_rules(), floating_ips.list_rules(), floating_ips_bulk.list_rules(), - fping.list_rules(), hide_server_addresses.list_rules(), hosts.list_rules(), hypervisors.list_rules(), diff --git a/nova/policies/fping.py b/nova/policies/fping.py deleted file mode 100644 index e2be025dd7..0000000000 --- a/nova/policies/fping.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2016 Cloudbase Solutions Srl -# 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. - -from oslo_policy import policy - -from nova.policies import base - - -BASE_POLICY_NAME = 'os_compute_api:os-fping' -POLICY_ROOT = 'os_compute_api:os-fping:%s' - - -fping_policies = [ - policy.DocumentedRuleDefault( - POLICY_ROOT % 'all_tenants', - base.RULE_ADMIN_API, - """Pings instances for all projects and reports which instances -are alive. - -os-fping API is deprecated as this works only with nova-network -which itself is deprecated.""", - [ - { - 'method': 'GET', - 'path': '/os-fping?all_tenants=true' - } - ]), - policy.DocumentedRuleDefault( - BASE_POLICY_NAME, - base.RULE_ADMIN_OR_OWNER, - """Pings instances, particular instance and reports which instances -are alive. - -os-fping API is deprecated as this works only with nova-network -which itself is deprecated.""", - [ - { - 'method': 'GET', - 'path': '/os-fping' - }, - { - 'method': 'GET', - 'path': '/os-fping/{instance_id}' - } - ]) -] - - -def list_rules(): - return fping_policies diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-fping/fping-get-details-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-fping/fping-get-details-resp.json.tpl deleted file mode 100644 index 59953dbf03..0000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-fping/fping-get-details-resp.json.tpl +++ /dev/null @@ -1,7 +0,0 @@ -{ - "server": { - "alive": false, - "id": "%(uuid)s", - "project_id": "6f70656e737461636b20342065766572" - } -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-fping/fping-get-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-fping/fping-get-resp.json.tpl deleted file mode 100644 index df03e5362a..0000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-fping/fping-get-resp.json.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{ - "servers": [ - { - "alive": false, - "id": "%(uuid)s", - "project_id": "6f70656e737461636b20342065766572" - } - ] -} diff --git a/nova/tests/functional/api_sample_tests/test_fping.py b/nova/tests/functional/api_sample_tests/test_fping.py index 2c94038c3e..f77501d95d 100644 --- a/nova/tests/functional/api_sample_tests/test_fping.py +++ b/nova/tests/functional/api_sample_tests/test_fping.py @@ -13,30 +13,22 @@ # License for the specific language governing permissions and limitations # under the License. -from nova.tests.functional.api_sample_tests import test_servers -from nova.tests.unit.api.openstack.compute import test_fping +from oslo_utils import uuidutils + +from nova.tests.functional.api import client as api_client +from nova.tests.functional import api_samples_test_base -class FpingSampleJsonTests(test_servers.ServersSampleBase): - sample_dir = "os-fping" - - def setUp(self): - super(FpingSampleJsonTests, self).setUp() - - def fake_check_fping(self): - pass - self.stub_out("oslo_concurrency.processutils.execute", - test_fping.execute) - self.stub_out("nova.api.openstack.compute.fping." - "FpingController.check_fping", - fake_check_fping) +class FpingSampleJsonTests(api_samples_test_base.ApiSampleTestBase): + api_major_version = 'v2' def test_get_fping(self): - self._post_server() - response = self._do_get('os-fping') - self._verify_response('fping-get-resp', {}, response, 200) + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_get, '/os-fping') + self.assertEqual(410, ex.response.status_code) def test_get_fping_details(self): - uuid = self._post_server() - response = self._do_get('os-fping/%s' % (uuid)) - self._verify_response('fping-get-details-resp', {}, response, 200) + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_get, '/os-fping/%s' % + uuidutils.generate_uuid()) + self.assertEqual(410, ex.response.status_code) diff --git a/nova/tests/unit/api/openstack/compute/test_fping.py b/nova/tests/unit/api/openstack/compute/test_fping.py deleted file mode 100644 index f9c03a6548..0000000000 --- a/nova/tests/unit/api/openstack/compute/test_fping.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright 2011 Grid Dynamics -# Copyright 2011 OpenStack Foundation -# 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. - -import mock -import webob - -from nova.api.openstack.compute import fping as fping_v21 -from nova import exception -from nova import test -from nova.tests.unit.api.openstack import fakes - - -FAKE_UUID = fakes.FAKE_UUID - - -def execute(*cmd, **args): - return "".join(["%s is alive" % ip for ip in cmd[1:]]) - - -class FpingTestV21(test.TestCase): - controller_cls = fping_v21.FpingController - - def setUp(self): - super(FpingTestV21, self).setUp() - self.flags(use_ipv6=False) - return_server = fakes.fake_instance_get() - return_servers = fakes.fake_instance_get_all_by_filters() - self.stub_out("nova.compute.instance_list.get_instances_sorted", - return_servers) - self.stub_out("nova.db.instance_get_by_uuid", - return_server) - self.stub_out('oslo_concurrency.processutils.execute', - execute) - self.stub_out("nova.api.openstack.compute.fping.FpingController." - "check_fping", - lambda self: None) - self.controller = self.controller_cls() - - def _get_url(self): - return "/v2/1234" - - def test_fping_index(self): - req = fakes.HTTPRequest.blank(self._get_url() + "/os-fping") - res_dict = self.controller.index(req) - self.assertIn("servers", res_dict) - for srv in res_dict["servers"]: - for key in "project_id", "id", "alive": - self.assertIn(key, srv) - - def test_fping_index_policy(self): - req = fakes.HTTPRequest.blank(self._get_url() + - "os-fping?all_tenants=1") - self.assertRaises(exception.Forbidden, self.controller.index, req) - req = fakes.HTTPRequest.blank(self._get_url() + - "/os-fping?all_tenants=1") - req.environ["nova.context"].is_admin = True - res_dict = self.controller.index(req) - self.assertIn("servers", res_dict) - - def test_fping_index_include(self): - req = fakes.HTTPRequest.blank(self._get_url() + "/os-fping") - res_dict = self.controller.index(req) - ids = [srv["id"] for srv in res_dict["servers"]] - req = fakes.HTTPRequest.blank(self._get_url() + - "/os-fping?include=%s" % ids[0]) - res_dict = self.controller.index(req) - self.assertEqual(len(res_dict["servers"]), 1) - self.assertEqual(res_dict["servers"][0]["id"], ids[0]) - - def test_fping_index_exclude(self): - req = fakes.HTTPRequest.blank(self._get_url() + "/os-fping") - res_dict = self.controller.index(req) - ids = [srv["id"] for srv in res_dict["servers"]] - req = fakes.HTTPRequest.blank(self._get_url() + - "/os-fping?exclude=%s" % - ",".join(ids[1:])) - res_dict = self.controller.index(req) - self.assertEqual(len(res_dict["servers"]), 1) - self.assertEqual(res_dict["servers"][0]["id"], ids[0]) - - def test_fping_index_with_negative_int_filters(self): - req = fakes.HTTPRequest.blank(self._get_url() + - '/os-fping?all_tenants=-1&include=-21&exclude=-3', - use_admin_context=True) - self.controller.index(req) - - def test_fping_index_with_string_filter(self): - req = fakes.HTTPRequest.blank(self._get_url() + - '/os-fping?all_tenants=abc&include=abc1&exclude=abc2', - use_admin_context=True) - self.controller.index(req) - - def test_fping_index_duplicate_query_parameters_validation(self): - params = { - 'all_tenants': 1, - 'include': 'UUID1', - 'exclude': 'UUID2' - } - - for param, value in params.items(): - req = fakes.HTTPRequest.blank(self._get_url() - + '/os-fping?%s=%s&%s=%s' % - (param, value, param, value), - use_admin_context=True) - self.controller.index(req) - - def test_fping_index_pagination_with_additional_filter(self): - req = fakes.HTTPRequest.blank(self._get_url() + - '/os-fping?all_tenants=1&include=UUID1&additional=3', - use_admin_context=True) - self.controller.index(req) - - def test_fping_show(self): - req = fakes.HTTPRequest.blank(self._get_url() + - "os-fping/%s" % FAKE_UUID) - res_dict = self.controller.show(req, FAKE_UUID) - self.assertIn("server", res_dict) - srv = res_dict["server"] - for key in "project_id", "id", "alive": - self.assertIn(key, srv) - - @mock.patch('nova.db.instance_get_by_uuid') - def test_fping_show_with_not_found(self, mock_get_instance): - mock_get_instance.side_effect = exception.InstanceNotFound( - instance_id='') - req = fakes.HTTPRequest.blank(self._get_url() + - "os-fping/%s" % FAKE_UUID) - self.assertRaises(webob.exc.HTTPNotFound, - self.controller.show, req, FAKE_UUID) - - -class FpingPolicyEnforcementV21(test.NoDBTestCase): - - def setUp(self): - super(FpingPolicyEnforcementV21, self).setUp() - self.controller = fping_v21.FpingController() - self.req = fakes.HTTPRequest.blank('') - - def common_policy_check(self, rule, func, *arg, **kwarg): - self.policy.set_rules(rule) - exc = self.assertRaises( - exception.PolicyNotAuthorized, func, *arg, **kwarg) - self.assertEqual( - "Policy doesn't allow %s to be performed." % - rule.popitem()[0], exc.format_message()) - - def test_list_policy_failed(self): - rule = {"os_compute_api:os-fping": "project:non_fake"} - self.common_policy_check(rule, self.controller.index, self.req) - - self.req.GET.update({"all_tenants": "True"}) - rule = {"os_compute_api:os-fping:all_tenants": - "project:non_fake"} - self.common_policy_check(rule, self.controller.index, self.req) - - def test_show_policy_failed(self): - rule = {"os_compute_api:os-fping": "project:non_fake"} - self.common_policy_check( - rule, self.controller.show, self.req, FAKE_UUID) - - -class FpingTestDeprecation(test.NoDBTestCase): - - def setUp(self): - super(FpingTestDeprecation, self).setUp() - self.controller = fping_v21.FpingController() - self.req = fakes.HTTPRequest.blank('', version='2.36') - - def test_all_apis_return_not_found(self): - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.show, self.req, fakes.FAKE_UUID) - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.index, self.req) diff --git a/nova/tests/unit/fake_policy.py b/nova/tests/unit/fake_policy.py index 8be88a30f5..c639fee207 100644 --- a/nova/tests/unit/fake_policy.py +++ b/nova/tests/unit/fake_policy.py @@ -53,7 +53,6 @@ policy_data = """ "os_compute_api:os-floating-ip-pools": "", "os_compute_api:os-floating-ips": "", "os_compute_api:os-floating-ips-bulk": "", - "os_compute_api:os-fping": "", "os_compute_api:os-instance-actions": "", "os_compute_api:os-instance-usage-audit-log": "", diff --git a/nova/tests/unit/test_policy.py b/nova/tests/unit/test_policy.py index a6f4fe1954..d5dad45d3c 100644 --- a/nova/tests/unit/test_policy.py +++ b/nova/tests/unit/test_policy.py @@ -315,7 +315,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase): "os_compute_api:os-floating-ips-bulk", "os_compute_api:os-floating-ip-dns:domain:delete", "os_compute_api:os-floating-ip-dns:domain:update", -"os_compute_api:os-fping:all_tenants", "os_compute_api:os-hosts", "os_compute_api:os-hypervisors", "os_compute_api:os-instance-actions:events", @@ -411,7 +410,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase): "os_compute_api:os-floating-ip-dns", "os_compute_api:os-floating-ip-pools", "os_compute_api:os-floating-ips", -"os_compute_api:os-fping", "os_compute_api:image-size", "os_compute_api:os-instance-actions", "os_compute_api:os-keypairs", diff --git a/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml b/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml new file mode 100644 index 0000000000..76c1706ba5 --- /dev/null +++ b/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml @@ -0,0 +1,14 @@ +--- +upgrade: + - | + The *nova-network* service has been deprecated since the 14.0.0 Newton + release and now the following *nova-network* specific REST APIs have been + removed along with their related policy rules. Calling these APIs will now + result in a ``410 HTTPGone`` error response. + + * ``GET /os-fping`` + * ``GET /os-fping/{server_id}`` + + In addition, the following configuration options have been removed. + + * ``[api]/fping_path``