added support for slinkspecs
[sfa.git] / geni / util / specdict.py
1 ##
2 # SpecDict
3 #
4 # SpecDict defines a means for converting a dictionary with plc specific keys
5 # to a dict with rspec specific keys. 
6 #
7 # SpecDict.fields dict defines all the rspec specific attribute and their 
8 # expected type. 
9
10 # SpecDict.plc_fields defines a one to one mapping of plc attribute to rspec 
11 # attribute
12
13 from types import StringTypes, ListType
14
15
16 class SpecDict(dict):
17     """
18     Base class of SpecDict objects. 
19     """
20     fields = {}
21     plc_fields = {}
22     type = None
23         
24     def __init__(self, spec_dict):
25         # convert plc dict and initialize self
26         sdict = self.plcToSpec(spec_dict)
27         dict.__init__(self, sdict)
28
29
30     def plcToSpec(self, spec_dict):
31         """
32         Defines how to convert a plc dict to rspec dict
33         """
34         spec = {}
35         for field in self.fields:
36             value = ""
37             expected = self.fields[field]
38             if isinstance(expected, StringTypes):
39                 if self.plc_fields.has_key(field):
40                     plc_field = self.plc_fields[field]
41                     if spec_dict.has_key(plc_field):
42                         value = spec_dict[plc_field]
43             elif isinstance(expected, ListType):
44                 expected = expected[0]
45                 if self.plc_fields.has_key(field):
46                     plc_field = self.plc_fields[field]
47                     if spec_dict.has_key(plc_field):
48                         value = [expected(value) for value in spec_dict[plc_field]]
49             spec[field] = value
50         return {self.type: spec}
51
52 #
53 # fields = { geni_field:  type.  Could be class for nested classes, otherwise prob str}
54 # plc_fields = {geni_field : plc_field}
55 #
56  
57 class IfSpecDict(SpecDict):
58     type = 'IfSpec'
59     fields = {'name': '',
60               'addr': '',
61               'type': '',
62               'init_params': '',
63               'min_rate': '',
64               'max_rate': '',
65               'max_kbyte': '',
66               'ip_spoof': ''}
67     plc_fields = {'name': 'is_primary', # XXX needs munging to return name instead of True or False
68                  'addr': 'ip',
69                  'type': 'type'}
70  
71 class LinkSpecDict(SpecDict):
72     type = 'LinkSpec'
73     fields = {'min_alloc': '', 
74               'max_alloc': '', 
75               'type': '', 
76               'start_time': '', 
77               'bw': '', 
78               'duration': '', 
79               'init_params': '',
80               'endpoints': [IfSpecDict]}
81     plc_fields = {'min_alloc': 'min_alloc',
82               'max_alloc': 'max_alloc', 
83               'type': 'type', 
84               'start_time': 'start_time', 
85               'bw': 'bw', 
86               'duration': 'duration', 
87               'init_params': 'init_params',
88               'endpoints': 'endpoints'}
89   
90             
91 class NodeSpecDict(SpecDict):
92     type = 'NodeSpec'
93     fields = {'name': '',
94               'type': '',
95               'init_params': '',
96               'cpu_min': '',
97               'cpu_share': '',
98               'cpu_pct': '',
99               'disk_max': '',
100               'start_time': '',
101               'duration': '',
102               'net_if': [IfSpecDict]}
103
104     plc_fields = {'name': 'hostname',
105                   'net_if': 'interfaces'}  
106
107 class NetSpecDict(SpecDict):
108     type = 'NetSpec'
109     fields = {'name': '',
110               'start_time': '',
111               'duration': '',
112               'nodes': [NodeSpecDict],
113               'links': [LinkSpecDict],
114              }
115     plc_fields = {'name': 'name',
116                   'start_time': 'start_time',
117                   'duration': 'duration',
118                   'nodes': 'nodes',
119                   'links': 'links'}
120
121 class RspecDict(SpecDict):
122     type = 'RSpec'
123     fields = {'start_time': '',
124               'duration': '',
125               'networks': [NetSpecDict]
126              }
127     plc_fields = {'networks': 'networks',
128                   'start_time': 'start_tim',
129                   'duration': 'duration'
130                  }
131
132 # vim:ts=4:expandtab