summaryrefslogtreecommitdiffstats
path: root/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/constraints.py
diff options
context:
space:
mode:
Diffstat (limited to 'azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/constraints.py')
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/modeling/constraints.py144
1 files changed, 144 insertions, 0 deletions
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