1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements. See the NOTICE file distributed with
3 # this work for additional information regarding copyright ownership.
4 # The ASF licenses this file to You under the Apache License, Version 2.0
5 # (the "License"); you may not use this file except in compliance with
6 # the License. You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
18 from aria.modeling.constraints import NodeTemplateConstraint
19 from aria.modeling.utils import NodeTemplateContainerHolder
20 from aria.modeling.functions import evaluate
21 from aria.parser import implements_specification
24 @implements_specification('3.5.2-2', 'tosca-simple-1.0')
25 class EvaluatingNodeTemplateConstraint(NodeTemplateConstraint):
27 A version of :class:`NodeTemplateConstraint` with boilerplate initialization for TOSCA
31 def __init__(self, property_name, capability_name, constraint, as_list=False):
32 self.property_name = property_name
33 self.capability_name = capability_name
34 self.constraint = constraint
35 self.as_list = as_list
37 def matches(self, source_node_template, target_node_template):
38 # TOSCA node template constraints can refer to either capability properties or node
40 if self.capability_name is not None:
42 capability = target_node_template.capability_templates.get(self.capability_name)
43 value = capability.properties.get(self.property_name) \
44 if capability is not None else None # Parameter
46 # Node template property
47 value = target_node_template.properties.get(self.property_name) # Parameter
49 value = value.value if value is not None else None
51 container_holder = NodeTemplateContainerHolder(source_node_template)
55 for constraint in self.constraint:
56 evaluation = evaluate(constraint, container_holder)
57 if evaluation is not None:
58 constraints.append(evaluation.value)
60 constraints.append(constraint)
61 constraint = constraints
63 evaluation = evaluate(self.constraint, container_holder)
64 if evaluation is not None:
65 constraint = evaluation.value
67 constraint = self.constraint
69 return self.matches_evaluated(value, constraint)
71 def matches_evaluated(self, value, constraint):
72 raise NotImplementedError
75 class Equal(EvaluatingNodeTemplateConstraint):
76 def matches_evaluated(self, value, constraint):
77 return value == constraint
80 class GreaterThan(EvaluatingNodeTemplateConstraint):
81 def matches_evaluated(self, value, constraint):
82 return value > constraint
85 class GreaterOrEqual(EvaluatingNodeTemplateConstraint):
86 def matches_evaluated(self, value, constraint):
87 return value >= constraint
90 class LessThan(EvaluatingNodeTemplateConstraint):
91 def matches_evaluated(self, value, constraint):
92 return value < constraint
95 class LessOrEqual(EvaluatingNodeTemplateConstraint):
96 def matches_evaluated(self, value, constraint):
97 return value <= constraint
100 class InRange(EvaluatingNodeTemplateConstraint):
101 def __init__(self, property_name, capability_name, constraint):
102 super(InRange, self).__init__(property_name, capability_name, constraint, as_list=True)
104 def matches_evaluated(self, value, constraints):
105 lower, upper = constraints
108 if (upper != 'UNBOUNDED') and (value > upper):
113 class ValidValues(EvaluatingNodeTemplateConstraint):
114 def __init__(self, property_name, capability_name, constraint):
115 super(ValidValues, self).__init__(property_name, capability_name, constraint, as_list=True)
117 def matches_evaluated(self, value, constraints):
118 return value in constraints
121 class Length(EvaluatingNodeTemplateConstraint):
122 def matches_evaluated(self, value, constraint):
123 return len(value) == constraint
126 class MinLength(EvaluatingNodeTemplateConstraint):
127 def matches_evaluated(self, value, constraint):
128 return len(value) >= constraint
131 class MaxLength(EvaluatingNodeTemplateConstraint):
132 def matches_evaluated(self, value, constraint):
133 return len(value) <= constraint
136 class Pattern(EvaluatingNodeTemplateConstraint):
137 def matches_evaluated(self, value, constraint):
138 # From TOSCA 1.0 3.5.2.1:
140 # "Note: Future drafts of this specification will detail the use of regular expressions and
141 # reference an appropriate standardized grammar."
143 # So we will just use Python's.
144 return re.match(constraint, unicode(value)) is not None