serializers.py 13.6 KB
Newer Older
1
# -*- mode: python; coding: utf-8 -*-
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017  Gabriel Détraz
# Copyright © 2017  Goulven Kermarec
# Copyright © 2017  Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

24
# Augustin Lemesle
25 26 27 28
"""machines.serializers
Serializers for the Machines app
"""

Dalahro's avatar
Dalahro committed
29
from rest_framework import serializers
erdnaxe's avatar
erdnaxe committed
30

Gabriel Detraz's avatar
Gabriel Detraz committed
31 32 33 34 35 36
from machines.models import (
    Interface,
    IpType,
    Extension,
    IpList,
    Domain,
Gabriel Detraz's avatar
Gabriel Detraz committed
37
    Txt,
Gabriel Detraz's avatar
Gabriel Detraz committed
38
    Mx,
Gabriel Detraz's avatar
Gabriel Detraz committed
39
    Srv,
Gabriel Detraz's avatar
Gabriel Detraz committed
40 41
    Service_link,
    Ns,
42 43
    OuverturePort,
    Ipv6List
Gabriel Detraz's avatar
Gabriel Detraz committed
44 45
)

Dalahro's avatar
Dalahro committed
46

47
class IpTypeField(serializers.RelatedField):
48 49
    """ Serializer for an IpType object field """

50 51 52
    def to_representation(self, value):
        return value.type

53 54 55
    def to_internal_value(self, data):
        pass

Gabriel Detraz's avatar
Gabriel Detraz committed
56

57
class IpListSerializer(serializers.ModelSerializer):
58 59
    """ Serializer for an Ipv4List obejct using the IpType serialization """

60 61 62 63 64 65
    ip_type = IpTypeField(read_only=True)

    class Meta:
        model = IpList
        fields = ('ipv4', 'ip_type')

Gabriel Detraz's avatar
Gabriel Detraz committed
66

67
class Ipv6ListSerializer(serializers.ModelSerializer):
68 69
    """ Serializer for an Ipv6List object """

70 71 72 73 74
    class Meta:
        model = Ipv6List
        fields = ('ipv6', 'slaac_ip')


75
class InterfaceSerializer(serializers.ModelSerializer):
76 77 78
    """ Serializer for an Interface object. Use SerializerMethodField
    to get ForeignKey values """

79
    ipv4 = IpListSerializer(read_only=True)
80
    # TODO : use serializer.RelatedField to avoid duplicate code
Gabriel Detraz's avatar
Gabriel Detraz committed
81
    mac_address = serializers.SerializerMethodField('get_macaddress')
chirac's avatar
chirac committed
82
    domain = serializers.SerializerMethodField('get_dns')
Mael Kervella's avatar
Mael Kervella committed
83
    extension = serializers.SerializerMethodField('get_interface_extension')
Gabriel Detraz's avatar
Gabriel Detraz committed
84

Dalahro's avatar
Dalahro committed
85 86
    class Meta:
        model = Interface
Gabriel Detraz's avatar
Gabriel Detraz committed
87
        fields = ('ipv4', 'mac_address', 'domain', 'extension')
chirac's avatar
chirac committed
88

89 90 91
    @staticmethod
    def get_dns(obj):
        """ The name of the associated  DNS object """
Gabriel Detraz's avatar
Gabriel Detraz committed
92 93
        return obj.domain.name

94 95 96
    @staticmethod
    def get_interface_extension(obj):
        """ The name of the associated Interface object """
97
        return obj.domain.extension.name
98

99 100 101
    @staticmethod
    def get_macaddress(obj):
        """ The string representation of the associated MAC address """
Gabriel Detraz's avatar
Gabriel Detraz committed
102 103
        return str(obj.mac_address)

Gabriel Detraz's avatar
Gabriel Detraz committed
104

Gabriel Detraz's avatar
Gabriel Detraz committed
105
class FullInterfaceSerializer(serializers.ModelSerializer):
106 107 108
    """ Serializer for an Interface obejct. Use SerializerMethodField
    to get ForeignKey values """

Gabriel Detraz's avatar
Gabriel Detraz committed
109
    ipv4 = IpListSerializer(read_only=True)
110
    ipv6 = Ipv6ListSerializer(read_only=True, many=True)
111
    # TODO : use serializer.RelatedField to avoid duplicate code
Gabriel Detraz's avatar
Gabriel Detraz committed
112 113 114 115 116 117 118 119
    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')

120 121 122
    @staticmethod
    def get_dns(obj):
        """ The name of the associated DNS object """
Gabriel Detraz's avatar
Gabriel Detraz committed
123 124
        return obj.domain.name

125 126 127
    @staticmethod
    def get_interface_extension(obj):
        """ The name of the associated Extension object """
Gabriel Detraz's avatar
Gabriel Detraz committed
128 129
        return obj.domain.extension.name

130 131 132
    @staticmethod
    def get_macaddress(obj):
        """ The string representation of the associated MAC address """
Gabriel Detraz's avatar
Gabriel Detraz committed
133 134
        return str(obj.mac_address)

Gabriel Detraz's avatar
Gabriel Detraz committed
135

136
class ExtensionNameField(serializers.RelatedField):
137 138
    """ Serializer for Extension object field """

139
    def to_representation(self, value):
140
        return value.name
Dalahro's avatar
Dalahro committed
141

142 143 144
    def to_internal_value(self, data):
        pass

Gabriel Detraz's avatar
Gabriel Detraz committed
145

root's avatar
root committed
146
class TypeSerializer(serializers.ModelSerializer):
147 148 149
    """ Serializer for an IpType object. Use SerializerMethodField to
    get ForeignKey values. Infos about the general port policy is added """

root's avatar
root committed
150
    extension = ExtensionNameField(read_only=True)
erdnaxe's avatar
erdnaxe committed
151
    ouverture_ports_tcp_in = serializers \
Gabriel Detraz's avatar
Gabriel Detraz committed
152
        .SerializerMethodField('get_port_policy_input_tcp')
erdnaxe's avatar
erdnaxe committed
153
    ouverture_ports_tcp_out = serializers \
Gabriel Detraz's avatar
Gabriel Detraz committed
154
        .SerializerMethodField('get_port_policy_output_tcp')
erdnaxe's avatar
erdnaxe committed
155
    ouverture_ports_udp_in = serializers \
Gabriel Detraz's avatar
Gabriel Detraz committed
156
        .SerializerMethodField('get_port_policy_input_udp')
erdnaxe's avatar
erdnaxe committed
157
    ouverture_ports_udp_out = serializers \
Gabriel Detraz's avatar
Gabriel Detraz committed
158
        .SerializerMethodField('get_port_policy_output_udp')
159

root's avatar
root committed
160 161
    class Meta:
        model = IpType
Gabriel Detraz's avatar
Gabriel Detraz committed
162
        fields = ('type', 'extension', 'domaine_ip_start', 'domaine_ip_stop',
Gabriel Detraz's avatar
Gabriel Detraz committed
163
                  'prefix_v6',
Gabriel Detraz's avatar
Gabriel Detraz committed
164 165
                  'ouverture_ports_tcp_in', 'ouverture_ports_tcp_out',
                  'ouverture_ports_udp_in', 'ouverture_ports_udp_out',)
166

167 168 169 170
    @staticmethod
    def get_port_policy(obj, protocole, io):
        """ Generic utility function to get the policy for a given
        port, protocole and IN or OUT """
171
        if obj.ouverture_ports is None:
172
            return []
Gabriel Detraz's avatar
Gabriel Detraz committed
173 174 175 176 177 178
        return map(
            str,
            obj.ouverture_ports.ouvertureport_set.filter(
                protocole=protocole
            ).filter(io=io)
        )
179 180

    def get_port_policy_input_tcp(self, obj):
Gabriel Detraz's avatar
Gabriel Detraz committed
181
        """Renvoie la liste des ports ouverts en entrée tcp"""
182 183 184
        return self.get_port_policy(obj, OuverturePort.TCP, OuverturePort.IN)

    def get_port_policy_output_tcp(self, obj):
Gabriel Detraz's avatar
Gabriel Detraz committed
185
        """Renvoie la liste des ports ouverts en sortie tcp"""
186 187 188
        return self.get_port_policy(obj, OuverturePort.TCP, OuverturePort.OUT)

    def get_port_policy_input_udp(self, obj):
Gabriel Detraz's avatar
Gabriel Detraz committed
189
        """Renvoie la liste des ports ouverts en entrée udp"""
190 191 192
        return self.get_port_policy(obj, OuverturePort.UDP, OuverturePort.IN)

    def get_port_policy_output_udp(self, obj):
Gabriel Detraz's avatar
Gabriel Detraz committed
193
        """Renvoie la liste des ports ouverts en sortie udp"""
194
        return self.get_port_policy(obj, OuverturePort.UDP, OuverturePort.OUT)
root's avatar
root committed
195

Gabriel Detraz's avatar
Gabriel Detraz committed
196

197
class ExtensionSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
198 199
    """Serialisation d'une extension : origin_ip et la zone sont
    des foreign_key donc evalués en get_..."""
200
    origin = serializers.SerializerMethodField('get_origin_ip')
201
    zone_entry = serializers.SerializerMethodField('get_zone_name')
202
    soa = serializers.SerializerMethodField('get_soa_data')
203 204 205

    class Meta:
        model = Extension
206
        fields = ('name', 'origin', 'origin_v6', 'zone_entry', 'soa')
207

208 209 210 211
    @staticmethod
    def get_origin_ip(obj):
        """ The IP of the associated origin for the zone """
        return obj.origin.ipv4
212

213 214 215
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone """
216 217
        return str(obj.dns_entry)

218 219 220
    @staticmethod
    def get_soa_data(obj):
        """ The representation of the associated SOA """
221
        return {'mail': obj.soa.dns_soa_mail, 'param': obj.soa.dns_soa_param}
222

Gabriel Detraz's avatar
Gabriel Detraz committed
223

224
class MxSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
225 226
    """Serialisation d'un MX, evaluation du nom, de la zone
    et du serveur cible, etant des foreign_key"""
227
    name = serializers.SerializerMethodField('get_entry_name')
228
    zone = serializers.SerializerMethodField('get_zone_name')
229
    mx_entry = serializers.SerializerMethodField('get_mx_name')
230

231
    class Meta:
232
        model = Mx
233
        fields = ('zone', 'priority', 'name', 'mx_entry')
234

235 236 237
    @staticmethod
    def get_entry_name(obj):
        """ The name of the DNS MX entry """
Mael Kervella's avatar
Mael Kervella committed
238
        return str(obj.name)
239

240 241 242
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone of the MX record """
243 244
        return obj.zone.name

245 246 247
    @staticmethod
    def get_mx_name(obj):
        """ The string representation of the entry to add to the DNS """
248 249
        return str(obj.dns_entry)

Gabriel Detraz's avatar
Gabriel Detraz committed
250

Gabriel Detraz's avatar
Gabriel Detraz committed
251
class TxtSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
252 253
    """Serialisation d'un txt : zone cible et l'entrée txt
    sont evaluées à part"""
Gabriel Detraz's avatar
Gabriel Detraz committed
254
    zone = serializers.SerializerMethodField('get_zone_name')
Gabriel Detraz's avatar
Gabriel Detraz committed
255
    txt_entry = serializers.SerializerMethodField('get_txt_name')
Gabriel Detraz's avatar
Gabriel Detraz committed
256 257

    class Meta:
Gabriel Detraz's avatar
Gabriel Detraz committed
258 259
        model = Txt
        fields = ('zone', 'txt_entry', 'field1', 'field2')
Gabriel Detraz's avatar
Gabriel Detraz committed
260

261 262 263
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone """
Gabriel Detraz's avatar
Gabriel Detraz committed
264 265
        return str(obj.zone.name)

266 267 268
    @staticmethod
    def get_txt_name(obj):
        """ The string representation of the entry to add to the DNS """
Gabriel Detraz's avatar
Gabriel Detraz committed
269
        return str(obj.dns_entry)
Gabriel Detraz's avatar
Gabriel Detraz committed
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290


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'
        )

291 292 293
    @staticmethod
    def get_extension_name(obj):
        """ The name of the associated extension """
Gabriel Detraz's avatar
Gabriel Detraz committed
294 295
        return str(obj.extension.name)

296 297 298
    @staticmethod
    def get_srv_name(obj):
        """ The string representation of the entry to add to the DNS """
Gabriel Detraz's avatar
Gabriel Detraz committed
299
        return str(obj.dns_entry)
Gabriel Detraz's avatar
Gabriel Detraz committed
300

Gabriel Detraz's avatar
Gabriel Detraz committed
301

302
class NsSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
303 304
    """Serialisation d'un NS : la zone, l'entrée ns complète et le serveur
    ns sont évalués à part"""
305
    zone = serializers.SerializerMethodField('get_zone_name')
Mael Kervella's avatar
Mael Kervella committed
306
    ns = serializers.SerializerMethodField('get_domain_name')
Gabriel Detraz's avatar
Gabriel Detraz committed
307
    ns_entry = serializers.SerializerMethodField('get_text_name')
Dalahro's avatar
Dalahro committed
308

309
    class Meta:
310
        model = Ns
311
        fields = ('zone', 'ns', 'ns_entry')
312

313 314 315
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone """
316 317
        return obj.zone.name

318 319 320
    @staticmethod
    def get_domain_name(obj):
        """ The name of the associated NS target """
Mael Kervella's avatar
Mael Kervella committed
321
        return str(obj.ns)
322

323 324 325
    @staticmethod
    def get_text_name(obj):
        """ The string representation of the entry to add to the DNS """
326 327
        return str(obj.dns_entry)

Gabriel Detraz's avatar
Gabriel Detraz committed
328

chirac's avatar
chirac committed
329
class DomainSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
330 331
    """Serialisation d'un domain, extension, cname sont des foreign_key,
    et l'entrée complète, sont évalués à part"""
332
    extension = serializers.SerializerMethodField('get_zone_name')
333
    cname = serializers.SerializerMethodField('get_alias_name')
Gabriel Detraz's avatar
Gabriel Detraz committed
334
    cname_entry = serializers.SerializerMethodField('get_cname_name')
Dalahro's avatar
Dalahro committed
335

336
    class Meta:
chirac's avatar
chirac committed
337
        model = Domain
338
        fields = ('name', 'extension', 'cname', 'cname_entry')
339

340 341 342
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone """
chirac's avatar
chirac committed
343
        return obj.extension.name
344

345 346 347
    @staticmethod
    def get_alias_name(obj):
        """ The name of the associated alias """
Mael Kervella's avatar
Mael Kervella committed
348
        return str(obj.cname)
chirac's avatar
chirac committed
349

350 351 352
    @staticmethod
    def get_cname_name(obj):
        """ The name of the associated CNAME target """
353 354
        return str(obj.dns_entry)

Gabriel Detraz's avatar
Gabriel Detraz committed
355

356
class ServiceServersSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
357
    """Evaluation d'un Service, et serialisation"""
358 359 360 361 362 363 364 365
    server = serializers.SerializerMethodField('get_server_name')
    service = serializers.SerializerMethodField('get_service_name')
    need_regen = serializers.SerializerMethodField('get_regen_status')

    class Meta:
        model = Service_link
        fields = ('server', 'service', 'need_regen')

366 367 368
    @staticmethod
    def get_server_name(obj):
        """ The name of the associated server """
369 370
        return str(obj.server.domain.name)

371 372 373
    @staticmethod
    def get_service_name(obj):
        """ The name of the service name """
374 375
        return str(obj.service)

376 377 378
    @staticmethod
    def get_regen_status(obj):
        """ The string representation of the regen status """
379
        return obj.need_regen
380

Gabriel Detraz's avatar
Gabriel Detraz committed
381

382
class OuverturePortsSerializer(serializers.Serializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
383
    """Serialisation de l'ouverture des ports"""
384 385 386
    ipv4 = serializers.SerializerMethodField()
    ipv6 = serializers.SerializerMethodField()

387 388 389 390 391 392 393 394 395 396 397
    def create(self, validated_data):
        """ Creates a new object based on the un-serialized data.
        Used to implement an abstract inherited method """
        pass

    def update(self, instance, validated_data):
        """ Updates an object based on the un-serialized data.
        Used to implement an abstract inherited method """
        pass

    @staticmethod
398
    def get_ipv4():
399
        """ The representation of the policy for the IPv4 addresses """
400 401 402
        return {
            i.ipv4.ipv4: {
                "tcp_in": [j.tcp_ports_in() for j in i.port_lists.all()],
erdnaxe's avatar
erdnaxe committed
403
                "tcp_out": [j.tcp_ports_out() for j in i.port_lists.all()],
404 405
                "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()],
Gabriel Detraz's avatar
Gabriel Detraz committed
406
            }
407
            for i in Interface.objects.all() if i.ipv4
408
        }
Gabriel Detraz's avatar
Gabriel Detraz committed
409

410
    @staticmethod
411
    def get_ipv6():
412
        """ The representation of the policy for the IPv6 addresses """
413 414 415
        return {
            i.ipv6: {
                "tcp_in": [j.tcp_ports_in() for j in i.port_lists.all()],
erdnaxe's avatar
erdnaxe committed
416
                "tcp_out": [j.tcp_ports_out() for j in i.port_lists.all()],
417 418
                "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()],
Gabriel Detraz's avatar
Gabriel Detraz committed
419
            }
420
            for i in Interface.objects.all() if i.ipv6
421
        }