Add pre-commit

pull/15/head
Christophe Mehay 7 years ago
parent 27dd14ab33
commit f206ea354c

@ -0,0 +1,21 @@
- repo: git://github.com/pre-commit/pre-commit-hooks
sha: v0.9.1
hooks:
- id: check-added-large-files
- id: check-docstring-first
- id: check-merge-conflict
- id: check-yaml
- id: end-of-file-fixer
- id: flake8
args:
- --exclude=__init__.py
language_version: python3
- id: autopep8-wrapper
language_version: python3
- id: requirements-txt-fixer
- id: trailing-whitespace
- repo: git://github.com/asottile/reorder_python_imports
sha: v0.3.5
hooks:
- id: reorder-python-imports
language_version: python3

@ -4,5 +4,7 @@ python:
- "3.4"
- "3.5"
- "3.6"
install: pip install tox-travis
script: tox
install: pip install tox-travis pre-commit
script:
- pre-commit run --all-files
- tox

@ -90,6 +90,34 @@ To increase security, it's possible to setup your service through socket between
__Warning__: Due to a bug in `tor` configuration parser, it's not possible to mix network link and socket link in the same `tor` configuration.
### Group services
Multiple services can be hosted behind the same onion address.
```yaml
links:
- hello
- world
- hey
environment:
# Set mapping ports
HELLO_PORTS: 80:80
# Multiple ports can be coma separated
WORLD_PORTS: 8000:80,8888:80,22:22
# Socket mapping is supported
HEY_PORTS: 80:unix:/var/run/socket.sock
# hello and world will share the same onion address
# Service name can be any string as long there is not special char
HELLO_SERVICE_NAME: foo
WORLD_SERVICE_NAME: foo
```
__Warning__: Be carefull to not use the same exposed ports for grouped services.
### Compose v2 support
Links setting are required when using docker-compose v2. See `docker-compose.v2.yml` for example.

@ -1,20 +1,17 @@
#!/usr/bin/env python3
import argparse
import logging
import os
import sys
from json import dumps
from re import match
from pyentrypoint import DockerLinks
import argparse
from jinja2 import Environment
from jinja2 import FileSystemLoader
from pyentrypoint import DockerLinks
from .Service import ServicesGroup, Service
import logging
from .Service import Service
from .Service import ServicesGroup
class Setup(object):
@ -163,13 +160,10 @@ class Setup(object):
def setup_hosts(self):
self.setup = {}
try:
self._get_setup_from_env()
self._get_setup_from_links()
self.check_services()
self.apply_conf()
except BaseException:
raise Exception('Something wrongs with setup')
self._get_setup_from_env()
self._get_setup_from_links()
self.check_services()
self.apply_conf()
def check_services(self):
for group in self.services:
@ -263,15 +257,26 @@ def main():
help='Setup hosts')
args = parser.parse_args()
onions = Onions()
if args.setup:
onions.setup_hosts()
return
onions.torrc_parser()
try:
onions = Onions()
if args.setup:
onions.setup_hosts()
else:
onions.torrc_parser()
except BaseException as e:
error_msg = str(e)
else:
error_msg = None
if args.json:
if error_msg:
print(dumps({'error': error_msg}))
sys.exit(1)
logging.getLogger().setLevel(logging.ERROR)
print(onions.to_json())
else:
if error_msg:
logging.error(error_msg)
sys.exit(1)
print(onions)

@ -1,12 +1,11 @@
'This class define a service link'
from Crypto.PublicKey import RSA
from hashlib import sha1
from base64 import b32encode
import logging
import os
import re
from base64 import b32encode
from hashlib import sha1
import logging
from Crypto.PublicKey import RSA
class ServicesGroup(object):
@ -18,6 +17,9 @@ class ServicesGroup(object):
hidden_service_dir = "/var/lib/tor/hidden_service/"
def __init__(self, name=None, service=None, hidden_service_dir=None):
name_regex = r'^[a-zA-Z0-9-_]+$'
self.hidden_service_dir = hidden_service_dir or self.hidden_service_dir
if not name and not service:
raise Exception(
@ -25,6 +27,10 @@ class ServicesGroup(object):
)
self.services = []
self.name = name or service.host
if not re.match(name_regex, self.name):
raise Exception(
'Group {name} has invalid name'.format(name=self.name)
)
if service:
self.add_service(service)

@ -1,2 +1,5 @@
from .Onions import Onions, main
from .Service import ServicesGroup, Service, Ports
from .Onions import main
from .Onions import Onions
from .Service import Ports
from .Service import Service
from .Service import ServicesGroup

@ -33,7 +33,7 @@ setup(
install_requires=['pyentrypoint==0.5.0',
'Jinja2>=2.8',
'pycrypto',],
'pycrypto', ],
entry_points={
'console_scripts': [

@ -1,13 +1,13 @@
from onions import Onions
import json
import os
import pytest
import re
from base64 import b32encode
from hashlib import sha1
import pytest
from Crypto.PublicKey import RSA
from hashlib import sha1
from base64 import b32encode
from onions import Onions
def get_key_and_onion():
key = '''
@ -40,6 +40,7 @@ bhJ3M9WzP/EMkAzyW8mVs1moFp3hRcfQlZHl6g1U9D8=
return key.strip(), onion
def get_torrc_template():
return r'''
{% for service_group in services %}
@ -65,6 +66,7 @@ SocksPort 0
# useless line for Jinja bug
'''.strip()
def test_ports(monkeypatch):
env = {
'SERVICE1_PORTS': '80:80',
@ -104,6 +106,7 @@ def test_ports(monkeypatch):
assert check == 10
def test_docker_links(fs, monkeypatch):
env = {
@ -186,6 +189,7 @@ def test_key(monkeypatch):
assert onion.services[0].onion_url == onion_url
def test_key_in_secret(fs, monkeypatch):
env = {
'SERVICE1_SERVICE_NAME': 'group1',
@ -284,6 +288,7 @@ def test_configuration(fs, monkeypatch):
(port.port_from, port.dest) for port in service.ports
) == set([(80, 'unix://unix.socket')])
def test_groups(monkeypatch):
env = {
'SERVICE1_SERVICE_NAME': 'group1',
@ -323,6 +328,7 @@ def test_groups(monkeypatch):
assert re.match(onion_match, group.onion_url)
def test_json(monkeypatch):
env = {
'SERVICE1_SERVICE_NAME': 'group1',
@ -345,6 +351,7 @@ def test_json(monkeypatch):
assert len(jsn['group1']) == 3
assert len(jsn['group2']) == 1
def test_output(monkeypatch):
env = {
'SERVICE1_SERVICE_NAME': 'group1',
@ -363,6 +370,7 @@ def test_output(monkeypatch):
for item in ['group1', 'group2', '.onion', ',']:
assert item in str(onion)
def test_not_valid_share_port(monkeypatch):
env = {
'SERVICE1_SERVICE_NAME': 'group1',
@ -382,6 +390,7 @@ def test_not_valid_share_port(monkeypatch):
onion.check_services()
assert 'Same port for multiple services' in str(excinfo.value)
def test_not_valid_no_services(monkeypatch):
env = {
'SERVICE1_SERVICE_NAME': 'group1',

Loading…
Cancel
Save