diff options
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.py | 144 |
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 |