feat: use custom type to handle existing naive datetimes
This commit is contained in:
parent
e22abb383c
commit
39bdac1ecf
45 changed files with 210 additions and 84 deletions
|
@ -3,24 +3,23 @@ import sys
|
|||
from typing import Iterator
|
||||
|
||||
import yaml
|
||||
from flask import Flask, redirect, url_for, send_from_directory
|
||||
from flask import Flask, redirect, send_from_directory, url_for
|
||||
from flask.typing import ResponseReturnValue
|
||||
from prometheus_client import make_wsgi_app, Metric, CollectorRegistry
|
||||
from prometheus_client.metrics_core import GaugeMetricFamily, CounterMetricFamily
|
||||
from prometheus_client.registry import Collector, REGISTRY
|
||||
from prometheus_client import CollectorRegistry, Metric, make_wsgi_app
|
||||
from prometheus_client.metrics_core import (CounterMetricFamily,
|
||||
GaugeMetricFamily)
|
||||
from prometheus_client.registry import REGISTRY, Collector
|
||||
from prometheus_flask_exporter import PrometheusMetrics
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from werkzeug.middleware.dispatcher import DispatcherMiddleware
|
||||
|
||||
from app.api import api
|
||||
from app.extensions import bootstrap
|
||||
from app.extensions import db
|
||||
from app.extensions import migrate
|
||||
from app.extensions import bootstrap, db, migrate
|
||||
from app.models.automation import Automation, AutomationState
|
||||
from app.portal import portal
|
||||
from app.portal.report import report
|
||||
from app.tfstate import tfstate
|
||||
from prometheus_flask_exporter import PrometheusMetrics
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_file("../config.yaml", load=yaml.safe_load)
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from typing import List, TypedDict, NotRequired, Optional
|
||||
from typing import List, NotRequired, Optional, TypedDict
|
||||
|
||||
from cryptography import x509
|
||||
from flask import request, abort, jsonify, Blueprint
|
||||
from flask import Blueprint, abort, jsonify, request
|
||||
from flask.typing import ResponseReturnValue
|
||||
from sqlalchemy import exc
|
||||
|
||||
from app.api.util import (DOMAIN_NAME_REGEX, MAX_ALLOWED_ITEMS,
|
||||
MAX_DOMAIN_NAME_LENGTH, ListFilter,
|
||||
get_single_resource, list_resources,
|
||||
validate_description)
|
||||
from app.extensions import db
|
||||
from app.api.util import ListFilter, MAX_DOMAIN_NAME_LENGTH, DOMAIN_NAME_REGEX, list_resources, MAX_ALLOWED_ITEMS, \
|
||||
validate_description, get_single_resource
|
||||
from app.models.base import Group
|
||||
from app.models.onions import Onion
|
||||
from app.util.onion import onion_hostname, decode_onion_keys
|
||||
from app.util.onion import decode_onion_keys, onion_hostname
|
||||
from app.util.x509 import validate_tls_keys
|
||||
|
||||
api_onion = Blueprint('api_onion', __name__)
|
||||
|
|
|
@ -2,9 +2,9 @@ import base64
|
|||
import binascii
|
||||
import logging
|
||||
import re
|
||||
from typing import Union, Any, Literal, Type, Callable, Dict, List, Optional
|
||||
from typing import Any, Callable, Dict, List, Literal, Optional, Type, Union
|
||||
|
||||
from flask import abort, request, jsonify
|
||||
from flask import abort, jsonify, request
|
||||
from flask.typing import ResponseReturnValue
|
||||
from sqlalchemy import BinaryExpression, ColumnElement, select
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from datetime import datetime, timedelta, timezone
|
||||
from typing import List
|
||||
|
||||
from flask import Blueprint, request, abort
|
||||
from flask import Blueprint, abort, request
|
||||
from flask.typing import ResponseReturnValue
|
||||
|
||||
from app.api.util import ListFilter, MAX_DOMAIN_NAME_LENGTH, DOMAIN_NAME_REGEX, list_resources, MAX_ALLOWED_ITEMS
|
||||
from app.api.util import (DOMAIN_NAME_REGEX, MAX_ALLOWED_ITEMS,
|
||||
MAX_DOMAIN_NAME_LENGTH, ListFilter, list_resources)
|
||||
from app.models.base import Group
|
||||
from app.models.mirrors import Origin, Proxy
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ Bypass Censorship Resource Names.
|
|||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
|
|
|
@ -9,15 +9,15 @@ from typing import Any, Callable, Dict, List, Type
|
|||
from sqlalchemy import inspect
|
||||
|
||||
from app import app
|
||||
from app.cli import _SubparserType, BaseCliHandler
|
||||
from app.cli import BaseCliHandler, _SubparserType
|
||||
from app.extensions import db
|
||||
from app.models.activity import Webhook, Activity
|
||||
from app.models.automation import AutomationLogs, Automation, AutomationState
|
||||
from app.models.base import Group, MirrorList, PoolGroup, Pool
|
||||
from app.models.activity import Activity, Webhook
|
||||
from app.models.alarms import Alarm, AlarmState
|
||||
from app.models.automation import Automation, AutomationLogs, AutomationState
|
||||
from app.models.base import Group, MirrorList, Pool, PoolGroup
|
||||
from app.models.bridges import Bridge, BridgeConf
|
||||
from app.models.mirrors import Origin, Proxy, SmartProxy
|
||||
from app.models.alarms import Alarm, AlarmState
|
||||
from app.models.onions import Onion, Eotk
|
||||
from app.models.onions import Eotk, Onion
|
||||
from app.models.tfstate import TerraformState
|
||||
|
||||
Model = Type[db.Model] # type: ignore[name-defined]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import json
|
||||
import logging
|
||||
import sys
|
||||
from typing import Callable, Any
|
||||
from typing import Any, Callable
|
||||
|
||||
from app import app
|
||||
from app.cli import _SubparserType, BaseCliHandler
|
||||
from app.cli import BaseCliHandler, _SubparserType
|
||||
from app.lists import lists
|
||||
from app.models.base import Pool
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from flask_bootstrap import Bootstrap5
|
||||
from flask_migrate import Migrate
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_bootstrap import Bootstrap5
|
||||
from sqlalchemy import MetaData
|
||||
|
||||
convention = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Dict, Callable, Any
|
||||
from typing import Any, Callable, Dict
|
||||
|
||||
from app.lists.bc2 import mirror_sites
|
||||
from app.lists.bridgelines import bridgelines
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from typing import List, Optional, TypedDict
|
||||
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.models.base import Pool
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from typing import List, Dict, Optional, TypedDict
|
||||
from typing import Dict, List, Optional, TypedDict
|
||||
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.models.base import Pool
|
||||
|
|
|
@ -7,6 +7,7 @@ from sqlalchemy.orm import Mapped, mapped_column
|
|||
|
||||
from app.brm.brn import BRN
|
||||
from app.extensions import db
|
||||
from app.models.types import AwareDateTime
|
||||
|
||||
|
||||
class AbstractConfiguration(db.Model): # type: ignore
|
||||
|
@ -14,9 +15,9 @@ class AbstractConfiguration(db.Model): # type: ignore
|
|||
|
||||
id: Mapped[int] = mapped_column(db.Integer, primary_key=True)
|
||||
description: Mapped[str]
|
||||
added: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
updated: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
destroyed: Mapped[Optional[datetime]] = mapped_column(db.DateTime(timezone=True), nullable=True)
|
||||
added: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
updated: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
destroyed: Mapped[Optional[datetime]] = mapped_column(AwareDateTime(), nullable=True)
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
|
@ -43,7 +44,7 @@ class Deprecation(db.Model): # type: ignore[name-defined,misc]
|
|||
id: Mapped[int] = mapped_column(db.Integer, primary_key=True)
|
||||
resource_type: Mapped[str]
|
||||
resource_id: Mapped[int]
|
||||
deprecated_at: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
deprecated_at: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
meta: Mapped[Optional[Dict[str, Any]]] = mapped_column(db.JSON())
|
||||
reason: Mapped[str]
|
||||
|
||||
|
@ -58,11 +59,11 @@ class AbstractResource(db.Model): # type: ignore
|
|||
__abstract__ = True
|
||||
|
||||
id: Mapped[int] = mapped_column(db.Integer, primary_key=True)
|
||||
added: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
updated: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
deprecated: Mapped[Optional[datetime]] = mapped_column(db.DateTime(timezone=True), nullable=True)
|
||||
added: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
updated: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
deprecated: Mapped[Optional[datetime]] = mapped_column(AwareDateTime(), nullable=True)
|
||||
deprecation_reason: Mapped[Optional[str]]
|
||||
destroyed: Mapped[Optional[datetime]] = mapped_column(db.DateTime(timezone=True), nullable=True)
|
||||
destroyed: Mapped[Optional[datetime]] = mapped_column(AwareDateTime(), nullable=True)
|
||||
|
||||
def __init__(self, *,
|
||||
id: Optional[int] = None,
|
||||
|
|
|
@ -7,6 +7,7 @@ from sqlalchemy.orm import Mapped, mapped_column
|
|||
from app.brm.brn import BRN
|
||||
from app.extensions import db
|
||||
from app.models import AbstractConfiguration
|
||||
from app.models.types import AwareDateTime
|
||||
|
||||
|
||||
class Activity(db.Model): # type: ignore
|
||||
|
@ -14,7 +15,7 @@ class Activity(db.Model): # type: ignore
|
|||
group_id: Mapped[Optional[int]]
|
||||
activity_type: Mapped[str]
|
||||
text: Mapped[str]
|
||||
added: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
added: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
|
||||
def __init__(self, *,
|
||||
id: Optional[int] = None,
|
||||
|
|
|
@ -6,6 +6,7 @@ from sqlalchemy.orm import Mapped, mapped_column
|
|||
|
||||
from app.extensions import db
|
||||
from app.models.activity import Activity
|
||||
from app.models.types import AwareDateTime
|
||||
|
||||
|
||||
class AlarmState(enum.Enum):
|
||||
|
@ -30,8 +31,8 @@ class Alarm(db.Model): # type: ignore
|
|||
target: Mapped[str]
|
||||
aspect: Mapped[str]
|
||||
alarm_state: Mapped[AlarmState] = mapped_column(default=AlarmState.UNKNOWN)
|
||||
state_changed: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
last_updated: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
state_changed: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
last_updated: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
text: Mapped[str]
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -7,6 +7,7 @@ from sqlalchemy.orm import Mapped, mapped_column
|
|||
from app.brm.brn import BRN
|
||||
from app.extensions import db
|
||||
from app.models import AbstractConfiguration, AbstractResource
|
||||
from app.models.types import AwareDateTime
|
||||
|
||||
|
||||
class AutomationState(enum.Enum):
|
||||
|
@ -19,8 +20,8 @@ class Automation(AbstractConfiguration):
|
|||
short_name: Mapped[str]
|
||||
state: Mapped[AutomationState] = mapped_column(default=AutomationState.IDLE)
|
||||
enabled: Mapped[bool]
|
||||
last_run: Mapped[Optional[datetime]] = mapped_column(db.DateTime(timezone=True))
|
||||
next_run: Mapped[Optional[datetime]] = mapped_column(db.DateTime(timezone=True))
|
||||
last_run: Mapped[Optional[datetime]] = mapped_column(AwareDateTime())
|
||||
next_run: Mapped[Optional[datetime]] = mapped_column(AwareDateTime())
|
||||
next_is_full: Mapped[bool]
|
||||
|
||||
logs = db.relationship("AutomationLogs", back_populates="automation")
|
||||
|
|
|
@ -8,6 +8,7 @@ from app.brm.brn import BRN
|
|||
from app.extensions import db
|
||||
from app.models import AbstractConfiguration, AbstractResource
|
||||
from app.models.base import Pool
|
||||
from app.models.types import AwareDateTime
|
||||
|
||||
|
||||
class ProviderAllocation(enum.Enum):
|
||||
|
@ -54,7 +55,7 @@ class BridgeConf(AbstractConfiguration):
|
|||
class Bridge(AbstractResource):
|
||||
conf_id: Mapped[int] = mapped_column(db.ForeignKey("bridge_conf.id"))
|
||||
cloud_account_id: Mapped[int] = mapped_column(db.ForeignKey("cloud_account.id"))
|
||||
terraform_updated: Mapped[Optional[datetime]] = mapped_column(db.DateTime(timezone=True), nullable=True)
|
||||
terraform_updated: Mapped[Optional[datetime]] = mapped_column(AwareDateTime(), nullable=True)
|
||||
nickname: Mapped[Optional[str]]
|
||||
fingerprint: Mapped[Optional[str]]
|
||||
hashed_fingerprint: Mapped[Optional[str]]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import enum
|
||||
from typing import Any, Dict, List, TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, Dict, List
|
||||
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
|
@ -8,7 +8,6 @@ from app.extensions import db
|
|||
from app.models import AbstractConfiguration
|
||||
from app.models.mirrors import StaticOrigin
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from app.models.bridges import Bridge
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ from app.extensions import db
|
|||
from app.models import AbstractConfiguration, AbstractResource, Deprecation
|
||||
from app.models.base import Group, Pool
|
||||
from app.models.onions import Onion
|
||||
from app.models.types import AwareDateTime
|
||||
|
||||
country_origin = db.Table(
|
||||
'country_origin',
|
||||
|
@ -275,7 +276,7 @@ class Proxy(AbstractResource):
|
|||
provider: Mapped[str] = mapped_column(db.String(20), nullable=False)
|
||||
psg: Mapped[Optional[int]] = mapped_column(db.Integer, nullable=True)
|
||||
slug: Mapped[Optional[str]] = mapped_column(db.String(20), nullable=True)
|
||||
terraform_updated: Mapped[Optional[datetime]] = mapped_column(db.DateTime(timezone=True), nullable=True)
|
||||
terraform_updated: Mapped[Optional[datetime]] = mapped_column(AwareDateTime(), nullable=True)
|
||||
url: Mapped[Optional[str]] = mapped_column(db.String(255), nullable=True)
|
||||
|
||||
origin: Mapped[Origin] = relationship("Origin", back_populates="proxies")
|
||||
|
|
|
@ -7,6 +7,7 @@ from app.brm.brn import BRN
|
|||
from app.extensions import db
|
||||
from app.models import AbstractConfiguration, AbstractResource
|
||||
from app.models.base import Group
|
||||
from app.models.types import AwareDateTime
|
||||
from app.util.onion import onion_hostname
|
||||
|
||||
|
||||
|
@ -36,7 +37,7 @@ class Onion(AbstractConfiguration):
|
|||
|
||||
group_id: Mapped[int] = mapped_column(db.ForeignKey("group.id"))
|
||||
domain_name: Mapped[str]
|
||||
cert_expiry: Mapped[datetime] = mapped_column(db.DateTime(timezone=True))
|
||||
cert_expiry: Mapped[datetime] = mapped_column(AwareDateTime())
|
||||
cert_sans: Mapped[str]
|
||||
onion_public_key: Mapped[bytes]
|
||||
onion_private_key: Mapped[bytes]
|
||||
|
|
21
app/models/types.py
Normal file
21
app/models/types.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from datetime import timezone
|
||||
|
||||
from sqlalchemy import DateTime, TypeDecorator
|
||||
|
||||
|
||||
class AwareDateTime(TypeDecorator):
|
||||
impl = DateTime(timezone=True)
|
||||
|
||||
cache_ok = True
|
||||
|
||||
def process_bind_param(self, value, dialect):
|
||||
# Ensure the value is aware. If it's naive, assume UTC.
|
||||
if value is not None and value.tzinfo is None:
|
||||
value = value.replace(tzinfo=timezone.utc)
|
||||
return value
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
# Ensure the value is aware. If it's naive, assume UTC.
|
||||
if value is not None and value.tzinfo is None:
|
||||
value = value.replace(tzinfo=timezone.utc)
|
||||
return value
|
|
@ -1,6 +1,7 @@
|
|||
from typing import Optional
|
||||
|
||||
from flask import render_template, Response, flash, redirect, url_for, Blueprint
|
||||
from flask import (Blueprint, Response, flash, redirect, render_template,
|
||||
url_for)
|
||||
from flask.typing import ResponseReturnValue
|
||||
|
||||
from app.extensions import db
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
from typing import List, Union, Optional, Dict, Type
|
||||
from typing import Dict, List, Optional, Type, Union
|
||||
|
||||
from flask import render_template, url_for, redirect, Blueprint
|
||||
from flask import Blueprint, redirect, render_template, url_for
|
||||
from flask.typing import ResponseReturnValue
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import SelectField, StringField, SubmitField, IntegerField, BooleanField, Form, FormField
|
||||
from wtforms import (BooleanField, Form, FormField, IntegerField, SelectField,
|
||||
StringField, SubmitField)
|
||||
from wtforms.validators import InputRequired
|
||||
|
||||
from app.extensions import db
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from flask import current_app, render_template, Blueprint, Response
|
||||
from flask import Blueprint, Response, current_app, render_template
|
||||
from flask.typing import ResponseReturnValue
|
||||
from sqlalchemy import desc
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField, SelectField
|
||||
from wtforms import SelectField, StringField, SubmitField
|
||||
|
||||
|
||||
class EditMirrorForm(FlaskForm): # type: ignore
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from typing import Optional
|
||||
|
||||
from flask import redirect, Blueprint
|
||||
from flask import Blueprint, redirect
|
||||
from flask.typing import ResponseReturnValue
|
||||
|
||||
from app.models.onions import Onion
|
||||
|
|
|
@ -2,15 +2,16 @@ import logging
|
|||
import secrets
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from flask import render_template, url_for, flash, redirect, Response, Blueprint
|
||||
import sqlalchemy
|
||||
from flask import (Blueprint, Response, flash, redirect, render_template,
|
||||
url_for)
|
||||
from flask.typing import ResponseReturnValue
|
||||
from flask_wtf import FlaskForm
|
||||
import sqlalchemy
|
||||
from wtforms import StringField, SubmitField, SelectField
|
||||
from wtforms import SelectField, StringField, SubmitField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
from app.extensions import db
|
||||
from app.models.base import Pool, Group
|
||||
from app.models.base import Group, Pool
|
||||
from app.portal.util import LifecycleForm
|
||||
|
||||
bp = Blueprint("pool", __name__)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from flask import render_template, Response, flash, redirect, url_for, Blueprint
|
||||
from flask import (Blueprint, Response, flash, redirect, render_template,
|
||||
url_for)
|
||||
from flask.typing import ResponseReturnValue
|
||||
from sqlalchemy import desc
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from flask import render_template, Blueprint
|
||||
from flask import Blueprint, render_template
|
||||
from flask.typing import ResponseReturnValue
|
||||
from sqlalchemy import desc
|
||||
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
import logging
|
||||
from typing import Optional, List, Any
|
||||
from typing import Any, List, Optional
|
||||
|
||||
import sqlalchemy.exc
|
||||
from flask import flash, redirect, url_for, render_template, Response, Blueprint, current_app
|
||||
from flask import (Blueprint, Response, current_app, flash, redirect,
|
||||
render_template, url_for)
|
||||
from flask.typing import ResponseReturnValue
|
||||
from flask_wtf import FlaskForm
|
||||
from sqlalchemy import exc
|
||||
from wtforms import StringField, SelectField, SubmitField, BooleanField, FileField
|
||||
from wtforms import (BooleanField, FileField, SelectField, StringField,
|
||||
SubmitField)
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
from app.brm.static import create_static_origin
|
||||
from app.models.base import Group
|
||||
from app.models.cloud import CloudAccount, CloudProvider
|
||||
from app.models.mirrors import StaticOrigin, Origin
|
||||
from app.models.mirrors import Origin, StaticOrigin
|
||||
from app.portal.util import response_404, view_lifecycle
|
||||
|
||||
bp = Blueprint("static", __name__)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from flask import Response, render_template, flash, redirect, url_for
|
||||
from flask import Response, flash, redirect, render_template, url_for
|
||||
from flask.typing import ResponseReturnValue
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import SubmitField
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import os
|
||||
import stat
|
||||
from typing import Tuple, Any, Optional
|
||||
from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED
|
||||
from typing import Any, Optional, Tuple
|
||||
from zipfile import ZIP_DEFLATED, ZipFile, ZipInfo
|
||||
|
||||
import jinja2
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Tuple, Optional
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import boto3
|
||||
from sqlalchemy import func
|
||||
|
@ -6,8 +6,8 @@ from sqlalchemy import func
|
|||
from app import app
|
||||
from app.alarms import get_or_create_alarm
|
||||
from app.extensions import db
|
||||
from app.models.base import Group
|
||||
from app.models.alarms import AlarmState
|
||||
from app.models.base import Group
|
||||
from app.models.onions import Eotk
|
||||
from app.terraform import BaseAutomation
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ from app import app
|
|||
from app.alarms import get_or_create_alarm
|
||||
from app.brm.brn import BRN
|
||||
from app.extensions import db
|
||||
from app.models.mirrors import Proxy
|
||||
from app.models.alarms import AlarmState
|
||||
from app.models.mirrors import Proxy
|
||||
from app.terraform import BaseAutomation
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Tuple, Optional
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import boto3
|
||||
from sqlalchemy import func
|
||||
|
@ -6,8 +6,8 @@ from sqlalchemy import func
|
|||
from app import app
|
||||
from app.alarms import get_or_create_alarm
|
||||
from app.extensions import db
|
||||
from app.models.base import Group
|
||||
from app.models.alarms import AlarmState
|
||||
from app.models.base import Group
|
||||
from app.models.mirrors import SmartProxy
|
||||
from app.terraform import BaseAutomation
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from flask import current_app
|
||||
from github import Github
|
||||
|
||||
from app.terraform.block.bridge_reachability import BlockBridgeReachabilityAutomation
|
||||
from app.terraform.block.bridge_reachability import \
|
||||
BlockBridgeReachabilityAutomation
|
||||
|
||||
|
||||
class BlockBridgeGitHubAutomation(BlockBridgeReachabilityAutomation):
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from flask import current_app
|
||||
from gitlab import Gitlab
|
||||
|
||||
from app.terraform.block.bridge_reachability import BlockBridgeReachabilityAutomation
|
||||
from app.terraform.block.bridge_reachability import \
|
||||
BlockBridgeReachabilityAutomation
|
||||
|
||||
|
||||
class BlockBridgeGitlabAutomation(BlockBridgeReachabilityAutomation):
|
||||
|
|
|
@ -2,7 +2,7 @@ import json
|
|||
import logging
|
||||
from io import BytesIO
|
||||
from typing import Any, Optional
|
||||
from zipfile import ZipFile, BadZipFile
|
||||
from zipfile import BadZipFile, ZipFile
|
||||
|
||||
import lxml # nosec: B410
|
||||
import requests
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from collections.abc import Mapping, Sequence
|
||||
import json
|
||||
import os
|
||||
from typing import List, Any
|
||||
from collections.abc import Mapping, Sequence
|
||||
from typing import Any, List
|
||||
|
||||
from app import app
|
||||
from app.lists import lists
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import datetime
|
||||
import os.path
|
||||
import sys
|
||||
from abc import abstractmethod
|
||||
import datetime
|
||||
from collections import defaultdict
|
||||
from typing import Optional, Any, List, Dict
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from flask import current_app
|
||||
from sqlalchemy import text
|
||||
|
@ -11,7 +11,7 @@ from sqlalchemy import text
|
|||
from app import app
|
||||
from app.extensions import db
|
||||
from app.models.base import Group
|
||||
from app.models.mirrors import Proxy, Origin, SmartProxy
|
||||
from app.models.mirrors import Origin, Proxy, SmartProxy
|
||||
from app.terraform.terraform import TerraformAutomation
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Optional, Any
|
||||
from typing import Any, Optional
|
||||
|
||||
from app.extensions import db
|
||||
from app.models.mirrors import Proxy
|
||||
|
|
|
@ -235,6 +235,7 @@ class ProxyMetaAutomation(BaseAutomation):
|
|||
"""
|
||||
pools = Pool.query.all()
|
||||
for pool in pools:
|
||||
logging.debug(pool.added < datetime.now(tz=timezone.utc))
|
||||
if pool.id == -1:
|
||||
continue # Skip hotspare pool
|
||||
logging.debug("Missing proxy check for %s", pool.pool_name)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
|
||||
from flask import Blueprint, request, Response
|
||||
from flask import Blueprint, Response, request
|
||||
from flask.typing import ResponseReturnValue
|
||||
|
||||
from app.extensions import db
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import base64
|
||||
import hashlib
|
||||
from typing import Tuple, Optional, List, Dict
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
|
||||
def onion_hostname(onion_public_key: bytes) -> str:
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import ssl
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional, Tuple, List, Dict, TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
|
||||
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat._oid import ExtensionOID
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa, padding
|
||||
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
||||
from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
|
||||
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
|
||||
|
||||
|
|
85
migrations/versions/cb3d6f0cdb86_switch_to_timezone_aware.py
Normal file
85
migrations/versions/cb3d6f0cdb86_switch_to_timezone_aware.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
"""switch to timezone aware
|
||||
|
||||
Revision ID: cb3d6f0cdb86
|
||||
Revises: 54b31e87fe33
|
||||
Create Date: 2024-12-06 17:34:51.630311
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'cb3d6f0cdb86'
|
||||
down_revision = '54b31e87fe33'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
def alter_column_to_timezone_aware(table_name, column_name):
|
||||
with op.batch_alter_table(table_name, schema=None) as batch_op:
|
||||
batch_op.alter_column(
|
||||
column_name,
|
||||
type_=sa.DateTime(timezone=True)
|
||||
)
|
||||
|
||||
# AbstractConfiguration derived tables
|
||||
configuration_tables = [
|
||||
"automation",
|
||||
"cloud_account",
|
||||
"bridge_conf",
|
||||
"country",
|
||||
"group",
|
||||
"mirror_list",
|
||||
"onion",
|
||||
"origin",
|
||||
"pool",
|
||||
"static_origin",
|
||||
"webhook"
|
||||
]
|
||||
for t in configuration_tables:
|
||||
alter_column_to_timezone_aware(t, 'added')
|
||||
alter_column_to_timezone_aware(t, 'updated')
|
||||
alter_column_to_timezone_aware(t, 'destroyed')
|
||||
|
||||
# AbstractResource derived tables
|
||||
resource_tables = [
|
||||
"bridge",
|
||||
"proxy",
|
||||
"smart_proxy",
|
||||
"automation_logs",
|
||||
"eotk"
|
||||
]
|
||||
for t in resource_tables:
|
||||
alter_column_to_timezone_aware(t, 'added')
|
||||
alter_column_to_timezone_aware(t, 'updated')
|
||||
alter_column_to_timezone_aware(t, 'deprecated')
|
||||
alter_column_to_timezone_aware(t, 'destroyed')
|
||||
|
||||
# Deprecation
|
||||
alter_column_to_timezone_aware("deprecation", "deprecated_at")
|
||||
|
||||
# Activity
|
||||
alter_column_to_timezone_aware("activity", "added")
|
||||
|
||||
# Alarm
|
||||
alter_column_to_timezone_aware("alarm", "state_changed")
|
||||
alter_column_to_timezone_aware("alarm", "last_updated")
|
||||
|
||||
# Bridge terraform_updated
|
||||
alter_column_to_timezone_aware("bridge", "terraform_updated")
|
||||
|
||||
# Proxy terraform_updated
|
||||
alter_column_to_timezone_aware("proxy", "terraform_updated")
|
||||
|
||||
# Automation last_run, next_run
|
||||
alter_column_to_timezone_aware("automation", "last_run")
|
||||
alter_column_to_timezone_aware("automation", "next_run")
|
||||
|
||||
# Onion cert_expiry
|
||||
alter_column_to_timezone_aware("onion", "cert_expiry")
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
Loading…
Add table
Add a link
Reference in a new issue