Add granular placement policy rules for aggregates

This adds the policy rules for the resource provider
aggregates GET and PUT APIs.

Note that this change also uses scope types, which are
not enforced by default (see the [oslo_policy]/enforce_scope
configuration option).

Part of blueprint granular-placement-policy

Change-Id: I2ffb8a8f1464381d7bfb1b81fb40a4689b0c80ea
This commit is contained in:
Matt Riedemann 2018-05-25 19:39:55 -04:00
parent f22f6d1443
commit 9e44dc3466
5 changed files with 99 additions and 0 deletions

View File

@ -144,6 +144,8 @@ PER_ROUTE_POLICY = [
# /resource_providers/{uuid}/inventories
# /resource_providers/{uuid}/inventories/{resource_class}
'/resource_providers(/[A-Za-z0-9-]+)?(/inventories)?(/[A-Z0-9_]+)?$',
# /resource_providers/{uuid}/aggregates
'/resource_providers/[A-Za-z0-9-]+/aggregates$',
# /resource_classes
# /resource_classes/{name}
'/resource_classes',

View File

@ -20,6 +20,7 @@ import webob
from nova.api.openstack.placement import exception
from nova.api.openstack.placement import microversion
from nova.api.openstack.placement.objects import resource_provider as rp_obj
from nova.api.openstack.placement.policies import aggregate as policies
from nova.api.openstack.placement.schemas import aggregate as schema
from nova.api.openstack.placement import util
from nova.api.openstack.placement import wsgi_wrapper
@ -86,6 +87,7 @@ def get_aggregates(req):
list of aggregate uuids.
"""
context = req.environ['placement.context']
context.can(policies.LIST)
uuid = util.wsgi_path_item(req.environ, 'uuid')
resource_provider = rp_obj.ResourceProvider.get_by_uuid(
context, uuid)
@ -99,6 +101,7 @@ def get_aggregates(req):
@microversion.version_handler('1.1')
def set_aggregates(req):
context = req.environ['placement.context']
context.can(policies.UPDATE)
want_version = req.environ[microversion.MICROVERSION_ENVIRON]
consider_generation = want_version.matches(
min_version=_INCLUDE_GENERATION_VERSION)

View File

@ -12,6 +12,7 @@
import itertools
from nova.api.openstack.placement.policies import aggregate
from nova.api.openstack.placement.policies import base
from nova.api.openstack.placement.policies import inventory
from nova.api.openstack.placement.policies import resource_class
@ -25,5 +26,6 @@ def list_rules():
resource_provider.list_rules(),
resource_class.list_rules(),
inventory.list_rules(),
aggregate.list_rules(),
usage.list_rules(),
)

View File

@ -0,0 +1,53 @@
# 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.api.openstack.placement.policies import base
PREFIX = 'placement:resource_providers:aggregates:%s'
LIST = PREFIX % 'list'
UPDATE = PREFIX % 'update'
BASE_PATH = '/resource_providers/{uuid}/aggregates'
rules = [
policy.DocumentedRuleDefault(
LIST,
base.RULE_ADMIN_API,
"List resource provider aggregates.",
[
{
'method': 'GET',
'path': BASE_PATH
}
],
scope_types=['system']
),
policy.DocumentedRuleDefault(
UPDATE,
base.RULE_ADMIN_API,
"Update resource provider aggregates.",
[
{
'method': 'PUT',
'path': BASE_PATH
}
],
scope_types=['system']
),
]
def list_rules():
return rules

View File

@ -0,0 +1,39 @@
# This tests the individual CRUD operations on
# /resource_providers/{uuid}/aggregates* using a non-admin user with an
# open policy configuration. The response validation is intentionally minimal.
fixtures:
- OpenPolicyFixture
defaults:
request_headers:
x-auth-token: user
accept: application/json
content-type: application/json
openstack-api-version: placement latest
vars:
- &agg_1 f918801a-5e54-4bee-9095-09a9d0c786b8
- &agg_2 a893eb5c-e2a0-4251-ab26-f71d3b0cfc0b
tests:
- name: post new resource provider
POST: /resource_providers
data:
name: $ENVIRON['RP_NAME']
uuid: $ENVIRON['RP_UUID']
status: 200
- name: put some aggregates
PUT: /resource_providers/$ENVIRON['RP_UUID']/aggregates
data:
resource_provider_generation: 0
aggregates:
- *agg_1
- *agg_2
status: 200
- name: get those aggregates
GET: $LAST_URL
response_json_paths:
$.aggregates.`len`: 2