Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Accept an arbitrary path to /migrations in config #613

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ The types of changes are:
* Subject Request Details page [#563](https://github.com/ethyca/fidesops/pull/563)
* Restart Graph from Failure [#578](https://github.com/ethyca/fidesops/pull/578)

### Changed
* Specify an arbitrary path to database migrations with the `FIDESOPS__PACKAGE__MIGRATION_PATH` ENV variable, rather than a path to the package source [#613](https://github.com/ethyca/fidesops/pull/613)


## [1.5.2](https://github.com/ethyca/fidesops/compare/1.5.1...1.5.2)

Expand Down
2 changes: 1 addition & 1 deletion fidesops.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PORT=8080
PORT = 8080

[database]
SERVER = "db"
Expand Down
47 changes: 23 additions & 24 deletions src/fidesops/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import hashlib
import logging
import os
from os import curdir, getenv, pardir, path
from typing import Any, Dict, List, MutableMapping, Optional, Tuple, Union

import bcrypt
Expand Down Expand Up @@ -98,23 +98,22 @@ class Config:
class PackageSettings(FidesSettings):
"""Configuration settings for the fidesops package itself."""

PATH: Optional[str] = None
MIGRATION_PATH: Optional[str] = None

@validator("PATH", pre=True)
def ensure_valid_package_path(cls, v: Optional[str]) -> str:
@validator("MIGRATION_PATH", pre=True)
def ensure_valid_migration_path(cls, v: Optional[str]) -> str:
"""
Ensure a valid path to the fidesops src/ directory is provided.
Ensure a valid path to the fidesops `migrations/` directory is provided.

This is required to enable fidesops-plus to start successfully.
"""

if isinstance(v, str) and os.path.isdir(v):
return (
v if os.path.basename(v) == "fidesops" else os.path.join(v, "fidesops/")
)

current_dir = os.path.dirname(os.path.abspath(__file__))
return os.path.normpath(os.path.join(current_dir, "../../"))
current_dir = path.dirname(path.abspath(__file__))
return (
path.normpath(v + "/migrations")
if isinstance(v, str) and path.isdir(v)
else path.normpath(path.join(current_dir, "../../migrations"))
)

class Config:
env_prefix = "FIDESOPS__PACKAGE__"
Expand Down Expand Up @@ -258,18 +257,18 @@ class FidesopsConfig(FidesSettings):
root_user: RootUserSettings

PORT: int
is_test_mode: bool = os.getenv("TESTING") == "True"
hot_reloading: bool = os.getenv("FIDESOPS__HOT_RELOAD") == "True"
dev_mode: bool = os.getenv("FIDESOPS__DEV_MODE") == "True"
is_test_mode: bool = getenv("TESTING") == "True"
hot_reloading: bool = getenv("FIDESOPS__HOT_RELOAD") == "True"
dev_mode: bool = getenv("FIDESOPS__DEV_MODE") == "True"

class Config: # pylint: disable=C0115
case_sensitive = True

logger.warning(
logger.debug(
f"Startup configuration: reloading = {hot_reloading}, dev_mode = {dev_mode}"
)
logger.warning(
f'Startup configuration: pii logging = {os.getenv("FIDESOPS__LOG_PII") == "True"}'
logger.debug(
f'Startup configuration: pii logging = {getenv("FIDESOPS__LOG_PII") == "True"}'
)

def log_all_config_values(self) -> None:
Expand All @@ -296,17 +295,17 @@ def load_file(file_name: str) -> str:
raises FileNotFound if none is found
"""
possible_directories = [
os.getenv("FIDESOPS__CONFIG_PATH"),
os.curdir,
os.pardir,
os.path.expanduser("~"),
getenv("FIDESOPS__CONFIG_PATH"),
curdir,
pardir,
path.expanduser("~"),
]

directories: List[str] = [d for d in possible_directories if d]

for dir_str in directories:
possible_location = os.path.join(dir_str, file_name)
if possible_location and os.path.isfile(possible_location):
possible_location = path.join(dir_str, file_name)
if possible_location and path.isfile(possible_location):
logger.info("Loading file %s from %s", NotPii(file_name), NotPii(dir_str))
return possible_location
logger.debug("%s not found at %s", NotPii(file_name), NotPii(dir_str))
Expand Down
12 changes: 5 additions & 7 deletions src/fidesops/db/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@

def get_alembic_config(
database_url: str,
package_source_dir: str = config.package.PATH,
migrations_dir: str = config.package.MIGRATION_PATH,
) -> Config:
"""
Do lots of magic to make alembic work programmatically.
"""

migrations_dir = os.path.join(package_source_dir, "migrations/")
current_dir = os.path.dirname(os.path.abspath(__file__))
package_source_dir = os.path.normpath(os.path.join(current_dir, "../../"))
alembic_config = Config(os.path.join(package_source_dir, "alembic.ini"))
alembic_config.set_main_option("script_location", migrations_dir.replace("%", "%%"))
alembic_config.set_main_option("sqlalchemy.url", database_url)
Expand All @@ -35,14 +36,11 @@ def upgrade_db(alembic_config: Config, revision: str = "head") -> None:
command.upgrade(alembic_config, revision)


def init_db(
database_url: PostgresDsn,
package_source_dir: str = config.package.PATH,
) -> None:
def init_db(database_url: PostgresDsn) -> None:
"""
Runs the migrations and creates all of the database objects.
"""
alembic_config = get_alembic_config(database_url, package_source_dir)
alembic_config = get_alembic_config(database_url)
upgrade_db(alembic_config)


Expand Down
2 changes: 1 addition & 1 deletion src/fidesops/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def start_webserver() -> None:

if config.database.ENABLED:
logger.info("Running any pending DB migrations...")
init_db(config.database.SQLALCHEMY_DATABASE_URI, config.package.PATH)
init_db(config.database.SQLALCHEMY_DATABASE_URI)

scheduler.start()

Expand Down