diff --git a/app/cli/automate.py b/app/cli/automate.py
index 93552cd..21e0b00 100644
--- a/app/cli/automate.py
+++ b/app/cli/automate.py
@@ -12,7 +12,7 @@ from app.terraform.block_bridge_github import BlockBridgeGitHubAutomation
from app.terraform.block_external import BlockExternalAutomation
from app.terraform.block_ooni import BlockOONIAutomation
from app.terraform.block_roskomsvoboda import BlockRoskomsvobodaAutomation
-from app.terraform.eotk import EotkAutomation
+from app.terraform.eotk.aws import EotkAWSAutomation
from app.terraform.alarms.proxy_azure_cdn import AlarmProxyAzureCdnAutomation
from app.terraform.alarms.proxy_cloudfront import AlarmProxyCloudfrontAutomation
from app.terraform.alarms.proxy_http_status import AlarmProxyHTTPStatusAutomation
@@ -41,7 +41,7 @@ jobs = {
BridgeGandiAutomation,
BridgeHcloudAutomation,
BridgeOvhAutomation,
- EotkAutomation,
+ EotkAWSAutomation,
ListGithubAutomation,
ListGitlabAutomation,
ListS3Automation,
diff --git a/app/models/onions.py b/app/models/onions.py
index faac6c6..cb8f252 100644
--- a/app/models/onions.py
+++ b/app/models/onions.py
@@ -13,6 +13,7 @@ class Onion(AbstractConfiguration):
class Eotk(AbstractResource):
group_id = db.Column(db.Integer(), db.ForeignKey("group.id"), nullable=False)
instance_id = db.Column(db.String(100), nullable=True)
+ provider = db.Column(db.String(20), nullable=False)
region = db.Column(db.String(20), nullable=False)
group = db.relationship("Group", back_populates="eotks")
diff --git a/app/portal/__init__.py b/app/portal/__init__.py
index 527589f..ac2987a 100644
--- a/app/portal/__init__.py
+++ b/app/portal/__init__.py
@@ -10,6 +10,7 @@ from app.portal.list import NewMirrorListForm
from app.portal.automation import bp as automation
from app.portal.bridgeconf import bp as bridgeconf
from app.portal.bridge import bp as bridge
+from app.portal.eotk import bp as eotk
from app.portal.group import bp as group
from app.portal.list import bp as list_
from app.portal.origin import bp as origin
@@ -20,6 +21,7 @@ portal = Blueprint("portal", __name__, template_folder="templates", static_folde
portal.register_blueprint(automation, url_prefix="/automation")
portal.register_blueprint(bridgeconf, url_prefix="/bridgeconf")
portal.register_blueprint(bridge, url_prefix="/bridge")
+portal.register_blueprint(eotk, url_prefix="/eotk")
portal.register_blueprint(group, url_prefix="/group")
portal.register_blueprint(list_, url_prefix="/list")
portal.register_blueprint(origin, url_prefix="/origin")
diff --git a/app/portal/eotk.py b/app/portal/eotk.py
new file mode 100644
index 0000000..d730c1a
--- /dev/null
+++ b/app/portal/eotk.py
@@ -0,0 +1,16 @@
+from flask import render_template, Blueprint
+from sqlalchemy import desc
+
+from app.models.onions import Eotk
+
+bp = Blueprint("eotk", __name__)
+
+
+@bp.route("/list")
+def eotk_list():
+ instances = Eotk.query.filter(Eotk.destroyed == None).order_by(desc(Eotk.added)).all()
+ return render_template("list.html.j2",
+ section="eotk",
+ title="EOTK Instances",
+ item="eotk",
+ items=instances)
diff --git a/app/portal/templates/base.html.j2 b/app/portal/templates/base.html.j2
index 1d9d65a..c763d4f 100644
--- a/app/portal/templates/base.html.j2
+++ b/app/portal/templates/base.html.j2
@@ -132,8 +132,8 @@
-
+
{{ icon("server") }} EOTK Instances
diff --git a/app/portal/templates/list.html.j2 b/app/portal/templates/list.html.j2
index 35e6407..525016f 100644
--- a/app/portal/templates/list.html.j2
+++ b/app/portal/templates/list.html.j2
@@ -1,5 +1,5 @@
{% extends "base.html.j2" %}
-{% from "tables.html.j2" import alarms_table, automations_table, bridgeconfs_table, bridges_table,
+{% 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 %}
{% block content %}
diff --git a/app/portal/templates/tables.html.j2 b/app/portal/templates/tables.html.j2
index b808ce2..a5e1f01 100644
--- a/app/portal/templates/tables.html.j2
+++ b/app/portal/templates/tables.html.j2
@@ -55,12 +55,62 @@
{% endmacro %}
-{% macro eotk_table(eotks) %}
- Not implemented yet.
+{% macro eotk_table(instances) %}
+
+
+
+
+ Group |
+ Provider |
+ Region |
+ Instance ID |
+ Created |
+ Alarms |
+ Actions |
+
+
+
+ {% for instance in instances %}
+ {% if not instance.destroyed %}
+
+
+ {{ instance.group.group_name }}
+ |
+ {{ instance.provider }} |
+ {{ instance.region }} |
+
+ {{ instance.instance_id }}
+ |
+
+ {{ instance.added | format_datetime }}
+ |
+
+ {% for alarm in [] %}
+
+ {% if alarm.alarm_state.name == "OK" %}
+ {{ alarm_ok() }}
+ {% elif alarm.alarm_state.name == "UNKNOWN" %}
+ {{ alarm_unknown() }}
+ {% else %}
+ {{ alarm_critical() }}
+ {% endif %}
+
+ {% endfor %}
+ |
+
+ Generate Configuration
+ |
+
+ {% endif %}
+ {% endfor %}
+
+
+
{% endmacro %}
{% macro automations_table(automations) %}
-
+
diff --git a/app/terraform/eotk.py b/app/terraform/eotk.py
deleted file mode 100644
index e88515a..0000000
--- a/app/terraform/eotk.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from app import app
-from app.models.base import Group
-from app.terraform.terraform import TerraformAutomation
-
-
-class EotkAutomation(TerraformAutomation):
- short_name = "eotk"
- description = "Deploy EOTK instances to AWS"
-
- template_parameters = [
- "aws_access_key",
- "aws_secret_key"
- ]
-
- template = """
- terraform {
- required_providers {
- aws = {
- version = "~> 4.4.0"
- }
- }
- }
-
- provider "aws" {
- access_key = "{{ aws_access_key }}"
- secret_key = "{{ aws_secret_key }}"
- region = "us-east-2"
- }
-
- provider "aws" {
- access_key = "{{ aws_access_key }}"
- secret_key = "{{ aws_secret_key }}"
- region = "eu-central-1"
- alias = "second_region"
- }
-
- {% for group in groups %}
- module "eotk_{{ group.id }}" {
- providers = {
- aws = aws,
- aws.second_region = aws.second_region
- }
- source = "sr2c/eotk/aws"
- version = "0.0.5"
- namespace = "{{ global_namespace }}"
- tenant = "{{ group.group_name }}"
- name = "eotk"
- label_order = ["namespace", "tenant", "name", "attributes"]
- disable_api_termination = true
- }
- {% endfor %}
- """
-
- def tf_generate(self):
- self.tf_write(
- self.template,
- groups=Group.query.filter(
- Group.eotk == True,
- Group.destroyed == None
- ).all(),
- global_namespace=app.config['GLOBAL_NAMESPACE'],
- **{
- k: app.config[k.upper()]
- for k in self.template_parameters
- }
- )
diff --git a/app/terraform/eotk/__init__.py b/app/terraform/eotk/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/app/terraform/eotk/aws.py b/app/terraform/eotk/aws.py
new file mode 100644
index 0000000..4f79384
--- /dev/null
+++ b/app/terraform/eotk/aws.py
@@ -0,0 +1,110 @@
+import datetime
+from typing import Any
+
+from app import app
+from app.extensions import db
+from app.models.base import Group
+from app.models.onions import Eotk
+from app.terraform.terraform import TerraformAutomation
+
+
+def update_eotk_instance(group_id: int, region: str, instance_id: str):
+ instance = Eotk.query.filter(
+ Eotk.group_id == group_id,
+ Eotk.region == region,
+ Eotk.provider == "aws",
+ Eotk.destroyed == None
+ ).first()
+ if instance is None:
+ instance = Eotk()
+ instance.added = datetime.datetime.utcnow()
+ instance.group_id = group_id
+ instance.provider = "aws"
+ instance.region = region
+ db.session.add(instance)
+ instance.updated = datetime.datetime.utcnow()
+ instance.instance_id = instance_id
+
+
+class EotkAWSAutomation(TerraformAutomation):
+ short_name = "eotk_aws"
+ description = "Deploy EOTK instances to AWS"
+
+ template_parameters = [
+ "aws_access_key",
+ "aws_secret_key"
+ ]
+
+ template = """
+ terraform {
+ required_providers {
+ aws = {
+ version = "~> 4.4.0"
+ }
+ }
+ }
+
+ provider "aws" {
+ access_key = "{{ aws_access_key }}"
+ secret_key = "{{ aws_secret_key }}"
+ region = "us-east-2"
+ }
+
+ provider "aws" {
+ access_key = "{{ aws_access_key }}"
+ secret_key = "{{ aws_secret_key }}"
+ region = "eu-central-1"
+ alias = "second_region"
+ }
+
+ {% for group in groups %}
+ module "eotk_{{ group.id }}" {
+ providers = {
+ aws = aws,
+ aws.second_region = aws.second_region
+ }
+ source = "sr2c/eotk/aws"
+ version = "0.0.5"
+ namespace = "{{ global_namespace }}"
+ tenant = "{{ group.group_name }}"
+ name = "eotk"
+ label_order = ["namespace", "tenant", "name", "attributes"]
+ disable_api_termination = true
+ }
+ {% endfor %}
+ """
+
+ def tf_generate(self):
+ self.tf_write(
+ self.template,
+ groups=Group.query.filter(
+ Group.eotk == True,
+ Group.destroyed == None
+ ).all(),
+ global_namespace=app.config['GLOBAL_NAMESPACE'],
+ **{
+ k: app.config[k.upper()]
+ for k in self.template_parameters
+ }
+ )
+
+ def tf_posthook(self, *, prehook_result: Any = None) -> None:
+ state = self.tf_show()
+ for g in state["values"]["root_module"]["child_modules"]:
+ if g["address"].startswith("module.eotk_"):
+ group_id = int(g["address"][len("module.eotk_"):])
+ for i in g["child_modules"]:
+ if ".module.instance_" in i["address"]:
+ instance = int(i["address"][-1])
+ region = "us-east-2" if instance == 1 else "eu-central-1"
+ for s in i["child_modules"]:
+ if s["address"].endswith(".module.instance"):
+ for x in s["resources"]:
+ if x["address"].endswith(".module.instance.aws_instance.default[0]"):
+ update_eotk_instance(group_id, region, x['values']['id'])
+ db.session.commit()
+
+
+with app.app_context():
+ auto = EotkAWSAutomation()
+ auto.tf_posthook()
diff --git a/migrations/versions/7ecfb305d243_add_eotk_provider.py b/migrations/versions/7ecfb305d243_add_eotk_provider.py
new file mode 100644
index 0000000..56e751e
--- /dev/null
+++ b/migrations/versions/7ecfb305d243_add_eotk_provider.py
@@ -0,0 +1,46 @@
+"""add eotk provider
+
+Revision ID: 7ecfb305d243
+Revises: 7155ba7dec60
+Create Date: 2022-05-13 15:34:59.922410
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+# revision identifiers, used by Alembic.
+revision = '7ecfb305d243'
+down_revision = '7155ba7dec60'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.create_table('eotk_instance',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('added', sa.DateTime(), nullable=False),
+ sa.Column('updated', sa.DateTime(), nullable=False),
+ sa.Column('deprecated', sa.DateTime(), nullable=True),
+ sa.Column('deprecation_reason', sa.String(), nullable=True),
+ sa.Column('destroyed', sa.DateTime(), nullable=True),
+ sa.Column('group_id', sa.Integer(), nullable=False),
+ sa.Column('provider', sa.String(length=20), nullable=False),
+ sa.Column('region', sa.String(length=20), nullable=False),
+ sa.Column('instance_id', sa.String(length=255), nullable=True),
+ sa.ForeignKeyConstraint(['group_id'], ['group.id'], name=op.f('fk_eotk_instance_group_id_group')),
+ sa.PrimaryKeyConstraint('id', name=op.f('pk_eotk_instance'))
+ )
+ with op.batch_alter_table('eotk', schema=None) as batch_op:
+ batch_op.add_column(sa.Column('provider', sa.String(length=20), nullable=False))
+
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ with op.batch_alter_table('eotk', schema=None) as batch_op:
+ batch_op.drop_column('provider')
+
+ op.drop_table('eotk_instance')
+ # ### end Alembic commands ###