summaryrefslogtreecommitdiffstats
path: root/azure/aria/aria-extension-cloudify/src/aria/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'azure/aria/aria-extension-cloudify/src/aria/extensions')
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/__init__.py56
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml97
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/azure-plugin/azureplugin.yaml1981
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml121
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml322
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml268
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml28
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml107
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml525
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml71
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml158
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/tosca-simple-1.0.yaml24
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/artifacts.yaml84
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml70
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml318
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml260
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml43
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml21
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_nfv_v1_0/__init__.py19
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py43
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/__init__.py199
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/assignments.py453
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/data_types.py561
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/definitions.py518
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/filters.py107
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/misc.py444
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py750
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py44
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py220
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/constraints.py144
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/copy.py32
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py514
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py681
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py530
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py230
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py79
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py364
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py167
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/__init__.py14
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py33
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py37
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py588
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py63
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presenter.py83
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/templates.py736
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/types.py892
46 files changed, 13099 insertions, 0 deletions
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/__init__.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/__init__.py
new file mode 100644
index 0000000..ff4fa7d
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/__init__.py
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 os.path
+
+from aria import extension
+
+from .simple_v1_0 import ToscaSimplePresenter1_0
+from .simple_nfv_v1_0 import ToscaSimpleNfvPresenter1_0
+
+
+@extension.parser
+class ParserExtensions(object):
+
+ @staticmethod
+ def presenter_class():
+ return ToscaSimplePresenter1_0, ToscaSimpleNfvPresenter1_0
+
+ @staticmethod
+ def specification_package():
+ return 'aria_extension_tosca'
+
+ @staticmethod
+ def specification_url():
+ return {
+ 'yaml-1.1': 'http://yaml.org',
+ 'tosca-simple-1.0': 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/'
+ 'cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html',
+ 'tosca-simple-nfv-1.0': 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/'
+ 'tosca-nfv-v1.0.html'
+ }
+
+ @staticmethod
+ def uri_loader_prefix():
+ the_dir = os.path.dirname(__file__)
+ return os.path.join(the_dir, 'profiles')
+
+
+MODULES = (
+ 'simple_v1_0',
+ 'simple_nfv_v1_0')
+
+__all__ = (
+ 'MODULES',)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
new file mode 100644
index 0000000..e421150
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
@@ -0,0 +1,97 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+policy_types:
+
+ aria.Plugin:
+ _extensions:
+ shorthand_name: Plugin
+ type_qualified_name: aria:Plugin
+ role: plugin
+ description: >-
+ Policy used to specify plugins used by services. For an operation to be able to use a plugin
+ it must have a matching policy. The name of the policy must be the name of the plugin. The
+ optional properties can be used to further specify plugin selection by the orchestrator.
+ derived_from: tosca.policies.Root
+ properties:
+ version:
+ description: >-
+ Minimum plugin version.
+ type: version
+ required: false
+ enabled:
+ description: >-
+ If the policy is to disable the plugin then it will be ignored and all operations and
+ workflows depending on it will also be disabled.
+ type: boolean
+ default: true
+
+ aria.Workflow:
+ _extensions:
+ shorthand_name: Workflow
+ type_qualified_name: aria:Workflow
+ role: workflow
+ description: >-
+ Policy used to specify custom workflows. A workflow is usually a workload of interconnected
+ calls to operations on nodes and relationships in the service topology. The name of the policy
+ is used as the name of the workflow. Note that it can be the same name as one of the normative
+ lifecycle workflows ("install", "uninstall", etc.), in which case it would be considered an
+ override of the default behavior. If the workflow requires parameters then this base type
+ should be inherited and extended with additional properties.
+ derived_from: tosca.policies.Root
+ properties:
+ implementation:
+ description: >-
+ The interpretation of the implementation string depends on the orchestrator. In ARIA it is
+ the full path to a Python @workflow function that generates a task graph based on the
+ service topology.
+ type: string
+
+ aria.Scaling:
+ _extensions:
+ type_qualified_name: aria:Scaling
+ role: scaling
+ description: >-
+ Scaling.
+ derived_from: tosca.policies.Scaling
+ properties:
+ min_instances:
+ description: >-
+ This property is used to indicate the minimum number of instances that should be created
+ for the associated TOSCA Node Template by a TOSCA orchestrator.
+ type: integer
+ default: 1
+ constraints:
+ - greater_or_equal: 0
+ max_instances:
+ description: >-
+ This property is used to indicate the maximum number of instances that should be created
+ for the associated TOSCA Node Template by a TOSCA orchestrator.
+ type: integer
+ default: 1
+ constraints:
+ - greater_or_equal: 0
+ default_instances:
+ description: >-
+ An optional property that indicates the requested default number of instances that should
+ be the starting number of instances a TOSCA orchestrator should attempt to allocate. Note:
+ The value for this property MUST be in the range between the values set for
+ "min_instances" and "max_instances" properties.
+ type: integer
+ constraints:
+ - greater_or_equal: 0
+ required: false
+ targets:
+ - tosca.nodes.Root
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/azure-plugin/azureplugin.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/azure-plugin/azureplugin.yaml
new file mode 100644
index 0000000..77b61b5
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/azure-plugin/azureplugin.yaml
@@ -0,0 +1,1981 @@
+#
+# Copyright (c) 2017 GigaSpaces Technologies Ltd. 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.
+#
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+
+topology_template:
+ policies:
+ cloudify-azure-plugin:
+ description: >-
+ azure plugin executes operations.
+ type: aria.Plugin
+ properties:
+ version: 1.4.2
+
+
+data_types:
+
+ aria.azure.datatypes.Config:
+ description: >-
+ azure configuration
+ properties:
+ subscription_id:
+ description: >
+ A Microsoft Azure subscription ID. This is a unique
+ user account in Azure. This can be found in the
+ Subscriptions tab on your dashboard.
+ type: string
+ required: false
+ tenant_id:
+ description: >
+ A Microsoft Azure tenant ID. This can be found in
+ the Azure Active Directory dashboard by accessing
+ your directory. Open the Application Endpoints
+ dialog and your tenant ID will be in the URL for
+ the OAUTH2.0 TOKEN ENDPOINT.
+ type: string
+ required: false
+ client_id:
+ description: >
+ A Microsoft Azure client ID. This can be found in
+ the Azure Active Directory dashboard by accessing
+ your directory. View the Applications tab and select
+ the application used to access Azure APIs. Your
+ client ID can be found by expanding the ACCESS WEB
+ APIS IN OTHER APPLICATIONS tab.
+ type: string
+ required: false
+ client_secret:
+ description: >
+ A Microsoft Azure client secret key. This can be found
+ or generated in the same location as your client ID.
+ type: string
+ required: false
+ scale_name_separator:
+ description: >
+ When scaling resources, a unique name must be sent to
+ the Azure API. Since names are left to the user to
+ manage (the service does not generate unique IDs),
+ this plugin will attempt to append characters or
+ numbers to the end of the resource name when resources
+ are scaled out. This value should be a character, or
+ characters, that will separate the base name from the
+ generated unique characters. For instance, if the
+ base name of a resource is "myvm", the separator is
+ set to "_", and a scale workflow attempts to create
+ another resource, the resulting name could be
+ something like "myvm_1". This field can be left blank.
+ type: string
+ required: false
+ default: "_"
+ scale_name_suffix_chars:
+ description: >
+ A string of characters (ASCII) to be used when
+ generating unique suffix data when scaling resources.
+ See "scale_name_separator" for more information.
+ type: string
+ required: true
+ default: "1234567890"
+
+ aria.azure.datatypes.AgentConfig:
+ properties:
+ install_method:
+ type: string
+ required: false
+ port:
+ type: integer
+ required: false
+
+
+ aria.azure.datatypes.StorageAccountConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163564.aspx
+ properties:
+ accountType:
+ description: >
+ An storage account type (case sensitive)
+ type: string
+ default: Standard_LRS
+ required: true
+
+ aria.azure.datatypes.DataDiskConfig:
+ properties:
+ container_name:
+ type: string
+ description: >
+ Container for the resource.
+ default: vhds
+ size:
+ description: >
+ Size of the Page Blob (Azure disk) in GiB. Maximum of 1023 GiB allowed.
+ type: integer
+ default: 20
+ required: true
+ force_delete:
+ description: >
+ If set to true, the resource's "delete" lifecycle will purge the
+ Azure Data Disk from the Azure Storage Account. If false, the
+ Data Disk is left as-is in the Storage Account.
+ type: boolean
+ default: false
+
+
+ aria.azure.datatypes.FileShareConfig:
+ properties:
+ metadata:
+ description: >
+ Metadata (dict) for the File Share
+ required: false
+ type: string
+ quota:
+ description: >
+ Quote, in GiB, for the maximum size of the file share
+ required: false
+ type: integer
+ fail_on_exist:
+ description: >
+ If true, causes the operation to raise a NonRecoverableError if
+ the file share already exists. If false, issues a warning and
+ continues execution.
+ default: false
+ type: boolean
+
+ aria.azure.datatypes.AddressSpace:
+ description: >
+ Contains the address prefix,typically network CIDR
+ properties:
+ addressPrefixes:
+ required: true
+ type: list
+ entry_schema: string
+
+ aria.azure.datatypes.VirtualNetworkConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163661.aspx
+ properties:
+ addressSpace:
+ default:
+ addressPrefixes:
+ - 172.16.0.0/16
+ required: true
+ type: aria.azure.datatypes.AddressSpace
+ dhcpOptions:
+ required: false
+ type: string
+ subnets:
+ required: false
+ type: string
+
+ aria.azure.datatypes.NetworkSecurityGroupConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163656.aspx
+ properties:
+ securityRules:
+ required: false
+ type: list
+ entry_schema: string
+
+
+
+ aria.azure.datatypes.NetworkSecurityRuleConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163645.aspx
+ properties:
+ description:
+ type: string
+ required: false
+ protocol:
+ type: string
+ required: true
+ sourcePortRange:
+ type: string
+ required: false
+ destinationPortRange:
+ type: string
+ required: false
+ sourceAddressPrefix:
+ type: string
+ required: true
+ destinationAddressPrefix:
+ type: string
+ required: true
+ access:
+ type: string
+ required: true
+ priority:
+ type: integer
+ required: true
+ direction:
+ type: string
+ required: true
+
+ aria.azure.datatypes.SubnetConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163621.aspx
+ properties:
+ addressPrefix:
+ type: string
+ required: false
+ networkSecurityGroup:
+ type: string
+ required: false
+ routeTable:
+ type: string
+ required: false
+
+
+
+
+
+
+
+ aria.azure.datatypes.RouteTableConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt502548.aspx
+ properties:
+ routes:
+ type: string
+ required: false
+
+
+ aria.azure.datatypes.RouteConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt459110.aspx
+ properties:
+ addressPrefix:
+ type: string
+ required: true
+ nextHopType:
+ type: string
+ required: true
+ nextHopIpAddress:
+ type: string
+ required: false
+
+
+ aria.azure.datatype.NetworkInterfaceDnsSettings:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163668.aspx
+ properties:
+ appliedDnsServers:
+ type: list
+ entry_schema: string
+ required: false
+ dnsServers:
+ type: list
+ entry_schema: string
+ required: false
+ internalDnsNameLabel:
+ type: string
+ required: false
+ internalDomainNameSuffix:
+ type: string
+ required: false
+ internalFqdn:
+ type: string
+ required: false
+
+
+ aria.azure.datatypes.NetworkInterfaceCardConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163668.aspx
+ properties:
+ networkSecurityGroups:
+ required: false
+ type: string
+ enableIPForwarding:
+ required: false
+ type: boolean
+ ipConfigurations:
+ required: false
+ type: string
+ dnsSettings:
+ required: false
+ type: aria.azure.datatype.NetworkInterfaceDnsSettings
+
+
+ aria.azure.datatypes.IPConfigurationConfig:
+ properties:
+ privateIPAddress:
+ type: string
+ description: >
+ Static, private IP Address
+ required: false
+ privateIPAllocationMethod:
+ type: string
+ description: >
+ Defines how a private IP address is assigned. Options
+ are Static or Dynamic
+ required: true
+ privateIPAddressVersion:
+ type: string
+ description: >
+ Define the version of the IP protocol
+ required: false
+
+
+ aria.azure.datatypes.PublicIPAddressDnsSettings:
+ description: >
+ See https://docs.microsoft.com/en-gb/rest/api/virtualnetwork/PublicIPAddresses/CreateOrUpdate#definitions_publicipaddressdnssettings
+ properties:
+ domainNameLabel:
+ type: string
+ description: >
+ name refer to the VM
+ required: false
+ fqdn:
+ type: string
+ required: false
+ reverseFqdn:
+ type: string
+ required: false
+
+ aria.azure.datatypes.PublicIPAddressConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163590.aspx
+ properties:
+ publicIPAllocationMethod:
+ type: string
+ description: >
+ Defines whether the IP address is stable or dynamic.
+ Options are Static or Dynamic
+ required: true
+ publicIPAddressVersion:
+ type: string
+ description:
+ Define the version of the public IP.
+ required: false
+ idleTimeoutInMinutes:
+ type: integer
+ description: >
+ Specifies the timeout (in minutes) for the TCP idle connection.
+ The value can be set between 4 and 30 minutes
+ required: false
+ dnsSettings:
+ type: aria.azure.datatypes.PublicIPAddressDnsSettings
+ required: false
+# domainNameLabel:
+# type: string
+# description: >
+# The concatenation of the domain name label and the regionalized
+# DNS zone make up the fully qualified domain name associated
+# with the public IP address.
+# required: false
+# reverseFqdn:
+# type: string
+# description: >
+# A fully qualified domain name that resolves to this
+# public IP address.
+# required: false
+
+
+
+
+
+
+ aria.azure.datatypes.AvailabilitySetConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163607.aspx
+ properties:
+ platformUpdateDomainCount:
+ type: integer
+ required: false
+ platformFaultDomainCount:
+ type: integer
+ required: false
+
+
+
+ aria.azure.datatypes.HardwareProfile:
+ properties:
+ vmSize:
+ required: true
+ type: string
+
+
+ aria.azure.datatypes.ImageReference:
+ properties:
+ publisher:
+ required: true
+ type: string
+ offer:
+ required: true
+ type: string
+ sku:
+ required: true
+ type: string
+ version:
+ required: true
+ type: string
+
+
+ aria.azure.datatypes.StorageProfile:
+ properties:
+ imageReference:
+ required: true
+ type: aria.azure.datatypes.ImageReference
+
+
+
+
+ aria.azure.datatypes.PublicKey:
+ properties:
+ keydata:
+ required: true
+ type: string
+ path:
+ required: true
+ type: string
+
+ aria.azure.datatypes.SSH:
+ properties:
+ publicKeys:
+ required: false
+ type: list
+ entry_schema: aria.azure.datatypes.PublicKey
+
+
+ aria.azure.datatypes.LinuxConfiguration:
+ properties:
+ ssh:
+ required: false
+ type: aria.azure.datatypes.SSH
+ disablePasswordAuthentication:
+ required: false
+ default: true
+ type: boolean
+
+
+ aria.azure.datatypes.OSProfile:
+ properties:
+ computerName:
+ required: true
+ type: string
+ adminUserName:
+ required: true
+ type: string
+ adminPassword:
+ required: true
+ type: string
+ linuxConfiguration:
+ required: false
+ type: aria.azure.datatypes.LinuxConfiguration
+
+
+
+ aria.azure.datatypes.VirtualMachineConfig:
+ description: >
+ https://msdn.microsoft.com/en-us/library/azure/mt163591.aspx
+ properties:
+ hardwareProfile:
+ required: true
+ type: aria.azure.datatypes.HardwareProfile
+ storageProfile:
+ required: true
+ type: aria.azure.datatypes.StorageProfile
+ osProfile:
+ required: true
+ type: aria.azure.datatypes.OSProfile
+
+ aria.azure.datatypes.LoadBalancerConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163574.aspx
+ properties:
+ frontendIPConfigurations:
+ required: false
+ type: string
+ backendAddressPools:
+ required: false
+ type: string
+ loadBalancingRules:
+ required: false
+ type: string
+ probes:
+ required: false
+ type: string
+ inboundNatRules:
+ required: false
+ type: string
+
+
+
+ aria.azure.datatypes.LoadBalancerProbeConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163574.aspx
+ properties:
+ protocol:
+ type: string
+ default: Tcp
+ required: true
+ port:
+ type: integer
+ required: true
+ requestPath:
+ type: string
+ required: false
+ intervalInSeconds:
+ type: integer
+ default: 5
+ required: true
+ numberOfProbes:
+ type: integer
+ default: 16
+ required: true
+
+ aria.azure.datatypes.LoadBalancerIncomingNATRuleConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163574.aspx
+ properties:
+ protocol:
+ type: string
+ default: Tcp
+ required: true
+ frontendPort:
+ type: integer
+ required: true
+ backendPort:
+ type: integer
+ required: true
+
+
+ aria.azure.datatypes.LoadBalancerRuleConfig:
+ description: >
+ See https://msdn.microsoft.com/en-us/library/mt163574.aspx
+ properties:
+ protocol:
+ type: string
+ default: Tcp
+ required: true
+ frontendPort:
+ type: integer
+ required: true
+ backendPort:
+ type: integer
+ required: true
+ enableFloatingIP:
+ type: boolean
+ required: false
+ default: false
+ idleTimeoutInMinutes:
+ type: integer
+ required: false
+ default: 5
+ loadDistribution:
+ type: string
+ required: false
+ default: Default
+
+
+
+
+
+interface_types:
+
+ aria.azure.interfaces.validation:
+ derived_from: tosca.interfaces.Root
+ creation:
+ description: >-
+ creation operation for the openstack validation interface
+ deletion:
+ description: >-
+ deletion operation for the openstack validation interface
+ aria.azure.interfaces.network:
+ derived_from: tosca.interfaces.Root
+ preconfigure:
+ establish:
+ unlink:
+
+node_types:
+
+ aria.azure.nodes.ResourceGroup:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource. Resource group name must be no longer than
+ 80 characters long. It can contain only alphanumeric characters,
+ dash, underscore, opening parenthesis, closing parenthesis,
+ and period. The name cannot end with a period.
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.resourcegroup.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.resourcegroup.delete
+
+
+
+
+
+
+
+ aria.azure.nodes.storage.StorageAccount:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource. Storage account name must be between
+ 3 and 24 characters in length and use numbers and lower-case
+ letters only.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.StorageAccountConfig
+ required: true
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.storage.storageaccount.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.storage.storageaccount.delete
+ requirements:
+ - resource_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.ResourceGroup
+ relationship: cloudify.azure.relationships.contained_in_resource_group
+ occurrences: [ 0, UNBOUNDED ]
+
+
+
+ aria.azure.nodes.storage.DataDisk:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource (include any extension, such as .vhd).
+ Can be up to 80 characters in length and
+ contain lowercase letters, numbers, ".", and "_". Must start
+ with a number or lowercase letter and cannot end with
+ either "_" or "."
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.DataDiskConfig
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.storage.disk.create_data_disk
+ delete: cloudify-azure-plugin > cloudify_azure.resources.storage.disk.delete_data_disk
+ requirements:
+ - storage_account:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.storage.StorageAccount
+ relationship: cloudify.azure.relationships.contained_in_storage_account
+ occurrences: [ 0, UNBOUNDED ]
+
+ aria.azure.nodes.storage.FileShare:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource. Can be up to 63 characters in length and
+ contain lowercase letters, numbers, and dashes. Must start
+ with a number or lowercase letter and cannot contain
+ two consecutive dashes.
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.FileShareConfig
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.storage.file.create_file_share
+
+
+
+
+ aria.azure.nodes.network.VirtualNetwork:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.VirtualNetworkConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.virtualnetwork.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.virtualnetwork.delete
+ requirements:
+ - resource_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.ResourceGroup
+ relationship: cloudify.azure.relationships.contained_in_resource_group
+ occurrences: [ 0, UNBOUNDED ]
+ - storage_account:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.storage.StorageAccount
+ relationship: cloudify.azure.relationships.virtual_network_depends_on_storage
+ occurrences: [ 0, UNBOUNDED ]
+
+
+
+ aria.azure.nodes.network.NetworkSecurityGroup:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.NetworkSecurityGroupConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.networksecuritygroup.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.networksecuritygroup.delete
+ requirements:
+ - resource_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.ResourceGroup
+ relationship: cloudify.azure.relationships.contained_in_resource_group
+ occurrences: [ 0, UNBOUNDED ]
+
+
+
+ aria.azure.nodes.network.NetworkSecurityRule:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ network_security_group_name:
+ type: string
+ description: >
+ Name of the Network Security Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Network Security Groupnode)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.NetworkSecurityRuleConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.networksecurityrule.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.networksecurityrule.delete
+ requirements:
+ - resource_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.ResourceGroup
+ relationship: cloudify.azure.relationships.contained_in_resource_group
+ occurrences: [ 0, UNBOUNDED ]
+ - network_security_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.NetworkSecurityGroup
+ relationship: cloudify.azure.relationships.nic_connected_to_network_security_group
+ occurrences: [ 0, UNBOUNDED ]
+
+
+
+ aria.azure.nodes.network.Subnet:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ virtual_network_name:
+ type: string
+ description: >
+ Name of the Virtual Network that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Virtual Network node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.SubnetConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.subnet.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.subnet.delete
+ requirements:
+ - virtual_network:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.VirtualNetwork
+ relationship: cloudify.azure.relationships.contained_in_virtual_network
+ occurrences: [ 0, UNBOUNDED ]
+ - subnet_dependency:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.Subnet
+ relationship: cloudify.azure.relationships.depends_on_subnet
+ occurrences: [ 0, UNBOUNDED ]
+
+
+
+ aria.azure.nodes.network.RouteTable:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.RouteTableConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.routetable.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.routetable.delete
+ requirements:
+ - virtual_subnet:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.Subnet
+ relationship: cloudify.azure.relationships.route_table_attached_to_subnet
+ occurrences: [ 0, UNBOUNDED ]
+
+ aria.azure.nodes.network.Route:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ route_table_name:
+ type: string
+ description: >
+ Name of the Network Security Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Virtual Network node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.RouteConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.route.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.route.delete
+ requirements:
+ - route_table:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.RouteTable
+ relationship: cloudify.azure.relationships.depends_on_route_table
+ occurrences: [ 0, UNBOUNDED ]
+
+
+ aria.azure.nodes.network.NetworkInterfaceCard:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ primary:
+ description: >
+ When using multiple Network Interfaces, a primary must be set
+ required: false
+ default: false
+ type: boolean
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.NetworkInterfaceCardConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.networkinterfacecard.create
+ configure: cloudify-azure-plugin > cloudify_azure.resources.network.networkinterfacecard.configure
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.networkinterfacecard.delete
+ requirements:
+ - resource_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.ResourceGroup
+ relationship: cloudify.azure.relationships.contained_in_resource_group
+ occurrences: [ 0, UNBOUNDED ]
+ - ip_config:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.IPConfiguration
+ relationship: cloudify.azure.relationships.nic_connected_to_ip_configuration
+ occurrences: [ 0, UNBOUNDED ]
+ - security_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.NetworkSecurityGroup
+ relationship: cloudify.azure.relationships.nic_connected_to_network_security_group
+ occurrences: [ 0, UNBOUNDED ]
+
+
+
+ aria.azure.nodes.network.IPConfiguration:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.IPConfigurationConfig
+ required: true
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ requirements:
+ - subnet:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.Subnet
+ relationship: cloudify.azure.relationships.ip_configuration_connected_to_subnet
+ occurrences: [ 0, UNBOUNDED ]
+ - ipaddress:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.PublicIPAddress
+ relationship: cloudify.azure.relationships.ip_configuration_connected_to_public_ip
+ occurrences: [ 0, UNBOUNDED ]
+ occurrences: [ 0, UNBOUNDED ]
+
+ aria.azure.nodes.network.PublicIPAddress:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.PublicIPAddressConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.publicipaddress.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.publicipaddress.delete
+ requirements:
+ - resource_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.ResourceGroup
+ relationship: cloudify.azure.relationships.contained_in_resource_group
+ occurrences: [ 0, UNBOUNDED ]
+
+ aria.azure.nodes.compute.AvailabilitySet:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.AvailabilitySetConfig
+ required: true
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.compute.availabilityset.create
+ delete: cloudify-azure-plugin > cloudify_azure.resources.compute.availabilityset.delete
+
+
+ aria.azure.nodes.compute.VirtualMachine:
+ derived_from: tosca.nodes.Compute
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ use_public_ip:
+ type: boolean
+ description: >
+ Tells the deployment to use the public IP (if available) of the resource
+ for Cloudify Agent connections
+ default: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ plan:
+ description: >
+ Specifies information about the marketplace image used to create the virtual
+ machine. This element is only used for marketplace images.
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.VirtualMachineConfig
+ required: true
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ ip:
+ description: |
+ Property specifying the IP address of the resource to
+ use for the agent installer.
+ type: string
+ required: false
+ os_family:
+ description: |
+ Property specifying what type of operating system family
+ this compute node will run.
+ default: windows
+ type: string
+ agent_config:
+ type: aria.azure.datatypes.AgentConfig
+ default:
+ install_method: remote
+ port: 5985
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.compute.virtualmachine.create
+# configure:
+# implementation: cloudify-azure-plugin > cloudify_azure.resources.compute.virtualmachine.configure
+# inputs:
+# command_to_execute:
+# description: >
+# This is the command that the CustomScriptExtension extension will
+# execute. The file_uris below will be downloaded and this property
+# should specify a command to start the execution of one of them.
+# default: powershell -ExecutionPolicy Unrestricted -file ps_enable_winrm_http.ps1
+# file_uris:
+# default:
+# - https://raw.githubusercontent.com/cloudify-cosmo/cloudify-azure-plugin/1.4/scripts/ps_enable_winrm_http.ps1
+ delete: cloudify-azure-plugin > cloudify_azure.resources.compute.virtualmachine.delete
+ requirements:
+ - resource_group:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.ResourceGroup
+ relationship: cloudify.azure.relationships.contained_in_resource_group
+ occurrences: [ 0, UNBOUNDED ]
+ - nic:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.network.NetworkInterfaceCard
+ relationship: cloudify.azure.relationships.connected_to_nic
+ occurrences: [ 0, UNBOUNDED ]
+ - storage_account:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.storage.StorageAccount
+ relationship: cloudify.azure.relationships.connected_to_storage_account
+ - data_disk:
+ capability: tosca.capabilities.Node
+ node: aria.azure.nodes.storage.DataDisk
+ relationship: cloudify.azure.relationships.vm_connected_to_datadisk
+ occurrences: [ 0, UNBOUNDED ]
+
+
+
+ aria.azure.nodes.network.LoadBalancer:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.LoadBalancerConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.create
+ configure: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.configure
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.delete
+
+
+
+
+ aria.azure.nodes.network.LoadBalancer.BackendAddressPool:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ load_balancer_name:
+ type: string
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.create_backend_pool
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.delete_backend_pool
+
+
+
+ aria.azure.nodes.network.LoadBalancer.Probe:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ load_balancer_name:
+ type: string
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.LoadBalancerProbeConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.create_probe
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.delete_probe
+
+
+ aria.azure.nodes.network.LoadBalancer.IncomingNATRule:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ load_balancer_name:
+ type: string
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.LoadBalancerIncomingNATRuleConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.create_incoming_nat_rule
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.delete_incoming_nat_rule
+
+
+
+ aria.azure.nodes.network.LoadBalancer.Rule:
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ type: string
+ description: >
+ Name for the resource.
+ required: false
+ resource_group_name:
+ type: string
+ description: >
+ Name of the Resource Group that the existing resource belongs to
+ (this is only useful when not using a relationship between a resource
+ node and a Resource Group node)
+ required: false
+ load_balancer_name:
+ type: string
+ required: false
+ location:
+ type: string
+ description: >
+ Specifies the supported Azure location for the resource
+ required: false
+ tags:
+ description: >
+ Specifies a dictionary of one or more name and value pairs that describe a tag
+ required: false
+ type: string
+ resource_config:
+ description: >
+ A dictionary of values to pass as properties when creating the resource
+ type: aria.azure.datatypes.LoadBalancerRuleConfig
+ required: false
+ use_external_resource:
+ description: >
+ Indicate whether the resource exists or if Cloudify should create the resource
+ type: boolean
+ default: false
+ required: true
+ retry_after:
+ description: >
+ Overrides the Azure-specified "retry_after" response. This property
+ will set the number of seconds for each task retry interval (in the
+ case of iteratively checking the status of an asynchronous operation)
+ type: integer
+ required: false
+ azure_config:
+ description: >
+ A dictionary of values to pass to authenticate with the Azure API
+ type: aria.azure.datatypes.Config
+ required: false
+ interfaces:
+ Standard:
+ create: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.create_rule
+ delete: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.delete_rule
+
+
+
+
+
+relationship_types:
+ cloudify.azure.relationships.contained_in_resource_group:
+ derived_from: tosca.relationships.HostedOn
+
+ cloudify.azure.relationships.contained_in_storage_account:
+ derived_from: tosca.relationships.HostedOn
+
+ cloudify.azure.relationships.contained_in_virtual_network:
+ derived_from: tosca.relationships.HostedOn
+
+ cloudify.azure.relationships.contained_in_network_security_group:
+ derived_from: tosca.relationships.HostedOn
+
+ cloudify.azure.relationships.contained_in_route_table:
+ derived_from: tosca.relationships.HostedOn
+
+ cloudify.azure.relationships.contained_in_load_balancer:
+ derived_from: tosca.relationships.HostedOn
+
+ cloudify.azure.relationships.depends_on_route_table:
+ derived_from: tosca.relationships.DependsOn
+
+ cloudify.azure.relationships.depends_on_subnet:
+ derived_from: tosca.relationships.DependsOn
+
+ cloudify.azure.relationships.virtual_network_depends_on_storage:
+ derived_from: tosca.relationships.DependsOn
+
+ cloudify.azure.relationships.network_security_group_attached_to_subnet:
+ derived_from: tosca.relationships.ConnectsTo
+ interfaces:
+ Configure:
+ add_source: cloudify-azure-plugin > cloudify_azure.resources.network.subnet.attach_network_security_group
+ remove_source: cloudify-azure-plugin > cloudify_azure.resources.network.subnet.detach_network_security_group
+
+ cloudify.azure.relationships.route_table_attached_to_subnet:
+ derived_from: tosca.relationships.ConnectsTo
+ interfaces:
+ Configure:
+ add_source: cloudify-azure-plugin > cloudify_azure.resources.network.subnet.attach_route_table
+ remove_source: cloudify-azure-plugin > cloudify_azure.resources.network.subnet.detach_route_table
+
+ cloudify.azure.relationships.nic_connected_to_network_security_group:
+ derived_from: tosca.relationships.ConnectsTo
+
+ cloudify.azure.relationships.nic_connected_to_ip_configuration:
+ derived_from: tosca.relationships.ConnectsTo
+ interfaces:
+ Configure:
+ pre_configure_source: cloudify-azure-plugin > cloudify_azure.resources.network.networkinterfacecard.attach_ip_configuration
+
+ cloudify.azure.relationships.lb_connected_to_ip_configuration:
+ derived_from: tosca.relationships.ConnectsTo
+ interfaces:
+ Configure:
+ preconfigure: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.attach_ip_configuration
+
+ cloudify.azure.relationships.ip_configuration_connected_to_subnet:
+ derived_from: tosca.relationships.ConnectsTo
+
+ cloudify.azure.relationships.ip_configuration_connected_to_public_ip:
+ derived_from: tosca.relationships.ConnectsTo
+
+ cloudify.azure.relationships.connected_to_storage_account:
+ derived_from: tosca.relationships.ConnectsTo
+
+ cloudify.azure.relationships.connected_to_data_disk:
+ derived_from: tosca.relationships.ConnectsTo
+ interfaces:
+ Configure:
+ add_target: cloudify-azure-plugin > cloudify_azure.resources.compute.virtualmachine.attach_disk
+ remove_target: cloudify-azure-plugin > cloudify_azure.resources.compute.virtualmachine.detach_disk
+
+
+ cloudify.azure.relationships.connected_to_nic:
+ derived_from: tosca.relationships.ConnectsTo
+
+
+ cloudify.azure.relationships.connected_to_availability_set:
+ derived_from: tosca.relationships.ConnectsTo
+
+ cloudify.azure.relationships.connected_to_ip_configuration:
+ derived_from: tosca.relationships.ConnectsTo
+
+ cloudify.azure.relationships.connected_to_lb_be_pool:
+ derived_from: tosca.relationships.ConnectsTo
+
+ cloudify.azure.relationships.connected_to_lb_probe:
+ derived_from: tosca.relationships.ConnectsTo
+
+ cloudify.azure.relationships.vmx_contained_in_vm:
+ derived_from: tosca.relationships.HostedOn
+
+ cloudify.azure.relationships.nic_connected_to_lb_be_pool:
+ derived_from: tosca.relationships.ConnectsTo
+ interfaces:
+ Configure:
+ add_target: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.attach_nic_to_backend_pool
+ remove_target: cloudify-azure-plugin > cloudify_azure.resources.network.loadbalancer.detach_nic_from_backend_pool
+
+ cloudify.azure.relationships.vm_connected_to_datadisk:
+ derived_from: tosca.relationships.ConnectsTo
+ interfaces:
+ Configure:
+ add_target:
+ implementation: cloudify-azure-plugin > cloudify_azure.resources.compute.virtualmachine.attach_data_disk
+ inputs:
+ lun:
+ description: >
+ Specifies the logical unit number of the data disk in the VM
+ default: 0
+ required: true
+ type: integer
+ remove_target: cloudify-azure-plugin > cloudify_azure.resources.compute.virtualmachine.detach_data_disk
+
+
+
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml
new file mode 100644
index 0000000..945622f
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml
@@ -0,0 +1,121 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+artifact_types:
+
+ tosca.artifacts.Root:
+ _extensions:
+ shorthand_name: Root # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Root
+ specification: tosca-simple-1.0
+ specification_section: 5.3.1
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_ARTIFACTS_ROOT'
+ description: >-
+ This is the default (root) TOSCA Artifact Type definition that all other TOSCA base Artifact Types derive from.
+
+ tosca.artifacts.File:
+ _extensions:
+ shorthand_name: File
+ type_qualified_name: tosca:File
+ specification: tosca-simple-1.0
+ specification_section: 5.3.2
+ description: >-
+ This artifact type is used when an artifact definition needs to have its associated file simply treated as a file and no special handling/handlers are invoked (i.e., it is not treated as either an implementation or deployment artifact type).
+ derived_from: tosca.artifacts.Root
+
+ #
+ # Deployments
+ #
+
+ tosca.artifacts.Deployment:
+ _extensions:
+ shorthand_name: Deployment # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Deployment
+ specification: tosca-simple-1.0
+ specification_section: 5.3.3.1
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_ARTIFACTS_DEPLOYMENT'
+ description: >-
+ This artifact type represents the parent type for all deployment artifacts in TOSCA. This class of artifacts typically
+ represents a binary packaging of an application or service that is used to install/create or deploy it as part of a node's
+ lifecycle.
+ derived_from: tosca.artifacts.Root
+
+ tosca.artifacts.Deployment.Image:
+ _extensions:
+ shorthand_name: Deployment.Image
+ type_qualified_name: tosca:Deployment.Image
+ specification: tosca-simple-1.0
+ specification_section: 5.3.3.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_ARTIFACTS_DEPLOYMENT_IMAGE'
+ description: >-
+ This artifact type represents a parent type for any "image" which is an opaque packaging of a TOSCA Node's deployment
+ (whether real or virtual) whose contents are typically already installed and pre-configured (i.e., "stateful") and prepared
+ to be run on a known target container.
+ derived_from: tosca.artifacts.Deployment
+
+ tosca.artifacts.Deployment.Image.VM:
+ _extensions:
+ shorthand_name: Deployment.VM # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Deployment.VM
+ specification: tosca-simple-1.0
+ specification_section: 5.3.3.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_ARTIFACTS_DEPLOY_IMAGE_VM'
+ description: >-
+ This artifact represents the parent type for all Virtual Machine (VM) image and container formatted deployment artifacts.
+ These images contain a stateful capture of a machine (e.g., server) including operating system and installed software along
+ with any configurations and can be run on another machine using a hypervisor which virtualizes typical server (i.e.,
+ hardware) resources.
+ derived_from: tosca.artifacts.Deployment
+
+ #
+ # Implementations
+ #
+
+ tosca.artifacts.Implementation:
+ _extensions:
+ shorthand_name: Implementation # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Implementation
+ specification: tosca-simple-1.0
+ specification_section: 5.3.4.1
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_ARTIFACTS_IMPLEMENTATION'
+ description: >-
+ This artifact type represents the parent type for all implementation artifacts in TOSCA. These artifacts are used to
+ implement operations of TOSCA interfaces either directly (e.g., scripts) or indirectly (e.g., config. files).
+ derived_from: tosca.artifacts.Root
+
+ tosca.artifacts.Implementation.Bash:
+ _extensions:
+ shorthand_name: Implementation.Bash # ARIA NOTE: mistake in spec? shouldn't we have "Implementation." as prefix?
+ type_qualified_name: tosca:Implementation.Bash
+ specification: tosca-simple-1.0
+ specification_section: 5.3.4.3
+ description: >-
+ This artifact type represents a Bash script type that contains Bash commands that can be executed on the Unix Bash shell.
+ derived_from: tosca.artifacts.Implementation
+ mime_type: application/x-sh
+ file_ext: [ sh ]
+
+ tosca.artifacts.Implementation.Python:
+ _extensions:
+ shorthand_name: Implementation.Python # ARIA NOTE: mistake in spec? shouldn't we have "Implementation." as prefix?
+ type_qualified_name: tosca:Implementation.Python
+ specification: tosca-simple-1.0
+ specification_section: 5.3.4.4
+ description: >-
+ This artifact type represents a Python file that contains Python language constructs that can be executed within a Python
+ interpreter.
+ derived_from: tosca.artifacts.Implementation
+ mime_type: application/x-python
+ file_ext: [ py ]
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
new file mode 100644
index 0000000..66a4046
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
@@ -0,0 +1,322 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+capability_types:
+
+ tosca.capabilities.Root:
+ _extensions:
+ shorthand_name: Root # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Root
+ specification: tosca-simple-1.0
+ specification_section: 5.4.1
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_ROOT'
+ description: >-
+ This is the default (root) TOSCA Capability Type definition that all other TOSCA Capability Types derive from.
+
+ tosca.capabilities.Node:
+ _extensions:
+ shorthand_name: Node
+ type_qualified_name: tosca:Node
+ specification: tosca-simple-1.0
+ specification_section: 5.4.2
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_NODE'
+ role: feature
+ description: >-
+ The Node capability indicates the base capabilities of a TOSCA Node Type.
+ derived_from: tosca.capabilities.Root
+
+ tosca.capabilities.Container:
+ _extensions:
+ shorthand_name: Container
+ type_qualified_name: tosca:Container
+ specification: tosca-simple-1.0
+ specification_section: 5.4.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_CONTAINER'
+ role: host
+ description: >-
+ The Container capability, when included on a Node Type or Template definition, indicates that the node can act as a container
+ for (or a host for) one or more other declared Node Types.
+ derived_from: tosca.capabilities.Root
+ properties:
+ num_cpus:
+ description: >-
+ Number of (actual or virtual) CPUs associated with the Compute node.
+ type: integer
+ constraints:
+ - greater_or_equal: 1
+ required: false
+ cpu_frequency:
+ description: >-
+ Specifies the operating frequency of CPU's core. This property expresses the expected frequency of one (1) CPU as
+ provided by the property "num_cpus".
+ type: scalar-unit.frequency
+ constraints:
+ - greater_or_equal: 0.1 GHz
+ required: false
+ disk_size:
+ description: >-
+ Size of the local disk available to applications running on the Compute node (default unit is MB).
+ type: scalar-unit.size
+ constraints:
+ - greater_or_equal: 0 MB
+ required: false
+ mem_size:
+ description: >-
+ Size of memory available to applications running on the Compute node (default unit is MB).
+ type: scalar-unit.size
+ constraints:
+ - greater_or_equal: 0 MB
+ required: false
+
+ tosca.capabilities.Attachment:
+ _extensions:
+ shorthand_name: Attachment
+ type_qualified_name: tosca:Attachment
+ specification: tosca-simple-1.0
+ specification_section: 5.4.8
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_ATTACHMENT'
+ description: >-
+ This is the default TOSCA type that should be used or extended to define an attachment capability of a (logical)
+ infrastructure device node (e.g., BlockStorage node).
+ derived_from: tosca.capabilities.Root
+
+ tosca.capabilities.OperatingSystem:
+ _extensions:
+ shorthand_name: OperatingSystem
+ type_qualified_name: tosca:OperatingSystem
+ specification: tosca-simple-1.0
+ specification_section: 5.4.9
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_OPSYS'
+ description: >-
+ This is the default TOSCA type that should be used to express an Operating System capability for a node.
+ derived_from: tosca.capabilities.Root
+ properties:
+ architecture:
+ description: >-
+ The Operating System (OS) architecture. Examples of valid values include: x86_32, x86_64, etc.
+ type: string
+ required: false
+ type:
+ description: >-
+ The Operating System (OS) type. Examples of valid values include: linux, aix, mac, windows, etc.
+ type: string
+ required: false
+ distribution:
+ description: >-
+ The Operating System (OS) distribution. Examples of valid values for a "type" of "Linux" would include: debian, fedora,
+ rhel and ubuntu.
+ type: string
+ required: false
+ version:
+ description: >-
+ The Operating System version.
+ type: version
+ required: false
+
+ tosca.capabilities.Scalable:
+ _extensions:
+ shorthand_name: Scalable
+ type_qualified_name: tosca:Scalable
+ specification: tosca-simple-1.0
+ specification_section: 5.4.10
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_SCALABLE'
+ role: scaling
+ description: >-
+ This is the default TOSCA type that should be used to express a scalability capability for a node.
+ derived_from: tosca.capabilities.Root
+ properties:
+ min_instances:
+ description: >-
+ This property is used to indicate the minimum number of instances that should be created for the associated TOSCA Node
+ Template by a TOSCA orchestrator.
+ type: integer
+ default: 1
+ max_instances:
+ description: >-
+ This property is used to indicate the maximum number of instances that should be created for the associated TOSCA Node
+ Template by a TOSCA orchestrator.
+ type: integer
+ default: 1
+ default_instances:
+ description: >-
+ An optional property that indicates the requested default number of instances that should be the starting number of
+ instances a TOSCA orchestrator should attempt to allocate. Note: The value for this property MUST be in the range between
+ the values set for "min_instances" and "max_instances" properties.
+ type: integer
+ required: false
+
+ #
+ # Endpoints
+ #
+
+ tosca.capabilities.Endpoint:
+ _extensions:
+ shorthand_name: Endpoint
+ type_qualified_name: tosca:Endpoint
+ specification: tosca-simple-1.0
+ specification_section: 5.4.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_ENDPOINT'
+ description: >-
+ This is the default TOSCA type that should be used or extended to define a network endpoint capability. This includes the information to express a basic endpoint with a single port or a complex endpoint with multiple ports. By default the Endpoint is assumed to represent an address on a private network unless otherwise specified.
+ derived_from: tosca.capabilities.Root
+ properties:
+ protocol:
+ description: >-
+ The name of the protocol (i.e., the protocol prefix) that the endpoint accepts (any OSI Layer 4-7 protocols). Examples:
+ http, https, ftp, tcp, udp, etc.
+ type: string
+ default: tcp
+ required: true
+ port:
+ description: >-
+ The optional port of the endpoint.
+ type: tosca.datatypes.network.PortDef
+ required: false
+ secure:
+ description: >-
+ Requests for the endpoint to be secure and use credentials supplied on the ConnectsTo relationship.
+ type: boolean
+ default: false
+ required: false
+ url_path:
+ description: >-
+ The optional URL path of the endpoint's address if applicable for the protocol.
+ type: string
+ required: false
+ port_name:
+ description: >-
+ The optional name (or ID) of the network port this endpoint should be bound to.
+ type: string
+ required: false
+ network_name:
+ description: >-
+ The optional name (or ID) of the network this endpoint should be bound to. network_name: PRIVATE | PUBLIC |
+ <network_name> | <network_id>.
+ type: string
+ default: PRIVATE
+ required: false
+ initiator:
+ description: >-
+ The optional indicator of the direction of the connection.
+ type: string
+ constraints:
+ - valid_values: [ source, target, peer ]
+ default: source
+ required: false
+ ports:
+ description: >-
+ The optional map of ports the Endpoint supports (if more than one).
+ type: map
+ entry_schema:
+ type: tosca.datatypes.network.PortSpec
+ constraints:
+ - min_length: 1
+ required: false
+ attributes:
+ ip_address:
+ description: >-
+ Note: This is the IP address as propagated up by the associated node's host (Compute) container.
+ type: string
+
+ tosca.capabilities.Endpoint.Public:
+ _extensions:
+ shorthand_name: Endpoint.Public
+ type_qualified_name: tosca:Endpoint.Public
+ specification: tosca-simple-1.0
+ specification_section: 5.4.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_ENDPOINT_PUBLIC'
+ description: >-
+ This capability represents a public endpoint which is accessible to the general internet (and its public IP address ranges).
+
+ This public endpoint capability also can be used to create a floating (IP) address that the underlying network assigns from a
+ pool allocated from the application's underlying public network. This floating address is managed by the underlying network
+ such that can be routed an application's private address and remains reliable to internet clients.
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ network_name:
+ type: string
+ constraints:
+ - equal: PUBLIC
+ default: PUBLIC
+ floating:
+ description: >-
+ Indicates that the public address should be allocated from a pool of floating IPs that are associated with the network.
+ type: boolean
+ default: false
+ status: experimental
+ dns_name:
+ description: >-
+ The optional name to register with DNS.
+ type: string
+ required: false
+ status: experimental
+
+ tosca.capabilities.Endpoint.Admin:
+ _extensions:
+ shorthand_name: Endpoint.Admin
+ type_qualified_name: tosca:Endpoint.Admin
+ specification: tosca-simple-1.0
+ specification_section: 5.4.6
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_ENDPOINT_ADMIN'
+ description: >-
+ This is the default TOSCA type that should be used or extended to define a specialized administrator endpoint capability.
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ secure:
+ description: >-
+ Requests for the endpoint to be secure and use credentials supplied on the ConnectsTo relationship.
+ type: boolean
+ constraints:
+ - equal: true
+ default: true
+
+ tosca.capabilities.Endpoint.Database:
+ _extensions:
+ shorthand_name: Endpoint.Database
+ type_qualified_name: tosca:Endpoint.Database
+ specification: tosca-simple-1.0
+ specification_section: 5.4.7
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_ENDPOINT_DATABASE'
+ description: >-
+ This is the default TOSCA type that should be used or extended to define a specialized database endpoint capability.
+ derived_from: tosca.capabilities.Endpoint
+
+ #
+ # Network
+ #
+
+ tosca.capabilities.network.Bindable:
+ _extensions:
+ shorthand_name: Bindable # ARIA NOTE: mistake in spec? has "network." as a prefix
+ type_qualified_name: tosca:Bindable
+ specification: tosca-simple-1.0
+ specification_section: 5.4.11
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_NETWORK_BINDABLE'
+ description: >-
+ A node type that includes the Bindable capability indicates that it can be bound to a logical network association via a
+ network port.
+ derived_from: tosca.capabilities.Node
+
+ tosca.capabilities.network.Linkable:
+ _extensions:
+ shorthand_name: Linkable
+ type_qualified_name: tosca:Linkable
+ specification: tosca-simple-1.0
+ specification_section: 7.5.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_NETWORK_LINKABLE'
+ description: >-
+ A node type that includes the Linkable capability indicates that it can be pointed by tosca.relationships.network.LinksTo
+ relationship type.
+ derived_from: tosca.capabilities.Node
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml
new file mode 100644
index 0000000..61d4186
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml
@@ -0,0 +1,268 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+data_types:
+
+ #
+ # Primitive
+ #
+
+ timestamp:
+ _extensions:
+ coerce_value: aria_extension_tosca.simple_v1_0.data_types.coerce_timestamp
+
+ version:
+ _extensions:
+ coerce_value: aria_extension_tosca.simple_v1_0.data_types.coerce_version
+ type_qualified_name: tosca:version
+ specification: tosca-simple-1.0
+ specification_section: 3.2.2
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_VERSION'
+
+ range:
+ _extensions:
+ coerce_value: aria_extension_tosca.simple_v1_0.data_types.coerce_range
+ type_qualified_name: tosca:range
+ specification: tosca-simple-1.0
+ specification_section: 3.2.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_RANGE'
+
+ #
+ # With entry schema
+ #
+
+ list:
+ _extensions:
+ use_entry_schema: true
+ coerce_value: aria_extension_tosca.simple_v1_0.data_types.coerce_list
+ type_qualified_name: tosca:list
+ specification: tosca-simple-1.0
+ specification_section: 3.2.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_LIST'
+
+ map:
+ _extensions:
+ use_entry_schema: true
+ coerce_value: aria_extension_tosca.simple_v1_0.data_types.coerce_map_value
+ type_qualified_name: tosca:map
+ specification: tosca-simple-1.0
+ specification_section: 3.2.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_MAP'
+
+ #
+ # Scalar
+ #
+
+ scalar-unit.size:
+ _extensions:
+ coerce_value: aria_extension_tosca.simple_v1_0.data_types.coerce_scalar_unit_size
+ type_qualified_name: tosca:scalar-unit.size
+ specification: tosca-simple-1.0
+ specification_section: 3.2.6.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_SCALAR_UNIT_SIZE'
+
+ scalar-unit.time:
+ _extensions:
+ coerce_value: aria_extension_tosca.simple_v1_0.data_types.coerce_scalar_unit_time
+ type_qualified_name: tosca:scalar-unit.time
+ specification: tosca-simple-1.0
+ specification_section: 3.2.6.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_SCALAR_UNIT_TIME'
+
+ scalar-unit.frequency:
+ _extensions:
+ coerce_value: aria_extension_tosca.simple_v1_0.data_types.coerce_scalar_unit_frequency
+ type_qualified_name: tosca:scalar-unit.frequency
+ specification: tosca-simple-1.0
+ specification_section: 3.2.6.6
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_SCALAR_UNIT_FREQUENCY'
+
+ #
+ # Complex
+ #
+
+ tosca.datatypes.Root:
+ _extensions:
+ shorthand_name: Root # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Root
+ specification: tosca-simple-1.0
+ specification_section: 5.2.1
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_DATA_ROOT'
+ description: >-
+ This is the default (root) TOSCA Root Type definition that all complex TOSCA Data Types derive from.
+
+ tosca.datatypes.Credential:
+ _extensions:
+ shorthand_name: Credential
+ type_qualified_name: tosca:Credential
+ specification: tosca-simple-1.0
+ specification_section: 5.2.2
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_DATA_CREDENTIAL'
+ description: >-
+ The Credential type is a complex TOSCA data Type used when describing authorization credentials used to access network
+ accessible resources.
+ derived_from: tosca.datatypes.Root
+ properties:
+ protocol:
+ description: >-
+ The optional protocol name.
+ type: string
+ required: false
+ token_type:
+ description: >-
+ The required token type.
+ type: string
+ default: password
+ token:
+ description: >-
+ The required token used as a credential for authorization or access to a networked resource.
+ type: string
+ required: false
+ keys:
+ description: >-
+ The optional list of protocol-specific keys or assertions.
+ type: map
+ entry_schema:
+ type: string
+ required: false
+ user:
+ description: >-
+ The optional user (name or ID) used for non-token based credentials.
+ type: string
+ required: false
+
+ tosca.datatypes.network.NetworkInfo:
+ _extensions:
+ shorthand_name: NetworkInfo
+ type_qualified_name: tosca:NetworkInfo
+ specification: tosca-simple-1.0
+ specification_section: 5.2.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_DATA_NETWORKINFO'
+ description: >-
+ The Network type is a complex TOSCA data type used to describe logical network information.
+ derived_from: tosca.datatypes.Root
+ properties:
+ network_name:
+ description: >-
+ The name of the logical network. e.g., "public", "private", "admin". etc.
+ type: string
+ required: false
+ network_id:
+ description: >-
+ The unique ID of for the network generated by the network provider.
+ type: string
+ required: false
+ addresses:
+ description: >-
+ The list of IP addresses assigned from the underlying network.
+ type: list
+ entry_schema:
+ type: string
+ required: false
+
+ tosca.datatypes.network.PortInfo:
+ _extensions:
+ shorthand_name: PortInfo
+ type_qualified_name: tosca:PortInfo
+ specification: tosca-simple-1.0
+ specification_section: 5.2.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_DATA_PORTINFO'
+ description: >-
+ The PortInfo type is a complex TOSCA data type used to describe network port information.
+ derived_from: tosca.datatypes.Root
+ properties:
+ port_name:
+ description: >-
+ The logical network port name.
+ type: string
+ required: false
+ port_id:
+ description: >-
+ The unique ID for the network port generated by the network provider.
+ type: string
+ required: false
+ network_id:
+ description: >-
+ The unique ID for the network.
+ type: string
+ required: false
+ mac_address:
+ description: >-
+ The unique media access control address (MAC address) assigned to the port.
+ type: string
+ required: false
+ addresses:
+ description: >-
+ The list of IP address(es) assigned to the port.
+ type: list
+ entry_schema:
+ type: string
+ required: false
+
+ tosca.datatypes.network.PortDef:
+ _extensions:
+ shorthand_name: PortDef
+ type_qualified_name: tosca:PortDef
+ specification: tosca-simple-1.0
+ specification_section: 5.2.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_DATA_PORTDEF'
+ description: >-
+ The PortDef type is a TOSCA data Type used to define a network port.
+ derived_from: integer # ARIA NOTE: we allow deriving from primitives
+ constraints:
+ - in_range: [ 1, 65535 ]
+
+ tosca.datatypes.network.PortSpec:
+ _extensions:
+ shorthand_name: PortSpec
+ type_qualified_name: tosca:PortSpec
+ specification: tosca-simple-1.0
+ specification_section: 5.2.6
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#TYPE_TOSCA_DATA_PORTSPEC'
+ description: >-
+ The PortSpec type is a complex TOSCA data Type used when describing port specifications for a network connection.
+ derived_from: tosca.datatypes.Root
+ properties:
+ protocol:
+ description: >-
+ The required protocol used on the port.
+ type: string
+ constraints:
+ - valid_values: [ udp, tcp, igmp ]
+ default: tcp
+ source:
+ description: >-
+ The optional source port.
+ type: tosca.datatypes.network.PortDef
+ required: false
+ source_range:
+ description: >-
+ The optional range for source port.
+ type: range
+ constraints:
+ - in_range: [ 1, 65535 ]
+ required: false
+ target:
+ description: >-
+ The optional target port.
+ type: tosca.datatypes.network.PortDef
+ required: false
+ target_range:
+ description: >-
+ The optional range for target port.
+ type: range
+ constraints:
+ - in_range: [ 1, 65535 ]
+ required: false
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml
new file mode 100644
index 0000000..66cc25f
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+group_types:
+
+ tosca.groups.Root:
+ _extensions:
+ shorthand_name: Root # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Root
+ specification: tosca-simple-1.0
+ specification_section: 5.9.1
+ description: >-
+ This is the default (root) TOSCA Group Type definition that all other TOSCA base Group Types derive from.
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml
new file mode 100644
index 0000000..29cc8dd
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml
@@ -0,0 +1,107 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+interface_types:
+
+ tosca.interfaces.Root:
+ _extensions:
+ shorthand_name: Root # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Root
+ specification: tosca-simple-1.0
+ specification_section: 5.7.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#_Ref384391055'
+ description: >-
+ This is the default (root) TOSCA Interface Type definition that all other TOSCA Interface Types derive from.
+
+ tosca.interfaces.node.lifecycle.Standard:
+ _extensions:
+ shorthand_name: Standard
+ type_qualified_name: tosca:Standard
+ specification: tosca-simple-1.0
+ specification_section: 5.7.4
+ description: >-
+ This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.
+ derived_from: tosca.interfaces.Root
+ create:
+ description: >-
+ Standard lifecycle create operation.
+ configure:
+ description: >-
+ Standard lifecycle configure operation.
+ start:
+ description: >-
+ Standard lifecycle start operation.
+ stop:
+ description: >-
+ Standard lifecycle stop operation.
+ delete:
+ description: >-
+ Standard lifecycle delete operation.
+
+ tosca.interfaces.relationship.Configure:
+ _extensions:
+ shorthand_name: Configure
+ type_qualified_name: tosca:Configure
+ specification: tosca-simple-1.0
+ specification_section: 5.7.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_ITFC_RELATIONSHIP_CONFIGURE'
+ description: >-
+ The lifecycle interfaces define the essential, normative operations that each TOSCA Relationship Types may support.
+ derived_from: tosca.interfaces.Root
+ pre_configure_source:
+ description: >-
+ Operation to pre-configure the source endpoint.
+ _extensions:
+ relationship_edge: source
+ pre_configure_target:
+ description: >-
+ Operation to pre-configure the target endpoint.
+ _extensions:
+ relationship_edge: target
+ post_configure_source:
+ description: >-
+ Operation to post-configure the source endpoint.
+ _extensions:
+ relationship_edge: source
+ post_configure_target:
+ description: >-
+ Operation to post-configure the target endpoint.
+ _extensions:
+ relationship_edge: target
+ add_target:
+ description: >-
+ Operation to notify the source node of a target node being added via a relationship.
+ _extensions:
+ relationship_edge: source
+ add_source:
+ description: >-
+ Operation to notify the target node of a source node which is now available via a relationship.
+ _extensions:
+ relationship_edge: target
+ target_changed:
+ description: >-
+ Operation to notify source some property or attribute of the target changed
+ _extensions:
+ relationship_edge: source
+ remove_target:
+ description: >-
+ Operation to remove a target node.
+ _extensions:
+ relationship_edge: source
+ remove_source:
+ description: >-
+ Operation to remove the source node.
+ _extensions:
+ relationship_edge: target
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml
new file mode 100644
index 0000000..05963b7
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml
@@ -0,0 +1,525 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+node_types:
+
+ tosca.nodes.Root:
+ _extensions:
+ shorthand_name: Root
+ type_qualified_name: tosca:Root
+ specification: tosca-simple-1.0
+ specification_section: 5.8.1
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_ROOT'
+ description: >-
+ The TOSCA Root Node Type is the default type that all other TOSCA base Node Types derive from. This allows for all TOSCA nodes to have a consistent set of features for modeling and management (e.g., consistent definitions for requirements, capabilities and lifecycle interfaces).
+ attributes:
+ tosca_id:
+ description: >-
+ A unique identifier of the realized instance of a Node Template that derives from any TOSCA normative type.
+ type: string
+ tosca_name:
+ description: >-
+ This attribute reflects the name of the Node Template as defined in the TOSCA service template. This name is not unique
+ to the realized instance model of corresponding deployed application as each template in the model can result in one or
+ more instances (e.g., scaled) when orchestrated to a provider environment.
+ type: string
+ state:
+ description: >-
+ The state of the node instance.
+ type: string
+ default: initial
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ capabilities:
+ feature:
+ type: tosca.capabilities.Node
+ requirements:
+ - dependency:
+ capability: tosca.capabilities.Node
+ node: tosca.nodes.Root
+ relationship: tosca.relationships.DependsOn
+ occurrences: [ 0, UNBOUNDED ]
+
+ tosca.nodes.Compute:
+ _extensions:
+ shorthand_name: Compute
+ type_qualified_name: tosca:Compute
+ specification: tosca-simple-1.0
+ specification_section: 5.8.2
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_COMPUTE'
+ role: host
+ description: >-
+ The TOSCA Compute node represents one or more real or virtual processors of software applications or services along with
+ other essential local resources. Collectively, the resources the compute node represents can logically be viewed as a (real
+ or virtual) "server".
+ derived_from: tosca.nodes.Root
+ attributes:
+ private_address:
+ description: >-
+ The primary private IP address assigned by the cloud provider that applications may use to access the Compute node.
+ type: string
+ public_address:
+ description: >-
+ The primary public IP address assigned by the cloud provider that applications may use to access the Compute node.
+ type: string
+ networks:
+ description: >-
+ The list of logical networks assigned to the compute host instance and information about them.
+ type: map
+ entry_schema:
+ type: tosca.datatypes.network.NetworkInfo
+ ports:
+ description: >-
+ The list of logical ports assigned to the compute host instance and information about them.
+ type: map
+ entry_schema:
+ type: tosca.datatypes.network.PortInfo
+ capabilities:
+ host:
+ type: tosca.capabilities.Container
+ valid_source_types: [ tosca.nodes.SoftwareComponent ]
+ binding:
+ type: tosca.capabilities.network.Bindable
+ os:
+ type: tosca.capabilities.OperatingSystem
+ scalable:
+ type: tosca.capabilities.Scalable
+ requirements:
+ - local_storage:
+ capability: tosca.capabilities.Attachment
+ node: tosca.nodes.BlockStorage
+ relationship: tosca.relationships.AttachesTo
+ occurrences: [ 0, UNBOUNDED ]
+
+ tosca.nodes.LoadBalancer:
+ _extensions:
+ shorthand_name: LoadBalancer
+ type_qualified_name: tosca:LoadBalancer
+ specification: tosca-simple-1.0
+ specification_section: 5.8.12
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#_Toc379548332'
+ description: >-
+ The TOSCA Load Balancer node represents logical function that be used in conjunction with a Floating Address to distribute an
+ application's traffic (load) across a number of instances of the application (e.g., for a clustered or scaled application).
+ derived_from: tosca.nodes.Root
+ properties:
+ algorithm:
+ description: >-
+ No description in spec.
+ type: string
+ required: false
+ status: experimental
+ capabilities:
+ client:
+ description: >-
+ The Floating (IP) client's on the public network can connect to.
+ type: tosca.capabilities.Endpoint.Public
+ occurrences: [ 0, UNBOUNDED ] # ARIA NOTE: it seems unnecessary to specify this, as it is the implied default
+ requirements:
+ - application:
+ capability: tosca.capabilities.Endpoint
+ relationship: tosca.relationships.RoutesTo
+ occurrences: [ 0, UNBOUNDED ]
+
+ #
+ # Software
+ #
+
+ tosca.nodes.SoftwareComponent:
+ _extensions:
+ shorthand_name: SoftwareComponent
+ type_qualified_name: tosca:SoftwareComponent
+ specification: tosca-simple-1.0
+ specification_section: 5.8.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_SOFTWARE_COMPONENT'
+ description: >-
+ The TOSCA SoftwareComponent node represents a generic software component that can be managed and run by a TOSCA Compute Node
+ Type.
+ derived_from: tosca.nodes.Root
+ properties:
+ component_version:
+ description: >-
+ The optional software component's version.
+ type: version
+ required: false
+ admin_credential:
+ description: >-
+ The optional credential that can be used to authenticate to the software component.
+ type: tosca.datatypes.Credential
+ required: false
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container
+ node: tosca.nodes.Compute
+ relationship: tosca.relationships.HostedOn
+
+ tosca.nodes.WebServer:
+ _extensions:
+ shorthand_name: WebServer
+ type_qualified_name: tosca:WebServer
+ specification: tosca-simple-1.0
+ specification_section: 5.8.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_WEBSERVER'
+ description: >-
+ This TOSCA WebServer Node Type represents an abstract software component or service that is capable of hosting and providing
+ management operations for one or more WebApplication nodes.
+ derived_from: tosca.nodes.SoftwareComponent
+ capabilities:
+ data_endpoint:
+ type: tosca.capabilities.Endpoint
+ admin_endpoint:
+ type: tosca.capabilities.Endpoint.Admin
+ host:
+ type: tosca.capabilities.Container
+ valid_source_types: [ tosca.nodes.WebApplication ]
+
+ tosca.nodes.WebApplication:
+ _extensions:
+ shorthand_name: WebApplication
+ type_qualified_name: tosca:WebApplication
+ specification: tosca-simple-1.0
+ specification_section: 5.8.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_WEBAPPLICATION'
+ description: >-
+ The TOSCA WebApplication node represents a software application that can be managed and run by a TOSCA WebServer node.
+ Specific types of web applications such as Java, etc. could be derived from this type.
+ derived_from: tosca.nodes.SoftwareComponent # ARIA NOTE: the spec says tosca.nodes.Root
+ properties:
+ context_root:
+ description: >-
+ The web application's context root which designates the application's URL path within the web server it is hosted on.
+ type: string
+ required: false
+ capabilities:
+ app_endpoint:
+ type: tosca.capabilities.Endpoint
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container
+ node: tosca.nodes.WebServer
+ relationship: tosca.relationships.HostedOn
+
+ tosca.nodes.DBMS:
+ _extensions:
+ shorthand_name: DBMS # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:DBMS
+ specification: tosca-simple-1.0
+ specification_section: 5.8.6
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_DBMS'
+ description: >-
+ The TOSCA DBMS node represents a typical relational, SQL Database Management System software component or service.
+ derived_from: tosca.nodes.SoftwareComponent
+ properties:
+ root_password:
+ description: >-
+ The optional root password for the DBMS server.
+ type: string
+ required: false
+ port:
+ description: >-
+ The DBMS server's port.
+ type: integer
+ required: false
+ capabilities:
+ host:
+ type: tosca.capabilities.Container
+ valid_source_types: [ tosca.nodes.Database ]
+
+ tosca.nodes.Database:
+ _extensions:
+ shorthand_name: Database
+ type_qualified_name: tosca:Database
+ specification: tosca-simple-1.0
+ specification_section: 5.8.7
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_DATABASE'
+ description: >-
+ The TOSCA Database node represents a logical database that can be managed and hosted by a TOSCA DBMS node.
+ derived_from: tosca.nodes.Root # ARIA NOTE: it's *not* a SoftwareComponent
+ properties:
+ name:
+ description: >-
+ The logical database Name.
+ type: string
+ port:
+ description: >-
+ The port the database service will use to listen for incoming data and requests.
+ type: integer
+ required: false
+ user:
+ description: >-
+ The special user account used for database administration.
+ type: string
+ required: false
+ password:
+ description: >-
+ The password associated with the user account provided in the 'user' property.
+ type: string
+ required: false
+ capabilities:
+ database_endpoint:
+ type: tosca.capabilities.Endpoint.Database
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container
+ node: tosca.nodes.DBMS
+ relationship: tosca.relationships.HostedOn
+
+ #
+ # Container
+ #
+
+ tosca.nodes.Container.Runtime:
+ _extensions:
+ shorthand_name: Container.Runtime
+ type_qualified_name: tosca:Container.Runtime
+ specification: tosca-simple-1.0
+ specification_section: 5.8.10
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_CONTAINER_RUNTIME'
+ description: >-
+ The TOSCA Container Runtime node represents operating system-level virtualization technology used to run multiple application
+ services on a single Compute host.
+ derived_from: tosca.nodes.SoftwareComponent
+ capabilities:
+ host:
+ type: tosca.capabilities.Container
+ scalable:
+ type: tosca.capabilities.Scalable
+
+ tosca.nodes.Container.Application:
+ _extensions:
+ shorthand_name: Container.Application
+ type_qualified_name: tosca:Container.Application
+ specification: tosca-simple-1.0
+ specification_section: 5.8.11
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_CONTAINER_APP'
+ description: >-
+ The TOSCA Container Application node represents an application that requires Container-level virtualization technology.
+ derived_from: tosca.nodes.Root
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container
+ # ARIA NOTE: seems a mistake in the spec
+ #node: tosca.nodes.Container
+ relationship: tosca.relationships.HostedOn
+
+ #
+ # Storage
+ #
+
+ tosca.nodes.ObjectStorage:
+ _extensions:
+ shorthand_name: ObjectStorage
+ type_qualified_name: tosca:ObjectStorage
+ specification: tosca-simple-1.0
+ specification_section: 5.8.8
+ description: >-
+ The TOSCA ObjectStorage node represents storage that provides the ability to store data as objects (or BLOBs of data) without
+ consideration for the underlying filesystem or devices.
+ derived_from: tosca.nodes.Root
+ properties:
+ name:
+ description: >-
+ The logical name of the object store (or container).
+ type: string
+ size:
+ description: >-
+ The requested initial storage size (default unit is in Gigabytes).
+ type: scalar-unit.size
+ constraints:
+ - greater_or_equal: 0 GB
+ required: false
+ maxsize:
+ description: >-
+ The requested maximum storage size (default unit is in Gigabytes).
+ type: scalar-unit.size
+ constraints:
+ - greater_or_equal: 0 GB
+ required: false
+ capabilities:
+ storage_endpoint:
+ type: tosca.capabilities.Endpoint
+
+ tosca.nodes.BlockStorage:
+ _extensions:
+ shorthand_name: BlockStorage
+ type_qualified_name: tosca:BlockStorage
+ specification: tosca-simple-1.0
+ specification_section: 5.8.9
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_NODES_BLOCK_STORAGE'
+ description: >-
+ derived_from: tosca.nodes.Root
+ properties:
+ size:
+ description: >-
+ The requested storage size (default unit is MB).
+ type: scalar-unit.size
+ constraints:
+ - greater_or_equal: 1 MB
+ volume_id:
+ description: >-
+ ID of an existing volume (that is in the accessible scope of the requesting application).
+ type: string
+ required: false
+ snapshot_id:
+ description: >-
+ Some identifier that represents an existing snapshot that should be used when creating the block storage (volume).
+ type: string
+ required: false
+ capabilities:
+ attachment:
+ type: tosca.capabilities.Attachment
+
+ #
+ # Network
+ #
+
+ tosca.nodes.network.Network:
+ _extensions:
+ shorthand_name: Network
+ type_qualified_name: tosca:Network
+ specification: tosca-simple-1.0
+ specification_section: 7.5.1
+ description: >-
+ The TOSCA Network node represents a simple, logical network service.
+ derived_from: tosca.nodes.Root
+ properties:
+ ip_version:
+ description: >-
+ The IP version of the requested network.
+ type: integer
+ constraints:
+ - valid_values: [ 4, 6 ]
+ default: 4
+ required: false
+ cidr:
+ description: >-
+ The cidr block of the requested network.
+ type: string
+ required: false
+ start_ip:
+ description: >-
+ The IP address to be used as the 1st one in a pool of addresses derived from the cidr block full IP range.
+ type: string
+ required: false
+ end_ip:
+ description: >-
+ The IP address to be used as the last one in a pool of addresses derived from the cidr block full IP range.
+ type: string
+ required: false
+ gateway_ip:
+ description: >-
+ The gateway IP address.
+ type: string
+ required: false
+ network_name:
+ description: >-
+ An Identifier that represents an existing Network instance in the underlying cloud infrastructure - OR - be used as the
+ name of the new created network.
+ type: string
+ required: false
+ network_id:
+ description: >-
+ An Identifier that represents an existing Network instance in the underlying cloud infrastructure. This property is
+ mutually exclusive with all other properties except network_name.
+ type: string
+ required: false
+ segmentation_id:
+ description: >-
+ A segmentation identifier in the underlying cloud infrastructure (e.g., VLAN id, GRE tunnel id). If the segmentation_id
+ is specified, the network_type or physical_network properties should be provided as well.
+ type: string
+ required: false
+ network_type:
+ description: >-
+ Optionally, specifies the nature of the physical network in the underlying cloud infrastructure. Examples are flat, vlan,
+ gre or vxlan. For flat and vlan types, physical_network should be provided too.
+ type: string
+ required: false
+ physical_network:
+ description: >-
+ Optionally, identifies the physical network on top of which the network is implemented, e.g. physnet1. This property is
+ required if network_type is flat or vlan.
+ type: string
+ required: false
+ dhcp_enabled:
+ description: >-
+ Indicates the TOSCA container to create a virtual network instance with or without a DHCP service.
+ type: boolean
+ default: true
+ required: false
+ capabilities:
+ link:
+ type: tosca.capabilities.network.Linkable
+
+ tosca.nodes.network.Port:
+ _extensions:
+ shorthand_name: Port
+ type_qualified_name: tosca:Port
+ specification: tosca-simple-1.0
+ specification_section: 7.5.2
+ description: >-
+ The TOSCA Port node represents a logical entity that associates between Compute and Network normative types.
+
+ The Port node type effectively represents a single virtual NIC on the Compute node instance.
+ derived_from: tosca.nodes.Root
+ properties:
+ ip_address:
+ description: >-
+ Allow the user to set a fixed IP address. Note that this address is a request to the provider which they will attempt to
+ fulfill but may not be able to dependent on the network the port is associated with.
+ type: string
+ required: false
+ order:
+ description: >-
+ The order of the NIC on the compute instance (e.g. eth2). Note: when binding more than one port to a single compute (aka
+ multi vNICs) and ordering is desired, it is *mandatory* that all ports will be set with an order value and. The order
+ values must represent a positive, arithmetic progression that starts with 0 (e.g. 0, 1, 2, ..., n).
+ type: integer
+ constraints:
+ - greater_or_equal: 0
+ default: 0
+ required: false
+ is_default:
+ description: >-
+ Set is_default=true to apply a default gateway route on the running compute instance to the associated network gateway.
+ Only one port that is associated to single compute node can set as default=true.
+ type: boolean
+ default: false
+ required: false
+ ip_range_start:
+ description: >-
+ Defines the starting IP of a range to be allocated for the compute instances that are associated by this Port. Without
+ setting this property the IP allocation is done from the entire CIDR block of the network.
+ type: string
+ required: false
+ ip_range_end:
+ description: >-
+ Defines the ending IP of a range to be allocated for the compute instances that are associated by this Port. Without
+ setting this property the IP allocation is done from the entire CIDR block of the network.
+ type: string
+ required: false
+ attributes:
+ ip_address:
+ description: >-
+ The IP address would be assigned to the associated compute instance.
+ type: string
+ requirements:
+ - link:
+ capability: tosca.capabilities.network.Linkable
+ relationship: tosca.relationships.network.LinksTo
+ - binding:
+ capability: tosca.capabilities.network.Bindable
+ relationship: tosca.relationships.network.BindsTo
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml
new file mode 100644
index 0000000..7b35bb9
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml
@@ -0,0 +1,71 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+policy_types:
+
+ tosca.policies.Root:
+ _extensions:
+ shorthand_name: Root # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Root
+ specification: tosca-simple-1.0
+ specification_section: 5.10.1
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_POLICIES_ROOT'
+ description: >-
+ This is the default (root) TOSCA Policy Type definition that all other TOSCA base Policy Types derive from.
+
+ tosca.policies.Placement:
+ _extensions:
+ shorthand_name: Placement # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Placement
+ specification: tosca-simple-1.0
+ specification_section: 5.10.2
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_POLICIES_PLACEMENT'
+ description: >-
+ This is the default (root) TOSCA Policy Type definition that is used to govern placement of TOSCA nodes or groups of nodes.
+ derived_from: tosca.policies.Root
+
+ tosca.policies.Scaling:
+ _extensions:
+ shorthand_name: Scaling # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Scaling
+ specification: tosca-simple-1.0
+ specification_section: 5.10.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_POLICIES_SCALING'
+ description: >-
+ This is the default (root) TOSCA Policy Type definition that is used to govern scaling of TOSCA nodes or groups of nodes.
+ derived_from: tosca.policies.Root
+
+ tosca.policies.Update:
+ _extensions:
+ shorthand_name: Update # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Update
+ specification: tosca-simple-1.0
+ specification_section: 5.10.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_POLICIES_UPDATE'
+ description: >-
+ This is the default (root) TOSCA Policy Type definition that is used to govern update of TOSCA nodes or groups of nodes.
+ derived_from: tosca.policies.Root
+
+ tosca.policies.Performance:
+ _extensions:
+ shorthand_name: Performance # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Performance
+ specification: tosca-simple-1.0
+ specification_section: 5.10.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_POLICIES_PERFORMANCE'
+ description: >-
+ This is the default (root) TOSCA Policy Type definition that is used to declare performance requirements for TOSCA nodes or
+ groups of nodes.
+ derived_from: tosca.policies.Root
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml
new file mode 100644
index 0000000..9f2c32c
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml
@@ -0,0 +1,158 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+relationship_types:
+
+ tosca.relationships.Root:
+ _extensions:
+ shorthand_name: Root # ARIA NOTE: omitted in the spec
+ type_qualified_name: tosca:Root
+ specification: tosca-simple-1.0
+ specification_section: 5.6.1
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_RELATIONSHIPS_ROOT'
+ description: >-
+ This is the default (root) TOSCA Relationship Type definition that all other TOSCA Relationship Types derive from.
+ attributes:
+ tosca_id:
+ description: >-
+ A unique identifier of the realized instance of a Relationship Template that derives from any TOSCA normative type.
+ type: string
+ tosca_name:
+ description: >-
+ This attribute reflects the name of the Relationship Template as defined in the TOSCA service template. This name is not
+ unique to the realized instance model of corresponding deployed application as each template in the model can result in
+ one or more instances (e.g., scaled) when orchestrated to a provider environment.
+ type: string
+ state:
+ description: >-
+ The state of the relationship instance.
+ type: string
+ default: initial
+ interfaces:
+ Configure:
+ type: tosca.interfaces.relationship.Configure
+
+ tosca.relationships.DependsOn:
+ _extensions:
+ shorthand_name: DependsOn
+ type_qualified_name: tosca:DependsOn
+ specification: tosca-simple-1.0
+ specification_section: 5.6.2
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_RELATIONSHIPS_DEPENDSON'
+ description: >-
+ This type represents a general dependency relationship between two nodes.
+ derived_from: tosca.relationships.Root
+ valid_target_types: [ tosca.capabilities.Node ]
+
+ tosca.relationships.HostedOn:
+ _extensions:
+ shorthand_name: HostedOn
+ type_qualified_name: tosca:HostedOn
+ specification: tosca-simple-1.0
+ specification_section: 5.6.3
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_RELATIONSHIPS_HOSTEDON'
+ description: >-
+ This type represents a hosting relationship between two nodes.
+ derived_from: tosca.relationships.Root
+ valid_target_types: [ tosca.capabilities.Container ]
+
+ tosca.relationships.ConnectsTo:
+ _extensions:
+ shorthand_name: ConnectsTo
+ type_qualified_name: tosca:ConnectsTo
+ specification: tosca-simple-1.0
+ specification_section: 5.6.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_RELATIONSHIPS_CONNECTSTO'
+ description: >-
+ This type represents a network connection relationship between two nodes.
+ derived_from: tosca.relationships.Root
+ valid_target_types: [ tosca.capabilities.Endpoint ]
+ properties:
+ credential:
+ type: tosca.datatypes.Credential
+ required: false
+
+ tosca.relationships.AttachesTo:
+ _extensions:
+ shorthand_name: AttachesTo
+ type_qualified_name: tosca:AttachesTo
+ specification: tosca-simple-1.0
+ specification_section: 5.6.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_RELATIONSHIPS_ATTACHTO'
+ description: >-
+ This type represents an attachment relationship between two nodes. For example, an AttachesTo relationship type would be used
+ for attaching a storage node to a Compute node.
+ derived_from: tosca.relationships.Root
+ valid_target_types: [ tosca.capabilities.Attachment ]
+ properties:
+ location:
+ description: >-
+ The relative location (e.g., path on the file system), which provides the root location to address an attached node.
+ e.g., a mount point / path such as '/usr/data'. Note: The user must provide it and it cannot be "root".
+ type: string
+ constraints:
+ - min_length: 1
+ device:
+ description: >-
+ The logical device name which for the attached device (which is represented by the target node in the model). e.g.,
+ '/dev/hda1'.
+ type: string
+ required: false
+ attributes:
+ device:
+ description: >-
+ The logical name of the device as exposed to the instance.
+ Note: A runtime property that gets set when the model gets instantiated by the orchestrator.
+ type: string
+
+ tosca.relationships.RoutesTo:
+ _extensions:
+ shorthand_name: RoutesTo
+ type_qualified_name: tosca:RoutesTo
+ specification: tosca-simple-1.0
+ specification_section: 5.6.6
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#_Toc397688815'
+ description: >-
+ This type represents an intentional network routing between two Endpoints in different networks.
+ derived_from: tosca.relationships.ConnectsTo
+ valid_target_types: [ tosca.capabilities.Endpoint ]
+
+ #
+ # Network
+ #
+
+ tosca.relationships.network.LinksTo:
+ _extensions:
+ shorthand_name: LinksTo
+ type_qualified_name: tosca:LinksTo
+ specification: tosca-simple-1.0
+ specification_section: 7.5.4
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_RELATIONSHIPS_NETWORK_LINKSTO'
+ description: >-
+ This relationship type represents an association relationship between Port and Network node types.
+ derived_from: tosca.relationships.DependsOn
+ valid_target_types: [ tosca.capabilities.network.Linkable ]
+
+ tosca.relationships.network.BindsTo:
+ _extensions:
+ shorthand_name: BindsTo # ARIA NOTE: the spec says "network.BindsTo" which seems wrong
+ type_qualified_name: tosca:BindsTo
+ specification: tosca-simple-1.0
+ specification_section: 7.5.5
+ specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_RELATIONSHIPS_NETWORK_BINDTO'
+ description: >-
+ This type represents a network association relationship between Port and Compute node types.
+ derived_from: tosca.relationships.DependsOn
+ valid_target_types: [ tosca.capabilities.network.Bindable ]
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/tosca-simple-1.0.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/tosca-simple-1.0.yaml
new file mode 100644
index 0000000..f8cc520
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/tosca-simple-1.0.yaml
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+imports:
+ - artifacts.yaml
+ - capabilities.yaml
+ - data.yaml
+ - groups.yaml
+ - interfaces.yaml
+ - nodes.yaml
+ - policies.yaml
+ - relationships.yaml
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/artifacts.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/artifacts.yaml
new file mode 100644
index 0000000..2427d9f
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/artifacts.yaml
@@ -0,0 +1,84 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+artifact_types:
+
+ tosca.artifacts.nfv.SwImage:
+ _extensions:
+ shorthand_name: SwImage
+ type_qualified_name: tosca:SwImage
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.4.1
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896067'
+ derived_from: tosca.artifacts.Deployment.Image
+ properties:
+ name:
+ description: >-
+ Name of this software image.
+ type: string
+ required: true
+ version:
+ description: >-
+ Version of this software image.
+ type: string
+ required: true
+ checksum:
+ description: >-
+ Checksum of the software image file.
+ type: string
+ container_format:
+ description: >-
+ The container format describes the container file format in which software image is
+ provided.
+ type: string
+ required: true
+ disk_format:
+ description: >-
+ The disk format of a software image is the format of the underlying disk image.
+ type: string
+ required: true
+ min_disk:
+ description: >-
+ The minimal disk size requirement for this software image.
+ type: scalar-unit.size
+ required: true
+ min_ram:
+ description: >-
+ The minimal disk size requirement for this software image.
+ type: scalar-unit.size
+ required: false
+ size: # ARIA NOTE: section [5.4.1.1 Properties] calls this field 'Size'
+ description: >-
+ The size of this software image
+ type: scalar-unit.size
+ required: true
+ sw_image:
+ description: >-
+ A reference to the actual software image within VNF Package, or url.
+ type: string
+ required: true
+ operating_system:
+ description: >-
+ Identifies the operating system used in the software image.
+ type: string
+ required: false
+ supported _virtualization_enviroment:
+ description: >-
+ Identifies the virtualization environments (e.g. hypervisor) compatible with this software
+ image.
+ type: list
+ entry_schema:
+ type: string
+ required: false
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml
new file mode 100644
index 0000000..7b6363f
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml
@@ -0,0 +1,70 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+capability_types:
+
+ tosca.capabilities.nfv.VirtualBindable:
+ _extensions:
+ shorthand_name: VirtualBindable
+ type_qualified_name: tosca:VirtualBindable
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.5.1
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896069'
+ description: >-
+ A node type that includes the VirtualBindable capability indicates that it can be pointed by
+ tosca.relationships.nfv.VirtualBindsTo relationship type.
+ derived_from: tosca.capabilities.Node
+
+ tosca.capabilities.nfv.Metric:
+ _extensions:
+ shorthand_name: Metric
+ type_qualified_name: tosca:Metric
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.5.2
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896070'
+ description: >-
+ A node type that includes the Metric capability indicates that it can be monitored using an nfv.relationships.Monitor
+ relationship type.
+ derived_from: tosca.capabilities.Endpoint
+
+ tosca.capabilities.nfv.VirtualCompute:
+ _extensions:
+ shorthand_name: VirtualCompute
+ type_qualified_name: tosca:VirtualCompute
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.5.3
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896071'
+ derived_from: tosca.capabilities.Root
+ properties:
+ requested_additional_capabilities:
+ # ARIA NOTE: in section [5.5.3.1 Properties] the name of this property is
+ # "request_additional_capabilities", and its type is not a map, but
+ # tosca.datatypes.nfv.RequestedAdditionalCapability
+ description: >-
+ Describes additional capability for a particular VDU.
+ type: map
+ entry_schema:
+ type: tosca.datatypes.nfv.RequestedAdditionalCapability
+ required: false
+ virtual_memory:
+ description: >-
+ Describes virtual memory of the virtualized compute.
+ type: tosca.datatypes.nfv.VirtualMemory
+ required: true
+ virtual_cpu:
+ description: >-
+ Describes virtual CPU(s) of the virtualized compute.
+ type: tosca.datatypes.nfv.VirtualCpu
+ required: true
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml
new file mode 100644
index 0000000..889dcf7
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml
@@ -0,0 +1,318 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+data_types:
+
+ tosca.datatypes.nfv.L2AddressData:
+ # TBD
+ _extensions:
+ shorthand_name: L2AddressData
+ type_qualified_name: tosca:L2AddressData
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.1
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896055'
+
+ tosca.datatypes.nfv.L3AddressData:
+ _extensions:
+ shorthand_name: L3AddressData
+ type_qualified_name: tosca:L3AddressData
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.2
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896056'
+ description: >-
+ The L3AddressData type is a complex TOSCA data type used to describe L3AddressData information
+ element as defined in [ETSI GS NFV-IFA 011], it provides the information on the IP addresses
+ to be assigned to the connection point instantiated from the parent Connection Point
+ Descriptor.
+ derived_from: tosca.datatypes.Root
+ properties:
+ ip_address_assignment:
+ description: >-
+ Specify if the address assignment is the responsibility of management and orchestration
+ function or not. If it is set to True, it is the management and orchestration function
+ responsibility.
+ type: boolean
+ required: true
+ floating_ip_activated:
+ description: Specify if the floating IP scheme is activated on the Connection Point or not.
+ type: boolean
+ required: true
+ ip_address_type:
+ description: >-
+ Define address type. The address type should be aligned with the address type supported by
+ the layer_protocol properties of the parent VnfExtCpd.
+ type: string
+ required: false
+ constraints:
+ - valid_values: [ ipv4, ipv6 ]
+ number_of_ip_address:
+ description: >-
+ Minimum number of IP addresses to be assigned.
+ type: integer
+ required: false
+
+ tosca.datatypes.nfv.AddressData:
+ _extensions:
+ shorthand_name: AddressData
+ type_qualified_name: tosca:AddressData
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.3
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896057'
+ description: >-
+ The AddressData type is a complex TOSCA data type used to describe AddressData information
+ element as defined in [ETSI GS NFV-IFA 011], it provides information on the addresses to be
+ assigned to the connection point(s) instantiated from a Connection Point Descriptor.
+ derived_from: tosca.datatypes.Root
+ properties:
+ address_type:
+ description: >-
+ Describes the type of the address to be assigned to the connection point instantiated from
+ the parent Connection Point Descriptor. The content type shall be aligned with the address
+ type supported by the layerProtocol property of the parent Connection Point Descriptor.
+ type: string
+ required: true
+ constraints:
+ - valid_values: [ mac_address, ip_address ]
+ l2_address_data:
+ # Shall be present when the addressType is mac_address.
+ description: >-
+ Provides the information on the MAC addresses to be assigned to the connection point(s)
+ instantiated from the parent Connection Point Descriptor.
+ type: tosca.datatypes.nfv.L2AddressData # Empty in "GS NFV IFA011 V0.7.3"
+ required: false
+ l3_address_data:
+ # Shall be present when the addressType is ip_address.
+ description: >-
+ Provides the information on the IP addresses to be assigned to the connection point
+ instantiated from the parent Connection Point Descriptor.
+ type: tosca.datatypes.nfv.L3AddressData
+ required: false
+
+ tosca.datatypes.nfv.VirtualNetworkInterfaceRequirements:
+ _extensions:
+ shorthand_name: VirtualNetworkInterfaceRequirements
+ type_qualified_name: tosca:VirtualNetworkInterfaceRequirements
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.4
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896058'
+ description: >-
+ The VirtualNetworkInterfaceRequirements type is a complex TOSCA data type used to describe
+ VirtualNetworkInterfaceRequirements information element as defined in [ETSI GS NFV-IFA 011],
+ it provides the information to specify requirements on a virtual network interface realising the
+ CPs instantiated from this CPD.
+ derived_from: tosca.datatypes.Root
+ properties:
+ name:
+ description: >-
+ Provides a human readable name for the requirement.
+ type: string
+ required: false
+ description:
+ description: >-
+ Provides a human readable description for the requirement.
+ type: string
+ required: false
+ support_mandatory:
+ description: >-
+ Indicates whether fulfilling the constraint is mandatory (TRUE) for successful operation
+ or desirable (FALSE).
+ type: boolean
+ required: false
+ requirement:
+ description: >-
+ Specifies a requirement such as the support of SR-IOV, a particular data plane
+ acceleration library, an API to be exposed by a NIC, etc.
+ type: string # ARIA NOTE: the spec says "not specified", but TOSCA requires a type
+ required: true
+
+ tosca.datatypes.nfv.ConnectivityType:
+ _extensions:
+ shorthand_name: ConnectivityType
+ type_qualified_name: tosca:ConnectivityType
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.5
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896059'
+ description: >-
+ The TOSCA ConnectivityType type is a complex TOSCA data type used to describe ConnectivityType
+ information element as defined in [ETSI GS NFV-IFA 011].
+ derived_from: tosca.datatypes.Root
+ properties:
+ layer_protocol:
+ description: >-
+ Identifies the protocol this VL gives access to (ethernet, mpls, odu2, ipv4, ipv6,
+ pseudo_wire).
+ type: string
+ required: true
+ constraints:
+ - valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo_wire ]
+ flow_pattern:
+ description: >-
+ Identifies the flow pattern of the connectivity (Line, Tree, Mesh).
+ type: string
+ required: false
+
+ tosca.datatypes.nfv.RequestedAdditionalCapability:
+ _extensions:
+ shorthand_name: RequestedAdditionalCapability
+ type_qualified_name: tosca:RequestedAdditionalCapability
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.6
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896060'
+ description: >-
+ RequestAdditionalCapability describes additional capability for a particular VDU.
+ derived_from: tosca.datatypes.Root
+ properties:
+ request_additional_capability_name:
+ description: >-
+ Identifies a requested additional capability for the VDU.
+ type: string
+ required: true
+ support_mandatory:
+ description: >-
+ Indicates whether the requested additional capability is mandatory for successful
+ operation.
+ type: string
+ required: true
+ min_requested_additional_capability_version:
+ description: >-
+ Identifies the minimum version of the requested additional capability.
+ type: string
+ required: false
+ preferred_requested_additional_capability_version:
+ description: >-
+ Identifies the preferred version of the requested additional capability.
+ type: string
+ required: false
+ target_performance_parameters:
+ description: >-
+ Identifies specific attributes, dependent on the requested additional capability type.
+ type: map
+ entry_schema:
+ type: string
+ required: true
+
+ tosca.datatypes.nfv.VirtualMemory:
+ _extensions:
+ shorthand_name: VirtualMemory
+ type_qualified_name: tosca:VirtualMemory
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.7
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896061'
+ description: >-
+ VirtualMemory describes virtual memory for a particular VDU.
+ derived_from: tosca.datatypes.Root
+ properties:
+ virtual_mem_size:
+ description: Amount of virtual memory.
+ type: scalar-unit.size
+ required: true
+ virtual_mem_oversubscription_policy:
+ description: >-
+ The memory core oversubscription policy in terms of virtual memory to physical memory on
+ the platform. The cardinality can be 0 during the allocation request, if no particular
+ value is requested.
+ type: string
+ required: false
+ numa_enabled:
+ description: >-
+ It specifies the memory allocation to be cognisant of the relevant process/core
+ allocation. The cardinality can be 0 during the allocation request, if no particular value
+ is requested.
+ type: boolean
+ required: false
+
+ tosca.datatypes.nfv.VirtualCpu:
+ _extensions:
+ shorthand_name: VirtualCpu
+ type_qualified_name: tosca:VirtualCpu
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.8
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896062'
+ description: >-
+ VirtualMemory describes virtual memory for a particular VDU.
+ derived_from: tosca.datatypes.Root
+ properties:
+ cpu_architecture:
+ description: >-
+ CPU architecture type. Examples are x86, ARM.
+ type: string
+ required: false
+ num_virtual_cpu:
+ description: >-
+ Number of virtual CPUs.
+ type: integer
+ required: true
+ virtual_cpu_clock:
+ description: >-
+ Minimum virtual CPU clock rate.
+ type: scalar-unit.frequency
+ required: false
+ virtual_cpu_oversubscription_policy:
+ description: >-
+ CPU core oversubscription policy.
+ type: string
+ required: false
+ virtual_cpu_pinning:
+ description: >-
+ The virtual CPU pinning configuration for the virtualized compute resource.
+ type: tosca.datatypes.nfv.VirtualCpuPinning
+ required: false
+
+ tosca.datatypes.nfv.VirtualCpuPinning:
+ _extensions:
+ shorthand_name: VirtualCpuPinning
+ type_qualified_name: tosca:VirtualCpuPinning
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.9
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896064'
+ description: >-
+ VirtualCpuPinning describes CPU pinning configuration for a particular CPU.
+ derived_from: tosca.datatypes.Root
+ properties:
+ cpu_pinning_policy:
+ description: >-
+ Indicates the policy for CPU pinning.
+ type: string
+ constraints:
+ - valid_values: [ static, dynamic ]
+ required: false
+ cpu_pinning_map:
+ description: >-
+ If cpuPinningPolicy is defined as "static", the cpuPinningMap provides the map of pinning
+ virtual CPU cores to physical CPU cores/threads.
+ type: map
+ entry_schema:
+ type: string
+ required: false
+
+ tosca.datatypes.nfv.VnfcConfigurableProperties:
+ _extensions:
+ shorthand_name: VnfcconfigurableProperties
+ type_qualified_name: tosca:VnfcconfigurableProperties
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.3.10
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896065'
+ # ARIA NOTE: description is mangled in spec
+ description: >-
+ VnfcConfigurableProperties describes additional configurable properties of a VNFC.
+ derived_from: tosca.datatypes.Root
+ properties:
+ additional_vnfc_configurable_properties:
+ description: >-
+ Describes additional configuration for VNFC.
+ type: map
+ entry_schema:
+ type: string
+ required: false
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml
new file mode 100644
index 0000000..8d1f0a2
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml
@@ -0,0 +1,260 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+node_types:
+
+ tosca.nodes.nfv.VDU.Compute:
+ _extensions:
+ shorthand_name: VDU.Compute
+ type_qualified_name: tosca:VDU.Compute
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.9.2
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896079'
+ description: >-
+ The TOSCA nfv.VDU.Compute node type represents the virtual compute part of a VDU entity which
+ it mainly describes the deployment and operational behavior of a VNF component (VNFC), as
+ defined by [ETSI NFV IFA011].
+ derived_from: tosca.nodes.Compute
+ properties:
+ name:
+ description: >-
+ Human readable name of the VDU.
+ type: string
+ required: true
+ description:
+ description: >-
+ Human readable description of the VDU.
+ type: string
+ required: true
+ boot_order:
+ description: >-
+ The key indicates the boot index (lowest index defines highest boot priority).
+ The Value references a descriptor from which a valid boot device is created e.g.
+ VirtualStorageDescriptor from which a VirtualStorage instance is created. If no boot order
+ is defined the default boot order defined in the VIM or NFVI shall be used.
+ type: list # ARIA NOTE: an explicit index (boot index) is unnecessary, contrary to IFA011
+ entry_schema:
+ type: string
+ required: false
+ nfvi_constraints:
+ description: >-
+ Describes constraints on the NFVI for the VNFC instance(s) created from this VDU.
+ For example, aspects of a secure hosting environment for the VNFC instance that involve
+ additional entities or processes. More software images can be attached to the
+ virtualization container using virtual_storage.
+ type: list
+ entry_schema:
+ type: string
+ required: false
+ configurable_properties:
+ description: >-
+ Describes the configurable properties of all VNFC instances based on this VDU.
+ type: map
+ entry_schema:
+ type: tosca.datatypes.nfv.VnfcConfigurableProperties
+ required: true
+ attributes:
+ # ARIA NOTE: The attributes are only described in section [5.9.2.5 Definition], but are not
+ # mentioned in section [5.9.2.2 Attributes]. Additionally, it does not seem to make sense to
+ # deprecate inherited attributes, as it breaks the inheritence contract.
+ private_address:
+ type: string
+ status: deprecated
+ public_address:
+ type: string
+ status: deprecated
+ networks:
+ type: map
+ entry_schema:
+ type: tosca.datatypes.network.NetworkInfo
+ status: deprecated
+ ports:
+ type: map
+ entry_schema:
+ type: tosca.datatypes.network.PortInfo
+ status: deprecated
+ capabilities:
+ virtual_compute:
+ description: >-
+ Describes virtual compute resources capabilities.
+ type: tosca.capabilities.nfv.VirtualCompute
+ virtual_binding:
+ description: >-
+ Defines ability of VirtualBindable.
+ type: tosca.capabilities.nfv.VirtualBindable
+ monitoring_parameter:
+ # ARIA NOTE: commented out in 5.9.2.5
+ description: >-
+ Monitoring parameter, which can be tracked for a VNFC based on this VDU. Examples include:
+ memory-consumption, CPU-utilisation, bandwidth-consumption, VNFC downtime, etc.
+ type: tosca.capabilities.nfv.Metric
+ #requirements:
+ # ARIA NOTE: virtual_storage is TBD
+
+ # ARIA NOTE: csd04 attempts to deprecate the inherited local_storage requirement, but this
+ # is not possible in TOSCA
+ artifacts:
+ sw_image:
+ description: >-
+ Describes the software image which is directly loaded on the virtualization container
+ realizing this virtual storage.
+ file: '' # ARIA NOTE: missing value even though it is required in TOSCA
+ type: tosca.artifacts.nfv.SwImage
+
+ tosca.nodes.nfv.VDU.VirtualStorage:
+ _extensions:
+ shorthand_name: VirtualStorage # ARIA NOTE: seems wrong in spec
+ type_qualified_name: tosca:VirtualStorage # ARIA NOTE: seems wrong in spec
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.9.3
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896080'
+ description: >-
+ The NFV VirtualStorage node type represents a virtual storage entity which it describes the
+ deployment and operational behavior of a virtual storage resources, as defined by
+ [ETSI NFV IFA011].
+ derived_from: tosca.nodes.Root
+ properties:
+ type_of_storage:
+ description: >-
+ Type of virtualized storage resource.
+ type: string
+ required: true
+ size_of_storage:
+ description: >-
+ Size of virtualized storage resource (in GB).
+ type: scalar-unit.size
+ required: true
+ rdma_enabled:
+ description: >-
+ Indicate if the storage support RDMA.
+ type: boolean
+ required: false
+ artifacts:
+ sw_image:
+ description: >-
+ Describes the software image which is directly loaded on the virtualization container
+ realizing this virtual storage.
+ file: '' # ARIA NOTE: missing in spec
+ type: tosca.artifacts.nfv.SwImage
+
+ tosca.nodes.nfv.Cpd:
+ _extensions:
+ shorthand_name: Cpd
+ type_qualified_name: tosca:Cpd
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.9.4
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896081'
+ description: >-
+ The TOSCA nfv.Cpd node represents network connectivity to a compute resource or a VL as defined
+ by [ETSI GS NFV-IFA 011]. This is an abstract type used as parent for the various Cpd types.
+ derived_from: tosca.nodes.Root
+ properties:
+ layer_protocol:
+ description: >-
+ Identifies which protocol the connection point uses for connectivity purposes.
+ type: string
+ constraints:
+ - valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo_wire ]
+ required: false
+ role: # Name in ETSI NFV IFA011 v0.7.3 cpRole
+ description: >-
+ Identifies the role of the port in the context of the traffic flow patterns in the VNF or
+ parent NS. For example a VNF with a tree flow pattern within the VNF will have legal
+ cpRoles of ROOT and LEAF.
+ type: string
+ constraints:
+ - valid_values: [ root, leaf ]
+ required: false
+ description:
+ description: >-
+ Provides human-readable information on the purpose of the connection point
+ (e.g. connection point for control plane traffic).
+ type: string
+ required: false
+ address_data:
+ description: >-
+ Provides information on the addresses to be assigned to the connection point(s) instantiated
+ from this Connection Point Descriptor.
+ type: list
+ entry_schema:
+ type: tosca.datatypes.nfv.AddressData
+ required: false
+
+ tosca.nodes.nfv.VduCpd:
+ _extensions:
+ shorthand_name: VduCpd
+ type_qualified_name: tosca:VduCpd
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.9.5
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896082'
+ description: >-
+ The TOSCA nfv.VduCpd node type represents a type of TOSCA Cpd node and describes network
+ connectivity between a VNFC instance (based on this VDU) and an internal VL as defined by
+ [ETSI GS NFV-IFA 011].
+ derived_from: tosca.nodes.nfv.Cpd
+ properties:
+ bitrate_requirement:
+ description: >-
+ Bitrate requirement on this connection point.
+ type: integer
+ required: false
+ virtual_network_interface_requirements:
+ description: >-
+ Specifies requirements on a virtual network interface realising the CPs instantiated from
+ this CPD.
+ type: list
+ entry_schema:
+ type: VirtualNetworkInterfaceRequirements
+ required: false
+ requirements:
+ # ARIA NOTE: seems to be a leftover from csd03
+ # - virtual_link:
+ # description: Describes the requirements for linking to virtual link
+ # capability: tosca.capabilities.nfv.VirtualLinkable
+ # relationship: tosca.relationships.nfv.VirtualLinksTo
+ # node: tosca.nodes.nfv.VnfVirtualLinkDesc
+ - virtual_binding:
+ capability: tosca.capabilities.nfv.VirtualBindable
+ relationship: tosca.relationships.nfv.VirtualBindsTo
+ node: tosca.nodes.nfv.VDU.Compute # ARIA NOTE: seems wrong in spec
+
+ tosca.nodes.nfv.VnfVirtualLinkDesc:
+ _extensions:
+ shorthand_name: VnfVirtualLinkDesc
+ type_qualified_name: tosca:VnfVirtualLinkDesc
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.9.6
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896083'
+ description: >-
+ The TOSCA nfv.VnfVirtualLinkDesc node type represents a logical internal virtual link as
+ defined by [ETSI GS NFV-IFA 011].
+ derived_from: tosca.nodes.Root
+ properties:
+ connectivity_type:
+ description: >-
+ specifies the protocol exposed by the VL and the flow pattern supported by the VL.
+ type: tosca.datatypes.nfv.ConnectivityType
+ required: true
+ description:
+ description: >-
+ Provides human-readable information on the purpose of the VL (e.g. control plane traffic).
+ type: string
+ required: false
+ test_access:
+ description: >-
+ Test access facilities available on the VL (e.g. none, passive, monitoring, or active
+ (intrusive) loopbacks at endpoints.
+ type: string
+ required: false
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml
new file mode 100644
index 0000000..4cf99a2
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml
@@ -0,0 +1,43 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+relationship_types:
+
+ tosca.relationships.nfv.VirtualBindsTo:
+ _extensions:
+ shorthand_name: VirtualBindsTo
+ type_qualified_name: tosca:VirtualBindsTo
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.7.1
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896074'
+ description: >-
+ This relationship type represents an association relationship between VDU and CP node types.
+ derived_from: tosca.relationships.DependsOn
+ valid_target_types: [ tosca.capabilities.nfv.VirtualBindable ]
+
+ # ARIA NOTE: csd04 lacks the definition of tosca.relationships.nfv.Monitor (the derived_from and
+ # valid_target_types), so we are using the definition in csd03 section 8.4.2.
+ tosca.relationships.nfv.Monitor:
+ _extensions:
+ shorthand_name: Monitor
+ type_qualified_name: tosca:Monitor
+ specification: tosca-simple-nfv-1.0
+ specification_section: 5.7.2
+ specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896075'
+ description: >-
+ This relationship type represents an association relationship to the Metric capability of VDU
+ node types.
+ derived_from: tosca.relationships.ConnectsTo
+ valid_target_types: [ tosca.capabilities.nfv.Metric ]
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml
new file mode 100644
index 0000000..764c739
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+imports:
+ - artifacts.yaml
+ - capabilities.yaml
+ - data.yaml
+ - nodes.yaml
+ - relationships.yaml
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_nfv_v1_0/__init__.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_nfv_v1_0/__init__.py
new file mode 100644
index 0000000..313e3ef
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_nfv_v1_0/__init__.py
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 .presenter import ToscaSimpleNfvPresenter1_0
+
+__all__ = (
+ 'ToscaSimpleNfvPresenter1_0',)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
new file mode 100644
index 0000000..64178aa
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
@@ -0,0 +1,43 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import FrozenList
+from aria.utils.caching import cachedmethod
+
+from ..simple_v1_0 import ToscaSimplePresenter1_0
+
+
+class ToscaSimpleNfvPresenter1_0(ToscaSimplePresenter1_0): # pylint: disable=invalid-name,abstract-method
+ """
+ ARIA presenter for the `TOSCA Simple Profile for NFV v1.0 csd04 <http://docs.oasis-open.org
+ /tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html>`__.
+
+ Supported ``tosca_definitions_version`` values:
+
+ * ``tosca_simple_profile_for_nfv_1_0``
+ """
+
+ DSL_VERSIONS = ('tosca_simple_profile_for_nfv_1_0',)
+ ALLOWED_IMPORTED_DSL_VERSIONS = ('tosca_simple_yaml_1_0', 'tosca_simple_profile_for_nfv_1_0')
+ SIMPLE_PROFILE_FOR_NFV_LOCATION = 'tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml'
+
+ # Presenter
+
+ @cachedmethod
+ def _get_import_locations(self, context):
+ import_locations = super(ToscaSimpleNfvPresenter1_0, self)._get_import_locations(context)
+ if context.presentation.import_profile:
+ return FrozenList([self.SIMPLE_PROFILE_FOR_NFV_LOCATION] + import_locations)
+ return import_locations
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/__init__.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/__init__.py
new file mode 100644
index 0000000..61995db
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/__init__.py
@@ -0,0 +1,199 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+"""
+Parser implementation of `TOSCA Simple Profile v1.0 cos01 <http://docs.oasis-open.org/tosca
+/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html>`__.
+
+.. autosummary::
+ :nosignatures:
+
+ aria_extension_tosca.simple_v1_0.ToscaSimplePresenter1_0
+
+Assignments
+-----------
+
+.. autosummary::
+ :nosignatures:
+
+ aria_extension_tosca.simple_v1_0.PropertyAssignment
+ aria_extension_tosca.simple_v1_0.OperationAssignment
+ aria_extension_tosca.simple_v1_0.InterfaceAssignment
+ aria_extension_tosca.simple_v1_0.RelationshipAssignment
+ aria_extension_tosca.simple_v1_0.RequirementAssignment
+ aria_extension_tosca.simple_v1_0.AttributeAssignment
+ aria_extension_tosca.simple_v1_0.CapabilityAssignment
+ aria_extension_tosca.simple_v1_0.ArtifactAssignment
+
+Definitions
+-----------
+
+.. autosummary::
+ :nosignatures:
+
+ aria_extension_tosca.simple_v1_0.PropertyDefinition
+ aria_extension_tosca.simple_v1_0.AttributeDefinition
+ aria_extension_tosca.simple_v1_0.ParameterDefinition
+ aria_extension_tosca.simple_v1_0.OperationDefinition
+ aria_extension_tosca.simple_v1_0.InterfaceDefinition
+ aria_extension_tosca.simple_v1_0.RelationshipDefinition
+ aria_extension_tosca.simple_v1_0.RequirementDefinition
+ aria_extension_tosca.simple_v1_0.CapabilityDefinition
+
+Filters
+-------
+
+.. autosummary::
+ :nosignatures:
+
+ aria_extension_tosca.simple_v1_0.CapabilityFilter
+ aria_extension_tosca.simple_v1_0.NodeFilter
+
+Miscellaneous
+-------------
+
+.. autosummary::
+ :nosignatures:
+
+ aria_extension_tosca.simple_v1_0.Description
+ aria_extension_tosca.simple_v1_0.MetaData
+ aria_extension_tosca.simple_v1_0.Repository
+ aria_extension_tosca.simple_v1_0.Import
+ aria_extension_tosca.simple_v1_0.ConstraintClause
+ aria_extension_tosca.simple_v1_0.EntrySchema
+ aria_extension_tosca.simple_v1_0.OperationImplementation
+ aria_extension_tosca.simple_v1_0.SubstitutionMappingsRequirement
+ aria_extension_tosca.simple_v1_0.SubstitutionMappingsCapability
+ aria_extension_tosca.simple_v1_0.SubstitutionMappings
+
+Templates
+---------
+
+.. autosummary::
+ :nosignatures:
+
+ aria_extension_tosca.simple_v1_0.NodeTemplate
+ aria_extension_tosca.simple_v1_0.RelationshipTemplate
+ aria_extension_tosca.simple_v1_0.GroupTemplate
+ aria_extension_tosca.simple_v1_0.PolicyTemplate
+ aria_extension_tosca.simple_v1_0.TopologyTemplate
+ aria_extension_tosca.simple_v1_0.ServiceTemplate
+
+Types
+-----
+
+.. autosummary::
+ :nosignatures:
+
+ aria_extension_tosca.simple_v1_0.ArtifactType
+ aria_extension_tosca.simple_v1_0.DataType
+ aria_extension_tosca.simple_v1_0.CapabilityType
+ aria_extension_tosca.simple_v1_0.InterfaceType
+ aria_extension_tosca.simple_v1_0.RelationshipType
+ aria_extension_tosca.simple_v1_0.NodeType
+ aria_extension_tosca.simple_v1_0.GroupType
+ aria_extension_tosca.simple_v1_0.PolicyType
+
+Data types
+----------
+
+.. autosummary::
+ :nosignatures:
+
+ aria_extension_tosca.simple_v1_0.Timestamp
+ aria_extension_tosca.simple_v1_0.Version
+ aria_extension_tosca.simple_v1_0.Range
+ aria_extension_tosca.simple_v1_0.List
+ aria_extension_tosca.simple_v1_0.Map
+ aria_extension_tosca.simple_v1_0.ScalarSize
+ aria_extension_tosca.simple_v1_0.ScalarTime
+ aria_extension_tosca.simple_v1_0.ScalarFrequency
+"""
+
+from .presenter import ToscaSimplePresenter1_0
+from .assignments import (PropertyAssignment, OperationAssignment, InterfaceAssignment,
+ RelationshipAssignment, RequirementAssignment, AttributeAssignment,
+ CapabilityAssignment, ArtifactAssignment)
+from .definitions import (PropertyDefinition, AttributeDefinition, ParameterDefinition,
+ OperationDefinition, InterfaceDefinition, RelationshipDefinition,
+ RequirementDefinition, CapabilityDefinition)
+from .filters import CapabilityFilter, NodeFilter
+from .misc import (Description, MetaData, Repository, Import, ConstraintClause, EntrySchema,
+ OperationImplementation, SubstitutionMappingsRequirement,
+ SubstitutionMappingsCapability, SubstitutionMappings)
+from .templates import (NodeTemplate, RelationshipTemplate, GroupTemplate, PolicyTemplate,
+ TopologyTemplate, ServiceTemplate)
+from .types import (ArtifactType, DataType, CapabilityType, InterfaceType, RelationshipType,
+ NodeType, GroupType, PolicyType)
+from .data_types import (Timestamp, Version, Range, List, Map, ScalarSize, ScalarTime,
+ ScalarFrequency)
+
+MODULES = (
+ 'modeling',
+ 'presentation')
+
+__all__ = (
+ 'MODULES',
+ 'ToscaSimplePresenter1_0',
+ 'PropertyAssignment',
+ 'OperationAssignment',
+ 'InterfaceAssignment',
+ 'RelationshipAssignment',
+ 'RequirementAssignment',
+ 'AttributeAssignment',
+ 'CapabilityAssignment',
+ 'ArtifactAssignment',
+ 'PropertyDefinition',
+ 'AttributeDefinition',
+ 'ParameterDefinition',
+ 'OperationDefinition',
+ 'InterfaceDefinition',
+ 'RelationshipDefinition',
+ 'RequirementDefinition',
+ 'CapabilityDefinition',
+ 'CapabilityFilter',
+ 'NodeFilter',
+ 'Description',
+ 'MetaData',
+ 'Repository',
+ 'Import',
+ 'ConstraintClause',
+ 'EntrySchema',
+ 'OperationImplementation',
+ 'SubstitutionMappingsRequirement',
+ 'SubstitutionMappingsCapability',
+ 'SubstitutionMappings',
+ 'NodeTemplate',
+ 'RelationshipTemplate',
+ 'GroupTemplate',
+ 'PolicyTemplate',
+ 'TopologyTemplate',
+ 'ServiceTemplate',
+ 'ArtifactType',
+ 'DataType',
+ 'CapabilityType',
+ 'InterfaceType',
+ 'RelationshipType',
+ 'NodeType',
+ 'GroupType',
+ 'PolicyType',
+ 'Timestamp',
+ 'Version',
+ 'Range',
+ 'List',
+ 'Map',
+ 'ScalarSize',
+ 'ScalarTime',
+ 'ScalarFrequency')
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/assignments.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/assignments.py
new file mode 100644
index 0000000..7b48ed0
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/assignments.py
@@ -0,0 +1,453 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import FrozenDict
+from aria.utils.caching import cachedmethod
+from aria.parser import implements_specification
+from aria.parser.presentation import (AsIsPresentation, has_fields, allow_unknown_fields,
+ short_form_field, primitive_field, object_field,
+ object_dict_field, object_dict_unknown_fields,
+ field_validator, type_validator)
+
+from .filters import NodeFilter
+from .misc import Description, OperationImplementation
+from .modeling.parameters import get_assigned_and_defined_parameter_values
+from .presentation.extensible import ExtensiblePresentation
+from .presentation.field_validators import (node_template_or_type_validator,
+ relationship_template_or_type_validator,
+ capability_definition_or_type_validator,
+ node_filter_validator)
+from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
+
+
+
+@implements_specification('3.5.9', 'tosca-simple-1.0')
+class PropertyAssignment(AsIsPresentation):
+ """
+ This section defines the grammar for assigning values to named properties within TOSCA Node and
+ Relationship templates that are defined in their corresponding named types.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_PROPERTY_VALUE_ASSIGNMENT>`__
+ """
+
+
+@short_form_field('implementation')
+@has_fields
+@implements_specification('3.5.13-2', 'tosca-simple-1.0')
+class OperationAssignment(ExtensiblePresentation):
+ """
+ An operation definition defines a named function or procedure that can be bound to an
+ implementation artifact (e.g., a script).
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_OPERATION_DEF>`__
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description string for the associated named operation.
+
+ :type: :class:`Description`
+ """
+
+ @object_field(OperationImplementation)
+ def implementation(self):
+ """
+ The optional implementation artifact name (e.g., a script file name within a TOSCA CSAR
+ file).
+
+ :type: :class:`OperationImplementation`
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def inputs(self):
+ """
+ The optional list of input property assignments (i.e., parameters assignments) for operation
+ definitions that are within TOSCA Node or Relationship Template definitions. This includes
+ when operation definitions are included as part of a Requirement assignment in a Node
+ Template.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`}
+ """
+
+ @cachedmethod
+ def _get_extensions(self, context):
+ def update_inherited_extensions(extensions, interface_type):
+ parent = interface_type._get_parent(context)
+ if parent is not None:
+ update_inherited_extensions(extensions, parent)
+ operation_definition = interface_type.operations.get(self._name)
+ if operation_definition is not None:
+ if operation_definition._extensions:
+ extensions.update(operation_definition._extensions)
+
+ extensions = {}
+ update_inherited_extensions(extensions, self._container._get_type(context))
+ if self._container._extensions:
+ extensions.update(self._container._extensions)
+ if self._extensions:
+ extensions.update(self._extensions)
+ return extensions
+
+
+@allow_unknown_fields
+@has_fields
+@implements_specification('3.5.14-2', 'tosca-simple-1.0')
+class InterfaceAssignment(ExtensiblePresentation):
+ """
+ An interface definition defines a named interface that can be associated with a Node or
+ Relationship Type.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_INTERFACE_DEF>`__
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def inputs(self):
+ """
+ The optional list of input property assignments (i.e., parameters assignments) for interface
+ definitions that are within TOSCA Node or Relationship Template definitions. This includes
+ when interface definitions are referenced as part of a Requirement assignment in a Node
+ Template.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`}
+ """
+
+ @object_dict_unknown_fields(OperationAssignment)
+ def operations(self):
+ """
+ :type: {:obj:`basestring`: :class:`OperationAssignment`}
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ the_type = self._container._get_type(context)
+
+ if isinstance(the_type, tuple):
+ # In RelationshipAssignment
+ the_type = the_type[0] # This could be a RelationshipTemplate
+
+ interface_definitions = the_type._get_interfaces(context) \
+ if the_type is not None else None
+ interface_definition = interface_definitions.get(self._name) \
+ if interface_definitions is not None else None
+ return interface_definition._get_type(context) \
+ if interface_definition is not None else None
+
+ def _validate(self, context):
+ super(InterfaceAssignment, self)._validate(context)
+ if self.operations:
+ for operation in self.operations.itervalues(): # pylint: disable=no-member
+ operation._validate(context)
+
+
+@short_form_field('type')
+@has_fields
+class RelationshipAssignment(ExtensiblePresentation):
+ """
+ Relationship assignment.
+ """
+
+ @field_validator(relationship_template_or_type_validator)
+ @primitive_field(str)
+ def type(self):
+ """
+ The optional reserved keyname used to provide the name of the Relationship Type for the
+ requirement assignment's relationship keyname.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def properties(self):
+ """
+ ARIA NOTE: This field is not mentioned in the spec, but is implied.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`}
+ """
+
+ @object_dict_field(InterfaceAssignment)
+ def interfaces(self):
+ """
+ The optional reserved keyname used to reference declared (named) interface definitions of
+ the corresponding Relationship Type in order to provide Property assignments for these
+ interfaces or operations of these interfaces.
+
+ :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ type_name = self.type
+ if type_name is not None:
+ the_type = context.presentation.get_from_dict('service_template', 'topology_template',
+ 'relationship_templates', type_name)
+ if the_type is not None:
+ return the_type, 'relationship_template'
+ the_type = get_type_by_name(context, type_name, 'relationship_types')
+ if the_type is not None:
+ return the_type, 'relationship_type'
+ return None, None
+
+
+@short_form_field('node')
+@has_fields
+@implements_specification('3.7.2', 'tosca-simple-1.0')
+class RequirementAssignment(ExtensiblePresentation):
+ """
+ A Requirement assignment allows template authors to provide either concrete names of TOSCA
+ templates or provide abstract selection criteria for providers to use to find matching TOSCA
+ templates that are used to fulfill a named requirement's declared TOSCA Node Type.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_REQUIREMENT_ASSIGNMENT>`__
+ """
+
+ # The example in 3.7.2.2.2 shows unknown fields in addition to these, but is this a mistake?
+
+ @field_validator(capability_definition_or_type_validator)
+ @primitive_field(str)
+ def capability(self):
+ """
+ The optional reserved keyname used to provide the name of either a:
+
+ * Capability definition within a target node template that can fulfill the requirement.
+ * Capability Type that the provider will use to select a type-compatible target node
+ template to fulfill the requirement at runtime.
+
+ :type: :obj:`basestring`
+ """
+
+ @field_validator(node_template_or_type_validator)
+ @primitive_field(str)
+ def node(self):
+ """
+ The optional reserved keyname used to identify the target node of a relationship.
+ Specifically, it is used to provide either a:
+
+ * Node Template name that can fulfill the target node requirement.
+ * Node Type name that the provider will use to select a type-compatible node template to
+ fulfill the requirement at runtime.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(RelationshipAssignment)
+ def relationship(self):
+ """
+ The optional reserved keyname used to provide the name of either a:
+
+ * Relationship Template to use to relate the source node to the (capability in the) target
+ node when fulfilling the requirement.
+ * Relationship Type that the provider will use to select a type-compatible relationship
+ template to relate the source node to the target node at runtime.
+
+ :type: :class:`RelationshipAssignment`
+ """
+
+ @field_validator(node_filter_validator)
+ @object_field(NodeFilter)
+ def node_filter(self):
+ """
+ The optional filter definition that TOSCA orchestrators or providers would use to select a
+ type-compatible target node that can fulfill the associated abstract requirement at runtime.
+
+ :type: :class:`NodeFilter`
+ """
+
+ @cachedmethod
+ def _get_node(self, context):
+ node = self.node
+
+ if node is not None:
+ node_template = context.presentation.get_from_dict('service_template',
+ 'topology_template',
+ 'node_templates', node)
+ if node_template is not None:
+ return node_template, 'node_template'
+ node_type = get_type_by_name(context, node, 'node_types')
+ if node_type is not None:
+ return node_type, 'node_type'
+
+ return None, None
+
+ @cachedmethod
+ def _get_capability(self, context):
+ capability = self.capability
+
+ if capability is not None:
+ node, node_variant = self._get_node(context)
+ if node_variant == 'node_template':
+ capabilities = node._get_capabilities(context)
+ if capability in capabilities:
+ return capabilities[capability], 'capability_assignment'
+ capability_type = get_type_by_name(context, capability, 'capability_types')
+ if capability_type is not None:
+ return capability_type, 'capability_type'
+
+ return None, None
+
+
+@implements_specification('3.5.11', 'tosca-simple-1.0')
+class AttributeAssignment(AsIsPresentation):
+ """
+ This section defines the grammar for assigning values to named attributes within TOSCA Node and
+ Relationship templates which are defined in their corresponding named types.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_ATTRIBUTE_VALUE_ASSIGNMENT>`__
+ """
+
+
+@has_fields
+@implements_specification('3.7.1', 'tosca-simple-1.0')
+class CapabilityAssignment(ExtensiblePresentation):
+ """
+ A capability assignment allows node template authors to assign values to properties and
+ attributes for a named capability definition that is part of a Node Template's type definition.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_CAPABILITY_ASSIGNMENT>`__
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def properties(self):
+ """
+ An optional list of property definitions for the Capability definition.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`}
+ """
+
+ @object_dict_field(AttributeAssignment)
+ def attributes(self):
+ """
+ An optional list of attribute definitions for the Capability definition.
+
+ :type: {:obj:`basestring`: :class:`AttributeAssignment`}
+ """
+
+ @cachedmethod
+ def _get_definition(self, context):
+ node_type = self._container._get_type(context)
+ capability_definitions = node_type._get_capabilities(context) \
+ if node_type is not None else None
+ return capability_definitions.get(self._name) \
+ if capability_definitions is not None else None
+
+ @cachedmethod
+ def _get_type(self, context):
+ capability_definition = self._get_definition(context)
+ return capability_definition._get_type(context) \
+ if capability_definition is not None else None
+
+
+@has_fields
+@implements_specification('3.5.6', 'tosca-simple-1.0')
+class ArtifactAssignmentForType(ExtensiblePresentation):
+ """
+ An artifact definition defines a named, typed file that can be associated with Node Type or Node
+ Template and used by orchestration engine to facilitate deployment and implementation of
+ interface operations.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_ARTIFACT_DEF>`__
+ """
+
+ @field_validator(type_validator('artifact type', convert_name_to_full_type_name,
+ 'artifact_types'))
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The required artifact type for the artifact definition.
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_field(str, required=True)
+ def file(self):
+ """
+ The required URI string (relative or absolute) which can be used to locate the artifact's
+ file.
+
+ :type: :obj:`basestring`
+ """
+
+ @field_validator(type_validator('repository', 'repositories'))
+ @primitive_field(str)
+ def repository(self):
+ """
+ The optional name of the repository definition which contains the location of the external
+ repository that contains the artifact. The artifact is expected to be referenceable by its
+ file URI within the repository.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the artifact definition.
+
+ :type: :class:`Description`
+ """
+
+ @primitive_field(str)
+ def deploy_path(self):
+ """
+ The file path the associated file would be deployed into within the target node's container.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def properties(self):
+ """
+ ARIA NOTE: This field is not mentioned in the spec, but is implied.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`}
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.type, 'artifact_types')
+
+ @cachedmethod
+ def _get_repository(self, context):
+ return context.presentation.get_from_dict('service_template', 'repositories',
+ self.repository)
+
+ @cachedmethod
+ def _get_property_values(self, context):
+ return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))
+
+ @cachedmethod
+ def _validate(self, context):
+ super(ArtifactAssignmentForType, self)._validate(context)
+
+
+class ArtifactAssignment(ArtifactAssignmentForType):
+ @cachedmethod
+ def _validate(self, context):
+ super(ArtifactAssignment, self)._validate(context)
+ self._get_property_values(context)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/data_types.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/data_types.py
new file mode 100644
index 0000000..216f1e4
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/data_types.py
@@ -0,0 +1,561 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 datetime import (datetime, tzinfo, timedelta)
+try:
+ from functools import total_ordering
+except ImportError:
+ from total_ordering import total_ordering
+
+from aria.parser import implements_specification
+from aria.utils.collections import (StrictDict, OrderedDict)
+from aria.utils.formatting import safe_repr
+
+from .modeling.data_types import (coerce_to_data_type_class, report_issue_for_bad_format,
+ coerce_value)
+
+
+class Timezone(tzinfo):
+ """
+ Timezone as fixed offset in hours and minutes east of UTC.
+ """
+
+ def __init__(self, hours=0, minutes=0):
+ super(Timezone, self).__init__()
+ self._offset = timedelta(hours=hours, minutes=minutes)
+
+ def utcoffset(self, dt): # pylint: disable=unused-argument
+ return self._offset
+
+ def tzname(self, dt): # pylint: disable=unused-argument
+ return str(self._offset)
+
+ def dst(self, dt): # pylint: disable=unused-argument
+ return Timezone._ZERO
+
+ _ZERO = timedelta(0)
+
+
+UTC = Timezone()
+
+
+@total_ordering
+@implements_specification('timestamp', 'yaml-1.1')
+class Timestamp(object):
+ '''
+ TOSCA timestamps follow the YAML specification, which in turn is a variant of ISO8601.
+
+ Long forms and short forms (without time of day and assuming UTC timezone) are supported for
+ parsing. The canonical form (for rendering) matches the long form at the UTC timezone.
+
+ See the `Timestamp Language-Independent Type for YAML Version 1.1 (Working Draft 2005-01-18)
+ <http://yaml.org/type/timestamp.html>`__
+ '''
+
+ REGULAR_SHORT = r'^(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9])-(?P<day>[0-9][0-9])$'
+ REGULAR_LONG = \
+ r'^(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9]?)-(?P<day>[0-9][0-9]?)' + \
+ r'([Tt]|[ \t]+)' \
+ r'(?P<hour>[0-9][0-9]?):(?P<minute>[0-9][0-9]):(?P<second>[0-9][0-9])' + \
+ r'(?P<fraction>\.[0-9]*)?' + \
+ r'(([ \t]*)Z|(?P<tzhour>[-+][0-9][0-9])?(:(?P<tzminute>[0-9][0-9])?)?)?$'
+ CANONICAL = '%Y-%m-%dT%H:%M:%S'
+
+ def __init__(self, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ value = str(value)
+ match = re.match(Timestamp.REGULAR_SHORT, value)
+ if match is not None:
+ # Parse short form
+ year = int(match.group('year'))
+ month = int(match.group('month'))
+ day = int(match.group('day'))
+ self.value = datetime(year, month, day, tzinfo=UTC)
+ else:
+ match = re.match(Timestamp.REGULAR_LONG, value)
+ if match is not None:
+ # Parse long form
+ year = int(match.group('year'))
+ month = int(match.group('month'))
+ day = int(match.group('day'))
+ hour = match.group('hour')
+ if hour is not None:
+ hour = int(hour)
+ minute = match.group('minute')
+ if minute is not None:
+ minute = int(minute)
+ second = match.group('second')
+ if second is not None:
+ second = int(second)
+ fraction = match.group('fraction')
+ if fraction is not None:
+ fraction = int(float(fraction) * 1000000.0) # convert to microseconds
+ tzhour = match.group('tzhour')
+ if tzhour is not None:
+ tzhour = int(tzhour)
+ else:
+ tzhour = 0
+ tzminute = match.group('tzminute')
+ if tzminute is not None:
+ tzminute = int(tzminute)
+ else:
+ tzminute = 0
+ self.value = datetime(year, month, day, hour, minute, second, fraction,
+ Timezone(tzhour, tzminute))
+ else:
+ raise ValueError(
+ 'timestamp must be formatted as YAML ISO8601 variant or "YYYY-MM-DD": %s'
+ % safe_repr(value))
+
+ @property
+ def as_datetime_utc(self):
+ return self.value.astimezone(UTC)
+
+ @property
+ def as_raw(self):
+ return self.__str__()
+
+ def __str__(self):
+ the_datetime = self.as_datetime_utc
+ return '%s%sZ' \
+ % (the_datetime.strftime(Timestamp.CANONICAL), Timestamp._fraction_as_str(the_datetime))
+
+ def __repr__(self):
+ return repr(self.__str__())
+
+ def __eq__(self, timestamp):
+ if not isinstance(timestamp, Timestamp):
+ return False
+ return self.value == timestamp.value
+
+ def __lt__(self, timestamp):
+ return self.value < timestamp.value
+
+ @staticmethod
+ def _fraction_as_str(the_datetime):
+ return '{0:g}'.format(the_datetime.microsecond / 1000000.0).lstrip('0')
+
+
+@total_ordering
+@implements_specification('3.2.2', 'tosca-simple-1.0')
+class Version(object):
+ """
+ TOSCA supports the concept of "reuse" of type definitions, as well as template definitions which
+ could be version and change over time. It is important to provide a reliable, normative means to
+ represent a version string which enables the comparison and management of types and templates
+ over time. Therefore, the TOSCA TC intends to provide a normative version type (string) for this
+ purpose in future Working Drafts of this specification.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #TYPE_TOSCA_VERSION>`__
+ """
+
+ REGEX = \
+ r'^(?P<major>\d+)\.(?P<minor>\d+)(\.(?P<fix>\d+)' + \
+ r'((\.(?P<qualifier>\d+))(\-(?P<build>\d+))?)?)?$'
+
+ @staticmethod
+ def key(version):
+ """
+ Key method for fast sorting.
+ """
+ return (version.major, version.minor, version.fix, version.qualifier, version.build)
+
+ def __init__(self, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ str_value = str(value)
+ match = re.match(Version.REGEX, str_value)
+ if match is None:
+ raise ValueError(
+ 'version must be formatted as <major_version>.<minor_version>'
+ '[.<fix_version>[.<qualifier>[-<build_version]]]: %s'
+ % safe_repr(value))
+
+ self.value = str_value
+
+ self.major = match.group('major')
+ self.major = int(self.major)
+ self.minor = match.group('minor')
+ self.minor = int(self.minor)
+ self.fix = match.group('fix')
+ if self.fix is not None:
+ self.fix = int(self.fix)
+ self.qualifier = match.group('qualifier')
+ if self.qualifier is not None:
+ self.qualifier = int(self.qualifier)
+ self.build = match.group('build')
+ if self.build is not None:
+ self.build = int(self.build)
+
+ @property
+ def as_raw(self):
+ return self.value
+
+ def __str__(self):
+ return self.value
+
+ def __repr__(self):
+ return repr(self.__str__())
+
+ def __eq__(self, version):
+ if not isinstance(version, Version):
+ return False
+ return (self.major, self.minor, self.fix, self.qualifier, self.build) == \
+ (version.major, version.minor, version.fix, version.qualifier, version.build)
+
+ def __lt__(self, version):
+ if self.major < version.major:
+ return True
+ elif self.major == version.major:
+ if self.minor < version.minor:
+ return True
+ elif self.minor == version.minor:
+ if self.fix < version.fix:
+ return True
+ elif self.fix == version.fix:
+ if self.qualifier < version.qualifier:
+ return True
+ elif self.qualifier == version.qualifier:
+ if self.build < version.build:
+ return True
+ return False
+
+
+@implements_specification('3.2.3', 'tosca-simple-1.0')
+class Range(object):
+ """
+ The range type can be used to define numeric ranges with a lower and upper boundary. For
+ example, this allows for specifying a range of ports to be opened in a firewall.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #TYPE_TOSCA_RANGE>`__
+ """
+
+ def __init__(self, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ if not isinstance(value, list):
+ raise ValueError('range value is not a list: %s' % safe_repr(value))
+ if len(value) != 2:
+ raise ValueError('range value does not have exactly 2 elements: %s' % safe_repr(value))
+
+ def is_int(v):
+ return isinstance(v, int) and (not isinstance(v, bool)) # In Python bool is an int
+
+ if not is_int(value[0]):
+ raise ValueError('lower bound of range is not a valid integer: %s'
+ % safe_repr(value[0]))
+
+ if value[1] != 'UNBOUNDED':
+ if not is_int(value[1]):
+ raise ValueError('upper bound of range is not a valid integer or "UNBOUNDED": %s'
+ % safe_repr(value[0]))
+
+ if value[0] >= value[1]:
+ raise ValueError(
+ 'upper bound of range is not greater than the lower bound: %s >= %s'
+ % (safe_repr(value[0]), safe_repr(value[1])))
+
+ self.value = value
+
+ def is_in(self, value):
+ if value < self.value[0]:
+ return False
+ if (self.value[1] != 'UNBOUNDED') and (value > self.value[1]):
+ return False
+ return True
+
+ @property
+ def as_raw(self):
+ return list(self.value)
+
+
+@implements_specification('3.2.4', 'tosca-simple-1.0')
+class List(list):
+ """
+ The list type allows for specifying multiple values for a parameter of property. For example, if
+ an application allows for being configured to listen on multiple ports, a list of ports could be
+ configured using the list data type.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #TYPE_TOSCA_LIST>`__
+ """
+
+ @staticmethod
+ def _create(context, presentation, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ if not isinstance(value, list):
+ raise ValueError('"list" data type value is not a list: %s' % safe_repr(value))
+
+ entry_schema_type = entry_schema._get_type(context)
+ entry_schema_constraints = entry_schema.constraints
+
+ the_list = List()
+ for v in value:
+ v = coerce_value(context, presentation, entry_schema_type, None,
+ entry_schema_constraints, v, aspect)
+ if v is not None:
+ the_list.append(v)
+
+ return the_list
+
+ # Can't define as property because it's old-style Python class
+ def as_raw(self):
+ return list(self)
+
+
+@implements_specification('3.2.5', 'tosca-simple-1.0')
+class Map(StrictDict):
+ """
+ The map type allows for specifying multiple values for a parameter of property as a map. In
+ contrast to the list type, where each entry can only be addressed by its index in the list,
+ entries in a map are named elements that can be addressed by their keys.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #TYPE_TOSCA_MAP>`__
+ """
+
+ @staticmethod
+ def _create(context, presentation, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ if not isinstance(value, dict):
+ raise ValueError('"map" data type value is not a dict: %s' % safe_repr(value))
+
+ if entry_schema is None:
+ raise ValueError('"map" data type does not define "entry_schema"')
+
+ entry_schema_type = entry_schema._get_type(context)
+ entry_schema_constraints = entry_schema.constraints
+
+ the_map = Map()
+ for k, v in value.iteritems():
+ v = coerce_value(context, presentation, entry_schema_type, None,
+ entry_schema_constraints, v, aspect)
+ if v is not None:
+ the_map[k] = v
+
+ return the_map
+
+ def __init__(self, items=None):
+ super(Map, self).__init__(items, key_class=str)
+
+ # Can't define as property because it's old-style Python class
+ def as_raw(self):
+ return OrderedDict(self)
+
+
+@total_ordering
+@implements_specification('3.2.6', 'tosca-simple-1.0')
+class Scalar(object):
+ """
+ The scalar-unit type can be used to define scalar values along with a unit from the list of
+ recognized units.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #TYPE_TOSCA_SCALAR_UNIT>`__
+ """
+
+ @staticmethod
+ def key(scalar):
+ """
+ Key method for fast sorting.
+ """
+ return scalar.value
+
+ def __init__(self, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ str_value = str(value)
+ match = re.match(self.REGEX, str_value) # pylint: disable=no-member
+ if match is None:
+ raise ValueError('scalar must be formatted as <scalar> <unit>: %s' % safe_repr(value))
+
+ self.factor = float(match.group('scalar'))
+ if self.factor < 0:
+ raise ValueError('scalar is negative: %s' % safe_repr(self.factor))
+
+ self.unit = match.group('unit')
+
+ unit_lower = self.unit.lower()
+ unit_size = None
+ for k, v in self.UNITS.iteritems(): # pylint: disable=no-member
+ if k.lower() == unit_lower:
+ self.unit = k
+ unit_size = v
+ break
+ if unit_size is None:
+ raise ValueError('scalar specified with unsupported unit: %s' % safe_repr(self.unit))
+
+ self.value = self.TYPE(self.factor * unit_size) # pylint: disable=no-member
+
+ @property
+ def as_raw(self):
+ return OrderedDict((
+ ('value', self.value),
+ ('factor', self.factor),
+ ('unit', self.unit),
+ ('unit_size', self.UNITS[self.unit]))) # pylint: disable=no-member
+
+ def __str__(self):
+ return '%s %s' % (self.value, self.UNIT) # pylint: disable=no-member
+
+ def __repr__(self):
+ return repr(self.__str__())
+
+ def __eq__(self, scalar):
+ if isinstance(scalar, Scalar):
+ value = scalar.value
+ else:
+ value = self.TYPE(scalar) # pylint: disable=no-member
+ return self.value == value
+
+ def __lt__(self, scalar):
+ if isinstance(scalar, Scalar):
+ value = scalar.value
+ else:
+ value = self.TYPE(scalar) # pylint: disable=no-member
+ return self.value < value
+
+
+@implements_specification('3.2.6.4', 'tosca-simple-1.0')
+class ScalarSize(Scalar):
+ """
+ Integer scalar for counting bytes.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #TYPE_TOSCA_SCALAR_UNIT_SIZE>`__
+ """
+
+ # See: http://www.regular-expressions.info/floatingpoint.html
+ REGEX = \
+ r'^(?P<scalar>[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)\s*(?P<unit>B|kB|KiB|MB|MiB|GB|GiB|TB|TiB)$'
+
+ UNITS = {
+ 'B': 1,
+ 'kB': 1000,
+ 'KiB': 1024,
+ 'MB': 1000000,
+ 'MiB': 1048576,
+ 'GB': 1000000000,
+ 'GiB': 1073741824,
+ 'TB': 1000000000000,
+ 'TiB': 1099511627776}
+
+ TYPE = int
+ UNIT = 'bytes'
+
+
+@implements_specification('3.2.6.5', 'tosca-simple-1.0')
+class ScalarTime(Scalar):
+ """
+ Floating point scalar for counting seconds.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #TYPE_TOSCA_SCALAR_UNIT_TIME>`__
+ """
+
+ # See: http://www.regular-expressions.info/floatingpoint.html
+ REGEX = r'^(?P<scalar>[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)\s*(?P<unit>ns|us|ms|s|m|h|d)$'
+
+ UNITS = {
+ 'ns': 0.000000001,
+ 'us': 0.000001,
+ 'ms': 0.001,
+ 's': 1.0,
+ 'm': 60.0,
+ 'h': 3600.0,
+ 'd': 86400.0}
+
+ TYPE = float
+ UNIT = 'seconds'
+
+
+@implements_specification('3.2.6.6', 'tosca-simple-1.0')
+class ScalarFrequency(Scalar):
+ """
+ Floating point scalar for counting cycles per second (Hz).
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #TYPE_TOSCA_SCALAR_UNIT_FREQUENCY>`__
+ """
+
+ # See: http://www.regular-expressions.info/floatingpoint.html
+ REGEX = r'^(?P<scalar>[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)\s*(?P<unit>Hz|kHz|MHz|GHz)$'
+
+ UNITS = {
+ 'Hz': 1.0,
+ 'kHz': 1000.0,
+ 'MHz': 1000000.0,
+ 'GHz': 1000000000.0}
+
+ TYPE = float
+ UNIT = 'Hz'
+
+
+#
+# The following are hooked in the YAML as 'coerce_value' extensions
+#
+
+def coerce_timestamp(context, presentation, the_type, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ return coerce_to_data_type_class(context, presentation, Timestamp, entry_schema, constraints,
+ value, aspect)
+
+
+def coerce_version(context, presentation, the_type, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ return coerce_to_data_type_class(context, presentation, Version, entry_schema, constraints,
+ value, aspect)
+
+
+def coerce_range(context, presentation, the_type, entry_schema, constraints, value, aspect):
+ if aspect == 'in_range':
+ # When we're in a "in_range" constraint, the values are *not* themselves ranges, but numbers
+ try:
+ return float(value)
+ except ValueError as e:
+ report_issue_for_bad_format(context, presentation, the_type, value, aspect, e)
+ except TypeError as e:
+ report_issue_for_bad_format(context, presentation, the_type, value, aspect, e)
+ else:
+ return coerce_to_data_type_class(context, presentation, Range, entry_schema, constraints,
+ value, aspect)
+
+
+def coerce_list(context, presentation, the_type, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ return coerce_to_data_type_class(context, presentation, List, entry_schema, constraints,
+ value, aspect)
+
+
+def coerce_map_value(context, presentation, the_type, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
+ return coerce_to_data_type_class(context, presentation, Map, entry_schema, constraints, value,
+ aspect)
+
+
+def coerce_scalar_unit_size(context, presentation, the_type, entry_schema, constraints, value, # pylint: disable=unused-argument
+ aspect):
+ return coerce_to_data_type_class(context, presentation, ScalarSize, entry_schema, constraints,
+ value, aspect)
+
+
+def coerce_scalar_unit_time(context, presentation, the_type, entry_schema, constraints, value, # pylint: disable=unused-argument
+ aspect):
+ return coerce_to_data_type_class(context, presentation, ScalarTime, entry_schema, constraints,
+ value, aspect)
+
+
+def coerce_scalar_unit_frequency(context, presentation, the_type, entry_schema, constraints, value, # pylint: disable=unused-argument
+ aspect):
+ return coerce_to_data_type_class(context, presentation, ScalarFrequency, entry_schema,
+ constraints, value, aspect)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/definitions.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/definitions.py
new file mode 100644
index 0000000..9158776
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/definitions.py
@@ -0,0 +1,518 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import FrozenDict
+from aria.utils.caching import cachedmethod
+from aria.parser import implements_specification
+from aria.parser.presentation import (has_fields, short_form_field, allow_unknown_fields,
+ primitive_field, primitive_list_field, object_field,
+ object_list_field, object_dict_field,
+ object_dict_unknown_fields, field_validator,
+ field_getter, type_validator, list_type_validator)
+
+from .data_types import Range
+from .misc import (Description, ConstraintClause, OperationImplementation, EntrySchema)
+from .presentation.extensible import ExtensiblePresentation
+from .presentation.field_getters import data_type_class_getter
+from .presentation.field_validators import (data_type_validator, data_value_validator,
+ entry_schema_validator)
+from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
+from .modeling.data_types import get_data_type, get_property_constraints
+from .modeling.interfaces import (get_and_override_input_definitions_from_type,
+ get_and_override_operation_definitions_from_type)
+
+
+@has_fields
+@implements_specification('3.5.8', 'tosca-simple-1.0')
+class PropertyDefinition(ExtensiblePresentation):
+ """
+ A property definition defines a named, typed value and related data that can be associated with
+ an entity defined in this specification (e.g., Node Types, Relationship Types, Capability Types,
+ etc.). Properties are used by template authors to provide input values to TOSCA entities which
+ indicate their "desired state" when they are instantiated. The value of a property can be
+ retrieved using the ``get_property`` function within TOSCA Service Templates.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_PROPERTY_DEFN>`__
+ """
+
+ @field_validator(data_type_validator())
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The required data type for the property.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the property.
+
+ :type: :class:`Description`
+ """
+
+ @primitive_field(bool, default=True)
+ def required(self):
+ """
+ An optional key that declares a property as required (true) or not (false).
+
+ :type: bool
+ """
+
+ @field_validator(data_value_validator)
+ @primitive_field()
+ def default(self):
+ """
+ An optional key that may provide a value to be used as a default if not provided by another
+ means.
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_field(str, default='supported', allowed=('supported', 'unsupported', 'experimental',
+ 'deprecated'))
+ @implements_specification(section='3.5.8.3', spec='tosca-simple-1.0')
+ def status(self):
+ """
+ The optional status of the property relative to the specification or implementation.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_list_field(ConstraintClause)
+ def constraints(self):
+ """
+ The optional list of sequenced constraint clauses for the property.
+
+ :type: list of (str, :class:`ConstraintClause`)
+ """
+
+ @field_validator(entry_schema_validator)
+ @object_field(EntrySchema)
+ def entry_schema(self):
+ """
+ The optional key that is used to declare the name of the Datatype definition for entries of
+ set types such as the TOSCA list or map.
+
+ :type: :obj:`basestring`
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_data_type(context, self, 'type')
+
+ @cachedmethod
+ def _get_constraints(self, context):
+ return get_property_constraints(context, self)
+
+
+@has_fields
+@implements_specification('3.5.10', 'tosca-simple-1.0')
+class AttributeDefinition(ExtensiblePresentation):
+ """
+ An attribute definition defines a named, typed value that can be associated with an entity
+ defined in this specification (e.g., a Node, Relationship or Capability Type). Specifically, it
+ is used to expose the "actual state" of some property of a TOSCA entity after it has been
+ deployed and instantiated (as set by the TOSCA orchestrator). Attribute values can be retrieved
+ via the ``get_attribute`` function from the instance model and used as values to other
+ entities within TOSCA Service Templates.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_ATTRIBUTE_DEFN>`__
+ """
+
+ @field_validator(data_type_validator())
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The required data type for the attribute.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the attribute.
+
+ :type: :class:`Description`
+ """
+
+ @field_validator(data_value_validator)
+ @primitive_field()
+ def default(self):
+ """
+ An optional key that may provide a value to be used as a default if not provided by another
+ means.
+
+ This value SHALL be type compatible with the type declared by the property definition's type
+ keyname.
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_field(str, default='supported', allowed=('supported', 'unsupported', 'experimental',
+ 'deprecated'))
+ def status(self):
+ """
+ The optional status of the attribute relative to the specification or implementation.
+
+ :type: :obj:`basestring`
+ """
+
+ @field_validator(entry_schema_validator)
+ @object_field(EntrySchema)
+ def entry_schema(self):
+ """
+ The optional key that is used to declare the name of the Datatype definition for entries of
+ set types such as the TOSCA list or map.
+
+ :type: :obj:`basestring`
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_data_type(context, self, 'type')
+
+
+@has_fields
+@implements_specification('3.5.12', 'tosca-simple-1.0')
+class ParameterDefinition(PropertyDefinition):
+ """
+ A parameter definition is essentially a TOSCA property definition; however, it also allows a
+ value to be assigned to it (as for a TOSCA property assignment). In addition, in the case of
+ output parameters, it can optionally inherit the data type of the value assigned to it rather
+ than have an explicit data type defined for it.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_PARAMETER_DEF>`__
+ """
+
+ @field_validator(data_type_validator())
+ @primitive_field(str)
+ def type(self):
+ """
+ The required data type for the parameter.
+
+ Note: This keyname is required for a TOSCA Property definition, but is not for a TOSCA
+ Parameter definition.
+
+ :type: :obj:`basestring`
+ """
+
+ @field_validator(data_value_validator)
+ @primitive_field()
+ def value(self):
+ """
+ The type-compatible value to assign to the named parameter. Parameter values may be provided
+ as the result from the evaluation of an expression or a function.
+ """
+
+
+@short_form_field('implementation')
+@has_fields
+@implements_specification('3.5.13-1', 'tosca-simple-1.0')
+class OperationDefinition(ExtensiblePresentation):
+ """
+ An operation definition defines a named function or procedure that can be bound to an
+ implementation artifact (e.g., a script).
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_OPERATION_DEF>`__
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description string for the associated named operation.
+
+ :type: :class:`Description`
+ """
+
+ @object_field(OperationImplementation)
+ def implementation(self):
+ """
+ The optional implementation artifact name (e.g., a script file name within a TOSCA CSAR
+ file).
+
+ :type: :class:`OperationImplementation`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def inputs(self):
+ """
+ The optional list of input property definitions available to all defined operations for
+ interface definitions that are within TOSCA Node or Relationship Type definitions. This
+ includes when interface definitions are included as part of a Requirement definition in a
+ Node Type.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+
+@allow_unknown_fields
+@has_fields
+@implements_specification('3.5.14-1', 'tosca-simple-1.0')
+class InterfaceDefinition(ExtensiblePresentation):
+ """
+ An interface definition defines a named interface that can be associated with a Node or
+ Relationship Type.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_INTERFACE_DEF>`__
+ """
+
+ @field_validator(type_validator('interface type', convert_name_to_full_type_name,
+ 'interface_types'))
+ @primitive_field(str)
+ def type(self):
+ """
+ ARIA NOTE: This field is not mentioned in the spec, but is implied.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def inputs(self):
+ """
+ The optional list of input property definitions available to all defined operations for
+ interface definitions that are within TOSCA Node or Relationship Type definitions. This
+ includes when interface definitions are included as part of a Requirement definition in a
+ Node Type.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @object_dict_unknown_fields(OperationDefinition)
+ def operations(self):
+ """
+ :type: {:obj:`basestring`: :class:`OperationDefinition`}
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.type, 'interface_types')
+
+ @cachedmethod
+ def _get_inputs(self, context):
+ return FrozenDict(get_and_override_input_definitions_from_type(context, self))
+
+ @cachedmethod
+ def _get_operations(self, context):
+ return FrozenDict(get_and_override_operation_definitions_from_type(context, self))
+
+ def _validate(self, context):
+ super(InterfaceDefinition, self)._validate(context)
+ if self.operations:
+ for operation in self.operations.itervalues(): # pylint: disable=no-member
+ operation._validate(context)
+
+
+@short_form_field('type')
+@has_fields
+class RelationshipDefinition(ExtensiblePresentation):
+ """
+ Relationship definition.
+ """
+
+ @field_validator(type_validator('relationship type', convert_name_to_full_type_name,
+ 'relationship_types'))
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The optional reserved keyname used to provide the name of the Relationship Type for the
+ requirement definition's relationship keyname.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_dict_field(InterfaceDefinition)
+ def interfaces(self):
+ """
+ The optional reserved keyname used to reference declared (named) interface definitions of
+ the corresponding Relationship Type in order to declare additional Property definitions for
+ these interfaces or operations of these interfaces.
+
+ :type: list of :class:`InterfaceDefinition`
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.type, 'relationship_types')
+
+
+
+@short_form_field('capability')
+@has_fields
+@implements_specification('3.6.2', 'tosca-simple-1.0')
+class RequirementDefinition(ExtensiblePresentation):
+ """
+ The Requirement definition describes a named requirement (dependencies) of a TOSCA Node Type or
+ Node template which needs to be fulfilled by a matching Capability definition declared by
+ another TOSCA modelable entity. The requirement definition may itself include the specific name
+ of the fulfilling entity (explicitly) or provide an abstract type, along with additional
+ filtering characteristics, that a TOSCA orchestrator can use to fulfill the capability at
+ runtime (implicitly).
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_REQUIREMENT_DEF>`__
+ """
+
+ @field_validator(type_validator('capability type', convert_name_to_full_type_name,
+ 'capability_types'))
+ @primitive_field(str, required=True)
+ def capability(self):
+ """
+ The required reserved keyname used that can be used to provide the name of a valid
+ Capability Type that can fulfill the requirement.
+
+ :type: :obj:`basestring`
+ """
+
+ @field_validator(type_validator('node type', convert_name_to_full_type_name,
+ 'node_types'))
+ @primitive_field(str)
+ def node(self):
+ """
+ The optional reserved keyname used to provide the name of a valid Node Type that contains
+ the capability definition that can be used to fulfill the requirement.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(RelationshipDefinition)
+ def relationship(self):
+ """
+ The optional reserved keyname used to provide the name of a valid Relationship Type to
+ construct when fulfilling the requirement.
+
+ :type: :class:`RelationshipDefinition`
+ """
+
+ @field_getter(data_type_class_getter(Range))
+ @primitive_field()
+ def occurrences(self):
+ """
+ The optional minimum and maximum occurrences for the requirement.
+
+ Note: the keyword UNBOUNDED is also supported to represent any positive integer.
+
+ :type: :class:`Range`
+ """
+
+ @cachedmethod
+ def _get_capability_type(self, context):
+ return get_type_by_name(context, self.capability, 'capability_types')
+
+ @cachedmethod
+ def _get_node_type(self, context):
+ return context.presentation.get_from_dict('service_template', 'node_types', self.node)
+
+
+@short_form_field('type')
+@has_fields
+@implements_specification('3.6.1', 'tosca-simple-1.0')
+class CapabilityDefinition(ExtensiblePresentation):
+ """
+ A capability definition defines a named, typed set of data that can be associated with Node Type
+ or Node Template to describe a transparent capability or feature of the software component the
+ node describes.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_CAPABILITY_DEFN>`__
+ """
+
+ @field_validator(type_validator('capability type', convert_name_to_full_type_name,
+ 'capability_types'))
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The required name of the Capability Type the capability definition is based upon.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description of the Capability definition.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def properties(self):
+ """
+ An optional list of property definitions for the Capability definition.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @object_dict_field(AttributeDefinition)
+ def attributes(self):
+ """
+ An optional list of attribute definitions for the Capability definition.
+
+ :type: {:obj:`basestring`: :class:`AttributeDefinition`}
+ """
+
+ @field_validator(list_type_validator('node type', convert_name_to_full_type_name,
+ 'node_types'))
+ @primitive_list_field(str)
+ def valid_source_types(self):
+ """
+ An optional list of one or more valid names of Node Types that are supported as valid
+ sources of any relationship established to the declared Capability Type.
+
+ :type: [:obj:`basestring`]
+ """
+
+ @field_getter(data_type_class_getter(Range))
+ @primitive_field()
+ def occurrences(self):
+ """
+ The optional minimum and maximum occurrences for the capability. By default, an exported
+ Capability should allow at least one relationship to be formed with it with a maximum of
+ ``UNBOUNDED`` relationships.
+
+ Note: the keyword ``UNBOUNDED`` is also supported to represent any positive integer.
+
+ ARIA NOTE: The spec seems wrong here: the implied default should be ``[0,UNBOUNDED]``, not
+ ``[1,UNBOUNDED]``, otherwise it would imply that at 1 least one relationship *must* be
+ formed.
+
+ :type: :class:`Range`
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.type, 'capability_types')
+
+ @cachedmethod
+ def _get_parent(self, context):
+ container_parent = self._container._get_parent(context)
+ container_parent_capabilities = container_parent._get_capabilities(context) \
+ if container_parent is not None else None
+ return container_parent_capabilities.get(self._name) \
+ if container_parent_capabilities is not None else None
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/filters.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/filters.py
new file mode 100644
index 0000000..95d84b2
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/filters.py
@@ -0,0 +1,107 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.caching import cachedmethod
+from aria.parser import implements_specification
+from aria.parser.presentation import (has_fields, object_sequenced_list_field, field_validator)
+
+from .misc import ConstraintClause
+from .presentation.extensible import ExtensiblePresentation
+from .presentation.field_validators import (node_filter_properties_validator,
+ node_filter_capabilities_validator)
+
+
+@has_fields
+class CapabilityFilter(ExtensiblePresentation):
+ """
+ Capability filter.
+ """
+
+ @object_sequenced_list_field(ConstraintClause)
+ def properties(self):
+ pass
+
+ @cachedmethod
+ def _get_node_type(self, context):
+ return self._container._get_node_type(context)
+
+ @cachedmethod
+ def _get_type_for_name(self, context, name):
+ node_type = self._get_node_type(context)
+ if node_type is not None:
+ capabilities = node_type._get_capabilities(context)
+ capability = capabilities.get(self._name)
+ properties = capability.properties if capability is not None else None
+ prop = properties.get(name) if properties is not None else None
+ return prop._get_type(context) if prop is not None else None
+
+ return None
+
+
+@has_fields
+@implements_specification('3.5.4', 'tosca-simple-1.0')
+class NodeFilter(ExtensiblePresentation):
+ """
+ A node filter definition defines criteria for selection of a TOSCA Node Template based upon the
+ template's property values, capabilities and capability properties.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_NODE_FILTER_DEFN>`__
+ """
+
+ @field_validator(node_filter_properties_validator)
+ @object_sequenced_list_field(ConstraintClause)
+ @implements_specification('3.5.3', 'tosca-simple-1.0')
+ def properties(self):
+ """
+ An optional sequenced list of property filters that would be used to select (filter)
+ matching TOSCA entities (e.g., Node Template, Node Type, Capability Types, etc.) based upon
+ their property definitions' values.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_PROPERTY_FILTER_DEFN>`__
+
+ :type: list of (str, :class:`ConstraintClause`)
+ """
+
+ @field_validator(node_filter_capabilities_validator)
+ @object_sequenced_list_field(CapabilityFilter)
+ def capabilities(self):
+ """
+ An optional sequenced list of property filters that would be used to select (filter)
+ matching TOSCA entities (e.g., Node Template, Node Type, Capability Types, etc.) based upon
+ their capabilities' property definitions' values.
+
+ :type: list of (str, :class:`CapabilityDefinition`)
+ """
+
+ @cachedmethod
+ def _get_node_type(self, context):
+ if hasattr(self._container, '_get_node'):
+ node_type, node_type_variant = self._container._get_node(context)
+ return node_type if node_type_variant == 'node_type' else None
+ return None
+
+ @cachedmethod
+ def _get_type_for_name(self, context, name):
+ node_type = self._get_node_type(context)
+ if node_type is not None:
+ properties = node_type._get_properties(context)
+ prop = properties.get(name)
+ return prop._get_type(context) if prop is not None else None
+
+ return None
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/misc.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/misc.py
new file mode 100644
index 0000000..221163c
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/misc.py
@@ -0,0 +1,444 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.caching import cachedmethod
+from aria.utils.console import puts
+from aria.utils.formatting import as_raw
+from aria.parser import implements_specification
+from aria.parser.presentation import (AsIsPresentation, has_fields, allow_unknown_fields,
+ short_form_field, primitive_field, primitive_list_field,
+ primitive_dict_unknown_fields, object_field,
+ object_list_field, object_dict_field, field_validator,
+ type_validator)
+
+from .modeling.data_types import (get_data_type, get_data_type_value, get_property_constraints,
+ apply_constraint_to_value)
+from .modeling.substitution_mappings import (validate_substitution_mappings_requirement,
+ validate_substitution_mappings_capability)
+from .presentation.extensible import ExtensiblePresentation
+from .presentation.field_validators import (constraint_clause_field_validator,
+ constraint_clause_in_range_validator,
+ constraint_clause_valid_values_validator,
+ constraint_clause_pattern_validator,
+ data_type_validator)
+from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
+
+
+
+@implements_specification('3.5.1', 'tosca-simple-1.0')
+class Description(AsIsPresentation):
+ """
+ Human-readable description.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_DESCRIPTION>`__
+ """
+
+ def __init__(self, name=None, raw=None, container=None, cls=None): # pylint: disable=unused-argument
+ super(Description, self).__init__(name, raw, container, cls=unicode)
+
+ def _dump(self, context):
+ value = as_raw(self.value)
+ puts(context.style.meta_style(value))
+
+
+@allow_unknown_fields
+@has_fields
+@implements_specification('3.9.3.2', 'tosca-simple-1.0')
+class MetaData(ExtensiblePresentation):
+ """
+ Meta data.
+ """
+
+ @primitive_field(str)
+ @implements_specification('3.9.3.3', 'tosca-simple-1.0')
+ def template_name(self):
+ """
+ This optional metadata keyname can be used to declare the name of service template as a
+ single-line string value.
+ """
+
+ @primitive_field(str)
+ @implements_specification('3.9.3.4', 'tosca-simple-1.0')
+ def template_author(self):
+ """
+ This optional metadata keyname can be used to declare the author(s) of the service template
+ as a single-line string value.
+ """
+
+ @primitive_field(str)
+ @implements_specification('3.9.3.5', 'tosca-simple-1.0')
+ def template_version(self):
+ """
+ This optional metadata keyname can be used to declare a domain specific version of the
+ service template as a single-line string value.
+ """
+
+ @primitive_dict_unknown_fields()
+ def custom(self):
+ """
+ :type: dict
+ """
+
+
+@short_form_field('url')
+@has_fields
+@implements_specification('3.5.5', 'tosca-simple-1.0')
+class Repository(ExtensiblePresentation):
+ """
+ A repository definition defines a named external repository which contains deployment and
+ implementation artifacts that are referenced within the TOSCA Service Template.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_REPOSITORY_DEF>`__
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the repository.
+
+ :type: :class:`Description`
+ """
+
+ @primitive_field(str, required=True)
+ def url(self):
+ """
+ The required URL or network address used to access the repository.
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_field()
+ def credential(self):
+ """
+ The optional Credential used to authorize access to the repository.
+
+ :type: tosca.datatypes.Credential
+ """
+
+ @cachedmethod
+ def _get_credential(self, context):
+ return get_data_type_value(context, self, 'credential', 'tosca.datatypes.Credential')
+
+
+@short_form_field('file')
+@has_fields
+@implements_specification('3.5.7', 'tosca-simple-1.0')
+class Import(ExtensiblePresentation):
+ """
+ An import definition is used within a TOSCA Service Template to locate and uniquely name another
+ TOSCA Service Template file which has type and template definitions to be imported (included)
+ and referenced within another Service Template.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_IMPORT_DEF>`__
+ """
+
+ @primitive_field(str, required=True)
+ def file(self):
+ """
+ The required symbolic name for the imported file.
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_field(str)
+ def repository(self):
+ """
+ The optional symbolic name of the repository definition where the imported file can be found
+ as a string.
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_field(str)
+ def namespace_uri(self):
+ """
+ The optional namespace URI to that will be applied to type definitions found within the
+ imported file as a string.
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_field(str)
+ def namespace_prefix(self):
+ """
+ The optional namespace prefix (alias) that will be used to indicate the namespace_uri when
+ forming a qualified name (i.e., qname) when referencing type definitions from the imported
+ file.
+
+ :type: :obj:`basestring`
+ """
+
+
+@has_fields
+@implements_specification('3.5.2-1', 'tosca-simple-1.0')
+class ConstraintClause(ExtensiblePresentation):
+ """
+ A constraint clause defines an operation along with one or more compatible values that can be
+ used to define a constraint on a property or parameter's allowed values when it is defined in a
+ TOSCA Service Template or one of its entities.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_CONSTRAINTS_CLAUSE>`__
+ """
+
+ @field_validator(constraint_clause_field_validator)
+ @primitive_field()
+ def equal(self):
+ """
+ Constrains a property or parameter to a value equal to ('=') the value declared.
+ """
+
+ @field_validator(constraint_clause_field_validator)
+ @primitive_field()
+ def greater_than(self):
+ """
+ Constrains a property or parameter to a value greater than ('>') the value declared.
+ """
+
+ @field_validator(constraint_clause_field_validator)
+ @primitive_field()
+ def greater_or_equal(self):
+ """
+ Constrains a property or parameter to a value greater than or equal to ('>=') the value
+ declared.
+ """
+
+ @field_validator(constraint_clause_field_validator)
+ @primitive_field()
+ def less_than(self):
+ """
+ Constrains a property or parameter to a value less than ('<') the value declared.
+ """
+
+ @field_validator(constraint_clause_field_validator)
+ @primitive_field()
+ def less_or_equal(self):
+ """
+ Constrains a property or parameter to a value less than or equal to ('<=') the value
+ declared.
+ """
+
+ @field_validator(constraint_clause_in_range_validator)
+ @primitive_list_field()
+ def in_range(self):
+ """
+ Constrains a property or parameter to a value in range of (inclusive) the two values
+ declared.
+
+ Note: subclasses or templates of types that declare a property with the ``in_range``
+ constraint MAY only further restrict the range specified by the parent type.
+ """
+
+ @field_validator(constraint_clause_valid_values_validator)
+ @primitive_list_field()
+ def valid_values(self):
+ """
+ Constrains a property or parameter to a value that is in the list of declared values.
+ """
+
+ @primitive_field(int)
+ def length(self):
+ """
+ Constrains the property or parameter to a value of a given length.
+ """
+
+ @primitive_field(int)
+ def min_length(self):
+ """
+ Constrains the property or parameter to a value to a minimum length.
+ """
+
+ @primitive_field(int)
+ def max_length(self):
+ """
+ Constrains the property or parameter to a value to a maximum length.
+ """
+
+ @field_validator(constraint_clause_pattern_validator)
+ @primitive_field(str)
+ def pattern(self):
+ """
+ Constrains the property or parameter to a value that is allowed by the provided regular
+ expression.
+
+ Note: Future drafts of this specification will detail the use of regular expressions and
+ reference an appropriate standardized grammar.
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ if hasattr(self._container, '_get_type_for_name'):
+ # NodeFilter or CapabilityFilter
+ return self._container._get_type_for_name(context, self._name)
+ elif hasattr(self._container, '_get_type'):
+ # Properties
+ return self._container._get_type(context)
+ else:
+ # DataType (the DataType itself is our type)
+ return self._container
+
+ def _apply_to_value(self, context, presentation, value):
+ return apply_constraint_to_value(context, presentation, self, value)
+
+
+@short_form_field('type')
+@has_fields
+class EntrySchema(ExtensiblePresentation):
+ """
+ ARIA NOTE: The specification does not properly explain this type, however it is implied by
+ examples.
+ """
+
+ @field_validator(data_type_validator('entry schema data type'))
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ :type: :class:`Description`
+ """
+
+ @object_list_field(ConstraintClause)
+ def constraints(self):
+ """
+ :type: list of (str, :class:`ConstraintClause`)
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_data_type(context, self, 'type')
+
+ @cachedmethod
+ def _get_constraints(self, context):
+ return get_property_constraints(context, self)
+
+
+@short_form_field('primary')
+@has_fields
+class OperationImplementation(ExtensiblePresentation):
+ """
+ Operation implementation.
+ """
+
+ @primitive_field(str)
+ def primary(self):
+ """
+ The optional implementation artifact name (i.e., the primary script file name within a
+ TOSCA CSAR file).
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_list_field(str)
+ def dependencies(self):
+ """
+ The optional ordered list of one or more dependent or secondary implementation artifact name
+ which are referenced by the primary implementation artifact (e.g., a library the script
+ installs or a secondary script).
+
+ :type: [:obj:`basestring`]
+ """
+
+
+class SubstitutionMappingsRequirement(AsIsPresentation):
+ """
+ Substitution mapping for requirement.
+ """
+
+ @property
+ @cachedmethod
+ def node_template(self):
+ return str(self._raw[0])
+
+ @property
+ @cachedmethod
+ def requirement(self):
+ return str(self._raw[1])
+
+ def _validate(self, context):
+ super(SubstitutionMappingsRequirement, self)._validate(context)
+ validate_substitution_mappings_requirement(context, self)
+
+
+class SubstitutionMappingsCapability(AsIsPresentation):
+ """
+ Substitution mapping for capability.
+ """
+
+ @property
+ @cachedmethod
+ def node_template(self):
+ return str(self._raw[0])
+
+ @property
+ @cachedmethod
+ def capability(self):
+ return str(self._raw[1])
+
+ def _validate(self, context):
+ super(SubstitutionMappingsCapability, self)._validate(context)
+ validate_substitution_mappings_capability(context, self)
+
+
+@has_fields
+@implements_specification('2.10', 'tosca-simple-1.0')
+class SubstitutionMappings(ExtensiblePresentation):
+ """
+ Substitution mappings.
+ """
+
+ @field_validator(type_validator('node type', convert_name_to_full_type_name, 'node_types'))
+ @primitive_field(str, required=True)
+ def node_type(self):
+ """
+ :type: :obj:`basestring`
+ """
+
+ @object_dict_field(SubstitutionMappingsRequirement)
+ def requirements(self):
+ """
+ :type: {:obj:`basestring`: :class:`SubstitutionMappingsRequirement`}
+ """
+
+ @object_dict_field(SubstitutionMappingsCapability)
+ def capabilities(self):
+ """
+ :type: {:obj:`basestring`: :class:`SubstitutionMappingsCapability`}
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.node_type, 'node_types')
+
+ def _validate(self, context):
+ super(SubstitutionMappings, self)._validate(context)
+ self._get_type(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'node_type',
+ 'requirements',
+ 'capabilities'))
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
new file mode 100644
index 0000000..d960e05
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -0,0 +1,750 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+"""
+Creates ARIA service template models based on the TOSCA presentation.
+
+Relies on many helper methods in the presentation classes.
+"""
+
+#pylint: disable=unsubscriptable-object
+
+import os
+import re
+from types import FunctionType
+from datetime import datetime
+
+from ruamel import yaml
+
+from aria.parser.validation import Issue
+from aria.utils.formatting import string_list_as_string
+from aria.utils.collections import (StrictDict, OrderedDict)
+from aria.orchestrator import WORKFLOW_DECORATOR_RESERVED_ARGUMENTS
+from aria.modeling.models import (Type, ServiceTemplate, NodeTemplate,
+ RequirementTemplate, RelationshipTemplate, CapabilityTemplate,
+ GroupTemplate, PolicyTemplate, SubstitutionTemplate,
+ SubstitutionTemplateMapping, InterfaceTemplate, OperationTemplate,
+ ArtifactTemplate, Metadata, Input, Output, Property,
+ Attribute, Configuration, PluginSpecification)
+
+from .parameters import coerce_parameter_value
+from .constraints import (Equal, GreaterThan, GreaterOrEqual, LessThan, LessOrEqual, InRange,
+ ValidValues, Length, MinLength, MaxLength, Pattern)
+from ..data_types import coerce_value
+
+
+# These match the first un-escaped ">"
+# See: http://stackoverflow.com/a/11819111/849021
+IMPLEMENTATION_PREFIX_REGEX = re.compile(r'(?<!\\)(?:\\\\)*>')
+
+
+def create_service_template_model(context): # pylint: disable=too-many-locals,too-many-branches
+ model = ServiceTemplate(created_at=datetime.now(),
+ main_file_name=os.path.basename(str(context.presentation.location)))
+
+ model.description = context.presentation.get('service_template', 'description', 'value')
+
+ # Metadata
+ metadata = context.presentation.get('service_template', 'metadata')
+ if metadata is not None:
+ create_metadata_models(context, model, metadata)
+
+ # Types
+ model.node_types = Type(variant='node')
+ create_types(context,
+ model.node_types,
+ context.presentation.get('service_template', 'node_types'))
+ model.group_types = Type(variant='group')
+ create_types(context,
+ model.group_types,
+ context.presentation.get('service_template', 'group_types'))
+ model.policy_types = Type(variant='policy')
+ create_types(context,
+ model.policy_types,
+ context.presentation.get('service_template', 'policy_types'))
+ model.relationship_types = Type(variant='relationship')
+ create_types(context,
+ model.relationship_types,
+ context.presentation.get('service_template', 'relationship_types'))
+ model.capability_types = Type(variant='capability')
+ create_types(context,
+ model.capability_types,
+ context.presentation.get('service_template', 'capability_types'))
+ model.interface_types = Type(variant='interface')
+ create_types(context,
+ model.interface_types,
+ context.presentation.get('service_template', 'interface_types'))
+ model.artifact_types = Type(variant='artifact')
+ create_types(context,
+ model.artifact_types,
+ context.presentation.get('service_template', 'artifact_types'))
+
+ # Topology template
+ topology_template = context.presentation.get('service_template', 'topology_template')
+ if topology_template is not None:
+ model.inputs.update(
+ create_input_models_from_values(topology_template._get_input_values(context)))
+ model.outputs.update(
+ create_output_models_from_values(topology_template._get_output_values(context)))
+
+ # Plugin specifications
+ policies = context.presentation.get('service_template', 'topology_template', 'policies')
+ if policies:
+ for policy in policies.itervalues():
+ role = model.policy_types.get_descendant(policy.type).role
+ if role == 'plugin':
+ plugin_specification = create_plugin_specification_model(context, policy)
+ model.plugin_specifications[plugin_specification.name] = plugin_specification
+ elif role == 'workflow':
+ operation_template = create_workflow_operation_template_model(context,
+ model, policy)
+ model.workflow_templates[operation_template.name] = operation_template
+
+ # Node templates
+ node_templates = context.presentation.get('service_template', 'topology_template',
+ 'node_templates')
+ if node_templates:
+ for node_template in node_templates.itervalues():
+ node_template_model = create_node_template_model(context, model, node_template)
+ model.node_templates[node_template_model.name] = node_template_model
+ for node_template in node_templates.itervalues():
+ fix_node_template_model(context, model, node_template)
+
+ # Group templates
+ groups = context.presentation.get('service_template', 'topology_template', 'groups')
+ if groups:
+ for group in groups.itervalues():
+ group_template_model = create_group_template_model(context, model, group)
+ model.group_templates[group_template_model.name] = group_template_model
+
+ # Policy templates
+ policies = context.presentation.get('service_template', 'topology_template', 'policies')
+ if policies:
+ for policy in policies.itervalues():
+ policy_template_model = create_policy_template_model(context, model, policy)
+ model.policy_templates[policy_template_model.name] = policy_template_model
+
+ # Substitution template
+ substitution_mappings = context.presentation.get('service_template', 'topology_template',
+ 'substitution_mappings')
+ if substitution_mappings:
+ model.substitution_template = create_substitution_template_model(context, model,
+ substitution_mappings)
+
+ return model
+
+
+def create_metadata_models(context, service_template, metadata):
+ service_template.meta_data['template_name'] = Metadata(name='template_name',
+ value=metadata.template_name)
+ service_template.meta_data['template_author'] = Metadata(name='template_author',
+ value=metadata.template_author)
+ service_template.meta_data['template_version'] = Metadata(name='template_version',
+ value=metadata.template_version)
+ custom = metadata.custom
+ if custom:
+ for name, value in custom.iteritems():
+ service_template.meta_data[name] = Metadata(name=name,
+ value=value)
+
+
+def create_node_template_model(context, service_template, node_template):
+ node_type = node_template._get_type(context)
+ node_type = service_template.node_types.get_descendant(node_type._name)
+ model = NodeTemplate(name=node_template._name, type=node_type)
+
+ if node_template.description:
+ model.description = node_template.description.value
+
+ if node_template.directives:
+ model.directives = node_template.directives
+
+ model.properties.update(create_property_models_from_values(
+ template_properties=node_template._get_property_values(context)))
+ model.attributes.update(create_attribute_models_from_values(
+ template_attributes=node_template._get_attribute_default_values(context)))
+
+ create_interface_template_models(context, service_template, model.interface_templates,
+ node_template._get_interfaces(context))
+
+ artifacts = node_template._get_artifacts(context)
+ if artifacts:
+ for artifact_name, artifact in artifacts.iteritems():
+ model.artifact_templates[artifact_name] = \
+ create_artifact_template_model(context, service_template, artifact)
+
+ capabilities = node_template._get_capabilities(context)
+ if capabilities:
+ for capability_name, capability in capabilities.iteritems():
+ model.capability_templates[capability_name] = \
+ create_capability_template_model(context, service_template, capability)
+
+ if node_template.node_filter:
+ model.target_node_template_constraints = []
+ create_node_filter_constraints(context, node_template.node_filter,
+ model.target_node_template_constraints)
+
+ return model
+
+
+def fix_node_template_model(context, service_template, node_template):
+ # Requirements have to be created after all node templates have been created, because
+ # requirements might reference another node template
+ model = service_template.node_templates[node_template._name]
+ requirements = node_template._get_requirements(context)
+ if requirements:
+ for _, requirement in requirements:
+ model.requirement_templates.append(create_requirement_template_model(context,
+ service_template,
+ requirement))
+
+
+def create_group_template_model(context, service_template, group):
+ group_type = group._get_type(context)
+ group_type = service_template.group_types.get_descendant(group_type._name)
+ model = GroupTemplate(name=group._name,
+ type=group_type)
+
+ if group.description:
+ model.description = group.description.value
+
+ model.properties.update(create_property_models_from_values(group._get_property_values(context)))
+
+ create_interface_template_models(context, service_template, model.interface_templates,
+ group._get_interfaces(context))
+ members = group.members
+ if members:
+ for member in members:
+ node_template = service_template.node_templates[member]
+ assert node_template
+ model.node_templates.append(node_template)
+
+ return model
+
+
+def create_policy_template_model(context, service_template, policy):
+ policy_type = policy._get_type(context)
+ policy_type = service_template.policy_types.get_descendant(policy_type._name)
+ model = PolicyTemplate(name=policy._name,
+ type=policy_type)
+
+ if policy.description:
+ model.description = policy.description.value
+
+ model.properties.update(
+ create_property_models_from_values(policy._get_property_values(context)))
+
+ node_templates, groups = policy._get_targets(context)
+ if node_templates:
+ for target in node_templates:
+ node_template = service_template.node_templates[target._name]
+ assert node_template
+ model.node_templates.append(node_template)
+ if groups:
+ for target in groups:
+ group_template = service_template.group_templates[target._name]
+ assert group_template
+ model.group_templates.append(group_template)
+
+ return model
+
+
+def create_requirement_template_model(context, service_template, requirement):
+ model = {'name': requirement._name}
+
+ node, node_variant = requirement._get_node(context)
+ if node is not None:
+ if node_variant == 'node_type':
+ node_type = service_template.node_types.get_descendant(node._name)
+ model['target_node_type'] = node_type
+ else:
+ node_template = service_template.node_templates[node._name]
+ model['target_node_template'] = node_template
+
+ capability, capability_variant = requirement._get_capability(context)
+ if capability is not None:
+ if capability_variant == 'capability_type':
+ capability_type = \
+ service_template.capability_types.get_descendant(capability._name)
+ model['target_capability_type'] = capability_type
+ else:
+ model['target_capability_name'] = capability._name
+
+ model = RequirementTemplate(**model)
+
+ if requirement.node_filter:
+ model.target_node_template_constraints = []
+ create_node_filter_constraints(context, requirement.node_filter,
+ model.target_node_template_constraints)
+
+ relationship = requirement.relationship
+ if relationship is not None:
+ model.relationship_template = \
+ create_relationship_template_model(context, service_template, relationship)
+ model.relationship_template.name = requirement._name
+
+ return model
+
+
+def create_relationship_template_model(context, service_template, relationship):
+ relationship_type, relationship_type_variant = relationship._get_type(context)
+ if relationship_type_variant == 'relationship_type':
+ relationship_type = service_template.relationship_types.get_descendant(
+ relationship_type._name)
+ model = RelationshipTemplate(type=relationship_type)
+ else:
+ relationship_template = relationship_type
+ relationship_type = relationship_template._get_type(context)
+ relationship_type = service_template.relationship_types.get_descendant(
+ relationship_type._name)
+ model = RelationshipTemplate(type=relationship_type)
+ if relationship_template.description:
+ model.description = relationship_template.description.value
+
+ create_parameter_models_from_assignments(model.properties,
+ relationship.properties,
+ model_cls=Property)
+ create_interface_template_models(context, service_template, model.interface_templates,
+ relationship.interfaces)
+
+ return model
+
+
+def create_capability_template_model(context, service_template, capability):
+ capability_type = capability._get_type(context)
+ capability_type = service_template.capability_types.get_descendant(capability_type._name)
+ model = CapabilityTemplate(name=capability._name,
+ type=capability_type)
+
+ capability_definition = capability._get_definition(context)
+ if capability_definition.description:
+ model.description = capability_definition.description.value
+ occurrences = capability_definition.occurrences
+ if occurrences is not None:
+ model.min_occurrences = occurrences.value[0]
+ if occurrences.value[1] != 'UNBOUNDED':
+ model.max_occurrences = occurrences.value[1]
+
+ valid_source_types = capability_definition.valid_source_types
+ if valid_source_types:
+ for valid_source_type in valid_source_types:
+ # TODO: handle shortcut type names
+ node_type = service_template.node_types.get_descendant(valid_source_type)
+ model.valid_source_node_types.append(node_type)
+
+ create_parameter_models_from_assignments(model.properties,
+ capability.properties,
+ model_cls=Property)
+
+ return model
+
+
+def create_interface_template_model(context, service_template, interface):
+ interface_type = interface._get_type(context)
+ interface_type = service_template.interface_types.get_descendant(interface_type._name)
+ model = InterfaceTemplate(name=interface._name, type=interface_type)
+
+ if interface_type.description:
+ model.description = interface_type.description
+
+ create_parameter_models_from_assignments(model.inputs, interface.inputs, model_cls=Input)
+
+ operations = interface.operations
+ if operations:
+ for operation_name, operation in operations.iteritems():
+ model.operation_templates[operation_name] = \
+ create_operation_template_model(context, service_template, operation)
+
+ return model if model.operation_templates else None
+
+
+def create_operation_template_model(context, service_template, operation):
+ model = OperationTemplate(name=operation._name)
+
+ if operation.description:
+ model.description = operation.description.value
+
+ implementation = operation.implementation
+ if implementation is not None:
+ primary = implementation.primary
+ extract_implementation_primary(context, service_template, operation, model, primary)
+ relationship_edge = operation._get_extensions(context).get('relationship_edge')
+ if relationship_edge is not None:
+ if relationship_edge == 'source':
+ model.relationship_edge = False
+ elif relationship_edge == 'target':
+ model.relationship_edge = True
+
+ dependencies = implementation.dependencies
+ configuration = OrderedDict()
+ if dependencies:
+ for dependency in dependencies:
+ key, value = split_prefix(dependency)
+ if key is not None:
+ # Special ARIA prefix: signifies configuration parameters
+
+ # Parse as YAML
+ try:
+ value = yaml.load(value)
+ except yaml.parser.MarkedYAMLError as e:
+ context.validation.report(
+ 'YAML parser {0} in operation configuration: {1}'
+ .format(e.problem, value),
+ locator=implementation._locator,
+ level=Issue.FIELD)
+ continue
+
+ # Coerce to intrinsic functions, if there are any
+ value = coerce_parameter_value(context, implementation, None, value).value
+
+ # Support dot-notation nesting
+ set_nested(configuration, key.split('.'), value)
+ else:
+ if model.dependencies is None:
+ model.dependencies = []
+ model.dependencies.append(dependency)
+
+ # Convert configuration to Configuration models
+ for key, value in configuration.iteritems():
+ model.configurations[key] = Configuration.wrap(key, value,
+ description='Operation configuration.')
+
+ create_parameter_models_from_assignments(model.inputs, operation.inputs, model_cls=Input)
+ return model
+
+
+def create_artifact_template_model(context, service_template, artifact):
+ artifact_type = artifact._get_type(context)
+ artifact_type = service_template.artifact_types.get_descendant(artifact_type._name)
+ model = ArtifactTemplate(name=artifact._name,
+ type=artifact_type,
+ source_path=artifact.file)
+
+ if artifact.description:
+ model.description = artifact.description.value
+
+ model.target_path = artifact.deploy_path
+
+ repository = artifact._get_repository(context)
+ if repository is not None:
+ model.repository_url = repository.url
+ credential = repository._get_credential(context)
+ if credential:
+ model.repository_credential = {}
+ for k, v in credential.iteritems():
+ model.repository_credential[k] = v
+
+ model.properties.update(
+ create_property_models_from_values(artifact._get_property_values(context)))
+
+ return model
+
+
+def create_substitution_template_model(context, service_template, substitution_mappings):
+ node_type = service_template.node_types.get_descendant(substitution_mappings.node_type)
+ model = SubstitutionTemplate(node_type=node_type)
+
+ capabilities = substitution_mappings.capabilities
+ if capabilities:
+ for mapped_capability_name, capability in capabilities.iteritems():
+ name = 'capability.' + mapped_capability_name
+ node_template_model = service_template.node_templates[capability.node_template]
+ capability_template_model = \
+ node_template_model.capability_templates[capability.capability]
+ model.mappings[name] = \
+ SubstitutionTemplateMapping(name=name,
+ capability_template=capability_template_model)
+
+ requirements = substitution_mappings.requirements
+ if requirements:
+ for mapped_requirement_name, requirement in requirements.iteritems():
+ name = 'requirement.' + mapped_requirement_name
+ node_template_model = service_template.node_templates[requirement.node_template]
+ requirement_template_model = None
+ for a_model in node_template_model.requirement_templates:
+ if a_model.name == requirement.requirement:
+ requirement_template_model = a_model
+ break
+ model.mappings[name] = \
+ SubstitutionTemplateMapping(name=name,
+ requirement_template=requirement_template_model)
+
+ return model
+
+
+def create_plugin_specification_model(context, policy):
+ properties = policy.properties
+
+ def get(name, default=None):
+ prop = properties.get(name)
+ return prop.value if prop is not None else default
+
+ model = PluginSpecification(name=policy._name,
+ version=get('version'),
+ enabled=get('enabled', True))
+
+ return model
+
+
+def create_workflow_operation_template_model(context, service_template, policy):
+ model = OperationTemplate(name=policy._name)
+ # since we use backpopulates, these fields are populated upon commit, we get a weird(temporary)
+ # behavior where in previous code service_template.workflow_templates is a dict which has None
+ # as key for the value of model.
+ service_template.workflow_templates[model.name] = model
+
+ if policy.description:
+ model.description = policy.description.value
+
+ properties = policy._get_property_values(context)
+ for prop_name, prop in properties.iteritems():
+ if prop_name == 'implementation':
+ model.function = prop.value
+ else:
+ input_model = create_parameter_model_from_value(prop, prop_name, model_cls=Input)
+ input_model.required = prop.required
+ model.inputs[prop_name] = input_model
+
+ used_reserved_names = WORKFLOW_DECORATOR_RESERVED_ARGUMENTS.intersection(model.inputs.keys())
+ if used_reserved_names:
+ context.validation.report('using reserved arguments in workflow policy "{0}": {1}'
+ .format(
+ policy._name,
+ string_list_as_string(used_reserved_names)),
+ locator=policy._locator,
+ level=Issue.EXTERNAL)
+ return model
+
+
+#
+# Utils
+#
+
+def create_types(context, root, types):
+ if types is None:
+ return
+
+ def added_all():
+ for name in types:
+ if root.get_descendant(name) is None:
+ return False
+ return True
+
+ while not added_all():
+ for name, the_type in types.iteritems():
+ if root.get_descendant(name) is None:
+ parent_type = the_type._get_parent(context)
+ model = Type(name=the_type._name,
+ role=the_type._get_extension('role'))
+ if the_type.description:
+ model.description = the_type.description.value
+ if parent_type is None:
+ model.parent = root
+ model.variant = root.variant
+ root.children.append(model)
+ else:
+ container = root.get_descendant(parent_type._name)
+ if container is not None:
+ model.parent = container
+ model.variant = container.variant
+ container.children.append(model)
+
+
+def create_input_models_from_values(template_inputs):
+ model_inputs = {}
+ if template_inputs:
+ for template_input_name, template_input in template_inputs.iteritems():
+ model_input = create_parameter_model_from_value(template_input, template_input_name,
+ model_cls=Input)
+ model_input.required = template_input.required
+ model_inputs[model_input.name] = model_input
+ return model_inputs
+
+def create_output_models_from_values(template_outputs):
+ model_outputs = {}
+ for template_output_name, template_output in template_outputs.iteritems():
+ model_outputs[template_output_name] = \
+ create_parameter_model_from_value(template_output,
+ template_output_name,
+ model_cls=Output)
+ return model_outputs
+
+
+def create_property_models_from_values(template_properties):
+ model_properties = {}
+ for template_property_name, template_property in template_properties.iteritems():
+ model_properties[template_property_name] = \
+ create_parameter_model_from_value(template_property,
+ template_property_name,
+ model_cls=Property)
+ return model_properties
+
+def create_attribute_models_from_values(template_attributes):
+ model_attributes = {}
+ for template_attribute_name, template_attribute in template_attributes.iteritems():
+ model_attributes[template_attribute_name] = \
+ create_parameter_model_from_value(template_attribute,
+ template_attribute_name,
+ model_cls=Attribute)
+ return model_attributes
+
+
+def create_parameter_model_from_value(template_parameter, template_parameter_name, model_cls):
+ return model_cls(name=template_parameter_name,
+ type_name=template_parameter.type,
+ value=template_parameter.value,
+ description=template_parameter.description)
+
+
+def create_parameter_models_from_assignments(properties, source_properties, model_cls):
+ if source_properties:
+ for property_name, prop in source_properties.iteritems():
+ properties[property_name] = model_cls(name=property_name, # pylint: disable=unexpected-keyword-arg
+ type_name=prop.value.type,
+ value=prop.value.value,
+ description=prop.value.description)
+
+
+def create_interface_template_models(context, service_template, interfaces, source_interfaces):
+ if source_interfaces:
+ for interface_name, interface in source_interfaces.iteritems():
+ interface = create_interface_template_model(context, service_template, interface)
+ if interface is not None:
+ interfaces[interface_name] = interface
+
+
+def create_node_filter_constraints(context, node_filter, target_node_template_constraints):
+ properties = node_filter.properties
+ if properties is not None:
+ for property_name, constraint_clause in properties:
+ constraint = create_constraint(context, node_filter, constraint_clause, property_name,
+ None)
+ target_node_template_constraints.append(constraint)
+
+ capabilities = node_filter.capabilities
+ if capabilities is not None:
+ for capability_name, capability in capabilities:
+ properties = capability.properties
+ if properties is not None:
+ for property_name, constraint_clause in properties:
+ constraint = create_constraint(context, node_filter, constraint_clause,
+ property_name, capability_name)
+ target_node_template_constraints.append(constraint)
+
+
+def create_constraint(context, node_filter, constraint_clause, property_name, capability_name): # pylint: disable=too-many-return-statements
+ constraint_key = constraint_clause._raw.keys()[0]
+
+ the_type = constraint_clause._get_type(context)
+
+ def coerce_constraint(constraint):
+ if the_type is not None:
+ return coerce_value(context, node_filter, the_type, None, None, constraint,
+ constraint_key)
+ else:
+ return constraint
+
+ def coerce_constraints(constraints):
+ if the_type is not None:
+ return tuple(coerce_constraint(constraint) for constraint in constraints)
+ else:
+ return constraints
+
+ if constraint_key == 'equal':
+ return Equal(property_name, capability_name,
+ coerce_constraint(constraint_clause.equal))
+ elif constraint_key == 'greater_than':
+ return GreaterThan(property_name, capability_name,
+ coerce_constraint(constraint_clause.greater_than))
+ elif constraint_key == 'greater_or_equal':
+ return GreaterOrEqual(property_name, capability_name,
+ coerce_constraint(constraint_clause.greater_or_equal))
+ elif constraint_key == 'less_than':
+ return LessThan(property_name, capability_name,
+ coerce_constraint(constraint_clause.less_than))
+ elif constraint_key == 'less_or_equal':
+ return LessOrEqual(property_name, capability_name,
+ coerce_constraint(constraint_clause.less_or_equal))
+ elif constraint_key == 'in_range':
+ return InRange(property_name, capability_name,
+ coerce_constraints(constraint_clause.in_range))
+ elif constraint_key == 'valid_values':
+ return ValidValues(property_name, capability_name,
+ coerce_constraints(constraint_clause.valid_values))
+ elif constraint_key == 'length':
+ return Length(property_name, capability_name,
+ coerce_constraint(constraint_clause.length))
+ elif constraint_key == 'min_length':
+ return MinLength(property_name, capability_name,
+ coerce_constraint(constraint_clause.min_length))
+ elif constraint_key == 'max_length':
+ return MaxLength(property_name, capability_name,
+ coerce_constraint(constraint_clause.max_length))
+ elif constraint_key == 'pattern':
+ return Pattern(property_name, capability_name,
+ coerce_constraint(constraint_clause.pattern))
+ else:
+ raise ValueError('malformed node_filter: {0}'.format(constraint_key))
+
+
+def split_prefix(string):
+ """
+ Splits the prefix on the first non-escaped ">".
+ """
+
+ split = IMPLEMENTATION_PREFIX_REGEX.split(string, 1)
+ if len(split) < 2:
+ return None, None
+ return split[0].strip(), split[1].strip()
+
+
+def set_nested(the_dict, keys, value):
+ """
+ If the ``keys`` list has just one item, puts the value in the the dict. If there are more items,
+ puts the value in a sub-dict, creating sub-dicts as necessary for each key.
+
+ For example, if ``the_dict`` is an empty dict, keys is ``['first', 'second', 'third']`` and
+ value is ``'value'``, then the_dict will be: ``{'first':{'second':{'third':'value'}}}``.
+
+ :param the_dict: Dict to change
+ :type the_dict: {}
+ :param keys: Keys
+ :type keys: [basestring]
+ :param value: Value
+ """
+ key = keys.pop(0)
+ if len(keys) == 0:
+ the_dict[key] = value
+ else:
+ if key not in the_dict:
+ the_dict[key] = StrictDict(key_class=basestring)
+ set_nested(the_dict[key], keys, value)
+
+
+def extract_implementation_primary(context, service_template, presentation, model, primary):
+ prefix, postfix = split_prefix(primary)
+ if prefix:
+ # Special ARIA prefix
+ model.plugin_specification = service_template.plugin_specifications.get(prefix)
+ model.function = postfix
+ if model.plugin_specification is None:
+ context.validation.report(
+ 'no policy for plugin "{0}" specified in operation implementation: {1}'
+ .format(prefix, primary),
+ locator=presentation._get_child_locator('properties', 'implementation'),
+ level=Issue.BETWEEN_TYPES)
+ else:
+ # Standard TOSCA artifact with default plugin
+ model.implementation = primary
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
new file mode 100644
index 0000000..b45615a
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
@@ -0,0 +1,44 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import OrderedDict
+
+
+#
+# NodeType, NodeTemplate
+#
+
+def get_inherited_artifact_definitions(context, presentation, for_presentation=None):
+ if for_presentation is None:
+ for_presentation = presentation
+
+ if hasattr(presentation, '_get_type'):
+ # In NodeTemplate
+ parent = presentation._get_type(context)
+ else:
+ # In NodeType
+ parent = presentation._get_parent(context)
+
+ # Get artifact definitions from parent
+ artifacts = get_inherited_artifact_definitions(context, parent, for_presentation) \
+ if parent is not None else OrderedDict()
+
+ # Add/override our artifact definitions
+ our_artifacts = presentation.artifacts
+ if our_artifacts:
+ for artifact_name, artifact in our_artifacts.iteritems():
+ artifacts[artifact_name] = artifact._clone(for_presentation)
+
+ return artifacts
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
new file mode 100644
index 0000000..1b95bec
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
@@ -0,0 +1,220 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import deepcopy_with_locators, OrderedDict
+from aria.parser.validation import Issue
+
+from .parameters import (convert_parameter_definitions_to_values, merge_raw_parameter_definitions,
+ get_assigned_and_defined_parameter_values)
+
+
+#
+# CapabilityType
+#
+
+def get_inherited_valid_source_types(context, presentation):
+ """
+ If we haven't set the ``valid_source_types`` fields, uses that value from our parent, if we have
+ one (recursively).
+ """
+
+ valid_source_types = presentation.valid_source_types
+
+ if valid_source_types is None:
+ parent = presentation._get_parent(context)
+ valid_source_types = get_inherited_valid_source_types(context, parent) \
+ if parent is not None else None
+
+ return valid_source_types
+
+
+#
+# NodeType
+#
+
+def get_inherited_capability_definitions(context, presentation, for_presentation=None):
+ """
+ Returns our capability capability definitions added on top of those of our parent, if we have
+ one (recursively).
+
+ Allows overriding all aspects of parent capability properties except data type.
+ """
+
+ if for_presentation is None:
+ for_presentation = presentation
+
+ # Get capability definitions from parent
+ parent = presentation._get_parent(context)
+ capability_definitions = get_inherited_capability_definitions(
+ context, parent, for_presentation) if parent is not None else OrderedDict()
+
+ # Add/merge our capability definitions
+ our_capability_definitions = presentation.capabilities
+ if our_capability_definitions:
+ for capability_name, our_capability_definition in our_capability_definitions.iteritems():
+ if capability_name in capability_definitions:
+ capability_definition = capability_definitions[capability_name]
+
+ # Check if we changed the type
+ type1 = capability_definition._get_type(context)
+ type2 = our_capability_definition._get_type(context)
+
+ if not type1._is_descendant(context, type2):
+ context.validation.report(
+ 'capability definition type "{0}" is not a descendant of overridden '
+ 'capability definition type "{1}"' \
+ .format(type1._name, type2._name),
+ locator=our_capability_definition._locator, level=Issue.BETWEEN_TYPES)
+
+ merge_capability_definition(context, presentation, capability_definition,
+ our_capability_definition)
+ else:
+ capability_definition = our_capability_definition._clone(for_presentation)
+ if isinstance(capability_definition._raw, basestring):
+ # Make sure we have a dict
+ the_type = capability_definition._raw
+ capability_definition._raw = OrderedDict()
+ capability_definition._raw['type'] = the_type
+ capability_definitions[capability_name] = capability_definition
+
+ merge_capability_definition_from_type(context, presentation, capability_definition)
+
+ for capability_definition in capability_definitions.itervalues():
+ capability_definition._reset_method_cache()
+
+ return capability_definitions
+
+
+#
+# NodeTemplate
+#
+
+def get_template_capabilities(context, presentation):
+ """
+ Returns the node type's capabilities with our assignments to properties and attributes merged
+ in.
+
+ Capability properties' default values, if available, will be used if we did not assign them.
+
+ Makes sure that required properties indeed end up with a value.
+ """
+
+ capability_assignments = OrderedDict()
+
+ the_type = presentation._get_type(context) # NodeType
+ capability_definitions = the_type._get_capabilities(context) if the_type is not None else None
+
+ # Copy over capability definitions from the type (will initialize properties with default
+ # values)
+ if capability_definitions:
+ for capability_name, capability_definition in capability_definitions.iteritems():
+ capability_assignments[capability_name] = \
+ convert_capability_from_definition_to_assignment(context, capability_definition,
+ presentation)
+
+ # Fill in our capability assignments
+ our_capability_assignments = presentation.capabilities
+ if our_capability_assignments:
+ for capability_name, our_capability_assignment in our_capability_assignments.iteritems():
+ if capability_name in capability_assignments:
+ capability_assignment = capability_assignments[capability_name]
+
+ # Assign properties
+ values = get_assigned_and_defined_parameter_values(context,
+ our_capability_assignment,
+ 'property')
+
+ if values:
+ capability_assignment._raw['properties'] = values
+ capability_assignment._reset_method_cache()
+ else:
+ context.validation.report(
+ 'capability "{0}" not declared at node type "{1}" in "{2}"'
+ .format(capability_name, presentation.type, presentation._fullname),
+ locator=our_capability_assignment._locator, level=Issue.BETWEEN_TYPES)
+
+ return capability_assignments
+
+
+#
+# Utils
+#
+
+def convert_capability_from_definition_to_assignment(context, presentation, container):
+ from ..assignments import CapabilityAssignment
+
+ raw = OrderedDict()
+
+ properties = presentation.properties
+ if properties is not None:
+ raw['properties'] = convert_parameter_definitions_to_values(context, properties)
+
+ # TODO attributes
+
+ return CapabilityAssignment(name=presentation._name, raw=raw, container=container)
+
+
+def merge_capability_definition(context, presentation, capability_definition,
+ from_capability_definition):
+ raw_properties = OrderedDict()
+
+ capability_definition._raw['type'] = from_capability_definition.type
+
+ # Merge properties from type
+ from_property_defintions = from_capability_definition.properties
+ merge_raw_parameter_definitions(context, presentation, raw_properties, from_property_defintions,
+ 'properties')
+
+ # Merge our properties
+ merge_raw_parameter_definitions(context, presentation, raw_properties,
+ capability_definition.properties, 'properties')
+
+ if raw_properties:
+ capability_definition._raw['properties'] = raw_properties
+ capability_definition._reset_method_cache()
+
+ # Merge occurrences
+ occurrences = from_capability_definition._raw.get('occurrences')
+ if (occurrences is not None) and (capability_definition._raw.get('occurrences') is None):
+ capability_definition._raw['occurrences'] = \
+ deepcopy_with_locators(occurrences)
+
+
+def merge_capability_definition_from_type(context, presentation, capability_definition):
+ """
+ Merge ``properties`` and ``valid_source_types`` from the node type's capability definition
+ over those taken from the parent node type.
+ """
+ raw_properties = OrderedDict()
+
+ # Merge properties from parent
+ the_type = capability_definition._get_type(context)
+ type_property_defintions = the_type._get_properties(context)
+ merge_raw_parameter_definitions(context, presentation, raw_properties, type_property_defintions,
+ 'properties')
+
+ # Merge our properties (might override definitions in parent)
+ merge_raw_parameter_definitions(context, presentation, raw_properties,
+ capability_definition.properties, 'properties')
+
+ if raw_properties:
+ capability_definition._raw['properties'] = raw_properties
+
+ # Override valid_source_types
+ if capability_definition._raw.get('valid_source_types') is None:
+ valid_source_types = the_type._get_valid_source_types(context)
+ if valid_source_types is not None:
+ capability_definition._raw['valid_source_types'] = \
+ deepcopy_with_locators(valid_source_types)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/constraints.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/constraints.py
new file mode 100644
index 0000000..9a30cc1
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/constraints.py
@@ -0,0 +1,144 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.modeling.constraints import NodeTemplateConstraint
+from aria.modeling.utils import NodeTemplateContainerHolder
+from aria.modeling.functions import evaluate
+from aria.parser import implements_specification
+
+
+@implements_specification('3.5.2-2', 'tosca-simple-1.0')
+class EvaluatingNodeTemplateConstraint(NodeTemplateConstraint):
+ """
+ A version of :class:`NodeTemplateConstraint` with boilerplate initialization for TOSCA
+ constraints.
+ """
+
+ def __init__(self, property_name, capability_name, constraint, as_list=False):
+ self.property_name = property_name
+ self.capability_name = capability_name
+ self.constraint = constraint
+ self.as_list = as_list
+
+ def matches(self, source_node_template, target_node_template):
+ # TOSCA node template constraints can refer to either capability properties or node
+ # template properties
+ if self.capability_name is not None:
+ # Capability property
+ capability = target_node_template.capability_templates.get(self.capability_name)
+ value = capability.properties.get(self.property_name) \
+ if capability is not None else None # Parameter
+ else:
+ # Node template property
+ value = target_node_template.properties.get(self.property_name) # Parameter
+
+ value = value.value if value is not None else None
+
+ container_holder = NodeTemplateContainerHolder(source_node_template)
+
+ if self.as_list:
+ constraints = []
+ for constraint in self.constraint:
+ evaluation = evaluate(constraint, container_holder)
+ if evaluation is not None:
+ constraints.append(evaluation.value)
+ else:
+ constraints.append(constraint)
+ constraint = constraints
+ else:
+ evaluation = evaluate(self.constraint, container_holder)
+ if evaluation is not None:
+ constraint = evaluation.value
+ else:
+ constraint = self.constraint
+
+ return self.matches_evaluated(value, constraint)
+
+ def matches_evaluated(self, value, constraint):
+ raise NotImplementedError
+
+
+class Equal(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ return value == constraint
+
+
+class GreaterThan(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ return value > constraint
+
+
+class GreaterOrEqual(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ return value >= constraint
+
+
+class LessThan(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ return value < constraint
+
+
+class LessOrEqual(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ return value <= constraint
+
+
+class InRange(EvaluatingNodeTemplateConstraint):
+ def __init__(self, property_name, capability_name, constraint):
+ super(InRange, self).__init__(property_name, capability_name, constraint, as_list=True)
+
+ def matches_evaluated(self, value, constraints):
+ lower, upper = constraints
+ if value < lower:
+ return False
+ if (upper != 'UNBOUNDED') and (value > upper):
+ return False
+ return True
+
+
+class ValidValues(EvaluatingNodeTemplateConstraint):
+ def __init__(self, property_name, capability_name, constraint):
+ super(ValidValues, self).__init__(property_name, capability_name, constraint, as_list=True)
+
+ def matches_evaluated(self, value, constraints):
+ return value in constraints
+
+
+class Length(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ return len(value) == constraint
+
+
+class MinLength(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ return len(value) >= constraint
+
+
+class MaxLength(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ return len(value) <= constraint
+
+
+class Pattern(EvaluatingNodeTemplateConstraint):
+ def matches_evaluated(self, value, constraint):
+ # From TOSCA 1.0 3.5.2.1:
+ #
+ # "Note: Future drafts of this specification will detail the use of regular expressions and
+ # reference an appropriate standardized grammar."
+ #
+ # So we will just use Python's.
+ return re.match(constraint, unicode(value)) is not None
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/copy.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/copy.py
new file mode 100644
index 0000000..bd9037f
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/copy.py
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+#
+# NodeTemplate, RelationshipTemplate
+#
+
+def get_default_raw_from_copy(presentation, field_name):
+ """
+ Used for the ``_get_default_raw`` field hook.
+ """
+
+ copy = presentation._raw.get('copy')
+ if copy is not None:
+ templates = getattr(presentation._container, field_name)
+ if templates is not None:
+ template = templates.get(copy)
+ if template is not None:
+ return template._raw
+ return None
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
new file mode 100644
index 0000000..13ce9a3
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
@@ -0,0 +1,514 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import OrderedDict
+from aria.utils.formatting import safe_repr
+from aria.utils.type import full_type_name
+from aria.utils.imports import import_fullname
+from aria.parser import implements_specification
+from aria.parser.presentation import (get_locator, validate_primitive)
+from aria.parser.validation import Issue
+
+from .functions import get_function
+from ..presentation.types import get_type_by_name
+
+
+#
+# DataType
+#
+
+def get_inherited_constraints(context, presentation):
+ """
+ If we don't have constraints, will return our parent's constraints (if we have one),
+ recursively.
+
+ Implication: if we define even one constraint, the parent's constraints will not be inherited.
+ """
+
+ constraints = presentation.constraints
+
+ if constraints is None:
+ # If we don't have any, use our parent's
+ parent = presentation._get_parent(context)
+ parent_constraints = get_inherited_constraints(context, parent) \
+ if parent is not None else None
+ if parent_constraints is not None:
+ constraints = parent_constraints
+
+ return constraints
+
+
+def coerce_data_type_value(context, presentation, data_type, entry_schema, constraints, value, # pylint: disable=unused-argument
+ aspect):
+ """
+ Handles the ``_coerce_data()`` hook for complex data types.
+
+ There are two kinds of handling:
+
+ 1. If we have a primitive type as our great ancestor, then we do primitive type coersion, and
+ just check for constraints.
+
+ 2. Otherwise, for normal complex data types we return the assigned property values while making
+ sure they are defined in our type. The property definition's default value, if available,
+ will be used if we did not assign it. We also make sure that required definitions indeed end
+ up with a value.
+ """
+
+ primitive_type = data_type._get_primitive_ancestor(context)
+ if primitive_type is not None:
+ # Must be coercible to primitive ancestor
+ value = coerce_to_primitive(context, presentation, primitive_type, constraints, value,
+ aspect)
+ else:
+ definitions = data_type._get_properties(context)
+ if isinstance(value, dict):
+ temp = OrderedDict()
+
+ # Fill in our values, but make sure they are defined
+ for name, v in value.iteritems():
+ if name in definitions:
+ definition = definitions[name]
+ definition_type = definition._get_type(context)
+ definition_entry_schema = definition.entry_schema
+ definition_constraints = definition._get_constraints(context)
+ temp[name] = coerce_value(context, presentation, definition_type,
+ definition_entry_schema, definition_constraints, v,
+ aspect)
+ else:
+ context.validation.report(
+ 'assignment to undefined property "%s" in type "%s" in "%s"'
+ % (name, data_type._fullname, presentation._fullname),
+ locator=get_locator(v, value, presentation), level=Issue.BETWEEN_TYPES)
+
+ # Fill in defaults from the definitions, and check if required definitions have not been
+ # assigned
+ for name, definition in definitions.iteritems():
+ if (temp.get(name) is None) and hasattr(definition, 'default') \
+ and (definition.default is not None):
+ definition_type = definition._get_type(context)
+ definition_entry_schema = definition.entry_schema
+ definition_constraints = definition._get_constraints(context)
+ temp[name] = coerce_value(context, presentation, definition_type,
+ definition_entry_schema, definition_constraints,
+ definition.default, 'default')
+
+ if getattr(definition, 'required', False) and (temp.get(name) is None):
+ context.validation.report(
+ 'required property "%s" in type "%s" is not assigned a value in "%s"'
+ % (name, data_type._fullname, presentation._fullname),
+ locator=presentation._get_child_locator('definitions'),
+ level=Issue.BETWEEN_TYPES)
+
+ value = temp
+ elif value is not None:
+ context.validation.report('value of type "%s" is not a dict in "%s"'
+ % (data_type._fullname, presentation._fullname),
+ locator=get_locator(value, presentation),
+ level=Issue.BETWEEN_TYPES)
+ value = None
+
+ return value
+
+
+def validate_data_type_name(context, presentation):
+ """
+ Makes sure the complex data type's name is not that of a built-in type.
+ """
+
+ name = presentation._name
+ if get_primitive_data_type(name) is not None:
+ context.validation.report('data type name is that of a built-in type: %s'
+ % safe_repr(name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+
+
+#
+# PropertyDefinition, AttributeDefinition, EntrySchema, DataType
+#
+
+def get_data_type(context, presentation, field_name, allow_none=False):
+ """
+ Returns the type, whether it's a complex data type (a DataType instance) or a primitive (a
+ Python primitive type class).
+
+ If the type is not specified, defaults to :class:`str`, per note in section 3.2.1.1 of the
+ `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #_Toc379455072>`__
+ """
+
+ type_name = getattr(presentation, field_name)
+
+ if type_name is None:
+ if allow_none:
+ return None
+ else:
+ return str
+
+ # Avoid circular definitions
+ container_data_type = get_container_data_type(presentation)
+ if (container_data_type is not None) and (container_data_type._name == type_name):
+ return None
+
+ # Try complex data type
+ data_type = get_type_by_name(context, type_name, 'data_types')
+ if data_type is not None:
+ return data_type
+
+ # Try primitive data type
+ return get_primitive_data_type(type_name)
+
+
+#
+# PropertyDefinition, EntrySchema
+#
+
+def get_property_constraints(context, presentation):
+ """
+ If we don't have constraints, will return our type's constraints (if we have one), recursively.
+
+ Implication: if we define even one constraint, the type's constraints will not be inherited.
+ """
+
+ constraints = presentation.constraints
+
+ if constraints is None:
+ # If we don't have any, use our type's
+ the_type = presentation._get_type(context)
+ type_constraints = the_type._get_constraints(context) \
+ if hasattr(the_type, '_get_constraints') else None
+ if type_constraints is not None:
+ constraints = type_constraints
+
+ return constraints
+
+
+#
+# ConstraintClause
+#
+
+def apply_constraint_to_value(context, presentation, constraint_clause, value): # pylint: disable=too-many-statements,too-many-return-statements,too-many-branches
+ """
+ Returns false if the value does not conform to the constraint.
+ """
+
+ constraint_key = constraint_clause._raw.keys()[0]
+ the_type = constraint_clause._get_type(context)
+ # PropertyAssignment does not have this:
+ entry_schema = getattr(presentation, 'entry_schema', None)
+
+ def coerce_constraint(constraint):
+ return coerce_value(context, presentation, the_type, entry_schema, None, constraint,
+ constraint_key)
+
+ def report(message, constraint):
+ context.validation.report('value %s %s per constraint in "%s": %s'
+ % (message, safe_repr(constraint),
+ presentation._name or presentation._container._name,
+ safe_repr(value)),
+ locator=presentation._locator, level=Issue.BETWEEN_FIELDS)
+
+ if constraint_key == 'equal':
+ constraint = coerce_constraint(constraint_clause.equal)
+ if value != constraint:
+ report('is not equal to', constraint)
+ return False
+
+ elif constraint_key == 'greater_than':
+ constraint = coerce_constraint(constraint_clause.greater_than)
+ if value <= constraint:
+ report('is not greater than', constraint)
+ return False
+
+ elif constraint_key == 'greater_or_equal':
+ constraint = coerce_constraint(constraint_clause.greater_or_equal)
+ if value < constraint:
+ report('is not greater than or equal to', constraint)
+ return False
+
+ elif constraint_key == 'less_than':
+ constraint = coerce_constraint(constraint_clause.less_than)
+ if value >= constraint:
+ report('is not less than', constraint)
+ return False
+
+ elif constraint_key == 'less_or_equal':
+ constraint = coerce_constraint(constraint_clause.less_or_equal)
+ if value > constraint:
+ report('is not less than or equal to', constraint)
+ return False
+
+ elif constraint_key == 'in_range':
+ lower, upper = constraint_clause.in_range
+ lower, upper = coerce_constraint(lower), coerce_constraint(upper)
+ if value < lower:
+ report('is not greater than or equal to lower bound', lower)
+ return False
+ if (upper != 'UNBOUNDED') and (value > upper):
+ report('is not lesser than or equal to upper bound', upper)
+ return False
+
+ elif constraint_key == 'valid_values':
+ constraint = tuple(coerce_constraint(v) for v in constraint_clause.valid_values)
+ if value not in constraint:
+ report('is not one of', constraint)
+ return False
+
+ elif constraint_key == 'length':
+ constraint = constraint_clause.length
+ try:
+ if len(value) != constraint:
+ report('is not of length', constraint)
+ return False
+ except TypeError:
+ pass # should be validated elsewhere
+
+ elif constraint_key == 'min_length':
+ constraint = constraint_clause.min_length
+ try:
+ if len(value) < constraint:
+ report('has a length lesser than', constraint)
+ return False
+ except TypeError:
+ pass # should be validated elsewhere
+
+ elif constraint_key == 'max_length':
+ constraint = constraint_clause.max_length
+ try:
+ if len(value) > constraint:
+ report('has a length greater than', constraint)
+ return False
+ except TypeError:
+ pass # should be validated elsewhere
+
+ elif constraint_key == 'pattern':
+ constraint = constraint_clause.pattern
+ try:
+ # From TOSCA 1.0 3.5.2.1:
+ #
+ # "Note: Future drafts of this specification will detail the use of regular expressions
+ # and reference an appropriate standardized grammar."
+ #
+ # So we will just use Python's.
+ if re.match(constraint, str(value)) is None:
+ report('does not match regular expression', constraint)
+ return False
+ except re.error:
+ pass # should be validated elsewhere
+
+ return True
+
+
+#
+# Repository
+#
+
+def get_data_type_value(context, presentation, field_name, type_name):
+ the_type = get_type_by_name(context, type_name, 'data_types')
+ if the_type is not None:
+ value = getattr(presentation, field_name)
+ if value is not None:
+ return coerce_data_type_value(context, presentation, the_type, None, None, value, None)
+ else:
+ context.validation.report('field "%s" in "%s" refers to unknown data type "%s"'
+ % (field_name, presentation._fullname, type_name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ return None
+
+
+#
+# Utils
+#
+
+PRIMITIVE_DATA_TYPES = {
+ # YAML 1.2:
+ 'tag:yaml.org,2002:str': unicode,
+ 'tag:yaml.org,2002:integer': int,
+ 'tag:yaml.org,2002:float': float,
+ 'tag:yaml.org,2002:bool': bool,
+ 'tag:yaml.org,2002:null': None.__class__,
+
+ # TOSCA aliases:
+ 'string': unicode,
+ 'integer': int,
+ 'float': float,
+ 'boolean': bool,
+ 'null': None.__class__}
+
+
+@implements_specification('3.2.1-3', 'tosca-simple-1.0')
+def get_primitive_data_type(type_name):
+ """
+ Many of the types we use in this profile are built-in types from the YAML 1.2 specification
+ (i.e., those identified by the "tag:yaml.org,2002" version tag) [YAML-1.2].
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #_Toc373867862>`__
+ """
+
+ return PRIMITIVE_DATA_TYPES.get(type_name)
+
+
+def get_data_type_name(the_type):
+ """
+ Returns the name of the type, whether it's a DataType, a primitive type, or another class.
+ """
+
+ return the_type._name if hasattr(the_type, '_name') else full_type_name(the_type)
+
+
+def coerce_value(context, presentation, the_type, entry_schema, constraints, value, aspect=None): # pylint: disable=too-many-return-statements
+ """
+ Returns the value after it's coerced to its type, reporting validation errors if it cannot be
+ coerced.
+
+ Supports both complex data types and primitives.
+
+ Data types can use the ``coerce_value`` extension to hook their own specialized function.
+ If the extension is present, we will delegate to that hook.
+ """
+
+ # TODO: should support models as well as presentations
+
+ is_function, func = get_function(context, presentation, value)
+ if is_function:
+ return func
+
+ if the_type is None:
+ return value
+
+ if the_type == None.__class__:
+ if value is not None:
+ context.validation.report('field "%s" is of type "null" but has a non-null value: %s'
+ % (presentation._name, safe_repr(value)),
+ locator=presentation._locator, level=Issue.BETWEEN_FIELDS)
+ return None
+
+ # Delegate to 'coerce_value' extension
+ if hasattr(the_type, '_get_extension'):
+ coerce_value_fn_name = the_type._get_extension('coerce_value')
+ if coerce_value_fn_name is not None:
+ if value is None:
+ return None
+ coerce_value_fn = import_fullname(coerce_value_fn_name)
+ return coerce_value_fn(context, presentation, the_type, entry_schema, constraints,
+ value, aspect)
+
+ if hasattr(the_type, '_coerce_value'):
+ # Delegate to '_coerce_value' (likely a DataType instance)
+ return the_type._coerce_value(context, presentation, entry_schema, constraints, value,
+ aspect)
+
+ # Coerce to primitive type
+ return coerce_to_primitive(context, presentation, the_type, constraints, value, aspect)
+
+
+def coerce_to_primitive(context, presentation, primitive_type, constraints, value, aspect=None):
+ """
+ Returns the value after it's coerced to a primitive type, translating exceptions to validation
+ errors if it cannot be coerced.
+ """
+
+ if value is None:
+ return None
+
+ try:
+ # Coerce
+ value = validate_primitive(value, primitive_type,
+ context.validation.allow_primitive_coersion)
+
+ # Check constraints
+ apply_constraints_to_value(context, presentation, constraints, value)
+ except (ValueError, TypeError) as e:
+ report_issue_for_bad_format(context, presentation, primitive_type, value, aspect, e)
+ value = None
+
+ return value
+
+
+def coerce_to_data_type_class(context, presentation, cls, entry_schema, constraints, value,
+ aspect=None):
+ """
+ Returns the value after it's coerced to a data type class, reporting validation errors if it
+ cannot be coerced. Constraints will be applied after coersion.
+
+ Will either call a ``_create`` static function in the class, or instantiate it using a
+ constructor if ``_create`` is not available.
+
+ This will usually be called by a ``coerce_value`` extension hook in a :class:`DataType`.
+ """
+
+ try:
+ if hasattr(cls, '_create'):
+ # Instantiate using creator function
+ value = cls._create(context, presentation, entry_schema, constraints, value, aspect)
+ else:
+ # Normal instantiation
+ value = cls(entry_schema, constraints, value, aspect)
+ except ValueError as e:
+ report_issue_for_bad_format(context, presentation, cls, value, aspect, e)
+ value = None
+
+ # Check constraints
+ value = apply_constraints_to_value(context, presentation, constraints, value)
+
+ return value
+
+
+def apply_constraints_to_value(context, presentation, constraints, value):
+ """
+ Applies all constraints to the value. If the value conforms, returns the value. If it does not
+ conform, returns None.
+ """
+
+ if (value is not None) and (constraints is not None):
+ valid = True
+ for constraint in constraints:
+ if not constraint._apply_to_value(context, presentation, value):
+ valid = False
+ if not valid:
+ value = None
+ return value
+
+
+def get_container_data_type(presentation):
+ if presentation is None:
+ return None
+ if type(presentation).__name__ == 'DataType':
+ return presentation
+ return get_container_data_type(presentation._container)
+
+
+def report_issue_for_bad_format(context, presentation, the_type, value, aspect, e):
+ if aspect == 'default':
+ aspect = '"default" value'
+ elif aspect is not None:
+ aspect = '"%s" aspect' % aspect
+
+ if aspect is not None:
+ context.validation.report('%s for field "%s" is not a valid "%s": %s'
+ % (aspect, presentation._name or presentation._container._name,
+ get_data_type_name(the_type), safe_repr(value)),
+ locator=presentation._locator, level=Issue.BETWEEN_FIELDS,
+ exception=e)
+ else:
+ context.validation.report('field "%s" is not a valid "%s": %s'
+ % (presentation._name or presentation._container._name,
+ get_data_type_name(the_type), safe_repr(value)),
+ locator=presentation._locator, level=Issue.BETWEEN_FIELDS,
+ exception=e)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
new file mode 100644
index 0000000..ecbfde9
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
@@ -0,0 +1,681 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 StringIO import StringIO # Note: cStringIO does not support Unicode
+import re
+
+from aria.utils.collections import FrozenList
+from aria.utils.formatting import (as_raw, safe_repr)
+from aria.utils.type import full_type_name
+from aria.parser import implements_specification
+from aria.parser.exceptions import InvalidValueError
+from aria.parser.validation import Issue
+from aria.modeling.exceptions import CannotEvaluateFunctionException
+from aria.modeling.models import (Node, NodeTemplate, Relationship, RelationshipTemplate)
+from aria.modeling.functions import (Function, Evaluation)
+
+
+#
+# Intrinsic
+#
+
+@implements_specification('4.3.1', 'tosca-simple-1.0')
+class Concat(Function):
+ """
+ The ``concat`` function is used to concatenate two or more string values within a TOSCA
+ service template.
+ """
+
+ def __init__(self, context, presentation, argument):
+ self.locator = presentation._locator
+
+ if not isinstance(argument, list):
+ raise InvalidValueError(
+ 'function "concat" argument must be a list of string expressions: {0}'
+ .format(safe_repr(argument)),
+ locator=self.locator)
+
+ string_expressions = []
+ for index, an_argument in enumerate(argument):
+ string_expressions.append(parse_string_expression(context, presentation, 'concat',
+ index, None, an_argument))
+ self.string_expressions = FrozenList(string_expressions)
+
+ @property
+ def as_raw(self):
+ string_expressions = []
+ for string_expression in self.string_expressions:
+ if hasattr(string_expression, 'as_raw'):
+ string_expression = as_raw(string_expression)
+ string_expressions.append(string_expression)
+ return {'concat': string_expressions}
+
+ def __evaluate__(self, container_holder):
+ final = True
+ value = StringIO()
+ for e in self.string_expressions:
+ e, final = evaluate(e, final, container_holder)
+ if e is not None:
+ value.write(unicode(e))
+ value = value.getvalue() or u''
+ return Evaluation(value, final)
+
+
+@implements_specification('4.3.2', 'tosca-simple-1.0')
+class Token(Function):
+ """
+ The ``token`` function is used within a TOSCA service template on a string to parse out
+ (tokenize) substrings separated by one or more token characters within a larger string.
+ """
+
+ def __init__(self, context, presentation, argument):
+ self.locator = presentation._locator
+
+ if (not isinstance(argument, list)) or (len(argument) != 3):
+ raise InvalidValueError('function "token" argument must be a list of 3 parameters: {0}'
+ .format(safe_repr(argument)),
+ locator=self.locator)
+
+ self.string_with_tokens = parse_string_expression(context, presentation, 'token', 0,
+ 'the string to tokenize', argument[0])
+ self.string_of_token_chars = parse_string_expression(context, presentation, 'token', 1,
+ 'the token separator characters',
+ argument[1])
+ self.substring_index = parse_int(context, presentation, 'token', 2,
+ 'the 0-based index of the token to return', argument[2])
+
+ @property
+ def as_raw(self):
+ string_with_tokens = self.string_with_tokens
+ if hasattr(string_with_tokens, 'as_raw'):
+ string_with_tokens = as_raw(string_with_tokens)
+ string_of_token_chars = self.string_of_token_chars
+ if hasattr(string_of_token_chars, 'as_raw'):
+ string_of_token_chars = as_raw(string_of_token_chars)
+ return {'token': [string_with_tokens, string_of_token_chars, self.substring_index]}
+
+ def __evaluate__(self, container_holder):
+ final = True
+ string_with_tokens, final = evaluate(self.string_with_tokens, final, container_holder)
+ string_of_token_chars, final = evaluate(self.string_of_token_chars, final, container_holder)
+
+ if string_of_token_chars:
+ regex = '[' + ''.join(re.escape(c) for c in string_of_token_chars) + ']'
+ split = re.split(regex, string_with_tokens)
+ if self.substring_index < len(split):
+ return Evaluation(split[self.substring_index], final)
+
+ raise CannotEvaluateFunctionException()
+
+
+#
+# Property
+#
+
+@implements_specification('4.4.1', 'tosca-simple-1.0')
+class GetInput(Function):
+ """
+ The ``get_input`` function is used to retrieve the values of properties declared within the
+ inputs section of a TOSCA Service Template.
+ """
+
+ def __init__(self, context, presentation, argument):
+ self.locator = presentation._locator
+
+ self.input_property_name = parse_string_expression(context, presentation, 'get_input',
+ None, 'the input property name',
+ argument)
+
+ if isinstance(self.input_property_name, basestring):
+ the_input = context.presentation.get_from_dict('service_template', 'topology_template',
+ 'inputs', self.input_property_name)
+ if the_input is None:
+ raise InvalidValueError(
+ 'function "get_input" argument is not a valid input name: {0}'
+ .format(safe_repr(argument)),
+ locator=self.locator)
+
+ @property
+ def as_raw(self):
+ return {'get_input': as_raw(self.input_property_name)}
+
+ def __evaluate__(self, container_holder):
+ service = container_holder.service
+ if service is None:
+ raise CannotEvaluateFunctionException()
+
+ value = service.inputs.get(self.input_property_name)
+ if value is not None:
+ value = value.value
+ return Evaluation(value, False) # We never return final evaluations!
+
+ raise InvalidValueError(
+ 'function "get_input" argument is not a valid input name: {0}'
+ .format(safe_repr(self.input_property_name)),
+ locator=self.locator)
+
+
+@implements_specification('4.4.2', 'tosca-simple-1.0')
+class GetProperty(Function):
+ """
+ The ``get_property`` function is used to retrieve property values between modelable entities
+ defined in the same service template.
+ """
+
+ def __init__(self, context, presentation, argument):
+ self.locator = presentation._locator
+
+ if (not isinstance(argument, list)) or (len(argument) < 2):
+ raise InvalidValueError(
+ 'function "get_property" argument must be a list of at least 2 string expressions: '
+ '{0}'.format(safe_repr(argument)),
+ locator=self.locator)
+
+ self.modelable_entity_name = parse_modelable_entity_name(context, presentation,
+ 'get_property', 0, argument[0])
+ # The first of these will be tried as a req-or-cap name:
+ self.nested_property_name_or_index = argument[1:]
+
+ @property
+ def as_raw(self):
+ return {'get_property': [self.modelable_entity_name] + self.nested_property_name_or_index}
+
+ def __evaluate__(self, container_holder):
+ modelable_entities = get_modelable_entities(container_holder, 'get_property', self.locator,
+ self.modelable_entity_name)
+ req_or_cap_name = self.nested_property_name_or_index[0]
+
+ for modelable_entity in modelable_entities:
+ properties = None
+
+ # First argument refers to a requirement template?
+ if hasattr(modelable_entity, 'requirement_templates') \
+ and modelable_entity.requirement_templates \
+ and (req_or_cap_name in [v.name for v in modelable_entity.requirement_templates]):
+ for requirement in modelable_entity.requirement_templates:
+ if requirement.name == req_or_cap_name:
+ # TODO
+ raise CannotEvaluateFunctionException()
+ # First argument refers to a capability?
+ elif hasattr(modelable_entity, 'capabilities') \
+ and modelable_entity.capabilities \
+ and (req_or_cap_name in modelable_entity.capabilities):
+ properties = modelable_entity.capabilities[req_or_cap_name].properties
+ nested_property_name_or_index = self.nested_property_name_or_index[1:]
+ # First argument refers to a capability template?
+ elif hasattr(modelable_entity, 'capability_templates') \
+ and modelable_entity.capability_templates \
+ and (req_or_cap_name in modelable_entity.capability_templates):
+ properties = modelable_entity.capability_templates[req_or_cap_name].properties
+ nested_property_name_or_index = self.nested_property_name_or_index[1:]
+ else:
+ properties = modelable_entity.properties
+ nested_property_name_or_index = self.nested_property_name_or_index
+
+ evaluation = get_modelable_entity_parameter(modelable_entity, properties,
+ nested_property_name_or_index)
+ if evaluation is not None:
+ return evaluation
+
+ raise InvalidValueError(
+ 'function "get_property" could not find "{0}" in modelable entity "{1}"'
+ .format('.'.join(self.nested_property_name_or_index), self.modelable_entity_name),
+ locator=self.locator)
+
+
+#
+# Attribute
+#
+
+@implements_specification('4.5.1', 'tosca-simple-1.0')
+class GetAttribute(Function):
+ """
+ The ``get_attribute`` function is used to retrieve the values of named attributes declared
+ by the referenced node or relationship template name.
+ """
+
+ def __init__(self, context, presentation, argument):
+ self.locator = presentation._locator
+
+ if (not isinstance(argument, list)) or (len(argument) < 2):
+ raise InvalidValueError(
+ 'function "get_attribute" argument must be a list of at least 2 string expressions:'
+ ' {0}'.format(safe_repr(argument)),
+ locator=self.locator)
+
+ self.modelable_entity_name = parse_modelable_entity_name(context, presentation,
+ 'get_attribute', 0, argument[0])
+ # The first of these will be tried as a req-or-cap name:
+ self.nested_attribute_name_or_index = argument[1:]
+
+ @property
+ def as_raw(self):
+ return {'get_attribute': [self.modelable_entity_name] + self.nested_attribute_name_or_index}
+
+ def __evaluate__(self, container_holder):
+ modelable_entities = get_modelable_entities(container_holder, 'get_attribute', self.locator,
+ self.modelable_entity_name)
+ for modelable_entity in modelable_entities:
+ attributes = modelable_entity.attributes
+ nested_attribute_name_or_index = self.nested_attribute_name_or_index
+ evaluation = get_modelable_entity_parameter(modelable_entity, attributes,
+ nested_attribute_name_or_index)
+ if evaluation is not None:
+ evaluation.final = False # We never return final evaluations!
+ return evaluation
+
+ raise InvalidValueError(
+ 'function "get_attribute" could not find "{0}" in modelable entity "{1}"'
+ .format('.'.join(self.nested_attribute_name_or_index), self.modelable_entity_name),
+ locator=self.locator)
+
+
+#
+# Operation
+#
+
+@implements_specification('4.6.1', 'tosca-simple-1.0') # pylint: disable=abstract-method
+class GetOperationOutput(Function):
+ """
+ The ``get_operation_output`` function is used to retrieve the values of variables exposed /
+ exported from an interface operation.
+ """
+
+ def __init__(self, context, presentation, argument):
+ self.locator = presentation._locator
+
+ if (not isinstance(argument, list)) or (len(argument) != 4):
+ raise InvalidValueError(
+ 'function "get_operation_output" argument must be a list of 4 parameters: {0}'
+ .format(safe_repr(argument)),
+ locator=self.locator)
+
+ self.modelable_entity_name = parse_string_expression(context, presentation,
+ 'get_operation_output', 0,
+ 'modelable entity name', argument[0])
+ self.interface_name = parse_string_expression(context, presentation, 'get_operation_output',
+ 1, 'the interface name', argument[1])
+ self.operation_name = parse_string_expression(context, presentation, 'get_operation_output',
+ 2, 'the operation name', argument[2])
+ self.output_variable_name = parse_string_expression(context, presentation,
+ 'get_operation_output', 3,
+ 'the output name', argument[3])
+
+ @property
+ def as_raw(self):
+ interface_name = self.interface_name
+ if hasattr(interface_name, 'as_raw'):
+ interface_name = as_raw(interface_name)
+ operation_name = self.operation_name
+ if hasattr(operation_name, 'as_raw'):
+ operation_name = as_raw(operation_name)
+ output_variable_name = self.output_variable_name
+ if hasattr(output_variable_name, 'as_raw'):
+ output_variable_name = as_raw(output_variable_name)
+ return {'get_operation_output': [self.modelable_entity_name, interface_name, operation_name,
+ output_variable_name]}
+
+
+#
+# Navigation
+#
+
+@implements_specification('4.7.1', 'tosca-simple-1.0')
+class GetNodesOfType(Function):
+ """
+ The ``get_nodes_of_type`` function can be used to retrieve a list of all known instances of
+ nodes of the declared Node Type.
+ """
+
+ def __init__(self, context, presentation, argument):
+ self.locator = presentation._locator
+
+ self.node_type_name = parse_string_expression(context, presentation, 'get_nodes_of_type',
+ None, 'the node type name', argument)
+
+ if isinstance(self.node_type_name, basestring):
+ node_types = context.presentation.get('service_template', 'node_types')
+ if (node_types is None) or (self.node_type_name not in node_types):
+ raise InvalidValueError(
+ 'function "get_nodes_of_type" argument is not a valid node type name: {0}'
+ .format(safe_repr(argument)),
+ locator=self.locator)
+
+ @property
+ def as_raw(self):
+ node_type_name = self.node_type_name
+ if hasattr(node_type_name, 'as_raw'):
+ node_type_name = as_raw(node_type_name)
+ return {'get_nodes_of_type': node_type_name}
+
+ def __evaluate__(self, container):
+ pass
+
+
+#
+# Artifact
+#
+
+@implements_specification('4.8.1', 'tosca-simple-1.0') # pylint: disable=abstract-method
+class GetArtifact(Function):
+ """
+ The ``get_artifact`` function is used to retrieve artifact location between modelable
+ entities defined in the same service template.
+ """
+
+ def __init__(self, context, presentation, argument):
+ self.locator = presentation._locator
+
+ if (not isinstance(argument, list)) or (len(argument) < 2) or (len(argument) > 4):
+ raise InvalidValueError(
+ 'function "get_artifact" argument must be a list of 2 to 4 parameters: {0}'
+ .format(safe_repr(argument)),
+ locator=self.locator)
+
+ self.modelable_entity_name = parse_string_expression(context, presentation, 'get_artifact',
+ 0, 'modelable entity name',
+ argument[0])
+ self.artifact_name = parse_string_expression(context, presentation, 'get_artifact', 1,
+ 'the artifact name', argument[1])
+ self.location = parse_string_expression(context, presentation, 'get_artifact', 2,
+ 'the location or "LOCAL_FILE"', argument[2])
+ self.remove = parse_bool(context, presentation, 'get_artifact', 3, 'the removal flag',
+ argument[3])
+
+ @property
+ def as_raw(self):
+ artifact_name = self.artifact_name
+ if hasattr(artifact_name, 'as_raw'):
+ artifact_name = as_raw(artifact_name)
+ location = self.location
+ if hasattr(location, 'as_raw'):
+ location = as_raw(location)
+ return {'get_artifacts': [self.modelable_entity_name, artifact_name, location, self.remove]}
+
+
+#
+# Utils
+#
+
+def get_function(context, presentation, value):
+ functions = context.presentation.presenter.functions
+ if isinstance(value, dict) and (len(value) == 1):
+ key = value.keys()[0]
+ if key in functions:
+ try:
+ return True, functions[key](context, presentation, value[key])
+ except InvalidValueError as e:
+ context.validation.report(issue=e.issue)
+ return True, None
+ return False, None
+
+
+def parse_string_expression(context, presentation, name, index, explanation, value): # pylint: disable=unused-argument
+ is_function, func = get_function(context, presentation, value)
+ if is_function:
+ return func
+ else:
+ value = str(value)
+ return value
+
+
+def parse_int(context, presentation, name, index, explanation, value): # pylint: disable=unused-argument
+ if not isinstance(value, int):
+ try:
+ value = int(value)
+ except ValueError:
+ raise invalid_value(name, index, 'an integer', explanation, value,
+ presentation._locator)
+ return value
+
+
+def parse_bool(context, presentation, name, index, explanation, value): # pylint: disable=unused-argument
+ if not isinstance(value, bool):
+ raise invalid_value(name, index, 'a boolean', explanation, value, presentation._locator)
+ return value
+
+
+def parse_modelable_entity_name(context, presentation, name, index, value):
+ value = parse_string_expression(context, presentation, name, index, 'the modelable entity name',
+ value)
+ if value == 'SELF':
+ the_self, _ = parse_self(presentation)
+ if the_self is None:
+ raise invalid_modelable_entity_name(name, index, value, presentation._locator,
+ 'a node template or a relationship template')
+ elif value == 'HOST':
+ _, self_variant = parse_self(presentation)
+ if self_variant != 'node_template':
+ raise invalid_modelable_entity_name(name, index, value, presentation._locator,
+ 'a node template')
+ elif (value == 'SOURCE') or (value == 'TARGET'):
+ _, self_variant = parse_self(presentation)
+ if self_variant != 'relationship_template':
+ raise invalid_modelable_entity_name(name, index, value, presentation._locator,
+ 'a relationship template')
+ elif isinstance(value, basestring):
+ node_templates = \
+ context.presentation.get('service_template', 'topology_template', 'node_templates') \
+ or {}
+ relationship_templates = \
+ context.presentation.get('service_template', 'topology_template',
+ 'relationship_templates') \
+ or {}
+ if (value not in node_templates) and (value not in relationship_templates):
+ raise InvalidValueError(
+ 'function "{0}" parameter {1:d} is not a valid modelable entity name: {2}'
+ .format(name, index + 1, safe_repr(value)),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ return value
+
+
+def parse_self(presentation):
+ from ..types import (NodeType, RelationshipType)
+ from ..templates import (
+ NodeTemplate as NodeTemplatePresentation,
+ RelationshipTemplate as RelationshipTemplatePresentation
+ )
+
+ if presentation is None:
+ return None, None
+ elif isinstance(presentation, NodeTemplatePresentation) or isinstance(presentation, NodeType):
+ return presentation, 'node_template'
+ elif isinstance(presentation, RelationshipTemplatePresentation) \
+ or isinstance(presentation, RelationshipType):
+ return presentation, 'relationship_template'
+ else:
+ return parse_self(presentation._container)
+
+
+def evaluate(value, final, container_holder):
+ """
+ Calls ``__evaluate__`` and passes on ``final`` state.
+ """
+
+ if hasattr(value, '__evaluate__'):
+ value = value.__evaluate__(container_holder)
+ if not value.final:
+ final = False
+ return value.value, final
+ else:
+ return value, final
+
+
+@implements_specification('4.1', 'tosca-simple-1.0')
+def get_modelable_entities(container_holder, name, locator, modelable_entity_name):
+ """
+ The following keywords MAY be used in some TOSCA function in place of a TOSCA Node or
+ Relationship Template name.
+ """
+
+ if modelable_entity_name == 'SELF':
+ return get_self(container_holder, name, locator)
+ elif modelable_entity_name == 'HOST':
+ return get_hosts(container_holder, name, locator)
+ elif modelable_entity_name == 'SOURCE':
+ return get_source(container_holder, name, locator)
+ elif modelable_entity_name == 'TARGET':
+ return get_target(container_holder, name, locator)
+ elif isinstance(modelable_entity_name, basestring):
+ modelable_entities = []
+
+ service = container_holder.service
+ if service is not None:
+ for node in service.nodes.itervalues():
+ if node.node_template.name == modelable_entity_name:
+ modelable_entities.append(node)
+ else:
+ service_template = container_holder.service_template
+ if service_template is not None:
+ for node_template in service_template.node_templates.itervalues():
+ if node_template.name == modelable_entity_name:
+ modelable_entities.append(node_template)
+
+ if not modelable_entities:
+ raise CannotEvaluateFunctionException()
+
+ return modelable_entities
+
+ raise InvalidValueError('function "{0}" could not find modelable entity "{1}"'
+ .format(name, modelable_entity_name),
+ locator=locator)
+
+
+def get_self(container_holder, name, locator):
+ """
+ A TOSCA orchestrator will interpret this keyword as the Node or Relationship Template instance
+ that contains the function at the time the function is evaluated.
+ """
+
+ container = container_holder.container
+ if (not isinstance(container, Node)) and \
+ (not isinstance(container, NodeTemplate)) and \
+ (not isinstance(container, Relationship)) and \
+ (not isinstance(container, RelationshipTemplate)):
+ raise InvalidValueError('function "{0}" refers to "SELF" but it is not contained in '
+ 'a node or a relationship: {1}'.format(name,
+ full_type_name(container)),
+ locator=locator)
+
+ return [container]
+
+
+def get_hosts(container_holder, name, locator):
+ """
+ A TOSCA orchestrator will interpret this keyword to refer to the all nodes that "host" the node
+ using this reference (i.e., as identified by its HostedOn relationship).
+
+ Specifically, TOSCA orchestrators that encounter this keyword when evaluating the get_attribute
+ or ``get_property`` functions SHALL search each node along the "HostedOn" relationship chain
+ starting at the immediate node that hosts the node where the function was evaluated (and then
+ that node's host node, and so forth) until a match is found or the "HostedOn" relationship chain
+ ends.
+ """
+
+ container = container_holder.container
+ if (not isinstance(container, Node)) and (not isinstance(container, NodeTemplate)):
+ raise InvalidValueError('function "{0}" refers to "HOST" but it is not contained in '
+ 'a node: {1}'.format(name, full_type_name(container)),
+ locator=locator)
+
+ if not isinstance(container, Node):
+ # NodeTemplate does not have "host"; we'll wait until instantiation
+ raise CannotEvaluateFunctionException()
+
+ host = container.host
+ if host is None:
+ # We might have a host later
+ raise CannotEvaluateFunctionException()
+
+ return [host]
+
+
+def get_source(container_holder, name, locator):
+ """
+ A TOSCA orchestrator will interpret this keyword as the Node Template instance that is at the
+ source end of the relationship that contains the referencing function.
+ """
+
+ container = container_holder.container
+ if (not isinstance(container, Relationship)) and \
+ (not isinstance(container, RelationshipTemplate)):
+ raise InvalidValueError('function "{0}" refers to "SOURCE" but it is not contained in '
+ 'a relationship: {1}'.format(name, full_type_name(container)),
+ locator=locator)
+
+ if not isinstance(container, RelationshipTemplate):
+ # RelationshipTemplate does not have "source_node"; we'll wait until instantiation
+ raise CannotEvaluateFunctionException()
+
+ return [container.source_node]
+
+
+def get_target(container_holder, name, locator):
+ """
+ A TOSCA orchestrator will interpret this keyword as the Node Template instance that is at the
+ target end of the relationship that contains the referencing function.
+ """
+
+ container = container_holder.container
+ if (not isinstance(container, Relationship)) and \
+ (not isinstance(container, RelationshipTemplate)):
+ raise InvalidValueError('function "{0}" refers to "TARGET" but it is not contained in '
+ 'a relationship: {1}'.format(name, full_type_name(container)),
+ locator=locator)
+
+ if not isinstance(container, RelationshipTemplate):
+ # RelationshipTemplate does not have "target_node"; we'll wait until instantiation
+ raise CannotEvaluateFunctionException()
+
+ return [container.target_node]
+
+
+def get_modelable_entity_parameter(modelable_entity, parameters, nested_parameter_name_or_index):
+ if not parameters:
+ return Evaluation(None, True)
+
+ found = True
+ final = True
+ value = parameters
+
+ for name_or_index in nested_parameter_name_or_index:
+ if (isinstance(value, dict) and (name_or_index in value)) \
+ or ((isinstance(value, list) and (name_or_index < len(value)))):
+ value = value[name_or_index] # Parameter
+ # We are not using Parameter.value, but rather Parameter._value, because we want to make
+ # sure to get "final" (it is swallowed by Parameter.value)
+ value, final = evaluate(value._value, final, value)
+ else:
+ found = False
+ break
+
+ return Evaluation(value, final) if found else None
+
+
+def invalid_modelable_entity_name(name, index, value, locator, contexts):
+ return InvalidValueError('function "{0}" parameter {1:d} can be "{2}" only in {3}'
+ .format(name, index + 1, value, contexts),
+ locator=locator, level=Issue.FIELD)
+
+
+def invalid_value(name, index, the_type, explanation, value, locator):
+ return InvalidValueError(
+ 'function "{0}" {1} is not {2}{3}: {4}'
+ .format(name,
+ 'parameter {0:d}'.format(index + 1) if index is not None else 'argument',
+ the_type,
+ ', {0}'.format(explanation) if explanation is not None else '',
+ safe_repr(value)),
+ locator=locator, level=Issue.FIELD)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
new file mode 100644
index 0000000..23a03b7
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
@@ -0,0 +1,530 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import (merge, deepcopy_with_locators, OrderedDict)
+from aria.parser.presentation import get_locator
+from aria.parser.validation import Issue
+
+from .parameters import (coerce_parameter_value, convert_parameter_definitions_to_values)
+
+
+#
+# InterfaceType
+#
+
+def get_inherited_operations(context, presentation):
+ """
+ Returns our operation definitions added on top of those of our parent, if we have one
+ (recursively).
+
+ Allows overriding all aspects of parent operations except input data types.
+ """
+
+ # Get operations from parent
+ parent = presentation._get_parent(context)
+ operations = get_inherited_operations(context, parent) if parent is not None else OrderedDict()
+
+ # Add/merge our operations
+ our_operations = presentation.operations # OperationDefinition
+ merge_operation_definitions(context, operations, our_operations, presentation._name,
+ presentation, 'type')
+
+ for operation in operations.itervalues():
+ operation._reset_method_cache()
+
+ return operations
+
+
+#
+# InterfaceDefinition
+#
+
+def get_and_override_input_definitions_from_type(context, presentation):
+ """
+ Returns our input definitions added on top of those of the interface type, if specified.
+
+ Allows overriding all aspects of parent interface type inputs except data types.
+ """
+
+ inputs = OrderedDict()
+
+ # Get inputs from type
+ the_type = presentation._get_type(context) # InterfaceType
+ type_inputs = the_type._get_inputs(context) if the_type is not None else None
+ if type_inputs:
+ for input_name, type_input in type_inputs.iteritems():
+ inputs[input_name] = type_input._clone(presentation)
+
+ # Add/merge our inputs
+ our_inputs = presentation.inputs # PropertyDefinition
+ if our_inputs:
+ merge_input_definitions(context, inputs, our_inputs, presentation._name, None, presentation,
+ 'definition')
+
+ return inputs
+
+
+def get_and_override_operation_definitions_from_type(context, presentation):
+ """
+ Returns our operation definitions added on top of those of the interface type, if specified.
+
+ Allows overriding all aspects of parent interface type inputs except data types.
+ """
+
+ operations = OrderedDict()
+
+ # Get operations from type
+ the_type = presentation._get_type(context) # InterfaceType
+ type_operations = the_type._get_operations(context) if the_type is not None else None
+ if type_operations:
+ for operations_name, type_operation in type_operations.iteritems():
+ operations[operations_name] = type_operation._clone(presentation)
+
+ # Add/merge our operations
+ our_operations = presentation.operations # OperationDefinition
+ merge_operation_definitions(context, operations, our_operations, presentation._name,
+ presentation, 'definition')
+
+ return operations
+
+
+#
+# NodeType, RelationshipType, GroupType
+#
+
+def get_inherited_interface_definitions(context, presentation, type_name, for_presentation=None):
+ """
+ Returns our interface definitions added on top of those of our parent, if we have one
+ (recursively).
+
+ Allows overriding all aspects of parent interfaces except interface and operation input data
+ types.
+ """
+
+ if for_presentation is None:
+ for_presentation = presentation
+
+ # Get interfaces from parent
+ parent = presentation._get_parent(context)
+ interfaces = get_inherited_interface_definitions(context, parent, type_name, for_presentation) \
+ if parent is not None else OrderedDict()
+
+ # Add/merge interfaces from their types
+ merge_interface_definitions_from_their_types(context, interfaces, presentation)
+
+ # Add/merge our interfaces
+ our_interfaces = presentation.interfaces
+ merge_interface_definitions(context, interfaces, our_interfaces, presentation, for_presentation)
+
+ return interfaces
+
+
+#
+# NodeTemplate, RelationshipTemplate, GroupTemplate
+#
+
+def get_template_interfaces(context, presentation, type_name):
+ """
+ Returns the assigned interface_template values while making sure they are defined in the type.
+ This includes the interfaces themselves, their operations, and inputs for interfaces and
+ operations.
+
+ Interface and operation inputs' default values, if available, will be used if we did not assign
+ them.
+
+ Makes sure that required inputs indeed end up with a value.
+
+ This code is especially complex due to the many levels of nesting involved.
+ """
+
+ template_interfaces = OrderedDict()
+
+ the_type = presentation._get_type(context) # NodeType, RelationshipType, GroupType
+ # InterfaceDefinition (or InterfaceAssignment in the case of RelationshipTemplate):
+ interface_definitions = the_type._get_interfaces(context) if the_type is not None else None
+
+ # Copy over interfaces from the type (will initialize inputs with default values)
+ if interface_definitions is not None:
+ for interface_name, interface_definition in interface_definitions.iteritems():
+ # Note that in the case of a RelationshipTemplate, we will already have the values as
+ # InterfaceAssignment. It will not be converted, just cloned.
+ template_interfaces[interface_name] = \
+ convert_interface_definition_from_type_to_template(context, interface_definition,
+ presentation)
+
+ # Fill in our interfaces
+ our_interface_assignments = presentation.interfaces
+ if our_interface_assignments:
+ # InterfaceAssignment:
+ for interface_name, our_interface_assignment in our_interface_assignments.iteritems():
+ if interface_name in template_interfaces:
+ interface_assignment = template_interfaces[interface_name] # InterfaceAssignment
+ # InterfaceDefinition (or InterfaceAssignment in the case of RelationshipTemplate):
+ interface_definition = interface_definitions[interface_name]
+ merge_interface(context, presentation, interface_assignment,
+ our_interface_assignment, interface_definition, interface_name)
+ else:
+ context.validation.report(
+ 'interface definition "%s" not declared at %s "%s" in "%s"'
+ % (interface_name, type_name, presentation.type, presentation._fullname),
+ locator=our_interface_assignment._locator, level=Issue.BETWEEN_TYPES)
+
+ # Check that there are no required inputs that we haven't assigned
+ for interface_name, interface_template in template_interfaces.iteritems():
+ if interface_name in interface_definitions:
+ # InterfaceDefinition (or InterfaceAssignment in the case of RelationshipTemplate):
+ interface_definition = interface_definitions[interface_name]
+ our_interface_assignment = our_interface_assignments.get(interface_name) \
+ if our_interface_assignments is not None else None
+ validate_required_inputs(context, presentation, interface_template,
+ interface_definition, our_interface_assignment, interface_name)
+
+ return template_interfaces
+
+
+#
+# Utils
+#
+
+def convert_interface_definition_from_type_to_template(context, presentation, container):
+ from ..assignments import InterfaceAssignment
+
+ if isinstance(presentation, InterfaceAssignment):
+ # Nothing to convert, so just clone
+ return presentation._clone(container)
+
+ raw = convert_interface_definition_from_type_to_raw_template(context, presentation)
+ return InterfaceAssignment(name=presentation._name, raw=raw, container=container)
+
+
+def convert_interface_definition_from_type_to_raw_template(context, presentation): # pylint: disable=invalid-name
+ raw = OrderedDict()
+
+ # Copy default values for inputs
+ interface_inputs = presentation._get_inputs(context)
+ if interface_inputs is not None:
+ raw['inputs'] = convert_parameter_definitions_to_values(context, interface_inputs)
+
+ # Copy operations
+ operations = presentation._get_operations(context)
+ if operations:
+ for operation_name, operation in operations.iteritems():
+ raw[operation_name] = OrderedDict()
+ description = operation.description
+ if description is not None:
+ raw[operation_name]['description'] = deepcopy_with_locators(description._raw)
+ implementation = operation.implementation
+ if implementation is not None:
+ raw[operation_name]['implementation'] = deepcopy_with_locators(implementation._raw)
+ inputs = operation.inputs
+ if inputs is not None:
+ raw[operation_name]['inputs'] = convert_parameter_definitions_to_values(context,
+ inputs)
+
+ return raw
+
+
+def convert_requirement_interface_definitions_from_type_to_raw_template(context, raw_requirement, # pylint: disable=invalid-name
+ interface_definitions):
+ if not interface_definitions:
+ return
+ if 'interfaces' not in raw_requirement:
+ raw_requirement['interfaces'] = OrderedDict()
+ for interface_name, interface_definition in interface_definitions.iteritems():
+ raw_interface = convert_interface_definition_from_type_to_raw_template(context,
+ interface_definition)
+ if interface_name in raw_requirement['interfaces']:
+ merge(raw_requirement['interfaces'][interface_name], raw_interface)
+ else:
+ raw_requirement['interfaces'][interface_name] = raw_interface
+
+
+def merge_interface(context, presentation, interface_assignment, our_interface_assignment,
+ interface_definition, interface_name):
+ # Assign/merge interface inputs
+ assign_raw_inputs(context, interface_assignment._raw, our_interface_assignment.inputs,
+ interface_definition._get_inputs(context), interface_name, None, presentation)
+
+ # Assign operation implementations and inputs
+ our_operation_templates = our_interface_assignment.operations # OperationAssignment
+ # OperationDefinition or OperationAssignment:
+ operation_definitions = interface_definition._get_operations(context) \
+ if hasattr(interface_definition, '_get_operations') else interface_definition.operations
+ if our_operation_templates:
+ # OperationAssignment:
+ for operation_name, our_operation_template in our_operation_templates.iteritems():
+ operation_definition = operation_definitions.get(operation_name) # OperationDefinition
+
+ our_input_assignments = our_operation_template.inputs
+ our_implementation = our_operation_template.implementation
+
+ if operation_definition is None:
+ context.validation.report(
+ 'interface definition "%s" refers to an unknown operation "%s" in "%s"'
+ % (interface_name, operation_name, presentation._fullname),
+ locator=our_operation_template._locator, level=Issue.BETWEEN_TYPES)
+
+ if (our_input_assignments is not None) or (our_implementation is not None):
+ # Make sure we have the dict
+ if (operation_name not in interface_assignment._raw) \
+ or (interface_assignment._raw[operation_name] is None):
+ interface_assignment._raw[operation_name] = OrderedDict()
+
+ if our_implementation is not None:
+ interface_assignment._raw[operation_name]['implementation'] = \
+ deepcopy_with_locators(our_implementation._raw)
+
+ # Assign/merge operation inputs
+ input_definitions = operation_definition.inputs \
+ if operation_definition is not None else None
+ assign_raw_inputs(context, interface_assignment._raw[operation_name],
+ our_input_assignments, input_definitions, interface_name,
+ operation_name, presentation)
+
+
+def merge_raw_input_definition(context, the_raw_input, our_input, interface_name, operation_name,
+ presentation, type_name):
+ # Check if we changed the type
+ # TODO: allow a sub-type?
+ input_type1 = the_raw_input.get('type')
+ input_type2 = our_input.type
+ if input_type1 != input_type2:
+ if operation_name is not None:
+ context.validation.report(
+ 'interface %s "%s" changes operation input "%s.%s" type from "%s" to "%s" in "%s"'
+ % (type_name, interface_name, operation_name, our_input._name, input_type1,
+ input_type2, presentation._fullname),
+ locator=input_type2._locator, level=Issue.BETWEEN_TYPES)
+ else:
+ context.validation.report(
+ 'interface %s "%s" changes input "%s" type from "%s" to "%s" in "%s"'
+ % (type_name, interface_name, our_input._name, input_type1, input_type2,
+ presentation._fullname),
+ locator=input_type2._locator, level=Issue.BETWEEN_TYPES)
+
+ # Merge
+ merge(the_raw_input, our_input._raw)
+
+
+def merge_input_definitions(context, inputs, our_inputs, interface_name, operation_name,
+ presentation, type_name):
+ for input_name, our_input in our_inputs.iteritems():
+ if input_name in inputs:
+ merge_raw_input_definition(context, inputs[input_name]._raw, our_input, interface_name,
+ operation_name, presentation, type_name)
+ else:
+ inputs[input_name] = our_input._clone(presentation)
+
+
+def merge_raw_input_definitions(context, raw_inputs, our_inputs, interface_name, operation_name,
+ presentation, type_name):
+ for input_name, our_input in our_inputs.iteritems():
+ if input_name in raw_inputs:
+ merge_raw_input_definition(context, raw_inputs[input_name], our_input, interface_name,
+ operation_name, presentation, type_name)
+ else:
+ raw_inputs[input_name] = deepcopy_with_locators(our_input._raw)
+
+
+def merge_raw_operation_definition(context, raw_operation, our_operation, interface_name,
+ presentation, type_name):
+ if not isinstance(our_operation._raw, dict):
+ # Convert short form to long form
+ raw_operation['implementation'] = deepcopy_with_locators(our_operation._raw)
+ return
+
+ # Add/merge inputs
+ our_operation_inputs = our_operation.inputs
+ if our_operation_inputs:
+ # Make sure we have the dict
+ if ('inputs' not in raw_operation) or (raw_operation.get('inputs') is None):
+ raw_operation['inputs'] = OrderedDict()
+
+ merge_raw_input_definitions(context, raw_operation['inputs'], our_operation_inputs,
+ interface_name, our_operation._name, presentation, type_name)
+
+ # Override the description
+ if our_operation._raw.get('description') is not None:
+ raw_operation['description'] = deepcopy_with_locators(our_operation._raw['description'])
+
+ # Add/merge implementation
+ if our_operation._raw.get('implementation') is not None:
+ if raw_operation.get('implementation') is not None:
+ merge(raw_operation['implementation'],
+ deepcopy_with_locators(our_operation._raw['implementation']))
+ else:
+ raw_operation['implementation'] = \
+ deepcopy_with_locators(our_operation._raw['implementation'])
+
+
+def merge_operation_definitions(context, operations, our_operations, interface_name, presentation,
+ type_name):
+ if not our_operations:
+ return
+ for operation_name, our_operation in our_operations.iteritems():
+ if operation_name in operations:
+ merge_raw_operation_definition(context, operations[operation_name]._raw, our_operation,
+ interface_name, presentation, type_name)
+ else:
+ operations[operation_name] = our_operation._clone(presentation)
+
+
+def merge_raw_operation_definitions(context, raw_operations, our_operations, interface_name,
+ presentation, type_name):
+ for operation_name, our_operation in our_operations.iteritems():
+ if operation_name in raw_operations:
+ raw_operation = raw_operations[operation_name]
+ if isinstance(raw_operation, basestring):
+ # Convert short form to long form
+ raw_operations[operation_name] = OrderedDict((('implementation', raw_operation),))
+ raw_operation = raw_operations[operation_name]
+ merge_raw_operation_definition(context, raw_operation, our_operation, interface_name,
+ presentation, type_name)
+ else:
+ raw_operations[operation_name] = deepcopy_with_locators(our_operation._raw)
+
+
+# From either an InterfaceType or an InterfaceDefinition:
+def merge_interface_definition(context, interface, our_source, presentation, type_name):
+ if hasattr(our_source, 'type'):
+ # Check if we changed the interface type
+ type1 = interface._get_type(context)
+ type2 = our_source._get_type(context)
+
+ if (type2 is not None) and not type1._is_descendant(context, type2):
+ context.validation.report(
+ 'interface definition type "{0}" is not a descendant of overridden '
+ 'interface definition type "{1}"' \
+ .format(type1._name, type2._name),
+ locator=our_source._locator, level=Issue.BETWEEN_TYPES)
+
+ # Add/merge inputs
+ our_interface_inputs = our_source._get_inputs(context) \
+ if hasattr(our_source, '_get_inputs') else our_source.inputs
+ if our_interface_inputs:
+ # Make sure we have the dict
+ if ('inputs' not in interface._raw) or (interface._raw.get('inputs') is None):
+ interface._raw['inputs'] = OrderedDict()
+
+ merge_raw_input_definitions(context, interface._raw['inputs'], our_interface_inputs,
+ our_source._name, None, presentation, type_name)
+
+ # Add/merge operations
+ our_operations = our_source._get_operations(context) \
+ if hasattr(our_source, '_get_operations') else our_source.operations
+ if our_operations is not None:
+ merge_raw_operation_definitions(context, interface._raw, our_operations, our_source._name,
+ presentation, type_name)
+
+
+def merge_interface_definitions(context, interfaces, our_interfaces, presentation,
+ for_presentation=None):
+ if not our_interfaces:
+ return
+ for name, our_interface in our_interfaces.iteritems():
+ if name in interfaces:
+ merge_interface_definition(context, interfaces[name], our_interface, presentation,
+ 'definition')
+ else:
+ interfaces[name] = our_interface._clone(for_presentation)
+
+
+def merge_interface_definitions_from_their_types(context, interfaces, presentation):
+ for interface in interfaces.itervalues():
+ the_type = interface._get_type(context) # InterfaceType
+ if the_type is not None:
+ merge_interface_definition(context, interface, the_type, presentation, 'type')
+
+
+def assign_raw_inputs(context, values, assignments, definitions, interface_name, operation_name,
+ presentation):
+ if not assignments:
+ return
+
+ # Make sure we have the dict
+ if ('inputs' not in values) or (values['inputs'] is None):
+ values['inputs'] = OrderedDict()
+
+ # Assign inputs
+ for input_name, assignment in assignments.iteritems():
+ if (definitions is not None) and (input_name not in definitions):
+ if operation_name is not None:
+ context.validation.report(
+ 'interface definition "%s" assigns a value to an unknown operation input'
+ ' "%s.%s" in "%s"'
+ % (interface_name, operation_name, input_name, presentation._fullname),
+ locator=assignment._locator, level=Issue.BETWEEN_TYPES)
+ else:
+ context.validation.report(
+ 'interface definition "%s" assigns a value to an unknown input "%s" in "%s"'
+ % (interface_name, input_name, presentation._fullname),
+ locator=assignment._locator, level=Issue.BETWEEN_TYPES)
+
+ definition = definitions.get(input_name) if definitions is not None else None
+
+ # Note: default value has already been assigned
+
+ # Coerce value
+ values['inputs'][input_name] = coerce_parameter_value(context, assignment, definition,
+ assignment.value)
+
+
+def validate_required_inputs(context, presentation, assignment, definition, original_assignment,
+ interface_name, operation_name=None):
+ # The validation of the `required` field of inputs that belong to operations and interfaces
+ # (as opposed to topology template and workflow inputs) is done only in the parsing stage.
+ # This reasoning follows the TOSCA spirit, where anything that is declared as required in the
+ # type, must be assigned in the corresponding template.
+ input_definitions = definition.inputs
+ if input_definitions:
+ for input_name, input_definition in input_definitions.iteritems():
+ if input_definition.required:
+ prop = assignment.inputs.get(input_name) \
+ if ((assignment is not None) and (assignment.inputs is not None)) else None
+ value = prop.value if prop is not None else None
+ value = value.value if value is not None else None
+ if value is None:
+ if operation_name is not None:
+ context.validation.report(
+ 'interface definition "%s" does not assign a value to a required'
+ ' operation input "%s.%s" in "%s"'
+ % (interface_name, operation_name, input_name, presentation._fullname),
+ locator=get_locator(original_assignment, presentation._locator),
+ level=Issue.BETWEEN_TYPES)
+ else:
+ context.validation.report(
+ 'interface definition "%s" does not assign a value to a required input'
+ ' "%s" in "%s"'
+ % (interface_name, input_name, presentation._fullname),
+ locator=get_locator(original_assignment, presentation._locator),
+ level=Issue.BETWEEN_TYPES)
+
+ if operation_name is not None:
+ return
+
+ assignment_operations = assignment.operations
+ operation_definitions = definition._get_operations(context)
+ if operation_definitions:
+ for operation_name, operation_definition in operation_definitions.iteritems():
+ assignment_operation = assignment_operations.get(operation_name) \
+ if assignment_operations is not None else None
+ original_operation = \
+ original_assignment.operations.get(operation_name, original_assignment) \
+ if (original_assignment is not None) \
+ and (original_assignment.operations is not None) \
+ else original_assignment
+ validate_required_inputs(context, presentation, assignment_operation,
+ operation_definition, original_operation, interface_name,
+ operation_name)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
new file mode 100644
index 0000000..9bafeec
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
@@ -0,0 +1,230 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import (merge, deepcopy_with_locators, OrderedDict)
+from aria.utils.formatting import pluralize
+from aria.parser.presentation import Value
+from aria.parser.validation import Issue
+
+from .data_types import (coerce_value, get_primitive_data_type)
+from ..presentation.types import get_type_by_name
+
+
+#
+# ArtifactType, DataType, CapabilityType, RelationshipType, NodeType, GroupType, PolicyType
+#
+
+def get_inherited_parameter_definitions(context, presentation, field_name, for_presentation=None):
+ """
+ Returns our parameter definitions added on top of those of our parent, if we have one
+ (recursively).
+
+ Allows overriding all aspects of parent properties except data type.
+ """
+
+ if for_presentation is None:
+ for_presentation = presentation
+
+ # Get definitions from parent
+ # If we inherit from a primitive, it does not have a parent:
+ parent = presentation._get_parent(context) if hasattr(presentation, '_get_parent') else None
+ definitions = get_inherited_parameter_definitions(context, parent, field_name,
+ for_presentation) \
+ if parent is not None else OrderedDict()
+
+ # Add/merge our definitions
+ # If we inherit from a primitive, it does not have our field
+ our_definitions = getattr(presentation, field_name, None)
+ if our_definitions:
+ our_definitions_clone = OrderedDict()
+ for name, our_definition in our_definitions.iteritems():
+ our_definitions_clone[name] = our_definition._clone(for_presentation)
+ our_definitions = our_definitions_clone
+ merge_parameter_definitions(context, presentation, definitions, our_definitions, field_name)
+
+ for definition in definitions.itervalues():
+ definition._reset_method_cache()
+
+ return definitions
+
+
+#
+# NodeTemplate, RelationshipTemplate, GroupTemplate, PolicyTemplate
+#
+
+def get_assigned_and_defined_parameter_values(context, presentation, field_name):
+ """
+ Returns the assigned parameter values while making sure they are defined in our type.
+
+ The parameter definition's default value, if available, will be used if we did not assign it.
+
+ Makes sure that required parameters indeed end up with a value.
+ """
+
+ values = OrderedDict()
+
+ the_type = presentation._get_type(context)
+ field_name_plural = pluralize(field_name)
+ assignments = getattr(presentation, field_name_plural)
+ get_fn_name = '_get_{0}'.format(field_name_plural)
+ definitions = getattr(the_type, get_fn_name)(context) if the_type is not None else None
+
+ # Fill in our assignments, but make sure they are defined
+ if assignments:
+ for name, value in assignments.iteritems():
+ if (definitions is not None) and (name in definitions):
+ definition = definitions[name]
+ values[name] = coerce_parameter_value(context, value, definition, value.value)
+ else:
+ context.validation.report('assignment to undefined {0} "{1}" in "{2}"'
+ .format(field_name, name, presentation._fullname),
+ locator=value._locator, level=Issue.BETWEEN_TYPES)
+
+ # Fill in defaults from the definitions
+ if definitions:
+ for name, definition in definitions.iteritems():
+ # Note: attributes will always have a default value, even if it's None
+ if (name not in values) and \
+ (('default' in definition._raw) or (field_name == 'attribute')):
+ values[name] = coerce_parameter_value(context, presentation, definition,
+ definition.default)
+
+ validate_required_values(context, presentation, values, definitions)
+
+ # Fill in nulls for missing values that are *not* required
+ if definitions:
+ for name, definition in definitions.iteritems():
+ if (name not in values) and not getattr(definition, 'required', False):
+ values[name] = coerce_parameter_value(context, presentation, definition, None)
+
+ return values
+
+
+#
+# TopologyTemplate
+#
+
+def get_parameter_values(context, presentation, field_name):
+ values = OrderedDict()
+
+ parameters = getattr(presentation, field_name)
+
+ # Fill in defaults and values
+ if parameters:
+ for name, parameter in parameters.iteritems():
+ if values.get(name) is None:
+ if hasattr(parameter, 'value') and (parameter.value is not None):
+ # For parameters only:
+ values[name] = coerce_parameter_value(context, presentation, parameter,
+ parameter.value)
+ else:
+ default = parameter.default if hasattr(parameter, 'default') else None
+ values[name] = coerce_parameter_value(context, presentation, parameter, default)
+
+ return values
+
+
+#
+# Utils
+#
+
+def validate_required_values(context, presentation, values, definitions):
+ """
+ Check if required properties have not been assigned.
+ """
+
+ if not definitions:
+ return
+ for name, definition in definitions.iteritems():
+ if getattr(definition, 'required', False) and \
+ ((values is None) or (values.get(name) is None)):
+ context.validation.report('required property "%s" is not assigned a value in "%s"'
+ % (name, presentation._fullname),
+ locator=presentation._get_child_locator('properties'),
+ level=Issue.BETWEEN_TYPES)
+
+
+def merge_raw_parameter_definition(context, presentation, raw_property_definition,
+ our_property_definition, field_name, property_name):
+ # Check if we changed the parameter type
+ type1_name = raw_property_definition.get('type')
+ type1 = get_type_by_name(context, type1_name, 'data_types')
+ if type1 is None:
+ type1 = get_primitive_data_type(type1_name)
+ our_property_definition._reset_method_cache()
+ type2 = our_property_definition._get_type(context)
+
+ if type1 != type2:
+ if not hasattr(type1, '_is_descendant') or not type1._is_descendant(context, type2):
+ context.validation.report(
+ 'property definition type "{0}" is not a descendant of overridden '
+ 'property definition type "{1}"' \
+ .format(type1_name, type2._name),
+ locator=presentation._get_child_locator(field_name, property_name),
+ level=Issue.BETWEEN_TYPES)
+
+ merge(raw_property_definition, our_property_definition._raw)
+
+
+def merge_raw_parameter_definitions(context, presentation, raw_property_definitions,
+ our_property_definitions, field_name):
+ if not our_property_definitions:
+ return
+ for property_name, our_property_definition in our_property_definitions.iteritems():
+ if property_name in raw_property_definitions:
+ raw_property_definition = raw_property_definitions[property_name]
+ merge_raw_parameter_definition(context, presentation, raw_property_definition,
+ our_property_definition, field_name, property_name)
+ else:
+ raw_property_definitions[property_name] = \
+ deepcopy_with_locators(our_property_definition._raw)
+
+
+def merge_parameter_definitions(context, presentation, property_definitions,
+ our_property_definitions, field_name):
+ if not our_property_definitions:
+ return
+ for property_name, our_property_definition in our_property_definitions.iteritems():
+ if property_name in property_definitions:
+ property_definition = property_definitions[property_name]
+ merge_raw_parameter_definition(context, presentation, property_definition._raw,
+ our_property_definition, field_name, property_name)
+ else:
+ property_definitions[property_name] = our_property_definition
+
+
+# Works on properties, inputs, and parameters
+def coerce_parameter_value(context, presentation, definition, value, aspect=None):
+ the_type = definition._get_type(context) if definition is not None else None
+ entry_schema = definition.entry_schema if definition is not None else None
+ constraints = definition._get_constraints(context) \
+ if ((definition is not None) and hasattr(definition, '_get_constraints')) else None
+ value = coerce_value(context, presentation, the_type, entry_schema, constraints, value, aspect)
+ if (the_type is not None) and hasattr(the_type, '_name'):
+ type_name = the_type._name
+ else:
+ type_name = getattr(definition, 'type', None)
+ description = getattr(definition, 'description', None)
+ description = description.value if description is not None else None
+ required = getattr(definition, 'required', None)
+ return Value(type_name, value, description, required)
+
+
+def convert_parameter_definitions_to_values(context, definitions):
+ values = OrderedDict()
+ for name, definition in definitions.iteritems():
+ default = definition.default
+ values[name] = coerce_parameter_value(context, definition, definition, default)
+ return values
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py
new file mode 100644
index 0000000..0376798
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py
@@ -0,0 +1,79 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 ..presentation.types import convert_name_to_full_type_name
+
+
+#
+# PolicyType
+#
+
+def get_inherited_targets(context, presentation):
+ """
+ Returns our target node types and group types if we have them or those of our parent, if we have
+ one (recursively).
+ """
+
+ parent = presentation._get_parent(context)
+
+ node_types, group_types = get_inherited_targets(context, parent) \
+ if parent is not None else ([], [])
+
+ our_targets = presentation.targets
+ if our_targets:
+ all_node_types = context.presentation.get('service_template', 'node_types') or {}
+ all_group_types = context.presentation.get('service_template', 'group_types') or {}
+ node_types = []
+ group_types = []
+
+ for our_target in our_targets:
+ if our_target in all_node_types:
+ our_target = convert_name_to_full_type_name(context, our_target, all_node_types)
+ node_types.append(all_node_types[our_target])
+ elif our_target in all_group_types:
+ our_target = convert_name_to_full_type_name(context, our_target, all_group_types)
+ group_types.append(all_group_types[our_target])
+
+ return node_types, group_types
+
+
+#
+# PolicyTemplate
+#
+
+def get_policy_targets(context, presentation):
+ """
+ Returns our target node templates and groups if we have them.
+ """
+
+ node_templates = []
+ groups = []
+
+ our_targets = presentation.targets
+ if our_targets:
+ all_node_templates = \
+ context.presentation.get('service_template', 'topology_template', 'node_templates') \
+ or {}
+ all_groups = \
+ context.presentation.get('service_template', 'topology_template', 'groups') \
+ or {}
+
+ for our_target in our_targets:
+ if our_target in all_node_templates:
+ node_templates.append(all_node_templates[our_target])
+ elif our_target in all_groups:
+ groups.append(all_groups[our_target])
+
+ return node_templates, groups
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py
new file mode 100644
index 0000000..6bdb5b1
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py
@@ -0,0 +1,364 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.parser.validation import Issue
+from aria.utils.collections import (deepcopy_with_locators, OrderedDict)
+
+from .parameters import (convert_parameter_definitions_to_values, validate_required_values,
+ coerce_parameter_value)
+from .interfaces import (convert_requirement_interface_definitions_from_type_to_raw_template,
+ merge_interface_definitions, merge_interface, validate_required_inputs)
+
+
+#
+# NodeType
+#
+
+def get_inherited_requirement_definitions(context, presentation):
+ """
+ Returns our requirement definitions added on top of those of our parent, if we have one
+ (recursively).
+
+ Allows overriding requirement definitions if they have the same name.
+ """
+
+ parent = presentation._get_parent(context)
+ requirement_definitions = get_inherited_requirement_definitions(context, parent) \
+ if parent is not None else []
+
+ our_requirement_definitions = presentation.requirements
+ if our_requirement_definitions:
+ for requirement_name, our_requirement_definition in our_requirement_definitions:
+ # Remove existing requirement definitions of this name if they exist
+ for name, requirement_definition in requirement_definitions:
+ if name == requirement_name:
+ requirement_definitions.remove((name, requirement_definition))
+
+ requirement_definitions.append((requirement_name, our_requirement_definition))
+
+ return requirement_definitions
+
+
+#
+# NodeTemplate
+#
+
+def get_template_requirements(context, presentation):
+ """
+ Returns our requirements added on top of those of the node type if they exist there.
+
+ If the requirement has a relationship, the relationship properties and interfaces are assigned.
+
+ Returns the assigned property, interface input, and interface operation input values while
+ making sure they are defined in our type. Default values, if available, will be used if we did
+ not assign them. Also makes sure that required properties and inputs indeed end up with a value.
+ """
+
+ requirement_assignments = []
+
+ the_type = presentation._get_type(context) # NodeType
+ requirement_definitions = the_type._get_requirements(context) if the_type is not None else None
+
+ # Add our requirement assignments
+ our_requirement_assignments = presentation.requirements
+ if our_requirement_assignments:
+ add_requirement_assignments(context, presentation, requirement_assignments,
+ requirement_definitions, our_requirement_assignments)
+
+ # Validate occurrences
+ if requirement_definitions:
+ for requirement_name, requirement_definition in requirement_definitions:
+ # Allowed occurrences
+ allowed_occurrences = requirement_definition.occurrences
+ allowed_occurrences = allowed_occurrences if allowed_occurrences is not None else None
+
+ # Count actual occurrences
+ actual_occurrences = 0
+ for name, _ in requirement_assignments:
+ if name == requirement_name:
+ actual_occurrences += 1
+
+ if allowed_occurrences is None:
+ # If not specified, we interpret this to mean that exactly 1 occurrence is required
+ if actual_occurrences == 0:
+ # If it's not there, we will automatically add it (this behavior is not in the
+ # TOSCA spec, but seems implied)
+ requirement_assignment, \
+ relationship_property_definitions, \
+ relationship_interface_definitions = \
+ convert_requirement_from_definition_to_assignment(context,
+ requirement_definition,
+ None, presentation)
+ validate_requirement_assignment(context, presentation, requirement_assignment,
+ relationship_property_definitions,
+ relationship_interface_definitions)
+ requirement_assignments.append((requirement_name, requirement_assignment))
+ elif actual_occurrences > 1:
+ context.validation.report(
+ 'requirement "%s" is allowed only one occurrence in "%s": %d'
+ % (requirement_name, presentation._fullname, actual_occurrences),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ else:
+ if not allowed_occurrences.is_in(actual_occurrences):
+ if allowed_occurrences.value[1] == 'UNBOUNDED':
+ context.validation.report(
+ 'requirement "%s" does not have at least %d occurrences in "%s": has %d'
+ % (requirement_name, allowed_occurrences.value[0],
+ presentation._fullname, actual_occurrences),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ else:
+ context.validation.report(
+ 'requirement "%s" is allowed between %d and %d occurrences in "%s":'
+ ' has %d'
+ % (requirement_name, allowed_occurrences.value[0],
+ allowed_occurrences.value[1], presentation._fullname,
+ actual_occurrences),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+
+ return requirement_assignments
+
+
+#
+# Utils
+#
+
+def convert_requirement_from_definition_to_assignment(context, requirement_definition, # pylint: disable=too-many-branches
+ our_requirement_assignment, container):
+ from ..assignments import RequirementAssignment
+
+ raw = OrderedDict()
+
+ # Capability type name:
+ raw['capability'] = deepcopy_with_locators(requirement_definition.capability)
+
+ node_type = requirement_definition._get_node_type(context)
+ if node_type is not None:
+ raw['node'] = deepcopy_with_locators(node_type._name)
+
+ relationship_type = None
+ relationship_template = None
+ relationship_property_definitions = None
+ relationship_interface_definitions = None
+
+ # First try to find the relationship if we declared it
+ # RelationshipAssignment:
+ our_relationship = our_requirement_assignment.relationship \
+ if our_requirement_assignment is not None else None
+ if our_relationship is not None:
+ relationship_type, relationship_type_variant = our_relationship._get_type(context)
+ if relationship_type_variant == 'relationship_template':
+ relationship_template = relationship_type
+ relationship_type = relationship_template._get_type(context)
+
+ definition_relationship_type = None
+ relationship_definition = requirement_definition.relationship # RelationshipDefinition
+ if relationship_definition is not None:
+ definition_relationship_type = relationship_definition._get_type(context)
+
+ # If not exists, try at the node type
+ if relationship_type is None:
+ relationship_type = definition_relationship_type
+ else:
+ # Make sure the type is derived
+ if not definition_relationship_type._is_descendant(context, relationship_type):
+ context.validation.report(
+ 'assigned relationship type "%s" is not a descendant of declared relationship type'
+ ' "%s"' \
+ % (relationship_type._name, definition_relationship_type._name),
+ locator=container._locator, level=Issue.BETWEEN_TYPES)
+
+ if relationship_type is not None:
+ raw['relationship'] = OrderedDict()
+
+ type_name = our_relationship.type if our_relationship is not None else None
+ if type_name is None:
+ type_name = relationship_type._name
+
+ raw['relationship']['type'] = deepcopy_with_locators(type_name)
+
+ # These are our property definitions
+ relationship_property_definitions = relationship_type._get_properties(context)
+
+ if relationship_template is not None:
+ # Property values from template
+ raw['relationship']['properties'] = relationship_template._get_property_values(context)
+ else:
+ if relationship_property_definitions:
+ # Convert property definitions to values
+ raw['relationship']['properties'] = \
+ convert_parameter_definitions_to_values(context,
+ relationship_property_definitions)
+
+ # These are our interface definitions
+ # InterfaceDefinition:
+ relationship_interface_definitions = OrderedDict(relationship_type._get_interfaces(context))
+
+ # Convert interface definitions to templates
+ convert_requirement_interface_definitions_from_type_to_raw_template(
+ context,
+ raw['relationship'],
+ relationship_interface_definitions)
+
+ if relationship_definition:
+ # Merge extra interface definitions
+ # InterfaceDefinition:
+ definition_interface_definitions = relationship_definition.interfaces
+ merge_interface_definitions(context, relationship_interface_definitions,
+ definition_interface_definitions, requirement_definition,
+ container)
+
+ if relationship_template is not None:
+ # Interfaces from template
+ interfaces = relationship_template._get_interfaces(context)
+ if interfaces:
+ raw['relationship']['interfaces'] = OrderedDict()
+ for interface_name, interface in interfaces.iteritems():
+ raw['relationship']['interfaces'][interface_name] = interface._raw
+
+ return \
+ RequirementAssignment(name=requirement_definition._name, raw=raw, container=container), \
+ relationship_property_definitions, \
+ relationship_interface_definitions
+
+
+def add_requirement_assignments(context, presentation, requirement_assignments,
+ requirement_definitions, our_requirement_assignments):
+ for requirement_name, our_requirement_assignment in our_requirement_assignments:
+ requirement_definition = get_first_requirement(requirement_definitions, requirement_name)
+ if requirement_definition is not None:
+ requirement_assignment, \
+ relationship_property_definitions, \
+ relationship_interface_definitions = \
+ convert_requirement_from_definition_to_assignment(context, requirement_definition,
+ our_requirement_assignment,
+ presentation)
+ merge_requirement_assignment(context,
+ relationship_property_definitions,
+ relationship_interface_definitions,
+ requirement_assignment, our_requirement_assignment)
+ validate_requirement_assignment(context,
+ our_requirement_assignment.relationship \
+ or our_requirement_assignment,
+ requirement_assignment,
+ relationship_property_definitions,
+ relationship_interface_definitions)
+ requirement_assignments.append((requirement_name, requirement_assignment))
+ else:
+ context.validation.report('requirement "%s" not declared at node type "%s" in "%s"'
+ % (requirement_name, presentation.type,
+ presentation._fullname),
+ locator=our_requirement_assignment._locator,
+ level=Issue.BETWEEN_TYPES)
+
+
+def merge_requirement_assignment(context, relationship_property_definitions,
+ relationship_interface_definitions, requirement, our_requirement):
+ our_capability = our_requirement.capability
+ if our_capability is not None:
+ requirement._raw['capability'] = deepcopy_with_locators(our_capability)
+
+ our_node = our_requirement.node
+ if our_node is not None:
+ requirement._raw['node'] = deepcopy_with_locators(our_node)
+
+ our_node_filter = our_requirement.node_filter
+ if our_node_filter is not None:
+ requirement._raw['node_filter'] = deepcopy_with_locators(our_node_filter._raw)
+
+ our_relationship = our_requirement.relationship # RelationshipAssignment
+ if (our_relationship is not None) and (our_relationship.type is None):
+ # Make sure we have a dict
+ if 'relationship' not in requirement._raw:
+ requirement._raw['relationship'] = OrderedDict()
+
+ merge_requirement_assignment_relationship(context, our_relationship,
+ relationship_property_definitions,
+ relationship_interface_definitions,
+ requirement, our_relationship)
+
+
+def merge_requirement_assignment_relationship(context, presentation, property_definitions,
+ interface_definitions, requirement, our_relationship):
+ our_relationship_properties = our_relationship._raw.get('properties')
+ if our_relationship_properties:
+ # Make sure we have a dict
+ if 'properties' not in requirement._raw['relationship']:
+ requirement._raw['relationship']['properties'] = OrderedDict()
+
+ # Merge our properties
+ for property_name, prop in our_relationship_properties.iteritems():
+ if property_name in property_definitions:
+ definition = property_definitions[property_name]
+ requirement._raw['relationship']['properties'][property_name] = \
+ coerce_parameter_value(context, presentation, definition, prop)
+ else:
+ context.validation.report(
+ 'relationship property "%s" not declared at definition of requirement "%s"'
+ ' in "%s"'
+ % (property_name, requirement._fullname,
+ presentation._container._container._fullname),
+ locator=our_relationship._get_child_locator('properties', property_name),
+ level=Issue.BETWEEN_TYPES)
+
+ our_interfaces = our_relationship.interfaces
+ if our_interfaces:
+ # Make sure we have a dict
+ if 'interfaces' not in requirement._raw['relationship']:
+ requirement._raw['relationship']['interfaces'] = OrderedDict()
+
+ # Merge interfaces
+ for interface_name, our_interface in our_interfaces.iteritems():
+ if interface_name not in requirement._raw['relationship']['interfaces']:
+ requirement._raw['relationship']['interfaces'][interface_name] = OrderedDict()
+
+ if (interface_definitions is not None) and (interface_name in interface_definitions):
+ interface_definition = interface_definitions[interface_name]
+ interface_assignment = requirement.relationship.interfaces[interface_name]
+ merge_interface(context, presentation, interface_assignment, our_interface,
+ interface_definition, interface_name)
+ else:
+ context.validation.report(
+ 'relationship interface "%s" not declared at definition of requirement "%s"'
+ ' in "%s"'
+ % (interface_name, requirement._fullname,
+ presentation._container._container._fullname),
+ locator=our_relationship._locator, level=Issue.BETWEEN_TYPES)
+
+
+def validate_requirement_assignment(context, presentation, requirement_assignment,
+ relationship_property_definitions,
+ relationship_interface_definitions):
+ relationship = requirement_assignment.relationship
+ if relationship is None:
+ return
+
+ validate_required_values(context, presentation, relationship.properties,
+ relationship_property_definitions)
+
+ if relationship_interface_definitions:
+ for interface_name, relationship_interface_definition \
+ in relationship_interface_definitions.iteritems():
+ interface_assignment = relationship.interfaces.get(interface_name) \
+ if relationship.interfaces is not None else None
+ validate_required_inputs(context, presentation, interface_assignment,
+ relationship_interface_definition, None, interface_name)
+
+
+def get_first_requirement(requirement_definitions, name):
+ if requirement_definitions is not None:
+ for requirement_name, requirement_definition in requirement_definitions:
+ if requirement_name == name:
+ return requirement_definition
+ return None
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py
new file mode 100644
index 0000000..e2af4b8
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py
@@ -0,0 +1,167 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.formatting import safe_repr
+from aria.parser.validation import Issue
+
+
+def validate_substitution_mappings_requirement(context, presentation):
+
+ # validate that the requirement in substitution_mapping is defined in the substitution node type
+ substitution_node_type = presentation._container._get_type(context)
+ if substitution_node_type is None:
+ return
+ for req_name, req in substitution_node_type._get_requirements(context):
+ if req_name == presentation._name:
+ substitution_type_requirement = req
+ break
+ else:
+ context.validation.report(
+ 'substitution mapping requirement "{0}" is not declared in node type "{1}"'.format(
+ presentation._name, substitution_node_type._name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ return
+
+ if not _validate_mapping_format(presentation):
+ _report_invalid_mapping_format(context, presentation, field='requirement')
+ return
+
+ # validate that the mapped requirement is defined in the corresponding node template
+ node_template = _get_node_template(context, presentation)
+ if node_template is None:
+ _report_missing_node_template(context, presentation, field='requirement')
+ return
+ mapped_requirement_name = presentation._raw[1]
+ for req_name, req in node_template._get_requirements(context):
+ if req_name == mapped_requirement_name:
+ node_template_requirement = req
+ break
+ else:
+ context.validation.report(
+ 'substitution mapping requirement "{0}" refers to an unknown requirement of node '
+ 'template "{1}": {mapped_requirement_name}'.format(
+ presentation._name, node_template._name,
+ mapped_requirement_name=safe_repr(mapped_requirement_name)),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ return
+
+ # validate that the requirement's capability type in substitution_mapping is derived from the
+ # requirement's capability type in the corresponding node template
+ substitution_type_requirement_capability_type = \
+ substitution_type_requirement._get_capability_type(context)
+ node_template_requirement_capability_type = \
+ node_template_requirement._get_capability(context)[0]
+ if not node_template_requirement_capability_type._is_descendant(
+ context, substitution_type_requirement_capability_type):
+ context.validation.report(
+ 'substitution mapping requirement "{0}" of capability type "{1}" is not a descendant '
+ 'of the mapped node template capability type "{2}"'.format(
+ presentation._name,
+ substitution_type_requirement_capability_type._name,
+ node_template_requirement_capability_type._name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+
+
+def validate_substitution_mappings_capability(context, presentation):
+
+ # validate that the capability in substitution_mapping is defined in the substitution node type
+ substitution_node_type = presentation._container._get_type(context)
+ if substitution_node_type is None:
+ return
+ substitution_type_capabilities = substitution_node_type._get_capabilities(context)
+ substitution_type_capability = substitution_type_capabilities.get(presentation._name)
+ if substitution_type_capability is None:
+ context.validation.report(
+ 'substitution mapping capability "{0}" '
+ 'is not declared in node type "{substitution_type}"'.format(
+ presentation._name, substitution_type=substitution_node_type._name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ return
+
+ if not _validate_mapping_format(presentation):
+ _report_invalid_mapping_format(context, presentation, field='capability')
+ return
+
+ # validate that the capability in substitution_mapping is declared in the corresponding
+ # node template
+ node_template = _get_node_template(context, presentation)
+ if node_template is None:
+ _report_missing_node_template(context, presentation, field='capability')
+ return
+ mapped_capability_name = presentation._raw[1]
+ node_template_capability = node_template._get_capabilities(context).get(mapped_capability_name)
+
+ if node_template_capability is None:
+ context.validation.report(
+ 'substitution mapping capability "{0}" refers to an unknown '
+ 'capability of node template "{1}": {mapped_capability_name}'.format(
+ presentation._name, node_template._name,
+ mapped_capability_name=safe_repr(mapped_capability_name)),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ return
+
+ # validate that the capability type in substitution_mapping is derived from the capability type
+ # in the corresponding node template
+ substitution_type_capability_type = substitution_type_capability._get_type(context)
+ node_template_capability_type = node_template_capability._get_type(context)
+
+ if not substitution_type_capability_type._is_descendant(context, node_template_capability_type):
+ context.validation.report(
+ 'node template capability type "{0}" is not a descendant of substitution mapping '
+ 'capability "{1}" of type "{2}"'.format(
+ node_template_capability_type._name,
+ presentation._name,
+ substitution_type_capability_type._name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+
+
+#
+# Utils
+#
+
+def _validate_mapping_format(presentation):
+ """Validate that the mapping is a list of 2 strings"""
+ if not isinstance(presentation._raw, list) or \
+ len(presentation._raw) != 2 or \
+ not isinstance(presentation._raw[0], basestring) or \
+ not isinstance(presentation._raw[1], basestring):
+ return False
+ return True
+
+
+def _get_node_template(context, presentation):
+ node_template_name = presentation._raw[0]
+ node_template = context.presentation.get_from_dict('service_template', 'topology_template',
+ 'node_templates', node_template_name)
+ return node_template
+
+
+def _report_missing_node_template(context, presentation, field):
+ context.validation.report(
+ 'substitution mappings {field} "{node_template_mapping}" '
+ 'refers to an unknown node template: {node_template_name}'.format(
+ field=field,
+ node_template_mapping=presentation._name,
+ node_template_name=safe_repr(presentation._raw[0])),
+ locator=presentation._locator, level=Issue.FIELD)
+
+
+def _report_invalid_mapping_format(context, presentation, field):
+ context.validation.report(
+ 'substitution mapping {field} "{field_name}" is not a list of 2 strings: {value}'.format(
+ field=field,
+ field_name=presentation._name,
+ value=safe_repr(presentation._raw)),
+ locator=presentation._locator, level=Issue.FIELD)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/__init__.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/__init__.py
new file mode 100644
index 0000000..ae1e83e
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/__init__.py
@@ -0,0 +1,14 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
new file mode 100644
index 0000000..0e3c94d
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.caching import cachedmethod
+from aria.parser.presentation import (Presentation, has_fields, primitive_dict_field)
+
+
+@has_fields
+class ExtensiblePresentation(Presentation):
+ """
+ A presentation that supports an optional ``_extensions`` dict field.
+ """
+
+ @primitive_dict_field()
+ def _extensions(self):
+ pass
+
+ @cachedmethod
+ def _get_extension(self, name, default=None):
+ extensions = self._extensions
+ return extensions.get(name, default) if extensions is not None else None # pylint: disable=no-member
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
new file mode 100644
index 0000000..f14164a
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
@@ -0,0 +1,37 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.formatting import safe_repr
+from aria.parser.exceptions import InvalidValueError
+
+
+def data_type_class_getter(cls):
+ """
+ Wraps the field value in a specialized data type class.
+
+ Can be used with the :func:`field_getter` decorator.
+ """
+
+ def getter(field, presentation, context=None):
+ raw = field.default_get(presentation, context)
+ if raw is not None:
+ try:
+ return cls(None, None, raw, None)
+ except ValueError as e:
+ raise InvalidValueError(
+ '%s is not a valid "%s" in "%s": %s'
+ % (field.full_name, field.full_cls_name, presentation._name, safe_repr(raw)),
+ cause=e, locator=field.get_locator(raw))
+ return getter
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
new file mode 100644
index 0000000..e5853d8
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
@@ -0,0 +1,588 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.formatting import safe_repr
+from aria.parser import implements_specification
+from aria.parser.presentation import (report_issue_for_unknown_type, derived_from_validator)
+from aria.parser.validation import Issue
+
+from ..modeling.data_types import (get_primitive_data_type, get_data_type_name, coerce_value,
+ get_container_data_type)
+from .types import (get_type_by_name, convert_name_to_full_type_name)
+
+
+
+#
+# NodeTemplate, RelationshipTemplate
+#
+
+@implements_specification('3.7.3.3', 'tosca-simple-1.0')
+def copy_validator(template_type_name, templates_dict_name):
+ """
+ Makes sure that the field refers to an existing template defined in the root presenter.
+
+ Use with the :func:`field_validator` decorator for the ``copy`` field in
+ :class:`NodeTemplate` and :class:`RelationshipTemplate`.
+ """
+
+ def validator_fn(field, presentation, context):
+ field.default_validate(presentation, context)
+
+ # Make sure type exists
+ value = getattr(presentation, field.name)
+ if value is not None:
+ copy = context.presentation.get_from_dict('service_template', 'topology_template',
+ templates_dict_name, value)
+ if copy is None:
+ report_issue_for_unknown_type(context, presentation, template_type_name, field.name)
+ else:
+ if copy.copy is not None:
+ context.validation.report(
+ '"copy" field refers to a %s that itself is a copy in "%s": %s'
+ % (template_type_name, presentation._fullname, safe_repr(value)),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+
+ return validator_fn
+
+
+#
+# PropertyDefinition, AttributeDefinition, ParameterDefinition, EntrySchema
+#
+
+def data_type_validator(type_name='data type'):
+ """
+ Makes sure that the field refers to a valid data type, whether complex or primitive.
+
+ Used with the :func:`field_validator` decorator for the ``type`` fields in
+ :class:`PropertyDefinition`, :class:`AttributeDefinition`, :class:`ParameterDefinition`,
+ and :class:`EntrySchema`.
+
+ Extra behavior beyond validation: generated function returns true if field is a complex data
+ type.
+ """
+
+ def validator(field, presentation, context):
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ # Test for circular definitions
+ container_data_type = get_container_data_type(presentation)
+ if (container_data_type is not None) and (container_data_type._name == value):
+ context.validation.report(
+ 'type of property "%s" creates a circular value hierarchy: %s'
+ % (presentation._fullname, safe_repr(value)),
+ locator=presentation._get_child_locator('type'), level=Issue.BETWEEN_TYPES)
+
+ # Can be a complex data type
+ if get_type_by_name(context, value, 'data_types') is not None:
+ return True
+
+ # Can be a primitive data type
+ if get_primitive_data_type(value) is None:
+ report_issue_for_unknown_type(context, presentation, type_name, field.name)
+
+ return False
+
+ return validator
+
+
+#
+# PropertyDefinition, AttributeDefinition
+#
+
+def entry_schema_validator(field, presentation, context):
+ """
+ According to whether the data type supports ``entry_schema`` (e.g., it is or inherits from
+ list or map), make sure that we either have or don't have a valid data type value.
+
+ Used with the :func:`field_validator` decorator for the ``entry_schema`` field in
+ :class:`PropertyDefinition` and :class:`AttributeDefinition`.
+ """
+
+ field.default_validate(presentation, context)
+
+ def type_uses_entry_schema(the_type):
+ use_entry_schema = the_type._get_extension('use_entry_schema', False) \
+ if hasattr(the_type, '_get_extension') else False
+ if use_entry_schema:
+ return True
+ parent = the_type._get_parent(context) if hasattr(the_type, '_get_parent') else None
+ if parent is None:
+ return False
+ return type_uses_entry_schema(parent)
+
+ value = getattr(presentation, field.name)
+ the_type = presentation._get_type(context)
+ if the_type is None:
+ return
+ use_entry_schema = type_uses_entry_schema(the_type)
+
+ if use_entry_schema:
+ if value is None:
+ context.validation.report(
+ '"entry_schema" does not have a value as required by data type "%s" in "%s"'
+ % (get_data_type_name(the_type), presentation._container._fullname),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ else:
+ if value is not None:
+ context.validation.report(
+ '"entry_schema" has a value but it is not used by data type "%s" in "%s"'
+ % (get_data_type_name(the_type), presentation._container._fullname),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+
+
+def data_value_validator(field, presentation, context):
+ """
+ Makes sure that the field contains a valid value according to data type and constraints.
+
+ Used with the :func:`field_validator` decorator for the ``default`` field in
+ :class:`PropertyDefinition` and :class:`AttributeDefinition`.
+ """
+
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ the_type = presentation._get_type(context)
+ entry_schema = presentation.entry_schema
+ # AttributeDefinition does not have this:
+ constraints = presentation._get_constraints(context) \
+ if hasattr(presentation, '_get_constraints') else None
+ coerce_value(context, presentation, the_type, entry_schema, constraints, value, field.name)
+
+
+#
+# DataType
+#
+
+_data_type_validator = data_type_validator()
+_data_type_derived_from_validator = derived_from_validator(convert_name_to_full_type_name,
+ 'data_types')
+
+
+def data_type_derived_from_validator(field, presentation, context):
+ """
+ Makes sure that the field refers to a valid parent data type (complex or primitive).
+
+ Used with the :func:`field_validator` decorator for the ``derived_from`` field in
+ :class:`DataType`.
+ """
+
+ if _data_type_validator(field, presentation, context):
+ # Validate derivation only if a complex data type (primitive types have no derivation
+ # hierarchy)
+ _data_type_derived_from_validator(field, presentation, context)
+
+
+def data_type_constraints_validator(field, presentation, context):
+ """
+ Makes sure that we do not have constraints if we are a complex type (with no primitive
+ ancestor).
+ """
+
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ if presentation._get_primitive_ancestor(context) is None:
+ context.validation.report(
+ 'data type "%s" defines constraints but does not have a primitive ancestor'
+ % presentation._fullname,
+ locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES)
+
+
+def data_type_properties_validator(field, presentation, context):
+ """
+ Makes sure that we do not have properties if we have a primitive ancestor.
+
+ Used with the :func:`field_validator` decorator for the ``properties`` field in
+ :class:`DataType`.
+ """
+
+ field.default_validate(presentation, context)
+
+ values = getattr(presentation, field.name)
+ if values is not None:
+ if presentation._get_primitive_ancestor(context) is not None:
+ context.validation.report(
+ 'data type "%s" defines properties even though it has a primitive ancestor'
+ % presentation._fullname,
+ locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES)
+
+
+#
+# ConstraintClause
+#
+
+def constraint_clause_field_validator(field, presentation, context):
+ """
+ Makes sure that field contains a valid value for the container type.
+
+ Used with the :func:`field_validator` decorator for various field in :class:`ConstraintClause`.
+ """
+
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ the_type = presentation._get_type(context)
+ constraints = the_type._get_constraints(context) \
+ if hasattr(the_type, '_get_constraints') else None
+ coerce_value(context, presentation, the_type, None, constraints, value, field.name)
+
+
+def constraint_clause_in_range_validator(field, presentation, context):
+ """
+ Makes sure that the value is a list with exactly two elements, that both lower bound contains a
+ valid value for the container type, and that the upper bound is either "UNBOUNDED" or a valid
+ value for the container type.
+
+ Used with the :func:`field_validator` decorator for the ``in_range`` field in
+ :class:`ConstraintClause`.
+ """
+
+ field.default_validate(presentation, context)
+
+ values = getattr(presentation, field.name)
+ if isinstance(values, list):
+ # Make sure list has exactly two elements
+ if len(values) == 2:
+ lower, upper = values
+ the_type = presentation._get_type(context)
+
+ # Lower bound must be coercible
+ lower = coerce_value(context, presentation, the_type, None, None, lower, field.name)
+
+ if upper != 'UNBOUNDED':
+ # Upper bound be coercible
+ upper = coerce_value(context, presentation, the_type, None, None, upper, field.name)
+
+ # Second "in_range" value must be greater than first
+ if (lower is not None) and (upper is not None) and (lower >= upper):
+ context.validation.report(
+ 'upper bound of "in_range" constraint is not greater than the lower bound'
+ ' in "%s": %s <= %s'
+ % (presentation._container._fullname, safe_repr(lower), safe_repr(upper)),
+ locator=presentation._locator, level=Issue.FIELD)
+ else:
+ context.validation.report(
+ 'constraint "%s" is not a list of exactly 2 elements in "%s"'
+ % (field.name, presentation._fullname),
+ locator=presentation._get_child_locator(field.name), level=Issue.FIELD)
+
+
+def constraint_clause_valid_values_validator(field, presentation, context):
+ """
+ Makes sure that the value is a list of valid values for the container type.
+
+ Used with the :func:`field_validator` decorator for the ``valid_values`` field in
+ :class:`ConstraintClause`.
+ """
+
+ field.default_validate(presentation, context)
+
+ values = getattr(presentation, field.name)
+ if isinstance(values, list):
+ the_type = presentation._get_type(context)
+ for value in values:
+ coerce_value(context, presentation, the_type, None, None, value, field.name)
+
+
+def constraint_clause_pattern_validator(field, presentation, context):
+ """
+ Makes sure that the value is a valid regular expression.
+
+ Used with the :func:`field_validator` decorator for the ``pattern`` field in
+ :class:`ConstraintClause`.
+ """
+
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ try:
+ # From TOSCA 1.0 3.5.2.1:
+ #
+ # "Note: Future drafts of this specification will detail the use of regular expressions
+ # and reference an appropriate standardized grammar."
+ #
+ # So we will just use Python's.
+ re.compile(value)
+ except re.error as e:
+ context.validation.report(
+ 'constraint "%s" is not a valid regular expression in "%s"'
+ % (field.name, presentation._fullname),
+ locator=presentation._get_child_locator(field.name), level=Issue.FIELD, exception=e)
+
+
+#
+# RequirementAssignment
+#
+
+def node_template_or_type_validator(field, presentation, context):
+ """
+ Makes sure that the field refers to either a node template or a node type.
+
+ Used with the :func:`field_validator` decorator for the ``node`` field in
+ :class:`RequirementAssignment`.
+ """
+
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ node_templates = \
+ context.presentation.get('service_template', 'topology_template', 'node_templates') \
+ or {}
+ if (value not in node_templates) and \
+ (get_type_by_name(context, value, 'node_types') is None):
+ report_issue_for_unknown_type(context, presentation, 'node template or node type',
+ field.name)
+
+
+def capability_definition_or_type_validator(field, presentation, context):
+ """
+ Makes sure refers to either a capability assignment name in the node template referred to by the
+ ``node`` field or a general capability type.
+
+ If the value refers to a capability type, make sure the ``node`` field was not assigned.
+
+ Used with the :func:`field_validator` decorator for the ``capability`` field in
+ :class:`RequirementAssignment`.
+ """
+
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ node, node_variant = presentation._get_node(context)
+ if node_variant == 'node_template':
+ capabilities = node._get_capabilities(context)
+ if value in capabilities:
+ return
+
+ if get_type_by_name(context, value, 'capability_types') is not None:
+ if node is not None:
+ context.validation.report(
+ '"%s" refers to a capability type even though "node" has a value in "%s"'
+ % (presentation._name, presentation._container._fullname),
+ locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_FIELDS)
+ return
+
+ if node_variant == 'node_template':
+ context.validation.report(
+ 'requirement "%s" refers to an unknown capability definition name or capability'
+ ' type in "%s": %s'
+ % (presentation._name, presentation._container._fullname, safe_repr(value)),
+ locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES)
+ else:
+ context.validation.report(
+ 'requirement "%s" refers to an unknown capability type in "%s": %s'
+ % (presentation._name, presentation._container._fullname, safe_repr(value)),
+ locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES)
+
+
+def node_filter_validator(field, presentation, context):
+ """
+ Makes sure that the field has a value only if "node" refers to a node type.
+
+ Used with the :func:`field_validator` decorator for the ``node_filter`` field in
+ :class:`RequirementAssignment`.
+ """
+
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ _, node_type_variant = presentation._get_node(context)
+ if node_type_variant != 'node_type':
+ context.validation.report(
+ 'requirement "%s" has a node filter even though "node" does not refer to a node'
+ ' type in "%s"'
+ % (presentation._fullname, presentation._container._fullname),
+ locator=presentation._locator, level=Issue.BETWEEN_FIELDS)
+
+
+#
+# RelationshipAssignment
+#
+
+def relationship_template_or_type_validator(field, presentation, context):
+ """
+ Makes sure that the field refers to either a relationship template or a relationship type.
+
+ Used with the :func:`field_validator` decorator for the ``type`` field in
+ :class:`RelationshipAssignment`.
+ """
+
+ field.default_validate(presentation, context)
+
+ value = getattr(presentation, field.name)
+ if value is not None:
+ relationship_templates = \
+ context.presentation.get('service_template', 'topology_template',
+ 'relationship_templates') \
+ or {}
+ if (value not in relationship_templates) and \
+ (get_type_by_name(context, value, 'relationship_types') is None):
+ report_issue_for_unknown_type(context, presentation,
+ 'relationship template or relationship type', field.name)
+
+
+#
+# PolicyType
+#
+
+def list_node_type_or_group_type_validator(field, presentation, context):
+ """
+ Makes sure that the field's elements refer to either node types or a group types.
+
+ Used with the :func:`field_validator` decorator for the ``targets`` field in
+ :class:`PolicyType`.
+ """
+
+ field.default_validate(presentation, context)
+
+ values = getattr(presentation, field.name)
+ if values is not None:
+ for value in values:
+ if (get_type_by_name(context, value, 'node_types') is None) and \
+ (get_type_by_name(context, value, 'group_types') is None):
+ report_issue_for_unknown_type(context, presentation, 'node type or group type',
+ field.name, value)
+
+
+#
+# PolicyTemplate
+#
+
+def policy_targets_validator(field, presentation, context):
+ """
+ Makes sure that the field's elements refer to either node templates or groups, and that
+ they match the node types and group types declared in the policy type.
+
+ Used with the :func:`field_validator` decorator for the ``targets`` field in
+ :class:`PolicyTemplate`.
+ """
+
+ field.default_validate(presentation, context)
+
+ values = getattr(presentation, field.name)
+ if values is not None:
+ for value in values:
+ node_templates = \
+ context.presentation.get('service_template', 'topology_template',
+ 'node_templates') \
+ or {}
+ groups = context.presentation.get('service_template', 'topology_template', 'groups') \
+ or {}
+ if (value not in node_templates) and (value not in groups):
+ report_issue_for_unknown_type(context, presentation, 'node template or group',
+ field.name, value)
+
+ policy_type = presentation._get_type(context)
+ if policy_type is None:
+ break
+
+ node_types, group_types = policy_type._get_targets(context)
+
+ is_valid = False
+
+ if value in node_templates:
+ our_node_type = node_templates[value]._get_type(context)
+ for node_type in node_types:
+ if node_type._is_descendant(context, our_node_type):
+ is_valid = True
+ break
+
+ elif value in groups:
+ our_group_type = groups[value]._get_type(context)
+ for group_type in group_types:
+ if group_type._is_descendant(context, our_group_type):
+ is_valid = True
+ break
+
+ if not is_valid:
+ context.validation.report(
+ 'policy definition target does not match either a node type or a group type'
+ ' declared in the policy type in "%s": %s'
+ % (presentation._name, safe_repr(value)),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+
+
+#
+# NodeFilter
+#
+
+def node_filter_properties_validator(field, presentation, context):
+ """
+ Makes sure that the field's elements refer to defined properties in the target node type.
+
+ Used with the :func:`field_validator` decorator for the ``properties`` field in
+ :class:`NodeFilter`.
+ """
+
+ field.default_validate(presentation, context)
+
+ values = getattr(presentation, field.name)
+ if values is not None:
+ node_type = presentation._get_node_type(context)
+ if node_type is not None:
+ properties = node_type._get_properties(context)
+ for name, _ in values:
+ if name not in properties:
+ context.validation.report(
+ 'node filter refers to an unknown property definition in "%s": %s'
+ % (node_type._name, name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+
+
+def node_filter_capabilities_validator(field, presentation, context):
+ """
+ Makes sure that the field's elements refer to defined capabilities and properties in the target
+ node type.
+
+ Used with the :func:`field_validator` decorator for the ``capabilities`` field in
+ :class:`NodeFilter`.
+ """
+
+ field.default_validate(presentation, context)
+
+ values = getattr(presentation, field.name)
+ if values is not None: # pylint: disable=too-many-nested-blocks
+ node_type = presentation._get_node_type(context)
+ if node_type is not None:
+ capabilities = node_type._get_capabilities(context)
+ for name, value in values:
+ capability = capabilities.get(name)
+ if capability is not None:
+ properties = value.properties
+ capability_properties = capability.properties
+ if (properties is not None) and (capability_properties is not None):
+ for property_name, _ in properties:
+ if property_name not in capability_properties:
+ context.validation.report(
+ 'node filter refers to an unknown capability definition'
+ ' property in "%s": %s'
+ % (node_type._name, property_name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
+ else:
+ context.validation.report(
+ 'node filter refers to an unknown capability definition in "%s": %s'
+ % (node_type._name, name),
+ locator=presentation._locator, level=Issue.BETWEEN_TYPES)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
new file mode 100644
index 0000000..5f9750e
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
@@ -0,0 +1,63 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+
+def convert_name_to_full_type_name(context, name, types_dict): # pylint: disable=unused-argument
+ """
+ Converts a type name to its full type name, or else returns it unchanged.
+
+ Works by checking for ``shorthand_name`` and ``type_qualified_name`` in the types'
+ ``_extensions`` field. See also
+ :class:`aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
+
+ Can be used as the conversion function argument in ``type_validator`` and
+ ``derived_from_validator``.
+ """
+
+ if (name is not None) and types_dict and (name not in types_dict):
+ for full_name, the_type in types_dict.iteritems():
+ if hasattr(the_type, '_extensions') and the_type._extensions \
+ and ((the_type._extensions.get('shorthand_name') == name) \
+ or (the_type._extensions.get('type_qualified_name') == name)):
+ return full_name
+ return name
+
+
+def get_type_by_name(context, name, *types_dict_names):
+ """
+ Gets a type either by its full name or its shorthand name or type-qualified name.
+
+ Works by checking for ``shorthand_name`` and ``type_qualified_name`` in the types'
+ ``_extensions`` field. See also
+ :class:`~aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
+
+ The arguments from the third onwards are used to locate a nested field under
+ ``service_template`` under the root presenter.
+ """
+
+ if name is not None:
+ types_dict = context.presentation.get('service_template', *types_dict_names)
+ if types_dict:
+ the_type = types_dict.get(name)
+ if the_type is not None:
+ # Full name
+ return the_type
+ for the_type in types_dict.itervalues():
+ if hasattr(the_type, '_extensions') and the_type._extensions \
+ and ((the_type._extensions.get('shorthand_name') == name) \
+ or (the_type._extensions.get('type_qualified_name') == name)):
+ # Shorthand name
+ return the_type
+ return None
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presenter.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presenter.py
new file mode 100644
index 0000000..8e1809f
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/presenter.py
@@ -0,0 +1,83 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import (FrozenList, EMPTY_READ_ONLY_LIST)
+from aria.utils.caching import cachedmethod
+from aria.parser.presentation import Presenter
+
+from .modeling import create_service_template_model
+from .modeling.functions import (Concat, Token, GetInput, GetProperty, GetAttribute,
+ GetOperationOutput, GetNodesOfType, GetArtifact)
+from .templates import ServiceTemplate
+
+
+class ToscaSimplePresenter1_0(Presenter): # pylint: disable=invalid-name,abstract-method
+ """
+ ARIA presenter for the `TOSCA Simple Profile v1.0 cos01 <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html>`__.
+
+ Supported ``tosca_definitions_version`` values:
+
+ * ``tosca_simple_yaml_1_0``
+ """
+
+ DSL_VERSIONS = ('tosca_simple_yaml_1_0',)
+ ALLOWED_IMPORTED_DSL_VERSIONS = ('tosca_simple_yaml_1_0',)
+ SIMPLE_PROFILE_LOCATION = 'tosca-simple-1.0/tosca-simple-1.0.yaml'
+ SPECIAL_IMPORTS = {
+ 'aria-1.0': 'aria-1.0/aria-1.0.yaml',
+ 'azure-plugin':'azure-plugin/azureplugin.yaml'}
+
+ @property
+ @cachedmethod
+ def service_template(self):
+ return ServiceTemplate(raw=self._raw)
+
+ @property
+ @cachedmethod
+ def functions(self):
+ return {
+ 'concat': Concat,
+ 'token': Token,
+ 'get_input': GetInput,
+ 'get_property': GetProperty,
+ 'get_attribute': GetAttribute,
+ 'get_operation_output': GetOperationOutput,
+ 'get_nodes_of_type': GetNodesOfType,
+ 'get_artifact': GetArtifact}
+
+ # Presentation
+
+ def _dump(self, context):
+ self.service_template._dump(context)
+
+ def _validate(self, context):
+ self.service_template._validate(context)
+
+ # Presenter
+
+ @cachedmethod
+ def _get_import_locations(self, context):
+ import_locations = []
+ if context.presentation.import_profile:
+ import_locations.append(self.SIMPLE_PROFILE_LOCATION)
+ imports = self._get('service_template', 'imports')
+ if imports:
+ import_locations += [self.SPECIAL_IMPORTS.get(i.file, i.file) for i in imports]
+ return FrozenList(import_locations) if import_locations else EMPTY_READ_ONLY_LIST
+
+ @cachedmethod
+ def _get_model(self, context): # pylint: disable=no-self-use
+ return create_service_template_model(context)
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/templates.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/templates.py
new file mode 100644
index 0000000..3c36bb8
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/templates.py
@@ -0,0 +1,736 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import (FrozenDict, FrozenList)
+from aria.utils.caching import cachedmethod
+from aria.parser import implements_specification
+from aria.parser.presentation import (has_fields, primitive_field, primitive_list_field,
+ object_field, object_list_field, object_dict_field,
+ object_sequenced_list_field, field_validator,
+ type_validator, list_type_validator)
+
+from .assignments import (PropertyAssignment, AttributeAssignment, RequirementAssignment,
+ CapabilityAssignment, InterfaceAssignment, ArtifactAssignment)
+from .definitions import ParameterDefinition
+from .filters import NodeFilter
+from .misc import (Description, MetaData, Repository, Import, SubstitutionMappings)
+from .modeling.parameters import (get_assigned_and_defined_parameter_values, get_parameter_values)
+from .modeling.interfaces import get_template_interfaces
+from .modeling.requirements import get_template_requirements
+from .modeling.capabilities import get_template_capabilities
+from .modeling.artifacts import get_inherited_artifact_definitions
+from .modeling.policies import get_policy_targets
+from .modeling.copy import get_default_raw_from_copy
+from .presentation.extensible import ExtensiblePresentation
+from .presentation.field_validators import copy_validator, policy_targets_validator
+from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
+from .types import (ArtifactType, DataType, CapabilityType, InterfaceType, RelationshipType,
+ NodeType, GroupType, PolicyType)
+
+
+@has_fields
+@implements_specification('3.7.3', 'tosca-simple-1.0')
+class NodeTemplate(ExtensiblePresentation):
+ """
+ A Node Template specifies the occurrence of a manageable software component as part of an
+ application's topology model which is defined in a TOSCA Service Template. A Node template is an
+ instance of a specified Node Type and can provide customized properties, constraints or
+ operations which override the defaults provided by its Node Type and its implementations.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_NODE_TEMPLATE>`__
+ """
+
+ @field_validator(type_validator('node type', convert_name_to_full_type_name, 'node_types'))
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The required name of the Node Type the Node Template is based upon.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ An optional description for the Node Template.
+
+ :type: :class:`Description`
+ """
+
+ @primitive_list_field(str)
+ def directives(self):
+ """
+ An optional list of directive values to provide processing instructions to orchestrators and
+ tooling.
+
+ :type: [:obj:`basestring`]
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def properties(self):
+ """
+ An optional list of property value assignments for the Node Template.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`}
+ """
+
+ @object_dict_field(AttributeAssignment)
+ def attributes(self):
+ """
+ An optional list of attribute value assignments for the Node Template.
+
+ :type: {:obj:`basestring`: :class:`AttributeAssignment`}
+ """
+
+ @object_sequenced_list_field(RequirementAssignment)
+ def requirements(self):
+ """
+ An optional sequenced list of requirement assignments for the Node Template.
+
+ :type: list of (str, :class:`RequirementAssignment`)
+ """
+
+ @object_dict_field(CapabilityAssignment)
+ def capabilities(self):
+ """
+ An optional list of capability assignments for the Node Template.
+
+ :type: {:obj:`basestring`: :class:`CapabilityAssignment`}
+ """
+
+ @object_dict_field(InterfaceAssignment)
+ def interfaces(self):
+ """
+ An optional list of named interface definitions for the Node Template.
+
+ :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
+ """
+
+ @object_dict_field(ArtifactAssignment)
+ def artifacts(self):
+ """
+ An optional list of named artifact definitions for the Node Template.
+
+ :type: {:obj:`basestring`: :class:`ArtifactAssignment`}
+ """
+
+ @object_field(NodeFilter)
+ def node_filter(self):
+ """
+ The optional filter definition that TOSCA orchestrators would use to select the correct
+ target node. This keyname is only valid if the directive has the value of "selectable" set.
+
+ :type: :class:`NodeFilter`
+ """
+
+ @field_validator(copy_validator('node template', 'node_templates'))
+ @primitive_field(str)
+ def copy(self):
+ """
+ The optional (symbolic) name of another node template to copy into (all keynames and values)
+ and use as a basis for this node template.
+
+ :type: :obj:`basestring`
+ """
+
+ @cachedmethod
+ def _get_default_raw(self):
+ return get_default_raw_from_copy(self, 'node_templates')
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.type, 'node_types')
+
+ @cachedmethod
+ def _get_property_values(self, context):
+ return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))
+
+ @cachedmethod
+ def _get_attribute_default_values(self, context):
+ return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'attribute'))
+
+ @cachedmethod
+ def _get_requirements(self, context):
+ return FrozenList(get_template_requirements(context, self))
+
+ @cachedmethod
+ def _get_capabilities(self, context):
+ return FrozenDict(get_template_capabilities(context, self))
+
+ @cachedmethod
+ def _get_interfaces(self, context):
+ return FrozenDict(get_template_interfaces(context, self, 'node template'))
+
+ @cachedmethod
+ def _get_artifacts(self, context):
+ return FrozenDict(get_inherited_artifact_definitions(context, self))
+
+ def _validate(self, context):
+ super(NodeTemplate, self)._validate(context)
+ self._get_property_values(context)
+ self._get_requirements(context)
+ self._get_capabilities(context)
+ self._get_interfaces(context)
+ self._get_artifacts(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'type',
+ 'directives',
+ 'properties',
+ 'attributes',
+ 'requirements',
+ 'capabilities',
+ 'interfaces',
+ 'artifacts',
+ 'node_filter',
+ 'copy'))
+
+
+@has_fields
+@implements_specification('3.7.4', 'tosca-simple-1.0')
+class RelationshipTemplate(ExtensiblePresentation):
+ """
+ A Relationship Template specifies the occurrence of a manageable relationship between node
+ templates as part of an application's topology model that is defined in a TOSCA Service
+ Template. A Relationship template is an instance of a specified Relationship Type and can
+ provide customized properties, constraints or operations which override the defaults provided by
+ its Relationship Type and its implementations.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_RELATIONSHIP_TEMPLATE>`__
+ """
+
+ @field_validator(type_validator('relationship type', convert_name_to_full_type_name,
+ 'relationship_types'))
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The required name of the Relationship Type the Relationship Template is based upon.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ An optional description for the Relationship Template.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def properties(self):
+ """
+ An optional list of property assignments for the Relationship Template.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`}
+ """
+
+ @object_dict_field(AttributeAssignment)
+ def attributes(self):
+ """
+ An optional list of attribute assignments for the Relationship Template.
+
+ :type: {:obj:`basestring`: :class:`AttributeAssignment`}
+ """
+
+ @object_dict_field(InterfaceAssignment)
+ def interfaces(self):
+ """
+ An optional list of named interface definitions for the Node Template.
+
+ ARIA NOTE: Spec is wrong here, should be Relationship Template.
+
+ :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
+ """
+
+ @field_validator(copy_validator('relationship template', 'relationship_templates'))
+ @primitive_field(str)
+ def copy(self):
+ """
+ The optional (symbolic) name of another relationship template to copy into (all keynames and
+ values) and use as a basis for this relationship template.
+
+ :type: :obj:`basestring`
+ """
+
+ @cachedmethod
+ def _get_default_raw(self):
+ return get_default_raw_from_copy(self, 'relationship_templates')
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.type, 'relationship_types')
+
+ @cachedmethod
+ def _get_property_values(self, context):
+ return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))
+
+ @cachedmethod
+ def _get_interfaces(self, context):
+ return FrozenDict(get_template_interfaces(context, self, 'relationship template'))
+
+ def _validate(self, context):
+ super(RelationshipTemplate, self)._validate(context)
+ self._get_property_values(context)
+ self._get_interfaces(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'type',
+ 'properties',
+ 'attributes',
+ 'interfaces',
+ 'copy'))
+
+
+@has_fields
+@implements_specification('3.7.5', 'tosca-simple-1.0')
+class GroupTemplate(ExtensiblePresentation):
+ """
+ A group definition defines a logical grouping of node templates, typically for management
+ purposes, but is separate from the application's topology template.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_GROUP_DEF>`__
+ """
+
+ @field_validator(type_validator('group type', convert_name_to_full_type_name,
+ 'group_types'))
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The required name of the group type the group definition is based upon.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the group definition.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def properties(self):
+ """
+ An optional list of property value assignments for the group definition.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`}
+ """
+
+ @field_validator(list_type_validator('node template', 'topology_template', 'node_templates'))
+ @primitive_list_field(str)
+ def members(self):
+ """
+ The optional list of one or more node template names that are members of this group
+ definition.
+
+ :type: [:obj:`basestring`]
+ """
+
+ @object_dict_field(InterfaceAssignment)
+ def interfaces(self):
+ """
+ An optional list of named interface definitions for the group definition.
+
+ :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.type, 'group_types')
+
+ @cachedmethod
+ def _get_property_values(self, context):
+ return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))
+
+ @cachedmethod
+ def _get_interfaces(self, context):
+ return FrozenDict(get_template_interfaces(context, self, 'group definition'))
+
+ def _validate(self, context):
+ super(GroupTemplate, self)._validate(context)
+ self._get_property_values(context)
+ self._get_interfaces(context)
+
+
+@has_fields
+@implements_specification('3.7.6', 'tosca-simple-1.0')
+class PolicyTemplate(ExtensiblePresentation):
+ """
+ A policy definition defines a policy that can be associated with a TOSCA topology or top-level
+ entity definition (e.g., group definition, node template, etc.).
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_POLICY_DEF>`__
+ """
+
+ @field_validator(type_validator('policy type', convert_name_to_full_type_name, 'policy_types'))
+ @primitive_field(str, required=True)
+ def type(self):
+ """
+ The required name of the policy type the policy definition is based upon.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the policy definition.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyAssignment)
+ def properties(self):
+ """
+ An optional list of property value assignments for the policy definition.
+
+ :type: {:obj:`basestring`: :class:`PropertyAssignment`
+ """
+
+ @field_validator(policy_targets_validator)
+ @primitive_list_field(str)
+ def targets(self):
+ """
+ An optional list of valid Node Templates or Groups the Policy can be applied to.
+
+ :type: [:obj:`basestring`]
+ """
+
+ @cachedmethod
+ def _get_type(self, context):
+ return get_type_by_name(context, self.type, 'policy_types')
+
+ @cachedmethod
+ def _get_property_values(self, context):
+ return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))
+
+ @cachedmethod
+ def _get_targets(self, context):
+ node_templates, groups = get_policy_targets(context, self)
+ return FrozenList(node_templates), FrozenList(groups)
+
+ def _validate(self, context):
+ super(PolicyTemplate, self)._validate(context)
+ self._get_property_values(context)
+
+
+@has_fields
+@implements_specification('3.8', 'tosca-simple-1.0')
+class TopologyTemplate(ExtensiblePresentation):
+ """
+ This section defines the topology template of a cloud application. The main ingredients of the
+ topology template are node templates representing components of the application and relationship
+ templates representing links between the components. These elements are defined in the nested
+ ``node_templates`` section and the nested relationship_templates sections, respectively.
+ Furthermore, a topology template allows for defining input parameters, output parameters as well
+ as grouping of node templates.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_TOPOLOGY_TEMPLATE>`__
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the Topology Template.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(ParameterDefinition)
+ def inputs(self):
+ """
+ An optional list of input parameters (i.e., as parameter definitions) for the Topology
+ Template.
+
+ :type: {:obj:`basestring`: :class:`ParameterDefinition`}
+ """
+
+ @object_dict_field(NodeTemplate)
+ def node_templates(self):
+ """
+ An optional list of node template definitions for the Topology Template.
+
+ :type: {:obj:`basestring`: :class:`NodeTemplate`}
+ """
+
+ @object_dict_field(RelationshipTemplate)
+ def relationship_templates(self):
+ """
+ An optional list of relationship templates for the Topology Template.
+
+ :type: {:obj:`basestring`: :class:`RelationshipTemplate`}
+ """
+
+ @object_dict_field(GroupTemplate)
+ def groups(self):
+ """
+ An optional list of Group definitions whose members are node templates defined within this
+ same Topology Template.
+
+ :class:`GroupTemplate`
+ """
+
+ @object_dict_field(PolicyTemplate)
+ def policies(self):
+ """
+ An optional list of Policy definitions for the Topology Template.
+
+ :type: {:obj:`basestring`: :class:`PolicyTemplate`}
+ """
+
+ @object_dict_field(ParameterDefinition)
+ def outputs(self):
+ """
+ An optional list of output parameters (i.e., as parameter definitions) for the Topology
+ Template.
+
+ :type: {:obj:`basestring`: :class:`ParameterDefinition`}
+ """
+
+ @object_field(SubstitutionMappings)
+ def substitution_mappings(self):
+ """
+ An optional declaration that exports the topology template as an implementation of a Node
+ type.
+
+ This also includes the mappings between the external Node Types named capabilities and
+ requirements to existing implementations of those capabilities and requirements on Node
+ templates declared within the topology template.
+ """
+
+ @cachedmethod
+ def _get_input_values(self, context):
+ return FrozenDict(get_parameter_values(context, self, 'inputs'))
+
+ @cachedmethod
+ def _get_output_values(self, context):
+ return FrozenDict(get_parameter_values(context, self, 'outputs'))
+
+ def _validate(self, context):
+ super(TopologyTemplate, self)._validate(context)
+ self._get_input_values(context)
+ self._get_output_values(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'inputs',
+ 'node_templates',
+ 'relationship_templates',
+ 'groups',
+ 'policies',
+ 'outputs',
+ 'substitution_mappings'))
+
+
+@has_fields
+@implements_specification('3.9', 'tosca-simple-1.0')
+class ServiceTemplate(ExtensiblePresentation):
+ """
+ Servicate template.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ELEMENT_SERVICE_TEMPLATE>`__.
+ """
+
+ @primitive_field(str)
+ @implements_specification('3.9.3.1', 'tosca-simple-1.0')
+ def tosca_definitions_version(self):
+ """
+ Defines the version of the TOSCA Simple Profile specification the template (grammar)
+ complies with.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #_Toc379455047>`__
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(MetaData)
+ def metadata(self):
+ """
+ Defines a section used to declare additional metadata information. Domain-specific TOSCA
+ profile specifications may define keynames that are required for their implementations.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #_Toc379455048>`__
+
+ :type: :class:`MetaData`
+ """
+
+ @object_field(Description)
+ @implements_specification('3.9.3.6', 'tosca-simple-1.0')
+ def description(self):
+ """
+ Declares a description for this Service Template and its contents.
+
+ :type: :class:`Description`
+ """
+
+ @primitive_field()
+ @implements_specification('3.9.3.7', 'tosca-simple-1.0')
+ def dsl_definitions(self):
+ """
+ Declares optional DSL-specific definitions and conventions. For example, in YAML, this
+ allows defining reusable YAML macros (i.e., YAML alias anchors) for use throughout the TOSCA
+ Service Template.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #_Toc397688790>`__
+ """
+
+ @object_dict_field(Repository)
+ @implements_specification('3.9.3.8', 'tosca-simple-1.0')
+ def repositories(self):
+ """
+ Declares the list of external repositories which contain artifacts that are referenced in
+ the service template along with their addresses and necessary credential information used to
+ connect to them in order to retrieve the artifacts.
+
+ :type: {:obj:`basestring`: :class:`Repository`}
+ """
+
+ @object_list_field(Import)
+ @implements_specification('3.9.3.9', 'tosca-simple-1.0')
+ def imports(self):
+ """
+ Declares import statements external TOSCA Definitions documents. For example, these may be
+ file location or URIs relative to the service template file within the same TOSCA CSAR file.
+
+ :type: list of :class:`Import`
+ """
+
+ @object_dict_field(ArtifactType)
+ @implements_specification('3.9.3.10', 'tosca-simple-1.0')
+ def artifact_types(self):
+ """
+ This section contains an optional list of artifact type definitions for use in the service
+ template.
+
+ :type: {:obj:`basestring`: :class:`ArtifactType`}
+ """
+
+ @object_dict_field(DataType)
+ @implements_specification('3.9.3.11', 'tosca-simple-1.0')
+ def data_types(self):
+ """
+ Declares a list of optional TOSCA Data Type definitions.
+
+ :type: {:obj:`basestring`: :class:`DataType`}
+ """
+
+ @object_dict_field(CapabilityType)
+ @implements_specification('3.9.3.12', 'tosca-simple-1.0')
+ def capability_types(self):
+ """
+ This section contains an optional list of capability type definitions for use in the service
+ template.
+
+ :type: {:obj:`basestring`: :class:`CapabilityType`}
+ """
+
+ @object_dict_field(InterfaceType)
+ @implements_specification('3.9.3.13', 'tosca-simple-1.0')
+ def interface_types(self):
+ """
+ This section contains an optional list of interface type definitions for use in the service
+ template.
+
+ :type: {:obj:`basestring`: :class:`InterfaceType`}
+ """
+
+ @object_dict_field(RelationshipType)
+ @implements_specification('3.9.3.14', 'tosca-simple-1.0')
+ def relationship_types(self):
+ """
+ This section contains a set of relationship type definitions for use in the service
+ template.
+
+ :type: {:obj:`basestring`: :class:`RelationshipType`}
+ """
+
+ @object_dict_field(NodeType)
+ @implements_specification('3.9.3.15', 'tosca-simple-1.0')
+ def node_types(self):
+ """
+ This section contains a set of node type definitions for use in the service template.
+
+ :type: {:obj:`basestring`: :class:`NodeType`}
+ """
+
+ @object_dict_field(GroupType)
+ @implements_specification('3.9.3.16', 'tosca-simple-1.0')
+ def group_types(self):
+ """
+ This section contains a list of group type definitions for use in the service template.
+
+ :type: {:obj:`basestring`: :class:`GroupType`}
+ """
+
+ @object_dict_field(PolicyType)
+ @implements_specification('3.9.3.17', 'tosca-simple-1.0')
+ def policy_types(self):
+ """
+ This section contains a list of policy type definitions for use in the service template.
+
+ :type: {:obj:`basestring`: :class:`PolicyType`}
+ """
+
+ @object_field(TopologyTemplate)
+ def topology_template(self):
+ """
+ Defines the topology template of an application or service, consisting of node templates
+ that represent the application's or service's components, as well as relationship templates
+ representing relations between the components.
+
+ :type: :class:`TopologyTemplate`
+ """
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'tosca_definitions_version',
+ 'metadata',
+ 'repositories',
+ 'imports',
+ 'artifact_types',
+ 'data_types',
+ 'capability_types',
+ 'interface_types',
+ 'relationship_types',
+ 'node_types',
+ 'group_types',
+ 'policy_types',
+ 'topology_template'))
diff --git a/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/types.py b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/types.py
new file mode 100644
index 0000000..43af44b
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/types.py
@@ -0,0 +1,892 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 aria.utils.collections import (FrozenDict, FrozenList)
+from aria.utils.caching import cachedmethod
+from aria.parser import implements_specification
+from aria.parser.presentation import (has_fields, allow_unknown_fields, primitive_field,
+ primitive_list_field, object_field, object_dict_field,
+ object_list_field, object_sequenced_list_field,
+ object_dict_unknown_fields, field_getter, field_validator,
+ list_type_validator, derived_from_validator,
+ get_parent_presentation)
+
+from .assignments import ArtifactAssignmentForType
+from .data_types import Version
+from .definitions import (PropertyDefinition, AttributeDefinition, InterfaceDefinition,
+ RequirementDefinition, CapabilityDefinition, OperationDefinition)
+from .misc import (Description, ConstraintClause)
+from .modeling.artifacts import get_inherited_artifact_definitions
+from .modeling.capabilities import (get_inherited_valid_source_types,
+ get_inherited_capability_definitions)
+from .modeling.data_types import (get_data_type, get_inherited_constraints, coerce_data_type_value,
+ validate_data_type_name)
+from .modeling.interfaces import (get_inherited_interface_definitions, get_inherited_operations)
+from .modeling.policies import get_inherited_targets
+from .modeling.parameters import get_inherited_parameter_definitions
+from .modeling.requirements import get_inherited_requirement_definitions
+from .presentation.extensible import ExtensiblePresentation
+from .presentation.field_getters import data_type_class_getter
+from .presentation.field_validators import (data_type_derived_from_validator,
+ data_type_constraints_validator,
+ data_type_properties_validator,
+ list_node_type_or_group_type_validator)
+from .presentation.types import convert_name_to_full_type_name
+
+
+
+@has_fields
+@implements_specification('3.6.3', 'tosca-simple-1.0')
+class ArtifactType(ExtensiblePresentation):
+ """
+ An Artifact Type is a reusable entity that defines the type of one or more files that are used
+ to define implementation or deployment artifacts that are referenced by nodes or relationships
+ on their operations.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_ARTIFACT_TYPE>`__
+ """
+
+ @field_validator(derived_from_validator(convert_name_to_full_type_name, 'artifact_types'))
+ @primitive_field(str)
+ def derived_from(self):
+ """
+ An optional parent Artifact Type name the Artifact Type derives from.
+
+ :type: :obj:`basestring`
+ """
+
+ @field_getter(data_type_class_getter(Version))
+ @primitive_field()
+ def version(self):
+ """
+ An optional version for the Artifact Type definition.
+
+ :type: :class:`Version`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ An optional description for the Artifact Type.
+
+ :type: :class:`Description`
+ """
+
+ @primitive_field(str)
+ def mime_type(self):
+ """
+ The required mime type property for the Artifact Type.
+
+ :type: :obj:`basestring`
+ """
+
+ @primitive_list_field(str)
+ def file_ext(self):
+ """
+ The required file extension property for the Artifact Type.
+
+ :type: [:obj:`basestring`]
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def properties(self):
+ """
+ An optional list of property definitions for the Artifact Type.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @cachedmethod
+ def _get_parent(self, context):
+ return get_parent_presentation(context, self, convert_name_to_full_type_name,
+ 'artifact_types')
+
+ @cachedmethod
+ def _get_properties(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
+
+ def _validate(self, context):
+ super(ArtifactType, self)._validate(context)
+ self._get_properties(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'version',
+ 'derived_from',
+ 'mime_type',
+ 'file_ext',
+ 'properties'))
+
+
+@has_fields
+@implements_specification('3.6.5', 'tosca-simple-1.0')
+class DataType(ExtensiblePresentation):
+ """
+ A Data Type definition defines the schema for new named datatypes in TOSCA.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_DATA_TYPE>`__
+ """
+
+ @field_validator(data_type_derived_from_validator)
+ @primitive_field(str)
+ def derived_from(self):
+ """
+ The optional key used when a datatype is derived from an existing TOSCA Data Type.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Version)
+ def version(self):
+ """
+ An optional version for the Data Type definition.
+
+ :type: :class:`Version`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the Data Type.
+
+ :type: :class:`Description`
+ """
+
+ @field_validator(data_type_constraints_validator)
+ @object_list_field(ConstraintClause)
+ def constraints(self):
+ """
+ The optional list of sequenced constraint clauses for the Data Type.
+
+ :type: list of (str, :class:`ConstraintClause`)
+ """
+
+ @field_validator(data_type_properties_validator)
+ @object_dict_field(PropertyDefinition)
+ def properties(self):
+ """
+ The optional list property definitions that comprise the schema for a complex Data Type in
+ TOSCA.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @cachedmethod
+ def _get_parent(self, context):
+ return get_data_type(context, self, 'derived_from', allow_none=True)
+
+ @cachedmethod
+ def _is_descendant(self, context, the_type):
+ if the_type is None:
+ return False
+ if not hasattr(the_type, '_name'):
+ # Must be a primitive type
+ return self._get_primitive_ancestor(context) == the_type
+ if the_type._name == self._name:
+ return True
+ return self._is_descendant(context, the_type._get_parent(context))
+
+ @cachedmethod
+ def _get_primitive_ancestor(self, context):
+ parent = self._get_parent(context)
+ if parent is not None:
+ if not isinstance(parent, DataType):
+ return parent
+ else:
+ return parent._get_primitive_ancestor(context) # pylint: disable=no-member
+ return None
+
+ @cachedmethod
+ def _get_properties(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
+
+ @cachedmethod
+ def _get_constraints(self, context):
+ return get_inherited_constraints(context, self)
+
+ def _validate(self, context):
+ super(DataType, self)._validate(context)
+ validate_data_type_name(context, self)
+ self._get_properties(context)
+
+ def _coerce_value(self, context, presentation, entry_schema, constraints, value, aspect):
+ return coerce_data_type_value(context, presentation, self, entry_schema, constraints, value,
+ aspect)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'version',
+ 'derived_from',
+ 'constraints',
+ 'properties'))
+
+
+@has_fields
+@implements_specification('3.6.6', 'tosca-simple-1.0')
+class CapabilityType(ExtensiblePresentation):
+ """
+ A Capability Type is a reusable entity that describes a kind of capability that a Node Type can
+ declare to expose. Requirements (implicit or explicit) that are declared as part of one node can
+ be matched to (i.e., fulfilled by) the Capabilities declared by another node.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_CAPABILITY_TYPE>`__
+ """
+
+ @field_validator(derived_from_validator(convert_name_to_full_type_name, 'capability_types'))
+ @primitive_field(str)
+ def derived_from(self):
+ """
+ An optional parent capability type name this new Capability Type derives from.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Version)
+ def version(self):
+ """
+ An optional version for the Capability Type definition.
+
+ :type: :class:`Version`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ An optional description for the Capability Type.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def properties(self):
+ """
+ An optional list of property definitions for the Capability Type.
+
+ ARIA NOTE: The spec says 'list', but the examples are all of dicts.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @object_dict_field(AttributeDefinition)
+ def attributes(self):
+ """
+ An optional list of attribute definitions for the Capability Type.
+
+ :type: {:obj:`basestring`: :class:`AttributeDefinition`}
+ """
+
+ @field_validator(list_type_validator('node type', convert_name_to_full_type_name, 'node_types'))
+ @primitive_list_field(str)
+ def valid_source_types(self):
+ """
+ An optional list of one or more valid names of Node Types that are supported as valid
+ sources of any relationship established to the declared Capability Type.
+
+ :type: [:obj:`basestring`]
+ """
+
+ @cachedmethod
+ def _get_parent(self, context):
+ return get_parent_presentation(context, self, convert_name_to_full_type_name,
+ 'capability_types')
+
+ @cachedmethod
+ def _is_descendant(self, context, other_type):
+ """returns True iff `other_type` is a descendant of the represented capability type"""
+ if other_type is None:
+ return False
+ elif other_type._name == self._name:
+ return True
+ return self._is_descendant(context, other_type._get_parent(context))
+
+ @cachedmethod
+ def _get_properties(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
+
+ @cachedmethod
+ def _get_valid_source_types(self, context):
+ return get_inherited_valid_source_types(context, self)
+
+ def _validate(self, context):
+ super(CapabilityType, self)._validate(context)
+ self._get_properties(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'version',
+ 'derived_from',
+ 'valid_source_types',
+ 'properties',
+ 'attributes'))
+
+
+@allow_unknown_fields
+@has_fields
+@implements_specification('3.6.4', 'tosca-simple-1.0')
+class InterfaceType(ExtensiblePresentation):
+ """
+ An Interface Type is a reusable entity that describes a set of operations that can be used to
+ interact with or manage a node or relationship in a TOSCA topology.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_INTERFACE_TYPE>`__
+ """
+
+ @field_validator(derived_from_validator(convert_name_to_full_type_name, 'interface_types'))
+ @primitive_field(str)
+ def derived_from(self):
+ """
+ An optional parent Interface Type name this new Interface Type derives from.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Version)
+ def version(self):
+ """
+ An optional version for the Interface Type definition.
+
+ :type: :class:`Version`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ An optional description for the Interface Type.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def inputs(self):
+ """
+ The optional list of input parameter definitions.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @object_dict_unknown_fields(OperationDefinition)
+ def operations(self):
+ """
+ :type: {:obj:`basestring`: :class:`OperationDefinition`}
+ """
+
+ @cachedmethod
+ def _get_parent(self, context):
+ return get_parent_presentation(context, self, convert_name_to_full_type_name,
+ 'interface_types')
+
+ @cachedmethod
+ def _is_descendant(self, context, the_type):
+ if the_type is None:
+ return False
+ elif the_type._name == self._name:
+ return True
+ return self._is_descendant(context, the_type._get_parent(context))
+
+ @cachedmethod
+ def _get_inputs(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'inputs'))
+
+ @cachedmethod
+ def _get_operations(self, context):
+ return FrozenDict(get_inherited_operations(context, self))
+
+ def _validate(self, context):
+ super(InterfaceType, self)._validate(context)
+ self._get_inputs(context)
+ for operation in self.operations.itervalues(): # pylint: disable=no-member
+ operation._validate(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'version',
+ 'derived_from',
+ 'inputs',
+ 'operations'))
+
+
+@has_fields
+@implements_specification('3.6.9', 'tosca-simple-1.0')
+class RelationshipType(ExtensiblePresentation):
+ """
+ A Relationship Type is a reusable entity that defines the type of one or more relationships
+ between Node Types or Node Templates.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_RELATIONSHIP_TYPE>`__
+ """
+
+ @field_validator(derived_from_validator(convert_name_to_full_type_name, 'relationship_types'))
+ @primitive_field(str)
+ def derived_from(self):
+ """
+ An optional parent Relationship Type name the Relationship Type derives from.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Version)
+ def version(self):
+ """
+ An optional version for the Relationship Type definition.
+
+ :type: :class:`Version`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ An optional description for the Relationship Type.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def properties(self):
+ """
+ An optional list of property definitions for the Relationship Type.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @object_dict_field(AttributeDefinition)
+ def attributes(self):
+ """
+ An optional list of attribute definitions for the Relationship Type.
+
+ :type: {:obj:`basestring`: :class:`AttributeDefinition`}
+ """
+
+ @object_dict_field(InterfaceDefinition)
+ def interfaces(self):
+ """
+ An optional list of interface definitions interfaces supported by the Relationship Type.
+
+ :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
+ """
+
+ @field_validator(list_type_validator('capability type', convert_name_to_full_type_name,
+ 'capability_types'))
+ @primitive_list_field(str)
+ def valid_target_types(self):
+ """
+ An optional list of one or more names of Capability Types that are valid targets for this
+ relationship.
+
+ :type: [:obj:`basestring`]
+ """
+
+ @cachedmethod
+ def _get_parent(self, context):
+ return get_parent_presentation(context, self, convert_name_to_full_type_name,
+ 'relationship_types')
+
+ @cachedmethod
+ def _is_descendant(self, context, the_type):
+ if the_type is None:
+ return False
+ elif the_type._name == self._name:
+ return True
+ return self._is_descendant(context, the_type._get_parent(context))
+
+ @cachedmethod
+ def _get_properties(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
+
+ @cachedmethod
+ def _get_attributes(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'attributes'))
+
+ @cachedmethod
+ def _get_interfaces(self, context):
+ return FrozenDict(get_inherited_interface_definitions(context, self, 'relationship type'))
+
+ def _validate(self, context):
+ super(RelationshipType, self)._validate(context)
+ self._get_properties(context)
+ self._get_attributes(context)
+ self._get_interfaces(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'version',
+ 'derived_from',
+ 'valid_target_types',
+ 'properties',
+ 'attributes',
+ 'interfaces'))
+
+
+@has_fields
+@implements_specification('3.6.8', 'tosca-simple-1.0')
+class NodeType(ExtensiblePresentation):
+ """
+ A Node Type is a reusable entity that defines the type of one or more Node Templates. As such, a
+ Node Type defines the structure of observable properties via a Properties Definition, the
+ Requirements and Capabilities of the node as well as its supported interfaces.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_NODE_TYPE>`__
+ """
+
+ @field_validator(derived_from_validator(convert_name_to_full_type_name, 'node_types'))
+ @primitive_field(str)
+ def derived_from(self):
+ """
+ An optional parent Node Type name this new Node Type derives from.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Version)
+ def version(self):
+ """
+ An optional version for the Node Type definition.
+
+ :type: :class:`Version`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ An optional description for the Node Type.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def properties(self):
+ """
+ An optional list of property definitions for the Node Type.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @object_dict_field(AttributeDefinition)
+ def attributes(self):
+ """
+ An optional list of attribute definitions for the Node Type.
+
+ :type: {:obj:`basestring`: :class:`AttributeDefinition`}
+ """
+
+ @object_sequenced_list_field(RequirementDefinition)
+ def requirements(self):
+ """
+ An optional sequenced list of requirement definitions for the Node Type.
+
+ ARIA NOTE: The spec seems wrong to make this a sequenced list. It seems that when you have
+ more than one requirement of the same name, behavior is undefined. The idea is to use the
+ "occurrences" field if you need to limit the number of requirement assignments.
+
+ :type: list of (str, :class:`RequirementDefinition`)
+ """
+
+ @object_dict_field(CapabilityDefinition)
+ def capabilities(self):
+ """
+ An optional list of capability definitions for the Node Type.
+
+ :type: list of :class:`CapabilityDefinition`
+ """
+
+ @object_dict_field(InterfaceDefinition)
+ def interfaces(self):
+ """
+ An optional list of interface definitions supported by the Node Type.
+
+ :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
+ """
+
+ @object_dict_field(ArtifactAssignmentForType)
+ def artifacts(self):
+ """
+ An optional list of named artifact definitions for the Node Type.
+
+ :type: {:obj:`basestring`: :class:`ArtifactAssignmentForType`}
+ """
+
+ @cachedmethod
+ def _get_parent(self, context):
+ return get_parent_presentation(context, self, convert_name_to_full_type_name, 'node_types')
+
+ @cachedmethod
+ def _is_descendant(self, context, the_type):
+ if the_type is None:
+ return False
+ elif the_type._name == self._name:
+ return True
+ return self._is_descendant(context, the_type._get_parent(context))
+
+ @cachedmethod
+ def _get_properties(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
+
+ @cachedmethod
+ def _get_attributes(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'attributes'))
+
+ @cachedmethod
+ def _get_requirements(self, context):
+ return FrozenList(get_inherited_requirement_definitions(context, self))
+
+ @cachedmethod
+ def _get_capabilities(self, context):
+ return FrozenDict(get_inherited_capability_definitions(context, self))
+
+ @cachedmethod
+ def _get_interfaces(self, context):
+ return FrozenDict(get_inherited_interface_definitions(context, self, 'node type'))
+
+ @cachedmethod
+ def _get_artifacts(self, context):
+ return FrozenDict(get_inherited_artifact_definitions(context, self))
+
+ def _validate(self, context):
+ super(NodeType, self)._validate(context)
+ self._get_properties(context)
+ self._get_attributes(context)
+ self._get_requirements(context)
+ self._get_capabilities(context)
+ self._get_interfaces(context)
+ self._get_artifacts(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'version',
+ 'derived_from',
+ 'properties',
+ 'attributes',
+ 'interfaces',
+ 'artifacts',
+ 'requirements',
+ 'capabilities'))
+
+
+@has_fields
+@implements_specification('3.6.10', 'tosca-simple-1.0')
+class GroupType(ExtensiblePresentation):
+ """
+ A Group Type defines logical grouping types for nodes, typically for different management
+ purposes. Groups can effectively be viewed as logical nodes that are not part of the physical
+ deployment topology of an application, yet can have capabilities and the ability to attach
+ policies and interfaces that can be applied (depending on the group type) to its member nodes.
+
+ Conceptually, group definitions allow the creation of logical "membership" relationships to
+ nodes in a service template that are not a part of the application's explicit requirement
+ dependencies in the topology template (i.e. those required to actually get the application
+ deployed and running). Instead, such logical membership allows for the introduction of things
+ such as group management and uniform application of policies (i.e., requirements that are also
+ not bound to the application itself) to the group's members.
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_GROUP_TYPE>`__
+ """
+
+ @field_validator(derived_from_validator(convert_name_to_full_type_name, 'group_types'))
+ @primitive_field(str)
+ def derived_from(self):
+ """
+ An optional parent Group Type name the Group Type derives from.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Version)
+ def version(self):
+ """
+ An optional version for the Group Type definition.
+
+ :type: :class:`Version`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the Group Type.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def properties(self):
+ """
+ An optional list of property definitions for the Group Type.
+
+ :type: {:obj:`basestring`: :class:`PropertyDefinition`}
+ """
+
+ @field_validator(list_type_validator('node type', convert_name_to_full_type_name, 'node_types'))
+ @primitive_list_field(str)
+ def members(self):
+ """
+ An optional list of one or more names of Node Types that are valid (allowed) as members of
+ the Group Type.
+
+ Note: This can be viewed by TOSCA Orchestrators as an implied relationship from the listed
+ members nodes to the group, but one that does not have operational lifecycle considerations.
+ For example, if we were to name this as an explicit Relationship Type we might call this
+ "MemberOf" (group).
+
+ :type: [:obj:`basestring`]
+ """
+
+ @object_dict_field(InterfaceDefinition)
+ def interfaces(self):
+ """
+ An optional list of interface definitions supported by the Group Type.
+
+ :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
+ """
+
+ @cachedmethod
+ def _get_parent(self, context):
+ return get_parent_presentation(context, self, convert_name_to_full_type_name,
+ 'group_types')
+
+ @cachedmethod
+ def _is_descendant(self, context, the_type):
+ if the_type is None:
+ return False
+ elif the_type._name == self._name:
+ return True
+ return self._is_descendant(context, the_type._get_parent(context))
+
+ @cachedmethod
+ def _get_properties(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
+
+ @cachedmethod
+ def _get_interfaces(self, context):
+ return FrozenDict(get_inherited_interface_definitions(context, self, 'group type'))
+
+ def _validate(self, context):
+ super(GroupType, self)._validate(context)
+ self._get_properties(context)
+ self._get_interfaces(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'version',
+ 'derived_from',
+ 'members',
+ 'properties',
+ 'interfaces'))
+
+
+@has_fields
+@implements_specification('3.6.11', 'tosca-simple-1.0')
+class PolicyType(ExtensiblePresentation):
+ """
+ A Policy Type defines a type of requirement that affects or governs an application or service's
+ topology at some stage of its lifecycle, but is not explicitly part of the topology itself
+ (i.e., it does not prevent the application or service from being deployed or run if it did not
+ exist).
+
+ See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+ /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
+ #DEFN_ENTITY_POLICY_TYPE>`__
+ """
+
+ @field_validator(derived_from_validator(convert_name_to_full_type_name, 'policy_types'))
+ @primitive_field(str)
+ def derived_from(self):
+ """
+ An optional parent Policy Type name the Policy Type derives from.
+
+ :type: :obj:`basestring`
+ """
+
+ @object_field(Version)
+ def version(self):
+ """
+ An optional version for the Policy Type definition.
+
+ :type: :class:`Version`
+ """
+
+ @object_field(Description)
+ def description(self):
+ """
+ The optional description for the Policy Type.
+
+ :type: :class:`Description`
+ """
+
+ @object_dict_field(PropertyDefinition)
+ def properties(self):
+ """
+ An optional list of property definitions for the Policy Type.
+
+ :type: :class:`PropertyDefinition`
+ """
+
+ @field_validator(list_node_type_or_group_type_validator)
+ @primitive_list_field(str)
+ def targets(self):
+ """
+ An optional list of valid Node Types or Group Types the Policy Type can be applied to.
+
+ Note: This can be viewed by TOSCA Orchestrators as an implied relationship to the target
+ nodes, but one that does not have operational lifecycle considerations. For example, if we
+ were to name this as an explicit Relationship Type we might call this "AppliesTo" (node or
+ group).
+
+ :type: [:obj:`basestring`]
+ """
+
+ @cachedmethod
+ def _get_parent(self, context):
+ return get_parent_presentation(context, self, convert_name_to_full_type_name,
+ 'policy_types')
+
+ @cachedmethod
+ def _get_properties(self, context):
+ return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
+
+ @cachedmethod
+ def _get_targets(self, context):
+ node_types, group_types = get_inherited_targets(context, self)
+ return FrozenList(node_types), FrozenList(group_types)
+
+ def _validate(self, context):
+ super(PolicyType, self)._validate(context)
+ self._get_properties(context)
+
+ def _dump(self, context):
+ self._dump_content(context, (
+ 'description',
+ 'version',
+ 'derived_from',
+ 'targets',
+ 'properties'))