Adding PlanetLab resources
[nepi.git] / src / nepi / execution / attribute.py
1 """
2     NEPI, a framework to manage network experiments
3     Copyright (C) 2013 INRIA
4
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.
9
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.
14
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/>.
17
18 """
19
20 ### Attribute Types
21 class Types:
22     String  = "STRING"
23     Bool    = "BOOL"
24     Enumerate    = "ENUM"
25     Double  = "DOUBLE"
26     Integer = "INTEGER"
27
28 ### Attribute Flags
29 class Flags:
30     # Attribute can be modified by the user 
31     NoFlags         = 0x00
32     # Attribute is not modifiable by the user
33     ReadOnly        = 0x01
34     # Attribute is not modifiable by the user during runtime
35     ExecReadOnly        = 0x02
36     # Attribute is an access credential
37     Credential      = 0x04
38     # Attribute is a filter used to discover resources
39     Filter      = 0x08
40
41 class Attribute(object):
42     def __init__(self, name, help, type = Types.String,
43             flags = Flags.NoFlags, default = None, allowed = None,
44             range = None, set_hook = None):
45         self._name = name
46         self._help = help
47         self._type = type
48         self._flags = flags
49         self._allowed = allowed
50         self._range = range
51         self._default = self._value = default
52         # callback to be invoked upon changing the 
53         # attribute value
54         self.set_hook = set_hook
55
56     @property
57     def name(self):
58         return self._name
59
60     @property
61     def default(self):
62         return self._default
63
64     @property
65     def type(self):
66         return self._type
67
68     @property
69     def help(self):
70         return self._help
71
72     @property
73     def flags(self):
74         return self._flags
75
76     @property
77     def allowed(self):
78         return self._allowed
79
80     @property
81     def range(self):
82         return self._range
83
84     def has_flag(self, flag):
85         return (self._flags & flag) == flag
86
87     def get_value(self):
88         return self._value
89
90     def set_value(self, value):
91         valid = True
92
93         if self.type == Types.Enumerate:
94             valid = value in self._allowed
95
96         if self.type in [Types.Double, Types.Integer] and self.range:
97             (min, max) = self.range
98             valid = (value >= min and value <= max) 
99         
100         valid = valid and self.is_valid_value(value)
101
102         if valid: 
103             if self.set_hook:
104                 # Hook receives old value, new value
105                 value = self.set_hook(self._value, value)
106
107             self._value = value
108         else:
109             raise ValueError("Invalid value %s for attribute %s" %
110                     (str(value), self.name))
111
112     value = property(get_value, set_value)
113
114     def is_valid_value(self, value):
115         """ Attribute subclasses will override this method to add 
116         adequate validation"""
117         return True
118