Add reservation policy support
This patch adds `tosca.policies.reservation` policy_type in TOSCA definitions and it's related unit tests. Tacker Blueprint: https://blueprints.launchpad.net/tacker/+spec/reservation-vnfm Tacker Spec: https://review.openstack.org/#/c/561840/ Change-Id: Ic5d790df938b40d75bc50252e1e688e9c09eb568
This commit is contained in:
parent
f2ca5eb7aa
commit
fd3c74b86b
@ -953,6 +953,11 @@ policy_types:
|
||||
description: The TOSCA Policy Type definition that is used to declare
|
||||
performance requirements for TOSCA nodes or groups of nodes.
|
||||
|
||||
tosca.policies.Reservation:
|
||||
derived_from: tosca.policies.Root
|
||||
description: The TOSCA Policy Type definition that is used to create
|
||||
TOSCA nodes or group of nodes based on the reservation.
|
||||
|
||||
##########################################################################
|
||||
# Group Type.
|
||||
# Group Type represents logical grouping of TOSCA nodes that have an
|
||||
|
@ -21,9 +21,9 @@ class PolicyType(StatefulEntityType):
|
||||
|
||||
'''TOSCA built-in policies type.'''
|
||||
SECTIONS = (DERIVED_FROM, METADATA, PROPERTIES, VERSION, DESCRIPTION,
|
||||
TARGETS, TRIGGERS, TYPE) = \
|
||||
TARGETS, TRIGGERS, TYPE, RESERVATION) = \
|
||||
('derived_from', 'metadata', 'properties', 'version',
|
||||
'description', 'targets', 'triggers', 'type')
|
||||
'description', 'targets', 'triggers', 'type', 'reservation')
|
||||
|
||||
def __init__(self, ptype, custom_def=None):
|
||||
super(PolicyType, self).__init__(ptype, self.POLICY_PREFIX,
|
||||
@ -55,6 +55,10 @@ class PolicyType(StatefulEntityType):
|
||||
self.targets_list = self.defs[self.TARGETS]
|
||||
self._validate_targets(self.targets_list, custom_def)
|
||||
|
||||
self.reservation = None
|
||||
if self.RESERVATION in self.defs:
|
||||
self.reservation = self.defs[self.RESERVATION]
|
||||
|
||||
def _get_parent_policies(self):
|
||||
policies = {}
|
||||
parent_policy = self.parent_type.type if self.parent_type else None
|
||||
|
@ -16,13 +16,15 @@ import logging
|
||||
from toscaparser.common.exception import ExceptionCollector
|
||||
from toscaparser.common.exception import UnknownFieldError
|
||||
from toscaparser.entity_template import EntityTemplate
|
||||
from toscaparser.reservation import Reservation
|
||||
from toscaparser.triggers import Triggers
|
||||
from toscaparser.utils import validateutils
|
||||
|
||||
|
||||
SECTIONS = (TYPE, METADATA, DESCRIPTION, PROPERTIES, TARGETS, TRIGGERS) = \
|
||||
SECTIONS = (TYPE, METADATA, DESCRIPTION, PROPERTIES, TARGETS, TRIGGERS,
|
||||
RESERVATION) = \
|
||||
('type', 'metadata', 'description',
|
||||
'properties', 'targets', 'triggers')
|
||||
'properties', 'targets', 'triggers', 'reservation')
|
||||
|
||||
log = logging.getLogger('tosca')
|
||||
|
||||
@ -42,6 +44,7 @@ class Policy(EntityTemplate):
|
||||
self.targets_list = targets
|
||||
self.targets_type = targets_type
|
||||
self.triggers = self._triggers(policy.get(TRIGGERS))
|
||||
self.reservation = self._reservation(policy.get(RESERVATION))
|
||||
self.properties = None
|
||||
if 'properties' in policy:
|
||||
self.properties = policy['properties']
|
||||
@ -73,6 +76,13 @@ class Policy(EntityTemplate):
|
||||
triggerObjs.append(triggersObj)
|
||||
return triggerObjs
|
||||
|
||||
def _reservation(self, reservation):
|
||||
reservationObjs = []
|
||||
if reservation:
|
||||
reservationObj = Reservation(reservation)
|
||||
reservationObjs.append(reservationObj)
|
||||
return reservationObjs
|
||||
|
||||
def _validate_keys(self):
|
||||
for key in self.entity_tpl.keys():
|
||||
if key not in SECTIONS:
|
||||
|
47
toscaparser/reservation.py
Normal file
47
toscaparser/reservation.py
Normal file
@ -0,0 +1,47 @@
|
||||
# Copyright (C) 2018 NTT DATA
|
||||
# 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 logging
|
||||
|
||||
from toscaparser.common.exception import UnknownFieldError
|
||||
from toscaparser.entity_template import EntityTemplate
|
||||
from toscaparser.entity_template import MissingRequiredFieldError
|
||||
|
||||
|
||||
SECTIONS = (START_ACTIONS, BEFORE_END_ACTIONS, END_ACTIONS, PROPERTIES) = \
|
||||
('start_actions', 'before_end_actions', 'end_actions', 'properties')
|
||||
|
||||
log = logging.getLogger('tosca')
|
||||
|
||||
|
||||
class Reservation(EntityTemplate):
|
||||
|
||||
'''Reservation defined in policies of topology template'''
|
||||
|
||||
def __init__(self, reservation_tpl):
|
||||
self.reservation_tpl = reservation_tpl
|
||||
self._validate_keys()
|
||||
self._validate_missing_field()
|
||||
|
||||
def _validate_keys(self):
|
||||
for key in self.reservation_tpl.keys():
|
||||
if key not in SECTIONS:
|
||||
raise UnknownFieldError(what='Reservation', field=key)
|
||||
|
||||
def _validate_missing_field(self):
|
||||
for key in SECTIONS:
|
||||
if key not in self.reservation_tpl.keys():
|
||||
raise MissingRequiredFieldError(what='Reservation',
|
||||
required=key)
|
@ -181,3 +181,26 @@ policy_types:
|
||||
required: false
|
||||
default: 120
|
||||
description: Wait time (in seconds) between consecutive scaling operations. During the cooldown period...
|
||||
|
||||
tosca.policies.tacker.Reservation:
|
||||
derived_from: tosca.policies.Reservation
|
||||
reservation:
|
||||
start_actions:
|
||||
type: map
|
||||
entry_schema:
|
||||
type: string
|
||||
required: True
|
||||
before_end_actions:
|
||||
type: map
|
||||
entry_schema:
|
||||
type: string
|
||||
required: True
|
||||
end_actions:
|
||||
type: map
|
||||
entry_schema:
|
||||
type: string
|
||||
required: True
|
||||
properties:
|
||||
lease_id:
|
||||
type: string
|
||||
required: True
|
||||
|
@ -39,6 +39,7 @@ artif_vm_qcow2_type = ArtifactTypeDef('tosca.artifacts.'
|
||||
policy_root_type = PolicyType('tosca.policies.Root')
|
||||
policy_placement_type = PolicyType('tosca.policies.Placement')
|
||||
policy_scaling_type = PolicyType('tosca.policies.Scaling')
|
||||
policy_reservation_type = PolicyType('tosca.policies.Reservation')
|
||||
policy_update_type = PolicyType('tosca.policies.Update')
|
||||
policy_performance_type = PolicyType('tosca.policies.Performance')
|
||||
group_type = GroupType('tosca.groups.Root')
|
||||
@ -334,6 +335,18 @@ class ToscaDefTest(TestCase):
|
||||
for name in policy_performance_type.defs],
|
||||
key=lambda x: str(x)))
|
||||
|
||||
self.assertEqual('tosca.policies.Root',
|
||||
policy_reservation_type.parent_type.type)
|
||||
self.assertEqual({}, policy_reservation_type.parent_policies)
|
||||
self.assertEqual(sorted(['tosca.policies.Root',
|
||||
'The TOSCA Policy Type definition that '
|
||||
'is used to create TOSCA nodes or group '
|
||||
'of nodes based on the reservation.'],
|
||||
key=lambda x: str(x)),
|
||||
sorted([policy_reservation_type.get_policy(name)
|
||||
for name in policy_reservation_type.defs],
|
||||
key=lambda x: str(x)))
|
||||
|
||||
def test_port_spec(self):
|
||||
tosca_def = EntityType.TOSCA_DEF
|
||||
port_spec = tosca_def.get('tosca.datatypes.network.PortSpec')
|
||||
|
@ -21,6 +21,7 @@ from toscaparser.parameters import Output
|
||||
from toscaparser.policy import Policy
|
||||
from toscaparser.relationship_template import RelationshipTemplate
|
||||
from toscaparser.repositories import Repository
|
||||
from toscaparser.reservation import Reservation
|
||||
from toscaparser.tests.base import TestCase
|
||||
from toscaparser.topology_template import TopologyTemplate
|
||||
from toscaparser.tosca_template import ToscaTemplate
|
||||
@ -1870,3 +1871,53 @@ heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"data/test_long_rel.yaml")
|
||||
self.assertIsNotNone(ToscaTemplate(tpl_path))
|
||||
|
||||
def test_policy_reservation_valid_keyname_heat_resources(self):
|
||||
tpl_snippet = '''
|
||||
reservation:
|
||||
start_actions: [SP_RSV]
|
||||
before_end_actions: [SP_RSV]
|
||||
end_actions: [noop]
|
||||
properties:
|
||||
lease_id: '58d2239c-f181-4915-bdcb-040f7ef911a7'
|
||||
'''
|
||||
reservation = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
|
||||
name = list(reservation.keys())[0]
|
||||
Reservation(reservation[name])
|
||||
|
||||
def test_policy_reservation_invalid_keyname_heat_resources(self):
|
||||
tpl_snippet = '''
|
||||
reservation:
|
||||
start_actions: [SP_RSV]
|
||||
before_actions: [SP_RSV]
|
||||
end_actions: [noop]
|
||||
properties:
|
||||
lease_id: '58d2239c-f181-4915-bdcb-040f7ef911a7'
|
||||
'''
|
||||
reservation = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
|
||||
name = list(reservation.keys())[0]
|
||||
expectedmessage = _(
|
||||
'Reservation contains unknown field '
|
||||
'"before_actions". Refer to the definition '
|
||||
'to verify valid values.')
|
||||
err = self.assertRaises(
|
||||
exception.UnknownFieldError,
|
||||
lambda: Reservation(reservation[name]))
|
||||
self.assertEqual(expectedmessage, err.__str__())
|
||||
|
||||
def test_policy_reservation_missing_key_heat_resources(self):
|
||||
tpl_snippet = '''
|
||||
reservation:
|
||||
start_actions: [SP_RSV]
|
||||
end_actions: [noop]
|
||||
properties:
|
||||
lease_id: '58d2239c-f181-4915-bdcb-040f7ef911a7'
|
||||
'''
|
||||
reservation = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
|
||||
name = list(reservation.keys())[0]
|
||||
expectedmessage = _('Reservation is missing '
|
||||
'required field "before_end_actions".')
|
||||
err = self.assertRaises(
|
||||
exception.MissingRequiredFieldError,
|
||||
lambda: Reservation(reservation[name]))
|
||||
self.assertEqual(expectedmessage, err.__str__())
|
||||
|
Loading…
Reference in New Issue
Block a user