Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EASI-4671: Refactor configuration to build frontend for k8s as static content #2911

Merged
merged 15 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
8 changes: 8 additions & 0 deletions .github/workflows/deploy_to_eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.GIT_REF_NAME }}-easi-frontend
cache-from: type=gha,scope=${{ env.GIT_REF_NAME }}-easi-frontend
tags: ${{ steps.login-ecr.outputs.registry }}/easi-frontend:${{ env.GIT_HASH }}
# TODO: Pull these from .envrc instead of hard-coding
build-args: |
VITE_LD_CLIENT_ID=63231d448bd05a111f06195b
VITE_OKTA_CLIENT_ID=0oa2e913coDQeG19S297
VITE_OKTA_SERVER_ID=aus2e96etlbFPnBHt297
VITE_OKTA_ISSUER=https://test.idp.idm.cms.gov/oauth2/aus2e96etlbFPnBHt297
VITE_OKTA_DOMAIN=https://test.idp.idm.cms.gov
VITE_OKTA_REDIRECT_URI=http://localhost:3000/implicit/callback
- name: Announce failure
if: ${{ failure() }}
run: |
Expand Down
37 changes: 0 additions & 37 deletions Dockerfile.backend_k8s

This file was deleted.

36 changes: 35 additions & 1 deletion Dockerfile.frontend_k8s
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,38 @@ COPY tsconfig.json .eslintrc vite.config.ts apollo.config.js index.html ./
COPY public ./public
COPY src ./src

ENTRYPOINT [ "yarn", "start" ]
# Pass in from outside (.envrc)
ARG VITE_LD_CLIENT_ID
ARG VITE_OKTA_CLIENT_ID
ARG VITE_OKTA_SERVER_ID
ARG VITE_OKTA_ISSUER
ARG VITE_OKTA_DOMAIN
ARG VITE_OKTA_REDIRECT_URI

# Difficult (depend on k8s instantiation of ingress)
# ARG VITE_API_ADDRESS
# ARG VITE_GRAPHQL_ADDRESS

ENV VITE_OKTA_CLIENT_ID=${VITE_OKTA_CLIENT_ID} \
VITE_OKTA_SERVER_ID=${VITE_OKTA_SERVER_ID} \
VITE_LD_CLIENT_ID=${VITE_LD_CLIENT_ID} \
VITE_APP_ENV=local \
VITE_OKTA_ISSUER=${VITE_OKTA_ISSUER} \
# VITE_API_ADDRESS=${VITE_API_ADDRESS} \
# VITE_GRAPHQL_ADDRESS=${VITE_GRAPHQL_ADDRESS} \
VITE_LOCAL_AUTH_ENABLED=true \
VITE_OKTA_DOMAIN=${VITE_OKTA_DOMAIN} \
VITE_OKTA_REDIRECT_URI=${VITE_OKTA_REDIRECT_URI}

RUN yarn build

#
# Final layer to export just built HTML
#
FROM nginx:1.27.1-alpine

# Copy built files from yarn build layer
COPY --from=build /app/build /usr/share/nginx/html

# https://github.com/nginxinc/docker-nginx/blob/04d0c5754673d6880b91e94c3cebaa767d9a1af7/Dockerfile
ENTRYPOINT ["nginx", "-g", "daemon off;"]
2 changes: 1 addition & 1 deletion deploy/base/easi/easi-backend_deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ spec:
protocol: TCP
resources: {}
command:
- ./bin/easi
- /easi/easi
- serve
restartPolicy: Always
20 changes: 0 additions & 20 deletions deploy/base/easi/easi-frontend_configmap.yaml

This file was deleted.

5 changes: 1 addition & 4 deletions deploy/base/easi/easi-frontend_deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ spec:
- name: easi-frontend
image: easi-frontend:latest
imagePullPolicy: Never
envFrom:
- configMapRef:
name: easi-frontend-configmap
ports:
- containerPort: 3000
- containerPort: 80
protocol: TCP
resources: {}
restartPolicy: Always
4 changes: 2 additions & 2 deletions deploy/base/easi/easi-frontend_service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
name: easi-frontend
spec:
ports:
- port: 3000
targetPort: 3000
- port: 80
targetPort: 80
selector:
app: easi-frontend
1 change: 0 additions & 1 deletion deploy/base/easi/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ resources:
- easi-backend_configmap.yaml
- easi-backend_deployment.yaml
- easi-backend_service.yaml
- easi-frontend_configmap.yaml
- easi-frontend_deployment.yaml
- easi-frontend_service.yaml
- email_deployment.yaml
Expand Down
2 changes: 1 addition & 1 deletion deploy/base/ingress/easi_ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ spec:
service:
name: easi-frontend
port:
number: 3000
number: 80
- path: /api
pathType: Prefix
backend:
Expand Down
4 changes: 0 additions & 4 deletions deploy/overlays/pr/easi/easi-backend_deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
path: /spec/template/spec/containers/0/imagePullPolicy
value: Always

- op: replace
path: /spec/template/spec/containers/0/command
value: ["/easi/easi", "serve"]

- op: replace
path: /spec/template/spec/containers/0/resources
value:
Expand Down
9 changes: 0 additions & 9 deletions deploy/overlays/pr/easi/easi-frontend_configmap.yaml

This file was deleted.

3 changes: 0 additions & 3 deletions deploy/overlays/pr/easi/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ patches:
- path: easi-backend_configmap.yaml
target:
name: easi-backend-configmap
- path: easi-frontend_configmap.yaml
target:
name: easi-frontend-configmap

# Patches for deployment changes
- path: easi-backend_deployment.yaml
Expand Down
2 changes: 1 addition & 1 deletion deploy/overlays/pr/ingress/easi_ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
service:
name: easi-frontend
port:
number: 3000
number: 80
- path: /api
pathType: Prefix
backend:
Expand Down
32 changes: 20 additions & 12 deletions scripts/k8s_dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,30 @@ if kubectl get ns "$NAMESPACE" > /dev/null 2>&1; then
}
fi

APPLICATION_VERSION="$(git rev-parse @)"
APPLICATION_DATETIME="$(date --rfc-3339='seconds' --utc)"
APPLICATION_TS="$(date --date="$APPLICATION_DATETIME" '+%s')"

export APPLICATION_VERSION
export APPLICATION_DATETIME
export APPLICATION_TS

# Build Docker images
(
echo "🐋 Building easi-frontend:${NAMESPACE} image 🐋"
docker build -f ../Dockerfile.frontend_k8s -t easi-frontend:"$NAMESPACE" ../.

# APPLICATION_VERSION=$(git rev-parse HEAD)
# APPLICATION_DATETIME="$(date --rfc-3339='seconds' --utc)"
# APPLICATION_TS="$(date --date="$APPLICATION_DATETIME" '+%s')"
# echo "APPLICATION_DATETIME=${APPLICATION_DATETIME}"
# echo "APPLICATION_TS=${APPLICATION_TS}"
# echo "APPLICATION_VERSION=${APPLICATION_VERSION}"
docker build -f ../Dockerfile.frontend_k8s -t easi-frontend:"$NAMESPACE" ../. \
--build-arg VITE_LD_CLIENT_ID=63231d448bd05a111f06195b \
--build-arg VITE_OKTA_CLIENT_ID=0oa2e913coDQeG19S297 \
--build-arg VITE_OKTA_SERVER_ID=aus2e96etlbFPnBHt297 \
--build-arg VITE_OKTA_ISSUER=https://test.idp.idm.cms.gov/oauth2/aus2e96etlbFPnBHt297 \
--build-arg VITE_OKTA_DOMAIN=https://test.idp.idm.cms.gov \
--build-arg VITE_OKTA_REDIRECT_URI=http://localhost:3000/implicit/callback

echo "🐋 Building easi-backend:${NAMESPACE} image 🐋"
# docker build -f ../Dockerfile --build-arg APPLICATION_DATETIME="${APPLICATION_DATETIME}" --build-arg APPLICATION_TS="${APPLICATION_TS}" --build-arg APPLICATION_VERSION="${APPLICATION_VERSION}" -t easi-backend:latest ../.
docker build -f ../Dockerfile.backend_k8s --target build -t easi-backend:"$NAMESPACE" ../.
docker build -f ../Dockerfile -t easi-backend:"$NAMESPACE" ../. \
--build-arg APPLICATION_DATETIME="${APPLICATION_DATETIME}" \
--build-arg APPLICATION_TS="${APPLICATION_TS}" \
--build-arg APPLICATION_VERSION="${APPLICATION_VERSION}"

echo "🐋 Building db-migrate:${NAMESPACE} image 🐋"
docker build -f ../Dockerfile.db_migrations --build-arg TAG=9.10-alpine -t db-migrate:"$NAMESPACE" ../.
Expand Down Expand Up @@ -134,7 +143,6 @@ delete_temp_dir() {
kustomize edit set namespace "$NAMESPACE"
kustomize build > manifest.yaml

sed -i'' -E "s/easi-backend.localdev.me/${NAMESPACE}-backend.localdev.me/" manifest.yaml
sed -i'' -E "s/easi.localdev.me/${NAMESPACE}.localdev.me/" manifest.yaml
sed -i'' -E "s/email.localdev.me/${NAMESPACE}-email.localdev.me/" manifest.yaml
sed -i'' -E "s/minio.localdev.me/${NAMESPACE}-minio.localdev.me/" manifest.yaml
Expand All @@ -143,7 +151,7 @@ delete_temp_dir() {
)

(
TEMPDIR=$(mktemp -d ../tmp.ingress.XXXXX)
TEMPDIR=$(mktemp -d ../tmp.easi.XXXXX)
cd "$TEMPDIR" || exit
kustomize create --resources ../deploy/base/easi
kustomize edit set namespace "$NAMESPACE"
Expand Down
16 changes: 13 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { detect } from 'detect-browser';
import { TextEncoder } from 'text-encoding';

import { localAuthStorageKey } from 'constants/localAuth';
import getWindowAddress from 'utils/host';

import './i18n';

Expand All @@ -20,7 +21,8 @@ import store from './store';

import './index.scss';

const apiHost = new URL(import.meta.env.VITE_API_ADDRESS || '').host;
const apiHost = new URL(import.meta.env.VITE_API_ADDRESS || getWindowAddress())
.host;

// Initialize tracker for Google Analytics
ReactGA.initialize([
Expand Down Expand Up @@ -61,12 +63,20 @@ function getAuthHeader(targetUrl: string) {
/**
* Setup client for GraphQL
*/

// Pull the graphql address from the vite environment variables
// However, if we don't have a VITE_GRAPHQL_ADDRESS, we should simply assume that the API is hosted on the same domain & port as the frontend
// We also assume a path of /api/graph/query should be tacked onto that
const graphqlAddress =
import.meta.env.VITE_GRAPHQL_ADDRESS ||
`${getWindowAddress()}/api/graph/query`;

const uploadLink = createUploadLink({
uri: import.meta.env.VITE_GRAPHQL_ADDRESS
uri: graphqlAddress
});

const authLink = setContext((request, { headers }) => {
const header = getAuthHeader(import.meta.env.VITE_GRAPHQL_ADDRESS as string);
const header = getAuthHeader(graphqlAddress);
return {
headers: {
...headers,
Expand Down
11 changes: 8 additions & 3 deletions src/sagas/actionSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ import { call, put, StrictEffect, takeLatest } from 'redux-saga/effects';

import { Action } from 'types/action';
import { postAction } from 'types/routines';
import getWindowAddress from 'utils/host';

// Pull the API address from the vite environment variables
// However, if we don't have a VITE_API_ADDRESS, we should simply assume that the API is hosted on the same domain & port as the frontend
// We also assume a path of /api/v1 should be tacked onto that
const apiAddress =
import.meta.env.VITE_API_ADDRESS || `${getWindowAddress()}/api/v1`;

export function postSystemIntakeActionRequest(formData: Action) {
return axios.post(
`${import.meta.env.VITE_API_ADDRESS}/system_intake/${
formData.intakeId
}/actions`,
`${apiAddress}/system_intake/${formData.intakeId}/actions`,
formData
);
}
Expand Down
16 changes: 10 additions & 6 deletions src/sagas/businessCaseSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ import {
postBusinessCase,
putBusinessCase
} from 'types/routines';
import getWindowAddress from 'utils/host';

// Pull the API address from the vite environment variables
// However, if we don't have a VITE_API_ADDRESS, we should simply assume that the API is hosted on the same domain & port as the frontend
// We also assume a path of /api/v1 should be tacked onto that
const apiAddress =
import.meta.env.VITE_API_ADDRESS || `${getWindowAddress()}/api/v1`;

function getBusinessCaseRequest(id: string) {
return axios.get(`${import.meta.env.VITE_API_ADDRESS}/business_case/${id}`);
return axios.get(`${apiAddress}/business_case/${id}`);
}

function* getBusinessCase(
Expand All @@ -30,7 +37,7 @@ function* getBusinessCase(

function postBusinessCaseRequest(formData: BusinessCaseModel) {
const data = prepareBusinessCaseForApi(formData);
return axios.post(`${import.meta.env.VITE_API_ADDRESS}/business_case`, data);
return axios.post(`${apiAddress}/business_case`, data);
}

function* createBusinessCase(
Expand All @@ -49,10 +56,7 @@ function* createBusinessCase(

function putBusinessCaseRequest(formData: BusinessCaseModel) {
const data = prepareBusinessCaseForApi(formData);
return axios.put(
`${import.meta.env.VITE_API_ADDRESS}/business_case/${data.id}`,
data
);
return axios.put(`${apiAddress}/business_case/${data.id}`, data);
}

function* updateBusinessCase(
Expand Down
5 changes: 5 additions & 0 deletions src/utils/host.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Returns the current browsers address in the format of ${PROTOCOL}//${HOST}
// i.e. https://dev.easi.cms.gov
export default function getWindowAddress(): string {
return `${window.location.protocol}//${window.location.host}`;
ClayBenson94 marked this conversation as resolved.
Show resolved Hide resolved
}
Loading