예제 #1
0
    def get(self, request, *args, **kwargs):
        hostname = self.getParam(request, 'hostname', '')
        product = LogicProducts().get_product(request, False)
        action = self.getParam(request, 'action', '')

        if action == "install":
            instance_status = [
                SaasInstance().IN_PREPARATION,
            ]
        elif action == "update" or action == "check" or action == "quota":
            instance_status = [
                SaasInstance().READY,
                SaasInstance().AVAILABLE,
                SaasInstance().RESERVED,
                SaasInstance().ASSIGNED,
                SaasInstance().EXPIRED,
                SaasInstance().TO_BE_REMOVED,
            ]
        elif action == "remove":
            instance_status = [
                SaasInstance().TO_BE_REMOVED,
            ]
        else:
            raise Exception('please specify valid action')

        if hostname and product:
            rows = SaasInstance.objects.filter(
                hostname=hostname, product=product,
                status__in=instance_status).order_by('id')
        else:
            raise Exception('please specify hostname and product_name')
        serializer = InstanceSerializer(rows, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)
예제 #2
0
    def create_new_instance(self, hostname, pacuser, product):
        # generate new password
        new_password = self.random_password(False)
        # generate the db password
        db_password = self.random_password(False)
        # the activation token that allows us to activate the instance
        activation_token = self.random_password(False)

        # find new available identifier
        instance_id_start = settings.INSTANCE_ID_START
        instance_id_end = settings.INSTANCE_ID_END
        startport = settings.PORT_START
        endport = settings.PORT_END
        new_id = random.randrange(instance_id_start, instance_id_end)
        while SaasInstance.objects.filter(identifier=str(new_id)).exists():
            new_id = random.randrange(instance_id_start, instance_id_end)

        # find new available port on that host, independant of the product
        new_port = -1
        last_port = -1
        if product.number_of_ports > 0:
            if SaasInstance.objects.filter(hostname=hostname).exists():
                with connection.cursor() as cursor:
                    sql = """SELECT MAX(last_port) FROM saas_instance WHERE hostname = %s"""
                    cursor.execute(sql, [
                        hostname,
                    ])
                    port_result = cursor.fetchone()
                    if port_result:
                        new_port = port_result[0] + 1
            if new_port < startport:
                new_port = startport
            last_port = new_port + product.number_of_ports - 1

        if new_port > endport:
            return False, {}

        # store to database
        instance = SaasInstance.objects.create(
            identifier=str(new_id),
            hostname=hostname,
            pacuser=pacuser,
            activation_token=activation_token,
            product=product,
            first_port=new_port,
            last_port=last_port,
            initial_password=new_password,
            password1=self.random_password(False),
            password2=self.random_password(False),
            db_password=db_password,
            status=SaasInstance().IN_PREPARATION)

        # return the result
        return True, {
            'new_id': new_id,
            'new_password': new_password,
            'db_password': db_password,
            'hostname': hostname,
            'port': new_port
        }
예제 #3
0
    def assign_instance(self, customer, product, plan):

        # check for first available instance
        instance = SaasInstance.objects.filter(product=product).filter(
            status=SaasInstance().AVAILABLE).first()
        if not instance:
            # send message to administrator
            self.notify_administrators(
                _("Missing free instance for %s") % (product.name, ),
                _("Assigning of %s instance for customer %d failed") %
                (product.name, customer.id))

            # TODO if no instance is available, then add the user to the waiting list

            return False
        else:
            # assign a free instance
            # there might be an unconfirmed contract already
            contract = LogicContracts().get_contract(customer, product)
            if not contract:
                contract = LogicContracts().get_new_contract(
                    customer, product, plan)
            contract.instance = instance
            contract.plan = plan
            contract.is_confirmed = True
            contract.save()
            instance.status = instance.ASSIGNED
            instance.save()

            # call activation url of hosted application
            [success, PasswordResetToken
             ] = LogicInstances().activate_instance(customer, product,
                                                    instance)

            if not success:
                # send message to administrator
                self.notify_administrators(
                    _("SaasAdmin Error during activation"),
                    _("Failed activation of %s instance %s for customer %d") %
                    (product.name, instance.identifier, customer.id))
                return False

            # send message to administrator
            instances_available = LogicInstances(
            ).get_number_of_available_instances(product)
            self.notify_administrators(
                _("Instance for %s assigned") % (product.name, ),
                _("Nice, an instance of %s was booked for customer %d") %
                (product.name, customer.id) + "\n" +
                _("Still %d instances are available for new customers.") %
                (instances_available, ))

            # TODO send invoice to customer, or send it later in batch processing?
            return True
예제 #4
0
def instances(request, product):
    product = SaasProduct.objects.filter(slug = product).first()
    unused_instances = SaasInstance.objects.filter(product = product).filter(Q(status=SaasInstance().AVAILABLE) | Q(status=SaasInstance().READY) | Q(status=SaasInstance().IN_PREPARATION))

    return render(request,"instances.html",
            {'unused_instances': unused_instances, 'product': product })
예제 #5
0
 def get_number_of_available_instances(self, product):
     return SaasInstance.objects.filter(product=product).filter(
         status=SaasInstance().AVAILABLE).count()
예제 #6
0
    def mark_deactivated_instances_for_deletion(self):
        """ to be called by a cronjob each night """
        contracts = SaasContract.objects.filter(is_confirmed = True, \
            is_auto_renew = False, end_date__lt = datetime.today(), instance__status = SaasInstance().EXPIRED)
        for contract in contracts:
            days = 30
            if contract.plan.period_length_in_months == 0:
                if contract.plan.period_length_in_days == 1:
                    # for the one day test instance, remove it immediately
                    days = 0
                elif contract.plan.period_length_in_days > 0:
                    # for other test instances, remove it after 3 days
                    days = 3

            if contract.end_date + timedelta(
                    days=days) < datetime.today().date():
                instance = contract.instance
                instance.status = instance.TO_BE_REMOVED
                instance.save()
예제 #7
0
 def deactivate_expired_instances(self):
     """ to be called by a cronjob each night """
     contracts = SaasContract.objects.filter(is_confirmed = True, \
         is_auto_renew = False, end_date__lt = datetime.today(), instance__status = SaasInstance().ASSIGNED)
     for contract in contracts:
         instance = contract.instance
         if self.deactivate_instance(instance.product, instance):
             instance.status = instance.EXPIRED
             instance.save()