2019-12-17 12:50:53 +00:00
|
|
|
import ast
|
|
|
|
import logging
|
|
|
|
|
2020-01-14 10:40:42 +00:00
|
|
|
from django.utils.dateparse import parse_datetime
|
2019-11-13 10:42:23 +00:00
|
|
|
from django.utils.html import format_html
|
2019-12-03 12:34:39 +00:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2019-11-13 10:08:19 +00:00
|
|
|
|
2020-01-22 12:03:23 +00:00
|
|
|
from . import settings as musician_settings
|
2020-02-17 11:40:27 +00:00
|
|
|
from .utils import get_bootstraped_percent
|
2020-01-22 12:03:23 +00:00
|
|
|
|
2019-11-13 10:42:23 +00:00
|
|
|
|
2019-12-17 12:50:53 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
class OrchestraModel:
|
|
|
|
""" Base class from which all orchestra models will inherit. """
|
2019-11-13 11:26:35 +00:00
|
|
|
api_name = None
|
2019-11-13 10:42:23 +00:00
|
|
|
verbose_name = None
|
|
|
|
fields = ()
|
2019-12-17 12:04:09 +00:00
|
|
|
id = None
|
2019-11-13 10:08:19 +00:00
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
def __init__(self, **kwargs):
|
2019-11-13 10:08:19 +00:00
|
|
|
if self.verbose_name is None:
|
2019-11-13 11:26:35 +00:00
|
|
|
self.verbose_name = self.api_name
|
2019-11-13 10:08:19 +00:00
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
for (param, default) in self.param_defaults.items():
|
|
|
|
setattr(self, param, kwargs.get(param, default))
|
2019-11-13 10:08:19 +00:00
|
|
|
|
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
@classmethod
|
|
|
|
def new_from_json(cls, data, **kwargs):
|
|
|
|
""" Create a new instance based on a JSON dict. Any kwargs should be
|
|
|
|
supplied by the inherited, calling class.
|
|
|
|
Args:
|
|
|
|
data: A JSON dict, as converted from the JSON in the orchestra API.
|
|
|
|
"""
|
2020-03-30 13:26:01 +00:00
|
|
|
if data is None:
|
|
|
|
return cls()
|
2019-11-20 09:29:39 +00:00
|
|
|
|
|
|
|
json_data = data.copy()
|
|
|
|
if kwargs:
|
|
|
|
for key, val in kwargs.items():
|
|
|
|
json_data[key] = val
|
|
|
|
|
|
|
|
c = cls(**json_data)
|
|
|
|
c._json = data
|
2019-12-17 12:50:53 +00:00
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
return c
|
2019-11-13 10:42:23 +00:00
|
|
|
|
2019-12-12 13:18:29 +00:00
|
|
|
def __repr__(self):
|
|
|
|
return '<%s: %s>' % (self.__class__.__name__, self)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return '%s object (%s)' % (self.__class__.__name__, self.id)
|
|
|
|
|
2019-11-13 11:27:25 +00:00
|
|
|
|
2019-12-17 13:48:21 +00:00
|
|
|
class Bill(OrchestraModel):
|
|
|
|
api_name = 'bill'
|
|
|
|
param_defaults = {
|
2019-12-17 14:15:58 +00:00
|
|
|
"id": None,
|
2019-12-17 13:48:21 +00:00
|
|
|
"number": "1",
|
|
|
|
"type": "INVOICE",
|
|
|
|
"total": 0.0,
|
|
|
|
"is_sent": False,
|
|
|
|
"created_on": "",
|
|
|
|
"due_on": "",
|
|
|
|
"comments": "",
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-11-20 19:07:35 +00:00
|
|
|
class BillingContact(OrchestraModel):
|
|
|
|
param_defaults = {
|
|
|
|
'name': None,
|
|
|
|
'address': None,
|
|
|
|
'city': None,
|
|
|
|
'zipcode': None,
|
|
|
|
'country': None,
|
|
|
|
'vat': None,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class PaymentSource(OrchestraModel):
|
|
|
|
api_name = 'payment-source'
|
|
|
|
param_defaults = {
|
|
|
|
"method": None,
|
|
|
|
"data": [],
|
|
|
|
"is_active": False,
|
|
|
|
}
|
|
|
|
|
2019-12-17 12:50:53 +00:00
|
|
|
def __init__(self, **kwargs):
|
|
|
|
super().__init__(**kwargs)
|
|
|
|
# payment details are passed as a plain string
|
|
|
|
# try to convert to a python structure
|
|
|
|
try:
|
|
|
|
self.data = ast.literal_eval(self.data)
|
|
|
|
except (ValueError, SyntaxError) as e:
|
|
|
|
logger.error(e)
|
|
|
|
|
2019-11-20 19:07:35 +00:00
|
|
|
|
|
|
|
class UserAccount(OrchestraModel):
|
|
|
|
api_name = 'accounts'
|
|
|
|
param_defaults = {
|
|
|
|
'username': None,
|
|
|
|
'type': None,
|
|
|
|
'language': None,
|
|
|
|
'short_name': None,
|
|
|
|
'full_name': None,
|
|
|
|
'billing': {},
|
2020-01-14 10:40:42 +00:00
|
|
|
'last_login': None,
|
2019-11-20 19:07:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def new_from_json(cls, data, **kwargs):
|
|
|
|
billing = None
|
2020-01-23 16:37:08 +00:00
|
|
|
language = None
|
2020-01-14 12:50:17 +00:00
|
|
|
last_login = None
|
2019-11-20 19:07:35 +00:00
|
|
|
|
|
|
|
if 'billcontact' in data:
|
|
|
|
billing = BillingContact.new_from_json(data['billcontact'])
|
2020-01-14 10:40:42 +00:00
|
|
|
|
2020-01-23 16:37:08 +00:00
|
|
|
# Django expects that language code is lowercase
|
|
|
|
if 'language' in data:
|
|
|
|
language = data['language'].lower()
|
|
|
|
|
2020-03-12 06:45:11 +00:00
|
|
|
last_login = data.get('last_login')
|
|
|
|
if last_login is not None:
|
|
|
|
last_login = parse_datetime(last_login)
|
2020-01-23 16:37:08 +00:00
|
|
|
|
|
|
|
return super().new_from_json(data=data, billing=billing, language=language, last_login=last_login)
|
2019-11-20 19:07:35 +00:00
|
|
|
|
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
class DatabaseUser(OrchestraModel):
|
|
|
|
api_name = 'databaseusers'
|
|
|
|
fields = ('username',)
|
|
|
|
param_defaults = {
|
|
|
|
'username': None,
|
|
|
|
}
|
2019-11-13 11:27:25 +00:00
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
|
|
|
|
class DatabaseService(OrchestraModel):
|
|
|
|
api_name = 'database'
|
2019-12-04 13:13:56 +00:00
|
|
|
verbose_name = _('Databases')
|
2019-12-18 10:35:28 +00:00
|
|
|
description = _('Description details for databases page.')
|
2019-11-20 09:29:39 +00:00
|
|
|
fields = ('name', 'type', 'users')
|
|
|
|
param_defaults = {
|
|
|
|
"id": None,
|
|
|
|
"name": None,
|
|
|
|
"type": None,
|
|
|
|
"users": None,
|
2019-12-04 13:13:56 +00:00
|
|
|
"usage": {},
|
2019-11-20 09:29:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def new_from_json(cls, data, **kwargs):
|
|
|
|
users = None
|
|
|
|
if 'users' in data:
|
|
|
|
users = [DatabaseUser.new_from_json(user_data) for user_data in data['users']]
|
2019-12-04 13:13:56 +00:00
|
|
|
|
2020-02-17 12:26:07 +00:00
|
|
|
usage = cls.get_usage(data)
|
2019-12-04 13:13:56 +00:00
|
|
|
|
|
|
|
return super().new_from_json(data=data, users=users, usage=usage)
|
2019-11-20 09:29:39 +00:00
|
|
|
|
2020-02-17 12:26:07 +00:00
|
|
|
@classmethod
|
|
|
|
def get_usage(self, data):
|
|
|
|
try:
|
|
|
|
resources = data['resources']
|
|
|
|
resource_disk = {}
|
|
|
|
for r in resources:
|
|
|
|
if r['name'] == 'disk':
|
|
|
|
resource_disk = r
|
|
|
|
break
|
|
|
|
|
|
|
|
details = {
|
|
|
|
'usage': float(resource_disk['used']),
|
|
|
|
'total': resource_disk['allocated'],
|
|
|
|
'unit': resource_disk['unit'],
|
|
|
|
}
|
|
|
|
except (IndexError, KeyError):
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
|
|
percent = get_bootstraped_percent(
|
|
|
|
details['usage'],
|
|
|
|
details['total']
|
|
|
|
)
|
|
|
|
details['percent'] = percent
|
|
|
|
|
|
|
|
return details
|
|
|
|
|
2020-02-17 12:45:47 +00:00
|
|
|
@property
|
|
|
|
def manager_url(self):
|
|
|
|
return musician_settings.URL_DB_PHPMYADMIN
|
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
|
2019-12-12 13:18:29 +00:00
|
|
|
class Domain(OrchestraModel):
|
|
|
|
api_name = 'domain'
|
|
|
|
param_defaults = {
|
|
|
|
"id": None,
|
|
|
|
"name": None,
|
|
|
|
"records": [],
|
|
|
|
"mails": [],
|
|
|
|
"usage": {},
|
2020-01-20 09:45:18 +00:00
|
|
|
"websites": [],
|
2019-12-12 13:18:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def new_from_json(cls, data, **kwargs):
|
|
|
|
records = cls.param_defaults.get("records")
|
|
|
|
if 'records' in data:
|
|
|
|
records = [DomainRecord.new_from_json(record_data) for record_data in data['records']]
|
|
|
|
|
|
|
|
return super().new_from_json(data=data, records=records)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
|
|
class DomainRecord(OrchestraModel):
|
|
|
|
param_defaults = {
|
|
|
|
"type": None,
|
|
|
|
"value": None,
|
|
|
|
}
|
|
|
|
def __str__(self):
|
|
|
|
return '<%s: %s>' % (self.type, self.value)
|
|
|
|
|
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
class MailService(OrchestraModel):
|
2019-11-13 11:26:35 +00:00
|
|
|
api_name = 'address'
|
2019-12-03 12:34:39 +00:00
|
|
|
verbose_name = _('Mail addresses')
|
2019-12-18 10:35:28 +00:00
|
|
|
description = _('Description details for mail addresses page.')
|
2019-11-13 10:42:23 +00:00
|
|
|
fields = ('mail_address', 'aliases', 'type', 'type_detail')
|
2019-12-17 13:10:59 +00:00
|
|
|
param_defaults = {}
|
2019-11-13 10:42:23 +00:00
|
|
|
|
|
|
|
FORWARD = 'forward'
|
|
|
|
MAILBOX = 'mailbox'
|
|
|
|
|
2019-12-17 13:10:59 +00:00
|
|
|
def __init__(self, **kwargs):
|
|
|
|
self.data = kwargs
|
|
|
|
super().__init__(**kwargs)
|
|
|
|
|
2019-11-13 10:08:19 +00:00
|
|
|
@property
|
|
|
|
def aliases(self):
|
|
|
|
return [
|
|
|
|
name + '@' + self.data['domain']['name'] for name in self.data['names'][1:]
|
|
|
|
]
|
|
|
|
|
|
|
|
@property
|
|
|
|
def mail_address(self):
|
|
|
|
return self.data['names'][0] + '@' + self.data['domain']['name']
|
|
|
|
|
|
|
|
@property
|
|
|
|
def type(self):
|
|
|
|
if self.data['forward']:
|
|
|
|
return self.FORWARD
|
|
|
|
return self.MAILBOX
|
|
|
|
|
|
|
|
@property
|
|
|
|
def type_detail(self):
|
|
|
|
if self.type == self.FORWARD:
|
|
|
|
return self.data['forward']
|
2020-02-17 11:05:55 +00:00
|
|
|
|
|
|
|
# retrieve mailbox usage
|
|
|
|
try:
|
|
|
|
resource = self.data['mailboxes'][0]['resources']
|
|
|
|
resource_disk = {}
|
|
|
|
for r in resource:
|
|
|
|
if r['name'] == 'disk':
|
|
|
|
resource_disk = r
|
|
|
|
break
|
|
|
|
|
|
|
|
mailbox_details = {
|
2020-02-17 11:40:27 +00:00
|
|
|
'usage': float(resource_disk['used']),
|
2020-02-17 11:05:55 +00:00
|
|
|
'total': resource_disk['allocated'],
|
|
|
|
'unit': resource_disk['unit'],
|
|
|
|
}
|
|
|
|
|
2020-02-17 11:40:27 +00:00
|
|
|
percent = get_bootstraped_percent(
|
|
|
|
mailbox_details['used'],
|
|
|
|
mailbox_details['total']
|
|
|
|
)
|
|
|
|
mailbox_details['percent'] = percent
|
2020-02-17 11:05:55 +00:00
|
|
|
except (IndexError, KeyError):
|
|
|
|
mailbox_details = {}
|
|
|
|
return mailbox_details
|
2019-11-13 10:42:23 +00:00
|
|
|
|
|
|
|
|
2019-11-20 09:29:39 +00:00
|
|
|
class MailinglistService(OrchestraModel):
|
2019-11-13 11:26:35 +00:00
|
|
|
api_name = 'mailinglist'
|
2019-12-04 11:37:35 +00:00
|
|
|
verbose_name = _('Mailing list')
|
2019-12-18 10:35:28 +00:00
|
|
|
description = _('Description details for mailinglist page.')
|
2019-11-13 10:42:23 +00:00
|
|
|
fields = ('name', 'status', 'address_name', 'admin_email', 'configure')
|
2019-11-20 16:41:15 +00:00
|
|
|
param_defaults = {
|
|
|
|
'name': None,
|
2020-01-14 10:28:57 +00:00
|
|
|
'is_active': True,
|
2019-11-20 16:41:15 +00:00
|
|
|
'admin_email': None,
|
|
|
|
}
|
2019-11-13 10:42:23 +00:00
|
|
|
|
2019-12-17 13:10:59 +00:00
|
|
|
def __init__(self, **kwargs):
|
|
|
|
self.data = kwargs
|
|
|
|
super().__init__(**kwargs)
|
|
|
|
|
2019-11-13 10:42:23 +00:00
|
|
|
@property
|
|
|
|
def address_name(self):
|
|
|
|
return "{}@{}".format(self.data['address_name'], self.data['address_domain']['name'])
|
|
|
|
|
|
|
|
@property
|
2020-01-22 12:03:23 +00:00
|
|
|
def manager_url(self):
|
|
|
|
return musician_settings.URL_MAILTRAIN
|
2019-12-06 09:27:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
class SaasService(OrchestraModel):
|
|
|
|
api_name = 'saas'
|
|
|
|
verbose_name = _('Software as a Service (SaaS)')
|
2019-12-18 10:35:28 +00:00
|
|
|
description = _('Description details for SaaS page.')
|
2019-12-06 09:27:18 +00:00
|
|
|
param_defaults = {
|
|
|
|
'name': None,
|
|
|
|
'service': None,
|
|
|
|
'is_active': True,
|
|
|
|
'data': {},
|
|
|
|
}
|
2020-01-20 09:15:27 +00:00
|
|
|
|
|
|
|
|
2020-01-23 15:13:23 +00:00
|
|
|
@property
|
|
|
|
def manager_url(self):
|
|
|
|
URLS = {
|
|
|
|
'gitlab': musician_settings.URL_SAAS_GITLAB,
|
|
|
|
'owncloud': musician_settings.URL_SAAS_OWNCLOUD,
|
|
|
|
'wordpress': musician_settings.URL_SAAS_WORDPRESS,
|
|
|
|
}
|
|
|
|
|
|
|
|
return URLS.get(self.service, '#none')
|
|
|
|
|
|
|
|
|
2020-01-20 09:15:27 +00:00
|
|
|
class WebSite(OrchestraModel):
|
|
|
|
api_name = 'website'
|
|
|
|
param_defaults = {
|
|
|
|
"id": None,
|
|
|
|
"name": None,
|
|
|
|
"protocol": None,
|
|
|
|
"is_active": True,
|
|
|
|
"domains": [],
|
|
|
|
"contents": [],
|
|
|
|
}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def new_from_json(cls, data, **kwargs):
|
|
|
|
domains = cls.param_defaults.get("domains")
|
|
|
|
if 'domains' in data:
|
|
|
|
domains = [Domain.new_from_json(domain_data) for domain_data in data['domains']]
|
|
|
|
|
|
|
|
return super().new_from_json(data=data, domains=domains)
|