107 changed files with 14264 additions and 9 deletions
@ -0,0 +1,24 @@
|
||||
--- |
||||
features: |
||||
- | |
||||
Support multi-version of RESTfulAPI. The client can use |
||||
both VNF LCM API "1.3.0" and "2.0.0" defined by ETSI NFV. |
||||
|
||||
- | |
||||
Add new RESTful APIs of List VNF LCM API versions |
||||
and Show VNF LCM API versions based on ETSI NFV specifications. |
||||
They enable the client to retrieve supported versions of VNF LCM API. |
||||
|
||||
- | |
||||
Add the following new version of RESTful APIs |
||||
based on ETSI NFV specifications. |
||||
Version "2.0.0" API of Create VNF, Delete VNF, |
||||
Instantiate VNF, Terminate VNF, List VNF, Show VNF, |
||||
List VNF LCM operation occurrence, Show VNF LCM operation occurrence, |
||||
Create subscription, List subscription, and Show subscription are added. |
||||
|
||||
- | |
||||
VNF LCM API "2.0.0" provides a new type of userdata script |
||||
and utility functions to describe it. |
||||
They enable the user to freely operate HEAT to meet the unique |
||||
requirements of VNF. |
@ -1 +1 @@
|
||||
6dc60a5760e5 |
||||
a23ebee909a8 |
||||
|
@ -0,0 +1,97 @@
|
||||
# Copyright 2021 OpenStack Foundation |
||||
# |
||||
# 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. |
||||
# |
||||
|
||||
"""introduce_sol_refactored_models |
||||
|
||||
Revision ID: a23ebee909a8 |
||||
Revises: 6dc60a5760e5 |
||||
Create Date: 2021-04-20 15:33:42.686284 |
||||
|
||||
""" |
||||
|
||||
# flake8: noqa: E402 |
||||
|
||||
# revision identifiers, used by Alembic. |
||||
revision = 'a23ebee909a8' |
||||
down_revision = '6dc60a5760e5' |
||||
|
||||
from alembic import op |
||||
import sqlalchemy as sa |
||||
|
||||
|
||||
def upgrade(active_plugins=None, options=None): |
||||
# ### commands auto generated by Alembic - please adjust! ### |
||||
op.create_table('LccnSubscriptionV2', |
||||
sa.Column('id', sa.String(length=255), nullable=False), |
||||
sa.Column('filter', sa.JSON(), nullable=True), |
||||
sa.Column('callbackUri', sa.String(length=255), nullable=False), |
||||
sa.Column('authentication', sa.JSON(), nullable=True), |
||||
sa.Column('verbosity', sa.Enum('FULL', 'SHORT'), nullable=False), |
||||
sa.PrimaryKeyConstraint('id'), |
||||
mysql_engine='InnoDB' |
||||
) |
||||
|
||||
op.create_table('VnfInstanceV2', |
||||
sa.Column('id', sa.String(length=255), nullable=False), |
||||
sa.Column('vnfInstanceName', sa.String(length=255), nullable=True), |
||||
sa.Column('vnfInstanceDescription', sa.Text(), nullable=True), |
||||
sa.Column('vnfdId', sa.String(length=255), nullable=False), |
||||
sa.Column('vnfProvider', sa.String(length=255), nullable=False), |
||||
sa.Column('vnfProductName', sa.String(length=255), nullable=False), |
||||
sa.Column('vnfSoftwareVersion', sa.String(length=255), nullable=False), |
||||
sa.Column('vnfdVersion', sa.String(length=255), nullable=False), |
||||
sa.Column('vnfConfigurableProperties', sa.JSON(), nullable=True), |
||||
sa.Column('vimConnectionInfo', sa.JSON(), nullable=True), |
||||
sa.Column('instantiationState', |
||||
sa.Enum('NOT_INSTANTIATED', 'INSTANTIATED'), |
||||
nullable=False), |
||||
sa.Column('instantiatedVnfInfo', sa.JSON(), nullable=True), |
||||
sa.Column('metadata', sa.JSON(), nullable=True), |
||||
sa.Column('extensions', sa.JSON(), nullable=True), |
||||
sa.PrimaryKeyConstraint('id'), |
||||
mysql_engine='InnoDB' |
||||
) |
||||
|
||||
op.create_table('VnfLcmOpOccV2', |
||||
sa.Column('id', sa.String(length=255), nullable=False), |
||||
sa.Column('operationState', |
||||
sa.Enum('STARTING', 'PROCESSING', 'COMPLETED', 'FAILED_TEMP', |
||||
'FAILED', 'ROLLING_BACK', 'ROLLED_BACK'), |
||||
nullable=False), |
||||
sa.Column('stateEnteredTime', sa.DateTime(), nullable=False), |
||||
sa.Column('startTime', sa.DateTime(), nullable=False), |
||||
sa.Column('vnfInstanceId', sa.String(length=255), nullable=False), |
||||
sa.Column('grantId', sa.String(length=255), nullable=True), |
||||
sa.Column('operation', |
||||
sa.Enum('INSTANTIATE', 'SCALE', 'SCALE_TO_LEVEL', |
||||
'CHANGE_FLAVOUR', 'TERMINATE', 'HEAL', 'OPERATE', |
||||
'CHANGE_EXT_CONN', 'MODIFY_INFO', 'CREATE_SNAPSHOT', |
||||
'REVERT_TO_SNAPSHOT', 'CHANGE_VNFPKG'), |
||||
nullable=False), |
||||
sa.Column('isAutomaticInvocation', sa.Boolean(), nullable=False), |
||||
sa.Column('operationParams', sa.JSON(), nullable=True), |
||||
sa.Column('isCancelPending', sa.Boolean(), nullable=False), |
||||
sa.Column('cancelMode', sa.Enum('GRACEFUL', 'FORCEFUL'), nullable=True), |
||||
sa.Column('error', sa.JSON(), nullable=True), |
||||
sa.Column('resourceChanges', sa.JSON(), nullable=True), |
||||
sa.Column('changedInfo', sa.JSON(), nullable=True), |
||||
sa.Column('changedExtConnectivity', sa.JSON(), nullable=True), |
||||
sa.Column('modificationsTriggeredByVnfPkgChange', sa.JSON(), |
||||
nullable=True), |
||||
sa.Column('vnfSnapshotInfoId', sa.String(length=255), nullable=True), |
||||
sa.PrimaryKeyConstraint('id'), |
||||
mysql_engine='InnoDB' |
||||
) |
||||
# ### end Alembic commands ### |
@ -0,0 +1,115 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone 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. |
||||
|
||||
|
||||
import re |
||||
|
||||
from tacker.sol_refactored.common import exceptions as sol_ex |
||||
|
||||
|
||||
supported_versions_v1 = { |
||||
'uriPrefix': '/vnflcm/v1', |
||||
'apiVersions': [ |
||||
{'version': '1.3.0', 'isDeprecated': False} |
||||
] |
||||
} |
||||
|
||||
supported_versions_v2 = { |
||||
'uriPrefix': '/vnflcm/v2', |
||||
'apiVersions': [ |
||||
{'version': '2.0.0', 'isDeprecated': False} |
||||
] |
||||
} |
||||
|
||||
CURRENT_VERSION = '2.0.0' |
||||
|
||||
supported_versions = [ |
||||
item['version'] for item in supported_versions_v2['apiVersions'] |
||||
] |
||||
|
||||
|
||||
class APIVersion(object): |
||||
|
||||
def __init__(self, version_string=None): |
||||
self.ver_major = 0 |
||||
self.ver_minor = 0 |
||||
self.ver_patch = 0 |
||||
|
||||
if version_string is None: |
||||
return |
||||
|
||||
version_string = self._get_version_id(version_string) |
||||
match = re.match(r"^([1-9]\d*)\.([1-9]\d*|0)\.([1-9]\d*|0)$", |
||||
version_string) |
||||
if match: |
||||
self.ver_major = int(match.group(1)) |
||||
self.ver_minor = int(match.group(2)) |
||||
self.ver_patch = int(match.group(3)) |
||||
else: |
||||
raise sol_ex.InvalidAPIVersionString(version=version_string) |
||||
|
||||
if version_string not in supported_versions: |
||||
raise sol_ex.APIVersionNotSupported(version=version_string) |
||||
|
||||
def _get_version_id(self, version_string): |
||||
# version example (see. SOL013 Table 4.2.2-1) |
||||
# `1.2.0` or `1.2.0-impl:example.com:myProduct:4` |
||||
# This method checks the later case and return the part of |
||||
# version identifier. check is loose. |
||||
if '-' not in version_string: |
||||
return version_string |
||||
items = version_string.split('-') |
||||
if len(items) == 2 and items[1].startswith("impl:"): |
||||
return items[0] |
||||
raise sol_ex.InvalidAPIVersionString(version=version_string) |
||||
|
||||
def is_null(self): |
||||
return (self.ver_major, self.ver_minor, self.ver_patch) == (0, 0, 0) |
||||
|
||||
def __str__(self): |
||||
return "%d.%d.%d" % (self.ver_major, self.ver_minor, self.ver_patch) |
||||
|
||||
def __lt__(self, other): |
||||
return ((self.ver_major, self.ver_minor, self.ver_patch) < |
||||
(other.ver_major, other.ver_minor, other.ver_patch)) |
||||
|
||||
def __eq__(self, other): |
||||
return ((self.ver_major, self.ver_minor, self.ver_patch) == |
||||
(other.ver_major, other.ver_minor, other.ver_patch)) |
||||
|
||||
def __gt__(self, other): |
||||
return ((self.ver_major, self.ver_minor, self.ver_patch) > |
||||
(other.ver_major, other.ver_minor, other.ver_patch)) |
||||
|
||||
def __le__(self, other): |
||||
return self < other or self == other |
||||
|
||||
def __ne__(self, other): |
||||
return not self.__eq__(other) |
||||
|
||||
def __ge__(self, other): |
||||
return self > other or self == other |
||||
|
||||
def matches(self, min_version, max_version): |
||||
if self.is_null(): |
||||
return False |
||||
if max_version.is_null() and min_version.is_null(): |
||||
return True |
||||
elif max_version.is_null(): |
||||
return min_version <= self |
||||
elif min_version.is_null(): |
||||
return self <= max_version |
||||
else: |
||||
return min_version <= self <= max_version |
@ -0,0 +1,170 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone 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 oslo_policy import policy |
||||
|
||||
|
||||
POLICY_NAME = 'os_nfv_orchestration_api_v2:vnf_instances:{}' |
||||
RULE_ANY = '@' |
||||
|
||||
V2_PATH = '/vnflcm/v2' |
||||
API_VERSIONS_PATH = V2_PATH + '/api_versions' |
||||
VNF_INSTANCES_PATH = V2_PATH + '/vnf_instances' |
||||
VNF_INSTANCES_ID_PATH = VNF_INSTANCES_PATH + '/{vnfInstanceId}' |
||||
SUBSCRIPTIONS_PATH = V2_PATH + '/subscriptions' |
||||
SUBSCRIPTIONS_ID_PATH = VNF_INSTANCES_PATH + '/{subscriptionId}' |
||||
VNF_LCM_OP_OCCS_PATH = V2_PATH + '/vnf_lcm_op_occs' |
||||
VNF_LCM_OP_OCCS_ID_PATH = VNF_LCM_OP_OCCS_PATH + '/{vnfLcmOpOccId}' |
||||
|
||||
rules = [ |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('api_versions'), |
||||
check_str=RULE_ANY, |
||||
description="Get API Versions.", |
||||
operations=[ |
||||
{'method': 'GET', |
||||
'path': API_VERSIONS_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('create'), |
||||
check_str=RULE_ANY, |
||||
description="Creates vnf instance.", |
||||
operations=[ |
||||
{'method': 'POST', |
||||
'path': VNF_INSTANCES_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('index'), |
||||
check_str=RULE_ANY, |
||||
description="Query VNF instances.", |
||||
operations=[ |
||||
{'method': 'GET', |
||||
'path': VNF_INSTANCES_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('show'), |
||||
check_str=RULE_ANY, |
||||
description="Query an Individual VNF instance.", |
||||
operations=[ |
||||
{'method': 'GET', |
||||
'path': VNF_INSTANCES_ID_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('delete'), |
||||
check_str=RULE_ANY, |
||||
description="Delete an Individual VNF instance.", |
||||
operations=[ |
||||
{'method': 'DELETE', |
||||
'path': VNF_INSTANCES_ID_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('instantiate'), |
||||
check_str=RULE_ANY, |
||||
description="Instantiate vnf instance.", |
||||
operations=[ |
||||
{'method': 'POST', |
||||
'path': VNF_INSTANCES_ID_PATH + '/instantiate'} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('terminate'), |
||||
check_str=RULE_ANY, |
||||
description="Terminate vnf instance.", |
||||
operations=[ |
||||
{'method': 'POST', |
||||
'path': VNF_INSTANCES_ID_PATH + '/terminate'} |
||||
] |
||||
), |
||||
|
||||
# TODO(oda-g): add more lcm operations etc when implemented. |
||||
|
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('subscription_create'), |
||||
check_str=RULE_ANY, |
||||
description="Create subscription.", |
||||
operations=[ |
||||
{'method': 'POST', |
||||
'path': SUBSCRIPTIONS_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('subscription_list'), |
||||
check_str=RULE_ANY, |
||||
description="List subscription.", |
||||
operations=[ |
||||
{'method': 'GET', |
||||
'path': SUBSCRIPTIONS_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('subscription_show'), |
||||
check_str=RULE_ANY, |
||||
description="Show subscription.", |
||||
operations=[ |
||||
{'method': 'GET', |
||||
'path': SUBSCRIPTIONS_ID_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('subscription_delete'), |
||||
check_str=RULE_ANY, |
||||
description="Delete subscription.", |
||||
operations=[ |
||||
{'method': 'DELETE', |
||||
'path': SUBSCRIPTIONS_ID_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('lcm_op_occ_list'), |
||||
check_str=RULE_ANY, |
||||
description="List VnfLcmOpOcc.", |
||||
operations=[ |
||||
{'method': 'GET', |
||||
'path': VNF_LCM_OP_OCCS_PATH} |
||||
] |
||||
), |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('lcm_op_occ_show'), |
||||
check_str=RULE_ANY, |
||||
description="Show VnfLcmOpOcc.", |
||||
operations=[ |
||||
{'method': 'GET', |
||||
'path': VNF_LCM_OP_OCCS_ID_PATH} |
||||
] |
||||
), |
||||
# NOTE: 'DELETE' is not defined in the specification. It is for test |
||||
# use since it is convenient to be able to delete under development. |
||||
# It is available when config parameter |
||||
# v2_vnfm.test_enable_lcm_op_occ_delete set to True. |
||||
policy.DocumentedRuleDefault( |
||||
name=POLICY_NAME.format('lcm_op_occ_delete'), |
||||
check_str=RULE_ANY, |
||||
description="Delete VnfLcmOpOcc.", |
||||
operations=[ |
||||
{'method': 'DELETE', |
||||
'path': VNF_LCM_OP_OCCS_ID_PATH} |
||||
] |
||||
), |
||||
] |
||||
|
||||
|
||||
def list_rules(): |
||||
return rules |
@ -0,0 +1,54 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone 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 tacker.sol_refactored.api.policies import vnflcm_v2 as vnflcm_policy_v2 |
||||
from tacker.sol_refactored.api import wsgi as sol_wsgi |
||||
from tacker.sol_refactored.controller import vnflcm_v2 |
||||
from tacker.sol_refactored.controller import vnflcm_versions |
||||
|
||||
|
||||
class VnflcmVersions(sol_wsgi.SolAPIRouter): |
||||
|
||||
controller = sol_wsgi.SolResource( |
||||
vnflcm_versions.VnfLcmVersionsController()) |
||||
route_list = [("/api_versions", {"GET": "index"})] |
||||
|
||||
|
||||
class VnflcmAPIRouterV2(sol_wsgi.SolAPIRouter): |
||||
|
||||
controller = sol_wsgi.SolResource(vnflcm_v2.VnfLcmControllerV2(), |
||||
policy_name=vnflcm_policy_v2.POLICY_NAME) |
||||
route_list = [ |
||||
("/vnf_instances", {"GET": "index", "POST": "create"}), |
||||
("/vnf_instances/{id}", |
||||
{"DELETE": "delete", "GET": "show", "PATCH": "update"}), |
||||
("/vnf_instances/{id}/instantiate", {"POST": "instantiate"}), |
||||
("/vnf_instances/{id}/heal", {"POST": "heal"}), |
||||
("/vnf_instances/{id}/terminate", {"POST": "terminate"}), |
||||
("/vnf_instances/{id}/scale", {"POST": "scale"}), |
||||
("/api_versions", {"GET": "api_versions"}), |
||||
("/subscriptions", {"GET": "subscription_list", |
||||
"POST": "subscription_create"}), |
||||
("/subscriptions/{id}", {"GET": "subscription_show", |
||||
"DELETE": "subscription_delete"}), |
||||
("/vnf_lcm_op_occs", {"GET": "lcm_op_occ_list"}), |
||||
# NOTE: 'DELETE' is not defined in the specification. It is for test |
||||
# use since it is convenient to be able to delete under development. |
||||
# It is available when config parameter |
||||
# v2_vnfm.test_enable_lcm_op_occ_delete set to True. |
||||
("/vnf_lcm_op_occs/{id}", {"GET": "lcm_op_occ_show", |
||||
"DELETE": "lcm_op_occ_delete"}) |
||||
] |
@ -0,0 +1,244 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone 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 tacker.api.validation import parameter_types |
||||
|
||||
|
||||
# SOL013 7.2.2 |
||||
Identifier = { |
||||
'type': 'string', 'minLength': 1, 'maxLength': 255 |
||||
} |
||||
|
||||
# SOL003 4.4.2.2 |
||||
IdentifierInVnfd = { |
||||
'type': 'string', 'minLength': 1, 'maxLength': 255 |
||||
} |
||||
|
||||
# SOL003 4.4.2.2 |
||||
IdentifierInVim = { |
||||
'type': 'string', 'minLength': 1, 'maxLength': 255 |
||||
} |
||||
|
||||
# SOL003 4.4.2.2 |
||||
IdentifierInVnf = { |
||||
'type': 'string', 'minLength': 1, 'maxLength': 255 |
||||
} |
||||
|
||||
# SOL003 4.4.2.2 |
||||
IdentifierLocal = { |
||||
'type': 'string', 'minLength': 1, 'maxLength': 255 |
||||
} |
||||
|
||||
# SOL003 4.4.1.7 |
||||
ResourceHandle = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'vimConnectionId': Identifier, |
||||
'resourceProviderId': Identifier, |
||||
'resourceId': IdentifierInVim, |
||||
'vimLevelResourceType': {'type': 'string', 'maxLength': 255}, |
||||
}, |
||||
'required': ['resourceId'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 4.4.1.6 |
||||
VimConnectionInfo = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'vimId': Identifier, |
||||
'vimType': {'type': 'string', 'minLength': 1, 'maxLength': 255}, |
||||
'interfaceInfo': parameter_types.keyvalue_pairs, |
||||
'accessInfo': parameter_types.keyvalue_pairs, |
||||
'extra': parameter_types.keyvalue_pairs, |
||||
}, |
||||
'required': ['vimType'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 4.4.1.10c (inner) |
||||
_IpAddresses = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'type': {'enum': ('IPV4', 'IPV6')}, |
||||
'fixedAddresses': {'type': 'array'}, |
||||
'numDynamicAddresses': parameter_types.positive_integer, |
||||
'addressRange': {'type': 'object'}, |
||||
'subnetId': IdentifierInVim |
||||
}, |
||||
'if': {'properties': {'type': {'const': 'IPV4'}}}, |
||||
'then': { |
||||
'properties': { |
||||
'fixedAddresses': { |
||||
'type': 'array', |
||||
'items': {'type': 'string', 'format': 'ipv4'} |
||||
}, |
||||
'addressRange': { |
||||
'type': 'object', |
||||
'properties': { |
||||
'minAddress': {'type': 'string', 'format': 'ipv4'}, |
||||
'maxAddress': {'type': 'string', 'format': 'ipv4'} |
||||
}, |
||||
'required': ['minAddress', 'maxAddress'], |
||||
'additionalProperties': True |
||||
}, |
||||
} |
||||
}, |
||||
'else': { |
||||
'properties': { |
||||
'fixedAddresses': { |
||||
'type': 'array', |
||||
'items': {'type': 'string', 'format': 'ipv6'} |
||||
}, |
||||
'addressRange': { |
||||
'type': 'object', |
||||
'properties': { |
||||
'minAddress': {'type': 'string', 'format': 'ipv6'}, |
||||
'maxAddress': {'type': 'string', 'format': 'ipv6'} |
||||
}, |
||||
'required': ['minAddress', 'maxAddress'], |
||||
'additionalProperties': True |
||||
}, |
||||
} |
||||
}, |
||||
'required': ['type'], |
||||
'oneOf': [ |
||||
{'required': ['numDynamicAddresses']}, |
||||
{'required': ['fixedAddresses']}, |
||||
{'required': ['addressRange']}, |
||||
], |
||||
'additionalProperties': True |
||||
} |
||||
|
||||
# SOL003 4.4.1.10c |
||||
IpOverEthernetAddressData = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'macAddress': {'type': 'string', 'format': 'mac_address'}, |
||||
'segmentationId': {'type': 'string'}, |
||||
'ipAddresses': { |
||||
'type': 'array', |
||||
'items': _IpAddresses} |
||||
}, |
||||
'anyOf': [ |
||||
{'required': ['macAddress']}, |
||||
{'required': ['ipAddresses']} |
||||
], |
||||
'additionalProperties': True |
||||
} |
||||
|
||||
# SOL003 4.4.1.10b |
||||
CpProtocolData = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'layerProtocol': { |
||||
'type': 'string', |
||||
'enum': 'IP_OVER_ETHERNET'}, |
||||
'ipOverEthernet': IpOverEthernetAddressData, |
||||
}, |
||||
'required': ['layerProtocol'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 4.4.1.10a |
||||
VnfExtCpConfig = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'parentCpConfigId': IdentifierInVnf, |
||||
'linkPortId': Identifier, |
||||
'cpProtocolData': { |
||||
'type': 'array', |
||||
'items': CpProtocolData} |
||||
}, |
||||
'additionalProperties': True |
||||
} |
||||
|
||||
# SOL003 4.4.1.10 |
||||
VnfExtCpData = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'cpdId': IdentifierInVnfd, |
||||
'cpConfig': { |
||||
'type': 'object', |
||||
'minProperties': 1, |
||||
'patternProperties': { |
||||
'^.*$': VnfExtCpConfig |
||||
} |
||||
} |
||||
}, |
||||
'required': ['cpdId', 'cpConfig'], |
||||
'additionalProperties': True |
||||
} |
||||
|
||||
# SOL003 4.4.1.14 |
||||
ExtLinkPortData = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'id': Identifier, |
||||
'resourceHandle': ResourceHandle, |
||||
}, |
||||
'required': ['id', 'resourceHandle'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 4.4.1.11 |
||||
ExtVirtualLinkData = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'id': Identifier, |
||||
'vimConnectionId': Identifier, |
||||
'resourceProviderId': Identifier, |
||||
'resourceId': IdentifierInVim, |
||||
'extCps': { |
||||
'type': 'array', |
||||
'minItems': 1, |
||||
'items': VnfExtCpData}, |
||||
'extLinkPorts': { |
||||
'type': 'array', |
||||
'items': ExtLinkPortData} |
||||
}, |
||||
'required': ['id', 'resourceId', 'extCps'], |
||||
'additionalProperties': True |
||||
} |
||||
|
||||
# SOL003 5.5.3.18 |
||||
VnfLinkPortData = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'vnfLinkPortId': Identifier, |
||||
'resourceHandle': ResourceHandle |
||||
}, |
||||
'required': ['vnfLinkPortId', 'resourceHandle'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 4.4.1.12 |
||||
ExtManagedVirtualLinkData = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'id': Identifier, |
||||
'vnfVirtualLinkDescId': IdentifierInVnfd, |
||||
'vimConnectionId': Identifier, |
||||
'resourceProviderId': Identifier, |
||||
'resourceId': IdentifierInVim, |
||||
'vnfLinkPort': { |
||||
'type': 'array', |
||||
'items': VnfLinkPortData}, |
||||
'extManagedMultisiteVirtualLinkId': Identifier |
||||
}, |
||||
'required': ['id', 'vnfVirtualLinkDescId', 'resourceId'], |
||||
'additionalProperties': True, |
||||
} |
@ -0,0 +1,252 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone 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 tacker.api.validation import parameter_types |
||||
|
||||
from tacker.sol_refactored.api.schemas import common_types |
||||
|
||||
|
||||
# SOL003 5.5.2.3 |
||||
CreateVnfRequest_V200 = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'vnfdId': common_types.Identifier, |
||||
'vnfInstanceName': {'type': 'string', 'maxLength': 255}, |
||||
'vnfInstanceDescription': {'type': 'string', 'maxLength': 1024}, |
||||
'metadata': parameter_types.keyvalue_pairs, |
||||
}, |
||||
'required': ['vnfdId'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 5.5.2.4 |
||||
InstantiateVnfRequest_V200 = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'flavourId': common_types.IdentifierInVnfd, |
||||
'instantiationLevelId': common_types.IdentifierInVnfd, |
||||
'extVirtualLinks': { |
||||
'type': 'array', |
||||
'items': common_types.ExtVirtualLinkData}, |
||||
'extManagedVirtualLinks': { |
||||
'type': 'array', |
||||
'items': common_types.ExtManagedVirtualLinkData}, |
||||
'vimConnectionInfo': { |
||||
'type': 'object', |
||||
'patternProperties': { |
||||
'^.*$': common_types.VimConnectionInfo |
||||
}, |
||||
}, |
||||
'localizationLanguage': {'type': 'string', 'maxLength': 255}, |
||||
'additionalParams': parameter_types.keyvalue_pairs, |
||||
'extensions': parameter_types.keyvalue_pairs, |
||||
'vnfConfigurableProperties': parameter_types.keyvalue_pairs |
||||
}, |
||||
'required': ['flavourId'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 5.5.2.8 |
||||
TerminateVnfRequest_V200 = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'terminationType': { |
||||
'type': 'string', |
||||
'enum': [ |
||||
'FORCEFUL', |
||||
'GRACEFUL'] |
||||
}, |
||||
'gracefulTerminationTimeout': { |
||||
'type': 'integer', 'minimum': 1 |
||||
}, |
||||
'additionalParams': parameter_types.keyvalue_pairs, |
||||
}, |
||||
'required': ['terminationType'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL013 8.3.4 |
||||
_SubscriptionAuthentication = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'authType': { |
||||
'type': 'array', |
||||
'items': { |
||||
'type': 'string', |
||||
'enum': [ |
||||
'BASIC', |
||||
'OAUTH2_CLIENT_CREDENTIALS', |
||||
'TLS_CERT'] |
||||
} |
||||
}, |
||||
'paramsBasic': { |
||||
'type': 'object', |
||||
'properties': { |
||||
'userName': {'type': 'string'}, |
||||
'password': {'type': 'string'} |
||||
}, |
||||
# NOTE: must be specified since the way to specify them out of |
||||
# band is not supported. |
||||
'required': ['userName', 'password'] |
||||
}, |
||||
'paramsOauth2ClientCredentials': { |
||||
'type': 'object', |
||||
'properties': { |
||||
'clientId': {'type': 'string'}, |
||||
'clientPassword': {'type': 'string'}, |
||||
'tokenEndpoint': {'type': 'string'} |
||||
}, |
||||
# NOTE: must be specified since the way to specify them out of |
||||
# band is not supported. |
||||
'required': ['clientId', 'clientPassword', 'tokenEndpoint'] |
||||
} |
||||
}, |
||||
'required': ['authType'], |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 4.4.1.5 inner |
||||
_VnfProductVersions = { |
||||
'type': 'array', |
||||
'items': { |
||||
'type': 'objects', |
||||
'properties': { |
||||
'vnfSoftwareVersion': {'type': 'string'}, |
||||
'vnfdVersions': { |
||||
'type': 'array', |
||||
'items': {'type': 'string'} |
||||
} |
||||
}, |
||||
'required': ['vnfSoftwareVersion'], |
||||
'additionalProperties': True, |
||||
} |
||||
} |
||||
|
||||
# SOL003 4.4.1.5 inner |
||||
_VnfProducts = { |
||||
'type': 'array', |
||||
'items': { |
||||
'type': 'object', |
||||
'properties': { |
||||
'vnfProductName': {'type': 'string'}, |
||||
'versions': _VnfProductVersions |
||||
}, |
||||
'required': ['vnfProductName'], |
||||
'additionalProperties': True, |
||||
} |
||||
} |
||||
|
||||
# SOL003 4.4.1.5 inner |
||||
_VnfProductsFromProviders = { |
||||
'type': 'array', |
||||
'items': { |
||||
'type': 'object', |
||||
'properties': { |
||||
'type': 'object', |
||||
'properties': { |
||||
'vnfProvider': {'type': 'string'}, |
||||
'vnfProducts': _VnfProducts |
||||
} |
||||
}, |
||||
'required': ['vnfProvider'], |
||||
'additionalProperties': True, |
||||
} |
||||
} |
||||
|
||||
# SOL003 4.4.1.5 |
||||
_VnfInstanceSubscriptionFilter = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'vnfdIds': { |
||||
'type': 'array', |
||||
'items': common_types.Identifier |
||||
}, |
||||
'vnfProductsFromProviders': _VnfProductsFromProviders, |
||||
'vnfInstanceIds': { |
||||
'type': 'array', |
||||
'items': common_types.Identifier |
||||
}, |
||||
'vnfInstanceNames': { |
||||
'type': 'array', |
||||
'items': {'type': 'string'} |
||||
} |
||||
}, |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 5.5.3.12 |
||||
_LifecycleChangeNotificationsFilter = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'vnfInstanceSubscriptionFilter': _VnfInstanceSubscriptionFilter, |
||||
'notificationTypes': { |
||||
'type': 'array', |
||||
'items': { |
||||
'type': 'string', |
||||
'enum': [ |
||||
'VnfLcmOperationOccurrenceNotification', |
||||
'VnfIdentifierCreationNotification', |
||||
'VnfIdentifierDeletionNotification'] |
||||
} |
||||
}, |
||||
'operationTypes': { |
||||
'type': 'array', |
||||
'items': { |
||||
'type': 'string', |
||||
'enum': [ |
||||
'INSTANTIATE', |
||||
'SCALE', |
||||
'SCALE_TO_LEVEL', |
||||
'CHANGE_FLAVOUR', |
||||
'TERMINATE', |
||||
'HEAL', |
||||
'OPERATE', |
||||
'CHANGE_EXT_CONN', |
||||
'MODIFY_INFO'] |
||||
} |
||||
}, |
||||
'operationStates': { |
||||
'type': 'array', |
||||
'items': { |
||||
'type': 'string', |
||||
'enum': [ |
||||
'STARTING', |
||||
'PROCESSING', |
||||
'COMPLETED', |
||||
'FAILED_TEMP', |
||||
'FAILED', |
||||
'ROLLING_BACK', |
||||
'ROLLED_BACK'] |
||||
} |
||||
} |
||||
}, |
||||
'additionalProperties': True, |
||||
} |
||||
|
||||
# SOL003 5.5.2.15 |
||||
LccnSubscriptionRequest_V200 = { |
||||
'type': 'object', |
||||
'properties': { |
||||
'filter': _LifecycleChangeNotificationsFilter, |
||||
'callbackUri': {'type': 'string', 'maxLength': 255}, |
||||
'authentication': _SubscriptionAuthentication, |
||||
'verbosity': { |
||||
'type': 'string', |
||||
'enum': ['FULL', 'SHORT'] |
||||
} |
||||
}, |
||||
'required': ['callbackUri'], |
||||
'additionalProperties': True, |
||||
} |
@ -0,0 +1,49 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone 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. |
||||
|
||||
|
||||
import functools |
||||
|
||||
from tacker.api.validation import validators |
||||
from tacker.common import exceptions as tacker_ex |
||||
|
||||
from tacker.sol_refactored.api import api_version |
||||
from tacker.sol_refactored.common import exceptions as sol_ex |
||||
|
||||
|
||||
class SolSchemaValidator(validators._SchemaValidator): |
||||
def validate(self, *args, **kwargs): |
||||
try: |
||||
super(SolSchemaValidator, self).validate(*args, **kwargs) |
||||
except tacker_ex.ValidationError as ex: |
||||
raise sol_ex.SolValidationError(detail=str(ex)) |
||||
|
||||
|
||||
def schema(request_body_schema, min_version, max_version=None): |
||||
|
||||