Added owncloud support
This commit is contained in:
parent
3faf519a49
commit
db295c36ad
|
@ -25,7 +25,7 @@ class Bind9MasterDomainBackend(ServiceController):
|
||||||
('domains.Record', 'domain__origin'),
|
('domains.Record', 'domain__origin'),
|
||||||
('domains.Domain', 'origin'),
|
('domains.Domain', 'origin'),
|
||||||
)
|
)
|
||||||
ignore_fields = ['serial']
|
ignore_fields = ('serial',)
|
||||||
doc_settings = (settings,
|
doc_settings = (settings,
|
||||||
('DOMAINS_MASTERS_PATH',)
|
('DOMAINS_MASTERS_PATH',)
|
||||||
)
|
)
|
||||||
|
|
|
@ -102,7 +102,7 @@ class Domain(models.Model):
|
||||||
for domain in self.subdomains.exclude(pk=self.pk):
|
for domain in self.subdomains.exclude(pk=self.pk):
|
||||||
# queryset.update() is not used because we want to trigger backend to delete ex-topdomains
|
# queryset.update() is not used because we want to trigger backend to delete ex-topdomains
|
||||||
domain.top = self
|
domain.top = self
|
||||||
domain.save(update_fields=['top'])
|
domain.save(update_fields=('top',))
|
||||||
|
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
if self.is_top:
|
if self.is_top:
|
||||||
|
@ -151,7 +151,7 @@ class Domain(models.Model):
|
||||||
serial = str(self.serial)[:8] + '%.2d' % num
|
serial = str(self.serial)[:8] + '%.2d' % num
|
||||||
serial = int(serial)
|
serial = int(serial)
|
||||||
self.serial = serial
|
self.serial = serial
|
||||||
self.save(update_fields=['serial'])
|
self.save(update_fields=('serial',))
|
||||||
|
|
||||||
def get_records(self):
|
def get_records(self):
|
||||||
types = {}
|
types = {}
|
||||||
|
|
103
orchestra/contrib/saas/backends/owncloud.py
Normal file
103
orchestra/contrib/saas/backends/owncloud.py
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import textwrap
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from orchestra.contrib.orchestration import ServiceController
|
||||||
|
|
||||||
|
from . import ApacheTrafficByHost
|
||||||
|
from .. import settings
|
||||||
|
|
||||||
|
|
||||||
|
class OwnCloudBackend(ServiceController):
|
||||||
|
"""
|
||||||
|
Creates a wordpress site on a WordPress MultiSite installation.
|
||||||
|
|
||||||
|
You should point it to the database server
|
||||||
|
"""
|
||||||
|
verbose_name = _("ownCloud SaaS")
|
||||||
|
model = 'saas.SaaS'
|
||||||
|
default_route_match = "saas.service == 'owncloud'"
|
||||||
|
doc_settings = (settings,
|
||||||
|
('SAAS_OWNCLOUD_API_URL',)
|
||||||
|
)
|
||||||
|
|
||||||
|
def validate_response(self, response):
|
||||||
|
if response.status_code != requests.codes.ok:
|
||||||
|
request = response.request
|
||||||
|
context = (request.method, response.url, request.body, response.status_code)
|
||||||
|
raise RuntimeError("%s %s '%s' HTTP %s" % context)
|
||||||
|
root = ET.fromstring(response.text)
|
||||||
|
statuscode = root.find("./meta/statuscode").text
|
||||||
|
if statuscode != '100':
|
||||||
|
message = root.find("./meta/status").text
|
||||||
|
request = response.request
|
||||||
|
context = (request.method, response.url, request.body, statuscode, message)
|
||||||
|
raise RuntimeError("%s %s '%s' ERROR %s, %s" % context)
|
||||||
|
|
||||||
|
def api_call(self, action, url_path, *args, **kwargs):
|
||||||
|
BASE_URL = settings.SAAS_OWNCLOUD_API_URL.rstrip('/')
|
||||||
|
url = '/'.join((BASE_URL, url_path))
|
||||||
|
response = action(url, *args, **kwargs)
|
||||||
|
self.validate_response(response)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def api_get(self, url_path, *args, **kwargs):
|
||||||
|
return self.api_call(requests.get, url_path, *args, **kwargs)
|
||||||
|
|
||||||
|
def api_post(self, url_path, *args, **kwargs):
|
||||||
|
return self.api_call(requests.post, url_path, *args, **kwargs)
|
||||||
|
|
||||||
|
def api_put(self, url_path, *args, **kwargs):
|
||||||
|
return self.api_call(requests.put, url_path, *args, **kwargs)
|
||||||
|
|
||||||
|
def api_delete(self, url_path, *args, **kwargs):
|
||||||
|
return self.api_call(requests.delete, url_path, *args, **kwargs)
|
||||||
|
|
||||||
|
def create(self, saas):
|
||||||
|
data = {
|
||||||
|
'userid': saas.name,
|
||||||
|
'password': saas.password
|
||||||
|
}
|
||||||
|
self.api_post('users', data)
|
||||||
|
|
||||||
|
def update(self, saas):
|
||||||
|
data = {
|
||||||
|
'password': saas.password,
|
||||||
|
}
|
||||||
|
self.api_put('users/%s' % saas.name, data)
|
||||||
|
|
||||||
|
def update_or_create(self, saas, server):
|
||||||
|
try:
|
||||||
|
self.api_get('users/%s' % saas.name)
|
||||||
|
except RuntimeError:
|
||||||
|
if getattr(saas, 'password'):
|
||||||
|
self.create(saas)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
if getattr(saas, 'password'):
|
||||||
|
self.update(saas)
|
||||||
|
|
||||||
|
def remove(self, saas, server):
|
||||||
|
self.api_delete('users/%s' % saas.name)
|
||||||
|
|
||||||
|
def save(self, saas):
|
||||||
|
self.append(self.update_or_create, saas)
|
||||||
|
|
||||||
|
def delete(self, saas):
|
||||||
|
self.append(self.remove, saas)
|
||||||
|
|
||||||
|
|
||||||
|
class OwncloudTraffic(ApacheTrafficByHost):
|
||||||
|
__doc__ = ApacheTrafficByHost.__doc__
|
||||||
|
verbose_name = _("ownCloud SaaS Traffic")
|
||||||
|
default_route_match = "saas.service == 'owncloud'"
|
||||||
|
doc_settings = (settings,
|
||||||
|
('SAAS_TRAFFIC_IGNORE_HOSTS', 'SAAS_OWNCLOUD_LOG_PATH')
|
||||||
|
)
|
||||||
|
log_path = settings.SAAS_OWNCLOUD_LOG_PATH
|
13
orchestra/contrib/saas/services/owncloud.py
Normal file
13
orchestra/contrib/saas/services/owncloud.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
from django import forms
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from .. import settings
|
||||||
|
from .options import SoftwareService
|
||||||
|
|
||||||
|
|
||||||
|
class OwnCloudService(SoftwareService):
|
||||||
|
name = 'owncloud'
|
||||||
|
verbose_name = "ownCloud"
|
||||||
|
icon = 'orchestra/icons/apps/ownCloud.png'
|
||||||
|
site_domain = settings.SAAS_OWNCLOUD_DOMAIN
|
|
@ -17,6 +17,7 @@ SAAS_ENABLED_SERVICES = Setting('SAAS_ENABLED_SERVICES',
|
||||||
'orchestra.contrib.saas.services.wordpress.WordPressService',
|
'orchestra.contrib.saas.services.wordpress.WordPressService',
|
||||||
'orchestra.contrib.saas.services.dokuwiki.DokuWikiService',
|
'orchestra.contrib.saas.services.dokuwiki.DokuWikiService',
|
||||||
'orchestra.contrib.saas.services.drupal.DrupalService',
|
'orchestra.contrib.saas.services.drupal.DrupalService',
|
||||||
|
'orchestra.contrib.saas.services.owncloud.OwnCloudService',
|
||||||
'orchestra.contrib.saas.services.seafile.SeaFileService',
|
'orchestra.contrib.saas.services.seafile.SeaFileService',
|
||||||
),
|
),
|
||||||
# lazy loading
|
# lazy loading
|
||||||
|
@ -201,6 +202,24 @@ SAAS_SEAFILE_DEFAULT_QUOTA = Setting('SAAS_SEAFILE_DEFAULT_QUOTA',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ownCloud
|
||||||
|
|
||||||
|
SAAS_OWNCLOUD_DOMAIN = Setting('SAAS_OWNCLOUD_DOMAIN',
|
||||||
|
'owncloud.{}'.format(ORCHESTRA_BASE_DOMAIN),
|
||||||
|
help_text="Uses <tt>ORCHESTRA_BASE_DOMAIN</tt> by default.",
|
||||||
|
)
|
||||||
|
|
||||||
|
SAAS_OWNCLOUD_API_URL = Setting('SAAS_OWNCLOUD_API_URL',
|
||||||
|
'https://admin:secret@owncloud.{}/ocs/v1.php/cloud/'.format(ORCHESTRA_BASE_DOMAIN),
|
||||||
|
)
|
||||||
|
|
||||||
|
SAAS_OWNCLOUD_LOG_PATH = Setting('SAAS_OWNCLOUD_LOG_PATH',
|
||||||
|
'',
|
||||||
|
help_text=_('Filesystem path for the webserver access logs.<br>'
|
||||||
|
'<tt>LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Host}i\"" host</tt>'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# BSCW
|
# BSCW
|
||||||
|
|
||||||
SAAS_BSCW_DOMAIN = Setting('SAAS_BSCW_DOMAIN',
|
SAAS_BSCW_DOMAIN = Setting('SAAS_BSCW_DOMAIN',
|
||||||
|
|
BIN
orchestra/static/orchestra/icons/apps/ownCloud.png
Normal file
BIN
orchestra/static/orchestra/icons/apps/ownCloud.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
151
orchestra/static/orchestra/icons/apps/ownCloud.svg
Normal file
151
orchestra/static/orchestra/icons/apps/ownCloud.svg
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
viewBox="0 0 48.000001 48"
|
||||||
|
id="svg2"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="ownCloud.svg"
|
||||||
|
inkscape:export-filename="/home/glic3rinu/orchestra/django-orchestra/orchestra/static/orchestra/icons/apps/ownCloud.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90">
|
||||||
|
<metadata
|
||||||
|
id="metadata28">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title>Druplicon</dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs26" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1025"
|
||||||
|
id="namedview24"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="9.6996722"
|
||||||
|
inkscape:cx="54.322274"
|
||||||
|
inkscape:cy="18.325473"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg2" />
|
||||||
|
<title
|
||||||
|
id="title4">Druplicon</title>
|
||||||
|
<circle
|
||||||
|
transform="matrix(0.1777725,0,0,0.1777725,-25.567169,11.465784)"
|
||||||
|
sodipodi:ry="20.332001"
|
||||||
|
sodipodi:rx="20.332001"
|
||||||
|
sodipodi:cy="43.648006"
|
||||||
|
sodipodi:cx="220.181"
|
||||||
|
cx="220.181"
|
||||||
|
cy="43.648006"
|
||||||
|
r="20.332001"
|
||||||
|
id="circle265"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:4;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
transform="matrix(0.1777725,0,0,0.1777725,-25.567169,11.465784)"
|
||||||
|
sodipodi:ry="37.242001"
|
||||||
|
sodipodi:rx="37.242001"
|
||||||
|
sodipodi:cy="114.314"
|
||||||
|
sodipodi:cx="182.89801"
|
||||||
|
cx="182.89801"
|
||||||
|
cy="114.314"
|
||||||
|
r="37.242001"
|
||||||
|
id="circle272"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:4;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
transform="matrix(0.1777725,0,0,0.1777725,-25.567169,11.465784)"
|
||||||
|
sodipodi:ry="40.261002"
|
||||||
|
sodipodi:rx="40.261002"
|
||||||
|
sodipodi:cy="89.533005"
|
||||||
|
sodipodi:cx="224.91202"
|
||||||
|
cx="224.91202"
|
||||||
|
cy="89.533005"
|
||||||
|
r="40.261002"
|
||||||
|
id="circle279"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:4;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
transform="matrix(0.1777725,0,0,0.1777725,-25.567169,11.465784)"
|
||||||
|
sodipodi:ry="37.242001"
|
||||||
|
sodipodi:rx="37.242001"
|
||||||
|
sodipodi:cy="73.209"
|
||||||
|
sodipodi:cx="307.02103"
|
||||||
|
cx="307.02103"
|
||||||
|
cy="73.209"
|
||||||
|
r="37.242001"
|
||||||
|
id="circle286"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:4;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
transform="matrix(0.1777725,0,0,0.1777725,-25.567169,11.465784)"
|
||||||
|
sodipodi:ry="37.241001"
|
||||||
|
sodipodi:rx="37.241001"
|
||||||
|
sodipodi:cy="44.241001"
|
||||||
|
sodipodi:cx="266.18002"
|
||||||
|
cx="266.18002"
|
||||||
|
cy="44.241001"
|
||||||
|
r="37.241001"
|
||||||
|
id="circle293"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:4;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
transform="matrix(0.1777725,0,0,0.1777725,-25.567169,11.465784)"
|
||||||
|
sodipodi:ry="21.299999"
|
||||||
|
sodipodi:rx="21.299999"
|
||||||
|
sodipodi:cy="128.69499"
|
||||||
|
sodipodi:cx="390.11401"
|
||||||
|
cx="390.11401"
|
||||||
|
cy="128.69499"
|
||||||
|
r="21.299999"
|
||||||
|
id="circle300"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:4;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
transform="matrix(0.1777725,0,0,0.1777725,-25.567169,11.465784)"
|
||||||
|
sodipodi:ry="40.261002"
|
||||||
|
sodipodi:rx="40.261002"
|
||||||
|
sodipodi:cy="112.3"
|
||||||
|
sodipodi:cx="344.85001"
|
||||||
|
cx="344.85001"
|
||||||
|
cy="112.3"
|
||||||
|
r="40.261002"
|
||||||
|
id="circle307"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:4;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
transform="matrix(0.1777725,0,0,0.1777725,-25.567169,11.465784)"
|
||||||
|
sodipodi:ry="21.299"
|
||||||
|
sodipodi:rx="21.299"
|
||||||
|
sodipodi:cy="130.748"
|
||||||
|
sodipodi:cx="222.44901"
|
||||||
|
cx="222.44901"
|
||||||
|
cy="130.748"
|
||||||
|
r="21.299"
|
||||||
|
id="circle314"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:4;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m 33.061135,29.31521 c 0,5.039494 -4.085923,9.124707 -9.125774,9.124707 -5.039849,0 -9.125594,-4.085213 -9.125594,-9.124707 0,-5.040027 4.085922,-9.125595 9.125594,-9.125595 5.039673,0 9.125774,4.085568 9.125774,9.125595 z"
|
||||||
|
id="path321"
|
||||||
|
style="fill:#1d2d44;fill-opacity:1;stroke:#ffffff;stroke-width:0.71108997;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
Loading…
Reference in a new issue