mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-09-19 04:59:01 +00:00
pagekite action: Use augeas pagekite lens
And allow setting any server as pagekite frontend.
This commit is contained in:
parent
07ee03941f
commit
cf96797040
0
actions/__init__.py
Normal file
0
actions/__init__.py
Normal file
296
actions/pagekite
Executable file
296
actions/pagekite
Executable file
@ -0,0 +1,296 @@
|
|||||||
|
#!/usr/bin/python2
|
||||||
|
# -*- mode: python -*-
|
||||||
|
#
|
||||||
|
# This file is part of Plinth.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Configuration helper for Plint PageKite interface
|
||||||
|
|
||||||
|
Unfortunately there is no python3 package for augeas yet
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import augeas
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from pagekite_common import SERVICE_PARAMS, construct_params
|
||||||
|
|
||||||
|
aug = augeas.Augeas()
|
||||||
|
|
||||||
|
CONF_PATH = '/files/etc/pagekite.d'
|
||||||
|
PATHS = {
|
||||||
|
'service_on': os.path.join(CONF_PATH, '*', 'service_on', '*'),
|
||||||
|
'kitename': os.path.join(CONF_PATH, '10_account.rc', 'kitename'),
|
||||||
|
'kitesecret': os.path.join(CONF_PATH, '10_account.rc', 'kitesecret'),
|
||||||
|
'abort_not_configured': os.path.join(CONF_PATH, '10_account.rc',
|
||||||
|
'abort_not_configured'),
|
||||||
|
'defaults': os.path.join(CONF_PATH, '20_frontends.rc', 'defaults'),
|
||||||
|
'frontend': os.path.join(CONF_PATH, '20_frontends.rc', 'frontend'),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_arguments():
|
||||||
|
"""Return parsed command line arguments as dictionary"""
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
|
||||||
|
|
||||||
|
# Start/Stop PageKite
|
||||||
|
subparsers.add_parser('start', help='Start PageKite service')
|
||||||
|
subparsers.add_parser('stop', help='Stop PageKite service')
|
||||||
|
|
||||||
|
# Get/set status
|
||||||
|
subparsers.add_parser('is-enabled', help='Get whether PakeKite is enabled')
|
||||||
|
subparsers.add_parser('enable', help='Enable PageKite service')
|
||||||
|
subparsers.add_parser('disable', help='Disable PageKite service')
|
||||||
|
|
||||||
|
# get/set using the default pagekite.net frontend
|
||||||
|
subparsers.add_parser('get-pagekitenet-frontend-status',
|
||||||
|
help='Get whether pagekite.net frontend is enabled')
|
||||||
|
subparsers.add_parser('enable-pagekitenet-frontend',
|
||||||
|
help='Enable using default pagekite.net frontend')
|
||||||
|
subparsers.add_parser('disable-pagekitenet-frontend',
|
||||||
|
help='Disable default pagekite.net frontend')
|
||||||
|
|
||||||
|
# Frontend
|
||||||
|
subparsers.add_parser('get-frontend', help='Get pagekite frontend')
|
||||||
|
set_frontend = subparsers.add_parser('set-frontend',
|
||||||
|
help='Set pagekite frontend')
|
||||||
|
set_frontend.add_argument('url', help='frontend url')
|
||||||
|
|
||||||
|
# Kite details (name + secret)
|
||||||
|
subparsers.add_parser('get-kite',
|
||||||
|
help='Get configured kite name and secret')
|
||||||
|
set_kite = subparsers.add_parser('set-kite',
|
||||||
|
help='Configure kite name and its secret')
|
||||||
|
set_kite.add_argument('--kite-name',
|
||||||
|
help='Name of the kite (eg: mybox.pagekite.me)')
|
||||||
|
set_kite.add_argument('--kite-secret', help='Secret for the kite')
|
||||||
|
|
||||||
|
# Services
|
||||||
|
subparsers.add_parser('get-services', help='Get list of enabled services')
|
||||||
|
add_service = subparsers.add_parser('add-service',
|
||||||
|
help='Add a pagekite service')
|
||||||
|
add_service.add_argument('--params', help='\':\'-separated parameters')
|
||||||
|
remove_service = subparsers.add_parser('remove-service',
|
||||||
|
help='Remove a pagekite service')
|
||||||
|
remove_service.add_argument('--params', help='\':\'-separated parameters')
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_start(_):
|
||||||
|
"""Start PageKite service"""
|
||||||
|
status = subprocess.call(['service', 'pagekite', 'start'])
|
||||||
|
if status:
|
||||||
|
raise Exception('Unable to start PageKite server')
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_stop(_):
|
||||||
|
"""Stop PageKite service"""
|
||||||
|
status = subprocess.call(['service', 'pagekite', 'stop'])
|
||||||
|
if status:
|
||||||
|
raise Exception('Unable to stop PageKite server')
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_is_enabled(_):
|
||||||
|
"""Print whether pagekite is enabled (yes or no)"""
|
||||||
|
is_enabled = is_pagekite_enabled()
|
||||||
|
print 'yes' if is_enabled else 'no'
|
||||||
|
|
||||||
|
|
||||||
|
def is_pagekite_enabled():
|
||||||
|
return not bool(aug.match(PATHS['abort_not_configured']))
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_enable(_):
|
||||||
|
pagekite_enable()
|
||||||
|
print 'enabled'
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_disable(_):
|
||||||
|
pagekite_disable()
|
||||||
|
print 'disabled'
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_frontend(_):
|
||||||
|
"""Get pagekite frontend url"""
|
||||||
|
url = aug.get(PATHS['frontend'])
|
||||||
|
print url if url else ""
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_set_frontend(arguments):
|
||||||
|
"""Set pagekite frontend url and disable default pagekite.net frontend"""
|
||||||
|
aug.remove(PATHS['defaults'])
|
||||||
|
aug.set(PATHS['frontend'], arguments.url)
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_pagekitenet_frontend_status(_):
|
||||||
|
match = aug.match(PATHS['defaults'])
|
||||||
|
print "enabled" if match else "disabled"
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_enable_pagekitenet_frontend(_):
|
||||||
|
"""Enable using default pageket.net frontend
|
||||||
|
|
||||||
|
This disables any other frontends.
|
||||||
|
"""
|
||||||
|
aug.set(PATHS['defaults'], '')
|
||||||
|
aug.remove(PATHS['frontend'])
|
||||||
|
aug.save()
|
||||||
|
print "enabled"
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_disable_pagekitenet_frontend(_):
|
||||||
|
aug.remove(PATHS['defaults'])
|
||||||
|
aug.save()
|
||||||
|
print "disabled"
|
||||||
|
|
||||||
|
|
||||||
|
def pagekite_enable():
|
||||||
|
"""Enable the pagekite daemon"""
|
||||||
|
aug.remove(PATHS['abort_not_configured'])
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def pagekite_disable():
|
||||||
|
"""Disable the pagekite daemon"""
|
||||||
|
aug.set(PATHS['abort_not_configured'], '')
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_services(arguments):
|
||||||
|
""" lists all available (enabled) services """
|
||||||
|
for match in aug.match(PATHS['service_on']):
|
||||||
|
print ":".join([aug.get(os.path.join(match, param)) for param in
|
||||||
|
SERVICE_PARAMS])
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_remove_service(arguments):
|
||||||
|
"""Searches and removes the service(s) that match all given parameters"""
|
||||||
|
params = construct_params(arguments.params)
|
||||||
|
paths = get_existing_service_paths(params)
|
||||||
|
# TODO: theoretically, everything to do here is:
|
||||||
|
# [aug.remove(path) for path in paths]
|
||||||
|
# but augeas won't let you save the changed files, and won't tell you why
|
||||||
|
for path in paths:
|
||||||
|
filepath = convert_augeas_path_to_filepath(path)
|
||||||
|
service_found = False
|
||||||
|
with open(filepath, 'r') as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if line.startswith('service_on') and \
|
||||||
|
all(param in line for param in params.values()):
|
||||||
|
lines[i] = ""
|
||||||
|
service_found = True
|
||||||
|
break
|
||||||
|
if service_found:
|
||||||
|
with open(filepath, 'w') as file:
|
||||||
|
file.writelines(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def get_existing_service_paths(params):
|
||||||
|
"""Returns paths of existing services that match the given params"""
|
||||||
|
# construct an augeas query path with patterns like:
|
||||||
|
# */service_on/*[protocol='http']
|
||||||
|
path = PATHS['service_on']
|
||||||
|
for key, value in params.items():
|
||||||
|
path += "[%s='%s']" % (key, value)
|
||||||
|
return aug.match(path)
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_add_service(arguments):
|
||||||
|
"""Add one service"""
|
||||||
|
params = construct_params(arguments.params)
|
||||||
|
if get_existing_service_paths(params):
|
||||||
|
msg = "Service with the parameters %s already exists"
|
||||||
|
raise RuntimeError(msg % params)
|
||||||
|
|
||||||
|
root = get_new_service_path(params['protocol'])
|
||||||
|
# TODO: after adding a service, augeas fails writing the config;
|
||||||
|
# so do it manually here
|
||||||
|
path = convert_augeas_path_to_filepath(root)
|
||||||
|
with open(path, 'a') as servicefile:
|
||||||
|
line = "service_on = %s" % arguments.params
|
||||||
|
servicefile.write(line)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_augeas_path_to_filepath(augpath, prefix='/files',
|
||||||
|
suffix='service_on'):
|
||||||
|
"""Convert an augeas service_on path to the actual file path"""
|
||||||
|
if augpath.startswith(prefix):
|
||||||
|
augpath = augpath.replace(prefix, "", 1)
|
||||||
|
|
||||||
|
index = augpath.rfind(suffix)
|
||||||
|
if index:
|
||||||
|
augpath = augpath[:index]
|
||||||
|
return augpath.rstrip('/')
|
||||||
|
|
||||||
|
|
||||||
|
def get_new_service_path(protocol):
|
||||||
|
"""Get the augeas path of a new service for a protocol
|
||||||
|
|
||||||
|
This takes care of existing services using a /service_on/*/ query"""
|
||||||
|
root = get_augeas_servicefile_path(protocol)
|
||||||
|
new_index = len(aug.match(root + '/*')) + 1
|
||||||
|
return os.path.join(root, str(new_index))
|
||||||
|
|
||||||
|
|
||||||
|
def get_augeas_servicefile_path(protocol):
|
||||||
|
"""Get the augeas path where a service for a protocol should be stored"""
|
||||||
|
if protocol == 'http':
|
||||||
|
relpath = '80_httpd.rc'
|
||||||
|
elif protocol == 'https':
|
||||||
|
relpath = '443_https.rc'
|
||||||
|
elif protocol == 'raw/22':
|
||||||
|
relpath = '22_ssh.rc'
|
||||||
|
elif protocol.startswith('raw'):
|
||||||
|
port = protocol.split('/')[1]
|
||||||
|
relpath = '%s.rc' % port
|
||||||
|
else:
|
||||||
|
raise ValueError('Unsupported protocol: %s' % protocol)
|
||||||
|
|
||||||
|
return os.path.join(CONF_PATH, relpath, 'service_on')
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_kite(_):
|
||||||
|
"""Print details of the currently configured kite"""
|
||||||
|
kitename = aug.get(PATHS['kitename'])
|
||||||
|
kitesecret = aug.get(PATHS['kitesecret'])
|
||||||
|
print kitename if kitename else ''
|
||||||
|
print kitesecret if kitesecret else ''
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_set_kite(arguments):
|
||||||
|
"""Set details of the kite"""
|
||||||
|
aug.set(PATHS['kitename'], arguments.kite_name)
|
||||||
|
aug.set(PATHS['kitesecret'], arguments.kite_secret)
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Parse arguments and perform all duties"""
|
||||||
|
arguments = parse_arguments()
|
||||||
|
|
||||||
|
subcommand = arguments.subcommand.replace('-', '_')
|
||||||
|
subcommand_method = globals()['subcommand_' + subcommand]
|
||||||
|
subcommand_method(arguments)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@ -1,290 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# -*- mode: python -*-
|
|
||||||
#
|
|
||||||
# This file is part of Plinth.
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as
|
|
||||||
# published by the Free Software Foundation, either version 3 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
|
||||||
Configuration helper for Plint PageKite inteface
|
|
||||||
|
|
||||||
TODO: Use augeas for manipulating /etc/pagekite.d/* files
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Disable warning about invalid module name # pylint: disable-msg=C0103
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
CONFIG_DIR = '/etc/pagekite.d'
|
|
||||||
|
|
||||||
SERVICE_FILE_MAP = {
|
|
||||||
'http': {
|
|
||||||
'file': '80_httpd.rc',
|
|
||||||
'match': 'http:',
|
|
||||||
'line': 'service_on = http:@kitename : localhost:80 : @kitesecret'},
|
|
||||||
'ssh': {
|
|
||||||
'file': '80_sshd.rc',
|
|
||||||
'match': 'raw/22:',
|
|
||||||
'line': 'service_on = raw/22:@kitename : localhost:22 : @kitesecret'}}
|
|
||||||
|
|
||||||
|
|
||||||
def parse_arguments():
|
|
||||||
"""Return parsed command line arguments as dictionary"""
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
|
|
||||||
|
|
||||||
# Start PageKite
|
|
||||||
subparsers.add_parser('start', help='Start PageKite service')
|
|
||||||
|
|
||||||
# Stop PageKite
|
|
||||||
subparsers.add_parser('stop', help='Stop PageKite service')
|
|
||||||
|
|
||||||
# Get status
|
|
||||||
subparsers.add_parser('get-status', help='Get whether PakeKite is enabled')
|
|
||||||
|
|
||||||
# Set status
|
|
||||||
set_status = subparsers.add_parser('set-status',
|
|
||||||
help='Enable/disable PageKite')
|
|
||||||
set_status.add_argument('enable', choices=['enable', 'disable'])
|
|
||||||
|
|
||||||
# Get kite details
|
|
||||||
subparsers.add_parser('get-kite',
|
|
||||||
help='Get configured kite name and secret')
|
|
||||||
|
|
||||||
# Set kite details
|
|
||||||
set_kite = subparsers.add_parser('set-kite',
|
|
||||||
help='Configure kite name and its secret')
|
|
||||||
set_kite.add_argument('--kite-name',
|
|
||||||
help='Name of the kite (eg: mybox.pagekite.me)')
|
|
||||||
set_kite.add_argument('--kite-secret', help='Secret for the kite')
|
|
||||||
|
|
||||||
# Get service status
|
|
||||||
get_service = subparsers.add_parser('get-service-status',
|
|
||||||
help='Get whether service is enabled')
|
|
||||||
get_service.add_argument('service', choices=['http', 'ssh'])
|
|
||||||
|
|
||||||
# Set service status
|
|
||||||
set_service = subparsers.add_parser('set-service-status',
|
|
||||||
help='Enable/disable a service')
|
|
||||||
set_service.add_argument('service', choices=['http', 'ssh'])
|
|
||||||
set_service.add_argument('enable', choices=['enable', 'disable'])
|
|
||||||
|
|
||||||
return parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_start(_):
|
|
||||||
"""Start PageKite service"""
|
|
||||||
status = subprocess.call(['service', 'pagekite', 'start'])
|
|
||||||
if status:
|
|
||||||
raise Exception('Unable to start PageKite server')
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_stop(_):
|
|
||||||
"""Stop PageKite service"""
|
|
||||||
status = subprocess.call(['service', 'pagekite', 'stop'])
|
|
||||||
if status:
|
|
||||||
raise Exception('Unable to stop PageKite server')
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_get_status(_):
|
|
||||||
"""Print status of the pagekite service"""
|
|
||||||
is_enabled = is_pagekite_enabled()
|
|
||||||
print('enabled' if is_enabled else 'disabled')
|
|
||||||
|
|
||||||
|
|
||||||
def is_pagekite_enabled():
|
|
||||||
"""Return if pagekite is enabled"""
|
|
||||||
service_file_path = os.path.join(CONFIG_DIR, '10_account.rc')
|
|
||||||
try:
|
|
||||||
with open(service_file_path, 'r') as file_object:
|
|
||||||
for line in file_object:
|
|
||||||
regex = r'^[ \t]*abort_not_configured'
|
|
||||||
if re.match(regex, line):
|
|
||||||
return False
|
|
||||||
except Exception:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_set_status(arguments):
|
|
||||||
"""Enable/disable the pagekite service"""
|
|
||||||
enable = arguments.enable == 'enable'
|
|
||||||
is_enabled = is_pagekite_enabled()
|
|
||||||
if enable and is_enabled:
|
|
||||||
print('already enabled')
|
|
||||||
return
|
|
||||||
|
|
||||||
if not enable and not is_enabled:
|
|
||||||
print('already disabled')
|
|
||||||
return
|
|
||||||
|
|
||||||
if enable:
|
|
||||||
pagekite_enable()
|
|
||||||
print('enabled')
|
|
||||||
else:
|
|
||||||
pagekite_disable()
|
|
||||||
print('disabled')
|
|
||||||
|
|
||||||
|
|
||||||
def pagekite_enable():
|
|
||||||
"""Enable the pagekite daemon"""
|
|
||||||
file_path = os.path.join(CONFIG_DIR, '10_account.rc')
|
|
||||||
file_path_new = os.path.join(CONFIG_DIR, '10_account.rc.new')
|
|
||||||
with open(file_path, 'r') as read_file_object, \
|
|
||||||
open(file_path_new, 'w') as write_file_object:
|
|
||||||
for line in read_file_object:
|
|
||||||
if not re.match('^[ \t]*abort_not_configured', line):
|
|
||||||
write_file_object.write(line)
|
|
||||||
|
|
||||||
os.rename(file_path_new, file_path)
|
|
||||||
|
|
||||||
|
|
||||||
def pagekite_disable():
|
|
||||||
"""Disable the pagekite daemon"""
|
|
||||||
file_path = os.path.join(CONFIG_DIR, '10_account.rc')
|
|
||||||
with open(file_path, 'a') as file_object:
|
|
||||||
file_object.write('abort_not_configured\n')
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_get_kite(_):
|
|
||||||
"""Print details of the currently configure kite"""
|
|
||||||
kite_name = ''
|
|
||||||
kite_secret = ''
|
|
||||||
|
|
||||||
file_path = os.path.join(CONFIG_DIR, '10_account.rc')
|
|
||||||
with open(file_path, 'r') as file_object:
|
|
||||||
for line in file_object:
|
|
||||||
match = re.match(r'[ \t]*kitename[ \t]*=[ \t]*(.*)', line)
|
|
||||||
if match:
|
|
||||||
kite_name = match.group(1)
|
|
||||||
continue
|
|
||||||
|
|
||||||
match = re.match(r'[ \t]*kitesecret[ \t]*=[ \t]*(.*)', line)
|
|
||||||
if match:
|
|
||||||
kite_secret = match.group(1)
|
|
||||||
continue
|
|
||||||
|
|
||||||
print(kite_name)
|
|
||||||
print(kite_secret)
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_set_kite(arguments):
|
|
||||||
"""Set details of the kite"""
|
|
||||||
kite_name = arguments.kite_name
|
|
||||||
kite_secret = arguments.kite_secret
|
|
||||||
|
|
||||||
file_path = os.path.join(CONFIG_DIR, '10_account.rc')
|
|
||||||
file_path_new = os.path.join(CONFIG_DIR, '10_account.rc.new')
|
|
||||||
with open(file_path, 'r') as read_file_object, \
|
|
||||||
os.fdopen(os.open(file_path_new, os.O_WRONLY | os.O_CREAT,
|
|
||||||
0o400), 'w') as write_file_object:
|
|
||||||
for line in read_file_object:
|
|
||||||
if re.match(r'[ \t]*kitename[ \t]*=.*', line):
|
|
||||||
write_file_object.write(
|
|
||||||
'kitename = {kite_name}\n'.format(kite_name=kite_name))
|
|
||||||
continue
|
|
||||||
|
|
||||||
if re.match(r'[ \t]*kitesecret[ \t]*=.*', line):
|
|
||||||
write_file_object.write('kitesecret = {kite_secret}\n'
|
|
||||||
.format(kite_secret=kite_secret))
|
|
||||||
continue
|
|
||||||
|
|
||||||
write_file_object.write(line)
|
|
||||||
|
|
||||||
os.rename(file_path_new, file_path)
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_get_service_status(arguments):
|
|
||||||
"""Print status of the pagekite service"""
|
|
||||||
is_enabled = is_service_enabled(arguments.service)
|
|
||||||
print('enabled' if is_enabled else 'disabled')
|
|
||||||
|
|
||||||
|
|
||||||
def is_service_enabled(service):
|
|
||||||
"""Return if a service is enabled"""
|
|
||||||
service = SERVICE_FILE_MAP[service]
|
|
||||||
service_file_path = os.path.join(CONFIG_DIR, service['file'])
|
|
||||||
if not os.path.isfile(service_file_path):
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(service_file_path, 'r') as file_object:
|
|
||||||
for line in file_object:
|
|
||||||
regex = '[ \t]*service_on[ \t]*=[ \t]*{match}'
|
|
||||||
regex = regex.format(match=service['match'])
|
|
||||||
if re.match(regex, line):
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_set_service_status(arguments):
|
|
||||||
"""Enable/disable a pagekite service"""
|
|
||||||
enable = arguments.enable == 'enable'
|
|
||||||
is_enabled = is_service_enabled(arguments.service)
|
|
||||||
if enable and is_enabled:
|
|
||||||
print('already enabled')
|
|
||||||
return
|
|
||||||
|
|
||||||
if not enable and not is_enabled:
|
|
||||||
print('already disabled')
|
|
||||||
return
|
|
||||||
|
|
||||||
if enable:
|
|
||||||
service_enable(arguments.service)
|
|
||||||
print('enabled')
|
|
||||||
else:
|
|
||||||
service_disable(arguments.service)
|
|
||||||
print('disabled')
|
|
||||||
|
|
||||||
|
|
||||||
def service_enable(service_name):
|
|
||||||
"""Enable a service"""
|
|
||||||
service = SERVICE_FILE_MAP[service_name]
|
|
||||||
service_file_path = os.path.join(CONFIG_DIR, service['file'])
|
|
||||||
with open(service_file_path, 'w') as file_object:
|
|
||||||
file_object.write('''
|
|
||||||
# Expose the local {service_name} daemon
|
|
||||||
# File auto-generated by Plinth
|
|
||||||
|
|
||||||
{line}
|
|
||||||
'''.format(service_name=service_name, line=service['line']))
|
|
||||||
|
|
||||||
|
|
||||||
def service_disable(service_name):
|
|
||||||
"""Disable a service"""
|
|
||||||
service = SERVICE_FILE_MAP[service_name]
|
|
||||||
service_file_path = os.path.join(CONFIG_DIR, service['file'])
|
|
||||||
service_file_path_new = os.path.join(CONFIG_DIR,
|
|
||||||
service['file'] + '.plinthbak')
|
|
||||||
os.rename(service_file_path, service_file_path_new)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Parse arguments and perform all duties"""
|
|
||||||
arguments = parse_arguments()
|
|
||||||
|
|
||||||
subcommand = arguments.subcommand.replace('-', '_')
|
|
||||||
subcommand_method = globals()['subcommand_' + subcommand]
|
|
||||||
subcommand_method(arguments)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
352
actions/pagekite-configure-configobj
Executable file
352
actions/pagekite-configure-configobj
Executable file
@ -0,0 +1,352 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- mode: python -*-
|
||||||
|
#
|
||||||
|
# This file is part of Plinth.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Configuration helper for Plint PageKite interface
|
||||||
|
|
||||||
|
Unfortunately there is no python3 package for augeas yet
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Disable warning about invalid module name # pylint: disable-msg=C0103
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
#import augeas
|
||||||
|
from configobj import ConfigObj
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
#aug = augeas.Augeas()
|
||||||
|
aug = "XX"
|
||||||
|
|
||||||
|
class ConfigFileCache(dict):
|
||||||
|
"""Cache files to not open files more than once"""
|
||||||
|
def __missing__(self, path):
|
||||||
|
self[path] = ConfigObj(path)
|
||||||
|
return self[path]
|
||||||
|
|
||||||
|
filecache = ConfigFileCache()
|
||||||
|
|
||||||
|
|
||||||
|
CONF_PATH = '/etc/pagekite.d'
|
||||||
|
PATHS = {
|
||||||
|
'account': os.path.join(CONF_PATH, '10_account.rc'),
|
||||||
|
'frontends': os.path.join(CONF_PATH, '20_frontends.rc'),
|
||||||
|
'kitesecret': os.path.join(CONF_PATH, '10_account.rc', 'kitesecret'),
|
||||||
|
'abort_not_configured': os.path.join(CONF_PATH, '10_account.rc',
|
||||||
|
'abort_not_configured'),
|
||||||
|
'defaults': os.path.join(CONF_PATH, '20_frontends.rc', 'defaults'),
|
||||||
|
'frontend': os.path.join(CONF_PATH, '20_frontends.rc', 'frontend'),
|
||||||
|
'http': os.path.join(CONF_PATH, '80_httpd.rc', 'service_on'),
|
||||||
|
'https': os.path.join(CONF_PATH, '443_https.rc', 'service_on'),
|
||||||
|
'ssh': os.path.join(CONF_PATH, '80_sshd.rc', 'service_on'),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_CONF_PATH = '/files/etc/pagekite.d'
|
||||||
|
_PATHS = {
|
||||||
|
'kitename': os.path.join(CONF_PATH, '10_account.rc', 'kitename'),
|
||||||
|
'kitesecret': os.path.join(CONF_PATH, '10_account.rc', 'kitesecret'),
|
||||||
|
'abort_not_configured': os.path.join(CONF_PATH, '10_account.rc',
|
||||||
|
'abort_not_configured'),
|
||||||
|
'defaults': os.path.join(CONF_PATH, '20_frontends.rc', 'defaults'),
|
||||||
|
'frontend': os.path.join(CONF_PATH, '20_frontends.rc', 'frontend'),
|
||||||
|
'http': os.path.join(CONF_PATH, '80_httpd.rc', 'service_on'),
|
||||||
|
'https': os.path.join(CONF_PATH, '443_https.rc', 'service_on'),
|
||||||
|
'ssh': os.path.join(CONF_PATH, '80_sshd.rc', 'service_on'),
|
||||||
|
}
|
||||||
|
# service entries are tuples with [source, destination, secret]
|
||||||
|
# this information will be used when enabling a service
|
||||||
|
SERVICES = {
|
||||||
|
'http': ['http:*.@kitename', 'localhost:80', '@kitesecret'],
|
||||||
|
'https': ['https:*.@kitename', 'localhost:443', '@kitesecret'],
|
||||||
|
'ssh': ['raw/22:@kitename', 'localhost:22', '@kitesecret'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_arguments():
|
||||||
|
"""Return parsed command line arguments as dictionary"""
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
|
||||||
|
|
||||||
|
# Start PageKite
|
||||||
|
subparsers.add_parser('start', help='Start PageKite service')
|
||||||
|
|
||||||
|
# Stop PageKite
|
||||||
|
subparsers.add_parser('stop', help='Stop PageKite service')
|
||||||
|
|
||||||
|
# Get status
|
||||||
|
subparsers.add_parser('get-status', help='Get whether PakeKite is enabled')
|
||||||
|
|
||||||
|
# Set status
|
||||||
|
set_status = subparsers.add_parser('set-status',
|
||||||
|
help='Enable/disable PageKite')
|
||||||
|
set_status.add_argument('enable', choices=['enable', 'disable'])
|
||||||
|
|
||||||
|
# Get whether default pagekite.net frontend is enabled
|
||||||
|
subparsers.add_parser('get-pagekitenet-frontend-status',
|
||||||
|
help='Get whether pagekite.net frontend is enabled')
|
||||||
|
|
||||||
|
# Enable/Disable using default pagekite.net frontend
|
||||||
|
subparsers.add_parser('enable-pagekitenet-frontend',
|
||||||
|
help='Enable using default pagekite.net frontend')
|
||||||
|
subparsers.add_parser('disable-pagekitenet-frontend',
|
||||||
|
help='Disable default pagekite.net frontend')
|
||||||
|
|
||||||
|
# Get frontend
|
||||||
|
subparsers.add_parser('get-frontend', help='Get pagekite frontend')
|
||||||
|
|
||||||
|
# Set frontend
|
||||||
|
set_frontend = subparsers.add_parser('set-frontend',
|
||||||
|
help='Set pagekite frontend')
|
||||||
|
set_frontend.add_argument('url', help='frontend url')
|
||||||
|
|
||||||
|
# Get kite details
|
||||||
|
subparsers.add_parser('get-kite',
|
||||||
|
help='Get configured kite name and secret')
|
||||||
|
|
||||||
|
# Set kite details
|
||||||
|
set_kite = subparsers.add_parser('set-kite',
|
||||||
|
help='Configure kite name and its secret')
|
||||||
|
set_kite.add_argument('--kite-name',
|
||||||
|
help='Name of the kite (eg: mybox.pagekite.me)')
|
||||||
|
set_kite.add_argument('--kite-secret', help='Secret for the kite')
|
||||||
|
|
||||||
|
# Get service status
|
||||||
|
get_service = subparsers.add_parser('get-service-status',
|
||||||
|
help='Get whether service is enabled')
|
||||||
|
get_service.add_argument('service', choices=['http', 'ssh'])
|
||||||
|
|
||||||
|
# Set service status
|
||||||
|
set_service = subparsers.add_parser('set-service-status',
|
||||||
|
help='Enable/disable a service')
|
||||||
|
set_service.add_argument('service', choices=['http', 'ssh'])
|
||||||
|
set_service.add_argument('enable', choices=['enable', 'disable'])
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_start(_):
|
||||||
|
"""Start PageKite service"""
|
||||||
|
status = subprocess.call(['service', 'pagekite', 'start'])
|
||||||
|
if status:
|
||||||
|
raise Exception('Unable to start PageKite server')
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_stop(_):
|
||||||
|
"""Stop PageKite service"""
|
||||||
|
status = subprocess.call(['service', 'pagekite', 'stop'])
|
||||||
|
if status:
|
||||||
|
raise Exception('Unable to stop PageKite server')
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_status(_):
|
||||||
|
"""Print status of the pagekite service"""
|
||||||
|
is_enabled = is_pagekite_enabled()
|
||||||
|
print('enabled' if is_enabled else 'disabled')
|
||||||
|
|
||||||
|
|
||||||
|
def is_pagekite_enabled():
|
||||||
|
conf = filecache[PATHS['account']]
|
||||||
|
return 'abort_not_configured' not in conf
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_set_status(arguments):
|
||||||
|
"""Enable/disable the pagekite service"""
|
||||||
|
enable = arguments.enable == 'enable'
|
||||||
|
is_enabled = is_pagekite_enabled()
|
||||||
|
if enable and is_enabled:
|
||||||
|
print('already enabled')
|
||||||
|
return
|
||||||
|
|
||||||
|
if not enable and not is_enabled:
|
||||||
|
print('already disabled')
|
||||||
|
return
|
||||||
|
|
||||||
|
if enable:
|
||||||
|
pagekite_enable()
|
||||||
|
print('enabled')
|
||||||
|
else:
|
||||||
|
pagekite_disable()
|
||||||
|
print('disabled')
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_frontend(_):
|
||||||
|
"""Get pagekite frontend url"""
|
||||||
|
import ipdb; ipdb.set_trace()
|
||||||
|
conf = filecache[PATHS['frontends']]
|
||||||
|
url = conf['frontend']
|
||||||
|
#url = aug.get(PATHS['frontend'])
|
||||||
|
print(url if url else "")
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_set_frontend(arguments):
|
||||||
|
"""Set pagekite frontend url and disable default pagekite.net frontend"""
|
||||||
|
aug.remove(PATHS['defaults'])
|
||||||
|
aug.set(PATHS['frontend'], arguments.url)
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_pagekitenet_frontend_status(_):
|
||||||
|
match = aug.match(PATHS['defaults'])
|
||||||
|
print("enabled" if match else "disabled")
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_enable_pagekitenet_frontend(_):
|
||||||
|
"""Enable using default pageket.net frontend
|
||||||
|
|
||||||
|
This disables any other frontends.
|
||||||
|
"""
|
||||||
|
aug.set(PATHS['defaults'], '')
|
||||||
|
aug.remove(PATHS['frontend'])
|
||||||
|
aug.save()
|
||||||
|
print("enabled")
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_disable_pagekitenet_frontend(_):
|
||||||
|
aug.remove(PATHS['defaults'])
|
||||||
|
aug.save()
|
||||||
|
print("disabled")
|
||||||
|
|
||||||
|
|
||||||
|
def pagekite_enable():
|
||||||
|
"""Enable the pagekite daemon"""
|
||||||
|
aug.remove(PATHS['abort_not_configured'])
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def pagekite_disable():
|
||||||
|
"""Disable the pagekite daemon"""
|
||||||
|
aug.set(PATHS['abort_not_configured'], '')
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_service_status(arguments):
|
||||||
|
"""Print status of the pagekite service"""
|
||||||
|
is_enabled = bool(get_enabled_service_paths(arguments.service))
|
||||||
|
print('enabled' if is_enabled else 'disabled')
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_kite(_):
|
||||||
|
"""Print details of the currently configured kite"""
|
||||||
|
kitename = aug.get(PATHS['kitename'])
|
||||||
|
kitesecret = aug.get(PATHS['kitesecret'])
|
||||||
|
print(kitename if kitename else '')
|
||||||
|
print(kitesecret if kitesecret else '')
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_set_kite(arguments):
|
||||||
|
"""Set details of the kite"""
|
||||||
|
aug.set(PATHS['kitename'], arguments.kite_name)
|
||||||
|
aug.set(PATHS['kitesecret'], arguments.kite_secret)
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_set_service_status(arguments):
|
||||||
|
"""Enable/disable a pagekite service"""
|
||||||
|
enable = arguments.enable == 'enable'
|
||||||
|
is_enabled = bool(get_enabled_service_paths(arguments.service))
|
||||||
|
if enable and is_enabled:
|
||||||
|
print('already enabled')
|
||||||
|
return
|
||||||
|
|
||||||
|
if not enable and not is_enabled:
|
||||||
|
print('already disabled')
|
||||||
|
return
|
||||||
|
|
||||||
|
if enable:
|
||||||
|
service_enable(arguments.service)
|
||||||
|
print('enabled')
|
||||||
|
else:
|
||||||
|
service_disable(arguments.service)
|
||||||
|
print('disabled')
|
||||||
|
|
||||||
|
|
||||||
|
def service_enable(service):
|
||||||
|
"""Enable a service"""
|
||||||
|
position = len(aug.match(PATHS[service])) + 1
|
||||||
|
root = os.path.join(PATHS[service], str(position))
|
||||||
|
set_service(root, *SERVICES[service])
|
||||||
|
|
||||||
|
|
||||||
|
def set_service(root, source, destination, secret=None):
|
||||||
|
"""Set service_on with the given augeas root (path)"""
|
||||||
|
aug.set(os.path.join(root, 'source'), source)
|
||||||
|
aug.set(os.path.join(root, 'destination'), destination)
|
||||||
|
if secret is not None:
|
||||||
|
aug.set(os.path.join(root, 'secret'), secret)
|
||||||
|
aug.save()
|
||||||
|
|
||||||
|
|
||||||
|
def get_enabled_service_paths(service):
|
||||||
|
"""Search all service_on lines of the given protocol"""
|
||||||
|
paths = []
|
||||||
|
for i, match in enumerate(aug.match(PATHS[service]), start=1):
|
||||||
|
service_path = os.path.join(match, str(i))
|
||||||
|
source = aug.get(os.path.join(service_path, 'source'))
|
||||||
|
if service == "ssh" and "raw/22" in source:
|
||||||
|
paths.append(service_path)
|
||||||
|
elif service == "http" and service in source:
|
||||||
|
paths.append(service_path)
|
||||||
|
return paths
|
||||||
|
|
||||||
|
|
||||||
|
def service_disable(service):
|
||||||
|
"""Disable a service"""
|
||||||
|
# TODO: saving config files after changing/deleting config entries with
|
||||||
|
# augeas fails with an IOError.
|
||||||
|
# Saving the file after removing this path does not work:
|
||||||
|
# /files/etc/pagekite.d/80_httpd.rc/service_on/1
|
||||||
|
# Saving the file after removing this path works:
|
||||||
|
# /files/etc/pagekite.d/80_httpd.rc/service_on
|
||||||
|
#
|
||||||
|
# This could be an augeas bug, see
|
||||||
|
# http://permalink.gmane.org/gmane.comp.sysutils.augeas.devel/5419
|
||||||
|
# Once this problem is solved, all you should need in this function is:
|
||||||
|
#
|
||||||
|
# paths = get_enabled_service_paths(service)
|
||||||
|
# [aug.remove(path) for path in paths]
|
||||||
|
# aug.save()
|
||||||
|
|
||||||
|
if service == "ssh":
|
||||||
|
path = '/etc/pagekite.d/80_sshd.rc'
|
||||||
|
activated_pattern = 'raw/22'
|
||||||
|
elif service == "http":
|
||||||
|
path = '/etc/pagekite.d/80_httpd.rc'
|
||||||
|
activated_pattern = 'http'
|
||||||
|
with open(path, 'r') as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if line.startswith('service_on') and activated_pattern in line:
|
||||||
|
lines[i] = "#%s" % line
|
||||||
|
break
|
||||||
|
with open(path, 'w') as file:
|
||||||
|
file.writelines(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Parse arguments and perform all duties"""
|
||||||
|
arguments = parse_arguments()
|
||||||
|
|
||||||
|
subcommand = arguments.subcommand.replace('-', '_')
|
||||||
|
subcommand_method = globals()['subcommand_' + subcommand]
|
||||||
|
subcommand_method(arguments)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
52
actions/pagekite_common.py
Normal file
52
actions/pagekite_common.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/python2
|
||||||
|
# -*- mode: python -*-
|
||||||
|
#
|
||||||
|
# This file is part of Plinth.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
The variables/functions defined here are used by both the action script
|
||||||
|
and the plinth pagekite module.
|
||||||
|
|
||||||
|
Currently that's functionality for converting pagekite service_on strings like
|
||||||
|
"http:@kitename:localhost:80:@kitestring"
|
||||||
|
into parameter dictionaries and the other way round.
|
||||||
|
"""
|
||||||
|
|
||||||
|
SERVICE_PARAMS = ['protocol', 'kitename', 'backend_host', 'backend_port',
|
||||||
|
'secret']
|
||||||
|
|
||||||
|
|
||||||
|
def construct_params(string):
|
||||||
|
""" Convert a parameter string into a params dictionary"""
|
||||||
|
try:
|
||||||
|
params = dict(zip(SERVICE_PARAMS, string.split(':')))
|
||||||
|
except:
|
||||||
|
msg = """params are expected to be a ':'-separated string
|
||||||
|
containing values for: %s , for example:\n"--params
|
||||||
|
http:@kitename:localhost:8000:@kitesecret"
|
||||||
|
"""
|
||||||
|
raise ValueError(msg % ", ".join(SERVICE_PARAMS))
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
def deconstruct_params(params):
|
||||||
|
""" Convert params into a ":"-separated parameter string """
|
||||||
|
try:
|
||||||
|
paramstring = ":".join([params[param] for param in SERVICE_PARAMS])
|
||||||
|
except KeyError:
|
||||||
|
raise ValueError("Could not parse params: %s " % params)
|
||||||
|
return paramstring
|
||||||
79
data/usr/share/augeas/lenses/pagekite.aug
Normal file
79
data/usr/share/augeas/lenses/pagekite.aug
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
(*
|
||||||
|
Module: Pagekite
|
||||||
|
Parses /etc/pagekite.d/
|
||||||
|
|
||||||
|
Author: Michael Pimmer <blubb@fonfon.at>
|
||||||
|
|
||||||
|
About: License
|
||||||
|
This file is licenced under the LGPL v2+, like the rest of Augeas.
|
||||||
|
*)
|
||||||
|
|
||||||
|
module Pagekite =
|
||||||
|
autoload xfm
|
||||||
|
|
||||||
|
(* View: lns *)
|
||||||
|
|
||||||
|
(* Variables *)
|
||||||
|
let equals = del /[ \t]*=[ \t]*/ "="
|
||||||
|
let neg2 = /[^# \n\t]+/
|
||||||
|
let neg3 = /[^# \:\n\t]+/
|
||||||
|
let eol = del /\n/ "\n"
|
||||||
|
(* Match everything from here to eol, cropping whitespace at both ends *)
|
||||||
|
let to_eol = /[^ \t\n](.*[^ \t\n])?/
|
||||||
|
|
||||||
|
(* A key followed by comma-separated values
|
||||||
|
k: name of the key
|
||||||
|
key_sep: separator between key and values
|
||||||
|
value_sep: separator between values
|
||||||
|
sto: store for values
|
||||||
|
*)
|
||||||
|
let key_csv_line (k:string) (key_sep:lens) (value_sep:lens) (sto:lens) =
|
||||||
|
[ key k . key_sep . [ seq k . sto ] .
|
||||||
|
[ seq k . value_sep . sto ]* . Util.eol ]
|
||||||
|
|
||||||
|
(* entries for pagekite.d/10_account.rc *)
|
||||||
|
let domain = [ key "domain" . equals . store neg2 . Util.comment_or_eol ]
|
||||||
|
let frontend = Build.key_value_line ("frontend" | "frontends")
|
||||||
|
equals (store Rx.neg1)
|
||||||
|
let host = Build.key_value_line "host" equals (store Rx.ip)
|
||||||
|
let ports = key_csv_line "ports" equals Sep.comma (store Rx.integer)
|
||||||
|
let protos = key_csv_line "protos" equals Sep.comma (store Rx.word)
|
||||||
|
|
||||||
|
(* entries for pagekite.d/20_frontends.rc *)
|
||||||
|
let kitesecret = Build.key_value_line "kitesecret" equals (store Rx.space_in)
|
||||||
|
let kv_frontend = Build.key_value_line ( "kitename" | "fe_certname" |
|
||||||
|
"ca_certs" | "tls_endpoint" )
|
||||||
|
equals (store Rx.neg1)
|
||||||
|
|
||||||
|
(* entries for services like 80_httpd.rc *)
|
||||||
|
let service_colon = del /[ \t]*:[ \t]*/ " : "
|
||||||
|
let service_on = [ key "service_on" . [ seq "service_on" . equals .
|
||||||
|
[ label "protocol" . store neg3 ] . service_colon .
|
||||||
|
[ label "kitename" . (store neg3) ] . service_colon .
|
||||||
|
[ label "backend_host" . (store neg3) ] . service_colon .
|
||||||
|
[ label "backend_port" . (store neg3) ] . service_colon . (
|
||||||
|
[ label "secret" . (store Rx.no_spaces) . Util.eol ] | eol
|
||||||
|
) ] ]
|
||||||
|
|
||||||
|
let service_cfg = [ key "service_cfg" . equals . store to_eol . eol ]
|
||||||
|
|
||||||
|
let flags = ( "defaults" | "isfrontend" | "abort_not_configured" | "insecure" )
|
||||||
|
|
||||||
|
let entries = Build.flag_line flags
|
||||||
|
| domain
|
||||||
|
| frontend
|
||||||
|
| host
|
||||||
|
| ports
|
||||||
|
| protos
|
||||||
|
| kv_frontend
|
||||||
|
| kitesecret
|
||||||
|
| service_on
|
||||||
|
| service_cfg
|
||||||
|
|
||||||
|
let lns = ( entries | Util.empty | Util.comment )*
|
||||||
|
|
||||||
|
(* View: filter *)
|
||||||
|
let filter = incl "/etc/pagekite.d/*.rc"
|
||||||
|
. Util.stdexcl
|
||||||
|
|
||||||
|
let xfm = transform lns filter
|
||||||
111
data/usr/share/augeas/lenses/tests/test_pagekite.aug
Normal file
111
data/usr/share/augeas/lenses/tests/test_pagekite.aug
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
module Test_Pagekite =
|
||||||
|
|
||||||
|
let conf1 = "# Use the pagekite.net service defaults.
|
||||||
|
defaults
|
||||||
|
"
|
||||||
|
test Pagekite.lns get conf1 =
|
||||||
|
{ "#comment" = "Use the pagekite.net service defaults." }
|
||||||
|
{ "defaults" }
|
||||||
|
|
||||||
|
|
||||||
|
let conf2 ="
|
||||||
|
frontends = pagekite.freedombox.me
|
||||||
|
ports=80,81
|
||||||
|
"
|
||||||
|
test Pagekite.lns get conf2 =
|
||||||
|
{ }
|
||||||
|
{ "frontends" = "pagekite.freedombox.me" }
|
||||||
|
{ "ports"
|
||||||
|
{ "1" = "80" }
|
||||||
|
{ "2" = "81" } }
|
||||||
|
|
||||||
|
|
||||||
|
let conf3 = "frontend=pagekite.freedombox.me
|
||||||
|
host=192.168.0.3
|
||||||
|
"
|
||||||
|
test Pagekite.lns get conf3 =
|
||||||
|
{ "frontend" = "pagekite.freedombox.me" }
|
||||||
|
{ "host" = "192.168.0.3" }
|
||||||
|
|
||||||
|
|
||||||
|
let conf4 = "isfrontend
|
||||||
|
ports=80,443
|
||||||
|
protos=http,https
|
||||||
|
domain=http,https:*.your.domain:MakeUpAPasswordHere
|
||||||
|
"
|
||||||
|
test Pagekite.lns get conf4 =
|
||||||
|
{ "isfrontend" }
|
||||||
|
{ "ports"
|
||||||
|
{ "1" = "80" }
|
||||||
|
{ "2" = "443" } }
|
||||||
|
{ "protos"
|
||||||
|
{ "1" = "http" }
|
||||||
|
{ "2" = "https" } }
|
||||||
|
{ "domain" = "http,https:*.your.domain:MakeUpAPasswordHere" }
|
||||||
|
|
||||||
|
let conf_account = "kitename = my.freedombox.me
|
||||||
|
kitesecret = 0420
|
||||||
|
# Delete this line!
|
||||||
|
abort_not_configured
|
||||||
|
"
|
||||||
|
test Pagekite.lns get conf_account =
|
||||||
|
{ "kitename" = "my.freedombox.me" }
|
||||||
|
{ "kitesecret" = "0420" }
|
||||||
|
{ "#comment" = "Delete this line!" }
|
||||||
|
{ "abort_not_configured" }
|
||||||
|
|
||||||
|
|
||||||
|
let conf_service = "
|
||||||
|
service_on = raw/22:@kitename : localhost:22 : @kitesecret
|
||||||
|
service_on=http:192.168.0.1:127.0.0.1:80:
|
||||||
|
service_on=https:yourhostname,fqdn:127.0.0.1:443:
|
||||||
|
"
|
||||||
|
test Pagekite.lns get conf_service =
|
||||||
|
{ }
|
||||||
|
{ "service_on"
|
||||||
|
{ "1"
|
||||||
|
{ "protocol" = "raw/22" }
|
||||||
|
{ "kitename" = "@kitename" }
|
||||||
|
{ "backend_host" = "localhost" }
|
||||||
|
{ "backend_port" = "22" }
|
||||||
|
{ "secret" = "@kitesecret" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ "service_on"
|
||||||
|
{ "2"
|
||||||
|
{ "protocol" = "http" }
|
||||||
|
{ "kitename" = "192.168.0.1" }
|
||||||
|
{ "backend_host" = "127.0.0.1" }
|
||||||
|
{ "backend_port" = "80" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ "service_on"
|
||||||
|
{ "3"
|
||||||
|
{ "protocol" = "https" }
|
||||||
|
{ "kitename" = "yourhostname,fqdn" }
|
||||||
|
{ "backend_host" = "127.0.0.1" }
|
||||||
|
{ "backend_port" = "443" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let conf_encryption = "
|
||||||
|
frontend=frontend.your.domain:443
|
||||||
|
fe_certname=frontend.your/domain
|
||||||
|
ca_certs=/etc/pagekite.d/site-cert.pem
|
||||||
|
tls_endpoint=frontend.your.domain:/path/to/frontend.pem
|
||||||
|
"
|
||||||
|
test Pagekite.lns get conf_encryption =
|
||||||
|
{ }
|
||||||
|
{ "frontend" = "frontend.your.domain:443" }
|
||||||
|
{ "fe_certname" = "frontend.your/domain" }
|
||||||
|
{ "ca_certs" = "/etc/pagekite.d/site-cert.pem" }
|
||||||
|
{ "tls_endpoint" = "frontend.your.domain:/path/to/frontend.pem" }
|
||||||
|
|
||||||
|
|
||||||
|
let conf_service_cfg = "insecure
|
||||||
|
service_cfg = KITENAME.pagekite.me/80 : insecure : True
|
||||||
|
"
|
||||||
|
test Pagekite.lns get conf_service_cfg =
|
||||||
|
{ "insecure" }
|
||||||
|
{ "service_cfg" = "KITENAME.pagekite.me/80 : insecure : True" }
|
||||||
@ -73,9 +73,9 @@ class ConfigureForm(forms.Form): # pylint: disable-msg=W0232
|
|||||||
|
|
||||||
server = forms.CharField(
|
server = forms.CharField(
|
||||||
label=_('Server'), required=False,
|
label=_('Server'), required=False,
|
||||||
help_text=_('Currently only pagekite.net server is supported'),
|
help_text=_('Select your pagekite.net server. Set "pagekite.net" to '
|
||||||
widget=forms.TextInput(attrs={'placeholder': 'pagekite.net',
|
'use the default pagekite.net server'),
|
||||||
'disabled': 'disabled'}))
|
widget=forms.TextInput())
|
||||||
|
|
||||||
kite_name = TrimmedCharField(
|
kite_name = TrimmedCharField(
|
||||||
label=_('Kite name'),
|
label=_('Kite name'),
|
||||||
@ -143,6 +143,15 @@ def get_status():
|
|||||||
status['kite_name'] = kite_details[0]
|
status['kite_name'] = kite_details[0]
|
||||||
status['kite_secret'] = kite_details[1]
|
status['kite_secret'] = kite_details[1]
|
||||||
|
|
||||||
|
# PageKite server: 'pagekite.net' if flag 'defaults' is set,
|
||||||
|
# the value of 'frontend' otherwise
|
||||||
|
use_pagekitenet_server = _run(['get-pagekitenet-frontend-status'])
|
||||||
|
if "enabled" in use_pagekitenet_server:
|
||||||
|
value = 'pagekite.net'
|
||||||
|
elif "disabled" in use_pagekitenet_server:
|
||||||
|
value = _run(['get-frontend'])
|
||||||
|
status['server'] = value.replace('\n', '')
|
||||||
|
|
||||||
# Service status
|
# Service status
|
||||||
status['service'] = {}
|
status['service'] = {}
|
||||||
for service in ('http', 'ssh'):
|
for service in ('http', 'ssh'):
|
||||||
@ -173,6 +182,14 @@ def _apply_changes(request, old_status, new_status):
|
|||||||
'--kite-secret', new_status['kite_secret']])
|
'--kite-secret', new_status['kite_secret']])
|
||||||
messages.success(request, _('Kite details set'))
|
messages.success(request, _('Kite details set'))
|
||||||
|
|
||||||
|
if old_status['server'] != new_status['server']:
|
||||||
|
server = new_status['server']
|
||||||
|
if server in ('defaults', 'default', 'pagekite.net'):
|
||||||
|
_run(['enable-pagekitenet-frontend'])
|
||||||
|
else:
|
||||||
|
_run(['set-frontend', server])
|
||||||
|
messages.success(request, _('Pagekite server set'))
|
||||||
|
|
||||||
for service in ['http', 'ssh']:
|
for service in ['http', 'ssh']:
|
||||||
if old_status[service + '_enabled'] != \
|
if old_status[service + '_enabled'] != \
|
||||||
new_status[service + '_enabled']:
|
new_status[service + '_enabled']:
|
||||||
|
|||||||
@ -30,13 +30,13 @@
|
|||||||
<div id='pagekite-post-enabled-form'
|
<div id='pagekite-post-enabled-form'
|
||||||
style='display: {{ form.enabled.value|yesno:'block,none' }};'>
|
style='display: {{ form.enabled.value|yesno:'block,none' }};'>
|
||||||
<h3>PageKite Account</h3>
|
<h3>PageKite Account</h3>
|
||||||
{% include 'bootstrapform/field.html' with field=form.server %}
|
{{ form.server|bootstrap_horizontal }}
|
||||||
{% include 'bootstrapform/field.html' with field=form.kite_name %}
|
{{ form.kite_name|bootstrap_horizontal }}
|
||||||
{% include 'bootstrapform/field.html' with field=form.kite_secret %}
|
{{ form.kite_secret|bootstrap_horizontal }}
|
||||||
|
|
||||||
<h3>Services</h3>
|
<h3>Services</h3>
|
||||||
{% include 'bootstrapform/field.html' with field=form.http_enabled %}
|
{{ form.http_enabled|bootstrap_horizontal }}
|
||||||
{% include 'bootstrapform/field.html' with field=form.ssh_enabled %}
|
{{ form.ssh_enabled|bootstrap_horizontal }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" class="btn btn-primary" value="Update setup"/>
|
<input type="submit" class="btn btn-primary" value="Update setup"/>
|
||||||
|
|||||||
4
setup.py
4
setup.py
@ -140,6 +140,10 @@ setuptools.setup(
|
|||||||
glob.glob(os.path.join('actions', '*'))),
|
glob.glob(os.path.join('actions', '*'))),
|
||||||
('/usr/share/man/man1', ['doc/plinth.1']),
|
('/usr/share/man/man1', ['doc/plinth.1']),
|
||||||
('/etc/plinth', ['data/etc/plinth/plinth.config']),
|
('/etc/plinth', ['data/etc/plinth/plinth.config']),
|
||||||
|
('/usr/share/augeas/lenses',
|
||||||
|
['data/usr/share/augeas/lenses/pagekite.aug']),
|
||||||
|
('/usr/share/augeas/lenses/tests',
|
||||||
|
['data/usr/share/augeas/lenses/tests/test_pagekite.aug']),
|
||||||
('/etc/plinth/modules-enabled',
|
('/etc/plinth/modules-enabled',
|
||||||
glob.glob(os.path.join('data/etc/plinth/modules-enabled',
|
glob.glob(os.path.join('data/etc/plinth/modules-enabled',
|
||||||
'*')))],
|
'*')))],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user