a31c11e269006b8bb5d658a4d046a05e399135cb
[sfa.git] / sfa / managers / aggregate_manager_openflow.py
1 import sys
2
3 import socket
4 import struct
5
6 #The following is not essential
7 #from soaplib.wsgi_soap import SimpleWSGISoapApp
8 #from soaplib.serializers.primitive import *
9 #from soaplib.serializers.clazz import *
10
11 from sfa.util.faults import *
12 from sfa.util.xrn import urn_to_hrn
13 from sfa.util.rspec import RSpec
14 from sfa.server.registry import Registries
15 from sfa.util.config import Config
16 from sfa.plc.nodes import *
17 from sfa.util.callids import Callids
18
19 # Message IDs for all the SFA light calls
20 # This will be used by the aggrMgr controller
21 SFA_GET_RESOURCES = 101
22 SFA_CREATE_SLICE = 102
23 SFA_START_SLICE = 103
24 SFA_STOP_SLICE = 104
25 SFA_DELETE_SLICE = 105
26 SFA_GET_SLICES = 106
27 SFA_RESET_SLICES = 107
28
29 DEBUG = 1
30
31 def print_buffer(buf):
32     for i in range(0,len(buf)):
33         print('%x' % buf[i])
34
35 def extract(sock):
36     # Shud we first obtain the message length?
37     # msg_len = socket.ntohs(sock.recv(2))
38     msg = ""
39
40     while (1):
41         try:
42             chunk = sock.recv(1)
43         except socket.error, message:
44             if 'timed out' in message:
45                 break
46             else:
47                 sys.exit("Socket error: " + message)
48
49         if len(chunk) == 0:
50             break
51         msg += chunk
52
53     print 'Done extracting %d bytes of response from aggrMgr' % len(msg)
54     return msg
55    
56 def connect(server, port):
57     '''Connect to the Aggregate Manager module'''
58     sock = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
59     sock.connect ( ( server, port) )
60     sock.settimeout(1)
61     if DEBUG: print 'Connected!'
62     return sock
63     
64 def connect_aggrMgr():
65     (aggr_mgr_ip, aggr_mgr_port) = Config().get_openflow_aggrMgr_info()
66     if DEBUG: print """Connecting to port %d of %s""" % (aggr_mgr_port, aggr_mgr_ip)
67     return connect(aggr_mgr_ip, aggr_mgr_port)
68
69 def generate_slide_id(cred, hrn):
70     if cred == None:
71         cred = ""
72     if hrn == None:
73         hrn = ""
74     #return cred + '_' + hrn
75     return str(hrn)
76
77 def msg_aggrMgr(cred, hrn, msg_id):
78     slice_id = generate_slide_id(cred, hrn)
79
80     msg = struct.pack('> B%ds' % len(slice_id), msg_id, slice_id)
81     buf = struct.pack('> H', len(msg)+2) + msg
82
83     try:
84         aggrMgr_sock = connect_aggrMgr()
85         aggrMgr_sock.send(buf)
86         aggrMgr_sock.close()
87         return 1
88     except socket.error, message:
89         print "Socket error"
90     except IOerror, message:
91         print "IO error"
92     return 0
93
94 def start_slice(cred, xrn):
95     hrn = urn_to_hrn(xrn)[0]
96     if DEBUG: print "Received start_slice call"
97     return msg_aggrMgr(SFA_START_SLICE)
98
99 def stop_slice(cred, xrn):
100     hrn = urn_to_hrn(xrn)[0]
101     if DEBUG: print "Received stop_slice call"
102     return msg_aggrMgr(SFA_STOP_SLICE)
103
104 def delete_slice(cred, xrn):
105     hrn = urn_to_hrn(xrn)[0]
106     if DEBUG: print "Received delete_slice call"
107     return msg_aggrMgr(SFA_DELETE_SLICE)
108
109 def reset_slices(cred, xrn):
110     hrn = urn_to_hrn(xrn)[0]
111     if DEBUG: print "Received reset_slices call"
112     return msg_aggrMgr(SFA_RESET_SLICES)
113
114 ### Thierry: xxx this should ahve api as a first arg - probably outdated 
115 def CreateSliver(cred, xrn, rspec, call_id):
116     if Callids().already_handled(call_id): return ""
117
118     hrn = urn_to_hrn(xrn)[0]
119     if DEBUG: print "Received CreateSliver call"
120     slice_id = generate_slide_id(cred, hrn)
121
122     msg = struct.pack('> B%ds%ds' % (len(slice_id)+1, len(rspec)), SFA_CREATE_SLICE, slice_id, rspec)
123     buf = struct.pack('> H', len(msg)+2) + msg
124
125     try:
126         aggrMgr_sock = connect_aggrMgr()
127         aggrMgr_sock.send(buf)
128         if DEBUG: print "Sent %d bytes and closing connection" % len(buf)
129         aggrMgr_sock.close()
130
131         if DEBUG: print "----------------"
132         return rspec
133     except socket.error, message:
134         print "Socket error"
135     except IOerror, message:
136         print "IO error"
137     return ""
138
139 # Thierry : xxx this would need to handle call_id like the other AMs but is outdated...
140 def ListResources(cred, xrn=None):
141     hrn = urn_to_hrn(xrn)[0]
142     if DEBUG: print "Received ListResources call"
143     slice_id = generate_slide_id(cred, hrn)
144
145     msg = struct.pack('> B%ds' % len(slice_id), SFA_GET_RESOURCES, slice_id)
146     buf = struct.pack('> H', len(msg)+2) + msg
147
148     try:
149         aggrMgr_sock = connect_aggrMgr()
150         aggrMgr_sock.send(buf)
151         resource_list = extract(aggrMgr_sock);
152         aggrMgr_sock.close()
153
154         if DEBUG: print "----------------"
155         return resource_list 
156     except socket.error, message:
157         print "Socket error"
158     except IOerror, message:
159         print "IO error"
160     return None
161
162 """
163 Returns the request context required by sfatables. At some point, this mechanism should be changed
164 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
165 return the basic information needed in a dict.
166 """
167 def fetch_context(slice_hrn, user_hrn, contexts):
168     base_context = {'sfa':{'user':{'hrn':user_hrn}}}
169     return base_context
170
171 def main():
172     r = RSpec()
173     r.parseFile(sys.argv[1])
174     rspec = r.toDict()
175     CreateSliver(None,'plc',rspec,'call-id-plc')
176     
177 if __name__ == "__main__":
178     main()