blob: 9a30cc11f2815a8fed70d9207422db58b53f9498 [file] [log] [blame]
# 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