Skip to content

Commit

Permalink
Merge pull request #1105 from nasa/develop
Browse files Browse the repository at this point in the history
Develop to main Release 12.0.1
  • Loading branch information
npauzenga authored Jul 13, 2023
2 parents 539e3a2 + 2f9f15c commit ee76f8e
Show file tree
Hide file tree
Showing 23 changed files with 12,961 additions and 11,159 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14.19.1
16.19.0
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [v12.0.1] - 2023-05-25
### Breaking Changes

This version of the dashboard requires Cumulus API v2 (Core version >= v16.0.0)

### Changed

- **CUMULUS-3092**
- Updated all PUT /granules/${granuleId} actions to use PATCH and supply the
required `Cumulus-API-Version` headers implemented in CUMULUS-3072
- Removed unused `reprocessGranule` action method
- **CUMULUS-3299**
- Docs: Update and fix links that reference the docs after Docusaurus upgrade

## [v12.0.0] - 2023-01-23

## Breaking Changes
Expand Down Expand Up @@ -1313,7 +1327,8 @@ Fix for serving the dashboard through the Cumulus API.
### Added

- Versioning and changelog [CUMULUS-197] by @kkelly51
[Unreleased]: https://github.com/nasa/cumulus-dashboard/compare/v12.0.0...HEAD
[Unreleased]: https://github.com/nasa/cumulus-dashboard/compare/v12.0.1...HEAD
[v12.0.1]: https://github.com/nasa/cumulus-dashboard/compare/v12.0.0...v12.0.1
[v12.0.0]: https://github.com/nasa/cumulus-dashboard/compare/v11.0.0...v12.0.0
[v11.0.0]: https://github.com/nasa/cumulus-dashboard/compare/v10.0.0...v11.0.0
[v10.0.0]: https://github.com/nasa/cumulus-dashboard/compare/v9.0.0...v10.0.0
Expand Down
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ Set the environment and build the dashboard with these commands:
$ source production.env && ./bin/build_dashboard_via_docker.sh
```

This script uses Docker Compose to build and copy the compiled dashboard into the `./dist` directory. You can now deploy this directory to AWS behind [CloudFront](https://aws.amazon.com/cloudfront/). If you are in NGAP, follow the instructions for "Request Public or Protected Access to the APIs and Dashboard" on the earthdata wiki page [Using Cumulus with Private APIs](https://wiki.earthdata.nasa.gov/display/CUMULUS/Cumulus+Deployments+in+NGAP).
This script uses Docker Compose to build and copy the compiled dashboard into the `./dist` directory. You can now deploy this directory to AWS behind [CloudFront](https://aws.amazon.com/cloudfront/). If you are in NGAP, follow the instructions for "Request Public or Protected Access to the APIs and Dashboard" on the earthdata wiki page [Using Cumulus with Private APIs](https://wiki.earthdata.nasa.gov/display/CUMULUS/Using+Cumulus+with+Private+APIs).


### Run the dashboard locally via Docker Image

You can also create a Docker container that will serve the dashboard behind a simple nginx configuration. Having a runnable Docker image is useful for testing a build before deployment or for NGAP Sandbox environments, where if you configure your computer to [access Cumulus APIs via SSM](https://wiki.earthdata.nasa.gov/display/CUMULUS/Accessing+Cumulus+APIs+via+SSM), you can run the dashboard container locally against the live Sandbox Cumulus API.
You can also create a Docker container that will serve the dashboard behind a simple nginx configuration. Having a runnable Docker image is useful for testing a build before deployment or for NGAP Sandbox environments, where if you configure your computer to [access Cumulus APIs via SSM](https://wiki.earthdata.nasa.gov/display/CUMULUS/Accessing+Cumulus+APIs+via+SSM+Port+Forwarding), you can run the dashboard container locally against the live Sandbox Cumulus API.

The script `./bin/build_dashboard_image.sh` will build a docker image containing the dashboard bundle served behind a basic [nginx](https://www.nginx.com/) configuration. The script takes one optional parameter, the tag to name the generated image which defaults to cumulus-dashboard:latest. The same customizations as described in the [previous section](#build-the-dashboard-using-docker-and-docker-compose) are available to configure your dashboard.

Expand All @@ -96,10 +96,10 @@ In this example, the dashboard would be available at `http://localhost:3000/` in

### Build the dashboard

The dashboard uses node v14.19.1. To build/run the dashboard on your local machine, install [nvm](https://github.com/creationix/nvm) and run `nvm install v14.19.1`.
The dashboard uses node v16.19.0. To build/run the dashboard on your local machine, install [nvm](https://github.com/creationix/nvm) and run `nvm install v16.19.0`.

#### install requirements
We use npm for local package management, run `npm install -g [email protected]` to install npm 8.6.0. To install the requirements:
We use npm for local package management. To install the requirements:
```bash
$ nvm use
$ npm ci
Expand Down Expand Up @@ -149,7 +149,7 @@ During development you can run the webpack development webserver to serve the da
```bash
APIROOT=http://<myapi>.com npm run serve
```
The dashboard should be available at http://localhost:3000
The dashboard should be available at `http://localhost:3000`

### Run a built dashboard

Expand Down Expand Up @@ -222,7 +222,7 @@ For **development** and **testing** purposes only, you can run a Cumulus API loc

*Important Note: These `docker-compose` commands do not build distributable containers, but are a provided as testing conveniences. The docker-compose[-\*].yml files show that they work by linking your local directories into the container.*

In order to run the Cumulus API locally you must first [build the dashboard](#buildlocally) and then run the containers that provide LocalStack and Elasticsearch services.
In order to run the Cumulus API locally you must first [build the dashboard](#build-the-dashboard) and then run the containers that provide LocalStack and Elasticsearch services.

These are started and stopped with the commands:
```bash
Expand Down Expand Up @@ -264,7 +264,7 @@ and
```bash
localstack_1 | Ready.
```
you should be able to verify access to the local Cumulus API at http://localhost:5001/token
you should be able to verify access to the local Cumulus API at `http://localhost:5001/token`


Then you can run the dashboard locally (without Docker) `[HIDE_PDR=false APIROOT=http://localhost:5001] npm run serve` and open cypress tests `npm run cypress`.
Expand All @@ -290,7 +290,7 @@ dashboard_1 | Hit CTRL-C to stop the server
```


##### Troubleshooting Docker containers.
#### Troubleshooting Docker Containers

If something is not running correctly, or you're just interested, you can view the logs with a helper script, this will print out logs from each of the running docker containers.
```bash
Expand All @@ -305,7 +305,7 @@ ERROR: for localapi_shim_1 Cannot start service shim: driver failed programming
ERROR: for shim Cannot start service shim: driver failed programming external connectivity on endpoint localapi_shim_1 (7105603a4ff7fbb6f92211086f617bfab45d78cff47232793d152a244eb16feb): Bind for 0.0.0.0:9200 failed: port is already allocated
```

#### Fully contained cypress testing.
#### Fully Contained Cypress Testing

You can run all of the cypress tests locally that Earthdata Bamboo runs with a single command:
```bash
Expand All @@ -314,7 +314,7 @@ You can run all of the cypress tests locally that Earthdata Bamboo runs with a s
This stands up the entire stack as well as begins the e2e service that will run all cypress commands and report an exit code for their success or failure. This is primarily used for CI, but can be useful to developers.


#### <a name=dockerdiagram></a> Docker Container Service Diagram.
#### <a name=dockerdiagram></a> Docker Container Service Diagram
![Docker Service Diagram](./ancillary/DashboardDockerServices.png)


Expand Down Expand Up @@ -395,8 +395,4 @@ It is likely that no branch plan will exist for the `master` branch.
- Choose Branch Name `master` and then click `create`.
- Verify that the build has started for this plan.





<a name="bundlefootnote">1</a>: A dashboard bundle is just a ready-to-deploy compiled version of the dashboard and environment.
5 changes: 3 additions & 2 deletions app/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import './public/favicon.ico';

import App from './js/App';

if (process.env.NODE_ENV !== 'production') {
// Broken - needs resolution in CUMULUS-3379
/* if (process.env.NODE_ENV !== 'production') {
import('@axe-core/react')
.then((axe) => {
axe.default(React, ReactDOM, 1000);
});
}
} */

ReactDOM.render(<App />, document.getElementById('site-canvas'));
27 changes: 12 additions & 15 deletions app/src/js/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,6 @@ export const listGranules = (options) => (dispatch, getState) => {
});
};

export const reprocessGranule = (granuleId) => ({
[CALL_API]: {
type: types.GRANULE_REPROCESS,
method: 'PUT',
id: granuleId,
path: `granules/${granuleId}`,
data: {
action: 'reprocess'
}
}
});

export const applyWorkflowToCollection = (name, version, workflow) => ({
[CALL_API]: {
type: types.COLLECTION_APPLYWORKFLOW,
Expand Down Expand Up @@ -252,13 +240,16 @@ export const applyRecoveryWorkflowToCollection = (collectionId) => (dispatch) =>
export const applyWorkflowToGranule = (granuleId, workflow, meta) => ({
[CALL_API]: {
type: types.GRANULE_APPLYWORKFLOW,
method: 'PUT',
method: 'PATCH',
id: granuleId,
path: `granules/${granuleId}`,
data: {
action: 'applyWorkflow',
workflow,
meta
},
headers: {
'Cumulus-API-Version': '2',
}
}
});
Expand Down Expand Up @@ -293,12 +284,15 @@ export const applyRecoveryWorkflowToGranule = (granuleId) => (dispatch) => dispa
export const reingestGranule = (granuleId, meta) => ({
[CALL_API]: {
type: types.GRANULE_REINGEST,
method: 'PUT',
method: 'PATCH',
id: granuleId,
path: `granules/${granuleId}`,
data: {
action: 'reingest',
...meta,
},
headers: {
'Cumulus-API-Version': '2',
}
}
});
Expand All @@ -311,11 +305,14 @@ export const reingestGranuleClearError = (granuleId) => ({
export const removeGranule = (granuleId) => ({
[CALL_API]: {
type: types.GRANULE_REMOVE,
method: 'PUT',
method: 'PATCH',
id: granuleId,
path: `granules/${granuleId}`,
data: {
action: 'removeFromCmr'
},
headers: {
'Cumulus-API-Version': '2',
}
}
});
Expand Down
22 changes: 12 additions & 10 deletions app/src/js/components/Granules/bulk.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,35 @@ const getRequestAsyncOpId = (request) => get(request, ['data', 'id']);
const isStatusInflight = (status) => status === 'inflight';
const isStatusSuccess = (status) => status === 'success';

const granulesOrQueryDescription = 'add either an array of granule objects in the form:\n { "granuleId": "(value)", "collectionId": "(value)" } or an elasticsearch query and index.';
const granulesOrQueryText = `In the box below, ${granulesOrQueryDescription}`;

const bulkOperationsDefaultQuery = {
workflowName: '',
index: '',
query: '',
ids: [],
granules: '',
meta: {}
};

const bulkDeleteDefaultQuery = {
index: '',
query: '',
ids: [],
granules: [],
forceRemoveFromCmr: false
};

const bulkReingestDefaultQuery = {
index: '',
query: '',
ids: []
granules: []
};

const bulkRecoveryDefaultQuery = {
workflowName: '',
index: '',
query: '',
ids: []
granules: []
};

const BulkGranule = ({
Expand Down Expand Up @@ -268,7 +271,7 @@ const BulkGranule = ({
<h4 className="modal_subtitle">To run and complete your bulk granule task:</h4>
<ol>
<li>In the box below, enter the <strong>workflowName</strong>.</li>
<li>Then add either an array of granule Ids or an elasticsearch query and index.</li>
<li>Then {granulesOrQueryText}</li>
</ol>
</BulkGranuleModal>
<BulkGranuleModal
Expand All @@ -293,7 +296,7 @@ const BulkGranule = ({
>
<h4 className="modal_subtitle">To run and complete your bulk delete task:</h4>
<ol>
<li>In the box below, add either an array of granule Ids or an elasticsearch query and index.</li>
<li>{granulesOrQueryText}</li>
<li>Set <strong>forceRemoveFromCmr</strong> to <strong>true</strong> to automatically have granules
removed from CMR as part of deletion.
If <strong>forceRemoveFromCmr</strong> is <strong>false</strong>, then the bulk granule deletion will
Expand Down Expand Up @@ -325,7 +328,7 @@ const BulkGranule = ({
>
<h4 className="modal_subtitle">To run and complete your bulk reingest task:</h4>
<ol>
<li>In the box below, add either an array of granule Ids or an elasticsearch query and index.</li>
<li>{granulesOrQueryText}.</li>
<li>Then select workflow to rerun for all the selected granules. The workflows listed are the
intersection of the selected granules' workflows.</li>
</ol>
Expand Down Expand Up @@ -353,9 +356,8 @@ const BulkGranule = ({
>
<h4 className="modal_subtitle">To run and complete your bulk granule task:</h4>
<ol>
<li>In the box below, enter the workflowName.</li>
<li>Then add either an array of granule Ids or an Elasticsearch query and
index (<i>see below</i>).</li>
<li>In the box below, enter the <strong>workflowName</strong>.</li>
<li>Then {granulesOrQueryText} (<i>see below</i>).</li>
</ol>
</BulkGranuleModal>
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/js/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const deploymentConfig = require('./config');
const baseConfig = {
environment: 'development',
requireEarthdataLogin: false,
minCompatibleApiVersion: 'v14.0.0',
minCompatibleApiVersion: 'v16.0.0',
oauthMethod: 'earthdata',

graphicsPath: '/src/assets/images/',
Expand Down
2 changes: 1 addition & 1 deletion app/src/js/utils/table-config/granules.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const tableColumns = [
Header: 'Published',
accessor: 'published',
Cell: ({ row: { original: { cmrLink, published } } }) => (// eslint-disable-line react/prop-types
cmrLink ? <a href={cmrLink} target='_blank'>{bool(published)}</a> : bool(published)
cmrLink && bool(published) ? <a href={cmrLink} target='_blank'>{bool(published)}</a> : bool(published)
)
},
{
Expand Down
7 changes: 7 additions & 0 deletions app/src/js/utils/table-config/reconciliation-reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,13 +292,16 @@ export const tableColumnsBackup = ({ reportType, reportName }) => ([
]);

const fileLink = (bucket, key) => `https://${bucket}.s3.amazonaws.com/${key}`;
// * es-lint disable react/prop-types */
export const tableColumnsGranuleConflictDetails = ({ reportType }) => {
const checkButton = <button className='button button__row button__row--check'/>;
const orcaBackupColumns = [
{
Header: 'In Orca Only',
id: 'onlyInOrca',
accessor: 'reason',
// TODO: Updated ES lint rules caused a changeset-unrelated violation - this should be fixed
// eslint-disable-next-line react/prop-types
Cell: ({ cell: { value } }) => (
(value === 'onlyInOrca') ? checkButton : nullValue
),
Expand All @@ -308,6 +311,8 @@ export const tableColumnsGranuleConflictDetails = ({ reportType }) => {
Header: 'Should Be Excluded From Orca',
id: 'shouldBeExcludedFromOrca',
accessor: 'reason',
// TODO: Updated ES lint rules caused a changeset-unrelated violation - this should be fixed
// eslint-disable-next-line react/prop-types
Cell: ({ cell: { value } }) => (
(value === 'shouldBeExcludedFromOrca') ? checkButton : nullValue
),
Expand Down Expand Up @@ -335,6 +340,8 @@ export const tableColumnsGranuleConflictDetails = ({ reportType }) => {
Header: 'In Cumulus Only',
id: 'onlyInCumulus',
accessor: 'reason',
// TODO: Updated ES lint rules caused a changeset-unrelated violation - this should be fixed
// eslint-disable-next-line react/prop-types
Cell: ({ cell: { value } }) => (
(value === 'onlyInCumulus') ? checkButton : nullValue
),
Expand Down
2 changes: 1 addition & 1 deletion audit-ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"high": true,
"pass-enoaudit": true,
"retry-count": 20,
"allowlist": ["d3-color", "knex", "json5", "jsonwebtoken"]
"allowlist": ["fast-xml-parser", "d3-color", "json5"]
}
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = {
[
'@babel/preset-env', {
targets: {
node: '14.19.1',
node: '16.19.0',
esmodules: true
}
}
Expand Down
5 changes: 5 additions & 0 deletions cypress/fixtures/seeds/granulesFixture.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"pdrName": "MOD09GQ_1granule_v3.PDR",
"execution": "https://console.aws.amazon.com/states/home?region=us-east-1#/executions/details/arn:aws:states:us-east-1:123456789012:execution:TestSourceIntegrationIngestGranuleStateMachine-MOyI0myKEXzf:c33e4091-e90d-449c-93f5-c4462b6e4e87",
"published": false,
"cmrLink": null,
"error": {
"Cause": "\"None\"",
"Error": "Unknown Error"
Expand Down Expand Up @@ -174,6 +175,7 @@
"pdrName": "MOD09GQ_1granule_v3.PDR",
"execution": "https://console.aws.amazon.com/states/home?region=us-east-1#/executions/details/arn:aws:states:us-east-1:123456789012:execution:TestSourceIntegrationParsePdrStateMachine-JVlCKfoXElDQ:9888b858-d70c-42ec-a887-c9367dcfd7cf",
"published": false,
"cmrLink": null,
"error": {
"Cause": "\"None\"",
"Error": "Unknown Error"
Expand Down Expand Up @@ -255,6 +257,7 @@
"granuleId": "MOD09GQ.A2417309.YZ9tCV.006.4640974889044",
"execution": "https://console.aws.amazon.com/states/home?region=us-east-1#/executions/details/arn:aws:states:us-east-1:123456789012:execution:TestSourceIntegrationIngestGranuleStateMachine-MOyI0myKEXzf:c33e4091-e90d-449c-93f5-c4462b6e4e87",
"published": false,
"cmrLink": null,
"error": {
"Cause": "{\"errorMessage\":\"verifyFile s3://cumulus-test-sandbox-internal/non-existent-path/non-existent-file failed: Actual file size 2MB did not match expected file size 3MB\",\"errorType\":\"UnexpectedFileSize\",\"stackTrace\":[\"S3Granule.sync (/var/task/index.js:147549:13)\",\"<anonymous>\",\"process._tickDomainCallback (internal/process/next_tick.js:228:7)\"]}",
"Error": "UnexpectedFileSize"
Expand Down Expand Up @@ -414,6 +417,7 @@
"granuleId": "MOD09GQ.A9344328.K9yI3O.006.4625818663028",
"execution": "https://console.aws.amazon.com/states/home?region=us-east-1#/executions/details/arn:aws:states:us-east-1:123456789012:execution:TestSourceIntegrationIngestAndPublishGranuleStateMachine-yCAhWOss5Xgo:b313e777-d28a-435b-a0dd-f1fad08116t1",
"published": false,
"cmrLink": null,
"error": {
"Cause": "{\"errorMessage\":\"Source file not found s3://cumulus-test-sandbox-internal/non-existent-path/non-existent-file\",\"errorType\":\"FileNotFound\",\"stackTrace\":[\"S3Granule.sync (/var/task/index.js:147549:13)\",\"<anonymous>\",\"process._tickDomainCallback (internal/process/next_tick.js:228:7)\"]}",
"Error": "FileNotFound"
Expand Down Expand Up @@ -462,6 +466,7 @@
"productVolume": "2488",
"provider": "s3_provider",
"published": false,
"cmrLink": null,
"status": "completed",
"timestamp": 1576106371369,
"timeToArchive": 0.01,
Expand Down
Loading

0 comments on commit ee76f8e

Please sign in to comment.