mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
feat: First draft of admin Open API specification (OAS) (#652)
Co-authored-by: Ivar Conradi Østhus <ivarconr@gmail.com>
This commit is contained in:
parent
abc93d55da
commit
c7c2f17bd0
18
.github/workflows/readme.yaml
vendored
Normal file
18
.github/workflows/readme.yaml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: Sync OAS to ReadMe
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: readmeio/github-readme-sync@v2
|
||||
with:
|
||||
readme-oas-key: oDf7vsdkbfuFmj6M7E5W98QcmyBnLpmM:5fc4b9a323e95041cd0a08fb
|
||||
|
||||
# OPTIONAL CONFIG, use if necessary
|
||||
# oas-file-path: './swagger.json'
|
||||
# api-version: 'v1.0.0'
|
BIN
docs/api/oas/favicon-16x16.png
Normal file
BIN
docs/api/oas/favicon-16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 665 B |
BIN
docs/api/oas/favicon-32x32.png
Normal file
BIN
docs/api/oas/favicon-32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 628 B |
76
docs/api/oas/index.html
Normal file
76
docs/api/oas/index.html
Normal file
@ -0,0 +1,76 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Unleash Open API</title>
|
||||
<link rel="stylesheet" href="theme-material.css">
|
||||
<!-- Material design styles from ostranme.github.io/swagger-ui-themes
|
||||
Original follows
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" > -->
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.topbar-wrapper img {
|
||||
content: url(https://unleash.github.io/img/logo-inverted.png);
|
||||
}
|
||||
|
||||
.swagger-ui .topbar .download-url-wrapper .download-url-button {
|
||||
background-color: #3f51b5 !important;
|
||||
}
|
||||
|
||||
.swagger-ui .topbar .download-url-wrapper input[type=text] {
|
||||
border-color: #3f51b5 !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "openapi.yaml",
|
||||
dom_id: '#swagger-ui',
|
||||
defaultModelsExpandDepth: -1,
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
74
docs/api/oas/oauth2-redirect.html
Normal file
74
docs/api/oas/oauth2-redirect.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Swagger UI: OAuth2 Redirect</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
}
|
||||
) : {}
|
||||
|
||||
isValid = qp.state === sentState
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
</script>
|
1335
docs/api/oas/openapi.yaml
Normal file
1335
docs/api/oas/openapi.yaml
Normal file
File diff suppressed because it is too large
Load Diff
24
docs/api/oas/redoc.html
Normal file
24
docs/api/oas/redoc.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ReDoc</title>
|
||||
<!-- needed for adaptive design -->
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
|
||||
|
||||
<!--
|
||||
ReDoc doesn't change outer page styles
|
||||
-->
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<redoc spec-url='openapi.yaml'></redoc>
|
||||
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>
|
||||
</body>
|
||||
</html>
|
3
docs/api/oas/swagger-ui-bundle.js
Normal file
3
docs/api/oas/swagger-ui-bundle.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/api/oas/swagger-ui-bundle.js.map
Normal file
1
docs/api/oas/swagger-ui-bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
3
docs/api/oas/swagger-ui-es-bundle-core.js
Normal file
3
docs/api/oas/swagger-ui-es-bundle-core.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/api/oas/swagger-ui-es-bundle-core.js.map
Normal file
1
docs/api/oas/swagger-ui-es-bundle-core.js.map
Normal file
File diff suppressed because one or more lines are too long
3
docs/api/oas/swagger-ui-es-bundle.js
Normal file
3
docs/api/oas/swagger-ui-es-bundle.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/api/oas/swagger-ui-es-bundle.js.map
Normal file
1
docs/api/oas/swagger-ui-es-bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
3
docs/api/oas/swagger-ui-standalone-preset.js
Normal file
3
docs/api/oas/swagger-ui-standalone-preset.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/api/oas/swagger-ui-standalone-preset.js.map
Normal file
1
docs/api/oas/swagger-ui-standalone-preset.js.map
Normal file
File diff suppressed because one or more lines are too long
4
docs/api/oas/swagger-ui.css
Normal file
4
docs/api/oas/swagger-ui.css
Normal file
File diff suppressed because one or more lines are too long
1
docs/api/oas/swagger-ui.css.map
Normal file
1
docs/api/oas/swagger-ui.css.map
Normal file
File diff suppressed because one or more lines are too long
3
docs/api/oas/swagger-ui.js
Normal file
3
docs/api/oas/swagger-ui.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/api/oas/swagger-ui.js.map
Normal file
1
docs/api/oas/swagger-ui.js.map
Normal file
File diff suppressed because one or more lines are too long
1676
docs/api/oas/swagger.json
Normal file
1676
docs/api/oas/swagger.json
Normal file
File diff suppressed because it is too large
Load Diff
1719
docs/api/oas/theme-material.css
Normal file
1719
docs/api/oas/theme-material.css
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,43 +5,90 @@ title: Getting Started
|
||||
|
||||
## Requirements
|
||||
|
||||
You will need **Node.js** >= 12 and a **PostgreSQL** >= 10 database instance to be able to run Unleash.
|
||||
You will need:
|
||||
|
||||
When starting Unleash you must specify a database URI (can be set as environment variable DATABASE_URL) which includes a username and password, that have rights to migrate the database.
|
||||
- [**Node.js**](https://nodejs.org/en/download/) (version 12 or later)
|
||||
- [**PostgreSQL**](https://www.postgresql.org/download/) (version 10 or later)
|
||||
- [Create an unleash user and database](./developer-guide.md).
|
||||
|
||||
On startup _Unleash_ will perform necessary migrations if needed.
|
||||
## Start Unleash server
|
||||
|
||||
## Start Unleash
|
||||
|
||||
### 1. The simplest way to get started:
|
||||
|
||||
```bash
|
||||
$ npm install unleash-server -g
|
||||
$ unleash -d postgres://unleash_user:password@localhost:5432/unleash -p 4242
|
||||
Whichever option you choose to start Unleash, you must specify a database URI (it can be set in the environment variable DATABASE_URL).
|
||||
|
||||
Once the server has started, you will see the message:
|
||||
```
|
||||
Unleash started on http://localhost:4242
|
||||
```
|
||||
|
||||
### 2. Or programmatically:
|
||||
### Option one - from a terminal/bash shell
|
||||
|
||||
You can also depend on unleash
|
||||
|
||||
```js
|
||||
const unleash = require('unleash-server');
|
||||
|
||||
unleash
|
||||
.start({
|
||||
databaseUrl: 'postgres://unleash_user:password@localhost:5432/unleash',
|
||||
port: 4242,
|
||||
})
|
||||
.then(unleash => {
|
||||
console.log(
|
||||
`Unleash started on http://localhost:${unleash.app.get('port')}`,
|
||||
);
|
||||
});
|
||||
```
|
||||
npm install unleash-server -g
|
||||
unleash -d postgres://unleash_user:password@localhost:5432/unleash -p 4242
|
||||
```
|
||||
|
||||
Available unleash options include:
|
||||
### Option two - from Node.js
|
||||
|
||||
1. Create a new folder/directory on your development computer.
|
||||
2. From a terminal/bash shell, install the dependencies:
|
||||
|
||||
```
|
||||
npm init
|
||||
npm install unleash-server --save
|
||||
```
|
||||
|
||||
3. Create a file called *server.js*, paste the following into it and save.
|
||||
```js
|
||||
const unleash = require('unleash-server');
|
||||
|
||||
unleash
|
||||
.start({
|
||||
databaseUrl: 'postgres://unleash_user:password@localhost:5432/unleash',
|
||||
port: 4242,
|
||||
})
|
||||
.then(unleash => {
|
||||
console.log(
|
||||
`Unleash started on http://localhost:${unleash.app.get('port')}`,
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
4. Run *server.js*:
|
||||
```
|
||||
node server.js
|
||||
```
|
||||
|
||||
### Option three - use Docker
|
||||
|
||||
Launch the [Unleash server Docker image](https://hub.docker.com/r/unleashorg/unleash-server/).
|
||||
|
||||
```
|
||||
docker run -d -e DATABASE_URL=postgres://user:pass@10.200.221.11:5432/unleash unleashorg/unleash-server
|
||||
```
|
||||
|
||||
## Test your server and create a sample API call
|
||||
|
||||
Once the Unleash server has started, go to [localhost:4242](http://localhost:4242) in your browser. If you see a list of example feature toggles, try modifying one of them with [curl](https://curl.se/) from a terminal/bash shell:
|
||||
|
||||
~~~
|
||||
curl --location --request PUT 'http://localhost:4242/api/admin/features/Feature.A' --header 'Content-Type: application/json' --data-raw '{\
|
||||
"name": "Feature.A",\
|
||||
"description": "Dolor sit amet.",\
|
||||
"type": "release",\
|
||||
"enabled": false,\
|
||||
"stale": false,\
|
||||
"strategies": [\
|
||||
{\
|
||||
"name": "default",\
|
||||
"parameters": {}\
|
||||
}\
|
||||
]\
|
||||
}'\
|
||||
~~~
|
||||
<!-- The following doesn't seem to fit the 'remit' of Getting started'. it would be a better fit in the developer section of the documentation -->
|
||||
## Unleash server options
|
||||
|
||||
Available Unleash options include:
|
||||
|
||||
- **db** - The database configuration object taking the following properties:
|
||||
- _user_ - the database username (`DATABASE_USERNAME`)
|
||||
@ -70,9 +117,9 @@ Available unleash options include:
|
||||
- **baseUriPath** (string) - use to register a base path for all routes on the application. For example `/my/unleash/base` (note the starting /). Defaults to `/`. Can also be configured through the environment variable `BASE_URI_PATH`.
|
||||
- **secureHeaders** (boolean) - use this to enable security headers (HSTS, CSP, etc) when serving Unleash from HTTPS. Can also be configured through the environment variable `SECURE_HEADERS`.
|
||||
|
||||
#### Disabling Auto-Start
|
||||
### Disabling Auto-Start
|
||||
|
||||
If you're using unleash as part of a larger express app, you can disable the automatic server start by calling `server.create`. It takes the same options as `sevrer.start`, but will not begin listening for connections.
|
||||
If you're using Unleash as part of a larger express app, you can disable the automatic server start by calling `server.create`. It takes the same options as `sevrer.start`, but will not begin listening for connections.
|
||||
|
||||
```js
|
||||
const unleash = require('unleash-server');
|
||||
@ -89,17 +136,9 @@ unleash
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Docker
|
||||
|
||||
You can also use the [hosted docker image](https://hub.docker.com/r/unleashorg/unleash-server/) to start the Unleash server
|
||||
|
||||
```sh
|
||||
docker run -d -e DATABASE_URL=postgres://user:pass@10.200.221.11:5432/unleash unleashorg/unleash-server
|
||||
```
|
||||
|
||||
## Securing Unleash
|
||||
|
||||
Unleash also have extension points where you can integrate Unleash with your authentication provider (OAuth 2.0). Read more about [securing unleash](./securing-unleash.md).
|
||||
You can integrate Unleash with your authentication provider (OAuth 2.0). Read more about [securing unleash](./securing-unleash.md).
|
||||
|
||||
## How do I configure the log output?
|
||||
|
||||
|
@ -43,6 +43,10 @@ module.exports = function(config) {
|
||||
app.use(baseUriPath, express.static(config.publicFolder));
|
||||
}
|
||||
|
||||
if (config.enableOAS) {
|
||||
app.use(`${baseUriPath}/oas`, express.static('docs/api/oas'));
|
||||
}
|
||||
|
||||
if (config.adminAuthentication === 'unsecure') {
|
||||
simpleAuthentication(baseUriPath, app);
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ function defaultOptions() {
|
||||
headersTimeout: 61 * 1000,
|
||||
version,
|
||||
secureHeaders: process.env.SECURE_HEADERS || false,
|
||||
enableOAS: process.env.ENABLE_OAS || false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -12,4 +12,5 @@ unleash.start({
|
||||
ssl: false,
|
||||
},
|
||||
enableRequestLogger: true,
|
||||
enableOAS: true,
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user