diff --git a/src/ralph/data_center/models/mixins.py b/src/ralph/data_center/models/mixins.py new file mode 100644 index 0000000000..22eea44e51 --- /dev/null +++ b/src/ralph/data_center/models/mixins.py @@ -0,0 +1,51 @@ +from ralph.networks.models import IPAddress + + +class WithManagementIPMixin(object): + def _get_management_ip(self): + eth = self.ethernet_set.select_related('ipaddress').filter( + ipaddress__is_management=True + ).first() + if eth: + return eth.ipaddress + return None + + def _get_or_create_management_ip(self): + ip = self._get_management_ip() + if not ip: + eth = self.ethernet_set.create() + ip = IPAddress(ethernet=eth, is_management=True) + return ip + + @property + def management_ip(self): + ip = self._get_management_ip() + if ip: + return ip.address + return '' + + @management_ip.setter + def management_ip(self, value): + ip = self._get_or_create_management_ip() + ip.address = value + ip.save() + + @management_ip.deleter + def management_ip(self): + ip = self._get_management_ip() + if ip: + ip.delete() + ip.ethernet.delete() + + @property + def management_hostname(self): + ip = self._get_management_ip() + if ip: + return ip.hostname or '' + return '' + + @management_hostname.setter + def management_hostname(self, value): + ip = self._get_or_create_management_ip() + ip.hostname = value + ip.save() diff --git a/src/ralph/data_center/models/physical.py b/src/ralph/data_center/models/physical.py index 3cadb53448..3a5c05e08c 100644 --- a/src/ralph/data_center/models/physical.py +++ b/src/ralph/data_center/models/physical.py @@ -28,6 +28,7 @@ Orientation, RackOrientation ) +from ralph.data_center.models.mixins import WithManagementIPMixin from ralph.lib.mixins.models import AdminAbsoluteUrlMixin from ralph.lib.transitions.decorators import transition_action from ralph.lib.transitions.fields import TransitionField @@ -327,7 +328,12 @@ class Meta: abstract = True -class DataCenterAsset(NetworkableBaseObject, AutocompleteTooltipMixin, Asset): +class DataCenterAsset( + WithManagementIPMixin, + NetworkableBaseObject, + AutocompleteTooltipMixin, + Asset +): _allow_in_dashboard = True rack = models.ForeignKey(Rack, null=True, blank=True) @@ -434,54 +440,6 @@ def cores_count(self): asset_cores_count = self.model.cores_count if self.model else 0 return asset_cores_count - def _get_management_ip(self): - eth = self.ethernet_set.select_related('ipaddress').filter( - ipaddress__is_management=True - ).first() - if eth: - return eth.ipaddress - return None - - def _get_or_create_management_ip(self): - ip = self._get_management_ip() - if not ip: - eth = self.ethernet_set.create() - ip = IPAddress(ethernet=eth, is_management=True) - return ip - - @property - def management_ip(self): - ip = self._get_management_ip() - if ip: - return ip.address - return '' - - @management_ip.setter - def management_ip(self, value): - ip = self._get_or_create_management_ip() - ip.address = value - ip.save() - - @management_ip.deleter - def management_ip(self): - ip = self._get_management_ip() - if ip: - ip.delete() - ip.ethernet.delete() - - @property - def management_hostname(self): - ip = self._get_management_ip() - if ip: - return ip.hostname or '' - return '' - - @management_hostname.setter - def management_hostname(self, value): - ip = self._get_or_create_management_ip() - ip.hostname = value - ip.save() - @cached_property def location(self): """ diff --git a/src/ralph/data_center/models/virtual.py b/src/ralph/data_center/models/virtual.py index 94c10fc1b5..e2cdb9ca03 100644 --- a/src/ralph/data_center/models/virtual.py +++ b/src/ralph/data_center/models/virtual.py @@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _ from ralph.assets.models.base import BaseObject +from ralph.data_center.models.mixins import WithManagementIPMixin from ralph.lib.mixins.fields import BaseObjectForeignKey, NullableCharField from ralph.lib.mixins.models import NamedMixin from ralph.lib.transitions.fields import TransitionField @@ -46,7 +47,7 @@ class ClusterStatus(Choices): for_deploy = _('for deploy') -class Cluster(BaseObject, models.Model): +class Cluster(WithManagementIPMixin, BaseObject, models.Model): name = models.CharField(_('name'), max_length=255, blank=True, null=True) hostname = NullableCharField( unique=True, diff --git a/src/ralph/ralph2_sync/subscribers.py b/src/ralph/ralph2_sync/subscribers.py index ed2bbcb60a..64b716a072 100644 --- a/src/ralph/ralph2_sync/subscribers.py +++ b/src/ralph/ralph2_sync/subscribers.py @@ -109,27 +109,27 @@ def _get_configuration_path_from_venture_role(venture_role_id): return None -def _handle_management_ip(dca, management_ip, management_hostname): +def _handle_management_ip(obj, management_ip, management_hostname): if management_ip: try: ip = IPAddress.objects.get(address=management_ip) except IPAddress.DoesNotExist: - dca.management_ip = management_ip + obj.management_ip = management_ip else: - ip.ethernet.base_object = dca + ip.ethernet.base_object = obj ip.ethernet.save() ip.is_management = True ip.save() - dca.management_hostname = management_hostname - dca.save() + obj.management_hostname = management_hostname + obj.save() else: - if dca.management_ip: + if obj.management_ip: logger.warning( 'Removing management IP {} from {}'.format( - dca.management_ip, dca + obj.management_ip, obj ) ) - del dca.management_ip + del obj.management_ip def _handle_ips(obj, ips): diff --git a/src/ralph/ralph2_sync/tests/test_subscribers.py b/src/ralph/ralph2_sync/tests/test_subscribers.py index 1874960371..24dff9b729 100644 --- a/src/ralph/ralph2_sync/tests/test_subscribers.py +++ b/src/ralph/ralph2_sync/tests/test_subscribers.py @@ -732,3 +732,48 @@ def test_stacked_switch_subscriber_for_existing_obj(self): ss.baseobjectcluster_set.get(is_master=True).base_object.pk, self.child2.pk ) + + def test_handle_management_ips(self): + ss = _create_imported_object( + factory=ClusterFactory, old_id=self.data['id'], + factory_kwargs={'type__name': self.data['type']} + ) + data = { + 'id': self.data['id'], + 'ips': [ + { + 'address': '10.20.30.40', + 'hostname': 'mgmt-1.net', + 'is_management': True, + 'mac': None, + 'dhcp_expose': False + }, + ], + } + sync_stacked_switch_to_ralph3(data) + ss.refresh_from_db() + self.assertEqual(ss.management_ip, '10.20.30.40') + + def test_handle_new_ip(self): + ss = _create_imported_object( + factory=ClusterFactory, old_id=self.data['id'], + factory_kwargs={'type__name': self.data['type']} + ) + data = { + 'id': self.data['id'], + 'ips': [ + { + 'address': '10.20.30.40', + 'hostname': 'foo-bar.net', + 'is_management': False, + 'mac': '31:8F:A1:2B:7F:80', + 'dhcp_expose': False + }, + ], + } + sync_stacked_switch_to_ralph3(data) + ss.refresh_from_db() + self.assertEqual( + IPAddress.objects.get(address='10.20.30.40').ethernet.base_object.pk, # noqa + ss.pk + )