-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Changes for CRON and Email Queue Table added (#136)
* Changes for CRON (#131) * fixed CI errors
- Loading branch information
1 parent
588c816
commit a517709
Showing
47 changed files
with
1,911 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
--- | ||
kind: Template | ||
apiVersion: template.openshift.io/v1 | ||
metadata: | ||
annotations: | ||
description: Build template for the Submit Cron job runner. | ||
tags: flask | ||
iconClass: icon-python | ||
name: "${NAME}-build-template" | ||
objects: | ||
- kind: ImageStream | ||
apiVersion: image.openshift.io/v1 | ||
metadata: | ||
name: "${NAME}" | ||
- kind: BuildConfig | ||
apiVersion: build.openshift.io/v1 | ||
metadata: | ||
name: "${NAME}" | ||
labels: | ||
app: "${NAME}" | ||
app-group: "${APP_GROUP}" | ||
template: "${NAME}-build" | ||
spec: | ||
source: | ||
type: Git | ||
git: | ||
uri: "${GIT_REPO_URL}" | ||
ref: "${GIT_REF}" | ||
contextDir: "${SOURCE_CONTEXT_DIR}" | ||
strategy: | ||
type: Docker | ||
dockerStrategy: | ||
dockerfilePath: "${DOCKER_FILE_PATH}" | ||
output: | ||
to: | ||
kind: ImageStreamTag | ||
name: "${NAME}:${OUTPUT_IMAGE_TAG}" | ||
triggers: | ||
- type: ConfigChange | ||
parameters: | ||
- name: NAME | ||
displayName: Name | ||
description: | ||
The name assigned to all of the objects defined in this template. You | ||
should keep this as default unless you know what you're doing. | ||
required: true | ||
value: submit-cron | ||
- name: APP_GROUP | ||
displayName: App Group | ||
description: The name assigned to all of the deployments in this project. | ||
required: true | ||
value: submit-app | ||
- name: GIT_REPO_URL | ||
displayName: Git Repo URL | ||
description: | ||
The URL to your GIT repo, don't use the this default unless you're just | ||
experimenting. | ||
required: true | ||
value: https://github.com/bcgov/EPIC.submit.git | ||
- name: GIT_REF | ||
displayName: Git Reference | ||
description: The git reference or branch. | ||
required: true | ||
value: cron | ||
- name: SOURCE_CONTEXT_DIR | ||
displayName: Source Context Directory | ||
description: The source context directory. | ||
required: true | ||
value: submit-cron | ||
- name: SOURCE_IMAGE_KIND | ||
displayName: Source Image Kind | ||
required: true | ||
description: | ||
The 'kind' (type) of the source image; typically ImageStreamTag, or | ||
DockerImage. | ||
value: ImageStreamTag | ||
- name: SOURCE_IMAGE_NAME_SPACE | ||
displayName: Source Image Name Space | ||
required: true | ||
description: The name space of the source image. | ||
value: c8b80a-tools | ||
- name: SOURCE_IMAGE_NAME | ||
displayName: Source Image Name | ||
required: true | ||
description: The name of the source image. | ||
value: python | ||
- name: OUTPUT_IMAGE_TAG | ||
displayName: Output Image Tag | ||
description: The tag given to the built image. | ||
required: true | ||
value: latest | ||
- name: DOCKER_FILE_PATH | ||
displayName: Docker File Path | ||
description: The path to the docker file defining the build. | ||
required: false | ||
value: Dockerfile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
apiVersion: template.openshift.io/v1 | ||
kind: Template | ||
metadata: | ||
name: cron-deploy-template | ||
annotations: | ||
description: "Deployment Configuration Template for the Submit Cron job Project" | ||
tags: "submit, cron, python" | ||
objects: | ||
- kind: DeploymentConfig | ||
apiVersion: apps.openshift.io/v1 | ||
metadata: | ||
name: ${NAME} | ||
labels: | ||
app: ${NAME} | ||
app-group: submit-app | ||
template: ${NAME}-deploy | ||
spec: | ||
strategy: | ||
type: Rolling | ||
rollingParams: | ||
updatePeriodSeconds: 1 | ||
intervalSeconds: 1 | ||
timeoutSeconds: 600 | ||
maxUnavailable: 25% | ||
maxSurge: 25% | ||
pre: | ||
execNewPod: | ||
command: | ||
- /submit-cron/pre-hook-update-db.sh | ||
containerName: ${NAME} | ||
failurePolicy: Abort | ||
triggers: | ||
- type: ImageChange | ||
imageChangeParams: | ||
automatic: true | ||
containerNames: | ||
- ${NAME} | ||
from: | ||
kind: ImageStreamTag | ||
namespace: ${IMAGE_NAMESPACE} | ||
name: ${NAME}:${IMAGE_TAG} | ||
- type: ConfigChange | ||
replicas: 1 | ||
test: false | ||
selector: | ||
app: ${NAME} | ||
deploymentconfig: ${NAME} | ||
template: | ||
metadata: | ||
labels: | ||
app: ${NAME} | ||
app-group: submit-app | ||
environment: ${ENV} | ||
deploymentconfig: ${NAME} | ||
template: ${NAME}-deploy | ||
spec: | ||
volumes: | ||
- name: cron-config | ||
configMap: | ||
name: ${NAME}-config | ||
defaultMode: 420 | ||
containers: | ||
- name: ${NAME} | ||
image: image-registry.openshift-image-registry.svc:5000/${IMAGE_NAMESPACE}/${NAME}:${IMAGE_TAG} | ||
ports: | ||
- containerPort: 8080 | ||
protocol: TCP | ||
volumeMounts: | ||
- name: cron-config | ||
readOnly: true | ||
mountPath: /submit-cron/cron/ | ||
env: | ||
- name: DATABASE_USERNAME | ||
valueFrom: | ||
secretKeyRef: | ||
key: app-db-username | ||
name: submit-patroni | ||
- name: DATABASE_PASSWORD | ||
valueFrom: | ||
secretKeyRef: | ||
name: submit-patroni | ||
key: app-db-password | ||
- name: DATABASE_NAME | ||
valueFrom: | ||
secretKeyRef: | ||
name: ${DATABASE_HOST} | ||
key: app-db-username | ||
- name: DATABASE_HOST | ||
value: ${DATABASE_HOST} | ||
- name: DATABASE_PORT | ||
value: ${DATABASE_PORT} | ||
resources: | ||
requests: | ||
cpu: ${CPU_REQUEST} | ||
memory: ${MEMORY_REQUEST} | ||
limits: | ||
cpu: ${CPU_LIMIT} | ||
memory: ${MEMORY_LIMIT} | ||
terminationMessagePath: "/dev/termination-log" | ||
terminationMessagePolicy: File | ||
imagePullPolicy: Always | ||
restartPolicy: Always | ||
terminationGracePeriodSeconds: 30 | ||
dnsPolicy: ClusterFirst | ||
securityContext: {} | ||
schedulerName: default-scheduler | ||
- kind: Service | ||
apiVersion: v1 | ||
metadata: | ||
name: ${NAME} | ||
creationTimestamp: | ||
labels: | ||
app: ${NAME} | ||
app-group: submit-app | ||
template: ${NAME}-deploy | ||
spec: | ||
ports: | ||
- name: 8080-tcp | ||
protocol: TCP | ||
port: 8080 | ||
targetPort: 8080 | ||
selector: | ||
deploymentconfig: ${NAME} | ||
type: ClusterIP | ||
sessionAffinity: None | ||
status: | ||
loadBalancer: {} | ||
- apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
labels: | ||
app: ${NAME} | ||
app-group: submit-app | ||
name: ${NAME} | ||
data: | ||
parameters: | ||
- name: NAME | ||
description: "The name assigned to all of the OpenShift resources associated to the server instance." | ||
required: true | ||
value: submit-cron | ||
- name: IMAGE_NAMESPACE | ||
required: true | ||
description: "The namespace of the OpenShift project containing the imagestream for the application." | ||
value: c8b80a-tools | ||
- name: ENV | ||
description: "The TAG name for this environment, e.g.(dev, test, prod)." | ||
required: true | ||
value: dev | ||
- name: DATABASE_HOST | ||
description: "The analytics postgresql application name." | ||
required: true | ||
value: submit-patroni | ||
- name: DATABASE_PORT | ||
description: "The analytics postgresql application port." | ||
required: true | ||
value: '5432' | ||
- name: CPU_REQUEST | ||
description: "The resources CPU request (in cores) for this build." | ||
required: true | ||
value: 100m | ||
- name: CPU_LIMIT | ||
description: "The resources CPU limit (in cores) for this build." | ||
required: true | ||
value: 750m | ||
- name: MEMORY_REQUEST | ||
description: "The resources Memory request (in Mi, Gi, etc) for this build." | ||
required: true | ||
value: 100Mi | ||
- name: MEMORY_LIMIT | ||
description: "The resources Memory limit (in Mi, Gi, etc) for this build." | ||
required: true | ||
value: 2Gi | ||
- name: REPLICAS | ||
description: "The number of replicas to run in this environment." | ||
required: true | ||
value: '1' | ||
- name: IMAGE_TAG | ||
description: "The image tag to deploy" | ||
value: latest |
42 changes: 42 additions & 0 deletions
42
submit-api/migrations/versions/5bf7b1f9a81c_email_queue_added.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
"""Email queue added | ||
Revision ID: 5bf7b1f9a81c | ||
Revises: e1e1b81ad5c8 | ||
Create Date: 2024-10-30 07:23:40.214720 | ||
""" | ||
from alembic import op | ||
import sqlalchemy as sa | ||
|
||
|
||
# revision identifiers, used by Alembic. | ||
revision = '5bf7b1f9a81c' | ||
down_revision = '075df7d4f03b' | ||
branch_labels = None | ||
depends_on = None | ||
|
||
|
||
def upgrade(): | ||
# ### commands auto generated by Alembic - please adjust! ### | ||
op.create_table('email_queue', | ||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), | ||
sa.Column('entity_id', sa.Integer(), nullable=False), | ||
sa.Column('entity_type', sa.String(length=50), nullable=False), | ||
sa.Column('template_name', sa.String(length=50), nullable=False), | ||
sa.Column('status', sa.String(length=50), nullable=False), | ||
sa.Column('created_at', sa.DateTime(), nullable=False), | ||
sa.Column('sent_at', sa.DateTime(), nullable=True), | ||
sa.Column('error_message', sa.String(length=500), nullable=True), | ||
sa.Column('created_date', sa.DateTime(), nullable=False), | ||
sa.Column('updated_date', sa.DateTime(), nullable=True), | ||
sa.Column('created_by', sa.String(length=50), nullable=True), | ||
sa.Column('updated_by', sa.String(length=50), nullable=True), | ||
sa.PrimaryKeyConstraint('id') | ||
) | ||
|
||
# ### end Alembic commands ### | ||
|
||
|
||
def downgrade(): | ||
op.drop_table('email_queue') | ||
# ### end Alembic commands ### |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Email queue model.""" | ||
from __future__ import annotations | ||
|
||
from datetime import datetime | ||
from typing import List | ||
|
||
from sqlalchemy import Column, DateTime | ||
|
||
from .base_model import BaseModel | ||
from .db import db | ||
|
||
|
||
class EmailQueue(BaseModel): | ||
"""Model class for email queue.""" | ||
|
||
__tablename__ = 'email_queue' | ||
|
||
id = Column(db.Integer, primary_key=True, autoincrement=True) | ||
entity_id = Column(db.Integer, nullable=False) | ||
entity_type = Column(db.String(50), nullable=False) | ||
template_name = Column(db.String(100), nullable=False) | ||
# Status can be one of: 'PENDING', 'SENT', 'FAILED' | ||
status = Column(db.String(50), nullable=False, default='PENDING') | ||
created_at = Column(DateTime, nullable=False, default=datetime.utcnow) | ||
sent_at = Column(DateTime, nullable=True) | ||
error_message = Column(db.String(500), nullable=True) | ||
|
||
@classmethod | ||
def find_pending(cls): | ||
"""Find all pending emails in the queue. | ||
Returns: | ||
list[EmailQueue]: List of pending email queue entries | ||
""" | ||
return cls.query.filter_by(status='PENDING').all() | ||
|
||
@classmethod | ||
def find_all(cls) -> List[EmailQueue]: | ||
"""Find all entries in the email queue. | ||
Returns: | ||
list[EmailQueue]: List of all email queue entries. | ||
""" | ||
return cls.query.all() |
Oops, something went wrong.