2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
22 """ Allowed types for the Attribute value
32 """ Flags to characterize the scope of an Attribute
34 # Attribute value can not be read (it is hidden to the user)
37 # Attribute value can not be modified (it is not editable by the user)
40 # Attribute value can be modified only before deployment
43 # Attribute value will be used at deployment time for initial configuration
44 Construct = 1 << 3 # 8
46 # Attribute provides credentials to access resources
47 Credential = 1 << 4 | Design # 16 + 4
49 # Attribute is a filter used to discover resources
50 Filter = 1 << 5 | Design # 32 + 4
52 # Attribute Flag is reserved for internal RM usage (i.e. should be
53 # transparent to the user)
54 Reserved = 1 << 6 # 64
56 # Attribute global is set to all resources of rtype
60 class Attribute(object):
61 """ An Attribute exposes a configuration parameter of a resource
64 def __init__(self, name, help, type = Types.String,
65 flags = None, default = None, allowed = None,
66 range = None, set_hook = None):
68 :param name: Name of the Attribute
71 :param help: Description of the Attribute
74 :param type: The type expected for the Attribute value.
75 Should be one of Attribute.Types
78 :param flags: Defines Attribute behavior (i.e. whether it is read-only,
79 read and write, etc). This parameter must take its values from
80 Attribute.Flags. Flags values can be bitwised
83 :param default: Default value for the Attribute
84 :type default: Depends on the type of Attribute
86 :param allowed: List of values that the Attribute can take.
87 This parameter is only meaningful for Enumerate type Attributes
90 :param range: (max, min) tuple with range of possible values for
92 This parameter is only meaningful for Integer or Double type
94 :type range: (int, int) or (float, float)
96 :param set_hook: Function that will be executed whenever a new
97 value is set for the Attribute.
98 :type set_hook: function
104 self._flags = flags or 0
105 self._allowed = allowed
107 self._default = self._value = default
108 # callback to be invoked upon changing the
110 self.set_hook = set_hook
114 """ Returns the name of the Attribute """
119 """ Returns the default value of the Attribute """
124 """ Returns the type of the Attribute """
129 """ Returns the description of the Attribute """
134 """ Returns the flags of the Attribute """
139 """ Returns the set of allowed values for the Attribute """
144 """ Returns the range of allowed numerical values for the Attribute """
147 def has_flag(self, flag):
148 """ Returns True if the Attribute has the flag 'flag'
150 :param flag: Flag to be checked
153 return (self._flags & flag) == flag
156 """ Returns the value of the Attribute """
159 def set_value(self, value):
160 """ Configure a new value for the Attribute """
163 if self.type == Types.Enumerate:
164 valid = value in self._allowed
166 if self.type in [Types.Double, Types.Integer] and self.range:
167 (min, max) = self.range
171 valid = (value >= min and value <= max)
173 valid = valid and self.is_valid_value(value)
177 # Hook receives old value, new value
178 value = self.set_hook(self._value, value)
182 raise ValueError("Invalid value %s for attribute %s" %
183 (str(value), self.name))
185 value = property(get_value, set_value)
187 def is_valid_value(self, value):
188 """ Attribute subclasses will override this method to add
189 adequate validation"""
193 def has_changed(self):
194 """ Returns True if the value has changed from the default """
195 return self.value != self.default