Skip to content

Commit

Permalink
Merge pull request #234 from adhocteam/main
Browse files Browse the repository at this point in the history
Fix migrations/Add URL routing to activity report
  • Loading branch information
rahearn authored Dec 23, 2020
2 parents 222c502 + 9f661a5 commit 87eea27
Show file tree
Hide file tree
Showing 29 changed files with 820 additions and 612 deletions.
3 changes: 2 additions & 1 deletion .cfignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
docs/
frontend/
cucumber/
deployment_config/
frontend/
src/
terraform/
16 changes: 14 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ executors:
docker-executor:
# for docker you must specify an image to use for the primary container
docker:
- image: circleci/node:12.19.0-browsers
- image: circleci/node:12.20.0-browsers
environment:
DATABASE_URL: postgresql://postgres@localhost/ttasmarthub
- image: circleci/postgres:12.4-ram
Expand All @@ -32,6 +32,10 @@ commands:
description: "Login to cloud foundry space with service account credentials
and push application using deployment configuration file."
parameters:
app_name:
description: "Name of Cloud Foundry cloud.gov application; must match
application name specified in manifest"
type: string
auth_client_id:
description: "Name of CircleCi project environment variable that
holds authentication client id, a required application variable"
Expand Down Expand Up @@ -80,6 +84,10 @@ commands:
--var AUTH_CLIENT_SECRET=${<< parameters.auth_client_secret >>} \
--var NEW_RELIC_LICENSE_KEY=${<< parameters.new_relic_license >>} \
--var SESSION_SECRET=${<< parameters.session_secret >>}
- run:
name: Run database migrations
command: |
cf run-task << parameters.app_name >> "yarn db:migrate:prod"
parameters:
cg_org:
description: "Cloud Foundry cloud.gov organization name"
Expand Down Expand Up @@ -114,7 +122,7 @@ parameters:
default: "main"
type: string
sandbox_git_branch: # change to feature branch to test deployment
default: "js-140-add-navigator"
default: "sj-cd-use-db-url"
type: string
jobs:
build:
Expand Down Expand Up @@ -291,6 +299,7 @@ jobs:
- equal: [<< pipeline.git.branch >>, << pipeline.parameters.sandbox_git_branch >>]
steps:
- cf_deploy:
app_name: tta-smarthub-sandbox
auth_client_id: SANDBOX_AUTH_CLIENT_ID
auth_client_secret: SANDBOX_AUTH_CLIENT_SECRET
cloudgov_username: CLOUDGOV_SANDBOX_USERNAME
Expand All @@ -306,6 +315,7 @@ jobs:
- equal: [<< pipeline.git.branch >>, << pipeline.parameters.dev_git_branch >>]
steps:
- cf_deploy:
app_name: tta-smarthub-dev
auth_client_id: DEV_AUTH_CLIENT_ID
auth_client_secret: DEV_AUTH_CLIENT_SECRET
cloudgov_username: CLOUDGOV_DEV_USERNAME
Expand All @@ -321,6 +331,7 @@ jobs:
- equal: [<< pipeline.git.branch >>, << pipeline.parameters.staging_git_branch >>]
steps:
- cf_deploy:
app_name: tta-smarthub-staging
auth_client_id: STAGING_AUTH_CLIENT_ID
auth_client_secret: STAGING_AUTH_CLIENT_SECRET
cloudgov_username: CLOUDGOV_STAGING_USERNAME
Expand All @@ -336,6 +347,7 @@ jobs:
- equal: [<< pipeline.git.branch >>, << pipeline.parameters.prod_git_branch >>]
steps:
- cf_deploy:
app_name: tta-smarthub-prod
auth_client_id: PROD_AUTH_CLIENT_ID
auth_client_secret: PROD_AUTH_CLIENT_SECRET
cloudgov_username: CLOUDGOV_PROD_USERNAME
Expand Down
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ CUCUMBER_USER_ID=999999;
NEW_RELIC_LICENSE_KEY=secret_key
# Set to false to require user to go through auth flow, never true in production envs
BYPASS_AUTH=true
# In production, Sequelize instance is created with a postgres URI.
# This URI is automatically dropped into the cloud.gov environment as the env variable DATABASE_URL
DATABASE_URL=secret
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12.19.0
12.20.0
8 changes: 8 additions & 0 deletions .production.sequelizerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const path = require('path');

module.exports = {
'config': path.resolve('build', 'config', 'config.js'),
'models-path': path.resolve('build', 'server', 'models'),
'seeders-path': path.resolve('build', 'server', 'seeders'),
'migrations-path': path.resolve('build', 'server', 'migrations')
}
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
FROM node:12.19.0
FROM node:12.20.0
WORKDIR /app
132 changes: 131 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,148 @@ deleting the application.

**Secret Management**

CircleCI's [project-based environment variables][env-vars] are used for secret management. These secrets include:
CircleCI's project-based "environment variables" are used for secret management. These secrets include:
- Cloud.gov deployer account username and password. These keys are specific to each cloud.gov
organization/space, i.e. each deployment environment, and can be [regenerated by developers][cloudgov-deployer]
who have proper cloud.gov permissions at any time.
- HSES authentication middleware secrets passed to the application as `AUTH_CLIENT_ID` and `AUTH_CLIENT_SECRET`.
- The application `SESSION_SECRET`.
- NewRelic license key, passed to the application as `NEW_RELIC_LICENSE_KEY`

Exception:
- The environment specific postgres database URI is automatically available in the relevant cloud.gov application environment (because they share a cloud.gov "space"). The URI is accessible to the application as POSTGRES_URL. Consequently, this secret does not need to be managed by developers.

**Adding environment variables to an application**

If you need to add a variable that is both public and _does not change_ between environments, simply add it under `env:` in **manifest.yml**. See `NODE_ENV` as an example.

If your env variable is secret or the value is dependent on the deployment environment follow these directions.

1. If secret, add your variable to CircleCI

If the variable value you want to add needs to remain secret, you will need to add it as a project-based "environment variable" in CircleCI. Ad Hoc engineers can use [this link][circleci-envvar] to navigate to the Environment Variables page for our forked repository. Add your environment variables here. If you need different values for sandbox and dev make sure to make two variables, one for each environment.

For example, if you needed to add an environment specific secret `SECRET_FRUIT` variable to your application, you could add `SANDBOX_SECRET_FRUIT` with value `strawberry` and `DEV_SECRET_FRUIT` with value `dewberry`.

1. Add both secret and public variables to manifest.yml

In the application manifest, add your `SECRET_FRUIT` variable to the `env:` object. If you need another non-secret but environment specific variable, like `PUBLIC_VEGGIE`, in your application, add that here.

**manifest.yml**

```
---
applications:
- name: tta-smarthub-((env))
env:
SECRET_FRUIT: ((SECRET_FRUIT))
PUBLIC_VEGGIE: ((public_veggie))
```

1. If public, add the variable values to your deployment_config files

**deployment_config/sandbox_vars.yml**

```
public_veggie: spinach
```

**deployment_config/dev_vars.yml**

```
public_veggie: dill
```

You're all done with public env variables! In sandbox, `process.env.PUBLIC_VEGGIE` will be `"spinach"`. In dev, `process.env.PUBLIC_VEGGIE` will be `"dill"`. 🎉

1. If secret, pass your variables to the `cf_deploy` command in the circleci config.

Make two additions here:
- Add the variable under `parameters`. Give your variable a description and a type of `env_var_name`.
- Under `steps:`, pass your new parameter to `cf push` with the `--var` flag. You can think of `cf_push` as a function, which uses the `parameters` as inputs. Make sure to retain the `${}` syntax. This forces CircleCI to interpret your `secret_fruit` parameter as a project-based environment variable, and make the correct substitution. This will become clearer in the next step.

**config/config.yml**
```
commands:
...
cf_deploy:
...
parameters:
...
secret_fruit:
description: "Name of CircleCI project environment variable that
holds the secret fruit"
type: env_var_name
steps:
...
- run:
name: Push application with deployment vars
command: |
cf push --vars-file << parameters.deploy_config_file >> \
--var SECRET_FRUIT=${<< parameters.secret_fruit >>}
```

1. If secret, in the `deploy` job, add the circle ci project environment variable name that you created in step 1 to the `cf_deploy` command as a parameter.

**config/config.yml**
```
jobs:
...
deploy:
...
when: # sandbox
...
steps:
- cf_deploy:
secret_fruit: SANDBOX_SECRET_FRUIT
when: # dev
...
steps:
- cf_deploy:
secret_fruit: DEV_SECRET_FRUIT
```

You're all done! In sandbox, `process.env.SECRET_FRUIT` will be `"strawberry"`. In dev, `process.env.SECRET_FRUIT` will be `"dewberry"`. 🎉


**Interacting with a deployed database**

Our project includes four deployed Postgres databases, one to interact with each application environment (sandbox, dev, staging, prod). For instructions on how to create and modify databases instances within the cloud.gov ecosystem see the [terraform/README.md](terraform/README.md).

You can run psql commands directly against a deployed database by following these directions.

1. Install the cloud foundry plugin [cf-service-connect][cf-service-connect]

```bash
# Example install for macOS
cf install-plugin https://github.com/18F/cf-service-connect/releases/download/1.1.0/cf-service-connect-darwin-386
```

1. Target the desired organization and space

```bash
cf target -o <org> -s <space>
# Example for sandbox
cf target -o hhs-acf-ohs-tta -s ttahub-sandbox
```

1. Connect to the desired database

```bash
cf connect-to-service <app_name> <service_instance_name>
# Example for sandbox
cf connect-to-service tta-smarthub-sandbox ttahub-sandbox
```

On success, your terminal prompt will change to match the `db_name` from the database instance credentials.
This indicates you are in an open psql session, the command-line interface to PostgreSQL.

<!-- Links -->

[adhoc-main]: https://github.com/adhocteam/Head-Start-TTADP/tree/main
[circleci-envvar]: https://app.circleci.com/settings/project/github/adhocteam/Head-Start-TTADP/environment-variables?return-to=https%3A%2F%2Fcircleci.com%2Fdashboard
[cloudgov]: https://dashboard.fr.cloud.gov/home
[cloudgov-deployer]: https://cloud.gov/docs/services/cloud-gov-service-account/
[cf-service-connect]: https://github.com/cloud-gov/cf-service-connect
[hhs-main]: https://github.com/HHS/Head-Start-TTADP/tree/main
[hhs-prod]: https://github.com/HHS/Head-Start-TTADP/tree/production
7 changes: 7 additions & 0 deletions axe-urls
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
http://localhost:3000,
http://localhost:3000/activity-reports/activity-summary,
http://localhost:3000/activity-reports/topics-resources,
http://localhost:3000/activity-reports/goals-objectives,
http://localhost:3000/activity-reports/next-steps,
http://localhost:3000/activity-reports/review,
http://localhost:3000/admin
1 change: 1 addition & 0 deletions config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module.exports = {
logging: false,
},
production: {
use_env_variable: 'DATABASE_URL',
username: process.env.POSTGRES_USERNAME,
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DB,
Expand Down
14 changes: 5 additions & 9 deletions deployment_config/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
# Deployment Configuration Variable Files

Files within this directory contain variables that are read/substituted into
the deployment manifest (manifest.yml). The deployment manifest configures
aspects of the application deployment such as the number of instances deployed
and variables that are passed to the application environment. Environment
variables that should remain secret and outside of version control are
overwritten in the manifest by a deployment command flag, `--var`, in the deploy
job (configured in .circleci/config.yml). See the treatment of `AUTH_CLIENT_SECRET`,
as an example of this variable substitution. For more information on secret
management see the Secret Management section of the main README.md.
Files within this directory contain variables that are both public and read/substituted into the deployment manifest (manifest.yml) based on the deployment environment. For an example, see the treatment of `instances` in dev_vars.yml, prod_vars.yml, and manifest.yml.

**Need to add a public env variable to the application that _does not change_ between envs?** You can add it directly under `env:` in manifest.yml. See `NODE_ENV` as an example.

**Need to add a secrete env variable to the application or a public or secret env variable that _changes_ between envs?** Check out the "Adding environment variables to an application" section in the main README.MD.

## REDIRECT_URI_HOST

Expand Down
5 changes: 0 additions & 5 deletions deployment_config/dev_vars.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
AUTH_BASE: https://uat.hsesinfo.org
AUTH_CLIENT_ID: ((AUTH_CLIENT_ID))
AUTH_CLIENT_SECRET: ((AUTH_CLIENT_SECRET))
env: dev
instances: 1
NODE_ENV: production
# This env variable should go away soon in favor of TTA_SMART_HUB_URI
REDIRECT_URI_HOST: https://tta-smarthub-dev.app.cloud.gov
rds_instance: ttahub-dev
s3_doc_upload_bucket: ttahub-document-upload-dev
SESSION_SECRET: ((SESSION_SECRET))
TTA_SMART_HUB_URI: https://tta-smarthub-dev.app.cloud.gov
2 changes: 0 additions & 2 deletions deployment_config/prod_vars.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
AUTH_BASE: https://uat.hsesinfo.org
env: prod
instances: 2
NODE_ENV: production
# This env variable should go away soon in favor of TTA_SMART_HUB_URI
REDIRECT_URI_HOST: https://tta-smarthub-prod.app.cloud.gov
rds_instance: ttahub-prod
Expand Down
2 changes: 0 additions & 2 deletions deployment_config/sandbox_vars.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
AUTH_BASE: https://uat.hsesinfo.org
env: sandbox
instances: 1
NODE_ENV: production
# This env variable should go away soon in favor of TTA_SMART_HUB_URI
REDIRECT_URI_HOST: https://tta-smarthub-sandbox.app.cloud.gov
rds_instance: ttahub-sandbox
Expand Down
2 changes: 0 additions & 2 deletions deployment_config/staging_vars.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
AUTH_BASE: https://uat.hsesinfo.org
env: staging
instances: 1
NODE_ENV: production
# This env variable should go away soon in favor of TTA_SMART_HUB_URI
REDIRECT_URI_HOST: https://tta-smarthub-staging.app.cloud.gov
rds_instance: ttahub-staging
Expand Down
1 change: 1 addition & 0 deletions docker-compose-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ services:
POSTGRES_USERNAME: postgres
POSTGRES_PASSWORD: secretpass
POSTGRES_DB: ttasmarthub
DATABASE_URL: postgres://postgres:secretpass@postgres_docker:5432/ttasmarthub
SESSION_SECRET: notasecret
volumes:
- ".:/app:rw"
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"uswds": "^2.9.0"
},
"engines": {
"node": "12.19.0"
"node": "12.20.0"
},
"scripts": {
"start": "react-scripts start",
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ function App() {
)}
/>
<Route
path="/activity-reports"
render={() => (
<ActivityReport />
path="/activity-reports/:currentPage?"
render={({ match }) => (
<ActivityReport match={match} />
)}
/>
<Route
Expand Down
Loading

0 comments on commit 87eea27

Please sign in to comment.