5 def __init__(self
, name
):
8 self
.subnet_name
= None
10 self
.subnet_creation_time
= None
11 self
.subnet_update_time
= None
12 self
.gateway_ip
= None
13 self
.segmentation_id
= None # not set
15 self
.start_end_dict
= None
16 self
._issued
_ip
_addresses
= dict()
18 def get_short_id(self
):
20 Returns a shortened UUID, with only the first 6 characters.
22 :return: First 6 characters of the UUID
25 return str(self
.id)[:6]
27 def get_new_ip_address(self
, port_name
):
29 Calculates the next unused IP Address which belongs to the subnet.
31 :param port_name: Specifies the port.
32 :type port_name: ``str``
33 :return: Returns a unused IP Address or none if all are in use.
36 if self
.start_end_dict
is None:
39 int_start_ip
= Net
.ip_2_int(self
.start_end_dict
['start']) + 2 # First address as network address not usable
40 # Second one is for gateways only
41 int_end_ip
= Net
.ip_2_int(self
.start_end_dict
['end']) - 1 # Last address for broadcasts
42 while int_start_ip
in self
._issued
_ip
_addresses
and int_start_ip
<= int_end_ip
:
45 if int_start_ip
> int_end_ip
:
48 self
._issued
_ip
_addresses
[int_start_ip
] = port_name
49 return Net
.int_2_ip(int_start_ip
) + '/' + self
._cidr
.rsplit('/', 1)[1]
51 def assign_ip_address(self
, cidr
, port_name
):
53 Assigns the IP address to the port if it is currently NOT used.
55 :param cidr: The cidr used by the port - e.g. 10.0.0.1/24
57 :param port_name: The port name
58 :type port_name: ``str``
59 :return: * *False*: If the IP address is already issued or if it is not within this subnet mask.
62 int_ip
= Net
.cidr_2_int(cidr
)
63 if int_ip
in self
._issued
_ip
_addresses
:
66 int_start_ip
= Net
.ip_2_int(self
.start_end_dict
['start']) + 1 # First address as network address not usable
67 int_end_ip
= Net
.ip_2_int(self
.start_end_dict
['end']) - 1 # Last address for broadcasts
68 if int_ip
< int_start_ip
or int_ip
> int_end_ip
:
71 self
._issued
_ip
_addresses
[int_ip
] = port_name
74 def is_my_ip(self
, cidr
, port_name
):
76 Checks if the IP is registered for this port name.
78 :param cidr: The cidr used by the port - e.g. 10.0.0.1/24
80 :param port_name: The port name
81 :type port_name: ``str``
82 :return: Returns true if the IP address belongs to the port name. Else it returns false.
84 int_ip
= Net
.cidr_2_int(cidr
)
86 if not int_ip
in self
._issued
_ip
_addresses
:
89 if self
._issued
_ip
_addresses
[int_ip
] == port_name
:
93 def withdraw_ip_address(self
, ip_address
):
95 Removes the IP address from the list of issued addresses, thus other ports can use it.
97 :param ip_address: The issued IP address.
98 :type ip_address: ``str``
100 if ip_address
is None:
103 if "/" in ip_address
:
104 address
, suffix
= ip_address
.rsplit('/', 1)
107 int_ip_address
= Net
.ip_2_int(address
)
108 if int_ip_address
in self
._issued
_ip
_addresses
.keys():
109 del self
._issued
_ip
_addresses
[int_ip_address
]
111 def reset_issued_ip_addresses(self
):
113 Resets all issued IP addresses.
115 self
._issued
_ip
_addresses
= dict()
117 def update_port_name_for_ip_address(self
, ip_address
, port_name
):
119 Updates the port name of the issued IP address.
121 :param ip_address: The already issued IP address.
122 :type ip_address: ``str``
123 :param port_name: The new port name
124 :type port_name: ``str``
126 address
, suffix
= ip_address
.rsplit('/', 1)
127 int_ip_address
= Net
.ip_2_int(address
)
128 self
._issued
_ip
_addresses
[int_ip_address
] = port_name
130 def set_cidr(self
, cidr
):
132 Sets the CIDR for the subnet. It previously checks for the correct CIDR format.
134 :param cidr: The new CIDR for the subnet.
136 :return: * *True*: When the new CIDR was set successfully.
137 * *False*: If the CIDR format was wrong.
141 if self
._cidr
is not None:
142 import emuvim
.api
.openstack
.ip_handler
as IP
143 IP
.free_cidr(self
._cidr
, self
.subnet_id
)
145 self
.reset_issued_ip_addresses()
146 self
.start_end_dict
= dict()
148 if not Net
.check_cidr_format(cidr
):
151 self
.reset_issued_ip_addresses()
152 self
.start_end_dict
= Net
.calculate_start_and_end_dict(cidr
)
165 def clear_cidr(self
):
167 self
.start_end_dict
= dict()
168 self
.reset_issued_ip_addresses()
170 def delete_subnet(self
):
171 self
.subnet_id
= None
172 self
.subnet_name
= None
173 self
.subnet_creation_time
= None
174 self
.subnet_update_time
= None
178 def calculate_start_and_end_dict(cidr
):
180 Calculates the start and end IP address for the subnet.
182 :param cidr: The CIDR for the subnet.
184 :return: Dict with start and end ip address
187 address
, suffix
= cidr
.rsplit('/', 1)
188 int_suffix
= int(suffix
)
189 int_address
= Net
.ip_2_int(address
)
190 address_space
= 2 ** 32 - 1
192 for x
in range(0, 31 - int_suffix
):
193 address_space
= ~
(~address_space |
(1 << x
))
195 start
= int_address
& address_space
196 end
= start
+ (2 ** (32 - int_suffix
) - 1)
198 return {'start': Net
.int_2_ip(start
), 'end': Net
.int_2_ip(end
)}
201 def cidr_2_int(cidr
):
204 ip
= cidr
.rsplit('/', 1)[0]
205 return Net
.ip_2_int(ip
)
210 Converts a IP address to int.
212 :param ip: IP address
214 :return: IP address as int.
217 o
= map(int, ip
.split('.'))
218 res
= (16777216 * o
[0]) + (65536 * o
[1]) + (256 * o
[2]) + o
[3]
222 def int_2_ip(int_ip
):
224 Converts a int IP address to string.
226 :param int_ip: Int IP address.
227 :type int_ip: ``int``
231 o1
= int(int_ip
/ 16777216) % 256
232 o2
= int(int_ip
/ 65536) % 256
233 o3
= int(int_ip
/ 256) % 256
234 o4
= int(int_ip
) % 256
235 return '%(o1)s.%(o2)s.%(o3)s.%(o4)s' % locals()
238 def check_cidr_format(cidr
):
240 Checks the CIDR format. An valid example is: 192.168.0.0/29
242 :param cidr: CIDR to be checked.
244 :return: * *True*: If the Format is correct.
245 * *False*: If it is not correct.
248 r
= re
.compile('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{2}')
253 def create_network_dict(self
):
255 Creates the network description dictionary.
257 :return: Network description.
260 network_dict
= dict()
261 network_dict
["status"] = "ACTIVE" # TODO do we support inactive networks?
262 if self
.subnet_id
== None:
263 network_dict
["subnets"] = []
265 network_dict
["subnets"] = [self
.subnet_id
]
266 network_dict
["name"] = self
.name
267 network_dict
["admin_state_up"] = True # TODO is it always true?
268 network_dict
["tenant_id"] = "abcdefghijklmnopqrstuvwxyz123456" # TODO what should go in here
269 network_dict
["id"] = self
.id
270 network_dict
["shared"] = False # TODO is it always false?
273 def create_subnet_dict(self
):
275 Creates the subnet description dictionary.
277 :return: Subnet description.
281 subnet_dict
["name"] = self
.subnet_name
282 subnet_dict
["network_id"] = self
.id
283 subnet_dict
["tenant_id"] = "abcdefghijklmnopqrstuvwxyz123456" # TODO what should go in here?
284 subnet_dict
["created_at"] = self
.subnet_creation_time
285 subnet_dict
["dns_nameservers"] = []
286 subnet_dict
["allocation_pools"] = [self
.start_end_dict
]
287 subnet_dict
["host_routers"] = []
288 subnet_dict
["gateway_ip"] = self
.gateway_ip
289 subnet_dict
["ip_version"] = "4"
290 subnet_dict
["cidr"] = self
.get_cidr()
291 subnet_dict
["updated_at"] = self
.subnet_update_time
292 subnet_dict
["id"] = self
.subnet_id
293 subnet_dict
["enable_dhcp"] = False # TODO do we support DHCP?
296 def __eq__(self
, other
):
297 if self
.name
== other
.name
and self
.subnet_name
== other
.subnet_name
and \
298 self
.gateway_ip
== other
.gateway_ip
and \
299 self
.segmentation_id
== other
.segmentation_id
and \
300 self
._cidr
== other
._cidr
and \
301 self
.start_end_dict
== other
.start_end_dict
:
306 return hash((self
.name
,
309 self
.segmentation_id
,
311 self
.start_end_dict
))