Ce serveur Gitlab sera éteint le 30 juin 2020, pensez à migrer vos projets vers les serveurs gitlab-research.centralesupelec.fr et gitlab-student.centralesupelec.fr !

Commit 80456455 authored by grizzly's avatar grizzly

Merge branch 'switch_conf' into 'dev'

Switch conf

See merge request federez/re2o!308
parents 916ec978 42d2f804
......@@ -153,7 +153,8 @@ class VlanSerializer(NamespacedHMSerializer):
"""
class Meta:
model = machines.Vlan
fields = ('vlan_id', 'name', 'comment', 'api_url')
fields = ('vlan_id', 'name', 'comment', 'arp_protect', 'dhcp_snooping',
'dhcpv6_snooping', 'igmp', 'mld', 'api_url')
class NasSerializer(NamespacedHMSerializer):
......@@ -310,6 +311,16 @@ class OuverturePortSerializer(NamespacedHMSerializer):
fields = ('begin', 'end', 'port_list', 'protocole', 'io', 'api_url')
class RoleSerializer(NamespacedHMSerializer):
"""Serialize `machines.models.OuverturePort` objects.
"""
servers = InterfaceSerializer(read_only=True, many=True)
class Meta:
model = machines.Role
fields = ('role_type', 'servers', 'api_url')
# PREFERENCES
......@@ -338,11 +349,15 @@ class OptionalMachineSerializer(NamespacedHMSerializer):
class OptionalTopologieSerializer(NamespacedHMSerializer):
"""Serialize `preferences.models.OptionalTopologie` objects.
"""
switchs_management_interface_ip = serializers.CharField()
class Meta:
model = preferences.OptionalTopologie
fields = ('radius_general_policy', 'vlan_decision_ok',
'vlan_decision_nok')
'vlan_decision_nok', 'switchs_ip_type', 'switchs_web_management',
'switchs_web_management_ssl', 'switchs_rest_management',
'switchs_management_utils', 'switchs_management_interface_ip',
'provision_switchs_enabled', 'switchs_provision', 'switchs_management_sftp_creds')
class GeneralOptionSerializer(NamespacedHMSerializer):
......@@ -467,16 +482,30 @@ class BuildingSerializer(NamespacedHMSerializer):
class SwitchPortSerializer(NamespacedHMSerializer):
"""Serialize `topologie.models.Port` objects
"""
get_port_profil = NamespacedHIField(view_name='portprofile-detail', read_only=True)
class Meta:
model = topologie.Port
fields = ('switch', 'port', 'room', 'machine_interface', 'related',
'custom_profile', 'state', 'details', 'api_url')
'custom_profile', 'state', 'get_port_profil', 'details', 'api_url')
extra_kwargs = {
'related': {'view_name': 'switchport-detail'},
'api_url': {'view_name': 'switchport-detail'},
}
class PortProfileSerializer(NamespacedHMSerializer):
"""Serialize `topologie.models.Room` objects
"""
class Meta:
model = topologie.PortProfile
fields = ('name', 'profil_default', 'vlan_untagged', 'vlan_tagged',
'radius_type', 'radius_mode', 'speed', 'mac_limit', 'flow_control',
'dhcp_snooping', 'dhcpv6_snooping', 'dhcpv6_snooping', 'arp_protect',
'ra_guard', 'loop_protect', 'api_url')
class RoomSerializer(NamespacedHMSerializer):
"""Serialize `topologie.models.Room` objects
"""
......@@ -644,6 +673,89 @@ class ServiceRegenSerializer(NamespacedHMSerializer):
'api_url': {'view_name': 'serviceregen-detail'}
}
# Switches et ports
class InterfaceVlanSerializer(NamespacedHMSerializer):
domain = serializers.CharField(read_only=True)
ipv4 = serializers.CharField(read_only=True)
ipv6 = Ipv6ListSerializer(read_only=True, many=True)
vlan_id = serializers.IntegerField(source='type.ip_type.vlan.vlan_id', read_only=True)
class Meta:
model = machines.Interface
fields = ('ipv4', 'ipv6', 'domain', 'vlan_id')
class InterfaceRoleSerializer(NamespacedHMSerializer):
interface = InterfaceVlanSerializer(source='machine.interface_set', read_only=True, many=True)
class Meta:
model = machines.Interface
fields = ('interface',)
class RoleSerializer(NamespacedHMSerializer):
"""Serialize `machines.models.OuverturePort` objects.
"""
servers = InterfaceRoleSerializer(read_only=True, many=True)
class Meta:
model = machines.Role
fields = ('role_type', 'servers', 'specific_role')
class VlanPortSerializer(NamespacedHMSerializer):
class Meta:
model = machines.Vlan
fields = ('vlan_id', 'name')
class ProfilSerializer(NamespacedHMSerializer):
vlan_untagged = VlanSerializer(read_only=True)
vlan_tagged = VlanPortSerializer(read_only=True, many=True)
class Meta:
model = topologie.PortProfile
fields = ('name', 'profil_default', 'vlan_untagged', 'vlan_tagged', 'radius_type', 'radius_mode', 'speed', 'mac_limit', 'flow_control', 'dhcp_snooping', 'dhcpv6_snooping', 'arp_protect', 'ra_guard', 'loop_protect', 'vlan_untagged', 'vlan_tagged')
class ModelSwitchSerializer(NamespacedHMSerializer):
constructor = serializers.CharField(read_only=True)
class Meta:
model = topologie.ModelSwitch
fields = ('reference', 'firmware', 'constructor')
class SwitchBaySerializer(NamespacedHMSerializer):
class Meta:
model = topologie.SwitchBay
fields = ('name',)
class PortsSerializer(NamespacedHMSerializer):
"""Serialize `machines.models.Ipv6List` objects.
"""
get_port_profil = ProfilSerializer(read_only=True)
class Meta:
model = topologie.Port
fields = ('state', 'port', 'pretty_name', 'get_port_profil')
class SwitchPortSerializer(serializers.ModelSerializer):
"""Serialize the data about the switches"""
ports = PortsSerializer(many=True, read_only=True)
model = ModelSwitchSerializer(read_only=True)
switchbay = SwitchBaySerializer(read_only=True)
class Meta:
model = topologie.Switch
fields = ('short_name', 'model', 'switchbay', 'ports', 'ipv4', 'ipv6',
'interfaces_subnet', 'interfaces6_subnet', 'automatic_provision', 'rest_enabled',
'web_management_enabled', 'get_radius_key_value', 'get_management_cred_value')
# LOCAL EMAILS
......
......@@ -63,6 +63,7 @@ router.register_viewset(r'machines/service', views.ServiceViewSet)
router.register_viewset(r'machines/servicelink', views.ServiceLinkViewSet, base_name='servicelink')
router.register_viewset(r'machines/ouvertureportlist', views.OuverturePortListViewSet)
router.register_viewset(r'machines/ouvertureport', views.OuverturePortViewSet)
router.register_viewset(r'machines/role', views.RoleViewSet)
# PREFERENCES
router.register_view(r'preferences/optionaluser', views.OptionalUserView),
router.register_view(r'preferences/optionalmachine', views.OptionalMachineView),
......@@ -81,7 +82,8 @@ router.register_viewset(r'topologie/modelswitch', views.ModelSwitchViewSet)
router.register_viewset(r'topologie/constructorswitch', views.ConstructorSwitchViewSet)
router.register_viewset(r'topologie/switchbay', views.SwitchBayViewSet)
router.register_viewset(r'topologie/building', views.BuildingViewSet)
router.register(r'topologie/switchport', views.SwitchPortViewSet, base_name='switchport')
router.register_viewset(r'topologie/switchport', views.SwitchPortViewSet, base_name='switchport')
router.register_viewset(r'topologie/portprofile', views.PortProfileViewSet, base_name='portprofile')
router.register_viewset(r'topologie/room', views.RoomViewSet)
router.register(r'topologie/portprofile', views.PortProfileViewSet)
# USERS
......@@ -105,6 +107,9 @@ router.register_view(r'localemail/users', views.LocalEmailUsersView),
# Firewall
router.register_view(r'firewall/subnet-ports', views.SubnetPortsOpenView),
router.register_view(r'firewall/interface-ports', views.InterfacePortsOpenView),
# Switches config
router.register_view(r'switchs/ports-config', views.SwitchPortView),
router.register_view(r'switchs/role', views.RoleView),
# DNS
router.register_view(r'dns/zones', views.DNSZonesView),
router.register_view(r'dns/reverse-zones', views.DNSReverseZonesView),
......
......@@ -242,6 +242,13 @@ class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = serializers.OuverturePortSerializer
class RoleViewSet(viewsets.ReadOnlyModelViewSet):
"""Exposes list and details of `machines.models.Machine` objects.
"""
queryset = machines.Role.objects.all()
serializer_class = serializers.RoleSerializer
# PREFERENCES
# Those views differ a bit because there is only one object
# to display, so we don't bother with the listing part
......@@ -397,6 +404,13 @@ class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = serializers.SwitchPortSerializer
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
"""Exposes list and details of `topologie.models.PortProfile` objects.
"""
queryset = topologie.PortProfile.objects.all()
serializer_class = serializers.PortProfileSerializer
class RoomViewSet(viewsets.ReadOnlyModelViewSet):
"""Exposes list and details of `topologie.models.Room` objects.
"""
......@@ -515,6 +529,24 @@ class ServiceRegenViewSet(viewsets.ModelViewSet):
queryset = queryset.filter(server__domain__name__iexact=hostname)
return queryset
# Config des switches
class SwitchPortView(generics.ListAPIView):
"""Exposes the associations between hostname, mac address and IPv4 in
order to build the DHCP lease files.
"""
queryset = topologie.Switch.objects.all().select_related("switchbay").select_related("model__constructor").prefetch_related("ports__custom_profile__vlan_tagged").prefetch_related("ports__custom_profile__vlan_untagged").prefetch_related("ports__machine_interface__domain__extension").prefetch_related("ports__room")
serializer_class = serializers.SwitchPortSerializer
class RoleView(generics.ListAPIView):
"""Exposes the associations between hostname, mac address and IPv4 in
order to build the DHCP lease files.
"""
queryset = machines.Role.objects.all().prefetch_related('servers')
serializer_class = serializers.RoleSerializer
# LOCAL EMAILS
......
......@@ -576,13 +576,24 @@ class VlanForm(FormRevMixin, ModelForm):
"""Ajout d'un vlan : id, nom"""
class Meta:
model = Vlan
fields = '__all__'
fields = ['vlan_id', 'name', 'comment']
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(VlanForm, self).__init__(*args, prefix=prefix, **kwargs)
class EditOptionVlanForm(FormRevMixin, ModelForm):
"""Ajout d'un vlan : id, nom"""
class Meta:
model = Vlan
fields = ['dhcp_snooping', 'dhcpv6_snooping', 'arp_protect', 'igmp', 'mld']
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(EditOptionVlanForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelVlanForm(FormRevMixin, Form):
"""Suppression d'un ou plusieurs vlans"""
vlan = forms.ModelMultipleChoiceField(
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-09-19 20:25
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('machines', '0094_auto_20180815_1918'),
]
operations = [
migrations.AddField(
model_name='vlan',
name='arp_protect',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='vlan',
name='dhcp_snooping',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='vlan',
name='dhcpv6_snooping',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='vlan',
name='igmp',
field=models.BooleanField(default=False, help_text='Gestion multicast v4'),
),
migrations.AddField(
model_name='vlan',
name='mld',
field=models.BooleanField(default=False, help_text='Gestion multicast v6'),
),
]
......@@ -201,6 +201,12 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
de cette machine"""
return str(self.interface_set.first().domain.name)
@cached_property
def complete_name(self):
"""Par defaut, renvoie le nom de la première interface
de cette machine"""
return str(self.interface_set.first())
@cached_property
def all_short_names(self):
"""Renvoie de manière unique, le nom des interfaces de cette
......@@ -515,6 +521,18 @@ class Vlan(RevMixin, AclMixin, models.Model):
vlan_id = models.PositiveIntegerField(validators=[MaxValueValidator(4095)])
name = models.CharField(max_length=256)
comment = models.CharField(max_length=256, blank=True)
#Réglages supplémentaires
arp_protect = models.BooleanField(default=False)
dhcp_snooping = models.BooleanField(default=False)
dhcpv6_snooping = models.BooleanField(default=False)
igmp = models.BooleanField(
default=False,
help_text="Gestion multicast v4"
)
mld = models.BooleanField(
default=False,
help_text="Gestion multicast v6"
)
class Meta:
permissions = (
......@@ -1634,6 +1652,19 @@ class Role(RevMixin, AclMixin, models.Model):
machine__interface__role=cls.objects.filter(specific_role=roletype)
)
@classmethod
def get_instance(cls, machineid, *_args, **_kwargs):
"""Get the Machine instance with machineid.
:param userid: The id
:return: The user
"""
return cls.objects.get(pk=machineid)
@classmethod
def interface_for_roletype(cls, roletype):
"""Return interfaces for a roletype"""
return Interface.objects.filter(role=cls.objects.filter(specific_role=roletype))
def save(self, *args, **kwargs):
super(Role, self).save(*args, **kwargs)
......
......@@ -37,7 +37,10 @@ from .models import (
MailContact,
AssoOption,
MailMessageOption,
HomeOption
HomeOption,
RadiusKey,
SwitchManagementCred,
Reminder
)
......@@ -86,6 +89,18 @@ class HomeOptionAdmin(VersionAdmin):
pass
class RadiusKeyAdmin(VersionAdmin):
"""Class radiuskey"""
pass
class SwitchManagementCredAdmin(VersionAdmin):
"""Class managementcred for switch"""
pass
class ReminderAdmin(VersionAdmin):
"""Class reminder for switch"""
pass
admin.site.register(OptionalUser, OptionalUserAdmin)
admin.site.register(OptionalMachine, OptionalMachineAdmin)
admin.site.register(OptionalTopologie, OptionalTopologieAdmin)
......@@ -93,5 +108,8 @@ admin.site.register(GeneralOption, GeneralOptionAdmin)
admin.site.register(HomeOption, HomeOptionAdmin)
admin.site.register(Service, ServiceAdmin)
admin.site.register(MailContact, MailContactAdmin)
admin.site.register(Reminder, ReminderAdmin)
admin.site.register(RadiusKey, RadiusKeyAdmin)
admin.site.register(SwitchManagementCred, SwitchManagementCredAdmin)
admin.site.register(AssoOption, AssoOptionAdmin)
admin.site.register(MailMessageOption, MailMessageOptionAdmin)
......@@ -38,9 +38,12 @@ from .models import (
MailMessageOption,
HomeOption,
Service,
MailContact
MailContact,
Reminder,
RadiusKey,
SwitchManagementCred,
)
from topologie.models import Switch
class EditOptionalUserForm(ModelForm):
"""Formulaire d'édition des options de l'user. (solde, telephone..)"""
......@@ -92,7 +95,14 @@ class EditOptionalMachineForm(ModelForm):
class EditOptionalTopologieForm(ModelForm):
"""Options de topologie, formulaire d'edition (vlan par default etc)"""
"""Options de topologie, formulaire d'edition (vlan par default etc)
On rajoute un champ automatic provision switchs pour gérer facilement
l'ajout de switchs au provisionning automatique"""
automatic_provision_switchs = forms.ModelMultipleChoiceField(
Switch.objects.all(),
required=False
)
class Meta:
model = OptionalTopologie
fields = '__all__'
......@@ -110,6 +120,14 @@ class EditOptionalTopologieForm(ModelForm):
self.fields['vlan_decision_nok'].label = _("VLAN for machines rejected"
" by RADIUS")
self.initial['automatic_provision_switchs'] = Switch.objects.filter(automatic_provision=True)
def save(self, commit=True):
instance = super().save(commit)
Switch.objects.all().update(automatic_provision=False)
self.cleaned_data['automatic_provision_switchs'].update(automatic_provision=True)
return instance
class EditGeneralOptionForm(ModelForm):
"""Options générales (affichages de résultats de recherche, etc)"""
......@@ -242,8 +260,68 @@ class DelServiceForm(Form):
else:
self.fields['services'].queryset = Service.objects.all()
class MailContactForm(FormRevMixin, ModelForm):
"""Edit and add contact email adress"""
class ReminderForm(FormRevMixin, ModelForm):
"""Edition, ajout de services sur la page d'accueil"""
class Meta:
model = Reminder
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(ReminderForm, self).__init__(*args, prefix=prefix, **kwargs)
class RadiusKeyForm(FormRevMixin, ModelForm):
"""Edition, ajout de clef radius"""
members = forms.ModelMultipleChoiceField(
queryset=Switch.objects.all(),
required=False
)
class Meta:
model = RadiusKey
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(RadiusKeyForm, self).__init__(*args, prefix=prefix, **kwargs)
instance = kwargs.get('instance', None)
if instance:
self.initial['members'] = Switch.objects.filter(radius_key=instance)
def save(self, commit=True):
instance = super().save(commit)
instance.switch_set = self.cleaned_data['members']
return instance
class SwitchManagementCredForm(FormRevMixin, ModelForm):
"""Edition, ajout de creds de management pour gestion
et interface rest des switchs"""
members = forms.ModelMultipleChoiceField(
Switch.objects.all(),
required=False
)
class Meta:
model = SwitchManagementCred
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(SwitchManagementCredForm, self).__init__(*args, prefix=prefix, **kwargs)
instance = kwargs.get('instance', None)
if instance:
self.initial['members'] = Switch.objects.filter(management_creds=instance)
def save(self, commit=True):
instance = super().save(commit)
instance.switch_set = self.cleaned_data['members']
return instance
class MailContactForm(ModelForm):
"""Edition, ajout d'adresse de contact"""
class Meta:
model = MailContact
fields = '__all__'
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-09-19 20:25
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import re2o.aes_field
import re2o.mixins
class Migration(migrations.Migration):
dependencies = [
('machines', '0095_auto_20180919_2225'),
('preferences', '0050_auto_20180818_1329'),
]
operations = [
migrations.CreateModel(
name='RadiusKey',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('radius_key', re2o.aes_field.AESEncryptedField(help_text='Clef radius', max_length=255)),
('comment', models.CharField(blank=True, help_text='Commentaire de cette clef', max_length=255, null=True)),
('default_switch', models.BooleanField(default=True, help_text='Clef par défaut des switchs', unique=True)),
],
options={
'permissions': (('view_radiuskey', 'Peut voir un objet radiuskey'),),
},
bases=(re2o.mixins.AclMixin, models.Model),
),
migrations.CreateModel(
name='Reminder',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('days', models.IntegerField(default=7, help_text="Délais entre le mail et la fin d'adhésion", unique=True)),
('message', models.CharField(blank=True, default='', help_text='Message affiché spécifiquement pour ce rappel', max_length=255, null=True)),
],
options={
'permissions': (('view_reminder', 'Peut voir un objet reminder'),),
},
bases=(re2o.mixins.AclMixin, models.Model),
),
migrations.CreateModel(
name='SwitchManagementCred',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('management_id', models.CharField(help_text='Login du switch', max_length=63)),
('management_pass', re2o.aes_field.AESEncryptedField(help_text='Mot de passe', max_length=63)),
('default_switch', models.BooleanField(default=True, help_text='Creds par défaut des switchs', unique=True)),
],
options={
'permissions': (('view_switchmanagementcred', 'Peut voir un objet switchmanagementcred'),),
},
bases=(re2o.mixins.AclMixin, models.Model),
),
migrations.AddField(
model_name='optionaltopologie',
name='sftp_login',
field=models.CharField(blank=True, help_text='Login sftp des switchs', max_length=32, null=True),
),
migrations.AddField(
model_name='optionaltopologie',
name='sftp_pass',
field=re2o.aes_field.AESEncryptedField(blank=True, help_text='Mot de passe sftp', max_length=63, null=True),
),
migrations.AddField(
model_name='optionaltopologie',
name='switchs_ip_type',
field=models.OneToOneField(blank=True, help_text="Plage d'ip de management des switchs", null=True, on_delete=django.db.models.deletion.PROTECT, to='machines.IpType'),
),
migrations.AddField(
model_name='optionaltopologie',
name='switchs_provision',
field=models.CharField(choices=[('sftp', 'sftp'), ('tftp', 'tftp')], default='tftp', help_text='Mode de récupération des confs par les switchs', max_length=32),
),
migrations.AddField(
model_name='optionaltopologie',
name='switchs_rest_management',
field=models.BooleanField(default=False, help_text='Rest management, activé si provision auto'),
),
migrations.AddField(
model_name='optionaltopologie',
name='switchs_web_management',
field=models.BooleanField(default=False, help_text='Web management, activé si provision automatique'),
),
migrations.AddField(
model_name='optionaltopologie',
name='switchs_web_management_ssl',
field=models.BooleanField(default=False, help_text='Web management ssl. Assurez-vous que un certif est installé sur le switch !'),
),
migrations.AlterField(
model_name='mailmessageoption',
name='welcome_mail_en',
field=models.TextField(default='', help_text='Mail de bienvenue en anglais'),
),
migrations.AlterField(
model_name='mailmessageoption',
name='welcome_mail_fr',
field=models.TextField(default='', help_text='Mail de bienvenue en français'),
),
]
......@@ -34,7 +34,10 @@ from django.forms import ValidationError
from django.utils.translation import ugettext_lazy as _
import machines.models
from re2o.mixins import AclMixin
from re2o.aes_field import AESEncryptedField
from datetime import timedelta
class PreferencesModel(models.Model):
......@@ -180,6 +183,10 @@ class OptionalTopologie(AclMixin, PreferencesModel):
(MACHINE, _("On the IP range's VLAN of the machine")),
(DEFINED, _("Preset in 'VLAN for machines accepted by RADIUS'")),
)
CHOICE_PROVISION = (
('sftp', 'sftp'),
('tftp', 'tftp'),
)
radius_general_policy = models.CharField(
max_length=32,
......@@ -200,6 +207,97 @@ class OptionalTopologie(AclMixin, PreferencesModel):
blank=True,
null=True
)
switchs_web_management = models.BooleanField(
default=False,
help_text="Web management, activé si provision automatique"
)
switchs_web_management_ssl = models.BooleanField(
default=False,
help_text="Web management ssl. Assurez-vous que un certif est installé sur le switch !"
)
switchs_rest_management = models.BooleanField(
default=False,
help_text="Rest management, activé si provision auto"
)
switchs_ip_type = models.OneToOneField(
'machines.IpType',
on_delete=models.PROTECT,
blank=True,
null=True,
help_text="Plage d'ip de management des switchs"
)
switchs_provision = models.CharField(
max_length=32,
choices=CHOICE_PROVISION,
default='tftp',
help_text="Mode de récupération des confs par les switchs"
)
sftp_login = models.CharField(
max_length=32,
null=True,
blank=True,
help_text="Login sftp des switchs"
)
sftp_pass = AESEncryptedField(
max_length=63,
null=True,
blank=True,
help_text="Mot de passe sftp"
)
@cached_property
def provisioned_switchs(self):
"""Liste des switches provisionnés"""
from topologie.models import Switch
return Switch.objects.filter(automatic_provision=True)
@cached_property
def switchs_management_interface(self):
"""Return the ip of the interface that the switch have to contact to get it's config"""
if self.switchs_ip_type:
from machines.models import Role, Interface
return Interface.objects.filter(machine__interface__in=Role.interface_for_roletype("switch-conf-server")).filter(type__ip_type=self.switchs_ip_type).first()
else:
return None
@cached_property
def switchs_management_interface_ip(self):
"""Same, but return the ipv4"""
if not self.switchs_management_interface:
return None
return self.switchs_management_interface.ipv4
@cached_property
def switchs_management_sftp_creds(self):
"""Credentials des switchs pour provion sftp"""
if self.sftp_login and self.sftp_pass:
return {'login' : self.sftp_login, 'pass' : self.sftp_pass}
else:
return None
@cached_property