├── api-client-py
├── Makefile
├── .gitignore
├── requirements.txt
├── cumulus_api
│ ├── __init__.py
│ └── cumulus_api.py
├── setup.py
└── LICENSE
├── examples
├── node
│ ├── logs.js
│ ├── pdrs.js
│ ├── rules.js
│ ├── stats.js
│ ├── executions.js
│ ├── providers.js
│ ├── resources.js
│ ├── schemas.js
│ ├── workflows.js
│ ├── README.md
│ ├── auth.js
│ ├── granules.js
│ ├── collections.js
│ ├── distribution.js
│ └── execution-status.js
├── python
│ ├── logs.py
│ ├── pdrs.py
│ ├── granules.py
│ ├── providers.py
│ ├── resources.py
│ ├── schemas.py
│ ├── stats.py
│ ├── collections.py
│ ├── README.md
│ ├── collections.pyc
│ └── auth.py
├── curl
│ ├── distribution.sh
│ ├── README.md
│ ├── logs.sh
│ ├── pdrs.sh
│ ├── rules.sh
│ ├── granules.sh
│ ├── workflows.sh
│ ├── executions.sh
│ ├── providers.sh
│ ├── collections.sh
│ ├── schemas.sh
│ ├── reconciliation-reports.sh
│ ├── execution-status.sh
│ ├── stats.sh
│ └── auth.sh
└── README.md
├── website
├── v11.0.0
│ ├── bundle.js
│ ├── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
│ └── favicon.ico
├── v13.0.0
│ ├── bundle.js
│ ├── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
│ └── favicon.ico
├── v13.3.0
│ ├── bundle.js
│ ├── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
│ └── favicon.ico
├── v13.4.0
│ ├── bundle.js
│ ├── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
│ └── favicon.ico
├── favicon.ico
├── v14.0.0
│ ├── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
│ └── favicon.ico
├── v14.1.0
│ ├── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
│ └── favicon.ico
├── v16.1.1
│ └── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
├── v18.1.0
│ └── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
├── v18.4.0
│ └── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
├── v18.5.3
│ └── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
├── v20.0.0
│ └── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
├── v20.1.2
│ ├── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
│ └── build
│ │ └── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
├── v21.0.0
│ ├── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
│ └── build
│ │ └── css
│ │ ├── icon.eot
│ │ ├── icon.woff
│ │ ├── railscasts.css
│ │ └── style.css
├── img
│ ├── ic_cumulus_logo_blue.svg
│ └── ic_cumulus_logo_white.svg
└── input.css
├── .prettierignore
├── .eslintignore
├── prettier.config.js
├── postcss.config.js
├── .gitignore
├── api-client-js
├── endpoints
│ ├── distribution.js
│ ├── logs.js
│ ├── schemas.js
│ ├── execution-status.js
│ ├── workflows.js
│ ├── executions.js
│ ├── pdrs.js
│ ├── granules.js
│ ├── stats.js
│ ├── reconciliation-reports.js
│ ├── rules.js
│ ├── providers.js
│ └── collections.js
├── tests
│ ├── README.md
│ └── index.js
├── package.json
└── index.js
├── content
├── version.md
├── orca.md
├── instance-meta.md
├── dashboard.md
├── granule-csv.md
├── replays-sqs-messages.md
├── replays.md
├── async-operations.md
├── dead-letter-archive.md
├── stats.md
├── pdrs.md
├── schemas.md
├── intro.md
├── auth.md
├── workflows.md
├── providers.md
├── rules.md
└── logs.md
├── template
├── defaults
│ └── index.html
└── src
│ ├── custom
│ ├── index.js
│ └── content.js
│ └── components
│ └── app.js
├── tailwind.config.js
├── README.md
├── .circleci
└── config.yml
├── package.json
├── bin
└── docs
├── release.md
├── CONTRIBUTING.md
└── LICENSE
/api-client-py/Makefile:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/logs.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/pdrs.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/rules.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/stats.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/python/logs.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/python/pdrs.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/executions.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/providers.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/resources.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/schemas.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/node/workflows.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/python/granules.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/python/providers.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/python/resources.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/python/schemas.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/python/stats.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/python/collections.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/website/v11.0.0/bundle.js:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/website/v13.0.0/bundle.js:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/website/v13.3.0/bundle.js:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/website/v13.4.0/bundle.js:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/curl/distribution.sh:
--------------------------------------------------------------------------------
1 | # TODO
--------------------------------------------------------------------------------
/examples/curl/README.md:
--------------------------------------------------------------------------------
1 | # Curl examples
2 |
--------------------------------------------------------------------------------
/api-client-py/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.pyc
3 |
--------------------------------------------------------------------------------
/examples/node/README.md:
--------------------------------------------------------------------------------
1 | # Node.js examples
2 |
--------------------------------------------------------------------------------
/examples/python/README.md:
--------------------------------------------------------------------------------
1 | # Python examples
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Ignore artifacts:
2 | build
3 | coverage
--------------------------------------------------------------------------------
/api-client-py/requirements.txt:
--------------------------------------------------------------------------------
1 | future
2 | requests==2.32.5
3 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | /build
3 | /dist
4 | test
5 | tmp
6 | public
7 |
--------------------------------------------------------------------------------
/website/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/favicon.ico
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [require("prettier-plugin-tailwindcss")],
3 | };
4 |
--------------------------------------------------------------------------------
/website/v11.0.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v11.0.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v11.0.0/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v11.0.0/favicon.ico
--------------------------------------------------------------------------------
/website/v13.0.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.0.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v13.0.0/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.0.0/favicon.ico
--------------------------------------------------------------------------------
/website/v13.3.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.3.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v13.3.0/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.3.0/favicon.ico
--------------------------------------------------------------------------------
/website/v13.4.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.4.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v13.4.0/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.4.0/favicon.ico
--------------------------------------------------------------------------------
/website/v14.0.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v14.0.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v14.0.0/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v14.0.0/favicon.ico
--------------------------------------------------------------------------------
/website/v14.1.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v14.1.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v14.1.0/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v14.1.0/favicon.ico
--------------------------------------------------------------------------------
/website/v16.1.1/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v16.1.1/css/icon.eot
--------------------------------------------------------------------------------
/website/v18.1.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v18.1.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v18.4.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v18.4.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v18.5.3/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v18.5.3/css/icon.eot
--------------------------------------------------------------------------------
/website/v20.0.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v20.0.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v20.1.2/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v20.1.2/css/icon.eot
--------------------------------------------------------------------------------
/website/v21.0.0/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v21.0.0/css/icon.eot
--------------------------------------------------------------------------------
/website/v11.0.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v11.0.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v13.0.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.0.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v13.3.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.3.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v13.4.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v13.4.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v14.0.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v14.0.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v14.1.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v14.1.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v16.1.1/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v16.1.1/css/icon.woff
--------------------------------------------------------------------------------
/website/v18.1.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v18.1.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v18.4.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v18.4.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v18.5.3/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v18.5.3/css/icon.woff
--------------------------------------------------------------------------------
/website/v20.0.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v20.0.0/css/icon.woff
--------------------------------------------------------------------------------
/website/v20.1.2/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v20.1.2/css/icon.woff
--------------------------------------------------------------------------------
/website/v21.0.0/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v21.0.0/css/icon.woff
--------------------------------------------------------------------------------
/examples/python/collections.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/examples/python/collections.pyc
--------------------------------------------------------------------------------
/website/v20.1.2/build/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v20.1.2/build/css/icon.eot
--------------------------------------------------------------------------------
/website/v20.1.2/build/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v20.1.2/build/css/icon.woff
--------------------------------------------------------------------------------
/website/v21.0.0/build/css/icon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v21.0.0/build/css/icon.eot
--------------------------------------------------------------------------------
/website/v21.0.0/build/css/icon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nasa/cumulus-api/HEAD/website/v21.0.0/build/css/icon.woff
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | }
6 | }
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Cumulus API Examples
2 |
3 | - [curl](./curl/README.md)
4 | - [node](./node/README.md)
5 | - [python](./python/README.md)
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .tmp
3 | npm-debug.log
4 | .DS_Store
5 | .swo
6 | package-lock.json
7 | .idea/
8 | website/unreleased/
9 | website/output.css
--------------------------------------------------------------------------------
/api-client-py/cumulus_api/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # coding: utf8
3 |
4 | from __future__ import absolute_import
5 | from .cumulus_api import CumulusApi
6 |
--------------------------------------------------------------------------------
/examples/curl/logs.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 |
6 | # Get logs
7 | URL="$CUMULUS_BASEURL/logs"
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/curl/pdrs.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/pdrs"
6 |
7 | # Get list of pdrs
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/curl/rules.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/rules"
6 |
7 | # Get list of rules
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/curl/granules.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/granules"
6 |
7 | # Get list of granules
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/curl/workflows.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/workflows"
6 |
7 | # Get list of workflows
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/curl/executions.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/executions"
6 |
7 | # Get list of executions
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/curl/providers.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/providers"
6 |
7 | # Get list of providers
8 | curl -i $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/curl/collections.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/collections"
6 |
7 | # Get list of collections
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/curl/schemas.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | SCHEMA="" # TODO
6 | URL="$CUMULUS_BASEURL/schemas/$SCHEMA"
7 |
8 | # Get list of schemas
9 | curl $URL \
10 | -H "Authorization: Bearer ${TOKEN}"
11 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/distribution.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = class Pdrs {
3 | constructor (client) {
4 | this.client = client
5 | }
6 |
7 | get (granuleId, options, callback) {
8 | return this.client._req('get', granuleId, options, callback)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/curl/reconciliation-reports.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/reconciliationReports"
6 |
7 | # Get list of reconciliation reports
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/logs.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Logs {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'logs'
7 | }
8 |
9 | list (options, callback) {
10 | return this.client._req('get', this.endpoint, options, callback)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/schemas.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Schemas {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'schemas'
7 | }
8 |
9 | get (name, options, callback) {
10 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/examples/node/auth.js:
--------------------------------------------------------------------------------
1 | var Cumulus = require('../../api-client-js')
2 |
3 | var api = new Cumulus({
4 | baseUrl: process.env.CUMULUS_BASEURL
5 | })
6 |
7 | var options = {
8 | username: process.env.EARTHDATA_USERNAME,
9 | password: process.env.EARTHDATA_PASSWORD
10 | }
11 |
12 | api.login(options, function (err, token) {
13 | console.log('token', token)
14 | })
15 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/execution-status.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class ExecutionStatus {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'executions/status'
7 | }
8 |
9 | get (name, options, callback) {
10 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/examples/curl/execution-status.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | EXECUTION_ARN="arn:aws:states:us-east-1:ACCOUNT:execution:LpdaacCumulusDiscoverPdrsStateMachine-TOSDNMC55QUA:7b242f9bab4628d49bc9f8d3a"
6 | URL="$CUMULUS_BASEURL/executions/status/$EXECUTION_ARN"
7 |
8 | curl $URL \
9 | -H "Authorization: Bearer ${TOKEN}"
10 |
--------------------------------------------------------------------------------
/examples/node/granules.js:
--------------------------------------------------------------------------------
1 | var Cumulus = require('../../api-client-js')
2 |
3 | var api = new Cumulus({
4 | baseUrl: process.env.CUMULUS_BASEURL
5 | })
6 |
7 | var options = {
8 | username: process.env.EARTHDATA_USERNAME,
9 | password: process.env.EARTHDATA_PASSWORD
10 | }
11 |
12 | api.login(options, function (err, token) {
13 | api.granules.list(function (err, response) {
14 |
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/api-client-py/setup.py:
--------------------------------------------------------------------------------
1 | from distutils.core import setup
2 |
3 | setup(
4 | name='cumulus_api',
5 | version='1.0.0',
6 | url='https://github.com/nasa/cumulus_api.py',
7 | author='',
8 | author_email='',
9 | description='',
10 | license='Apache-2.0',
11 | packages=[''],
12 | install_requires=['future', 'requests'],
13 | tests_require=['pytest'],
14 | classifiers=[]
15 | )
16 |
--------------------------------------------------------------------------------
/examples/node/collections.js:
--------------------------------------------------------------------------------
1 | var Cumulus = require('../../api-client-js')
2 |
3 | var api = new Cumulus({
4 | baseUrl: process.env.CUMULUS_BASEURL
5 | })
6 |
7 | var options = {
8 | username: process.env.EARTHDATA_USERNAME,
9 | password: process.env.EARTHDATA_PASSWORD
10 | }
11 |
12 | api.login(options, function (err, token) {
13 | api.collections.list(function (err, response) {
14 | console.log(response)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/examples/node/distribution.js:
--------------------------------------------------------------------------------
1 | var Cumulus = require('../../api-client-js')
2 |
3 | var api = new Cumulus({
4 | baseUrl: process.env.CUMULUS_BASEURL
5 | })
6 |
7 | var options = {
8 | username: process.env.EARTHDATA_USERNAME,
9 | password: process.env.EARTHDATA_PASSWORD
10 | }
11 |
12 | api.login(options, function (err, token) {
13 | api.distribution.get(function (err, response) {
14 | console.log(response)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/workflows.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Workflows {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'workflows'
7 | }
8 |
9 | get (name, options, callback) {
10 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
11 | }
12 |
13 | list (options, callback) {
14 | return this.client._req('get', this.endpoint, options, callback)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/executions.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Executions {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'executions'
7 | }
8 |
9 | get (name, options, callback) {
10 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
11 | }
12 |
13 | list (options, callback) {
14 | return this.client._req('get', this.endpoint, options, callback)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/python/auth.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 |
4 | sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../api-client-py')
5 |
6 | from cumulus_api import CumulusApi
7 |
8 | CUMULUS_BASEURL = os.environ["CUMULUS_BASEURL"]
9 | EARTHDATA_USERNAME = os.environ["EARTHDATA_USERNAME"]
10 | EARTHDATA_PASSWORD = os.environ["EARTHDATA_PASSWORD"]
11 |
12 | api = CumulusApi(CUMULUS_BASEURL)
13 |
14 | token = api.login(EARTHDATA_USERNAME, EARTHDATA_PASSWORD)
15 | print token
16 |
--------------------------------------------------------------------------------
/api-client-js/tests/README.md:
--------------------------------------------------------------------------------
1 | # Tests
2 |
3 | Tests are run using [tape](https://npmjs.com/tape).
4 |
5 | Linting is performed using [standard](https://npmjs.com/standard)
6 |
7 | ## Running tests
8 |
9 | ```sh
10 | git clone {this repo}
11 | cd {this repo}
12 | npm install
13 | npm test
14 | ```
15 |
16 | `npm test` runs both the linter and the tests.
17 |
18 | ### Just run the linter
19 |
20 | ```sh
21 | npm run lint
22 | ```
23 |
24 | ### Only run the tests
25 |
26 | ```sh
27 | npm run test:no-lint
28 | ```
29 |
--------------------------------------------------------------------------------
/api-client-js/tests/index.js:
--------------------------------------------------------------------------------
1 | var test = require('tape')
2 |
3 | var CumulusApiClient = require('../index')
4 |
5 | var api = new CumulusApiClient({
6 | baseUrl: process.env.CUMULUS_BASEURL
7 | })
8 |
9 | test('login', function (t) {
10 | var options = {
11 | username: process.env.EARTHDATA_USERNAME,
12 | password: process.env.EARTHDATA_PASSWORD
13 | }
14 |
15 | api.login(options, function (err, token) {
16 | t.notOk(err)
17 | t.ok(token && typeof token === 'string')
18 | t.end()
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/content/version.md:
--------------------------------------------------------------------------------
1 | ## Versioning
2 |
3 | The Cumulus API is versioned and the current version is v2. Retrieve the latest API version from Cumulus.
4 |
5 | ```endpoint
6 | GET /version
7 | ```
8 |
9 | To use any version, include the version number in the path before the query endpoint. `{API_URL}/{version}/{query}`
10 |
11 | #### Example Request
12 | ```curl
13 | $ curl https://example.com/version
14 | ```
15 |
16 | #### Example Response
17 | ```json
18 | {
19 | "response_version": "v2",
20 | "api_version": "15.0.0"
21 | }
22 | ```
23 |
24 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/pdrs.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Pdrs {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'pdrs'
7 | }
8 |
9 | get (name, options, callback) {
10 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
11 | }
12 |
13 | list (options, callback) {
14 | return this.client._req('get', this.endpoint, options, callback)
15 | }
16 |
17 | del (name, callback) {
18 | return this.client._req('delete', joinUrl(this.endpoint, name), callback)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/template/defaults/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Cumulus API
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/content/orca.md:
--------------------------------------------------------------------------------
1 | ## ORCA
2 |
3 | This endpoint authenticates and forwards requests to the ORCA private API, and returns the response from the ORCA API. Please refer to [ORCA API reference](https://nasa.github.io/cumulus-orca/docs/developer/api/orca-api) on how to use ORCA API.
4 |
5 | ```endpoint
6 | POST /orca
7 | ```
8 |
9 | #### Example request
10 |
11 | ```curl
12 | $ curl --request POST https://example.com/orca/recovery/granules --header 'Authorization: Bearer ReplaceWithTheToken' --header 'Content-Type: application/json' --data '{
13 | "granuleId": "MOD14A1.061.H5V12.2020312.141531789"
14 | }'
15 | ```
16 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ['./website/index.html'],
4 | theme: {
5 | screens: {
6 | sm: '480px',
7 | md: '768px',
8 | lg: '976px',
9 | xl: '1440px',
10 | },
11 | fontFamily: {
12 | sans: ['Open Sans', 'sans-serif'],
13 | },
14 | extend: {
15 | colors: {
16 | 'blue': '#2276AC',
17 | 'gray-light': '#F5F6F7',
18 | 'dark-surface': '#121212',
19 | 'dark-blue': '#52BDFF',
20 | 'dark-highlight': '#EBF7FF'
21 | },
22 | },
23 | },
24 | plugins: [],
25 | };
26 |
--------------------------------------------------------------------------------
/api-client-js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@cumulus/cumulus-api-client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "lint": "standard",
8 | "test": "CUMULUS_BASEURL=https://wjdkfyb6t6.execute-api.us-east-1.amazonaws.com/dev/ node tests/index.js"
9 | },
10 | "dependencies": {
11 | "base-64": "^0.1.0",
12 | "call-me-maybe": "^1.0.1",
13 | "got": "^7.1.0",
14 | "nanoassert": "^1.1.0",
15 | "url-join": "^2.0.2"
16 | },
17 | "devDependencies": {
18 | "documentation": "^5.3.3",
19 | "standard": "^10.0.3",
20 | "tap-spec": "^5.0.0",
21 | "tape": "^4.8.0"
22 | },
23 | "author": "",
24 | "license": "Apache-2.0"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/curl/stats.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Get the access token using the auth example
4 | TOKEN=`"./auth.sh"`
5 | URL="$CUMULUS_BASEURL/stats"
6 |
7 | # Get stats summary
8 | printf "\nsummary\n"
9 | curl -i $URL \
10 | -H "Authorization: Bearer ${TOKEN}"
11 |
12 | # Get histogram
13 | printf "\nhistogram\n"
14 | URL="$CUMULUS_BASEURL/stats/histogram"
15 | curl -i $URL \
16 | -H "Authorization: Bearer ${TOKEN}"
17 |
18 | # Get aggregate
19 | printf "\naggregate\n"
20 | URL="$CUMULUS_BASEURL/stats/aggregate"
21 | curl -i $URL \
22 | -H "Authorization: Bearer ${TOKEN}"
23 |
24 | # Get average
25 | printf "\naverage\n"
26 | URL="$CUMULUS_BASEURL/stats/average?field=grade"
27 | curl -i $URL \
28 | -H "Authorization: Bearer ${TOKEN}"
29 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/granules.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Granules {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'granules'
7 | }
8 |
9 | put (name, options, callback) {
10 | return this.client._req('put', joinUrl(this.endpoint, name), options, callback)
11 | }
12 |
13 | get (name, options, callback) {
14 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
15 | }
16 |
17 | list (options, callback) {
18 | return this.client._req('get', this.endpoint, options, callback)
19 | }
20 |
21 | del (name, callback) {
22 | return this.client._req('delete', joinUrl(this.endpoint, name), callback)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/node/execution-status.js:
--------------------------------------------------------------------------------
1 | var Cumulus = require('../../api-client-js')
2 |
3 | var api = new Cumulus({
4 | baseUrl: process.env.CUMULUS_BASEURL
5 | })
6 |
7 | var options = {
8 | username: process.env.EARTHDATA_USERNAME,
9 | password: process.env.EARTHDATA_PASSWORD
10 | }
11 |
12 | api.login(options, function (err, token) {
13 | getExecutionsList(function (err, list) {
14 | var execution = list[0]
15 | api.executionStatus.get(execution.arn, function (err, response) {
16 | console.log(response)
17 | })
18 | })
19 | })
20 |
21 | function getExecutionsList (callback) {
22 | api.executions.list(function (err, res) {
23 | if (err) return callback(err)
24 | return callback(null, res.results)
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Cumulus API Docs
2 |
3 | [](https://circleci.com/gh/nasa/cumulus-api)
4 |
5 | Cumulus API documentation: https://nasa.github.io/cumulus-api
6 |
7 | ### Installation
8 |
9 | $ npm install
10 |
11 | ### Build CSS (Styling)
12 |
13 | $ npm run build-css
14 |
15 | ### Build Site
16 |
17 | $ npm run build
18 |
19 | ### Serve
20 |
21 | #### Serve current(unreleased) document
22 |
23 | $ npm run serve
24 |
25 | #### Serve current and released document
26 |
27 | $ npm run serve-all
28 |
29 | ### Deploy
30 |
31 | $ npm run deploy
32 |
33 | ### 🛒 Release
34 |
35 | To release a new version of Cumulus API document [read this](release.md).
36 |
--------------------------------------------------------------------------------
/content/instance-meta.md:
--------------------------------------------------------------------------------
1 | ## Instance Metadata
2 |
3 | The Cumulus API can provide information about its configuration.
4 |
5 | GET requests to the instance metadata endpoint return a json object with information about how the Cumulus stack is configured. It returns the CMR provider and environment as well as the stackName (prefix).
6 |
7 | ```endpoint
8 | GET /instanceMeta
9 | ```
10 |
11 | #### Example Request
12 | ```curl
13 | $ curl https://example.com/instanceMeta --header 'Authorization: Bearer ReplaceWithTheToken'
14 | ```
15 |
16 | #### Example Response
17 | ```json
18 | {
19 | "cmr": {
20 | "provider": "CUMULUS",
21 | "environment": "UAT"
22 | },
23 | "cumulus": {
24 | "stackName": "cumulus-stack-prefix"
25 | }
26 | }
27 | ```
28 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/stats.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Stats {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'stats'
7 | }
8 |
9 | get (options, callback) {
10 | return this.client._req('get', this.endpoint, options, callback)
11 | }
12 |
13 | aggregate (options, callback) {
14 | return this.client._req('get', joinUrl('aggregate', this.endpoint), options, callback)
15 | }
16 |
17 | average (options, callback) {
18 | return this.client._req('get', joinUrl('average', this.endpoint), options, callback)
19 | }
20 |
21 | histogram (options, callback) {
22 | return this.client._req('get', joinUrl('histogram', this.endpoint), options, callback)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/reconciliation-reports.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class ReconciliationReports {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'reconciliationReports'
7 | }
8 |
9 | post (name, options, callback) {
10 | return this.client._req('post', joinUrl(this.endpoint, name), options, callback)
11 | }
12 |
13 | get (name, options, callback) {
14 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
15 | }
16 |
17 | list (options, callback) {
18 | return this.client._req('get', this.endpoint, options, callback)
19 | }
20 |
21 | del (name, callback) {
22 | return this.client._req('delete', joinUrl(this.endpoint, name), callback)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/content/dashboard.md:
--------------------------------------------------------------------------------
1 | ## Serve the dashboard from a bucket
2 |
3 | Serve the dashboard from an S3 bucket.
4 |
5 | ```endpoint
6 | GET /dashboard/{bucket}/{key}
7 | ```
8 |
9 | This is a way to serve the Cumulus dashboard in a browser from an S3 bucket without making the bucket or files public.
10 |
11 | To use this:
12 | - Your dashboard bucket must be in the bucket definitions in your Cumulus `terraform.tfvars`, otherwise you will not be able to access the bucket.
13 | - Deploy the dashboard to your bucket using the instructions in the Cumulus dashboard README.
14 | - In a browser, use the example request below, but replace `example.com` with your Cumulus backend API and `dashboard-bucket` with your bucket name.
15 |
16 | #### Example request
17 |
18 | ```
19 | https://example.com/dashboard/dashboard-bucket/index.html
20 | ```
21 |
--------------------------------------------------------------------------------
/content/granule-csv.md:
--------------------------------------------------------------------------------
1 | ## Get Granule CSV file
2 |
3 | Get a CSV file of all the granule in the Cumulus database.
4 |
5 | ```endpoint
6 | GET /granule-csv
7 | ```
8 |
9 | #### Example request
10 |
11 | ```curl
12 | $ curl https://example.com/granule-csv --header 'Authorization: Bearer ReplaceWithTheToken'
13 | ```
14 |
15 | #### Example response
16 |
17 | ``` json
18 | "granuleUr","collectionId","createdAt","startDateTime","endDateTime","status","updatedAt","published"
19 | "MOD14A1.A9506271.IvEJsu.006.8359924290786","MOD14A1___006","2020-05-18T20:15:54.525Z","2017-10-24T00:00:00Z","2017-11-08T23:59:59Z","completed","2020-05-18T20:16:02.473Z",false
20 | "MYD13Q1.A9663671.0zkwKH.006.9812354158395","MYD13Q1___006","2020-07-06T19:46:19.957Z","2017-10-24T00:00:00Z","2017-11-08T23:59:59Z","completed","2020-07-06T19:46:57.054Z",true
21 | ```
22 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/rules.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Rules {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'rules'
7 | }
8 |
9 | post (name, options, callback) {
10 | return this.client._req('post', joinUrl(this.endpoint, name), options, callback)
11 | }
12 |
13 | put (name, options, callback) {
14 | return this.client._req('put', joinUrl(this.endpoint, name), options, callback)
15 | }
16 |
17 | get (name, options, callback) {
18 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
19 | }
20 |
21 | list (options, callback) {
22 | return this.client._req('get', this.endpoint, options, callback)
23 | }
24 |
25 | del (name, callback) {
26 | return this.client._req('delete', joinUrl(this.endpoint, name), callback)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/providers.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | module.exports = class Providers {
4 | constructor (client) {
5 | this.client = client
6 | this.endpoint = 'providers'
7 | }
8 |
9 | post (name, options, callback) {
10 | return this.client._req('post', joinUrl(this.endpoint, name), options, callback)
11 | }
12 |
13 | put (name, options, callback) {
14 | return this.client._req('put', joinUrl(this.endpoint, name), options, callback)
15 | }
16 |
17 | get (name, options, callback) {
18 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
19 | }
20 |
21 | list (options, callback) {
22 | return this.client._req('get', this.endpoint, options, callback)
23 | }
24 |
25 | del (name, callback) {
26 | return this.client._req('delete', joinUrl(this.endpoint, name), callback)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/content/replays-sqs-messages.md:
--------------------------------------------------------------------------------
1 | ## SQS Messages Replays
2 | Cumulus archives all incoming SQS messages to S3 and removes messages once they have been processed. Unprocessed messages are archived at the path: `${stackName}/archived-incoming-messages/${queueName}/${messageId}`.
3 |
4 | The Cumulus API supports requests to replay archived SQS messages by queue name.
5 | The schema below describes the expected fields in a replay request
6 |
7 | | Field | Type | Description |
8 | | ------ | ------ | ------ |
9 | | `queueName` | string | Any valid SQS queue name (*not* ARN) | |
10 |
11 | #### Example Request
12 |
13 | ```curl
14 | $ curl -X POST https://example.com/replays/sqs --header 'Authorization: Bearer ReplaceWithTheToken' --data '{ "queueName": "my-queue" }'
15 | ```
16 |
17 | #### Example Response
18 |
19 | ```json
20 | {
21 | "asyncOperationId": "208a463a-e096-4dd9-b006-e09345319ae6"
22 | }
23 | ```
24 |
--------------------------------------------------------------------------------
/examples/curl/auth.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | ORIGIN=$(dirname $CUMULUS_BASEURL)
4 | LOGIN_URL="$CUMULUS_BASEURL/token"
5 |
6 | # create a base64 hash of your login credentials
7 | AUTH=$(printf "$EARTHDATA_USERNAME:$EARTHDATA_PASSWORD" | base64)
8 |
9 | # Request the Earthdata url with client id and redirect uri to use with Cumulus
10 | AUTHORIZE_URL=$(curl -s -i ${LOGIN_URL} | grep location | sed -e "s/^location: //");
11 |
12 | # Request an authorization grant code
13 | TOKEN_URL=$(curl -s -i -X POST \
14 | -F "credentials=${AUTH}" \
15 | -H "Origin: ${ORIGIN}" \
16 | ${AUTHORIZE_URL%$'\r'} | grep Location | sed -e "s/^Location: //")
17 |
18 | # Request the token through the CUMULUS API url that's returned from Earthdata
19 | # Response is a JSON object of the form { token: String }
20 | # This uses the cli tool jq to parse the JSON and get the token string
21 | # More info on jq: https://stedolan.github.io/jq/
22 | TOKEN=$(curl -s ${TOKEN_URL%$'\r'} | jq -r '.token')
23 |
24 | echo $TOKEN
25 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: circleci/node:14.18.2
6 | working_directory: ~/cumulus-api
7 | steps:
8 | - checkout
9 |
10 | # restore cache
11 | - restore_cache:
12 | keys:
13 | - cumulus-api-{{ .Branch }}-{{ checksum "package.json" }}
14 |
15 | - run:
16 | name: Installing Dependencies
17 | command: sudo npm install -g npm@8.6.0 && npm install
18 |
19 | # save node_module and yarn-cache folders
20 | - save_cache:
21 | key: cumulus-api-{{ .Branch }}-{{ checksum "package.json" }}
22 | paths:
23 | - ~/cumulus-api/node_modules
24 |
25 |
26 | - add_ssh_keys:
27 | fingerprints:
28 | - "e3:e2:f2:ad:45:cc:79:08:79:ad:b3:3f:16:a3:fd:10"
29 |
30 | - deploy:
31 | name: deploy documentation to gh-pages
32 | command: |
33 | if [ "${CIRCLE_BRANCH}" == "master" ]; then
34 | npm run build
35 | npm run deploy
36 | fi
37 |
--------------------------------------------------------------------------------
/website/img/ic_cumulus_logo_blue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/website/img/ic_cumulus_logo_white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@cumulus/cumulus-api",
3 | "version": "0.1.0",
4 | "description": "Cumulus API Docs",
5 | "main": "handler.js",
6 | "scripts": {
7 | "bootstrap": "./bin/docs install",
8 | "serve": "./bin/docs serve",
9 | "serve-all": "budo --dir website --live",
10 | "build": "./bin/docs build",
11 | "build-css": "tailwindcss -i ./website/input.css -o ./website/output.css --minify",
12 | "deploy": "./bin/docs deploy"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/nasa/cumulus-api.git"
17 | },
18 | "author": "https://nasa.github.io/cumulus/docs/team",
19 | "license": "Apache-2.0",
20 | "bugs": {
21 | "url": "https://github.com/nasa/cumulus-api/issues"
22 | },
23 | "homepage": "https://github.com/nasa/cumulus-api#readme",
24 | "dependencies": {
25 | "autoprefixer": "^10.4.14",
26 | "docbox": "^1.0.11",
27 | "postcss": "^8.4.23"
28 | },
29 | "devDependencies": {
30 | "babel-register": "^6.3.13",
31 | "budo": "^11.6.3",
32 | "cross-env": "7.0.3",
33 | "cz-conventional-changelog": "2.0.0",
34 | "expect": "^25.0.0",
35 | "prettier": "^2.8.7",
36 | "prettier-plugin-tailwindcss": "^0.2.7",
37 | "tailwindcss": "^3.3.1",
38 | "to-vfile": "^2.0.0",
39 | "uglify-js": "^3.0.27"
40 | },
41 | "engines": {
42 | "node": ">=14.18.2",
43 | "npm": "8.6.0"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/api-client-js/endpoints/collections.js:
--------------------------------------------------------------------------------
1 | var joinUrl = require('url-join')
2 |
3 | /**
4 | * Request collections
5 | * @name collections
6 | * @example
7 | *
8 | * const api = new CumulusApi({ baseUrl: 'baseurl' })
9 | * const listPromise = api.collections.list()
10 | **/
11 | module.exports = class Collections {
12 | constructor (client) {
13 | this.client = client
14 | this.endpoint = 'collections'
15 | }
16 |
17 | /**
18 | * @name post
19 | * @memberof collections
20 | **/
21 | post (name, options, callback) {
22 | return this.client._req('post', joinUrl(this.endpoint, name), options, callback)
23 | }
24 |
25 | /**
26 | * @name put
27 | * @memberof collections
28 | **/
29 | put (name, options, callback) {
30 | return this.client._req('put', joinUrl(this.endpoint, name), options, callback)
31 | }
32 |
33 | /**
34 | * @name get
35 | * @memberof collections
36 | **/
37 | get (name, options, callback) {
38 | return this.client._req('get', joinUrl(this.endpoint, name), options, callback)
39 | }
40 |
41 | /**
42 | * @name list
43 | * @memberof collections
44 | **/
45 | list (options, callback) {
46 | return this.client._req('get', this.endpoint, options, callback)
47 | }
48 |
49 | /**
50 | * @name del
51 | * @memberof collections
52 | **/
53 | del (name, callback) {
54 | return this.client._req('delete', joinUrl(this.endpoint, name), callback)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/content/replays.md:
--------------------------------------------------------------------------------
1 | ## Ingest Replays
2 |
3 | The Cumulus API supports requests to replay ingest notifications.
4 | The schema below describes the expected fields in a replay request
5 |
6 | | Field | Type | Required | Description |
7 | | ------ | ------ | ------ | ------ |
8 | | `type` | string | required | Currently only accepts `kinesis`. |
9 | | `kinesisStream` | string | for type `kinesis` | Any valid kinesis stream name (*not* ARN) |
10 | | `kinesisStreamCreationTimestamp` | * | optional | Any input valid for a JS Date constructor. For reasons to use this field see [AWS documentation on StreamCreationTimestamp](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListShards.html#API_ListShards_RequestSyntax). |
11 | | `endTimestamp` | * | optional | Any input valid for a JS Date constructor. Messages newer than this timestamp will be skipped.
12 | | `startTimestamp` | * | optional | Any input valid for a JS Date constructor. Messages will be fetched from the Kinesis stream starting at this timestamp. Ignored if it is further in the past than the stream's retention period. |
13 |
14 | #### Example Request
15 |
16 | ```curl
17 | $ curl -X POST https://example.com/replays --header 'Authorization: Bearer ReplaceWithTheToken' --data '{ "type: "kinesis", "kinesisStream": "my-stream", "endTimestamp": 1567890123456, "startTimestamp": "2019-08-31T22:22:03.456Z"}'
18 | ```
19 |
20 | #### Example Response
21 |
22 | ```json
23 | {
24 | "asyncOperationId": "208a463a-e096-4dd9-b006-e09345319ae6"
25 | }
26 | ```
27 |
--------------------------------------------------------------------------------
/website/input.css:
--------------------------------------------------------------------------------
1 | /**
2 | * This injects Tailwind's base styles and any base styles registered by
3 | * plugins.
4 | */
5 | @tailwind base;
6 |
7 | /**
8 | * This injects Tailwind's component classes and any component classes
9 | * registered by plugins.
10 | */
11 | @tailwind components;
12 |
13 | /**
14 | * This injects Tailwind's utility classes and any utility classes registered
15 | * by plugins.
16 | */
17 | @tailwind utilities;
18 |
19 | /**
20 | * Use this directive to control where Tailwind injects the hover, focus,
21 | * responsive, dark mode, and other variants of each class.
22 | *
23 | * If omitted, Tailwind will append these classes to the very end of
24 | * your stylesheet by default.
25 | */
26 | @tailwind variants;
27 |
28 | @layer components {
29 | .version {
30 | @apply text-lg text-blue hover:underline dark:text-dark-blue;
31 | }
32 |
33 | .row-release {
34 | @apply border-b hover:bg-gray-50 dark:border-gray-600 dark:hover:bg-dark-highlight/10;
35 | }
36 |
37 | .latest-badge {
38 | @apply ml-2 mr-2 rounded border border-green-400 bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800 dark:bg-gray-700 dark:text-green-400;
39 | }
40 | }
41 |
42 | tr {
43 | height: 50px;
44 | }
45 |
46 | td {
47 | padding: 0 20px;
48 | }
49 |
50 | #mobile-menu {
51 | visibility: hidden;
52 | opacity: 0;
53 | transition: opacity 2s 0 ease;
54 | }
55 |
56 | .overlay {
57 | background-color: rgba(0,0,0,.50);
58 | cursor: pointer;
59 | }
--------------------------------------------------------------------------------
/website/v11.0.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v13.0.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v13.3.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v13.4.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v14.0.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v14.1.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v16.1.1/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v18.1.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v18.4.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v18.5.3/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v20.0.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v20.1.2/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v21.0.0/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v20.1.2/build/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/website/v21.0.0/build/css/railscasts.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #232323;
6 | color: #e6e1dc;
7 | }
8 |
9 | .hljs-comment,
10 | .hljs-quote {
11 | color: #bc9458;
12 | font-style: italic;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag {
17 | color: #c26230;
18 | }
19 |
20 | .hljs-string,
21 | .hljs-number,
22 | .hljs-regexp,
23 | .hljs-variable,
24 | .hljs-template-variable {
25 | color: #a5c261;
26 | }
27 |
28 | .hljs-subst {
29 | color: #519f50;
30 | }
31 |
32 | .hljs-tag,
33 | .hljs-name {
34 | color: #e8bf6a;
35 | }
36 |
37 | .hljs-type {
38 | color: #da4939;
39 | }
40 |
41 |
42 | .hljs-symbol,
43 | .hljs-bullet,
44 | .hljs-built_in,
45 | .hljs-builtin-name,
46 | .hljs-attr,
47 | .hljs-link {
48 | color: #6d9cbe;
49 | }
50 |
51 | .hljs-params {
52 | color: #d0d0ff;
53 | }
54 |
55 | .hljs-attribute {
56 | color: #cda869;
57 | }
58 |
59 | .hljs-meta {
60 | color: #9b859d;
61 | }
62 |
63 | .hljs-title,
64 | .hljs-section {
65 | color: #ffc66d;
66 | }
67 |
68 | .hljs-addition {
69 | background-color: #144212;
70 | color: #e6e1dc;
71 | display: inline-block;
72 | width: 100%;
73 | }
74 |
75 | .hljs-deletion {
76 | background-color: #600;
77 | color: #e6e1dc;
78 | display: inline-block;
79 | width: 100%;
80 | }
81 |
82 | .hljs-selector-class {
83 | color: #9b703f;
84 | }
85 |
86 | .hljs-selector-id {
87 | color: #8b98ab;
88 | }
89 |
90 | .hljs-emphasis {
91 | font-style: italic;
92 | }
93 |
94 | .hljs-strong {
95 | font-weight: bold;
96 | }
97 |
98 | .hljs-link {
99 | text-decoration: underline;
100 | }
101 |
--------------------------------------------------------------------------------
/template/src/custom/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Brand names, in order to decreasing length, for different
5 | * media queries.
6 | */
7 | module.exports.brandNames = {
8 | desktop: 'Cumulus API',
9 | tablet: 'Cumulus API',
10 | mobile: 'API Docs'
11 | };
12 |
13 | /**
14 | * Classes that define the top-left brand box.
15 | */
16 | module.exports.brandClasses = 'fill-blue';
17 |
18 |
19 | /**
20 | * Text for the link back to the linking website.
21 | */
22 | module.exports.backLink = 'Back to Cumulus Docs';
23 |
24 | /**
25 | * Runs after highlighting code samples. You can use this
26 | * hook to, for instance, highlight a token and link it
27 | * to some canonical part of documentation.
28 | */
29 | module.exports.postHighlight = function(html) {
30 | return html;
31 | };
32 |
33 | /**
34 | * Highlight tokens in endpoint URLs, optionally linking to documentation
35 | * or adding detail. This is the equivalent of postHighlight but it
36 | * operates on endpoint URLs only.
37 | */
38 | function highlightTokens(str) {
39 | return str.replace(/{[\w_]+}/g,
40 | (str) => '' + str + '');
41 | }
42 |
43 | /**
44 | * Transform endpoints given as strings in a highlighted block like
45 | *
46 | * ```endpoint
47 | * GET /foo/bar
48 | * ```
49 | *
50 | * Into HTML nodes that format those endpoints in nice ways.
51 | */
52 | module.exports.transformURL = function(value) {
53 | let parts = value.split(/\s+/);
54 | return {
55 | type: 'html',
56 | value: `
57 |
${parts[0]}
58 |
${highlightTokens(parts[1])}
59 |
`
60 | };
61 | };
62 |
63 | module.exports.remarkPlugins = [];
64 |
--------------------------------------------------------------------------------
/api-client-py/cumulus_api/cumulus_api.py:
--------------------------------------------------------------------------------
1 | # stdlib
2 | import json
3 | import base64
4 | from urlparse import urlparse
5 |
6 | # requests
7 | import requests
8 |
9 | class CumulusApi(object):
10 | """An API client for Cumulus
11 | Example usage:
12 | >>> import os
13 | >>> from cumulus_api import CumulusApi
14 | >>>
15 | >>> BASEURL = os.environ["CUMULUS_BASEURL"]
16 | >>> USERNAME = os.environ["EARTHDATA_USERNAME"]
17 | >>> PASSWORD = os.environ["EARTHDATA_PASSWORD"]
18 | >>>
19 | >>> api = CumulusAPI(BASEURL)
20 | >>> api.login(USERNAME, PASSWORD)
21 | """
22 |
23 | def __init__(self, base_url, access_token=None):
24 | # TODO: validate base_url
25 | self.base_url = base_url
26 | self.access_token = access_token
27 |
28 | def login(self, username, password):
29 | # send a request to cumulus to get the Earthdata authorization url
30 | authorize_response = requests.get(self.base_url + '/token', allow_redirects=False)
31 | authorize_url = authorize_response.headers['location']
32 |
33 | # send username & password to Earthdata to request a code to use to get an access token
34 | credentials = base64.b64encode('{}:{}'.format(username, password))
35 | payload = { 'credentials': credentials }
36 | parsed_url = urlparse(self.base_url)
37 | headers = {'origin': parsed_url.scheme + '://' + parsed_url.hostname }
38 | grant_code_response = requests.post(authorize_url, data=payload, headers=headers, allow_redirects=False)
39 | grant_code_url = grant_code_response.headers['Location']
40 |
41 | # get the access token for use in future requests
42 | token_response = requests.get(grant_code_url)
43 | self.access_token = token_response.json()['message']['token']
44 | return self.access_token
45 |
--------------------------------------------------------------------------------
/bin/docs:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | copy_docs() {
4 | echo 'Copying API content and custom template to DocBox'
5 | rm -rf node_modules/docbox/content
6 | ln -s $(pwd)/content $(pwd)/node_modules/docbox/content
7 | cp template/src/components/app.js node_modules/docbox/src/components/app.js
8 | cp template/src/custom/* node_modules/docbox/src/custom/
9 | cp template/defaults/* node_modules/docbox/
10 | }
11 |
12 | # Serves docbox
13 | serve() {
14 | cd node_modules/docbox || exit
15 | npm start
16 | }
17 |
18 | build() {
19 | RELEASE=$1
20 | rm -rf website/unreleased
21 | npm run build-css
22 | pushd node_modules/docbox || exit
23 | rm -rf build
24 | mkdir -p build
25 | npm run build
26 | cp -r css build/
27 | cp index.html build/
28 | cp bundle.js build/
29 | popd
30 | cp -r node_modules/docbox/build website/unreleased
31 | if [ "$RELEASE" ]
32 | then
33 | cp -r node_modules/docbox/build "website/$RELEASE"
34 | fi
35 | }
36 |
37 | deploy() {
38 | cd website || exit
39 | git init
40 | git config user.name "Dvseed"
41 | git config user.email "info@developmentseed.org"
42 | git config commit.gpgsign "false"
43 | git add .
44 | git commit -m "Automated to gh-pages [skip ci]"
45 | git push --force --quiet git@github.com:nasa/cumulus-api.git master:gh-pages
46 | rm -rf .git/
47 | }
48 |
49 | while [[ $1 ]]
50 | do
51 | case "$1" in
52 | serve)
53 | copy_docs
54 | serve
55 | exit 0
56 | ;;
57 | copy)
58 | copy_docs
59 | exit 0
60 | ;;
61 | build)
62 | copy_docs
63 | build $2
64 | exit 0
65 | ;;
66 | deploy)
67 | deploy
68 | exit 0
69 | ;;
70 | *)
71 | echo 'Argument(s) not supported'
72 | exit 0
73 | ;;
74 | esac
75 | done
76 |
--------------------------------------------------------------------------------
/release.md:
--------------------------------------------------------------------------------
1 | # Releasing a new Cumulus API version
2 |
3 | ## Releasing a version
4 |
5 | ### 1. Create a branch for the new release
6 |
7 | #### From Master
8 |
9 | Create a branch titled `release-MAJOR.MINOR.x` for the release (use a literal x
10 | for the patch version).
11 |
12 | ```shell
13 | git checkout -b release-MAJOR.MINOR.x
14 | ```
15 | e.g.:
16 | ```shell
17 | git checkout -b release-9.1.x
18 | ```
19 |
20 | If creating a new major version release from master, say `5.0.0`, then the
21 | branch would be named `release-5.0.x`. If creating a new minor version release
22 | from master, say `1.14.0` then the branch would be named `release-1.14.x`.
23 |
24 | Push the `release-MAJOR.MINOR.x` branch to GitHub if it was created locally.
25 | (Commits should be even with master at this point.)
26 |
27 | If creating a patch release, you can check out the existing base branch. NOTE:
28 | We **should not** create a patch release if there is no API update.
29 |
30 | ### 2. Create a git tag for the release
31 |
32 | From the minor version base branch (`release-1.2.x`), create and push a new git
33 | tag:
34 |
35 | ```bash
36 | git tag -a vMAJOR.MINOR.PATCH -m "Release MAJOR.MINOR.PATCH"
37 | git push origin vMAJOR.MINOR.PATCH
38 | ```
39 | e.g.:
40 | ```shell
41 | git tag -a v9.1.0 -m "Release 9.1.0"
42 | git push origin v9.1.0
43 | ```
44 |
45 | ### 3. Generate the API document
46 |
47 | ```bash
48 | npm install
49 | ```
50 | ```bash
51 | npm run build vMAJOR.MINOR.PATCH
52 | ```
53 | e.g.:
54 | ```shell
55 | npm run build v9.1.0
56 | ```
57 |
58 | You can view the generated API document with `npm run serve-all`.
59 |
60 | ### 4. Add the new API document
61 |
62 | Add the new API document link to `website/index.html`. Then add it to the
63 | commit along with the new API document with `git add website/index.html`.
64 |
65 | ```bash
66 | git add website/vMAJOR.MINOR.PATCH
67 | git commit -m "Release MAJOR.MINOR.PATCH"
68 | ```
69 | e.g.:
70 | ```shell
71 | git add website/v9.1.0 website/index.html
72 | git commit -m "Release 9.1.0"
73 | ```
74 |
75 | ### 5: Create a PR against master
76 |
--------------------------------------------------------------------------------
/content/async-operations.md:
--------------------------------------------------------------------------------
1 | ## List async operations
2 |
3 | Async operations are long-running requests serviced by the Cumulus API.
4 |
5 | These tend to be bulk operations. Examples include bulk granule operations and replaying ingest notifications.
6 |
7 | This endpoint lists async operations in the Cumulus system.
8 |
9 | ```endpoint
10 | GET /asyncOperations
11 | ```
12 |
13 | #### Example request
14 |
15 | ```curl
16 | $ curl https://example.com/asyncOperations --header 'Authorization: Bearer ReplaceWithTheToken'
17 | ```
18 |
19 | #### Example response
20 |
21 | ```json
22 | {
23 | "meta": {
24 | "name": "cumulus-api",
25 | "stack": "lpdaac-cumulus",
26 | "table": "async_operations",
27 | "limit": 1,
28 | "page": 1,
29 | "count": 8
30 | },
31 | "results": [
32 | {
33 | "output": "{\"deletedGranules\":[\"granule-id-f02a53418f\"]}",
34 | "createdAt": 1591384094512,
35 | "taskArn": "arn:aws:ecs:us-east-1:111111111111:task/d481e76e-f5fc-9c1c-2411-fa13779b111a",
36 | "description": "Bulk granule deletion",
37 | "operationType": "Bulk Granule Delete",
38 | "id": "0eb8e809-8790-5409-1239-bcd9e8d28b8e",
39 | "status": "SUCCEEDED",
40 | "updatedAt": 1591384094512,
41 | "timestamp": 1591384095235
42 | }
43 | ]
44 | }
45 | ```
46 |
47 | ## Retrieve async operation
48 |
49 | Retrieve information about a single async operation. Useful for determining the status of an async operation.
50 |
51 | ```endpoint
52 | GET /asyncOperations/{id}
53 | ```
54 |
55 | #### Example request
56 |
57 | ```curl
58 | $ curl https://example.com/asyncOperations/0eb8e809-8790-5409-1239-bcd9e8d28b8e --header 'Authorization: Bearer ReplaceWithTheToken'
59 | ```
60 |
61 | #### Example response
62 |
63 | ```json
64 | {
65 | "id": "0eb8e809-8790-5409-1239-bcd9e8d28b8e",
66 | "updatedAt": 1574730504762,
67 | "status": "RUNNING",
68 | "taskArn": "arn:aws:ecs:us-east-1:111111111111:task/d481e76e-f5fc-9c1c-2411-fa13779b111a",
69 | "description": "Bulk granule deletion",
70 | "operationType": "Bulk Granule Delete"
71 | }
72 | ```
73 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Thanks for considering contributing and making our planet easier to explore!
4 |
5 | We're excited you would like to contribute to Cumulus! Whether you're finding bugs, adding new features, fixing anything broken, or improving documentation, get started by submitting an issue or pull request!
6 |
7 | ## Submitting an Issue
8 |
9 | If you have any questions or ideas, or notice any problems or bugs, first [search open issues](https://github.com/nasa/cumulus-api/issues) to see if the issue has already been submitted. We may already be working on the issue. If you think your issue is new, you're welcome to [create a new issue](https://github.com/nasa/cumulus-api/issues/new).
10 |
11 | ## Pull Requests
12 |
13 | If you want to submit your own contributions, follow these steps:
14 |
15 | * Fork the Cumulus API repo
16 | * Create a new branch from the branch you'd like to contribute to
17 | * If an issue doesn't already exist, submit one (see above)
18 | * [Create a pull request](https://help.github.com/articles/creating-a-pull-request/) from your fork into the target branch of the nasa/cumulus-api repo
19 | * Be sure to [mention the corresponding issue number](https://help.github.com/articles/closing-issues-using-keywords/) in the PR description, i.e. "Fixes Issue #10"
20 | * Upon submission of a pull request, the Cumulus development team will review the code
21 | * The request will then either be merged, declined, or an adjustment to the code will be requested
22 |
23 | ## Guidelines
24 |
25 | We ask that you follow these guidelines with your contributions:
26 |
27 | ### Commits
28 |
29 | * Make small commits that show the individual changes you are making
30 | * Write descriptive commit messages that explain your changes
31 |
32 | Example of a good commit message:
33 |
34 | ```
35 | Improve contributing guidelines. Fixes #10
36 |
37 | Improve contributing docs and consolidate them in the standard location https://help.github.com/articles/setting-guidelines-for-repository-contributors/
38 | ```
39 |
40 | ### For more information on Cumulus governance, see the [Cumulus Code Contribution Guidelines](https://docs.google.com/document/d/14J_DS6nyQ32BpeVjdR-YKfzHAzFB299tKghPGshXUTU/edit) and [the Cumulus Wiki](https://wiki.earthdata.nasa.gov/display/CUMULUS/Cumulus).
41 |
--------------------------------------------------------------------------------
/content/dead-letter-archive.md:
--------------------------------------------------------------------------------
1 | ## Recover cumulus messages
2 |
3 | Endpoint provides a mechanism for recovery of S3 sfEventSqsToDbRecords dead letter objects (created as described in the [Core Documentation](https://nasa.github.io/cumulus/docs/features/dead_letter_archive)). The endpoint will invoke an async operation that will attempt to process all of the objects in the specified location.
4 |
5 | The endpoint by default will process all records contained in the S3 objects from the default storage location on the S3 system bucket under the prefix of `/dead-letter-archive/sqs/`. However, it is likely useful to process a subset of those objects, which you can do by moving the desired subset of objects to a new path on S3 and then specifying that new path using the `path` parameter to the endpoint request.
6 |
7 | The query uses the following optional parameters:
8 |
9 | | parameter | description |
10 | | --- | --- |
11 | | bucket | The bucket to read records from. Defaults to the Core system bucket|
12 | | path | The S3 prefix (path) to read DLQ records from. Defaults to `/dead-letter-archive/sqs/`|
13 | | batchSize | Specifies how many DLA objects to read from S3 and hold in memory. Defaults to 1000|
14 | | concurrency | Specifies how many messages to process at the same time. Defaults to 30|
15 | | dbMaxPool | Specifies how many database connections to allow the process to utilize. Defaults to 30. Process should at minimum the value set for `concurrency`|
16 |
17 | ```endpoint
18 | POST /deadLetterArchive/recoverCumulusMessages
19 | ```
20 |
21 | #### Example request
22 |
23 | ```curl
24 | curl -X POST https://cumulus.podaac.sit.earthdata.nasa.gov/deadLetterArchive/recoverCumulusMessages --header "Authorization: Bearer $TOKEN" --header 'Content-Type: application/json' --data '{
25 | "bucket": "some-cumulus-bucket",
26 | "path": "some/path/to/records/"
27 | }'
28 | ```
29 |
30 | #### Example response
31 |
32 | ```json
33 | {
34 | "createdAt":1646861517957,
35 | "updatedAt":1646861517957,
36 | "id":"a0cd2cf0-a677-e82a-27d1-0a09271aa37d",
37 | "status":"RUNNING",
38 | "taskArn":"arn:aws:ecs:us-west-2:xxxxxxxxxx:task/stack-CumulusECSCluster/{SHA}",
39 | "description":"Dead-Letter Processor ECS Run",
40 | "operationType":"Dead-Letter Processing"
41 | }
42 | ```
43 |
--------------------------------------------------------------------------------
/template/src/custom/content.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 |
3 | /**
4 | * This file exports the content of your website, as a bunch of concatenated
5 | * Markdown files. By doing this explicitly, you can control the order
6 | * of content without any level of abstraction.
7 | *
8 | * Using the brfs module, fs.readFileSync calls in this file are translated
9 | * into strings of those files' content before the file is delivered to a
10 | * browser: the content is read ahead-of-time and included in bundle.js.
11 | */
12 | module.exports =
13 | '# Introduction\n' +
14 | fs.readFileSync('./content/intro.md', 'utf8') + '\n' +
15 |
16 | '# Versioning\n' +
17 | fs.readFileSync('./content/version.md', 'utf8') + '\n' +
18 |
19 | '# Authentication\n' +
20 | fs.readFileSync('./content/auth.md', 'utf8') + '\n' +
21 |
22 | '# Providers\n' +
23 | fs.readFileSync('./content/providers.md', 'utf8') + '\n' +
24 |
25 | '# Collections\n' +
26 | fs.readFileSync('./content/collections.md', 'utf8') + '\n' +
27 |
28 | '# Granules\n' +
29 | fs.readFileSync('./content/granules.md', 'utf8') + '\n' +
30 |
31 | '# PDRs\n' +
32 | fs.readFileSync('./content/pdrs.md', 'utf8') + '\n' +
33 |
34 | '# Rules\n' +
35 | fs.readFileSync('./content/rules.md', 'utf8') + '\n' +
36 |
37 | '# Stats\n' +
38 | fs.readFileSync('./content/stats.md', 'utf8') + '\n' +
39 |
40 | '# Logs\n' +
41 | fs.readFileSync('./content/logs.md', 'utf8') + '\n' +
42 |
43 | '# Granule CSV\n' +
44 | fs.readFileSync('./content/granule-csv.md', 'utf8') + '\n' +
45 |
46 | '# Executions\n' +
47 | fs.readFileSync('./content/executions.md', 'utf8') + '\n' +
48 |
49 | '# Workflows\n' +
50 | fs.readFileSync('./content/workflows.md', 'utf8') + '\n' +
51 |
52 | '# Async Operations\n' +
53 | fs.readFileSync('./content/async-operations.md', 'utf8') + '\n' +
54 |
55 | '# Replays\n' +
56 | fs.readFileSync('./content/replays.md', 'utf8') + '\n' +
57 |
58 | '# Schemas\n' +
59 | fs.readFileSync('./content/schemas.md', 'utf8') + '\n' +
60 |
61 | '# Reconciliation Reports\n' +
62 | fs.readFileSync('./content/reconciliation-reports.md', 'utf8') + '\n' +
63 |
64 | '# Instance Metadata\n' +
65 | fs.readFileSync('./content/instance-meta.md') + '\n' +
66 |
67 | '# Dashboard\n' +
68 | fs.readFileSync('./content/dashboard.md') + '\n' +
69 |
70 | '# ORCA\n' +
71 | fs.readFileSync('./content/orca.md', 'utf8') + '\n' +
72 |
73 | '# Dead Letter Archive\n' +
74 | fs.readFileSync('./content/dead-letter-archive.md') + '\n'
75 | ;
76 |
--------------------------------------------------------------------------------
/content/stats.md:
--------------------------------------------------------------------------------
1 | ## Summary
2 |
3 | Retrieve a summary of statistics around the granules in the system. The `collections` returned are the number of distinct collections for the granules active during the given time period, defaulted to the last day if none is specified.
4 |
5 | ```endpoint
6 | GET /stats
7 | ```
8 |
9 | #### Example Request
10 |
11 | ```curl
12 | $ curl https://example.com/stats --header 'Authorization: Bearer ReplaceWithTheToken'
13 | ```
14 |
15 | #### Example success response
16 |
17 | ```json
18 | {
19 | "errors": {
20 | "dateFrom": "1970-01-18T12:36:59+00:00",
21 | "dateTo": "2017-12-26T04:38:15+00:00",
22 | "value": 2,
23 | "aggregation": "count",
24 | "unit": "error"
25 | },
26 | "collections": {
27 | "dateFrom": "1970-01-01T12:00:00+00:00",
28 | "dateTo": "2017-12-26T04:38:15+00:00",
29 | "value": 3,
30 | "aggregation": "count",
31 | "unit": "collection"
32 | },
33 | "processingTime": {
34 | "dateFrom": "1970-01-18T12:36:59+00:00",
35 | "dateTo": "2017-12-26T04:38:15+00:00",
36 | "value": null,
37 | "aggregation": "average",
38 | "unit": "second"
39 | },
40 | "granules": {
41 | "dateFrom": "1970-01-18T12:36:59+00:00",
42 | "dateTo": "2017-12-26T04:38:15+00:00",
43 | "value": 8,
44 | "aggregation": "count",
45 | "unit": "granule"
46 | }
47 | }
48 | ```
49 |
50 | ## Count
51 |
52 | Count the value frequencies for a given field, for a given type of record in Cumulus. Requires the following query parameters, and may include the regular filter parameters:
53 |
54 | | query string parameter | description |
55 | | --- | --- |
56 | | `type={providers|collections|granules|pdrs|logs}` | type of Cumulus record to query |
57 | | `field={fieldName}` | which field to count frequencies for; no default |
58 |
59 | ```endpoint
60 | GET /stats/aggregate
61 | ```
62 |
63 | #### Example request
64 |
65 | ```curl
66 | curl 'https://example.com/stats/aggregate?field=status&type=pdrs' --header 'Authorization: Bearer ReplaceWithTheToken'
67 | ```
68 |
69 | #### Example response
70 |
71 | ```json
72 | {
73 | "meta": {
74 | "name": "cumulus-api",
75 | "count": 52,
76 | "field": "status.keyword"
77 | },
78 | "count": [
79 | {
80 | "key": "failed",
81 | "count": 43
82 | },
83 | {
84 | "key": "completed",
85 | "count": 5
86 | },
87 | {
88 | "key": "parsed",
89 | "count": 3
90 | }
91 | ]
92 | }
93 | ```
--------------------------------------------------------------------------------
/website/v11.0.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v13.0.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v13.3.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v13.4.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v14.0.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v14.1.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v16.1.1/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v18.1.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v18.4.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v18.5.3/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v20.0.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v20.1.2/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v21.0.0/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v20.1.2/build/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/website/v21.0.0/build/css/style.css:
--------------------------------------------------------------------------------
1 | /* BASE OVERRIDES */
2 |
3 | /* Add buffer for nicer anchor links */
4 | .prose h2:first-child {
5 | padding-top: 20px;
6 | }
7 |
8 | .prose h3:first-child {
9 | padding-top: 20px;
10 | }
11 |
12 | /* Header gets big */
13 | @media only screen and (max-width:960px) {
14 | .prose h2:first-child {
15 | padding-top: 60px;
16 | }
17 |
18 | .prose h3:first-child {
19 | padding-top: 60px;
20 | }
21 | }
22 |
23 | /* Header gets bigger */
24 | @media only screen and (max-width:640px) {
25 | .prose h2:first-child {
26 | padding-top: 100px;
27 | }
28 |
29 | .prose h3:first-child {
30 | padding-top: 100px;
31 | }
32 | }
33 |
34 |
35 | /* tables are too giant */
36 | .prose table,
37 | .prose table code {
38 | margin-bottom: 20px;
39 | font-size: 12px;
40 | line-height: 1.5;
41 | }
42 |
43 | .prose table th, .prose table td {
44 | padding: 5px;
45 | }
46 |
47 | .dark.keyline-top,
48 | .dark.keyline-bottom {
49 | border-color: #313131;
50 | }
51 |
52 | html, body, #app, .container {
53 | height: 100%;
54 | }
55 |
56 | body pre {
57 | padding: 0;
58 | }
59 |
60 | /* BASE ADDONS */
61 | .fill-dark2 { background-color: #313131; }
62 | .fill-dark2 .rounded-toggle input[type=radio]:checked + label,
63 | .fill-dark2 .rounded-toggle .active { background-color: #313131; }
64 | .space-top3 { margin-top: 30px;}
65 | .space-top5 { margin-top: 50px;}
66 | .line-height15 { line-height: 15px; }
67 | .pad00y { padding-top: 2px; padding-bottom: 2px; }
68 | .space-bottom00 { margin-bottom: 3px;}
69 |
70 | .endpoint {
71 | width: 100%;
72 | display: flex;
73 | }
74 |
75 | .endpoint-method {
76 | }
77 |
78 | .endpoint-url {
79 | flex-grow: 1;
80 | word-wrap: break-word;
81 | }
82 |
83 | .endpoint-url a {
84 | background-color: rgba(255, 255, 255, 0.1);
85 | border-radius: 2px;
86 | font-weight:bold;
87 | padding: 2px;
88 | color: #fff;
89 | }
90 |
91 | .endpoint-url a:hover {
92 | background-color: rgba(255, 255, 255, 0.15);
93 | }
94 |
95 | .endpoint-token {
96 | }
97 |
98 | a.hljs-linked {
99 | border-radius: 2px;
100 | color: #a5c261;
101 | background: #383C2F;
102 | padding: 2px;
103 | }
104 |
105 | body .prose blockquote {
106 | padding: 5px 10px;
107 | background: #232323;
108 | }
109 |
110 | .preview {
111 | background-image: -webkit-linear-gradient(#F1F075, #F1F075);
112 | background-size: 10px 10px;
113 | background-repeat: repeat-y;
114 | }
115 |
116 | .preview h2::after,
117 | .preview h3::after {
118 | content: 'PREVIEW';
119 | background-color: #F1F075;
120 | border-radius: 2px;
121 | font-size: 9px;
122 | font-weight: normal;
123 | padding: 2px 5px;
124 | color: rgba(0, 0, 0, 0.5);
125 | margin-left: 10px;
126 | vertical-align: middle;
127 | }
128 |
--------------------------------------------------------------------------------
/content/pdrs.md:
--------------------------------------------------------------------------------
1 | ## List PDRs
2 |
3 | List PDRs in the Cumulus system.
4 |
5 | ```endpoint
6 | GET /pdrs
7 | ```
8 |
9 | #### Example request
10 |
11 | ```curl
12 | $ curl https://example.com/pdrs --header 'Authorization: Bearer ReplaceWithTheToken'
13 | ```
14 |
15 | #### Example response
16 |
17 | ```json
18 | {
19 | "meta": {
20 | "name": "cumulus-api",
21 | "stack": "lpdaac-cumulus",
22 | "table": "pdrs",
23 | "limit": 1,
24 | "page": 1,
25 | "count": 8
26 | },
27 | "results": [
28 | {
29 | "pdrName": "7970bff5-128a-489f-b43c-de4ad7834ce5.PDR",
30 | "collectionId": "MOD11A1___006",
31 | "status": "failed",
32 | "provider": "LP_TS2_DataPool",
33 | "progress": 0,
34 | "execution": "https://console.aws.amazon.com/states/home?region=us-east-1#/executions/details/arn:aws:states:us-east-1:ACCOUNT:execution:LpdaacCumulusIngestGranuleStateMachine-N3CLGBXRPAT9:6ef0c52f83c549db58b3a1e50",
35 | "PANSent": false,
36 | "PANmessage": "N/A",
37 | "stats": {
38 | "processing": 0,
39 | "completed": 0,
40 | "failed": 0,
41 | "total": 0
42 | },
43 | "createdAt": 1514305411204,
44 | "timestamp": 1514305424036,
45 | "duration": 12.832
46 | }
47 | ]
48 | }
49 | ```
50 |
51 | ## Retrieve PDR
52 |
53 | Retrieve a single PDR.
54 |
55 | ```endpoint
56 | GET /pdrs/{pdrName}
57 | ```
58 |
59 | #### Example request
60 |
61 | ```curl
62 | $ curl https://example.com/pdrs/7970bff5-128a-489f-b43c-de4ad7834ce5.PDR --header 'Authorization: Bearer ReplaceWithTheToken'
63 | ```
64 |
65 | #### Example response
66 |
67 | ```json
68 | {
69 | "pdrName": "7970bff5-128a-489f-b43c-de4ad7834ce5.PDR",
70 | "collectionId": "MOD11A1___006",
71 | "status": "failed",
72 | "provider": "LP_TS2_DataPool",
73 | "progress": 0,
74 | "execution": "https://console.aws.amazon.com/states/home?region=us-east-1#/executions/details/arn:aws:states:us-east-1:ACCOUNT:execution:LpdaacCumulusIngestGranuleStateMachine-N3CLGBXRPAT9:6ef0c52f83c549db58b3a1e50",
75 | "PANSent": false,
76 | "PANmessage": "N/A",
77 | "stats": {
78 | "processing": 0,
79 | "completed": 0,
80 | "failed": 0,
81 | "total": 0
82 | },
83 | "createdAt": 1514305411204,
84 | "timestamp": 1514305424036,
85 | "duration": 12.832,
86 | "_id": "7970bff5-128a-489f-b43c-de4ad7834ce5.PDR"
87 | }
88 | ```
89 |
90 | ## Delete PDR
91 |
92 | Delete a PDR from Cumulus. Its granules will remain, and the PDR may be re-discovered and re-ingested/re-processed from scratch in the future.
93 |
94 | ```endpoint
95 | DELETE /pdrs/{pdrName}
96 | ```
97 |
98 | #### Example request
99 |
100 | ```curl
101 | $ curl --request DELETE https://example.com/pdrs/good_25grans.PDR --header 'Authorization: Bearer ReplaceWithTheToken'
102 |
103 | ```
104 |
105 | #### Example response
106 |
107 | ```json
108 | {
109 | "message": "Record deleted"
110 | }
111 | ```
112 |
--------------------------------------------------------------------------------
/content/schemas.md:
--------------------------------------------------------------------------------
1 | ## Retrieve schema
2 |
3 | Retrieve the data schema for a particular type of Cumulus record.
4 |
5 | This schema describes the expected format of a record's JSON object when retrieving from Cumulus, as well as a summary of what each field may contain. The schema response can also be used to determine which fields are required when creating a new record using the API.
6 |
7 | Supported `type` values are `provider`, `collection`, `granule`, and `pdr`.
8 |
9 | ```endpoint
10 | GET /schemas/{type}
11 | ```
12 |
13 | #### Example request
14 |
15 | ```curl
16 | $ curl https://example.com/schemas/provider --header 'Authorization: Bearer ReplceWithTheToken'
17 | ```
18 |
19 | #### Example response
20 |
21 | ```json
22 | {
23 | "$schema": "http://json-schema.org/draft-04/schema#",
24 | "title": "Provider Object",
25 | "description": "Keep the information about each ingest endpoint",
26 | "type": "object",
27 | "properties": {
28 | "name": {
29 | "title": "Title",
30 | "description": "A title for the provider record",
31 | "type": "string",
32 | "pattern": "^([\\w\\d_\\-]*)$"
33 | },
34 | "providerName": {
35 | "title": "Provider, e.g. MODAPS",
36 | "description": "Name of the SIP",
37 | "type": "string"
38 | },
39 | "protocol": {
40 | "title": "Protocol",
41 | "type": "string",
42 | "enum": [
43 | "http",
44 | "ftp"
45 | ],
46 | "default": "http"
47 | },
48 | "host": {
49 | "title": "Host",
50 | "type": "string"
51 | },
52 | "path": {
53 | "title": "Path to the PDR/files folder",
54 | "type": "string"
55 | },
56 | "config": {
57 | "title": "Configuration",
58 | "type": "object",
59 | "properties": {
60 | "username": {
61 | "type": "string"
62 | },
63 | "password": {
64 | "type": "string"
65 | },
66 | "port": {
67 | "type": "string"
68 | }
69 | }
70 | },
71 | "status": {
72 | "title": "Status",
73 | "type": "string",
74 | "enum": [
75 | "ingesting",
76 | "stopped",
77 | "failed"
78 | ],
79 | "default": "stopped",
80 | "readonly": true
81 | },
82 | "isActive": {
83 | "title": "Is Active?",
84 | "type": "boolean",
85 | "default": false,
86 | "readonly": true
87 | },
88 | "regex": {
89 | "type": "object",
90 | "patternProperties": {
91 | "^([\\S]*)$": {
92 | "type": "string"
93 | }
94 | },
95 | "readonly": true
96 | },
97 | "lastTimeIngestedAt": {
98 | "title": "Last Time Ingest from the Provider",
99 | "type": "number",
100 | "readonly": true
101 | },
102 | "createdAt": {
103 | "type": "number",
104 | "readonly": true
105 | },
106 | "updatedAt": {
107 | "type": "number",
108 | "readonly": true
109 | }
110 | },
111 | "required": [
112 | "name",
113 | "providerName",
114 | "protocol",
115 | "host",
116 | "path",
117 | "isActive",
118 | "status",
119 | "createdAt",
120 | "updatedAt"
121 | ]
122 | }
123 | ```
124 |
--------------------------------------------------------------------------------
/content/intro.md:
--------------------------------------------------------------------------------
1 | ## Cumulus API
2 |
3 | The Cumulus API allows developers to interact with the [Cumulus Framework](https://github.com/nasa/cumulus), such as monitoring status or creating, editing, and deleting records. This is the same API that powers the [Cumulus dashboard](https://github.com/nasa/cumulus-dashboard).
4 |
5 | By utilizing this API, a developer can integrate with the Cumulus framework in any language or environment; although interacting with Cumulus through the Cumulus dashboard may be appropriate for many end users, for some use cases it's best to have the flexibility of a web-accessible API.
6 |
7 | The API accepts and responds with JSON payloads at various HTTPS endpoints.
8 |
9 | In order to use these endpoints, you must include authentication information in your HTTPS request; authentication is explained in the following section.
10 |
11 | The following table lists the [query string](https://en.wikipedia.org/wiki/Query_string) parameters that can be used with most of the Cumulus API endpoints. `{fieldName}` is a stand-in for any of the fields in the record, and for nested objects dot notation can be used; for example, valid `fieldName`s include: `pdrName`, `status`, and `recipe.processStep.description`.
12 |
13 | | query string parameter | description |
14 | | ----- | ----------- |
15 | | `countOnly={boolean}` | For search/list endpoints ONLY, if set to `true`, return only count/meta information but an empty array of results. Used for cases where returning results is undesirable for performance reasons. Defaults to `false` |
16 | | `limit={number}` | Number of records to be returned by the API call; default is `10`. A value of `null` will return all records. |
17 | | `page={number}` | page number, 1-indexed; default is `1` |
18 | | `sort_by={fieldName}` | which field to sort by; default is `timestamp` |
19 | | `order={asc|desc}` | whether to sort in `asc` or `desc` order |
20 | | `sort_key[]={-fieldName1}&sort_key[]={fieldName2}` | One or more sort keys can be specified using the sort_key[] parameter. The order used impacts searching. Fields can be prepended with a `-` to sort in descending order or a `+` to sort in ascending. Ascending order is the default. The + must be escaped with %2B|
21 | | `prefix={value}` | `startsWith` search of the Providers by `name`, Collections by `name`, Granules by `granuleId`, PDRs by `pdrName`, Rules by `name`, Executions by `arn`, Async Operations by `id`, Reconciliation Reports by `name` |
22 | | `infix={value}` | `includes` search of the Providers by `name`, Collections by `name`, Granules by `granuleId`, PDRs by `pdrName`, Rules by `name`, Executions by `arn`, Async Operations by `id`, Reconciliation Reports by `name` |
23 | | `fields={fieldName1, fieldName2}` | which fields to return, separated by a comma |
24 | | `{fieldName}={value}` | exact value match for the given field |
25 | | `{fieldName}__from={number}` | for numeric fields, field value must be greater than the given number |
26 | | `{fieldName}__to={number}` | for numeric fields, field value must be less than the given number |
27 | | `{fieldName}__not={value}` | field does not match the given value |
28 | | `{fieldName}__in={value1, value2}` | field matches _one of_ the values in the comma-separated list |
29 | | `{fieldName}__exists={true|false}` | field exists or doesn't exist in the record |
30 | | `q="fieldName:[1 TO 2] AND fieldName2:[3 TO 4]"` | arbitrary Apache [Lucene query syntax], _not needed for most uses of the API_; if the `q` parameter is used, all other query parameters will be ignored, besides `limit`, `page`, and `fields` |
31 |
32 | [Lucene query syntax]:
33 | https://www.elastic.co/guide/en/kibana/current/lucene-query.html
34 |
--------------------------------------------------------------------------------
/content/auth.md:
--------------------------------------------------------------------------------
1 | ## Token
2 |
3 | Returns a bearer token using oAuth with [Earthdata Login](https://urs.earthdata.nasa.gov) service. The token will be returned as a [JWT (JSON Web Token)](https://jwt.io/introduction/).
4 |
5 | ```endpoint
6 | GET /token
7 | ```
8 |
9 | ### Query Parameters
10 |
11 | | query string parameter | description |
12 | | ----- | ----------- |
13 | | `state={string}` | The URI to redirect to after if oAuth was successful |
14 |
15 |
16 | #### Example request
17 |
18 | ```curl
19 | $ curl https://example.com/token
20 | ```
21 |
22 | #### Example response
23 |
24 | ```json
25 | {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NUb2tlbiI6IjIyMzc0YWE4MDM1M2E3ODFkYWJjYmFhZGJhOGE3ZmMwZmE1MWYzYjQzNWYxNTc4MjU2NjA0ZjFiNGQ0NTE2ODYiLCJleHAiOiIxNTQ0NDY1MDk3ODczIn0.SxFtZ7dqp9KsUSn1uTXhWis8Il8Hig8mwLANGU3cXhY"}
26 | ```
27 |
28 | ## Refresh token
29 |
30 | Refreshes a bearer token received from oAuth with [Earthdata Login](https://urs.earthdata.nasa.gov) service. The token will be returned as a [JWT (JSON Web Token)](https://jwt.io/introduction/).
31 |
32 | ```endpoint
33 | POST /refresh
34 | ```
35 |
36 | ### Request body
37 |
38 | | parameter | type | required | description |
39 | | ----- | --- | -- | ----------- |
40 | | `token` | string | `true` | The JWT received from the `/token` endpoint to refresh |
41 |
42 |
43 | #### Example request
44 |
45 | ```curl
46 | $ curl --request POST https://example.com/refresh --header 'Content-Type: application/json' --data '{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NUb2tlbiI6IjIyMzc0YWE4MDM1M2E3ODFkYWJjYmFhZGJhOGE3ZmMwZmE1MWYzYjQzNWYxNTc4MjU2NjA0ZjFiNGQ0NTE2ODYiLCJleHAiOiIxNTQ0NDY1MDk3ODczIn0.SxFtZ7dqp9KsUSn1uTXhWis8Il8Hig8mwLANGU3cXhY"}'
47 | ```
48 |
49 | #### Example response
50 |
51 | ```json
52 | {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NUb2tlbiI6IjIyMzc0YWE4MDM1M2E3ODFkYWJjYmFhZGJhOGE3ZmMwZmE1MWYzYjQzNWYxNTc4MjU2NjA0ZjFiNGQ0NTE2ODYiLCJleHAiOiIxNTQ0NDcxMjk4ODEzIn0.vO6RlSRo47kkH15_muoUYNvv74fRzFxs7FlmVaarHlc"}
53 | ```
54 |
55 | ## Delete token
56 |
57 | Delete the record for an access token received from oAuth with [Earthdata Login](https://urs.earthdata.nasa.gov) service.
58 |
59 | ```endpoint
60 | DELETE /tokenDelete/{token}
61 | ```
62 |
63 | `token` is the JWT containing access token information to delete
64 |
65 | #### Example request
66 |
67 | ```curl
68 | $ curl --request DELETE https://example.com/tokenDelete/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NUb2tlbiI6IjIyMzc0YWE4MDM1M2E3ODFkYWJjYmFhZGJhOGE3ZmMwZmE1MWYzYjQzNWYxNTc4MjU2NjA0ZjFiNGQ0NTE2ODYiLCJleHAiOiIxNTQ0NDY1MDk3ODczIn0.SxFtZ7dqp9KsUSn1uTXhWis8Il8Hig8mwLANGU3cXhY
69 | ```
70 |
71 | #### Example response
72 |
73 | ```json
74 | {"message": "Token record was deleted"}
75 | ```
76 |
77 | ## Authorization header
78 |
79 | When a request is made to the Cumulus API, it must contain a bearer token generated by the API.
80 |
81 | The token is generated after the user login with [Earthdata Login](https://urs.earthdata.nasa.gov) service.
82 |
83 | The token is included in requests using the `Authorization` header.
84 |
85 | If no token is provided, the Cumulus API server will respond with an error, requesting credentials. If an incorrect token is provided, the server will respond with a separate error noting this.
86 |
87 | #### Authentication example
88 |
89 | ```curl
90 | #! /bin/sh
91 |
92 | ORIGIN=$(dirname $CUMULUS_BASEURL)
93 | LOGIN_URL="$CUMULUS_BASEURL/token"
94 |
95 | # create a base64 hash of your login credentials
96 | AUTH=$(printf "$EARTHDATA_USERNAME:$EARTHDATA_PASSWORD" | base64)
97 |
98 | # Request the Earthdata url with client id and redirect uri to use with Cumulus
99 | AUTHORIZE_URL=$(curl -s -i ${LOGIN_URL} | grep location | sed -e "s/^location: //");
100 |
101 | # Request an authorization grant code
102 | TOKEN_URL=$(curl -s -i -X POST \
103 | -F "credentials=${AUTH}" \
104 | -H "Origin: ${ORIGIN}" \
105 | ${AUTHORIZE_URL%$'\r'} | grep Location | sed -e "s/^Location: //")
106 |
107 | # Request the token through the CUMULUS API url that's returned from Earthdata
108 | # Response is a JSON object of the form { token: String }
109 | # This uses the cli tool jq to parse the JSON and get the token string
110 | # More info on jq: https://stedolan.github.io/jq/
111 | TOKEN=$(curl -s ${TOKEN_URL%$'\r'} | jq -r '.message.token')
112 |
113 | echo $TOKEN
114 | ```
115 |
116 | ```python
117 | import os
118 |
119 | from cumulus_api import CumulusApi
120 |
121 | CUMULUS_BASEURL = os.environ["CUMULUS_BASEURL"]
122 | EARTHDATA_USERNAME = os.environ["EARTHDATA_USERNAME"]
123 | EARTHDATA_PASSWORD = os.environ["EARTHDATA_PASSWORD"]
124 |
125 | api = CumulusApi(CUMULUS_BASEURL)
126 |
127 | token = api.login(EARTHDATA_USERNAME, EARTHDATA_PASSWORD)
128 | print token
129 | ```
130 |
131 | ```javascript
132 | var Cumulus = require('../../api-client-js')
133 |
134 | var api = new Cumulus({
135 | baseUrl: process.env.CUMULUS_BASEURL
136 | })
137 |
138 | var options = {
139 | username: process.env.EARTHDATA_USERNAME,
140 | password: process.env.EARTHDATA_PASSWORD
141 | }
142 |
143 | api.login(options, function (err, token) {
144 | console.log('token', token)
145 | })
146 | ```
147 |
--------------------------------------------------------------------------------
/content/workflows.md:
--------------------------------------------------------------------------------
1 | ## List workflows
2 |
3 | List workflows in the Cumulus system.
4 |
5 | ```endpoint
6 | GET /workflows
7 | ```
8 |
9 | #### Example request
10 |
11 | ```curl
12 | $ curl https://example.com/workflows --header 'Authorization: Bearer ReplaceWithTheToken'
13 | ```
14 |
15 | #### Example response
16 |
17 | ```json
18 | [
19 | {
20 | "name": "TestLambdaVersionWorkflow",
21 | "template": "s3://cumulus-test-sandbox-internal/cumulus/workflows/TestLambdaVersionWorkflow.json",
22 | "definition": {
23 | "Comment": "Tests Lambda update after redeploy",
24 | "StartAt": "StartStatus",
25 | "States": {
26 | "StartStatus": {
27 | "Type": "Task",
28 | "Resource": "${SfSnsReportLambdaAliasOutput}",
29 | "Next": "WaitForDeployment"
30 | },
31 | "WaitForDeployment": {
32 | "Type": "Task",
33 | "Resource": "${WaitForDeploymentLambdaAliasOutput}",
34 | "Next": "VersionUpTest"
35 | },
36 | "VersionUpTest": {
37 | "Type": "Task",
38 | "Resource": "${VersionUpTestLambdaAliasOutput}",
39 | "Next": "StopStatus"
40 | },
41 | "StopStatus": {
42 | "Type": "Task",
43 | "Resource": "${SfSnsReportLambdaAliasOutput}",
44 | "Catch": [
45 | {
46 | "ErrorEquals": [
47 | "States.ALL"
48 | ],
49 | "Next": "WorkflowFailed"
50 | }
51 | ],
52 | "End": true
53 | },
54 | "WorkflowFailed": {
55 | "Type": "Fail",
56 | "Cause": "Workflow failed"
57 | }
58 | }
59 | }
60 | },
61 | {
62 | "name": "HelloWorldWorkflow",
63 | "template": "s3://cumulus-test-sandbox-internal/cumulus/workflows/HelloWorldWorkflow.json",
64 | "definition": {
65 | "Comment": "Returns Hello World",
66 | "StartAt": "StartStatus",
67 | "States": {
68 | "StartStatus": {
69 | "Type": "Task",
70 | "Resource": "${SfSnsReportLambdaAliasOutput}",
71 | "Next": "HelloWorld"
72 | },
73 | "HelloWorld": {
74 | "Type": "Task",
75 | "Resource": "${HelloWorldLambdaAliasOutput}",
76 | "Next": "StopStatus"
77 | },
78 | "StopStatus": {
79 | "Type": "Task",
80 | "Resource": "${SfSnsReportLambdaAliasOutput}",
81 | "Catch": [
82 | {
83 | "ErrorEquals": [
84 | "States.ALL"
85 | ],
86 | "Next": "WorkflowFailed"
87 | }
88 | ],
89 | "End": true
90 | },
91 | "WorkflowFailed": {
92 | "Type": "Fail",
93 | "Cause": "Workflow failed"
94 | }
95 | }
96 | }
97 | }
98 | ]
99 | ```
100 |
101 | ## Retrieve workflow
102 |
103 | Retrieve a single workflow.
104 |
105 | ```endpoint
106 | GET /workflow/{name}
107 | ```
108 |
109 | #### Example request
110 |
111 | ```curl
112 | $ curl https://example.com/workflows/HelloWorldWorkflow --header 'Authorization: Bearer ReplaceWithTheToken'
113 | ```
114 |
115 | #### Example response
116 |
117 | ```json
118 | {
119 | "name": "HelloWorldWorkflow",
120 | "template": "s3://cumulus-test-sandbox-internal/cumulus/workflows/HelloWorldWorkflow.json",
121 | "definition": {
122 | "Comment": "Returns Hello World",
123 | "StartAt": "StartStatus",
124 | "States": {
125 | "StartStatus": {
126 | "Type": "Task",
127 | "Resource": "${SfSnsReportLambdaAliasOutput}",
128 | "Next": "HelloWorld"
129 | },
130 | "HelloWorld": {
131 | "Type": "Task",
132 | "Resource": "${HelloWorldLambdaAliasOutput}",
133 | "Next": "StopStatus"
134 | },
135 | "StopStatus": {
136 | "Type": "Task",
137 | "Resource": "${SfSnsReportLambdaAliasOutput}",
138 | "Catch": [
139 | {
140 | "ErrorEquals": [
141 | "States.ALL"
142 | ],
143 | "Next": "WorkflowFailed"
144 | }
145 | ],
146 | "End": true
147 | },
148 | "WorkflowFailed": {
149 | "Type": "Fail",
150 | "Cause": "Workflow failed"
151 | }
152 | }
153 | }
154 | }
155 | ```
156 |
--------------------------------------------------------------------------------
/api-client-js/index.js:
--------------------------------------------------------------------------------
1 | var parseUrl = require('url').parse
2 |
3 | const maybe = require('call-me-maybe')
4 | const joinUrl = require('url-join')
5 | const assert = require('nanoassert')
6 | const base64 = require('base-64')
7 | const request = require('got')
8 |
9 | const Collections = require('./endpoints/collections')
10 | const Distribution = require('./endpoints/distribution')
11 | const ExecutionStatus = require('./endpoints/execution-status')
12 | const Executions = require('./endpoints/executions')
13 | const Granules = require('./endpoints/granules')
14 | const Logs = require('./endpoints/logs')
15 | const Pdrs = require('./endpoints/pdrs')
16 | const Providers = require('./endpoints/providers')
17 | const Rules = require('./endpoints/rules')
18 | const Schemas = require('./endpoints/schemas')
19 | const Stats = require('./endpoints/stats')
20 | const Workflows = require('./endpoints/workflows')
21 |
22 | /**
23 | *
24 | * @name CumulusApi
25 | **/
26 | class CumulusApi {
27 | constructor (baseUrl, options) {
28 | if (typeof baseUrl === 'object') {
29 | options = baseUrl
30 | baseUrl = options.baseUrl
31 | }
32 |
33 | assert(options && typeof options === 'object', 'options object is required')
34 | assert(baseUrl && typeof baseUrl === 'string', 'baseUrl string is required')
35 |
36 | this.baseUrl = baseUrl
37 | this.token = options.token || null
38 |
39 | this.collections = new Collections(this)
40 | this.distribution = new Distribution(this)
41 | this.executionStatus = new ExecutionStatus(this)
42 | this.executions = new Executions(this)
43 | this.granules = new Granules(this)
44 | this.logs = new Logs(this)
45 | this.pdrs = new Pdrs(this)
46 | this.providers = new Providers(this)
47 | this.rules = new Rules(this)
48 | this.schemas = new Schemas(this)
49 | this.stats = new Stats(this)
50 | this.workflows = new Workflows(this)
51 | }
52 |
53 | /**
54 | *
55 | * @name
56 | **/
57 | login (options, callback) {
58 | assert(options && typeof options === 'object', 'options object is required')
59 | assert(options.username && typeof options.username === 'string', 'options.username string is required')
60 | assert(options.password && typeof options.password === 'string', 'options.password string is required')
61 |
62 | var url = joinUrl(this.baseUrl, '/token')
63 |
64 | return maybe(callback, new Promise((resolve, reject) => {
65 | return request(url, { followRedirect: false })
66 | .catch(reject)
67 | .then((res) => {
68 | if (res.statusCode && res.headers.location) {
69 | resolve(this._authorize(res.headers.location, options))
70 | } else {
71 | reject(new Error('Error authenticating with EarthData login. Check that your baseUrl, username, and password are correct, and the app client_id and redirect_uri are correctly set up'))
72 | }
73 | })
74 | }))
75 | }
76 |
77 | /**
78 | *
79 | * @private
80 | **/
81 | _authorize (url, options) {
82 | assert(url && typeof url === 'string', 'url string is required')
83 |
84 | var urlObj = parseUrl(url)
85 | var auth = base64.encode(options.username + ':' + options.password)
86 |
87 | var requestOptions = {
88 | method: 'POST',
89 | form: true,
90 | body: { credentials: auth },
91 | headers: {
92 | origin: urlObj.protocol + '//' + urlObj.host
93 | }
94 | }
95 |
96 | return new Promise((resolve, reject) => {
97 | return request(url, requestOptions)
98 | .catch((err) => {
99 | if (err.statusCode === 302 && err.headers.location) {
100 | return resolve(this._getToken(err.headers.location))
101 | }
102 |
103 | reject(err)
104 | })
105 | .then((res) => {
106 | reject(new Error('Error authenticating with EarthData login. Check that your baseUrl, username, and password are correct, and the app client_id and redirect_uri are correctly set up'))
107 | })
108 | })
109 | }
110 |
111 | /**
112 | *
113 | * @private
114 | **/
115 | _getToken (url) {
116 | return new Promise((resolve, reject) => {
117 | request(url)
118 | .catch(reject)
119 | .then((res) => {
120 | var body = JSON.parse(res.body)
121 | this.token = body.message.token
122 | resolve(body.message.token)
123 | })
124 | })
125 | }
126 |
127 | _req (method, url, options, callback) {
128 | if (typeof options === 'function') {
129 | callback = options
130 | options = {}
131 | }
132 |
133 | if (!options) options = {}
134 | options.headers = { authorization: `Bearer ${this.token}` }
135 | options.method = method
136 |
137 | const requestPromise = new Promise((resolve, reject) => {
138 | return request(joinUrl(this.baseUrl, url), options)
139 | .catch(reject)
140 | .then((res) => {
141 | console.log('res.statusCode', res.statusCode)
142 | console.log(res)
143 | resolve(JSON.parse(res.body))
144 | })
145 | })
146 |
147 | return maybe(callback, requestPromise)
148 | }
149 | }
150 |
151 | module.exports = CumulusApi
152 |
--------------------------------------------------------------------------------
/content/providers.md:
--------------------------------------------------------------------------------
1 | ## List providers
2 |
3 | List providers in the Cumulus system.
4 |
5 | ```endpoint
6 | GET /providers
7 | ```
8 |
9 | #### Example request
10 |
11 | ```curl
12 | $ curl https://example.com/providers --header 'Authorization: Bearer ReplaceWithTheToken'
13 | ```
14 |
15 | #### Example response
16 |
17 | ```json
18 | {
19 | "meta": {
20 | "name": "cumulus-api",
21 | "stack": "daac-cumulus",
22 | "table": "providers",
23 | "limit": 1,
24 | "page": 1,
25 | "count": 2
26 | },
27 | "results": [
28 | {
29 | "id": "HTTP_MODIS",
30 | "globalConnectionLimit": 10,
31 | "maxDownloadTime": 300,
32 | "protocol": "http",
33 | "host": "https://data.modis.gov/",
34 | "timestamp": 1508861082226
35 | }
36 | ]
37 | }
38 | ```
39 |
40 | ## Retrieve provider
41 |
42 | Retrieve a single provider.
43 |
44 | ```endpoint
45 | GET /providers/{id}
46 | ```
47 |
48 | #### Example request
49 |
50 | ```curl
51 | $ curl https://example.com/providers/HTTP_MODIS --header 'Authorization: Bearer ReplaceWithTheToken'
52 | ```
53 |
54 | #### Example response
55 |
56 | ```json
57 | {
58 | "createdAt": 1508861081785,
59 | "id": "HTTP_MODIS",
60 | "host": "https://data.modis.gov/",
61 | "globalConnectionLimit": 10,
62 | "maxDownloadTime": 300,
63 | "updatedAt": 1508861081785,
64 | "protocol": "http"
65 | }
66 | ```
67 |
68 | ## Create provider
69 |
70 | Create a provider. For more information on creating providers and the contents of a request see [the Cumulus setup documentation](https://nasa.github.io/cumulus/docs/data-cookbooks/setup#providers).
71 |
72 | Overview of the schema fields:
73 |
74 | | Field | Value | Description |
75 | | --- | --- | --- |
76 | | `id` | `string` | provider id/name |
77 | | `protocol` | `"s3"`|`"http"`|`"https"`|`"ftp"` | file transfer (sync) protocol |
78 | | `host` | `string` | provider host endpoint |
79 | | `port` | `number` | provider host port |
80 | | `globalConnectionLimit` | `number` | limit to number of concurrent connections. This is the maximum number of connections Cumulus compatible ingest lambdas are expected to make to a provider. Defaults to unlimited |
81 | | `maxDownloadTime` | `number` | Maximum download time in seconds for all granule files on a sync granule task. The timeout is used together with globalConnectionLimit to limit concurrent downloads. |
82 | | `username` | `string` | provider connection username |
83 | | `password` | `string` | provider connection password |
84 | | `privateKey` | `string` | filename assumed to be in s3://bucketInternal/stackName/crypto |
85 | | `cmKeyId` | `string` | AWS KMS Customer Master Key arn or alias |
86 | | `allowedRedirects` | `Array` | Only hosts in this list will have the provider username/password forwarded for authentication. Entries should be specified as host.com or host.com:7000 if redirect port is different than the provider port. |
87 | | `certificateUri` | `string` | Optional SSL Certificate S3 URI for custom or self-signed SSL (TLS) certificate |
88 |
89 | ```endpoint
90 | POST /providers
91 | ```
92 |
93 | #### Example request
94 |
95 | ```curl
96 | $ curl --request POST https://example.com/providers --header 'Authorization: Bearer ReplaceWithTheToken' --header 'Content-Type: application/json' --data '{
97 | "host": "https://www.example.gov",
98 | "id": "MY_DAAC_SATELLITE",
99 | "protocol": "http",
100 | "globalConnectionLimit": 10,
101 | "maxDownloadTime": 300
102 | }'
103 | ```
104 |
105 | #### Example response
106 |
107 | ```json
108 | {
109 | "message": "Record saved",
110 | "record": {
111 | "createdAt": 1491941727851,
112 | "host": "https://www.example.gov",
113 | "id": "MY_DAAC_SATELLITE",
114 | "protocol": "http",
115 | "globalConnectionLimit": 10,
116 | "maxDownloadTime": 300,
117 | "timestamp": 1513956151186
118 | }
119 | }
120 | ```
121 |
122 | ## Update/replace provider
123 |
124 | Update/replace an existing provider. Expects payload to specify the entire
125 | provider object, and will completely replace the existing provider with the
126 | specified payload. For a field reference see
127 | ["Create provider"](#create-provider).
128 |
129 | Returns status 200 on successful replacement, 400 if the `id` property in the
130 | payload does not match the corresponding value in the resource URI, or 404 if
131 | there is no provider with the specified ID.
132 |
133 | ```endpoint
134 | PUT /providers/{id}
135 | ```
136 |
137 | #### Example request
138 |
139 | ```curl
140 | $ curl --request PUT https://example.com/providers/MY_DAAC_SATELLITE --header 'Authorization: Bearer ReplaceWithTheToken' --header 'Content-Type: application/json' --data '{
141 | "id": "MY_DAAC_SATELLITE",
142 | "host": "https://www.example.co.uk",
143 | "globalConnectionLimit": 10,
144 | "maxDownloadTime": 300,
145 | "protocol": "http"
146 | }'
147 | ```
148 |
149 | #### Example successful response
150 |
151 | ```json
152 | {
153 | "createdAt": 1491941727851,
154 | "id": "MY_DAAC_SATELLITE",
155 | "host": "https://www.example.co.uk",
156 | "globalConnectionLimit": 10,
157 | "maxDownloadTime": 300,
158 | "updatedAt": 1513956150733,
159 | "protocol": "http",
160 | "timestamp": 1513956555713
161 | }
162 | ```
163 |
164 | ## Delete provider
165 |
166 | Delete a provider from Cumulus. The related PDRs and granules remain in the Cumulus and CMR systems.
167 |
168 | ```endpoint
169 | DELETE /providers/{id}
170 | ```
171 |
172 | #### Example request
173 |
174 | ```curl
175 | $ curl --request DELETE https://example.com/providers/MY_DAAC_SATELLITE --header 'Authorization: Bearer ReplaceWithTheToken'
176 |
177 | ```
178 |
179 | #### Example response
180 |
181 | ```json
182 | {
183 | "message": "Record deleted"
184 | }
185 | ```
186 |
--------------------------------------------------------------------------------
/template/src/components/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Navigation from './navigation';
3 | import PropTypes from 'prop-types';
4 | import Content from './content';
5 | import RoundedToggle from './rounded_toggle';
6 | import GithubSlugger from 'github-slugger';
7 | import debounce from 'lodash.debounce';
8 | import { brandNames, brandClasses } from '../custom';
9 | import qs from 'querystring';
10 |
11 | let slugger = new GithubSlugger();
12 | let slug = title => { slugger.reset(); return slugger.slug(title); };
13 |
14 | let languageOptions = [
15 | { title: 'cURL',
16 | short: 'cURL',
17 | value: 'curl' },
18 | { title: 'Python',
19 | short: 'Python',
20 | value: 'python' },
21 | { title: 'JavaScript',
22 | short: 'JS',
23 | value: 'javascript' }
24 | ];
25 |
26 | let defaultLanguage = languageOptions[0];
27 |
28 | let debouncedReplaceState = debounce(hash => {
29 | window.history.replaceState('', '', hash);
30 | }, 100);
31 |
32 | export default class App extends React.PureComponent {
33 | static propTypes = {
34 | content: PropTypes.string.isRequired,
35 | ast: PropTypes.object.isRequired
36 | }
37 | constructor(props) {
38 | super(props);
39 | var active = 'Introduction';
40 |
41 | if (process.browser) {
42 | let hash = window.location.hash.split('#').pop();
43 | let languageFromURL = qs.parse(window.location.search.substring(1)).language;
44 | let language = languageOptions.find(option => option.title === languageFromURL) ||
45 | defaultLanguage;
46 | let mqls = [
47 | { name: 'widescreen', query: window.matchMedia('(min-width: 1200px)') },
48 | { name: 'desktop', query: window.matchMedia('(min-width: 961px)') },
49 | { name: 'tablet', query: window.matchMedia('(max-width: 960px)') },
50 | { name: 'mobile', query: window.matchMedia('(max-width: 640px)') }
51 | ];
52 | mqls.forEach(q => q.query.addListener(this.mediaQueryChanged));
53 | if (hash) {
54 | let headingForHash = this.props.ast.children
55 | .filter(child => child.type === 'heading')
56 | .find(heading => heading.data.id === hash);
57 | if (headingForHash) {
58 | active = headingForHash.children[0].value;
59 | }
60 | }
61 | this.state = {
62 | // media queryMatches
63 | mqls: mqls,
64 | // object of currently matched queries, like { desktop: true }
65 | queryMatches: {},
66 | language: language,
67 | columnMode: 2,
68 | activeSection: active,
69 | // for the toggle-able navigation on mobile
70 | showNav: false
71 | };
72 | } else {
73 | this.state = {
74 | mqls: { },
75 | queryMatches: {
76 | desktop: true
77 | },
78 | language: defaultLanguage,
79 | activeSection: '',
80 | showNav: false
81 | };
82 | }
83 | }
84 | toggleNav() {
85 | this.setState({ showNav: !this.state.showNav });
86 | }
87 | componentDidMount() {
88 | this.mediaQueryChanged();
89 | this.onScroll = debounce(this.onScrollImmediate, 100);
90 | document.addEventListener('scroll', this.onScroll);
91 | this.onScrollImmediate();
92 | }
93 | onScrollImmediate = () => {
94 | var sections = document.querySelectorAll('div.section');
95 | if (!sections.length) return;
96 | for (var i = 0; i < sections.length; i++) {
97 | var rect = sections[i].getBoundingClientRect();
98 | if (rect.bottom > 0) {
99 | this.setState({
100 | activeSection: sections[i].getAttribute('data-title')
101 | });
102 | return;
103 | }
104 | }
105 | }
106 | mediaQueryChanged() {
107 | this.setState({
108 | queryMatches: this.state.mqls.reduce((memo, q) => {
109 | memo[q.name] = q.query.matches;
110 | return memo;
111 | }, {})
112 | });
113 | }
114 | componentWillUnmount() {
115 | this.state.mqls.forEach(q => q.removeListener(this.mediaQueryChanged));
116 | document.body.removeEventListener('scroll', this.onScroll);
117 | }
118 | onChangeLanguage = (language) => {
119 | this.setState({ language }, () => {
120 | if (window.history) {
121 | window.history.pushState(null, null,
122 | `?${qs.stringify({ language: language.title })}${window.location.hash}`);
123 | }
124 | });
125 | }
126 | componentDidUpdate(_, prevState) {
127 | if (prevState.activeSection !== this.state.activeSection) {
128 | // when the section changes, replace the hash
129 | debouncedReplaceState(`#${slug(this.state.activeSection)}`);
130 | } else if (prevState.language.title !== this.state.language.title ||
131 | prevState.columnMode !== this.state.columnMode) {
132 | // when the language changes, use the hash to set scroll
133 | window.location.hash = window.location.hash;
134 | }
135 | }
136 | navigationItemClicked = activeSection => {
137 | setTimeout(() => {
138 | this.setState({ activeSection });
139 | }, 10);
140 | if (!this.state.queryMatches.desktop) {
141 | this.toggleNav();
142 | }
143 | }
144 | toggleColumnMode() {
145 | this.setState({
146 | columnMode: this.state.columnMode === 1 ? 2 : 1
147 | });
148 | }
149 | render() {
150 | let ast = JSON.parse(JSON.stringify(this.props.ast));
151 | let { activeSection, queryMatches, showNav, columnMode } = this.state;
152 | let col1 = columnMode === 1 && queryMatches.desktop;
153 | return (
154 |
155 | {/* Content background */ }
156 | {(!col1 && !queryMatches.mobile) &&
}
159 |
160 | {/* Desktop nav */ }
161 | {queryMatches.desktop &&
162 |
166 |
}
167 |
168 | {/* Content */ }
169 |
178 |
179 | {/* Language toggle */ }
180 |
181 |
182 |
183 | Show examples in:
184 |
185 |
190 |
191 | {queryMatches.desktop ?
192 |
: null}
197 |
198 |
199 |
200 |
201 | {/* Header */ }
202 |
203 |
204 |
207 | {queryMatches.desktop ? brandNames.desktop :
208 | queryMatches.mobile ? brandNames.mobile : brandNames.tablet}
209 |
210 | {queryMatches.tablet &&
211 |
216 | {showNav &&
218 |
222 |
}
223 |
}
224 |
225 |
226 |
);
227 | }
228 | }
229 |
230 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2017 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
4 | You may obtain a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10 |
11 | ---
12 |
13 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
14 |
15 | 1. Definitions.
16 |
17 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
18 |
19 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
20 |
21 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
26 |
27 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
28 |
29 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
30 |
31 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
32 |
33 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
34 |
35 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
36 |
37 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
38 |
39 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
40 |
41 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
42 |
43 | You must give any other recipients of the Work or Derivative Works a copy of this License; and
44 | You must cause any modified files to carry prominent notices stating that You changed the files; and
45 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
46 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
47 |
48 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
49 |
50 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
51 |
52 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
53 |
54 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
55 |
56 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
57 |
58 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
59 |
60 | END OF TERMS AND CONDITIONS
61 |
--------------------------------------------------------------------------------
/content/rules.md:
--------------------------------------------------------------------------------
1 | ## List rules
2 |
3 | List rules in the Cumulus system.
4 |
5 | ```endpoint
6 | GET /rules
7 | ```
8 |
9 | #### Example request
10 |
11 | ```curl
12 | $ curl https://example.com/rules --header 'Authorization: Bearer ReplaceWithTheToken'
13 | ```
14 |
15 | #### Example response
16 |
17 | ```json
18 | {
19 | "meta": {
20 | "name": "cumulus-api",
21 | "stack": "lpdaac-cumulus",
22 | "table": "rules",
23 | "limit": 1,
24 | "page": 1,
25 | "count": 7
26 | },
27 | "results": [
28 | {
29 | "name": "repeat",
30 | "workflow": "DiscoverPdrs",
31 | "provider": "local",
32 | "collection": {
33 | "name": "AST_L1A",
34 | "version": "003"
35 | },
36 | "rule": {
37 | "type": "scheduled",
38 | "value": "rate(5 minutes)"
39 | },
40 | "timestamp": 1511232462534,
41 | "state": "DISABLED"
42 | }
43 | ]
44 | }
45 | ```
46 |
47 | ## Retrieve rule
48 |
49 | Retrieve a single rule.
50 |
51 | ```endpoint
52 | GET /rules/{name}
53 | ```
54 |
55 | #### Example request
56 |
57 | ```curl
58 | $ curl https://example.com/rules/repeat --header 'Authorization: Bearer ReplaceWithTheToken'
59 | ```
60 |
61 | #### Example response
62 |
63 | ```json
64 | {
65 | "workflow": "DiscoverPdrs",
66 | "collection": {
67 | "name": "AST_L1A",
68 | "version": "003"
69 | },
70 | "updatedAt": 1511232462507,
71 | "createdAt": 1510903518741,
72 | "provider": "local",
73 | "name": "repeat",
74 | "rule": {
75 | "type": "scheduled",
76 | "value": "rate(5 minutes)"
77 | },
78 | "state": "DISABLED"
79 | }
80 | ```
81 |
82 | ## Create rule
83 |
84 | Create a rule. For more information on creating rules and the contents of a request see [the Cumulus setup documentation](https://nasa.github.io/cumulus/docs/data-cookbooks/setup#rules).
85 |
86 | Overview of the schema fields:
87 |
88 | | Field | Value | Required | Description |
89 | | --- | --- | --- | --- |
90 | | `name` | `string` | `yes` | rule name (letters, numbers, underscores only) |
91 | | `state` | `"DISABLED"`|`"ENABLED"` | `yes` | rule state (default: ENABLED) |
92 | | `workflow` | `string` | `yes` | name of workflow started by the rule |
93 | | `rule` | `Object` | `yes` | rule object |
94 | | `-- rule.type` | `"onetime"`|`"scheduled"`|`"kinesis"`|
`"sns"`|`"sqs"` | `yes` | rule trigger type |
95 | | `-- rule.value` | `onetime`: N/A
`scheduled`: cron-type or rate expression
`kinesis`: Kinesis stream ARN
`sns`: SNS topic ARN
`sqs`: SQS queue URL | `no` | required value differs by type |
96 | | `-- rule.arn` | `string` | `no` | `kinesis` scheduled event arn |
97 | | `-- rule.logEventArn` | `string` | `no` | `kinesis` scheduled log event arn |
98 | | `collection` | `Object` | `no` | collection record provided to workflow |
99 | | `-- collection.name` | `string` | `yes` | collection name |
100 | | `-- collection.version` | `string` | `yes` | collection version |
101 | | `executionNamePrefix` | `string` | `no` | Execution Name Prefix |
102 | | `meta` | `Object` | `no` | contents to add to workflow input's `meta` field |
103 | | `payload` | `string` | `no` | input payload to be used in onetime and scheduled rules|
104 | | `provider` | `string` | `no` | provider record provided to workflow |
105 | | `queueUrl` | `string` | `no` | queue URL for Scheduled Executions |
106 | | `tags` | `array` | `no` | tags (for search) |
107 |
108 | ```endpoint
109 | POST /rules
110 | ```
111 |
112 | #### Example request
113 |
114 | ```curl
115 | $ curl --request POST https://example.com/rules --header 'Authorization: Bearer ReplaceWithToken' --header 'Content-Type: application/json' --data '{
116 | "workflow": "DiscoverPdrs",
117 | "collection": {
118 | "name": "AST_L1A",
119 | "version": "003"
120 | },
121 | "provider": "local",
122 | "name": "repeat_test",
123 | "rule": {
124 | "type": "scheduled",
125 | "value": "rate(5 minutes)"
126 | },
127 | "meta": { "publish": false },
128 | "state": "DISABLED"
129 | }'
130 | ```
131 |
132 | #### Example response
133 |
134 | ```json
135 | {
136 | "message": "Record saved",
137 | "record": {
138 | "workflow": "DiscoverPdrs",
139 | "collection": {
140 | "name": "AST_L1A",
141 | "version": "003"
142 | },
143 | "createdAt": 1510903518741,
144 | "provider": "local",
145 | "name": "repeat_test",
146 | "rule": {
147 | "type": "scheduled",
148 | "value": "rate(5 minutes)"
149 | },
150 | "meta": { "publish": false },
151 | "state": "DISABLED"
152 | }
153 | }
154 | ```
155 |
156 | ## Replace rule
157 |
158 | Replace an existing rule. Expects payload to specify the entire
159 | rule object, and will completely replace the existing rule with the
160 | specified payload. For a field reference see ["Create rule"](#create-rule).
161 |
162 | Returns status 200 on successful replacement, 400 if the `name` property in the
163 | payload does not match the corresponding value in the resource URI, or 404 if
164 | there is no rule with the specified name.
165 |
166 | Special case:
167 |
168 | | Field | Value | Description |
169 | | --- | --- | --- |
170 | | `action` | `"rerun"` | rerun rule (`onetime` rule only), and rule record is not replaced |
171 |
172 | ```endpoint
173 | PUT /rules/{name}
174 | ```
175 |
176 | #### Example request
177 |
178 | ```curl
179 | $ curl --request PUT https://example.com/rules/repeat_test \
180 | --header 'Authorization: Bearer ReplaceWithToken' \
181 | --header 'Content-Type: application/json' \
182 | --header 'Cumulus-API-Version: 2' \
183 | --data '{
184 | "name": "repeat_test",
185 | "workflow": "DiscoverPdrs",
186 | "collection": {
187 | "name": "AST_L1A",
188 | "version": "003"
189 | },
190 | "provider": "local",
191 | "rule": {
192 | "type": "scheduled",
193 | "value": "rate(5 minutes)"
194 | },
195 | "state": "ENABLED"
196 | }'
197 | ```
198 |
199 | #### Example successful response
200 |
201 | ```json
202 | {
203 | "name": "repeat_test",
204 | "workflow": "DiscoverPdrs",
205 | "collection": {
206 | "name": "AST_L1A",
207 | "version": "003"
208 | },
209 | "updatedAt": 1521755265130,
210 | "createdAt": 1510903518741,
211 | "provider": "local",
212 | "rule": {
213 | "type": "scheduled",
214 | "value": "rate(5 minutes)"
215 | },
216 | "state": "ENABLED"
217 | }
218 | ```
219 |
220 | #### Rerun request (`onetime`-rule special case)
221 |
222 | ```curl
223 | $ curl --request PUT https://example.com/rules/my_onetime_rule \
224 | --header 'Authorization: Bearer ReplaceWithToken' \
225 | --header 'Content-Type: application/json' \
226 | --header 'Cumulus-API-Version: 2' \
227 | --data '{
228 | "name": "repeat_test",
229 | "workflow": "DiscoverPdrs",
230 | "collection": {
231 | "name": "AST_L1A",
232 | "version": "003"
233 | },
234 | "provider": "local",
235 | "rule": {
236 | "type": "scheduled",
237 | "value": "rate(5 minutes)"
238 | },
239 | "state": "ENABLED",
240 | "action": "rerun"
241 | }'
242 | ```
243 |
244 | ## Update rule
245 |
246 | Update an existing rule. Expects payload to contain the modified and/or additional
247 | fields of the rule and the existing rule values will be overwritten by the
248 | modified portions. Unspecified keys will be retained. Keys set to `null`
249 | will be removed. For a field reference see ["Create rule"](#create-rule).
250 |
251 | Returns status 200 on successful update, 400 if the `name` property in the
252 | payload does not match the corresponding value in the resource URI, or 404 if
253 | there is no rule with the specified name.
254 |
255 | Special case:
256 |
257 | | Field | Value | Description |
258 | | --- | --- | --- |
259 | | `action` | `"rerun"` | rerun rule (`onetime` rule only), and rule record is not updated |
260 |
261 | ```endpoint
262 | PATCH /rules/{name}
263 | ```
264 |
265 | #### Example request
266 |
267 | ```curl
268 | $ curl --request PATCH https://example.com/rules/repeat_test \
269 | --header 'Authorization: Bearer ReplaceWithToken' \
270 | --header 'Content-Type: application/json' \
271 | --header 'Cumulus-API-Version: 2' \
272 | --data '{
273 | "name": "repeat_test",
274 | "workflow": "NewDiscoverPdrs",
275 | "meta": {
276 | "additionalKey": "additionalKeyValue"
277 | },
278 | "state": "ENABLED"
279 | }'
280 | ```
281 |
282 | #### Example successful response
283 |
284 | ```json
285 | {
286 | "name": "repeat_test",
287 | "workflow": "NewDiscoverPdrs",
288 | "collection": {
289 | "name": "AST_L1A",
290 | "version": "003"
291 | },
292 | "updatedAt": 1521755265130,
293 | "createdAt": 1510903518741,
294 | "provider": "local",
295 | "rule": {
296 | "type": "scheduled",
297 | "value": "rate(5 minutes)"
298 | },
299 | "meta": {
300 | "publish": false,
301 | "additionalKey": "additionalKeyValue"
302 | },
303 | "state": "ENABLED"
304 | }
305 | ```
306 |
307 | #### Rerun request (`onetime`-rule special case)
308 |
309 | ```curl
310 | $ curl --request PATCH https://example.com/rules/my_onetime_rule \
311 | --header 'Authorization: Bearer ReplaceWithToken' \
312 | --header 'Content-Type: application/json' \
313 | --header 'Cumulus-API-Version: 2' \
314 | --data '{"action": "rerun"}'
315 | ```
316 |
317 | ## Delete rule
318 |
319 | Delete a rule from Cumulus.
320 |
321 | ```endpoint
322 | DELETE /rules/{name}
323 | ```
324 |
325 | #### Example request
326 |
327 | ```curl
328 | $ curl --request DELETE https://example.com/rules/repeat_test --header 'Authorization: Bearer ReplaceWithTheToken'
329 |
330 | ```
331 |
332 | #### Example response
333 |
334 | ```json
335 | {
336 | "message": "Record deleted"
337 | }
338 | ```
339 |
--------------------------------------------------------------------------------
/content/logs.md:
--------------------------------------------------------------------------------
1 | ## List logs
2 |
3 | **Note:** This endpoint will only work if logs are being delivered to the Metrics system. Otherwise it will
4 | return a 400 Error.
5 |
6 | List processing logs from the Cumulus engine. A log's `level` field should be specified by their string value and be one of:
7 | * fatal (60)
8 | * error (50)
9 | * warn (40)
10 | * info (30)
11 | * debug (20)
12 | * trace (10)
13 |
14 | ```endpoint
15 | GET /logs
16 | ```
17 |
18 | #### Example request
19 |
20 | ```curl
21 | $ curl https://example.com/logs?limit=5 --header 'Authorization: Bearer ReplaceWithTheToken'
22 | ```
23 |
24 | #### Example response
25 |
26 | ```json
27 | {
28 | "meta": {
29 | "name": "cumulus-api",
30 | "stack": "lpdaac-cumulus",
31 | "table": "logs",
32 | "limit": 5,
33 | "page": 1,
34 | "count": 750
35 | },
36 | "results": [
37 | {
38 | "pid": 1,
39 | "hostname": "ip-10-29-4-186",
40 | "name": "cumulus",
41 | "level": 50,
42 | "msg": "https://ba008ffc.ngrok.io/ not found",
43 | "file": "discover-pdrs/index.js",
44 | "type": "Error",
45 | "stack": "HostNotFound: https://ba008ffc.ngrok.io/ not found\n at discover.discover.then.catch.e (/var/task/index.js:9006:22)\n at process._tickDomainCallback (internal/process/next_tick.js:135:7)",
46 | "message": "https://ba008ffc.ngrok.io/ not found",
47 | "v": 1,
48 | "timestamp": 1513881407867
49 | },
50 | {
51 | "pid": 1,
52 | "hostname": "ip-10-29-4-186",
53 | "name": "cumulus",
54 | "level": 50,
55 | "file": "discover-pdrs/index.js",
56 | "message": "Received a 404 error from undefined. Check your endpoint!",
57 | "details": {
58 | "host": "ba008ffc.ngrok.io",
59 | "path": "/",
60 | "port": "",
61 | "protocol": "https",
62 | "uriPath": "/",
63 | "url": "https://ba008ffc.ngrok.io/",
64 | "depth": 1,
65 | "fetched": true,
66 | "status": "notfound",
67 | "stateData": {
68 | "requestLatency": 66,
69 | "requestTime": 66,
70 | "contentLength": 34,
71 | "contentType": "text/plain",
72 | "code": 404,
73 | "headers": {
74 | "content-length": "34",
75 | "connection": "close",
76 | "content-type": "text/plain"
77 | }
78 | },
79 | "id": 0
80 | },
81 | "v": 1,
82 | "timestamp": 1513881407867
83 | },
84 | {
85 | "pid": 1,
86 | "hostname": "ip-10-29-4-186",
87 | "name": "cumulus",
88 | "level": 50,
89 | "msg": "Cannot read property 'provider_path' of undefined",
90 | "file": "discover-pdrs/index.js",
91 | "type": "Error",
92 | "stack": "TypeError: Cannot read property 'provider_path' of undefined\n at HttpDiscover.Discover (/var/task/index.js:10098:33)\n at HttpDiscover._class (/var/task/index.js:96368:255)\n at new HttpDiscover (/var/task/index.js:10342:241)\n at handler (/var/task/index.js:8968:23)\n at Promise (/var/task/cumulus-sled/index.js:82:5)\n at invokeHandler (/var/task/cumulus-sled/index.js:72:10)\n at then.then.then (/var/task/cumulus-sled/index.js:112:14)\n at process._tickDomainCallback (internal/process/next_tick.js:135:7)",
93 | "v": 1,
94 | "timestamp": 1513881031694
95 | },
96 | {
97 | "pid": 1,
98 | "hostname": "ip-10-29-4-186",
99 | "name": "cumulus",
100 | "level": 50,
101 | "msg": "Provider info not provided",
102 | "file": "discover-pdrs/index.js",
103 | "type": "Error",
104 | "stack": "ProviderNotFound: Provider info not provided\n at handler (/var/task/index.js:8962:20)\n at Promise (/var/task/cumulus-sled/index.js:82:5)\n at invokeHandler (/var/task/cumulus-sled/index.js:72:10)\n at then.then.then (/var/task/cumulus-sled/index.js:112:14)\n at process._tickDomainCallback (internal/process/next_tick.js:135:7)",
105 | "message": "Provider info not provided",
106 | "v": 1,
107 | "timestamp": 1513879654040
108 | },
109 | {
110 | "pid": 1,
111 | "hostname": "ip-10-29-4-186",
112 | "name": "cumulus",
113 | "level": 50,
114 | "msg": "Provider info not provided",
115 | "file": "discover-pdrs/index.js",
116 | "type": "Error",
117 | "stack": "ProviderNotFound: Provider info not provided\n at handler (/var/task/index.js:8962:20)\n at Promise (/var/task/cumulus-sled/index.js:82:5)\n at invokeHandler (/var/task/cumulus-sled/index.js:72:10)\n at then.then.then (/var/task/cumulus-sled/index.js:112:14)\n at process._tickDomainCallback (internal/process/next_tick.js:135:7)",
118 | "message": "Provider info not provided",
119 | "v": 1,
120 | "timestamp": 1513879435010
121 | }
122 | ]
123 | }
124 | ```
125 |
126 | #### Example request for errors
127 |
128 | ```curl
129 | $ curl https://example.com/logs?level=error --header 'Authorization: Bearer ReplaceWithTheToken'
130 | ```
131 |
132 | #### Example response for errors
133 |
134 | ```json
135 | {
136 | "meta": {
137 | "name": "cumulus-api",
138 | "stack": "lpdaac-cumulus",
139 | "table": "logs",
140 | "limit": 1,
141 | "page": 1,
142 | "count": 181
143 | },
144 | "results": [
145 | {
146 | "level": 50,
147 | "msg": "Unexpected HTTP status code: 404",
148 | "pid": 1,
149 | "hostname": "ip-10-26-125-174",
150 | "name": "cumulus",
151 | "file": "sync-granule/index.js",
152 | "type": "Error",
153 | "stack": "Error: Unexpected HTTP status code: 404\n at ClientRequest. (/var/task/sync-granule/index.js:125136:29)\n at ClientRequest.g (events.js:292:16)\n at emitOne (events.js:96:13)\n at ClientRequest.emit (events.js:188:7)\n at HTTPParser.parserOnIncomingClient (_http_client.js:473:21)\n at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)\n at TLSSocket.socketOnData (_http_client.js:362:20)\n at emitOne (events.js:96:13)\n at TLSSocket.emit (events.js:188:7)\n at readableAddChunk (_stream_readable.js:176:18)",
154 | "code": 404,
155 | "v": 1,
156 | "timestamp": 1515446810226
157 | }
158 | ]
159 | }
160 | ```
161 |
162 | ## Retrieve Logs
163 |
164 | **Note:** This endpoint will only work if logs are being delivered to the Metrics system. Otherwise it will
165 | return a 400 Error.
166 |
167 | Retrieve all logs from a specific execution.
168 |
169 | ```endpoint
170 | GET /logs/{executionName}
171 | ```
172 |
173 | #### Example request
174 |
175 | ```curl
176 | $ curl https://example.com/logs/93e5e049-89aa-47e5-900d-0eec87327260?limit=5 --header 'Authorization: Bearer ReplaceWithTheToken'
177 | ```
178 |
179 | #### Example response
180 |
181 | ```json
182 | {
183 | "meta": {
184 | "name": "cumulus-api",
185 | "stack": "test-src-integration",
186 | "table": "logs",
187 | "limit": 5,
188 | "page": 1,
189 | "count": 10
190 | },
191 | "results": [
192 | {
193 | "level": 30,
194 | "executions": "93e5e049-89aa-47e5-900d-0eec87327260",
195 | "timestamp": "2018-08-15T19:23:57.752Z",
196 | "sender": "test-src-integration-PostToCmr",
197 | "version": "$LATEST",
198 | "message": "Published MOD09GQ.A8009365.7JQhni.006.6594428626875 to the CMR. conceptId: G1223210348-CUMULUS",
199 | "RequestId": "05712fb1-5593-4640-b5a3-a99db41d8003"
200 | },
201 | {
202 | "level": 30,
203 | "executions": "93e5e049-89aa-47e5-900d-0eec87327260",
204 | "timestamp": "2018-08-15T19:23:42.054Z",
205 | "sender": "test-src-integration-SyncGranuleNoVpc",
206 | "version": "$LATEST",
207 | "message": "uploaded s3://cumulus-test-sandbox-internal/file-staging/test-src-integration/MOD09GQ___006/MOD09GQ.A8009365.7JQhni.006.6594428626875.hdf",
208 | "RequestId": "a20698f3-a9a1-4e64-acbf-09ef77827fbc"
209 | },
210 | {
211 | "level": 30,
212 | "executions": "93e5e049-89aa-47e5-900d-0eec87327260",
213 | "timestamp": "2018-08-15T19:23:41.913Z",
214 | "sender": "test-src-integration-SyncGranuleNoVpc",
215 | "version": "$LATEST",
216 | "message": "Finishing downloading s3://cumulus-test-sandbox-internal/cumulus-test-data/pdrs/MOD09GQ.A8009365.7JQhni.006.6594428626875.hdf",
217 | "RequestId": "a20698f3-a9a1-4e64-acbf-09ef77827fbc"
218 | },
219 | {
220 | "level": 30,
221 | "executions": "93e5e049-89aa-47e5-900d-0eec87327260",
222 | "timestamp": "2018-08-15T19:23:41.888Z",
223 | "sender": "test-src-integration-SyncGranuleNoVpc",
224 | "version": "$LATEST",
225 | "message": "uploaded s3://cumulus-test-sandbox-internal/file-staging/test-src-integration/MOD09GQ___006/MOD09GQ.A8009365.7JQhni.006.6594428626875_ndvi.jpg",
226 | "RequestId": "a20698f3-a9a1-4e64-acbf-09ef77827fbc"
227 | },
228 | {
229 | "level": 30,
230 | "executions": "93e5e049-89aa-47e5-900d-0eec87327260",
231 | "timestamp": "2018-08-15T19:23:41.886Z",
232 | "sender": "test-src-integration-SyncGranuleNoVpc",
233 | "version": "$LATEST",
234 | "message": "uploaded s3://cumulus-test-sandbox-internal/file-staging/test-src-integration/MOD09GQ___006/MOD09GQ.A8009365.7JQhni.006.6594428626875.hdf.met",
235 | "RequestId": "a20698f3-a9a1-4e64-acbf-09ef77827fbc"
236 | }
237 | ]
238 | }
239 | ```
240 |
--------------------------------------------------------------------------------
/api-client-py/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------