Merge pull request #2562 from spotify/rugvip/api

backend: change the default backend plugin mount point to /api
This commit is contained in:
Patrik Oldsberg
2020-09-24 15:58:12 +02:00
committed by GitHub
22 changed files with 68 additions and 60 deletions
+4
View File
@@ -12,6 +12,10 @@ If you encounter issues while upgrading to a newer version, don't hesitate to re
- Renamed `SessionStateApi` to `SessionApi` and `logout` to `signOut`. Custom implementations of the `SingInPage` app-component will need to rename their `logout` function. The different auth provider items for the `UserSettingsMenu` have been consolidated into a single `ProviderSettingsItem`, meaning you need to replace existing usages of `OAuthProviderSettings` and `OIDCProviderSettings`. [#2555](https://github.com/spotify/backstage/pull/2555).
### @backstage/auth-backend
- The default mount path of backend plugins was changed to `/api/:pluginId`, and as part of that it was needed to enable configuration of the base path of the auth backend, so that it can construct redirect URLs correctly. The default base path is `/api/auth`, but you need to set this to `/auth` if you want to keep using the old path. Note that you will also need to reconfigure any allowed redirect URLs to include `/api` if you switch to the new recommended pattern. [#2562](https://github.com/spotify/backstage/pull/2562)
## v0.1.1-alpha.22
### @backstage/core
+2 -2
View File
@@ -33,8 +33,8 @@ organization:
name: Spotify
techdocs:
storageUrl: http://localhost:7000/techdocs/static/docs
requestUrl: http://localhost:7000/techdocs/docs
storageUrl: http://localhost:7000/api/techdocs/static/docs
requestUrl: http://localhost:7000/api/techdocs/docs
generators:
techdocs: 'docker'
+4 -3
View File
@@ -229,9 +229,10 @@ name.
### Test the new provider
You can `curl -i localhost:7000/auth/providerA/start` and which should provide a
`302` redirect with a `Location` header. Paste the url from that header into a
web browser and you should be able to trigger the authorization flow.
You can `curl -i localhost:7000/api/auth/providerA/start` and which should
provide a `302` redirect with a `Location` header. Paste the url from that
header into a web browser and you should be able to trigger the authorization
flow.
---
@@ -88,7 +88,7 @@ running:
```sh
curl \
--location \
--request POST 'localhost:7000/catalog/locations' \
--request POST 'localhost:7000/api/catalog/locations' \
--header 'Content-Type: application/json' \
--data-raw "{\"type\": \"file\", \"target\": \"${YOUR PATH HERE}/template.yaml\"}"
```
@@ -98,7 +98,7 @@ If loading from a Git location, you can run the following
```sh
curl \
--location \
--request POST 'localhost:7000/catalog/locations' \
--request POST 'localhost:7000/api/catalog/locations' \
--header 'Content-Type: application/json' \
--data-raw "{\"type\": \"github\", \"target\": \"https://${YOUR GITHUB REPO}blob/master/${PATH TO FOLDER}/template.yaml\"}"
```
+2 -2
View File
@@ -57,8 +57,8 @@ The default storage and request URLs:
```yaml
techdocs:
storageUrl: http://localhost:7000/techdocs/static/docs
requestUrl: http://localhost:7000/techdocs/docs
storageUrl: http://localhost:7000/api/techdocs/static/docs
requestUrl: http://localhost:7000/api/techdocs/docs
```
If you want `techdocs-backend` to manage building and publishing, you want
+3 -3
View File
@@ -6,10 +6,10 @@ info:
**Provided by `@backstage/auth-backend`.**
The purpose of the Auth APIs in Backstage are to identify the user, and to provide a way for plugins
The purpose of the Auth APIs in Backstage are to identify the user, and to provide a way for plugins
to request access to 3rd party services on behalf of that user.
The API is supplied with a list of providers - such as `Google` or `Github` - and will add the endpoints
The API is supplied with a list of providers - such as `Google` or `Github` - and will add the endpoints
described below to each of those providers.
Read more about [User Authentication and Authorization in Backstage](https://github.com/spotify/backstage/blob/master/docs/auth/overview.md).
@@ -21,7 +21,7 @@ externalDocs:
description: Backstage official documentation
url: https://github.com/spotify/backstage/blob/master/docs/README.md
servers:
- url: http://localhost:7000/auth/
- url: http://localhost:7000/api/auth/
tags:
- name: provider
description: List of endpoints per provider
+1 -1
View File
@@ -115,7 +115,7 @@ export AUTH_GITHUB_CLIENT_SECRET=xxx
> Log into http://github.com
> Navigate to (Settings > Developer Settings > OAuth Apps > New OAuth App)[https://github.com/settings/applications/new]
> Set Homepage URL = http://localhost:3000
> Set Callback URL = http://localhost:7000/auth/github
> Set Callback URL = http://localhost:7000/api/auth/github
> Click [Register application]
> On the next page, copy and paste your new Client ID and Client Secret to the environment variables above, `AUTH_GITHUB_CLIENT_ID` & `AUTH_GITHUB_CLIENT_SECRET`
> Don't forget to `source` that profile file again if necessary.
+1 -1
View File
@@ -31,7 +31,7 @@ describe('App', () => {
baseUrl: 'http://localhost:3003',
},
techdocs: {
storageUrl: 'http://localhost:7000/techdocs/static/docs',
storageUrl: 'http://localhost:7000/api/techdocs/static/docs',
},
},
context: 'test',
-12
View File
@@ -16,11 +16,8 @@
import {
errorApiRef,
discoveryApiRef,
UrlPatternDiscovery,
githubAuthApiRef,
createApiFactory,
configApiRef,
} from '@backstage/core';
import {
@@ -38,15 +35,6 @@ import {
} from '@roadiehq/backstage-plugin-github-pull-requests';
export const apis = [
// TODO(Rugvip): migrate to use /api
createApiFactory({
api: discoveryApiRef,
deps: { configApi: configApiRef },
factory: ({ configApi }) =>
UrlPatternDiscovery.compile(
`${configApi.getString('backend.baseUrl')}/{{ pluginId }}`,
),
}),
createApiFactory({
api: graphQlBrowseApiRef,
deps: { errorApi: errorApiRef, githubAuthApi: githubAuthApiRef },
+1
View File
@@ -37,6 +37,7 @@
"dockerode": "^3.2.0",
"example-app": "^0.1.1-alpha.23",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
"knex": "^0.21.1",
"pg": "^8.3.0",
"pg-connection-string": "^2.3.0",
+16 -10
View File
@@ -22,12 +22,14 @@
* Happy hacking!
*/
import Router from 'express-promise-router';
import {
createDatabaseClient,
createServiceBuilder,
loadBackendConfig,
getRootLogger,
useHotMemoize,
notFoundHandler,
} from '@backstage/backend-common';
import { ConfigReader, AppConfig } from '@backstage/config';
import healthcheck from './plugins/healthcheck';
@@ -78,19 +80,23 @@ async function main() {
const graphqlEnv = useHotMemoize(module, () => createEnv('graphql'));
const appEnv = useHotMemoize(module, () => createEnv('app'));
const apiRouter = Router();
apiRouter.use('/catalog', await catalog(catalogEnv));
apiRouter.use('/rollbar', await rollbar(rollbarEnv));
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
apiRouter.use('/sentry', await sentry(sentryEnv));
apiRouter.use('/auth', await auth(authEnv, '/api/auth'));
apiRouter.use('/identity', await identity(identityEnv));
apiRouter.use('/techdocs', await techdocs(techdocsEnv));
apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv));
apiRouter.use('/proxy', await proxy(proxyEnv, '/api/proxy'));
apiRouter.use('/graphql', await graphql(graphqlEnv));
apiRouter.use(notFoundHandler());
const service = createServiceBuilder(module)
.loadConfig(configReader)
.addRouter('', await healthcheck(healthcheckEnv))
.addRouter('/catalog', await catalog(catalogEnv))
.addRouter('/rollbar', await rollbar(rollbarEnv))
.addRouter('/scaffolder', await scaffolder(scaffolderEnv))
.addRouter('/sentry', await sentry(sentryEnv))
.addRouter('/auth', await auth(authEnv))
.addRouter('/identity', await identity(identityEnv))
.addRouter('/techdocs', await techdocs(techdocsEnv))
.addRouter('/kubernetes', await kubernetes(kubernetesEnv))
.addRouter('/proxy', await proxy(proxyEnv, '/proxy'))
.addRouter('/graphql', await graphql(graphqlEnv))
.addRouter('/api', apiRouter)
.addRouter('', await app(appEnv));
await service.start().catch(err => {
+5 -6
View File
@@ -17,10 +17,9 @@
import { createRouter } from '@backstage/plugin-auth-backend';
import { PluginEnvironment } from '../types';
export default async function createPlugin({
logger,
database,
config,
}: PluginEnvironment) {
return await createRouter({ logger, config, database });
export default async function createPlugin(
{ logger, database, config }: PluginEnvironment,
basePath: string,
) {
return await createRouter({ logger, config, database, basePath });
}
@@ -44,8 +44,8 @@ proxy:
changeOrigin: true
techdocs:
storageUrl: http://localhost:7000/techdocs/static/docs
requestUrl: http://localhost:7000/techdocs/docs
storageUrl: http://localhost:7000/api/techdocs/static/docs
requestUrl: http://localhost:7000/api/techdocs/docs
generators:
techdocs: 'docker'
@@ -12,7 +12,7 @@ describe('App', () => {
app: { title: 'Test' },
backend: { baseUrl: 'http://localhost:7000' },
techdocs: {
storageUrl: 'http://localhost:7000/techdocs/static/docs',
storageUrl: 'http://localhost:7000/api/techdocs/static/docs',
},
},
context: 'test',
@@ -31,6 +31,7 @@
"@gitbeaker/node": "^23.5.0",
"dockerode": "^3.2.0",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
"knex": "^0.21.1",
{{#if dbTypePG}}
"pg": "^8.3.0",
@@ -6,12 +6,14 @@
* Happy hacking!
*/
import Router from 'express-promise-router';
import {
createDatabaseClient,
createServiceBuilder,
loadBackendConfig,
getRootLogger,
useHotMemoize,
notFoundHandler,
} from '@backstage/backend-common';
import { ConfigReader, AppConfig } from '@backstage/config';
import auth from './plugins/auth';
@@ -51,14 +53,18 @@ async function main() {
const proxyEnv = useHotMemoize(module, () => createEnv('proxy'));
const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs'));
const apiRouter = Router();
apiRouter.use('/catalog', await catalog(catalogEnv))
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv))
apiRouter.use('/auth', await auth(authEnv))
apiRouter.use('/identity', await identity(identityEnv))
apiRouter.use('/techdocs', await techdocs(techdocsEnv))
apiRouter.use('/proxy', await proxy(proxyEnv, '/api/proxy'))
apiRouter.use(notFoundHandler());
const service = createServiceBuilder(module)
.loadConfig(configReader)
.addRouter('/catalog', await catalog(catalogEnv))
.addRouter('/scaffolder', await scaffolder(scaffolderEnv))
.addRouter('/auth', await auth(authEnv))
.addRouter('/identity', await identity(identityEnv))
.addRouter('/techdocs', await techdocs(techdocsEnv))
.addRouter('/proxy', await proxy(proxyEnv, '/proxy'));
.addRouter('/api', apiRouter)
await service.start().catch(err => {
console.log(err);
+1 -1
View File
@@ -391,7 +391,7 @@ async function testBackendStart(appDir: string, isPostgres: boolean) {
print('Try to fetch entities from the backend');
// Try fetch entities, should be ok
await fetch('http://localhost:7000/catalog/entities').then(res =>
await fetch('http://localhost:7000/api/catalog/entities').then(res =>
res.json(),
);
print('Entities fetched successfully');
+3 -3
View File
@@ -34,7 +34,7 @@ Follow this link, [Create new OAuth App](https://github.com/settings/application
1. Set Application Name to `backstage-dev` or something along those lines.
1. You can set the Homepage URL to whatever you want to.
1. The Authorization Callback URL should match the redirect URI set in Backstage.
1. Set this to `http://localhost:7000/auth/github` for local development.
1. Set this to `http://localhost:7000/api/auth/github` for local development.
1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/auth/github` for non-local deployments.
```bash
@@ -78,14 +78,14 @@ export AUTH_AUTH0_CLIENT_SECRET=x
#### Creating an Azure AD App Registration
An Azure AD App Registration is required to be able to sign in using Azure AD and the Microsoft Graph API.
An Azure AD App Registration is required to be able to sign in using Azure AD and the Microsoft Graph API.
Click [here](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps) to create a new one.
- Click on the `New Registration` button.
- Give the app a name. e.g. `backstage-dev`
- Select `Accounts in this organizational directory only` under supported account types.
- Enter the callback URL for your backstage backend instance:
- For local development, this is likely `http://localhost:7000/auth/microsoft/handler/frame`
- For local development, this is likely `http://localhost:7000/api/auth/microsoft/handler/frame`
- For non-local deployments, this will be `https://{APP_FQDN}:{APP_BACKEND_PORT}/auth/microsoft/handler/frame`
- Click `Register`.
@@ -18,4 +18,4 @@ fi
echo "Downloading and starting SAML-IdP"
export NPM_CONFIG_REGISTRY=https://registry.npmjs.org
exec npx saml-idp --acsUrl "http://localhost:7000/auth/saml/handler/frame" --audience "http://localhost:7000" --port 7001
exec npx saml-idp --acsUrl "http://localhost:7000/api/auth/saml/handler/frame" --audience "http://localhost:7000" --port 7001
+3 -1
View File
@@ -28,6 +28,7 @@ export interface RouterOptions {
logger: Logger;
database: Knex;
config: Config;
basePath?: string;
}
export async function createRouter(
@@ -38,7 +39,8 @@ export async function createRouter(
const appUrl = options.config.getString('app.baseUrl');
const backendUrl = options.config.getString('backend.baseUrl');
const authUrl = `${backendUrl}/auth`;
// TODO(Rugvip): Replace with service discovery of external URL
const authUrl = backendUrl + (options.basePath ?? '/api/auth');
const keyDurationSeconds = 3600;
+2 -2
View File
@@ -18,11 +18,11 @@ yarn start
## What techdocs-backend does
This plugin is the backend part of the techdocs plugin. It provides building and serving of your docs without having to use another service and hosting provider. To use it set your techdocs storageUrl in your `app-config.yml` to `http://localhost:7000/techdocs/static/docs`.
This plugin is the backend part of the techdocs plugin. It provides building and serving of your docs without having to use another service and hosting provider. To use it set your techdocs storageUrl in your `app-config.yml` to `http://localhost:7000/api/techdocs/static/docs`.
```yaml
techdocs:
storageUrl: http://localhost:7000/techdocs/static/docs
storageUrl: http://localhost:7000/api/techdocs/static/docs
```
## Extending techdocs-backend
@@ -64,7 +64,7 @@ export class LocalPublish implements PublisherBase {
}
resolve({
remoteUrl: `http://localhost:7000/techdocs/static/docs/${entity.metadata.name}`,
remoteUrl: `http://localhost:7000/api/techdocs/static/docs/${entity.metadata.name}`,
});
});
});