8511f23c21d63b8a394a7a526149454028074c4c
[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 def create_slice(cred, xrn, rspec, call_id):
115     if Callids().already_handled(call_id): return False
116
117     hrn = urn_to_hrn(xrn)[0]
118     if DEBUG: print "Received create_slice call"
119     slice_id = generate_slide_id(cred, hrn)
120
121     msg = struct.pack('> B%ds%ds' % (len(slice_id)+1, len(rspec)), SFA_CREATE_SLICE, slice_id, rspec)
122     buf = struct.pack('> H', len(msg)+2) + msg
123
124     try:
125         aggrMgr_sock = connect_aggrMgr()
126         aggrMgr_sock.send(buf)
127         if DEBUG: print "Sent %d bytes and closing connection" % len(buf)
128         aggrMgr_sock.close()
129
130         if DEBUG: print "----------------"
131         return 1
132     except socket.error, message:
133         print "Socket error"
134     except IOerror, message:
135         print "IO error"
136     return 0
137
138 # Thierry : this would need to handle call_id like the other AMs but is outdated...
139 def ListResources(cred, xrn=None):
140     hrn = urn_to_hrn(xrn)[0]
141     if DEBUG: print "Received ListResources call"
142     slice_id = generate_slide_id(cred, hrn)
143
144     msg = struct.pack('> B%ds' % len(slice_id), SFA_GET_RESOURCES, slice_id)
145     buf = struct.pack('> H', len(msg)+2) + msg
146
147     try:
148         aggrMgr_sock = connect_aggrMgr()
149         aggrMgr_sock.send(buf)
150         resource_list = extract(aggrMgr_sock);
151         aggrMgr_sock.close()
152
153         if DEBUG: print "----------------"
154         return resource_list 
155     except socket.error, message:
156         print "Socket error"
157     except IOerror, message:
158         print "IO error"
159     return None
160
161 """
162 Returns the request context required by sfatables. At some point, this mechanism should be changed
163 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
164 return the basic information needed in a dict.
165 """
166 def fetch_context(slice_hrn, user_hrn, contexts):
167     base_context = {'sfa':{'user':{'hrn':user_hrn}}}
168     return base_context
169
170 def main():
171     r = RSpec()
172     r.parseFile(sys.argv[1])
173     rspec = r.toDict()
174     create_slice(None,'plc',rspec,'call-id-plc')
175     
176 if __name__ == "__main__":
177     main()