Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
re2o
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nounous
re2o
Commits
e97e3041
Commit
e97e3041
authored
Mar 17, 2018
by
Maël Kervella
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
API: Add support for DNS
parent
ef6b6243
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
460 additions
and
0 deletions
+460
-0
api/serializers.py
api/serializers.py
+265
-0
api/urls.py
api/urls.py
+10
-0
api/views.py
api/views.py
+185
-0
No files found.
api/serializers.py
View file @
e97e3041
...
...
@@ -26,7 +26,19 @@ from rest_framework import serializers
from
users.models
import
Club
,
Adherent
from
machines.models
import
(
Interface
,
IpType
,
Extension
,
IpList
,
MachineType
,
Domain
,
Txt
,
Mx
,
Srv
,
Service_link
,
Ns
,
OuverturePortList
,
OuverturePort
,
Ipv6List
)
...
...
@@ -52,6 +64,28 @@ class MailingMemberSerializer(serializers.ModelSerializer):
fields
=
(
'email'
,
'name'
,
'surname'
,
'pseudo'
,)
class
IpTypeField
(
serializers
.
RelatedField
):
"""Serialisation d'une iptype, renvoie son evaluation str"""
def
to_representation
(
self
,
value
):
return
value
.
type
class
IpListSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'une iplist, ip_type etant une foreign_key,
on evalue sa methode str"""
ip_type
=
IpTypeField
(
read_only
=
True
)
class
Meta
:
model
=
IpList
fields
=
(
'ipv4'
,
'ip_type'
)
class
Ipv6ListSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
Ipv6List
fields
=
(
'ipv6'
,
'slaac_ip'
)
class
InterfaceSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'une interface, ipv4, domain et extension sont
des foreign_key, on les override et on les evalue avec des fonctions
...
...
@@ -75,6 +109,209 @@ class InterfaceSerializer(serializers.ModelSerializer):
return
str
(
obj
.
mac_address
)
class
FullInterfaceSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation complete d'une interface avec les ipv6 en plus"""
ipv4
=
IpListSerializer
(
read_only
=
True
)
ipv6
=
Ipv6ListSerializer
(
read_only
=
True
,
many
=
True
)
mac_address
=
serializers
.
SerializerMethodField
(
'get_macaddress'
)
domain
=
serializers
.
SerializerMethodField
(
'get_dns'
)
extension
=
serializers
.
SerializerMethodField
(
'get_interface_extension'
)
class
Meta
:
model
=
Interface
fields
=
(
'ipv4'
,
'ipv6'
,
'mac_address'
,
'domain'
,
'extension'
)
def
get_dns
(
self
,
obj
):
return
obj
.
domain
.
name
def
get_interface_extension
(
self
,
obj
):
return
obj
.
domain
.
extension
.
name
def
get_macaddress
(
self
,
obj
):
return
str
(
obj
.
mac_address
)
class
ExtensionNameField
(
serializers
.
RelatedField
):
"""Evaluation str d'un objet extension (.example.org)"""
def
to_representation
(
self
,
value
):
return
value
.
name
class
TypeSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'un iptype : extension et la liste des
ouvertures de port son evalués en get_... etant des
foreign_key ou des relations manytomany"""
extension
=
ExtensionNameField
(
read_only
=
True
)
ouverture_ports_tcp_in
=
serializers
\
.
SerializerMethodField
(
'get_port_policy_input_tcp'
)
ouverture_ports_tcp_out
=
serializers
\
.
SerializerMethodField
(
'get_port_policy_output_tcp'
)
ouverture_ports_udp_in
=
serializers
\
.
SerializerMethodField
(
'get_port_policy_input_udp'
)
ouverture_ports_udp_out
=
serializers
\
.
SerializerMethodField
(
'get_port_policy_output_udp'
)
class
Meta
:
model
=
IpType
fields
=
(
'type'
,
'extension'
,
'domaine_ip_start'
,
'domaine_ip_stop'
,
'prefix_v6'
,
'ouverture_ports_tcp_in'
,
'ouverture_ports_tcp_out'
,
'ouverture_ports_udp_in'
,
'ouverture_ports_udp_out'
,)
def
get_port_policy
(
self
,
obj
,
protocole
,
io
):
if
obj
.
ouverture_ports
is
None
:
return
[]
return
map
(
str
,
obj
.
ouverture_ports
.
ouvertureport_set
.
filter
(
protocole
=
protocole
).
filter
(
io
=
io
)
)
def
get_port_policy_input_tcp
(
self
,
obj
):
"""Renvoie la liste des ports ouverts en entrée tcp"""
return
self
.
get_port_policy
(
obj
,
OuverturePort
.
TCP
,
OuverturePort
.
IN
)
def
get_port_policy_output_tcp
(
self
,
obj
):
"""Renvoie la liste des ports ouverts en sortie tcp"""
return
self
.
get_port_policy
(
obj
,
OuverturePort
.
TCP
,
OuverturePort
.
OUT
)
def
get_port_policy_input_udp
(
self
,
obj
):
"""Renvoie la liste des ports ouverts en entrée udp"""
return
self
.
get_port_policy
(
obj
,
OuverturePort
.
UDP
,
OuverturePort
.
IN
)
def
get_port_policy_output_udp
(
self
,
obj
):
"""Renvoie la liste des ports ouverts en sortie udp"""
return
self
.
get_port_policy
(
obj
,
OuverturePort
.
UDP
,
OuverturePort
.
OUT
)
class
ExtensionSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'une extension : origin_ip et la zone sont
des foreign_key donc evalués en get_..."""
origin
=
serializers
.
SerializerMethodField
(
'get_origin_ip'
)
zone_entry
=
serializers
.
SerializerMethodField
(
'get_zone_name'
)
soa
=
serializers
.
SerializerMethodField
(
'get_soa_data'
)
class
Meta
:
model
=
Extension
fields
=
(
'name'
,
'origin'
,
'origin_v6'
,
'zone_entry'
,
'soa'
)
def
get_origin_ip
(
self
,
obj
):
return
obj
.
origin
.
ipv4
def
get_zone_name
(
self
,
obj
):
return
str
(
obj
.
dns_entry
)
def
get_soa_data
(
self
,
obj
):
return
{
'mail'
:
obj
.
soa
.
dns_soa_mail
,
'param'
:
obj
.
soa
.
dns_soa_param
}
class
MxSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'un MX, evaluation du nom, de la zone
et du serveur cible, etant des foreign_key"""
name
=
serializers
.
SerializerMethodField
(
'get_entry_name'
)
zone
=
serializers
.
SerializerMethodField
(
'get_zone_name'
)
mx_entry
=
serializers
.
SerializerMethodField
(
'get_mx_name'
)
class
Meta
:
model
=
Mx
fields
=
(
'zone'
,
'priority'
,
'name'
,
'mx_entry'
)
def
get_entry_name
(
self
,
obj
):
return
str
(
obj
.
name
)
def
get_zone_name
(
self
,
obj
):
return
obj
.
zone
.
name
def
get_mx_name
(
self
,
obj
):
return
str
(
obj
.
dns_entry
)
class
TxtSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'un txt : zone cible et l'entrée txt
sont evaluées à part"""
zone
=
serializers
.
SerializerMethodField
(
'get_zone_name'
)
txt_entry
=
serializers
.
SerializerMethodField
(
'get_txt_name'
)
class
Meta
:
model
=
Txt
fields
=
(
'zone'
,
'txt_entry'
,
'field1'
,
'field2'
)
def
get_zone_name
(
self
,
obj
):
return
str
(
obj
.
zone
.
name
)
def
get_txt_name
(
self
,
obj
):
return
str
(
obj
.
dns_entry
)
class
SrvSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'un srv : zone cible et l'entrée txt"""
extension
=
serializers
.
SerializerMethodField
(
'get_extension_name'
)
srv_entry
=
serializers
.
SerializerMethodField
(
'get_srv_name'
)
class
Meta
:
model
=
Srv
fields
=
(
'service'
,
'protocole'
,
'extension'
,
'ttl'
,
'priority'
,
'weight'
,
'port'
,
'target'
,
'srv_entry'
)
def
get_extension_name
(
self
,
obj
):
return
str
(
obj
.
extension
.
name
)
def
get_srv_name
(
self
,
obj
):
return
str
(
obj
.
dns_entry
)
class
NsSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'un NS : la zone, l'entrée ns complète et le serveur
ns sont évalués à part"""
zone
=
serializers
.
SerializerMethodField
(
'get_zone_name'
)
ns
=
serializers
.
SerializerMethodField
(
'get_domain_name'
)
ns_entry
=
serializers
.
SerializerMethodField
(
'get_text_name'
)
class
Meta
:
model
=
Ns
fields
=
(
'zone'
,
'ns'
,
'ns_entry'
)
def
get_zone_name
(
self
,
obj
):
return
obj
.
zone
.
name
def
get_domain_name
(
self
,
obj
):
return
str
(
obj
.
ns
)
def
get_text_name
(
self
,
obj
):
return
str
(
obj
.
dns_entry
)
class
DomainSerializer
(
serializers
.
ModelSerializer
):
"""Serialisation d'un domain, extension, cname sont des foreign_key,
et l'entrée complète, sont évalués à part"""
extension
=
serializers
.
SerializerMethodField
(
'get_zone_name'
)
cname
=
serializers
.
SerializerMethodField
(
'get_alias_name'
)
cname_entry
=
serializers
.
SerializerMethodField
(
'get_cname_name'
)
class
Meta
:
model
=
Domain
fields
=
(
'name'
,
'extension'
,
'cname'
,
'cname_entry'
)
def
get_zone_name
(
self
,
obj
):
return
obj
.
extension
.
name
def
get_alias_name
(
self
,
obj
):
return
str
(
obj
.
cname
)
def
get_cname_name
(
self
,
obj
):
return
str
(
obj
.
dns_entry
)
class
ServicesSerializer
(
serializers
.
ModelSerializer
):
"""Evaluation d'un Service, et serialisation"""
server
=
serializers
.
SerializerMethodField
(
'get_server_name'
)
...
...
@@ -93,3 +330,31 @@ class ServicesSerializer(serializers.ModelSerializer):
def
get_regen_status
(
self
,
obj
):
return
obj
.
need_regen
()
class
OuverturePortsSerializer
(
serializers
.
Serializer
):
"""Serialisation de l'ouverture des ports"""
ipv4
=
serializers
.
SerializerMethodField
()
ipv6
=
serializers
.
SerializerMethodField
()
def
get_ipv4
():
return
{
i
.
ipv4
.
ipv4
:
{
"tcp_in"
:[
j
.
tcp_ports_in
()
for
j
in
i
.
port_lists
.
all
()],
"tcp_out"
:[
j
.
tcp_ports_out
()
for
j
in
i
.
port_lists
.
all
()],
"udp_in"
:[
j
.
udp_ports_in
()
for
j
in
i
.
port_lists
.
all
()],
"udp_out"
:[
j
.
udp_ports_out
()
for
j
in
i
.
port_lists
.
all
()],
}
for
i
in
Interface
.
objects
.
all
()
if
i
.
ipv4
}
def
get_ipv6
():
return
{
i
.
ipv6
:
{
"tcp_in"
:[
j
.
tcp_ports_in
()
for
j
in
i
.
port_lists
.
all
()],
"tcp_out"
:[
j
.
tcp_ports_out
()
for
j
in
i
.
port_lists
.
all
()],
"udp_in"
:[
j
.
udp_ports_in
()
for
j
in
i
.
port_lists
.
all
()],
"udp_out"
:[
j
.
udp_ports_out
()
for
j
in
i
.
port_lists
.
all
()],
}
for
i
in
Interface
.
objects
.
all
()
if
i
.
ipv6
}
api/urls.py
View file @
e97e3041
...
...
@@ -35,6 +35,16 @@ urlpatterns = [
url
(
r
'^services/(?P<server_name>\w+)/(?P<service_name>\w+)/regen/$'
,
views
.
services_server_service_regen
),
url
(
r
'^services/(?P<server_name>\w+)/$'
,
views
.
services_server
),
# DNS
url
(
r
'^dns/mac-ip-dns/$'
,
views
.
dns_mac_ip_dns
),
url
(
r
'^dns/alias/$'
,
views
.
dns_alias
),
url
(
r
'^dns/corresp/$'
,
views
.
dns_corresp
),
url
(
r
'^dns/mx/$'
,
views
.
dns_mx
),
url
(
r
'^dns/ns/$'
,
views
.
dns_ns
),
url
(
r
'^dns/txt/$'
,
views
.
dns_txt
),
url
(
r
'^dns/srv/$'
,
views
.
dns_srv
),
url
(
r
'^dns/zones/$'
,
views
.
dns_zones
),
# Firewall
url
(
r
'^firewall/ouverture_ports/$'
,
views
.
firewall_ouverture_ports
),
...
...
api/views.py
View file @
e97e3041
...
...
@@ -115,6 +115,191 @@ def services_server(request, server_name):
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
@
accept_method
([
'GET'
])
def
dns_mac_ip_dns
(
request
):
"""The list of all active interfaces with all the associated infos
(MAC, IP, IpType, DNS name and associated zone extension)
Returns:
GET:
A JSON Success response with a field `data` containing:
* a list of dictionnaries (one for each interface) containing:
* a field `ipv4` containing:
* a field `ipv4`: the ip for this interface
* a field `ip_type`: the name of the IpType of this interface
* a field `ipv6` containing `null` if ipv6 is deactivated else:
* a field `ipv6`: the ip for this interface
* a field `ip_type`: the name of the IpType of this interface
* a field `mac_address`: the MAC of this interface
* a field `domain`: the DNS name for this interface
* a field `extension`: the extension for the DNS zone of this interface
"""
interfaces
=
all_active_assigned_interfaces
(
full
=
True
)
seria
=
FullInterfaceSerializer
(
interfaces
,
many
=
True
)
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
@
accept_method
([
'GET'
])
def
dns_alias
(
request
):
"""The list of all the alias used and the DNS info associated
Returns:
GET:
A JSON Success response with a field `data` containing:
* a list of dictionnaries (one for each alias) containing:
* a field `name`: the alias used
* a field `cname`: the target of the alias (real name of the interface)
* a field `cname_entry`: the entry to write in the DNS to have the alias
* a field `extension`: the extension for the DNS zone of this interface
"""
alias
=
Domain
.
objects
.
filter
(
interface_parent
=
None
).
filter
(
cname__in
=
Domain
.
objects
.
filter
(
interface_parent__in
=
Interface
.
objects
.
exclude
(
ipv4
=
None
))).
select_related
(
'extension'
).
select_related
(
'cname__extension'
)
seria
=
DomainSerializer
(
alias
,
many
=
True
)
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
@
accept_method
([
'GET'
])
def
dns_corresp
(
request
):
"""The list of the IpTypes possible with the infos about each
Returns:
GET:
A JSON Success response with a field `data` containing:
* a list of dictionnaries (one for each IpType) containing:
* a field `type`: the name of the type
* a field `extension`: the DNS extension associated
* a field `domain_ip_start`: the first ip to use for this type
* a field `domain_ip_stop`: the last ip to use for this type
* a field `prefix_v6`: `null` if IPv6 is deactivated else the prefix to use
* a field `ouverture_ports_tcp_in`: the policy for TCP IN ports
* a field `ouverture_ports_tcp_out`: the policy for TCP OUT ports
* a field `ouverture_ports_udp_in`: the policy for UDP IN ports
* a field `ouverture_ports_udp_out`: the policy for UDP OUT ports
"""
ip_type
=
IpType
.
objects
.
all
().
select_related
(
'extension'
)
seria
=
TypeSerializer
(
ip_type
,
many
=
True
)
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
@
accept_method
([
'GET'
])
def
dns_mx
(
request
):
"""The list of MX record to add to the DNS
Returns:
GET:
A JSON Success response with a field `data` containing:
* a list of dictionnaries (one for each MX record) containing:
* a field `zone`: the extension for the concerned zone
* a field `priority`: the priority to use
* a field `name`: the name of the target
* a field `mx_entry`: the full entry to add in the DNS for this MX record
"""
mx
=
Mx
.
objects
.
all
().
select_related
(
'zone'
).
select_related
(
'name__extension'
)
seria
=
MxSerializer
(
mx
,
many
=
True
)
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
@
accept_method
([
'GET'
])
def
dns_ns
(
request
):
"""The list of NS record to add to the DNS
Returns:
GET:
A JSON Success response with a field `data` containing:
* a list of dictionnaries (one for each NS record) containing:
* a field `zone`: the extension for the concerned zone
* a field `ns`: the DNS name for the NS server targeted
* a field `ns_entry`: the full entry to add in the DNS for this NS record
"""
ns
=
Ns
.
objects
.
exclude
(
ns__in
=
Domain
.
objects
.
filter
(
interface_parent__in
=
Interface
.
objects
.
filter
(
ipv4
=
None
))).
select_related
(
'zone'
).
select_related
(
'ns__extension'
)
seria
=
NsSerializer
(
ns
,
many
=
True
)
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
@
accept_method
([
'GET'
])
def
dns_txt
(
request
):
"""The list of TXT record to add to the DNS
Returns:
GET:
A JSON Success response with a field `data` containing:
* a list of dictionnaries (one for each TXT record) containing:
* a field `zone`: the extension for the concerned zone
* a field `field1`: the first field in the record (target)
* a field `field2`: the second field in the record (value)
* a field `txt_entry`: the full entry to add in the DNS for this TXT record
"""
txt
=
Txt
.
objects
.
all
().
select_related
(
'zone'
)
seria
=
TxtSerializer
(
txt
,
many
=
True
)
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
@
accept_method
([
'GET'
])
def
dns_srv
(
request
):
"""The list of SRV record to add to the DNS
Returns:
GET:
A JSON Success response with a field `data` containing:
* a list of dictionnaries (one for each SRV record) containing:
* a field `extension`: the extension for the concerned zone
* a field `service`: the name of the service concerned
* a field `protocole`: the name of the protocol to use
* a field `ttl`: the Time To Live to use
* a field `priority`: the priority for this service
* a field `weight`: the weight for same priority entries
* a field `port`: the port targeted
* a field `target`: the interface targeted by this service
* a field `srv_entry`: the full entry to add in the DNS for this SRV record
"""
srv
=
Srv
.
objects
.
all
().
select_related
(
'extension'
).
select_related
(
'target__extension'
)
seria
=
SrvSerializer
(
srv
,
many
=
True
)
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
@
accept_method
([
'GET'
])
def
dns_zones
(
request
):
"""The list of the zones managed
Returns:
GET:
A JSON Success response with a field `data` containing:
* a list of dictionnaries (one for each zone) containing:
* a field `name`: the extension for the zone
* a field `origin`: the server IPv4 for the orgin of the zone
* a field `origin_v6`: `null` if ipv6 is deactivated else the server IPv6 for the origin of the zone
* a field `soa` containing:
* a field `mail` containing the mail to contact in case of problem with the zone
* a field `param` containing the full soa paramters to use in the DNS for this zone
* a field `zone_entry`: the full entry to add in the DNS for the origin of the zone
"""
zones
=
Extension
.
objects
.
all
().
select_related
(
'origin'
)
seria
=
ExtensionSerializer
(
zones
,
many
=
True
)
return
JSONSuccess
(
seria
.
data
)
@
csrf_exempt
@
login_required
@
permission_required
(
'machines.serveur'
)
...
...
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