예제 #1
0
    def get(self, request, *args, **kwargs):
        """Trigger regeneration of machine-related/service files."""
        fqdn = request.GET.get('fqdn', None)
        option = request.GET.get('option', None)
        service = request.GET.get('service', None)

        if service and (service.lower()
                        in {Regenerate.COBBLER, Regenerate.SERIALCONSOLE}):
            if isinstance(request.user, AnonymousUser) or not request.auth:
                return AuthRequiredSerializer().as_json

            if not request.user.is_superuser:
                return ErrorMessage(
                    "Only superusers are allowed to perform this action!"
                ).as_json

            # regenerate Cobbler entries
            if service.lower() == Regenerate.COBBLER:
                signal_cobbler_regenerate.send(sender=None, domain_id=None)
                return Message("Regenerate Cobbler entries...").as_json

            # regenerate serial console entries iterating over all cscreen servers
            elif service.lower() == Regenerate.SERIALCONSOLE:
                machines = SerialConsole.objects.all().values_list(
                    'cscreen_server__fqdn', flat=True)

                for fqdn in machines.distinct():
                    signal_serialconsole_regenerate.send(
                        sender=None, cscreen_server_fqdn=fqdn)

                return Message("Regenerate serial console entries...").as_json

        elif (fqdn is not None) and (option is not None):
            try:
                result = get_machine(fqdn,
                                     redirect_to='api:regenerate',
                                     data=request.GET)
                if isinstance(result, Serializer):
                    return result.as_json
                elif isinstance(result, HttpResponseRedirect):
                    return result
                machine = result
            except Exception as e:
                return ErrorMessage(str(e)).as_json

            if option.lower() != Regenerate.MOTD:
                return ErrorMessage(
                    "Unknown option '{}'!".format(option)).as_json

            if isinstance(request.user, AnonymousUser) or not request.auth:
                return AuthRequiredSerializer().as_json

            try:
                if option.lower() == Regenerate.MOTD:
                    machine.update_motd(user=request.user)
                    return Message("OK.").as_json
            except Exception as e:
                return ErrorMessage(str(e)).as_json

        return ErrorMessage("Unknown service '{}'!".format(service)).as_json
예제 #2
0
    def save(self, *args, **kwargs):
        """
        Save machine object.

        Set FQDN to lower case, check if FQDN is resolvable by DNS and set
        domain and enclosure correctly (create if necessary).
        """
        self.fqdn = self.fqdn.lower()

        if not self.mac_address:
            raise ValidationError("'{}' has no MAC address!".format(self))

        validate_mac_address(self.mac_address)

        # create & assign network domain and ensure that the FQDN always matches the fqdn_domain
        domain, created = Domain.objects.get_or_create(
            name=get_domain(self.fqdn))
        if created:
            domain.save()
        self.fqdn_domain = domain

        # create & assign enclosure according to naming convention if no enclosure given
        if not hasattr(self, 'enclosure'):
            name = re.split(r'-(\d|sp)+$', get_hostname(self.fqdn))[0]
            enclosure, created = Enclosure.objects.get_or_create(name=name)
            self.enclosure = enclosure

        if isinstance(self.virtualization_api, VirtualizationAPI):
            self.virtualization_api = self.virtualization_api.get_type()

        super(Machine, self).save(*args, **kwargs)

        # check if DHCP needs to be regenerated
        if self._original is not None:
            try:
                assert self.mac_address == self._original.mac_address
                assert self.fqdn == self._original.fqdn
                assert self.fqdn_domain == self._original.fqdn_domain
                assert self.architecture == self._original.architecture
                assert self.group == self._original.group
                assert self.dhcp_filename == self._original.dhcp_filename
                assert self.dhcpv4_write == self._original.dhcpv4_write
                assert self.dhcpv6_write == self._original.dhcpv6_write
            except AssertionError:
                from orthos2.data.signals import signal_cobbler_regenerate

                # regenerate DHCP on all domains (deletion/registration) if domain changed
                if self.fqdn_domain == self._original.fqdn_domain:
                    domain_id = self.fqdn_domain.pk
                else:
                    domain_id = None

                signal_cobbler_regenerate.send(sender=self.__class__,
                                               domain_id=domain_id)
예제 #3
0
    def save(self, *args, **kwargs):
        """
        Save machine object.

        Set FQDN to lower case, check if FQDN is resolvable by DNS and set
        domain and enclosure correctly (create if necessary).
        """
        self.fqdn = self.fqdn.lower()

        if not self.mac_address and not self.unknown_mac:
            raise ValidationError(
                "'{}' You must select 'MAC Unkown' for systems without MAC".
                format(self))

        if self.mac_address and self.unknown_mac:
            raise ValidationError(
                "'{}' You must not select 'MAC Unkown' for systems with a MAC".
                format(self))
        if self.unknown_mac and not self.bmc_allowed():
            raise ValidationError(
                "You may only skip the MAC for systems with BMC")
        if self.mac_address:
            validate_mac_address(self.mac_address)

        if not self.system.virtual and self.hypervisor:
            raise ValidationError("Only virtual machines may have hypervisors")
        if hasattr(self, 'bmc') and not self.bmc_allowed():
            raise ValidationError("{} systems cannot use a BMC".format(
                self.system.name))
        # create & assign network domain and ensure that the FQDN always matches the fqdn_domain
        domain, created = Domain.objects.get_or_create(
            name=get_domain(self.fqdn))
        if created:
            domain.save()
        self.fqdn_domain = domain

        # create & assign enclosure according to naming convention if no enclosure given
        if not hasattr(self, 'enclosure'):
            name = re.split(r'-(\d|sp)+$', get_hostname(self.fqdn))[0]
            enclosure, created = Enclosure.objects.get_or_create(name=name)
            self.enclosure = enclosure

        super(Machine, self).save(*args, **kwargs)

        # check if DHCP needs to be regenerated
        if self._original is not None:
            try:
                assert self.mac_address == self._original.mac_address
                assert self.fqdn == self._original.fqdn
                assert self.fqdn_domain == self._original.fqdn_domain
                assert self.architecture == self._original.architecture
                assert self.group == self._original.group
                assert self.dhcp_filename == self._original.dhcp_filename
                assert self.kernel_options == self._original.kernel_options
                if self.has_remotepower():
                    assert hasattr(self._original, 'remotepower')
                    assert self.remotepower.fence_name == self._original.remotepower.fence_name
                    assert self.remotepower.options == self._original.remotepower.options
                    if hasattr(self.remotepower, 'remote_power_device'):
                        assert hasattr(self._original.remotepower,
                                       'remote_power_device')
                        assert self.remotepower.remote_power_device == \
                               self._original.remotepower.remote_power_device
                if hasattr(self, 'bmc'):
                    assert hasattr(self._original, 'bmc')
                    assert self.bmc.username == self._original.bmc.username
                    assert self.bmc.password == self._original.bmc.password
                    assert self.bmc.mac == self._original.bmc.mac
                    assert self.bmc.fqdn == self._original.bmc.fqdn
                if self.has_serialconsole():
                    assert hasattr(self._original, 'serialconsole')
                    assert self.serialconsole.baud_rate == self._original.serialconsole.baud_rate
                    assert self.serialconsole.kernel_device_num == \
                        self._original.serialconsole.kernel_device_num
            except AssertionError:
                if ServerConfig.objects.bool_by_key("orthos.cobblersync.full"):
                    from orthos2.data.signals import signal_cobbler_regenerate

                    # regenerate DHCP on all domains (deletion/registration) if domain changed
                    if self.fqdn_domain == self._original.fqdn_domain:
                        domain_id = self.fqdn_domain.pk
                    else:
                        domain_id = None

                    signal_cobbler_regenerate.send(sender=self.__class__,
                                                   domain_id=domain_id)
                else:
                    from orthos2.data.signals import signal_cobbler_machine_update
                    if self.fqdn_domain == self._original.fqdn_domain:
                        domain_id = self.fqdn_domain.pk
                        machine_id = self.pk
                        signal_cobbler_machine_update.send(
                            sender=self.__class__,
                            domain_id=domain_id,
                            machine_id=machine_id)
                    else:
                        raise NotImplementedError(
                            "Moving machines between domains with quick cobbler synchronization "
                            "is not implemented yet")
예제 #4
0
    def regenerate_dhcp_record(self, user=None):
        """Call respective signal."""
        from orthos2.data.signals import signal_cobbler_regenerate

        signal_cobbler_regenerate.send(sender=self.__class__,
                                       domain_id=self.fqdn_domain.pk)
예제 #5
0
    def get(self, request, *args, **kwargs):
        """Trigger regeneration of machine-related/service files."""
        service = request.GET.get('service', None)
        fqdn = request.GET.get('fqdn', None)
        machine = None

        if isinstance(request.user, AnonymousUser) or not request.auth:
            return AuthRequiredSerializer().as_json

        if not request.user.is_superuser:
            return ErrorMessage(
                "Only superusers are allowed to perform this action!").as_json

        if not service:
            return ErrorMessage("Service not set").as_json

        if fqdn:
            try:
                machine = get_machine(fqdn,
                                      redirect_to='api:regenerate',
                                      data=request.GET)
                if not machine:
                    return ErrorMessage(
                        "machine {} not found".format(fqdn)).as_json
                if isinstance(machine, Serializer):
                    return machine.as_json
                elif isinstance(machine, HttpResponseRedirect):
                    return machine
            except Exception as e:
                return ErrorMessage(str(e)).as_json

        # regenerate Cobbler entries
        if service.lower() == RegenerateCommand.COBBLER:
            domain_id = None
            if fqdn:
                domain = get_domain(fqdn)
                if not domain:
                    return ErrorMessage("No domain found for machine: " +
                                        fqdn).as_json
                o_domain = Domain.objects.get(name=domain)
                if not o_domain:
                    return ErrorMessage("No orthos domain found for domain: " +
                                        domain).as_json
                domain_id = getattr(o_domain, 'id', None)
                if not domain_id:
                    return ErrorMessage(
                        "Could not find id for orthos domain: " +
                        domain).as_json
                msg = 'domain ' + domain
            else:
                domain = None
                msg = 'all domains'
            signal_cobbler_regenerate.send(sender=None, domain_id=domain_id)
            return Message("Regenerate Cobbler entries for " + msg).as_json

        # regenerate serial console entries iterating over all cscreen servers
        elif service.lower() == RegenerateCommand.SERIALCONSOLE:
            machines = SerialConsole.objects.all().values_list(
                'cscreen_server__fqdn', flat=True)
            if fqdn:
                if fqdn in machines.distinct():
                    signal_serialconsole_regenerate.send(
                        sender=None, cscreen_server_fqdn=fqdn)
                    msg = fqdn
                else:
                    return ErrorMessage("Not a serial console server: " +
                                        fqdn).as_json
            else:
                msg = ''
                for fqdn in machines.distinct():
                    signal_serialconsole_regenerate.send(
                        sender=None, cscreen_server_fqdn=fqdn)
                    msg += ' ' + fqdn
            return Message(
                "Regenerated serial console entries for serial console servers: "
                + msg).as_json

        # regenerate MOTD (only works per machine atm)
        elif service.lower() == RegenerateCommand.MOTD:
            if not fqdn:
                return Message("regenerte motd needs fqdn parameter").as_json
            machine.update_motd(user=request.user)
            return Message("OK.").as_json
        else:
            return ErrorMessage("Unknown service {}".format(service)).as_json

        return ErrorMessage("Unknown error - params: {} - {}".format(
            service, fqdn)).as_json
예제 #6
0
    def save(self, *args, **kwargs):
        """
        Save machine object.

        Set FQDN to lower case, check if FQDN is resolvable by DNS and set
        domain and enclosure correctly (create if necessary).
        """
        self.fqdn = self.fqdn.lower()

        if not self.mac_address:
            raise ValidationError("'{}' has no MAC address!".format(self))

        validate_mac_address(self.mac_address)

        if not self.system.virtual and self.hypervisor:
            raise ValidationError("Only virtuals machines may have hypervisors")
        if self.system.virtual and self.use_bmc:
            raise ValidationError("Virtual machines can not use a BMC")
        # create & assign network domain and ensure that the FQDN always matches the fqdn_domain
        domain, created = Domain.objects.get_or_create(name=get_domain(self.fqdn))
        if created:
            domain.save()
        self.fqdn_domain = domain

        # create & assign enclosure according to naming convention if no enclosure given
        if not hasattr(self, 'enclosure'):
            name = re.split(r'-(\d|sp)+$', get_hostname(self.fqdn))[0]
            enclosure, created = Enclosure.objects.get_or_create(name=name)
            self.enclosure = enclosure

        if isinstance(self.virtualization_api, VirtualizationAPI):
            self.virtualization_api = self.virtualization_api.get_type()

        super(Machine, self).save(*args, **kwargs)

        # check if DHCP needs to be regenerated
        if self._original is not None:
            try:
                assert self.mac_address == self._original.mac_address
                assert self.fqdn == self._original.fqdn
                assert self.fqdn_domain == self._original.fqdn_domain
                assert self.architecture == self._original.architecture
                assert self.group == self._original.group
                assert self.dhcp_filename == self._original.dhcp_filename
                assert self.dhcpv4_write == self._original.dhcpv4_write
                assert self.dhcpv6_write == self._original.dhcpv6_write
            except AssertionError:
                if ServerConfig.bool_by_key("orthos.cobblersync.full"):
                    from orthos2.data.signals import signal_cobbler_regenerate

                    # regenerate DHCP on all domains (deletion/registration) if domain changed
                    if self.fqdn_domain == self._original.fqdn_domain:
                        domain_id = self.fqdn_domain.pk
                    else:
                        domain_id = None

                    signal_cobbler_regenerate.send(sender=self.__class__, domain_id=domain_id)
                else:
                    from orthos2.data.signals import signal_cobbler_machine_update
                    if self.fqdn_domain == self._original.fqdn_domain:
                        domain_id = self.fqdn_domain.pk
                        machine_id = self.pk
                        signal_cobbler_machine_update.send(
                            sender=self.__class__, domain_id=domain_id, machine_id=machine_id)
                    else:
                        raise NotImplementedError(
                            "Moving machines between domains with quick cobbler synchronization "
                            "is not implemented yet")