Maintenance électrique le 12 août, nos services, et y compris Gitlab, seront fortement impactés autour de cette date. Retour à un état normal prévu dans le milieu de la semaine prochaine.

serializers.py 13.7 KB
Newer Older
1
# -*- mode: python; coding: utf-8 -*-
2 3 4 5 6
# 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
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
7
# Copyright © 2017  Lara Kermarec
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 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.

Maël Kervella's avatar
Maël Kervella committed
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
    OuverturePort,
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
43
    Ipv6List,
Gabriel Detraz's avatar
Gabriel Detraz committed
44 45
)

Dalahro's avatar
Dalahro committed
46

Dalahro's avatar
Dalahro committed
47
class IpTypeField(serializers.RelatedField):
48 49
    """ Serializer for an IpType object field """

Dalahro's avatar
Dalahro committed
50
    def to_representation(self, value):
51
        return str(value)
Dalahro's avatar
Dalahro committed
52

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

Gabriel Detraz's avatar
Gabriel Detraz committed
56

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

Dalahro's avatar
Dalahro committed
60 61 62 63
    ip_type = IpTypeField(read_only=True)

    class Meta:
        model = IpList
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
64
        fields = ("ipv4", "ip_type")
Dalahro's avatar
Dalahro committed
65

Gabriel Detraz's avatar
Gabriel Detraz committed
66

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

70 71
    class Meta:
        model = Ipv6List
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
72
        fields = ("ipv6", "slaac_ip")
73 74


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

Dalahro's avatar
Dalahro committed
79
    ipv4 = IpListSerializer(read_only=True)
80
    # TODO : use serializer.RelatedField to avoid duplicate code
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
81 82 83
    mac_address = serializers.SerializerMethodField("get_macaddress")
    domain = serializers.SerializerMethodField("get_dns")
    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
Hugo Levy-Falk's avatar
Hugo Levy-Falk 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
Dalahro's avatar
Dalahro committed
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
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
112 113 114
    mac_address = serializers.SerializerMethodField("get_macaddress")
    domain = serializers.SerializerMethodField("get_dns")
    extension = serializers.SerializerMethodField("get_interface_extension")
Gabriel Detraz's avatar
Gabriel Detraz committed
115 116 117

    class Meta:
        model = Interface
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
118
        fields = ("ipv4", "ipv6", "mac_address", "domain", "extension")
Gabriel Detraz's avatar
Gabriel Detraz committed
119

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

Dalahro's avatar
Dalahro committed
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)
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
151 152 153 154 155 156 157 158 159 160 161 162
    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"
    )
163

root's avatar
root committed
164 165
    class Meta:
        model = IpType
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
166
        fields = (
167
            "name",
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
168 169 170 171 172 173 174 175 176
            "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",
        )
177

178 179 180 181
    @staticmethod
    def get_port_policy(obj, protocole, io):
        """ Generic utility function to get the policy for a given
        port, protocole and IN or OUT """
182
        if obj.ouverture_ports is None:
183
            return []
Gabriel Detraz's avatar
Gabriel Detraz committed
184 185
        return map(
            str,
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
186 187 188
            obj.ouverture_ports.ouvertureport_set.filter(protocole=protocole).filter(
                io=io
            ),
Gabriel Detraz's avatar
Gabriel Detraz committed
189
        )
190 191

    def get_port_policy_input_tcp(self, obj):
Gabriel Detraz's avatar
Gabriel Detraz committed
192
        """Renvoie la liste des ports ouverts en entrée tcp"""
193 194 195
        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
196
        """Renvoie la liste des ports ouverts en sortie tcp"""
197 198 199
        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
200
        """Renvoie la liste des ports ouverts en entrée udp"""
201 202 203
        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
204
        """Renvoie la liste des ports ouverts en sortie udp"""
205
        return self.get_port_policy(obj, OuverturePort.UDP, OuverturePort.OUT)
root's avatar
root committed
206

Gabriel Detraz's avatar
Gabriel Detraz committed
207

208
class ExtensionSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
209 210
    """Serialisation d'une extension : origin_ip et la zone sont
    des foreign_key donc evalués en get_..."""
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
211 212 213 214

    origin = serializers.SerializerMethodField("get_origin_ip")
    zone_entry = serializers.SerializerMethodField("get_zone_name")
    soa = serializers.SerializerMethodField("get_soa_data")
215 216 217

    class Meta:
        model = Extension
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
218
        fields = ("name", "origin", "origin_v6", "zone_entry", "soa")
219

220 221 222 223
    @staticmethod
    def get_origin_ip(obj):
        """ The IP of the associated origin for the zone """
        return obj.origin.ipv4
224

225 226 227
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone """
228 229
        return str(obj.dns_entry)

230 231 232
    @staticmethod
    def get_soa_data(obj):
        """ The representation of the associated SOA """
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
233
        return {"mail": obj.soa.dns_soa_mail, "param": obj.soa.dns_soa_param}
234

Gabriel Detraz's avatar
Gabriel Detraz committed
235

236
class MxSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
237 238
    """Serialisation d'un MX, evaluation du nom, de la zone
    et du serveur cible, etant des foreign_key"""
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
239 240 241 242

    name = serializers.SerializerMethodField("get_entry_name")
    zone = serializers.SerializerMethodField("get_zone_name")
    mx_entry = serializers.SerializerMethodField("get_mx_name")
Dalahro's avatar
Dalahro committed
243

Dalahro's avatar
Dalahro committed
244
    class Meta:
245
        model = Mx
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
246
        fields = ("zone", "priority", "name", "mx_entry")
247

248 249 250
    @staticmethod
    def get_entry_name(obj):
        """ The name of the DNS MX entry """
Mael Kervella's avatar
Mael Kervella committed
251
        return str(obj.name)
252

253 254 255
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone of the MX record """
256 257
        return obj.zone.name

258 259 260
    @staticmethod
    def get_mx_name(obj):
        """ The string representation of the entry to add to the DNS """
261 262
        return str(obj.dns_entry)

Gabriel Detraz's avatar
Gabriel Detraz committed
263

Gabriel Detraz's avatar
Gabriel Detraz committed
264
class TxtSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
265 266
    """Serialisation d'un txt : zone cible et l'entrée txt
    sont evaluées à part"""
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
267 268 269

    zone = serializers.SerializerMethodField("get_zone_name")
    txt_entry = serializers.SerializerMethodField("get_txt_name")
Gabriel Detraz's avatar
Gabriel Detraz committed
270 271

    class Meta:
Gabriel Detraz's avatar
Gabriel Detraz committed
272
        model = Txt
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
273
        fields = ("zone", "txt_entry", "field1", "field2")
Gabriel Detraz's avatar
Gabriel Detraz committed
274

275 276 277
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone """
Gabriel Detraz's avatar
Gabriel Detraz committed
278 279
        return str(obj.zone.name)

280 281 282
    @staticmethod
    def get_txt_name(obj):
        """ The string representation of the entry to add to the DNS """
Gabriel Detraz's avatar
Gabriel Detraz committed
283
        return str(obj.dns_entry)
Gabriel Detraz's avatar
Gabriel Detraz committed
284 285 286 287


class SrvSerializer(serializers.ModelSerializer):
    """Serialisation d'un srv : zone cible et l'entrée txt"""
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
288 289 290

    extension = serializers.SerializerMethodField("get_extension_name")
    srv_entry = serializers.SerializerMethodField("get_srv_name")
Gabriel Detraz's avatar
Gabriel Detraz committed
291 292 293 294

    class Meta:
        model = Srv
        fields = (
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
295 296 297 298 299 300 301 302 303
            "service",
            "protocole",
            "extension",
            "ttl",
            "priority",
            "weight",
            "port",
            "target",
            "srv_entry",
Gabriel Detraz's avatar
Gabriel Detraz committed
304 305
        )

306 307 308
    @staticmethod
    def get_extension_name(obj):
        """ The name of the associated extension """
Gabriel Detraz's avatar
Gabriel Detraz committed
309 310
        return str(obj.extension.name)

311 312 313
    @staticmethod
    def get_srv_name(obj):
        """ The string representation of the entry to add to the DNS """
Gabriel Detraz's avatar
Gabriel Detraz committed
314
        return str(obj.dns_entry)
Gabriel Detraz's avatar
Gabriel Detraz committed
315

Gabriel Detraz's avatar
Gabriel Detraz committed
316

317
class NsSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
318 319
    """Serialisation d'un NS : la zone, l'entrée ns complète et le serveur
    ns sont évalués à part"""
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
320 321 322 323

    zone = serializers.SerializerMethodField("get_zone_name")
    ns = serializers.SerializerMethodField("get_domain_name")
    ns_entry = serializers.SerializerMethodField("get_text_name")
Dalahro's avatar
Dalahro committed
324

325
    class Meta:
326
        model = Ns
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
327
        fields = ("zone", "ns", "ns_entry")
328

329 330 331
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone """
332 333
        return obj.zone.name

334 335 336
    @staticmethod
    def get_domain_name(obj):
        """ The name of the associated NS target """
Mael Kervella's avatar
Mael Kervella committed
337
        return str(obj.ns)
338

339 340 341
    @staticmethod
    def get_text_name(obj):
        """ The string representation of the entry to add to the DNS """
342 343
        return str(obj.dns_entry)

Gabriel Detraz's avatar
Gabriel Detraz committed
344

chirac's avatar
chirac committed
345
class DomainSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
346 347
    """Serialisation d'un domain, extension, cname sont des foreign_key,
    et l'entrée complète, sont évalués à part"""
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
348 349 350 351

    extension = serializers.SerializerMethodField("get_zone_name")
    cname = serializers.SerializerMethodField("get_alias_name")
    cname_entry = serializers.SerializerMethodField("get_cname_name")
Dalahro's avatar
Dalahro committed
352

353
    class Meta:
chirac's avatar
chirac committed
354
        model = Domain
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
355
        fields = ("name", "extension", "cname", "cname_entry")
356

357 358 359
    @staticmethod
    def get_zone_name(obj):
        """ The name of the associated zone """
chirac's avatar
chirac committed
360
        return obj.extension.name
361

362 363 364
    @staticmethod
    def get_alias_name(obj):
        """ The name of the associated alias """
Mael Kervella's avatar
Mael Kervella committed
365
        return str(obj.cname)
chirac's avatar
chirac committed
366

367 368 369
    @staticmethod
    def get_cname_name(obj):
        """ The name of the associated CNAME target """
370 371
        return str(obj.dns_entry)

Gabriel Detraz's avatar
Gabriel Detraz committed
372

373
class ServiceServersSerializer(serializers.ModelSerializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
374
    """Evaluation d'un Service, et serialisation"""
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
375 376 377 378

    server = serializers.SerializerMethodField("get_server_name")
    service = serializers.SerializerMethodField("get_service_name")
    need_regen = serializers.SerializerMethodField("get_regen_status")
379 380 381

    class Meta:
        model = Service_link
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
382
        fields = ("server", "service", "need_regen")
383

384 385 386
    @staticmethod
    def get_server_name(obj):
        """ The name of the associated server """
387 388
        return str(obj.server.domain.name)

389 390 391
    @staticmethod
    def get_service_name(obj):
        """ The name of the service name """
392 393
        return str(obj.service)

394 395 396
    @staticmethod
    def get_regen_status(obj):
        """ The string representation of the regen status """
397
        return obj.need_regen
398

Gabriel Detraz's avatar
Gabriel Detraz committed
399

400
class OuverturePortsSerializer(serializers.Serializer):
Gabriel Detraz's avatar
Gabriel Detraz committed
401
    """Serialisation de l'ouverture des ports"""
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
402

403 404 405
    ipv4 = serializers.SerializerMethodField()
    ipv6 = serializers.SerializerMethodField()

406 407 408 409 410 411 412 413 414 415 416
    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
417
    def get_ipv4():
418
        """ The representation of the policy for the IPv4 addresses """
Maël Kervella's avatar
Maël Kervella committed
419 420 421
        return {
            i.ipv4.ipv4: {
                "tcp_in": [j.tcp_ports_in() for j in i.port_lists.all()],
erdnaxe's avatar
erdnaxe committed
422
                "tcp_out": [j.tcp_ports_out() for j in i.port_lists.all()],
Maël Kervella's avatar
Maël Kervella committed
423 424
                "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
425
            }
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
426 427
            for i in Interface.objects.all()
            if i.ipv4
428
        }
Gabriel Detraz's avatar
Gabriel Detraz committed
429

430
    @staticmethod
431
    def get_ipv6():
432
        """ The representation of the policy for the IPv6 addresses """
Maël Kervella's avatar
Maël Kervella committed
433 434 435
        return {
            i.ipv6: {
                "tcp_in": [j.tcp_ports_in() for j in i.port_lists.all()],
erdnaxe's avatar
erdnaxe committed
436
                "tcp_out": [j.tcp_ports_out() for j in i.port_lists.all()],
Maël Kervella's avatar
Maël Kervella committed
437 438
                "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
439
            }
Hugo Levy-Falk's avatar
Hugo Levy-Falk committed
440 441
            for i in Interface.objects.all()
            if i.ipv6
442
        }