proxies: add smart proxy support

still to do:

* document new configuration options
* add smart proxies to groups view
* import bandwidth and CPU alarms
This commit is contained in:
Iain Learmonth 2022-05-24 19:51:38 +01:00
parent 9b90101cf4
commit 66af6e6550
15 changed files with 275 additions and 32 deletions

View file

@ -21,6 +21,7 @@ from app.portal.list import bp as list_
from app.portal.origin import bp as origin
from app.portal.onion import bp as onion
from app.portal.proxy import bp as proxy
from app.portal.smart_proxy import bp as smart_proxy
from app.portal.webhook import bp as webhook
portal = Blueprint("portal", __name__, template_folder="templates", static_folder="static")
@ -33,6 +34,7 @@ portal.register_blueprint(list_, url_prefix="/list")
portal.register_blueprint(origin, url_prefix="/origin")
portal.register_blueprint(onion, url_prefix="/onion")
portal.register_blueprint(proxy, url_prefix="/proxy")
portal.register_blueprint(smart_proxy, url_prefix="/smart")
portal.register_blueprint(webhook, url_prefix="/webhook")

View file

@ -21,6 +21,7 @@ class NewOriginForm(FlaskForm): # type: ignore
description = StringField('Description', validators=[DataRequired()])
group = SelectField('Group', validators=[DataRequired()])
auto_rotate = BooleanField("Enable auto-rotation?", default=True)
smart_proxy = BooleanField("Requires smart proxy?", default=False)
submit = SubmitField('Save Changes')
@ -28,6 +29,7 @@ class EditOriginForm(FlaskForm): # type: ignore
description = StringField('Description', validators=[DataRequired()])
group = SelectField('Group', validators=[DataRequired()])
auto_rotate = BooleanField("Enable auto-rotation?")
smart_proxy = BooleanField("Requires smart proxy?")
submit = SubmitField('Save Changes')
@ -42,6 +44,7 @@ def origin_new(group_id: Optional[int] = None) -> ResponseReturnValue:
origin.domain_name = form.domain_name.data
origin.description = form.description.data
origin.auto_rotation = form.auto_rotate.data
origin.smart = form.smart_proxy.data
origin.created = datetime.utcnow()
origin.updated = datetime.utcnow()
try:
@ -69,12 +72,14 @@ def origin_edit(origin_id: int) -> ResponseReturnValue:
status=404)
form = EditOriginForm(group=origin.group_id,
description=origin.description,
auto_rotate=origin.auto_rotation)
auto_rotate=origin.auto_rotation,
smart_proxy=origin.smart)
form.group.choices = [(x.id, x.group_name) for x in Group.query.all()]
if form.validate_on_submit():
origin.group_id = form.group.data
origin.description = form.description.data
origin.auto_rotation = form.auto_rotate.data
origin.smart = form.smart_proxy.data
origin.updated = datetime.utcnow()
try:
db.session.commit()

17
app/portal/smart_proxy.py Normal file
View file

@ -0,0 +1,17 @@
from flask import render_template, Blueprint
from flask.typing import ResponseReturnValue
from sqlalchemy import desc
from app.models.mirrors import SmartProxy
bp = Blueprint("smart_proxy", __name__)
@bp.route("/list")
def smart_proxy_list() -> ResponseReturnValue:
instances = SmartProxy.query.filter(SmartProxy.destroyed.is_(None)).order_by(desc(SmartProxy.added)).all()
return render_template("list.html.j2",
section="smart_proxy",
title="Smart Proxy Instances",
item="smart proxy",
items=instances)

View file

@ -132,8 +132,8 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link{% if section == "smart_proxy" %} active{% endif %} disabled text-secondary"
href="#">
<a class="nav-link{% if section == "smart_proxy" %} active{% endif %}"
href="{{ url_for("portal.smart_proxy.smart_proxy_list") }}">
{{ icon("globe") }} Smart Proxy Instances
</a>
</li>

View file

@ -71,6 +71,11 @@
viewBox="0 0 16 16">
<path d="M8 4.5a7 7 0 0 0-7 7 .5.5 0 0 1-1 0 8 8 0 1 1 16 0 .5.5 0 0 1-1 0 7 7 0 0 0-7-7zm0 2a5 5 0 0 0-5 5 .5.5 0 0 1-1 0 6 6 0 1 1 12 0 .5.5 0 0 1-1 0 5 5 0 0 0-5-5zm0 2a3 3 0 0 0-3 3 .5.5 0 0 1-1 0 4 4 0 1 1 8 0 .5.5 0 0 1-1 0 3 3 0 0 0-3-3zm0 2a1 1 0 0 0-1 1 .5.5 0 0 1-1 0 2 2 0 1 1 4 0 .5.5 0 0 1-1 0 1 1 0 0 0-1-1z"/>
</svg>
{% elif i == "terminal" %}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-terminal" viewBox="0 0 16 16">
<path d="M6 9a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3A.5.5 0 0 1 6 9zM3.854 4.146a.5.5 0 1 0-.708.708L4.793 6.5 3.146 8.146a.5.5 0 1 0 .708.708l2-2a.5.5 0 0 0 0-.708l-2-2z"/>
<path d="M2 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H2zm12 1a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h12z"/>
</svg>
{% elif i == "onion" %}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-onion"
viewBox="0 2 24 24" style="margin-top: -3px;">

View file

@ -1,6 +1,6 @@
{% extends "base.html.j2" %}
{% from "tables.html.j2" import alarms_table, automations_table, bridgeconfs_table, bridges_table, eotk_table,
groups_table, mirrorlists_table, origins_table, origin_onion_table, onions_table, proxies_table,
groups_table, instances_table, mirrorlists_table, origins_table, origin_onion_table, onions_table, proxies_table,
webhook_table %}
{% block content %}
@ -35,6 +35,8 @@
{{ origins_table(items) }}
{% elif item == "proxy" %}
{{ proxies_table(items) }}
{% elif item == "smart proxy" %}
{{ instances_table("smart_proxy", items) }}
{% elif item == "webhook" %}
{{ webhook_table(items) }}
{% endif %}

View file

@ -1,3 +1,5 @@
{% from "icons.html.j2" import icon %}
{% macro alarm_ok() %}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-check-circle text-success" viewBox="0 0 16 16">
@ -49,7 +51,7 @@
</div>
{% endmacro %}
{% macro eotk_table(instances) %}
{% macro instances_table(application, instances) %}
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
@ -92,8 +94,13 @@
{% endfor %}
</td>
<td>
<a href="{{ url_for("portal.eotk.eotk_conf", group_id=instance.group_id) }}"
{% if application in ["eotk"] %}
<a href="{{ url_for("portal." + application + "." + application + "_conf", group_id=instance.group_id) }}"
class="btn btn-primary btn-sm">Preview Configuration</a>
{% endif %}
<a href="https://{{ instance.region }}.console.aws.amazon.com/systems-manager/session-manager/{{ instance.instance_id }}?region={{ instance.region }}" class="btn btn-outline-secondary btn-sm" target="_ssm">
{{ icon("terminal") }}
</a>
</td>
</tr>
{% endif %}
@ -103,6 +110,10 @@
</div>
{% endmacro %}
{% macro eotk_table(instances) %}
{{ instances_table("eotk", instances) }}
{% endmacro %}
{% macro automations_table(automations) %}
<div class="table-responsive">
<table class="table table-striped table-sm">
@ -198,7 +209,8 @@
<tr>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Auto-rotation</th>
<th scope="col">Auto-Rotation</th>
<th scope="col">Smart Proxy</th>
<th scope="col">Onion Service</th>
<th scope="col">Group</th>
<th scope="col">Actions</th>
@ -215,6 +227,7 @@
</td>
<td>{{ origin.description }}</td>
<td>{% if origin.auto_rotation %}✅{% else %}❌{% endif %}</td>
<td>{% if origin.smart %}✅{% else %}❌{% endif %}</td>
<td>{% if origin.onion() %}✅{% else %}❌{% endif %}</td>
<td>
<a href="{{ url_for("portal.group.group_edit", group_id=origin.group.id) }}">{{ origin.group.group_name }}</a>
@ -257,9 +270,9 @@
<td>{{ origin.description }}</td>
<td>
{% if origin.onion() %}
<a href="https://{{ origin.onion() }}.onion" target="_bypass" rel="noopener noreferer"
<a href="https://{{ origin.onion() }}" target="_bypass" rel="noopener noreferer"
class="btn btn-secondary btn-sm">⎋</a>
{{ origin.onion() }}.onion
{{ origin.onion() }}
{% endif %}
</td>
<td>