Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
RECIRCLE
/
interface-openstack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
2
Merge Requests
4
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
5b8b9cae
authored
Apr 27, 2020
by
Arnau Comas Codina
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Port Forwarding
parent
841e3e1f
Pipeline
#1098
failed with stage
in 56 seconds
Changes
1
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
61 additions
and
37 deletions
+61
-37
implementation/network/port_forwarding.py
+61
-37
No files found.
implementation/network/port_forwarding.py
View file @
5b8b9cae
from
openstack.exceptions
import
ResourceNotFound
from
openstack.exceptions
import
BadRequestException
from
interface.network.port_forwarding
import
PortForwardingInterface
from
interface.network.resources
import
Port
,
FloatingIP
,
PortForwarding
from
implementation.utils.connection
import
OpenStackConnection
from
implementation.utils.decorators
import
OpenStackError
import
logging
import
random
# for limiting the ones that can be allocated over floating ips
RESERVED_PORT_NUMBERS
=
[
22
,
80
,
9696
]
class
OSPortForwardingManager
(
PortForwardingInterface
,
OpenStackConnection
):
...
...
@@ -27,10 +34,14 @@ class OSPortForwardingManager(PortForwardingInterface, OpenStackConnection):
# PortForwarding(item) for item in self.openstack.network.port_forwardings(self.floating_ips[0].id)]
@OpenStackError
def
create_port_forwarding
(
self
,
instance_id
,
internal_port_number
,
protocol
):
"""DUBTE hem de gestionar condicions com ara que no estigui creat ja
un port forwarding igual, que la floating_ip no estigui activa, que no
estigui associat a un router, etc.?
Les floating ips estan separades de la ip on hi ha les apis dels serveis
d'openstack? Perquè en devstack no, i no es pot habilitar un port extern
que ja es faci servir (s'ha de restringir)?
"""
project_id
=
self
.
openstack
.
auth
[
'project_id'
]
...
...
@@ -40,50 +51,33 @@ class OSPortForwardingManager(PortForwardingInterface, OpenStackConnection):
internal_port_id
=
internal_port_object
.
id
internal_ip_address
=
internal_port_object
.
ip_address
# recorrer cada floating ip i cridar una funció que ens torni un port lliure o None, sinó crear nova ip
#
TODO:
recorrer cada floating ip i cridar una funció que ens torni un port lliure o None, sinó crear nova ip
floating_ip_id
=
self
.
floating_ips
[
0
]
.
id
external_port
=
"8000"
#get_free_port() from list of ports
# floating_ip_id = "3179d648-9bb0-4871-854c-efffceb74fb0" #get_floating_ip_id
floating_ip_address
=
self
.
floating_ips
[
0
]
.
address
self
.
openstack
.
network
.
create_port_forwarding
(
external_port
=
self
.
__obtain_free_port_by_floating_ip_id
(
floating_ip_id
)
print
(
f
"PORT {external_port}"
)
return
PortForwarding
(
self
.
openstack
.
network
.
create_port_forwarding
(
floatingip_id
=
floating_ip_id
,
internal_port_id
=
internal_port_id
,
internal_ip_address
=
internal_ip_address
,
internal_port
=
int
ernal_port_number
,
internal_port
=
int
(
internal_port_number
)
,
external_port
=
external_port
,
protocol
=
protocol
,
description
=
''
)
port_forwardings
=
[
PortForwarding
(
item
)
for
item
in
self
.
openstack
.
network
.
port_forwardings
(
self
.
floating_ips
[
0
]
.
id
)]
# DUBTE: l'instància de la connection sempre s'ha d'inicialitzar amb l'objecte auth.
# no es podria compartir? Perquè aquí necessito accedir a funcions del port manager
# (internal_port_id no coincideix amb la instance_id)
# sinó s'haurà de fer a un nivell superior? de cercar-lo i passar-lo per paràmetre aquí
# on ha d'estar aquesta lògica doncs?
payload
=
{
"port_forwarding"
:
{
"project_id"
:
f
"{project_id}"
,
"protocol"
:
f
"{protocol}"
,
"internal_ip_address"
:
f
"{instance_id}"
,
"internal_port"
:
f
"{internal_port_number}"
,
"internal_port_id"
:
f
"{internal_port_id}"
,
"external_port"
:
f
"{external_port}"
}
}
# create a ks client and get token or do a post directly with client
#ks = self.obtain_keystone_client()
#print(ks)
description
=
''
),
floating_ip_address
)
# more handcrafted alternatives
#res = self.openstack.network.post(
# f"/floatingips/{floating_ip_id}/port_forwardings", json=payload)
#r = requests.post("http://vm.niif.cloud.bme.hu:18686/v2.0/floatingips" \
# f"/{floating_ip_id}/port_forwardings", data = payload)
#r.json()
@OpenStackError
def
delete_port_forwarding
(
self
,
instance_id
,
internal_port_number
):
""" Removes port forwarding rule
"""
...
...
@@ -97,8 +91,8 @@ class OSPortForwardingManager(PortForwardingInterface, OpenStackConnection):
floating_ip_id
=
None
for
floating_ip
in
self
.
openstack
.
list_floating_ips
():
for
port_forwarding
in
floating_ip
.
port_forwardings
:
if
(
port_forwarding
.
internal_ip_address
==
internal_ip_address
)
and
(
port_forwarding
.
internal_port
==
internal_port_number
):
if
(
(
port_forwarding
.
internal_ip_address
==
internal_ip_address
)
and
(
port_forwarding
.
internal_port
==
internal_port_number
)
)
:
# found
floating_ip_id
=
floating_ip
.
id
break
...
...
@@ -107,15 +101,16 @@ class OSPortForwardingManager(PortForwardingInterface, OpenStackConnection):
# loop again to fetch port forwarding id
# because is not contained in objects from the above results
port_forwarding_id
=
None
for
port_forwarding
in
self
.
openstack
.
network
.
floating_ip_port_forwardings
(
floating_ip_id
)
if
(
port_forwarding
.
internal_ip_address
==
internal_ip_address
)
and
(
port_forwarding
.
internal_port
==
internal_port_number
):
for
port_forwarding
in
self
.
openstack
.
network
.
floating_ip_port_forwardings
(
floating_ip_id
)
:
if
(
(
port_forwarding
.
internal_ip_address
==
internal_ip_address
)
and
(
port_forwarding
.
internal_port
==
internal_port_number
)
)
:
port_forwarding_id
=
port_forwarding
.
id
self
.
openstack
.
network
.
delete_port_forwarding
(
port_forwarding_id
,
floating_ip_id
)
@OpenStackError
def
list_instance_port_forwardings
(
self
,
instance_id
):
""" Lists all port forwarding rules defined from a vm instance
"""
...
...
@@ -147,3 +142,32 @@ class OSPortForwardingManager(PortForwardingInterface, OpenStackConnection):
internal_port_object
=
results
.
pop
()
return
internal_port_object
def
__obtain_free_port_by_floating_ip_id
(
self
,
floating_ip_id
):
""" Pot una vm tenir port forwardings en diferents floating ips?
"""
# initialize list with the full range of ports
port_numbers
=
list
(
range
(
1
,
2
**
16
))
# remove reserved ones
for
reserved
in
RESERVED_PORT_NUMBERS
:
if
reserved
in
port_numbers
:
port_numbers
.
remove
(
reserved
)
# query all current port forwardings from the floating ip
already_allocated_port_numbers
=
[]
for
item
in
self
.
openstack
.
network
.
port_forwardings
(
floating_ip_id
):
already_allocated_port_numbers
.
append
(
PortForwarding
(
item
)
.
external_port
)
# remove already allocated ports from range list
for
allocated
in
already_allocated_port_numbers
:
if
allocated
in
port_numbers
:
port_numbers
.
remove
(
allocated
)
free_port_number
=
None
if
len
(
port_numbers
):
free_port_number
=
random
.
choice
(
port_numbers
)
return
free_port_number
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment