Source code for nepi.execution.attribute

#
#    NEPI, a framework to manage network experiments
#    Copyright (C) 2013 INRIA
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 2 as
#    published by the Free Software Foundation;
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Author: Alina Quereilhac <alina.quereilhac@inria.fr>

### Attribute Types
[docs]class Types: """ Allowed types for the Attribute value """ String = "STRING" Bool = "BOOL" Enumerate = "ENUM" Double = "DOUBLE" Integer = "INTEGER" ### Attribute Flags
[docs]class Flags: """ Flags to characterize the scope of an Attribute """ # Attribute value can not be read (it is hidden to the user) NoRead = 1 # 1 # Attribute value can not be modified (it is not editable by the user) NoWrite = 1 << 1 # 2 # Attribute value can be modified only before deployment Design = 1 << 2 # 4 # Attribute value will be used at deployment time for initial configuration Construct = 1 << 3 # 8 # Attribute provides credentials to access resources Credential = 1 << 4 | Design # 16 + 4 # Attribute is a filter used to discover resources Filter = 1 << 5 | Design # 32 + 4 # Attribute Flag is reserved for internal RM usage (i.e. should be # transparent to the user) Reserved = 1 << 6 # 64 # Attribute global is set to all resources of rtype Global = 1 << 7 # 128
[docs]class Attribute(object): """ An Attribute exposes a configuration parameter of a resource """ def __init__(self, name, help, type = Types.String, flags = None, default = None, allowed = None, range = None, set_hook = None): """ :param name: Name of the Attribute :type name: str :param help: Description of the Attribute :type help: str :param type: The type expected for the Attribute value. Should be one of Attribute.Types :type type: str :param flags: Defines Attribute behavior (i.e. whether it is read-only, read and write, etc). This parameter must take its values from Attribute.Flags. Flags values can be bitwised :type flags: hex :param default: Default value for the Attribute :type default: Depends on the type of Attribute :param allowed: List of values that the Attribute can take. This parameter is only meaningful for Enumerate type Attributes :type allowed: list :param range: (max, min) tuple with range of possible values for Attributes. This parameter is only meaningful for Integer or Double type Attributes :type range: (int, int) or (float, float) :param set_hook: Function that will be executed whenever a new value is set for the Attribute. :type set_hook: function """ self._name = name self._help = help self._type = type self._flags = flags or 0 self._allowed = allowed self._range = range self._default = self._value = default # callback to be invoked upon changing the # attribute value self.set_hook = set_hook @property
[docs] def name(self): """ Returns the name of the Attribute """ return self._name
@property
[docs] def default(self): """ Returns the default value of the Attribute """ return self._default
@property
[docs] def type(self): """ Returns the type of the Attribute """ return self._type
@property
[docs] def help(self): """ Returns the description of the Attribute """ return self._help
@property
[docs] def flags(self): """ Returns the flags of the Attribute """ return self._flags
@property
[docs] def allowed(self): """ Returns the set of allowed values for the Attribute """ return self._allowed
@property
[docs] def range(self): """ Returns the range of allowed numerical values for the Attribute """ return self._range
[docs] def has_flag(self, flag): """ Returns True if the Attribute has the flag 'flag' :param flag: Flag to be checked :type flag: Flags """ return (self._flags & flag) == flag
[docs] def get_value(self): """ Returns the value of the Attribute """ return self._value
[docs] def set_value(self, value): """ Configure a new value for the Attribute """ valid = True if self.type == Types.Enumerate: valid = value in self._allowed if self.type in [Types.Double, Types.Integer] and self.range: (min, max) = self.range value = float(value) valid = (value >= min and value <= max) valid = valid and self.is_valid_value(value) if valid: if self.set_hook: # Hook receives old value, new value value = self.set_hook(self._value, value) self._value = value else: raise ValueError("Invalid value %s for attribute %s" % (str(value), self.name))
value = property(get_value, set_value)
[docs] def is_valid_value(self, value): """ Attribute subclasses will override this method to add adequate validation""" return True
@property
[docs] def has_changed(self): """ Returns True if the value has changed from the default """ return self.value != self.default