Skip to content

Commit

Permalink
PPR API update to poetry; GCP CI, CD set up (#2072)
Browse files Browse the repository at this point in the history
Signed-off-by: Doug Lovett <[email protected]>
  • Loading branch information
doug-lovett authored Nov 22, 2024
1 parent 1fe76ab commit d6de16d
Show file tree
Hide file tree
Showing 194 changed files with 15,491 additions and 14,089 deletions.
12 changes: 9 additions & 3 deletions mhr-api/src/mhr_api/resources/v1/admin_registrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from mhr_api.reports.v2.report_utils import ReportTypes
from mhr_api.resources import registration_utils as reg_utils
from mhr_api.resources import utils as resource_utils
from mhr_api.services.authz import get_group, is_all_staff_account, is_bcol_help, is_staff
from mhr_api.services.authz import get_group, is_all_staff_account, is_bcol_help, is_sbc_office_account, is_staff
from mhr_api.services.payment import TransactionTypes
from mhr_api.services.payment.exceptions import SBCPaymentException
from mhr_api.utils.auth import jwt
Expand Down Expand Up @@ -73,7 +73,14 @@ def post_admin_registration(mhr_number: str): # pylint: disable=too-many-return
return resource_utils.unauthorized_error_response(account_id)
# Not found throws exception.
current_reg: MhrRegistration = MhrRegistration.find_all_by_mhr_number(mhr_number, account_id, True)
if not is_all_staff_account(account_id) and doc_type == MhrDocumentTypes.CANCEL_PERMIT:
is_all_staff: bool = is_staff(jwt) or is_all_staff_account(account_id)
if (
not is_all_staff
and doc_type == MhrDocumentTypes.CANCEL_PERMIT
and is_sbc_office_account(jwt.get_token_auth_header(), account_id, jwt)
):
is_all_staff = True
if not is_all_staff and doc_type == MhrDocumentTypes.CANCEL_PERMIT:
can_edit: bool = False
if current_reg.change_registrations:
for reg in current_reg.change_registrations:
Expand All @@ -100,7 +107,6 @@ def post_admin_registration(mhr_number: str): # pylint: disable=too-many-return
# Validate request against the schema.
valid_format, errors = schema_utils.validate(request_json, "adminRegistration", "mhr")
# Additional validation not covered by the schema.
is_all_staff: bool = is_staff(jwt) or is_all_staff_account(account_id)
extra_validation_msg = resource_utils.validate_admin_registration(current_reg, request_json, is_all_staff)
if not valid_format or extra_validation_msg != "":
return resource_utils.validation_error_response(errors, reg_utils.VAL_ERROR, extra_validation_msg)
Expand Down
3 changes: 2 additions & 1 deletion mhr-api/src/mhr_api/resources/v1/registrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
is_all_staff_account,
is_bcol_help,
is_reg_staff_account,
is_sbc_office_account,
is_staff,
)
from mhr_api.services.document_storage.storage_service import DocumentTypes, GoogleStorageService
Expand Down Expand Up @@ -226,7 +227,7 @@ def get_registrations(mhr_number: str): # pylint: disable=too-many-return-state
)

if current_param and response_json.get("permitStatus", "") == MhrNoteStatusTypes.ACTIVE:
if is_all_staff_account(account_id):
if is_all_staff_account(account_id) or is_sbc_office_account(jwt.get_token_auth_header(), account_id, jwt):
response_json["changePermit"] = True
else:
response_json["changePermit"] = get_change_permit(registration, account_id)
Expand Down
97 changes: 59 additions & 38 deletions ppr-api/.env.sample
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
# third party Services
#SENTRY_DSN=
#CODECOV_TOKEN=
#LD_SDK_KEY=
DEPLOYMENT_PLATFORM=
DEPLOYMENT_ENV=
DEPLOYMENT_PROJECT=
TRACING_ENABLE=

# Registry Integration Services
PAYMENT_SVC_URL=
#AUTH_SVC_URL=
AUTH_SVC_URL=
#REPORT_SVC_URL=
REPORT_SVC_URL=

# Flask shite
FLASK_ENV=development
FLASK_APP=wsgi.py
SECRET=some md5 hash
APP_SETTINGS=dev
LD_SDK_KEY=

# SQL Alchemy
DATABASE_USERNAME=
Expand All @@ -23,20 +12,13 @@ DATABASE_NAME=
DATABASE_HOST=
DATABASE_PORT=

## TEST DB
## UNIT TEST/CI DB
DATABASE_TEST_USERNAME=
DATABASE_TEST_PASSWORD=
DATABASE_TEST_NAME=
DATABASE_TEST_HOST=localhost
DATABASE_TEST_PORT=5432

# ## NATS - STAN
NATS_SERVERS=nats://localhost:4222
NATS_CLIENT_NAME=entity.legal_api
NATS_CLUSTER_ID=test-cluster
NATS_FILER_SUBJECT=entity.filing.filer
NATS_QUEUE=entity-filer-worker

# JWT Settings
JWT_OIDC_WELL_KNOWN_CONFIG=
JWT_OIDC_ALGORITHMS=RS256
Expand All @@ -45,21 +27,60 @@ JWT_OIDC_CLIENT_SECRET=
JWT_OIDC_CACHING_ENABLED=True
JWT_OIDC_JWKS_CACHE_TIMEOUT=300

# Service Accounts
# Accounts
ACCOUNT_SVC_URL=
JWT_OIDC_TEST_ISSUER=
JWT_OIDC_TEST_WELL_KNOWN_CONFIG=
JWT_OIDC_TEST_ALGORITHMS=RS256
JWT_OIDC_TEST_AUDIENCE=
JWT_OIDC_TEST_CLIENT_SECRET=
JWT_OIDC_TEST_CACHING_ENABLED=True
JWT_OIDC_TEST_JWKS_CACHE_TIMEOUT=300
JWT_OIDC_PUBLIC_KEY_PEM=

# Integration Settings
AUTH_SVC_URL=
PAYMENT_SVC_URL=
PAYMENT_GATEWAY_APIKEY_TEST=
REPORT_SVC_URL=
REPORT_TEMPLATE_PATH="report-templates"
REPORT_API_AUDIENCE=
REPORT_VERSION="2"
GATEWAY_URL=
SUBSCRIPTION_API_KEY=

# Service account for payment refunds
ACCOUNT_SVC_CLIENT_ID=
ACCOUNT_SVC_CLIENT_SECRET=
ACCOUNT_SVC_TIMEOUT=20

# ## MVP Settings
GO_LIVE_DATE=2019-08-12
# DB Query limits on result set sizes
ACCOUNT_REGISTRATIONS_MAX_RESULTS="100"
ACCOUNT_DRAFTS_MAX_RESULTS="10"
ACCOUNT_SEARCH_MAX_RESULTS="1000"

# DEBTOR search trigram similarity quotients
SIMILARITY_QUOTIENT_BUSINESS_NAME="0.6"
SIMILARITY_QUOTIENT_FIRST_NAME="0.4"
SIMILARITY_QUOTIENT_LAST_NAME="0.29"
SIMILARITY_QUOTIENT_DEFAULT="0.5"
# Maximum length of search results for real time report generation.
MAX_SIZE_SEARCH_RT="200000"
# Number of registrations threshold for large search report format.
REPORT_SEARCH_LIGHT="700"
SEARCH_PDF_ASYNC_THRESHOLD="75"
EVENT_MAX_RETRIES="3"

# Cloud Settings
GOOGLE_DEFAULT_SA=
GCP_CS_SA_SCOPES=
GCP_CS_BUCKET_ID=
GCP_CS_BUCKET_ID_VERIFICATION=
GCP_CS_BUCKET_ID_REGISTRATION=
GCP_CS_BUCKET_ID_MAIL=
GCP_PS_PROJECT_ID=
GCP_PS_SEARCH_REPORT_TOPIC=
GCP_PS_NOTIFICATION_TOPIC=
GCP_PS_VERIFICATION_REPORT_TOPIC=
GCP_PS_REGISTRATION_REPORT_TOPIC=

# ## INTEGRATION TESTS
#RUN_AFFILIATION_TESTS=True
#TEST_NATS_DOCKER=True
#RUN_COLIN_TESTS=True
#RUN_NATS_TESTS=True
#RUN_PAYMENT_TESTS=True
#RUN_AUTHORIZATION_TESTS=True
NOT_GITHUB_CI=True
# Host name/IP of mail out service for file transfer: only in TEST and PROD.
SURFACE_MAIL_HOST=''
SURFACE_MAIL_TARGET_PATH='FIN_PPR/TEST'
88 changes: 73 additions & 15 deletions ppr-api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,34 +1,92 @@
FROM python:3.11-buster
FROM python:3.12-bullseye AS development_build

USER root

ARG VCS_REF="missing"
ARG BUILD_DATE="missing"

ENV VCS_REF=${VCS_REF}
ENV BUILD_DATE=${BUILD_DATE}
ENV PORT=8080

LABEL org.label-schema.vcs-ref=${VCS_REF} \
org.label-schema.build-date=${BUILD_DATE}

# Create working directory
RUN mkdir /opt/app-root && chmod 755 /opt/app-root
WORKDIR /opt/app-root
LABEL maintainer="thorwolpert"
LABEL vendor="BCROS"

ARG APP_ENV \
# Needed for fixing permissions of files created by Docker:
UID=1000 \
GID=1000

ENV APP_ENV=${APP_ENV} \
# python:
PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PYTHONHASHSEED=random \
PYTHONDONTWRITEBYTECODE=1 \
# pip:
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_DEFAULT_TIMEOUT=100 \
PIP_ROOT_USER_ACTION=ignore \
# poetry:
POETRY_VERSION=1.8.3 \
POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_CREATE=false \
POETRY_CACHE_DIR='/var/cache/pypoetry' \
POETRY_HOME='/usr/local'

SHELL ["/bin/bash", "-eo", "pipefail", "-c"]

RUN apt-get update && apt-get upgrade -y \
&& apt-get install --no-install-recommends -y \
bash \
brotli \
build-essential \
curl \
gettext \
git \
libpq-dev \
wait-for-it \
&& curl -sSL 'https://install.python-poetry.org' | python - \
&& poetry --version \
# Cleaning cache:
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*

WORKDIR /code

RUN groupadd -g "${GID}" -r web \
&& useradd -d '/code' -g web -l -r -u "${UID}" web \
&& chown web:web -R '/code'

# Install the requirements
COPY ./requirements.txt .
# Copy only requirements, to cache them in docker layer
COPY --chown=web:web ./poetry.lock ./pyproject.toml /code/

RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
COPY --chown=web:web ./src /code/src
COPY --chown=web:web ./README.md /code

COPY . .
# Project initialization:
RUN --mount=type=cache,target="$POETRY_CACHE_DIR" \
echo "$APP_ENV" \
&& poetry version \
# Install deps:
&& poetry run pip install -U pip \
&& poetry install \
$(if [ -z ${APP_ENV+x} ] | [ "$APP_ENV" = 'production' ]; then echo '--only main'; fi) \
--no-interaction --no-ansi

RUN pip install .
# Running as non-root user:
USER web

USER 1001
# The following stage is only for production:
FROM development_build AS production_build
COPY --chown=web:web . /code

# Run the server
ENV PYTHONPATH=/opt/app-root/src
# ENV PYTHONPATH=/opt/app-root/src

EXPOSE 8080
# CMD gunicorn --bind 0.0.0.0:${PORT} --config /code/gunicorn_config.py wsgi:app

CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--config", "/opt/app-root/gunicorn_config.py", "wsgi:application"]
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 wsgi:app
Loading

0 comments on commit d6de16d

Please sign in to comment.