Merge branch 'master' into feature/EKSCatalog
Signed-off-by: Jonah Back <jonah@jonahback.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 82 KiB |
Regular → Executable
+2
-1
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 10 KiB |
Regular → Executable
+2
-1
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 18 KiB |
+179
-98
@@ -1,9 +1,113 @@
|
||||
---
|
||||
id: add-auth-provider
|
||||
title: Adding authentication providers
|
||||
description: Documentation on Adding authentication providers
|
||||
title: Contributing New Providers
|
||||
description: Documentation on adding new authentication providers
|
||||
---
|
||||
|
||||
> NOTE: The primary audience for this documentation are contributors to the main
|
||||
> Backstage project that want to add support for new authentication providers.
|
||||
> While you can follow it to implement your own custom providers it is much
|
||||
> more advanced than using our built-in providers.
|
||||
|
||||
## How Does Authentication Work?
|
||||
|
||||
The Backstage application can use various external authentication providers for
|
||||
authentication. An external provider is wrapped using an
|
||||
`AuthProviderRouteHandlers` interface for handling authentication. This
|
||||
interface consists of four methods. Each of these methods is hosted at an
|
||||
endpoint (by default) `/api/auth/[provider]/method`, where `method` performs a
|
||||
certain operation as follows:
|
||||
|
||||
```
|
||||
/auth/[provider]/start -> Initiate a login from the web page
|
||||
/auth/[provider]/handler/frame -> Handle a finished authentication operation
|
||||
/auth/[provider]/refresh -> Refresh the validity of a login
|
||||
/auth/[provider]/logout -> Log out a logged-in user
|
||||
```
|
||||
|
||||
The flow is as follows:
|
||||
|
||||
1. A user attempts to sign in.
|
||||
2. A popup window is opened, pointing to the `auth` endpoint. That endpoint does
|
||||
initial preparations and then re-directs the user to an external
|
||||
authenticator, still inside the popup.
|
||||
3. The authenticator validates the user and returns the result of the validation
|
||||
(success OR failure), to the wrapper's endpoint (`handler/frame`).
|
||||
4. The `handler/frame` rendered webpage will issue the appropriate response to
|
||||
the webpage that opened the popup window, and the popup is closed.
|
||||
5. The user signs out by clicking on a UI interface and the webpage makes a
|
||||
request to logout the user.
|
||||
|
||||
## Implementing Your Own Auth Wrapper
|
||||
|
||||
The core interface of any auth wrapper is the `AuthProviderRouteHandlers`
|
||||
interface. This interface has four methods corresponding to the API described in
|
||||
the initial section. Any auth wrapper will have to implement this interface.
|
||||
|
||||
When initiating a login, a pop-up window is created by the frontend, to allow
|
||||
the user to initiate a login. This login request is done to the `/start`
|
||||
endpoint which is handled by the `start` method.
|
||||
|
||||
The `start` method re-directs to the external auth provider who authenticates
|
||||
the request and re-directs the request to the `/frame/handler` endpoint, which
|
||||
is handled by the `frameHandler` method.
|
||||
|
||||
The `frameHandler` returns an HTML response, containing a script that does a
|
||||
`postMessage` to the frontend window, containing the result of the request.
|
||||
The `WebMessageResponse` type is the message sent by the `postMessage` to the
|
||||
frontend.
|
||||
|
||||
A `postMessageResponse` utility function wraps the logic of generating a
|
||||
`postMessage` response that ensures that CORS is successfully handled. This
|
||||
function takes an `express.Response`, a `WebMessageResponse` and the URL of the
|
||||
frontend (`appOrigin`) as parameters and return an HTML page with the script and
|
||||
the message.
|
||||
|
||||
There is a helper class for [OAuth2](https://oauth.net/2/) based authentication providers, [OAuthAdapter](../reference/plugin-auth-backend.oauthadapter.md). This class implements the `AuthProviderRouteHandlers` interface
|
||||
for you, and instead requires you to implement [OAuthHandlers](../reference/plugin-auth-backend.oauthhandlers.md), which
|
||||
is significantly easier.
|
||||
|
||||
### Auth Environment Separation
|
||||
|
||||
The concept of an `env` is core to the way the auth backend works. It uses an
|
||||
`env` query parameter to identify the environment in which the application is
|
||||
running (`development`, `staging`, `production`, etc). Each runtime can
|
||||
simultaneously support multiple environments at the same time and the right
|
||||
handler for each request is identified and dispatched to, based on the `env`
|
||||
parameter.
|
||||
|
||||
`OAuthEnvironmentHandler` is a utility wrapper for an `OAuthHandlers` that
|
||||
implements the `AuthProviderRouteHandlers` interface while supporting multiple
|
||||
`env`s.
|
||||
|
||||
To instantiate OAuth providers (the same but for different environments), use
|
||||
`OAuthEnvironmentHandler.mapConfig`. It's a helper to iterate over a
|
||||
configuration object that is a map of environments to configurations. See one of
|
||||
the existing OAuth providers for an example of how it is used.
|
||||
|
||||
Given the following configuration:
|
||||
|
||||
```yaml
|
||||
development:
|
||||
clientId: abc
|
||||
clientSecret: secret
|
||||
production:
|
||||
clientId: xyz
|
||||
clientSecret: supersecret
|
||||
```
|
||||
|
||||
The `OAuthEnvironmentHandler.mapConfig(config, envConfig => ...)` call will
|
||||
split the config by the top level `development` and `production` keys, and pass
|
||||
on each block as `envConfig`.
|
||||
|
||||
For convenience, the `AuthProviderFactory` is a factory function that has to be
|
||||
implemented which can then generate a `AuthProviderRouteHandlers` for a given
|
||||
provider.
|
||||
|
||||
All of the supported providers provide an `AuthProviderFactory` that returns an
|
||||
`OAuthEnvironmentHandler`, capable of handling authentication for multiple
|
||||
environments.
|
||||
|
||||
## Passport
|
||||
|
||||
We chose [Passport](http://www.passportjs.org/) as our authentication platform
|
||||
@@ -46,13 +150,13 @@ plugins/auth-backend/src/providers/providerA
|
||||
**`plugins/auth-backend/src/providers/providerA/provider.ts`** defines the
|
||||
provider class which implements a handler for the chosen framework.
|
||||
|
||||
#### Adding an OAuth based provider
|
||||
### Adding an OAuth based provider
|
||||
|
||||
If we're adding an `OAuth` based provider we would implement the
|
||||
[OAuthProviderHandlers](#OAuthProviderHandlers) interface. By implementing this
|
||||
`OAuthHandlers` interface. By implementing this
|
||||
interface we can use the `OAuthProvider` class provided by `lib/oauth`, meaning
|
||||
we don't need to implement the full
|
||||
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers) interface that providers
|
||||
`AuthProviderRouteHandlers` interface that providers
|
||||
otherwise need to implement.
|
||||
|
||||
The provider class takes the provider's options as a class parameter. It also
|
||||
@@ -65,7 +169,7 @@ export type ProviderAProviderOptions = OAuthProviderOptions & {
|
||||
// extra options here
|
||||
}
|
||||
|
||||
export class ProviderAAuthProvider implements OAuthProviderHandlers {
|
||||
export class ProviderAAuthProvider implements OAuthHandlers {
|
||||
private readonly _strategy: ProviderAStrategy;
|
||||
|
||||
constructor(options: ProviderAProviderOptions) {
|
||||
@@ -87,13 +191,10 @@ export class ProviderAAuthProvider implements OAuthProviderHandlers {
|
||||
}
|
||||
```
|
||||
|
||||
#### Adding an non-OAuth based provider
|
||||
|
||||
_**Note**: We have prioritized OAuth-based providers and non-OAuth providers
|
||||
should be considered experimental._
|
||||
### Adding an non-OAuth based provider
|
||||
|
||||
An non-`OAuth` based provider could implement
|
||||
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers) instead.
|
||||
`AuthProviderRouteHandlers` instead.
|
||||
|
||||
```ts
|
||||
type ProviderAOptions = {
|
||||
@@ -119,13 +220,19 @@ export class ProviderAAuthProvider implements AuthProviderRouteHandlers {
|
||||
}
|
||||
```
|
||||
|
||||
#### Factory function
|
||||
#### Integration Wrapper
|
||||
|
||||
Each provider exports a factory function that instantiates the provider. The
|
||||
factory should implement [AuthProviderFactory](#AuthProviderFactory), which
|
||||
Each provider exports an object that provides a way to create new instances
|
||||
of the provider, along with related utilities like predefined sign-in resolvers.
|
||||
|
||||
The object is created using `createAuthProviderIntegration`, with the most
|
||||
important part being the `create` method that acts as the factory function
|
||||
for our provider.
|
||||
|
||||
The factory should return an implementation of `AuthProviderFactory`, which
|
||||
passes in a object with utilities for configuration, logging, token issuing,
|
||||
etc. The factory should return an implementation of
|
||||
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers).
|
||||
`AuthProviderRouteHandlers`.
|
||||
|
||||
The factory is what decides the mapping from
|
||||
[static configuration](../conf/index.md) to the creation of auth providers. For
|
||||
@@ -133,48 +240,70 @@ example, OAuth providers use `OAuthEnvironmentHandler` to allow for multiple
|
||||
different configurations, one for each environment, which looks like this;
|
||||
|
||||
```ts
|
||||
export const createOktaProvider: AuthProviderFactory = ({
|
||||
globalConfig,
|
||||
config,
|
||||
tokenIssuer,
|
||||
}) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
// read options from config
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
export const okta = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
// instantiate our OAuthProviderHandlers implementation
|
||||
const provider = new OktaAuthProvider({
|
||||
audience,
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
});
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
// read options from config
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
|
||||
// Wrap the OAuthProviderHandlers with OAuthProvider, which implements AuthProviderRouteHandlers
|
||||
return OAuthProvider.fromConfig(globalConfig, provider, {
|
||||
providerId,
|
||||
tokenIssuer,
|
||||
});
|
||||
});
|
||||
// Use provided auth handler, or create a default one
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
|
||||
// instantiate our OAuthHandlers implementation
|
||||
const provider = new OktaAuthProvider({
|
||||
audience,
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
// Wrap the OAuthHandlers with OAuthProvider, which implements AuthProviderRouteHandlers
|
||||
return OAuthProvider.fromConfig(globalConfig, provider, {
|
||||
providerId,
|
||||
tokenIssuer,
|
||||
});
|
||||
});
|
||||
},
|
||||
resolvers: {
|
||||
/**
|
||||
* Looks up the user by matching their email local part to the entity name.
|
||||
*/
|
||||
emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
|
||||
|
||||
// ... additional predefined resolvers
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The purpose of the different environments is to allow for a single auth-backend
|
||||
to serve as the authentication service for multiple different frontend
|
||||
environments, such as local development, staging, and production.
|
||||
|
||||
The factory function for other providers can be a lot simpler, as they might not
|
||||
have configuration for each environment. Looking something like this:
|
||||
|
||||
```ts
|
||||
export const createProviderAProvider: AuthProviderFactory = ({ config }) => {
|
||||
const a = config.getString('a');
|
||||
const b = config.getString('b');
|
||||
|
||||
return new ProviderAAuthProvider({ a, b });
|
||||
};
|
||||
```
|
||||
|
||||
#### Verify Callback
|
||||
|
||||
> Strategies require what is known as a verify callback. The purpose of a verify
|
||||
@@ -202,7 +331,7 @@ export { createProviderAProvider } from './provider';
|
||||
|
||||
**`plugins/auth-backend/src/providers/factories.ts`** When the `auth-backend`
|
||||
starts it sets up routing for all the available providers by calling
|
||||
`createAuthProviderRouter` on each provider. You need to import the factory
|
||||
the factory function of each provider. You need to import the factory
|
||||
function from the provider and add it to the factory:
|
||||
|
||||
```ts
|
||||
@@ -232,51 +361,3 @@ You can `curl -i localhost:7007/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.
|
||||
|
||||
---
|
||||
|
||||
##### OAuthProviderHandlers
|
||||
|
||||
```ts
|
||||
export interface OAuthProviderHandlers {
|
||||
start(
|
||||
req: express.Request,
|
||||
options: Record<string, string>,
|
||||
): Promise<RedirectInfo>;
|
||||
handler(req: express.Request): Promise<{
|
||||
response: AuthResponse<OAuthProviderInfo>;
|
||||
refreshToken?: string;
|
||||
}>;
|
||||
refresh?(
|
||||
refreshToken: string,
|
||||
scope: string,
|
||||
): Promise<AuthResponse<OAuthProviderInfo>>;
|
||||
logout?(): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
##### AuthProviderRouteHandlers
|
||||
|
||||
```ts
|
||||
export interface AuthProviderRouteHandlers {
|
||||
start(req: express.Request, res: express.Response): Promise<any>;
|
||||
frameHandler(req: express.Request, res: express.Response): Promise<any>;
|
||||
refresh?(req: express.Request, res: express.Response): Promise<any>;
|
||||
logout(req: express.Request, res: express.Response): Promise<any>;
|
||||
}
|
||||
```
|
||||
|
||||
##### AuthProviderFactory
|
||||
|
||||
```ts
|
||||
export type AuthProviderFactoryOptions = {
|
||||
globalConfig: AuthProviderConfig;
|
||||
config: Config;
|
||||
logger: Logger;
|
||||
tokenIssuer: TokenIssuer;
|
||||
};
|
||||
|
||||
export type AuthProviderFactory = (
|
||||
options: AuthProviderFactoryOptions,
|
||||
) => AuthProviderRouteHandlers;
|
||||
```
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
---
|
||||
id: auth-backend-classes
|
||||
title: Auth backend classes
|
||||
description: Documentation on Auth backend classes
|
||||
---
|
||||
|
||||
## How Does Authentication Work?
|
||||
|
||||
The Backstage application can use various external authentication providers for
|
||||
authentication. An external provider is wrapped using an
|
||||
`AuthProviderRouteHandlers` interface for handling authentication. This
|
||||
interface consists of four methods. Each of these methods is hosted at an
|
||||
endpoint (by default) `/api/auth/[provider]/method`, where `method` performs a
|
||||
certain operation as follows:
|
||||
|
||||
```
|
||||
/auth/[provider]/start -> Initiate a login from the web page
|
||||
/auth/[provider]/handler/frame -> Handle a finished authentication operation
|
||||
/auth/[provider]/refresh -> Refresh the validity of a login
|
||||
/auth/[provider]/logout -> Log out a logged-in user
|
||||
```
|
||||
|
||||
The flow is as follows:
|
||||
|
||||
1. A user attempts to sign in.
|
||||
2. A popup window is opened, pointing to the `auth` endpoint. That endpoint does
|
||||
initial preparations and then re-directs the user to an external
|
||||
authenticator, still inside the popup.
|
||||
3. The authenticator validates the user and returns the result of the validation
|
||||
(success OR failure), to the wrapper's endpoint (`handler/frame`).
|
||||
4. The `handler/frame` rendered b´webpage will issue the appropriate response to
|
||||
the webpage that opened the popup window, and the popup is closed.
|
||||
5. The user signs out by clicking on a UI interface and the webpage makes a
|
||||
request to logout the user.
|
||||
|
||||
There are currently two different classes for two authentication mechanisms that
|
||||
implement this interface: an `OAuthAdapter` for [OAuth](https://oauth.net/2/)
|
||||
based mechanisms and a `SAMLAuthProvider` for
|
||||
[SAML](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).
|
||||
|
||||
If you do not have an `OAuth2` or `SAML` based authentication provider, look in
|
||||
the section [below](#implementing-your-own-auth-wrapper).
|
||||
|
||||
### OAuth Mechanisms
|
||||
|
||||
For more information on how these methods are used and for which purpose, refer
|
||||
to the [OAuth documentation](oauth.md).
|
||||
|
||||
Currently OAuth is assumed to be the de facto authentication mechanism for
|
||||
Backstage based applications.
|
||||
|
||||
Backstage comes with a "batteries-included" set of supported commonly used OAuth
|
||||
providers: Okta, GitHub, Google, GitLab, and a generic OAuth2 provider. For a
|
||||
list of available providers, look at the available wrappers in
|
||||
`backstage/plugins/auth-backend/src/providers/`.
|
||||
|
||||
All of these use the **authorization flow** of OAuth2 to implement
|
||||
authentication.
|
||||
|
||||
If your authentication provider is any of the above mentioned providers, you can
|
||||
configure them by setting the right variables in `app-config.yaml` under the
|
||||
`auth` section.
|
||||
|
||||
### SAML
|
||||
|
||||
The SAML Provider is currently under development. Additional validation and
|
||||
profile handling is still required before use in production.
|
||||
|
||||
To configure the SAML Auth provider, look at the configuration parameters
|
||||
supported by
|
||||
[Passport-SAML](https://github.com/node-saml/passport-saml#config-parameter-details)
|
||||
under the `auth.providers.saml` key
|
||||
|
||||
For security reasons, validate that the response from the IdP is indeed signed
|
||||
by also providing the `cert` configuration.
|
||||
|
||||
### Configuration
|
||||
|
||||
Each authentication provider (except SAML) needs six parameters: an OAuth client
|
||||
ID, a client secret, an authorization endpoint, a token endpoint, an optional
|
||||
list of scopes (as a string separated by spaces) that may be required by the
|
||||
OAuth2 Server to enable end-user sign-on, and an app origin. The app origin is
|
||||
the URL at which the frontend of the application is hosted, and it is read from
|
||||
the `app.baseUrl` config. This is required because the application opens a popup
|
||||
window to perform the authentication, and once the flow is completed, the popup
|
||||
window sends a `postMessage` to the frontend application to indicate the result
|
||||
of the operation. Also this URL is used to verify that authentication requests
|
||||
are coming from only this endpoint.
|
||||
|
||||
These values are configured via the `app-config.yaml` present in the root of
|
||||
your app folder.
|
||||
|
||||
```
|
||||
auth:
|
||||
providers:
|
||||
google:
|
||||
development:
|
||||
clientId: ${AUTH_GOOGLE_CLIENT_ID}
|
||||
clientSecret: ${AUTH_GOOGLE_CLIENT_SECRET}
|
||||
github:
|
||||
development:
|
||||
clientId: ${AUTH_GITHUB_CLIENT_ID}
|
||||
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
|
||||
enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL}
|
||||
gitlab:
|
||||
development:
|
||||
clientId: ${AUTH_GITLAB_CLIENT_ID}
|
||||
oauth2:
|
||||
development:
|
||||
clientId: ${AUTH_OAUTH2_CLIENT_ID}
|
||||
clientSecret: ${AUTH_OAUTH2_CLIENT_SECRET}
|
||||
authorizationUrl: ${AUTH_OAUTH2_AUTH_URL}
|
||||
tokenUrl: ${AUTH_OAUTH2_TOKEN_URL}
|
||||
scope: ${AUTH_OAUTH2_SCOPE}
|
||||
saml:
|
||||
entryPoint: ${AUTH_SAML_ENTRY_POINT}
|
||||
issuer: ${AUTH_SAML_ISSUER}
|
||||
...
|
||||
```
|
||||
|
||||
## Implementing Your Own Auth Wrapper
|
||||
|
||||
The core interface of any auth wrapper is the `AuthProviderRouteHandlers`
|
||||
interface. This interface has four methods corresponding to the API described in
|
||||
the initial section. Any auth wrapper will have to implement this interface.
|
||||
|
||||
When initiating a login, a pop-up window is created by the frontend, to allow
|
||||
the user to initiate a login. This login request is done to the `/start`
|
||||
endpoint which is handled by the `start` method.
|
||||
|
||||
The `start` method re-directs to the external auth provider who authenticates
|
||||
the request and re-directs the request to the `/frame/handler` endpoint, which
|
||||
is handled by the `frameHandler` method.
|
||||
|
||||
The `frameHandler` returns an HTML response, containing a script that does a
|
||||
`postMessage` to the frontend's window, containing the result of the request.
|
||||
The `WebMessageResponse` type is the message sent by the `postMessage` to the
|
||||
frontend.
|
||||
|
||||
A `postMessageResponse` utility function wraps the logic of generating a
|
||||
`postMessage` response that ensures that CORS is successfully handled. This
|
||||
function takes an `express.Response`, a `WebMessageResponse` and the URL of the
|
||||
frontend (`appOrigin`) as parameters and return an HTML page with the script and
|
||||
the message.
|
||||
|
||||
### OAuth Wrapping Interfaces.
|
||||
|
||||
Each OAuth external provider is supported by a corresponding
|
||||
[Passport](https://github.com/jaredhanson/passport) strategy. For a generic
|
||||
OAuth2 provider, passport has a `passport-oauth2` strategy. The strategy class
|
||||
handles the implementation details of working with each provider.
|
||||
|
||||
Each strategy is wrapped by an `OAuthHandlers` interface.
|
||||
|
||||
This interface cannot be directly used as an Express HTTP request handler. To do
|
||||
so, `OAuthHandlers` are wrapped in an `OAuthAdapter`, which implements the
|
||||
`AuthProviderRouterHandlers` interface.
|
||||
|
||||
#### Env
|
||||
|
||||
The concept of an `env` is core to the way the auth backend works. It uses an
|
||||
`env` query parameter to identify the environment in which the application is
|
||||
running (`development`, `staging`, `production`, etc). Each runtime can
|
||||
simultaneously support multiple environments at the same time and the right
|
||||
handler for each request is identified and dispatched to, based on the `env`
|
||||
parameter.
|
||||
|
||||
`OAuthEnvironmentHandler` is a utility wrapper for an `OAuthHandlers` that
|
||||
implements the `AuthProviderRouteHandlers` interface while supporting multiple
|
||||
`env`s.
|
||||
|
||||
To instantiate OAuth providers (the same but for different environments), use
|
||||
`OAuthEnvironmentHandler.mapConfig`. It's a helper to iterate over a
|
||||
configuration object that is a map of environments to configurations. See one of
|
||||
the existing OAuth providers for an example of how it is used.
|
||||
|
||||
Given the following configuration:
|
||||
|
||||
```yaml
|
||||
development:
|
||||
clientId: abc
|
||||
clientSecret: secret
|
||||
production:
|
||||
clientId: xyz
|
||||
clientSecret: supersecret
|
||||
```
|
||||
|
||||
The `OAuthEnvironmentHandler.mapConfig(config, envConfig => ...)` call will
|
||||
split the config by the top level `development` and `production` keys, and pass
|
||||
on each block as `envConfig`.
|
||||
|
||||
For convenience, the `AuthProviderFactory` is a factory function that has to be
|
||||
implemented which can then generate a `AuthProviderRouteHandlers` for a given
|
||||
provider.
|
||||
|
||||
All of the supported providers provide an `AuthProviderFactory` that returns an
|
||||
`OAuthEnvironmentHandler`, capable of handling authentication for multiple
|
||||
environments.
|
||||
|
||||
### OAuth2 Provider
|
||||
|
||||
The `oauth2` provider abstracts a generic **OAuth2 + OIDC** based authentication
|
||||
provider. What this means is that after the application has been given
|
||||
permission by the user, the `authorization code` will be exchanged for an
|
||||
`access_token`, a `refresh_token` and an `id_token`. This `id_token` is used to
|
||||
obtain an email id of the user, which is then used for creating the session.
|
||||
@@ -12,6 +12,37 @@ If you want to use an auth provider to sign in users, you need to explicitly con
|
||||
it have sign-in enabled and also tell it how the external identities should
|
||||
be mapped to user identities within Backstage.
|
||||
|
||||
## Quick Start
|
||||
|
||||
> See [providers](../reference/plugin-auth-backend.providers.md)
|
||||
> for a full list of auth providers and their built-in sign-in resolvers.
|
||||
|
||||
Backstage projects created with `npx @backstage/create-app` come configured with a
|
||||
sign-in resolver for GitHub guest access. This resolver makes all users share
|
||||
a single "guest" identity and is only intended as a minimum requirement to quickly
|
||||
get up and running. You can replace `github` for any of the other providers if you need.
|
||||
|
||||
This resolver should not be used in production, as it uses a single shared identity,
|
||||
and has no restrictions on who is able to sign-in. Be sure to read through the rest
|
||||
of this page to understand the Backstage identity system once you need to install
|
||||
a resolver for your production environment.
|
||||
|
||||
The guest resolver can be useful for testing purposes too, and it looks like this:
|
||||
|
||||
```ts
|
||||
signIn: {
|
||||
resolver(_, ctx) {
|
||||
const userRef = 'user:default/guest'
|
||||
return ctx.issueToken({
|
||||
claims: {
|
||||
sub: userRef,
|
||||
ent: [userRef],
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
## Backstage User Identity
|
||||
|
||||
A user identity within Backstage is built up from two pieces of information, a
|
||||
@@ -59,6 +90,11 @@ the given auth provider, as well as a context object that contains various helpe
|
||||
for looking up users and issuing tokens. There are also a number of built-in sign-in
|
||||
resolvers that can be used, which are covered a bit further down.
|
||||
|
||||
Note that while it possible to configure multiple auth providers to be used for sign-in,
|
||||
you should take care when doing so. It is best to make sure that the different auth
|
||||
providers either do not have any user overlap, or that any users that are able to log
|
||||
in with multiple providers always end up with the same Backstage identity.
|
||||
|
||||
### Custom Resolver Example
|
||||
|
||||
Let's look at an example of a custom sign-in resolver for the Google auth provider.
|
||||
@@ -210,6 +246,11 @@ is that it can be tricky to determine the ownership references, although it can
|
||||
be achieved for example through a lookup to an external service. You typically
|
||||
want to at least use the user itself as a lone ownership reference.
|
||||
|
||||
Because we no longer use the catalog as an allow-list of users, it is often important
|
||||
that you limit what users are allowed to sign in. This could be a simple email domain
|
||||
check like in the example below, or you might for example look up the GitHub organizations
|
||||
that the user belongs to using the user access token in the provided result object.
|
||||
|
||||
```ts
|
||||
import { DEFAULT_NAMESPACE, stringifyEntityRef, } from '@backstage/catalog-model';
|
||||
|
||||
@@ -220,8 +261,14 @@ async ({ profile }, ctx) => {
|
||||
'Login failed, user profile does not contain an email',
|
||||
);
|
||||
}
|
||||
// We again use the local part of the email as the user name.
|
||||
const [localPart] = profile.email.split('@');
|
||||
// Split the email into the local part and the domain.
|
||||
const [localPart, domain] = profile.email.split('@');
|
||||
|
||||
// Next we verify the email domain. It is recommended to include this
|
||||
// kind of check if you don't look up the user in an external service.
|
||||
if (domain !== 'acme.org') {
|
||||
throw new Error('Login failed, user email domain check failed');
|
||||
}
|
||||
|
||||
// By using `stringifyEntityRef` we ensure that the reference is formatted correctly
|
||||
const userEntityRef = stringifyEntityRef({
|
||||
|
||||
@@ -185,6 +185,24 @@ const app = createApp({
|
||||
When using multiple auth providers like this, it's important that you configure the different
|
||||
sign-in resolvers so that they resolve to the same identity regardless of the method used.
|
||||
|
||||
## Scaffolder Configuration (Software Templates)
|
||||
|
||||
If you want to use the authentication capabilities of the [Repository Picker](../features/software-templates/writing-templates.md#the-repository-picker) inside your software templates you will need to configure the [`ScmAuthApi`](https://backstage.io/docs/reference/integration-react.scmauthapi) alongside your authentication provider. It is an API used to authenticate towards different SCM systems in a generic way, based on what resource is being accessed.
|
||||
|
||||
To set it up, you'll need to add an API factory entry to `packages/app/src/apis.ts`. The example below sets up the `ScmAuthApi` for an already configured GitLab authentication provider:
|
||||
|
||||
```ts
|
||||
createApiFactory({
|
||||
api: scmAuthApiRef,
|
||||
deps: {
|
||||
gitlabAuthApi: gitlabAuthApiRef,
|
||||
},
|
||||
factory: ({ gitlabAuthApi }) => ScmAuth.forGitlab(gitlabAuthApi),
|
||||
});
|
||||
```
|
||||
|
||||
In case you are using a custom authentication providers, you might need to add a [custom `ScmAuthApi` implementation](./index.md#custom-scmauthapi-implementation).
|
||||
|
||||
## For Plugin Developers
|
||||
|
||||
The Backstage frontend core APIs provide a set of Utility APIs for plugin developers
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Adding OAuth2Proxy as an authentication provider in Backstage
|
||||
---
|
||||
|
||||
The Backstage `@backstage/plugin-auth-backend` package comes with an
|
||||
`oauth2proxy` authentication provider that can authenticate users by using a
|
||||
`oauth2Proxy` authentication provider that can authenticate users by using a
|
||||
[oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy) in front of an
|
||||
actual Backstage instance. This enables to reuse existing authentications within
|
||||
a cluster. In general the `oauth2-proxy` supports all OpenID Connect providers,
|
||||
@@ -21,17 +21,17 @@ The provider configuration can be added to your `app-config.yaml` under the root
|
||||
```yaml
|
||||
auth:
|
||||
providers:
|
||||
oauth2proxy: {}
|
||||
oauth2Proxy: {}
|
||||
```
|
||||
|
||||
Right now no configuration options are supported, but the empty object is needed
|
||||
to enable the provider in the auth backend.
|
||||
|
||||
To use the `oauth2proxy` provider you must also configure it with a sign-in resolver.
|
||||
To use the `oauth2Proxy` provider you must also configure it with a sign-in resolver.
|
||||
For more information about the sign-in process in general, see the
|
||||
[Sign-in Identities and Resolvers](../identity-resolver.md) documentation.
|
||||
|
||||
For the `oauth2proxy` provider, the sign-in result is quite different than other providers.
|
||||
For the `oauth2Proxy` provider, the sign-in result is quite different than other providers.
|
||||
Because it's a proxy provider that can be configured to forward information through
|
||||
arbitrary headers, the auth result simply just gives you access to the HTTP headers
|
||||
of the incoming request. Using these you can either extract the information directly,
|
||||
@@ -40,19 +40,22 @@ or grab ID or access tokens to look up additional information and/or validate th
|
||||
A simple sign-in resolver might for example look like this:
|
||||
|
||||
```ts
|
||||
providers.oauth2Proxy.create({
|
||||
signIn: {
|
||||
async resolver({ result }, ctx) {
|
||||
const name = result.getHeader('x-forwarded-user');
|
||||
if (!name) {
|
||||
throw new Error('Request did not contain a user')
|
||||
}
|
||||
return ctx.signInWithCatalogUser({
|
||||
entityRef: { name },
|
||||
});
|
||||
providerFactories: {
|
||||
...defaultAuthProviderFactories,
|
||||
oauth2Proxy: providers.oauth2Proxy.create({
|
||||
signIn: {
|
||||
async resolver({ result }, ctx) {
|
||||
const name = result.getHeader('x-forwarded-user');
|
||||
if (!name) {
|
||||
throw new Error('Request did not contain a user')
|
||||
}
|
||||
return ctx.signInWithCatalogUser({
|
||||
entityRef: { name },
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
},
|
||||
```
|
||||
|
||||
## Adding the provider to the Backstage frontend
|
||||
@@ -65,7 +68,7 @@ installed in `packages/app/src/App.tsx` like this:
|
||||
|
||||
const app = createApp({
|
||||
components: {
|
||||
+ SignInPage: props => <ProxiedSignInPage {...props} provider="oauth2proxy" />,
|
||||
+ SignInPage: props => <ProxiedSignInPage {...props} provider="oauth2Proxy" />,
|
||||
```
|
||||
|
||||
See the [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) section for more information.
|
||||
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page to also work smoothly for local development.
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
---
|
||||
id: helm
|
||||
title: Deploying with Helm
|
||||
description: How to deploy Backstage with Helm and Kubernetes
|
||||
sidebar_label: Helm
|
||||
---
|
||||
|
||||
An example Backstage app can be deployed in Kubernetes using the
|
||||
[Backstage Helm charts](https://github.com/backstage/backstage/tree/master/contrib/chart/backstage).
|
||||
|
||||
First, choose a DNS name where Backstage will be hosted, and create a YAML file
|
||||
for your custom configuration.
|
||||
|
||||
```yaml
|
||||
appConfig:
|
||||
app:
|
||||
baseUrl: https://backstage.mydomain.com
|
||||
title: Backstage
|
||||
backend:
|
||||
baseUrl: https://backstage.mydomain.com
|
||||
cors:
|
||||
origin: https://backstage.mydomain.com
|
||||
lighthouse:
|
||||
baseUrl: https://backstage.mydomain.com/lighthouse-api
|
||||
techdocs:
|
||||
storageUrl: https://backstage.mydomain.com/api/techdocs/static/docs
|
||||
requestUrl: https://backstage.mydomain.com/api/techdocs
|
||||
```
|
||||
|
||||
Then use it to run:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/backstage/backstage.git
|
||||
cd backstage/contrib/chart/backstage
|
||||
helm dependency update
|
||||
helm install -f backstage-mydomain.yaml backstage .
|
||||
```
|
||||
|
||||
This command will deploy the following pieces:
|
||||
|
||||
- Backstage frontend
|
||||
- Backstage backend with scaffolder and auth plugins
|
||||
- (optional) a PostgreSQL instance
|
||||
- lighthouse plugin
|
||||
- ingress
|
||||
|
||||
After a few minutes Backstage should be up and running in your cluster under the
|
||||
DNS specified earlier.
|
||||
|
||||
Make sure to create the appropriate DNS entry in your infrastructure. To find
|
||||
the public IP address run:
|
||||
|
||||
```bash
|
||||
$ kubectl get ingress
|
||||
NAME HOSTS ADDRESS PORTS AGE
|
||||
backstage-ingress * 123.1.2.3 80 17m
|
||||
```
|
||||
|
||||
> **NOTE**: this is not a production ready deployment.
|
||||
|
||||
For more information on how to customize the deployment check the
|
||||
[README](https://github.com/backstage/backstage/tree/master/contrib/chart/backstage/README.md).
|
||||
@@ -29,9 +29,7 @@ This method is covered in [Building a Docker image](docker.md) and
|
||||
There is also an example of deploying on [Heroku](heroku.md), which only
|
||||
requires the first two steps.
|
||||
|
||||
An example of deploying Backstage with a [Helm chart](helm.md), a common pattern
|
||||
in AWS, is also available. There is also a contrib guide to deploying Backstage
|
||||
with
|
||||
There is also a contrib guide to deploying Backstage with
|
||||
[AWS Fargate and Aurora PostgreSQL](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/aws-fargate-deployment.md).
|
||||
|
||||
Please consider contributing other deployment guides if you get Backstage set up
|
||||
|
||||
@@ -33,10 +33,14 @@ const serviceEntityPage = (
|
||||
<EntityLayout>
|
||||
{/* other tabs... */}
|
||||
<EntityLayout.Route path="/kubernetes" title="Kubernetes">
|
||||
<EntityKubernetesContent />
|
||||
<EntityKubernetesContent refreshIntervalMs={30000} />
|
||||
</EntityLayout.Route>
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
|
||||
- The optional `refreshIntervalMs` property on the `EntityKubernetesContent` defines the interval in which the content automatically refreshes, if not set this will default to 10 seconds.
|
||||
|
||||
That's it! But now, we need the Kubernetes Backend plugin for the frontend to
|
||||
work.
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ If you haven't setup Backstage already, start
|
||||
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
yarn add --cwd packages/app @backstage/plugin-search
|
||||
yarn add --cwd packages/app @backstage/plugin-search @backstage/plugin-search-react
|
||||
```
|
||||
|
||||
Create a new `packages/app/src/components/search/SearchPage.tsx` file in your
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
SearchResult,
|
||||
DefaultResultListItem,
|
||||
SearchFilter,
|
||||
} from '@backstage/plugin-search';
|
||||
} from '@backstage/plugin-search-react';
|
||||
import { CatalogResultListItem } from '@backstage/plugin-catalog';
|
||||
|
||||
export const searchPage = (
|
||||
@@ -213,7 +213,7 @@ apiRouter.use('/search', await search(searchEnv));
|
||||
|
||||
### Frontend
|
||||
|
||||
The Search Plugin exposes several default filter types as static properties,
|
||||
The Search Plugin web library (`@backstage/plugin-search-react`) exposes several default filter types as static properties,
|
||||
including `<SearchFilter.Select />` and `<SearchFilter.Checkbox />`. These allow
|
||||
you to provide values relevant to your Backstage instance that, when selected,
|
||||
get passed to the backend.
|
||||
@@ -237,7 +237,7 @@ If you have advanced filter needs, you can specify your own filter component
|
||||
like this (although new core filter contributions are welcome):
|
||||
|
||||
```tsx
|
||||
import { useSearch, SearchFilter } from '@backstage/plugin-search';
|
||||
import { useSearch, SearchFilter } from '@backstage/plugin-search-react';
|
||||
|
||||
const MyCustomFilter = () => {
|
||||
// Note: filters contain filter data from other filter components. Be sure
|
||||
|
||||
@@ -102,6 +102,31 @@ import { Client } from '@elastic/elastic-search';
|
||||
const client = searchEngine.newClient(options => new Client(options));
|
||||
```
|
||||
|
||||
#### Set custom index template
|
||||
|
||||
The elasticsearch engine gives you the ability to set a custom index template if needed.
|
||||
|
||||
> Index templates define settings, mappings, and aliases that can be applied automatically to new indices.
|
||||
|
||||
```typescript
|
||||
// app/backend/src/plugins/search.ts
|
||||
const searchEngine = await ElasticSearchSearchEngine.initialize({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
});
|
||||
|
||||
searchEngine.setIndexTemplate({
|
||||
name: '<name-of-your-custom-template>',
|
||||
body: {
|
||||
index_patterns: ['<your-index-pattern>'],
|
||||
template: {
|
||||
mappings: {},
|
||||
settings: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Example configurations
|
||||
|
||||
### AWS
|
||||
|
||||
@@ -55,6 +55,7 @@ metadata:
|
||||
- url: https://admin.example-org.com
|
||||
title: Admin Dashboard
|
||||
icon: dashboard
|
||||
type: admin-dashboard
|
||||
spec:
|
||||
type: website
|
||||
lifecycle: production
|
||||
@@ -83,7 +84,8 @@ This is the same entity as returned in JSON from the software catalog API:
|
||||
{
|
||||
"url": "https://admin.example-org.com",
|
||||
"title": "Admin Dashboard",
|
||||
"icon": "dashboard"
|
||||
"icon": "dashboard",
|
||||
"type": "admin-dashboard"
|
||||
}
|
||||
],
|
||||
"tags": ["java"],
|
||||
@@ -353,6 +355,7 @@ Fields of a link are:
|
||||
| `url` | String | [Required] A `url` in a standard `uri` format (e.g. `https://example.com/some/page`) |
|
||||
| `title` | String | [Optional] A user friendly display name for the link. |
|
||||
| `icon` | String | [Optional] A key representing a visual icon to be displayed in the UI. |
|
||||
| `type` | String | [Optional] An optional value to categorize links into specific groups. |
|
||||
|
||||
_NOTE_: The `icon` field value is meant to be a semantic key that will map to a
|
||||
specific icon that may be provided by an icon library (e.g. `material-ui`
|
||||
@@ -362,6 +365,8 @@ Backstage integrator will ultimately be left to provide the appropriate icon
|
||||
component mappings. A generic fallback icon would be provided if a mapping
|
||||
cannot be resolved.
|
||||
|
||||
The semantics of the `type` field are undefined. The adopter is free to define their own set of types and utilize them as they wish. Some potential use cases can be to utilize the type field to validate certain links exist on entities or to create customized UI components for specific link types.
|
||||
|
||||
## Common to All Kinds: Relations
|
||||
|
||||
The `relations` root field is a read-only list of relations, between the current
|
||||
|
||||
@@ -33,8 +33,8 @@ tracked in source control, or use some existing open source or commercial
|
||||
software.
|
||||
|
||||
A component can implement APIs for other components to consume. In turn it might
|
||||
depend on APIs implemented by other components, or resources that are attached
|
||||
to it at runtime.
|
||||
consume APIs implemented by other components, or directly depend on components or
|
||||
resources that are attached to it at runtime.
|
||||
|
||||
### API
|
||||
|
||||
|
||||
@@ -353,6 +353,19 @@ to `scm-only`, the plugin will only take into account files stored in source
|
||||
control (e.g. ignoring generated code). If set to `enabled`, all files covered
|
||||
by a coverage report will be taken into account.
|
||||
|
||||
### vault.io/secrets-path
|
||||
|
||||
```yaml
|
||||
# Example:
|
||||
metadata:
|
||||
annotations:
|
||||
vault.io/secrets-path: test/backstage
|
||||
```
|
||||
|
||||
The value of this annotation contains the path to the secrets of the entity in
|
||||
Vault. If not present when the Vault plugin is in use, a message will be shown
|
||||
instead, letting the user know what is missing in the `catalog-info.yaml`.
|
||||
|
||||
## Deprecated Annotations
|
||||
|
||||
The following annotations are deprecated, and only listed here to aid in
|
||||
|
||||
@@ -397,6 +397,29 @@ There's also the ability to pass additional scopes when requesting the `oauth`
|
||||
token from the user, which you can do on a per-provider basis, in case your
|
||||
template can be published to multiple providers.
|
||||
|
||||
Note, that you will need to configure an [authentication provider](../../auth/index.md#configuring-authentication-providers), alongside the
|
||||
[`ScmAuthApi`](../../auth/index.md#scaffolder-configuration-software-templates) for your source code management (SCM) service to make this feature work.
|
||||
|
||||
### Accessing the signed-in users details
|
||||
|
||||
Sometimes when authoring templates, you'll want to access the user that is running the template, and get details from the profile or the users `Entity` in the Catalog.
|
||||
|
||||
If you have enabled a sign in provider and have a [sign in resolver](../../auth/identity-resolver.md) that points to a user in the Catalog, then you can use the `${{ user.entity }}` templating expression to access the raw entity from the Catalog.
|
||||
|
||||
This can be particularly useful if you have processors setup in the Catalog to write `spec.profile.email` of the `User Entities` to reference them and pass them into actions like below:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
action: publish:github
|
||||
...
|
||||
input:
|
||||
...
|
||||
gitAuthorName: ${{ user.entity.metadata.name }}
|
||||
gitAuthorEmail: ${{ user.entity.spec.profile.email }}
|
||||
```
|
||||
|
||||
You also have access to `user.entity.metadata.annotations` too, so if you have some other additional information stored in there, you reference those too.
|
||||
|
||||
### The Owner Picker
|
||||
|
||||
When the scaffolder needs to add new components to the catalog, it needs to have
|
||||
|
||||
@@ -95,7 +95,7 @@ See [TechDocs Architecture](architecture.md) to get an overview of where the bel
|
||||
[techdocs/frontend-library]: https://github.com/backstage/backstage/blob/master/plugins/techdocs-react
|
||||
[techdocs/backend]: https://github.com/backstage/backstage/blob/master/plugins/techdocs-backend
|
||||
[techdocs/container]: https://github.com/backstage/techdocs-container
|
||||
[techdocs/cli]: https://github.com/backstage/techdocs-cli
|
||||
[techdocs/cli]: https://github.com/backstage/backstage/blob/master/packages/techdocs-cli
|
||||
|
||||
## Get involved
|
||||
|
||||
|
||||
@@ -164,27 +164,25 @@ Open `packages/app/src/App.tsx` and below the last `import` line, add:
|
||||
```typescript
|
||||
import { githubAuthApiRef } from '@backstage/core-plugin-api';
|
||||
import { SignInProviderConfig, SignInPage } from '@backstage/core-components';
|
||||
|
||||
const githubProvider: SignInProviderConfig = {
|
||||
id: 'github-auth-provider',
|
||||
title: 'GitHub',
|
||||
message: 'Sign in using GitHub',
|
||||
apiRef: githubAuthApiRef,
|
||||
};
|
||||
```
|
||||
|
||||
Search for `const app = createApp({` in this file, and below `apis,` add:
|
||||
|
||||
```typescript
|
||||
components: {
|
||||
SignInPage: props => (
|
||||
<SignInPage
|
||||
{...props}
|
||||
auto
|
||||
provider={githubProvider}
|
||||
/>
|
||||
),
|
||||
},
|
||||
SignInPage: props => (
|
||||
<SignInPage
|
||||
{...props}
|
||||
auto
|
||||
provider={{
|
||||
id: 'github-auth-provider',
|
||||
title: 'GitHub',
|
||||
message: 'Sign in using GitHub',
|
||||
apiRef: githubAuthApiRef,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
```
|
||||
|
||||
> Since [v1.1.0](https://github.com/backstage/backstage/releases/tag/v1.1.0-next.3), you must provide an [explicit sign-in resolver](../auth/identity-resolver.md).
|
||||
|
||||
@@ -6,25 +6,95 @@ sidebar_label: Discovery
|
||||
description: Automatically discovering catalog entities from repositories in an Azure DevOps organization
|
||||
---
|
||||
|
||||
The Azure DevOps integration has a special discovery processor for discovering
|
||||
catalog entities within an Azure DevOps. The processor will crawl the Azure
|
||||
The Azure DevOps integration has a special entity provider for discovering
|
||||
catalog entities within an Azure DevOps. The provider will crawl your Azure
|
||||
DevOps organization and register entities matching the configured path. This can
|
||||
be useful as an alternative to static locations or manually adding things to the
|
||||
catalog.
|
||||
|
||||
This guide explains how to install and configure the Azure DevOps Entity Provider (recommended) or the Azure DevOps Processor.
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Code Search Feature
|
||||
|
||||
Azure discovery is driven by the Code Search feature in Azure DevOps, this may not be enabled by default. For Azure
|
||||
DevOps Services you can confirm this by looking at the installed extensions in your Organization Settings. For Azure
|
||||
DevOps Server you'll find this information in your Collection Settings.
|
||||
|
||||
If the Code Search extension is not listed then you can install it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms.vss-code-search&targetId=f9352dac-ba6e-434e-9241-a848a510ce3f&utm_source=vstsproduct&utm_medium=SearchExtStatus).
|
||||
|
||||
### Azure Integration
|
||||
|
||||
Setup [Azure integration](locations.md) with `host` and `token`. Host must be `dev.azure.com` for Cloud users, otherwise set this to your on-premise hostname.
|
||||
|
||||
## Installation
|
||||
|
||||
You will have to add the processors in the catalog initialization code of your
|
||||
backend. They are not installed by default, therefore you have to add a
|
||||
dependency to `@backstage/plugin-catalog-backend-module-azure` to your backend
|
||||
package.
|
||||
At your configuration, you add one or more provider configs:
|
||||
|
||||
```yaml
|
||||
# app-config.yaml
|
||||
catalog:
|
||||
providers:
|
||||
azureDevOps:
|
||||
yourProviderId: # identifies your dataset / provider independent of config changes
|
||||
organization: myorg
|
||||
project: myproject
|
||||
repository: service-* # this will match all repos starting with service-*
|
||||
path: /catalog-info.yaml
|
||||
anotherProviderId: # another identifier
|
||||
organization: myorg
|
||||
project: myproject
|
||||
repository: '*' # this will match all repos starting with service-*
|
||||
path: /src/*/catalog-info.yaml # this will search for files deep inside the /src folder
|
||||
yetAotherProviderId: # guess, what? Another one :)
|
||||
host: selfhostedazure.yourcompany.com
|
||||
organization: myorg
|
||||
project: myproject
|
||||
```
|
||||
|
||||
The parameters available are:
|
||||
|
||||
- `host:` Leave empty for Cloud hosted, otherwise set to your self-hosted instance host.
|
||||
- `organization:` Your Organization slug (or Collection for on-premise users). Required.
|
||||
- `project:` Your project slug. Required.
|
||||
- `repository:` The repository name. Wildcards are supported as show on the examples above. If not set, all repositories will be searched.
|
||||
- `path:` Where to find catalog-info.yaml files. Defaults to /catalog-info.yaml.
|
||||
|
||||
_Note:_ the path parameter follows the same rules as the search on Azure DevOps
|
||||
web interface. For more details visit the
|
||||
[official search documentation](https://docs.microsoft.com/en-us/azure/devops/project/search/get-started-search?view=azure-devops).
|
||||
|
||||
As this provider is not one of the default providers, you will first need to install
|
||||
the Azure catalog plugin:
|
||||
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-azure
|
||||
```
|
||||
|
||||
And then add the processors to your catalog builder:
|
||||
Once you've done that, you'll also need to add the segment below to `packages/backend/src/plugins/catalog.ts`:
|
||||
|
||||
```diff
|
||||
/* packages/backend/src/plugins/catalog.ts */
|
||||
+import { AzureDevOpsEntityProvider } from '@backstage/plugin-catalog-backend-module-azure';
|
||||
|
||||
const builder = await CatalogBuilder.create(env);
|
||||
/** ... other processors and/or providers ... */
|
||||
+builder.addEntityProvider(
|
||||
+ AzureDevOpsEntityProvider.fromConfig(env.config, {
|
||||
+ logger: env.logger,
|
||||
+ schedule: env.scheduler.createScheduledTaskRunner({
|
||||
+ frequency: Duration.fromObject({ minutes: 30 }),
|
||||
+ timeout: Duration.fromObject({ minutes: 3 }),
|
||||
+ }),
|
||||
+ }),
|
||||
+);
|
||||
```
|
||||
|
||||
## Alternative Processor
|
||||
|
||||
As an alternative to the entity provider `AzureDevOpsEntityProvider`, you can still use the `AzureDevopsDiscoveryProcessor`.
|
||||
|
||||
```diff
|
||||
// In packages/backend/src/plugins/catalog.ts
|
||||
@@ -37,12 +107,6 @@ And then add the processors to your catalog builder:
|
||||
+ builder.addProcessor(AzureDevOpsDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }));
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
To use the discovery processor, you'll need a Azure integration
|
||||
[set up](locations.md) with a `AZURE_TOKEN`. Then you can add a location target
|
||||
to the catalog configuration:
|
||||
|
||||
```yaml
|
||||
catalog:
|
||||
locations:
|
||||
@@ -70,13 +134,3 @@ When using a custom pattern, the target is composed of five parts:
|
||||
- The path within each repository to find the catalog YAML file. This will
|
||||
usually be `/catalog-info.yaml`, `/src/*/catalog-info.yaml` or a similar
|
||||
variation for catalog files stored in the root directory of each repository.
|
||||
|
||||
_Note:_ the path parameter follows the same rules as the search on Azure DevOps
|
||||
web interface. For more details visit the
|
||||
[official search documentation](https://docs.microsoft.com/en-us/azure/devops/project/search/get-started-search?view=azure-devops).
|
||||
|
||||
Azure discovery is driven by the Code Search feature in Azure DevOps, this may not be enabled by default. For Azure
|
||||
DevOps Services you can confirm this by looking at the installed extensions in your Organization Settings. For Azure
|
||||
DevOps Server you'll find this information in your Collection Settings.
|
||||
|
||||
If the Code Search extension is not listed then you can install it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms.vss-code-search&targetId=f9352dac-ba6e-434e-9241-a848a510ce3f&utm_source=vstsproduct&utm_medium=SearchExtStatus).
|
||||
|
||||
@@ -6,14 +6,55 @@ sidebar_label: Discovery
|
||||
description: Automatically discovering catalog entities from repositories in GitLab
|
||||
---
|
||||
|
||||
The GitLab integration has a special discovery processor for discovering catalog
|
||||
entities from GitLab. The processor will crawl the GitLab instance and register
|
||||
entities matching the configured path. This can be useful as an alternative to
|
||||
The GitLab integration has a special entity provider for discovering catalog
|
||||
entities from GitLab. The entity provider will crawl the GitLab instance and register
|
||||
entities matching the configured paths. This can be useful as an alternative to
|
||||
static locations or manually adding things to the catalog.
|
||||
|
||||
To use the discovery processor, you'll need a GitLab integration
|
||||
[set up](locations.md) with a `token`. Then you can add a location target to the
|
||||
catalog configuration:
|
||||
To use the discovery provider, you'll need a GitLab integration
|
||||
[set up](locations.md) with a `token`. Then you can add a provider config per group
|
||||
to the catalog configuration:
|
||||
|
||||
```yaml
|
||||
catalog:
|
||||
providers:
|
||||
gitlab:
|
||||
yourProviderId:
|
||||
host: gitlab-host # Identifies one of the hosts set up in the integrations
|
||||
branch: main # Optional. Uses `master` as default
|
||||
group: example-group # Group and subgroup (if needed) to look for repositories
|
||||
entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml`
|
||||
```
|
||||
|
||||
As this provider is not one of the default providers, you will first need to install
|
||||
the gitlab catalog plugin:
|
||||
|
||||
```bash
|
||||
# From the Backstage root directory
|
||||
yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-gitlab
|
||||
```
|
||||
|
||||
Once you've done that, you'll also need to add the segment below to `packages/backend/src/plugins/catalog.ts`:
|
||||
|
||||
```ts
|
||||
/* packages/backend/src/plugins/catalog.ts */
|
||||
|
||||
import { GitlabDiscoveryEntityProvider } from '@backstage/plugin-catalog-backend-module-gitlab';
|
||||
|
||||
const builder = await CatalogBuilder.create(env);
|
||||
/** ... other processors and/or providers ... */
|
||||
builder.addEntityProvider(
|
||||
...GitlabDiscoveryEntityProvider.fromConfig(env.config, {
|
||||
logger: env.logger,
|
||||
schedule: env.scheduler.createScheduledTaskRunner({
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
}),
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
## Alternative processor
|
||||
|
||||
```yaml
|
||||
catalog:
|
||||
@@ -22,6 +63,9 @@ catalog:
|
||||
target: https://gitlab.com/group/subgroup/blob/main/catalog-info.yaml
|
||||
```
|
||||
|
||||
As alternative to the entity provider `GitlabDiscoveryEntityProvider`
|
||||
you can still use the `GitLabDiscoveryProcessor`.
|
||||
|
||||
Note the `gitlab-discovery` type, as this is not a regular `url` processor.
|
||||
|
||||
The target is composed of three parts:
|
||||
|
||||
@@ -52,11 +52,12 @@ learn how to contribute the integration yourself!
|
||||
The following table summarizes events that, depending on the plugins you have
|
||||
installed, may be captured.
|
||||
|
||||
| Action | Provided By | Subject |
|
||||
| ---------- | -------------- | --------------------------------------------------- |
|
||||
| `navigate` | Backstage Core | The URL of the page that was navigated to |
|
||||
| `click` | Backstage Core | The text of the link that was clicked on |
|
||||
| `search` | Backstage Core | The search term entered in any search bar component |
|
||||
| Action | Subject | Other Notes |
|
||||
| ---------- | --------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `navigate` | The URL of the page that was navigated to | |
|
||||
| `click` | The text of the link that was clicked on | The `to` attribute represents the URL clicked to |
|
||||
| `search` | The search term entered in any search bar component | The `searchTypes` attribute holds `types` constraining the search |
|
||||
| `discover` | The title of the search result that was clicked on | The `value` is the result rank. A `to` attribute is also provided |
|
||||
|
||||
If there is an event you'd like to see captured, please [open an
|
||||
issue][add-event] describing the event you want to see and the questions it
|
||||
|
||||
@@ -104,10 +104,10 @@ directly be used with a URL. Some example usages -
|
||||
|
||||
- [`read`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/plugins/catalog-backend/src/ingestion/processors/codeowners/read.ts#L24-L33) -
|
||||
Catalog using the `read` method to read the CODEOWNERS file in a repository.
|
||||
- [`readTree`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/techdocs-common/src/helpers.ts#L198-L220) -
|
||||
- [`readTree`](https://github.com/backstage/backstage/blob/84a8788/plugins/techdocs-node/src/helpers.ts#L146-L167) -
|
||||
TechDocs using the `readTree` method to download markdown files in order to
|
||||
generate the documentation site.
|
||||
- [`readTree`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/techdocs-common/src/stages/prepare/url.ts#L33-L54) -
|
||||
- [`readTree`](https://github.com/backstage/backstage/blob/cb4f0e4/plugins/techdocs-node/src/stages/prepare/url.ts#L51-L73) -
|
||||
TechDocs using `NotModifiedError` to maintain cache and speed up and limit the
|
||||
number of requests.
|
||||
- [`search`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.ts#L88-L108) -
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,678 @@
|
||||
# Release v1.3.0-next.2
|
||||
|
||||
## @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 55647ec7df: **BREAKING**: Server-to-server tokens that are authenticated by the `ServerTokenManager` now must have an `exp` claim that has not expired. Tokens where the `exp` claim is in the past or missing are considered invalid and will throw an error. This is a followup to the deprecation from the `1.2` release of Backstage where perpetual tokens were deprecated. Be sure to update any usage of the `getToken()` method to have it be called every time a token is needed. Do not store tokens for later use.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
|
||||
## @backstage/plugin-pagerduty@0.4.0-next.2
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- b157c2eb1c: **Breaking**: Use identityApi to provide auth token for pagerduty API calls.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
|
||||
## @backstage/plugin-scaffolder@1.3.0-next.2
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- dc39366bdb: - Added a new page under `/create/tasks` to show tasks that have been run by the Scaffolder.
|
||||
- Ability to filter these tasks by the signed in user, and all tasks.
|
||||
- Added optional method to the `ScaffolderApi` interface called `listTasks` to get tasks with an required `filterByOwnership` parameter.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ac0c7e45ee: Fixes review mask in `MultistepJsonForm` to work as documented. `show: true` no longer needed when mask is set.
|
||||
- fd505f40c0: Handle binary files and files that are too large during dry-run content upload.
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-catalog-common@1.0.3-next.1
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
|
||||
## @backstage/plugin-scaffolder-backend@1.3.0-next.2
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- ce0d8d7eb1: Fixed a bug in `publish:github` action that didn't permit to add users as collaborators.
|
||||
This fix required changing the way parameters are passed to the action.
|
||||
In order to add a team as collaborator, now you must use the `team` field instead of `username`.
|
||||
In order to add a user as collaborator, you must use the `user` field.
|
||||
|
||||
It's still possible to use the field `username` but is deprecated in favor of `team`.
|
||||
|
||||
```yaml
|
||||
- id: publish
|
||||
name: Publish
|
||||
action: publish:github
|
||||
input:
|
||||
repoUrl: ...
|
||||
collaborators:
|
||||
- access: ...
|
||||
team: my_team
|
||||
- access: ...
|
||||
user: my_username
|
||||
```
|
||||
|
||||
- 582003a059: - Added an optional `list` method on the `TaskBroker` and `TaskStore` interface to list tasks by an optional `userEntityRef`
|
||||
- Implemented a `list` method on the `DatabaseTaskStore` class to list tasks by an optional `userEntityRef`
|
||||
- Added a route under `/v2/tasks` to list tasks by a `userEntityRef` using the `createdBy` query parameter
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
|
||||
## @backstage/backend-tasks@0.3.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/backend-test-utils@0.1.25-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/cli@0.17.2-next.2
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/cli@0.17.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 026cfe525a: Fix the public path configuration of the frontend app build so that a trailing `/` is always appended when needed.
|
||||
- 9002ebd76b: Updated dependency `@rollup/plugin-commonjs` to `^22.0.0`.
|
||||
- 1a33e8b287: Updated dependency `minimatch` to `5.1.0`.
|
||||
|
||||
## @backstage/core-components@0.9.5-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ee2cd642c5: Updated dependency `rc-progress` to `3.3.3`.
|
||||
- 1cf9caecd6: fix Sidebar Contexts deprecation message
|
||||
|
||||
## @backstage/create-app@0.4.28-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- aaf7652084: Bump version of `cypress` in newly scaffolded Backstage Applications. To apply this change to your own instance, please make the following change to `packages/app/package.json` under `devDependencies`.
|
||||
|
||||
```diff
|
||||
- "cypress": "^7.3.0",
|
||||
+ "cypress": "^9.7.0",
|
||||
```
|
||||
|
||||
## @backstage/integration@1.2.1-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e37c71b5a4: Updated to support deployments of Azure DevOps Server under TFS or similar sub path
|
||||
|
||||
## @backstage/search-common@0.3.5-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
|
||||
## @techdocs/cli@1.1.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f96e98f4cd: Updated dependency `cypress` to `^10.0.0`.
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-techdocs-node@1.1.2-next.2
|
||||
|
||||
## @backstage/techdocs-common@0.11.16-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-techdocs-node@1.1.2-next.2
|
||||
|
||||
## @backstage/plugin-adr-backend@0.1.1-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
|
||||
## @backstage/plugin-airbrake-backend@0.2.6-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-app-backend@0.3.33-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-auth-backend@0.14.1-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- bc6fb57094: Updated dependency `passport` to `^0.6.0`.
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-auth-node@0.2.2-next.2
|
||||
|
||||
## @backstage/plugin-auth-node@0.2.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-azure-devops-backend@0.3.12-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-badges-backend@0.1.27-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-bazaar-backend@0.1.17-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/backend-test-utils@0.1.25-next.2
|
||||
|
||||
## @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/plugin-catalog-common@1.0.3-next.1
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/plugin-permission-node@0.6.2-next.2
|
||||
|
||||
## @backstage/plugin-catalog-backend-module-aws@0.1.6-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/backend-tasks@0.3.2-next.2
|
||||
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
|
||||
## @backstage/plugin-catalog-backend-module-azure@0.1.4-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b8884fd579: Add a new provider `AzureDevOpsEntityProvider` as replacement for `AzureDevOpsDiscoveryProcessor`.
|
||||
|
||||
In order to migrate from the `AzureDevOpsDiscoveryProcessor` you need to apply
|
||||
the following changes:
|
||||
|
||||
**Before:**
|
||||
|
||||
```yaml
|
||||
# app-config.yaml
|
||||
|
||||
catalog:
|
||||
locations:
|
||||
- type: azure-discovery
|
||||
target: https://dev.azure.com/myorg/myproject/_git/service-*?path=/catalog-info.yaml
|
||||
```
|
||||
|
||||
```ts
|
||||
/* packages/backend/src/plugins/catalog.ts */
|
||||
|
||||
import { AzureDevOpsDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-azure';
|
||||
|
||||
const builder = await CatalogBuilder.create(env);
|
||||
/** ... other processors ... */
|
||||
builder.addProcessor(new AzureDevOpsDiscoveryProcessor(env.reader));
|
||||
```
|
||||
|
||||
**After:**
|
||||
|
||||
```yaml
|
||||
# app-config.yaml
|
||||
|
||||
catalog:
|
||||
providers:
|
||||
azureDevOps:
|
||||
anyProviderId:
|
||||
host: selfhostedazure.yourcompany.com # This is only really needed for on-premise user, defaults to dev.azure.com
|
||||
organization: myorg # For on-premise this would be your Collection
|
||||
project: myproject
|
||||
repository: service-*
|
||||
path: /catalog-info.yaml
|
||||
```
|
||||
|
||||
```ts
|
||||
/* packages/backend/src/plugins/catalog.ts */
|
||||
|
||||
import { AzureDevOpsEntityProvider } from '@backstage/plugin-catalog-backend-module-azure';
|
||||
|
||||
const builder = await CatalogBuilder.create(env);
|
||||
/** ... other processors and/or providers ... */
|
||||
builder.addEntityProvider(
|
||||
AzureDevOpsEntityProvider.fromConfig(env.config, {
|
||||
logger: env.logger,
|
||||
schedule: env.scheduler.createScheduledTaskRunner({
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
}),
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
Visit <https://backstage.io/docs/integrations/azure/discovery> for more details and options on configuration.
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/backend-tasks@0.3.2-next.2
|
||||
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
|
||||
## @backstage/plugin-catalog-backend-module-bitbucket@0.2.0-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
|
||||
## @backstage/plugin-catalog-backend-module-gerrit@0.1.1-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/backend-tasks@0.3.2-next.2
|
||||
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
|
||||
## @backstage/plugin-catalog-backend-module-github@0.1.4-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/backend-tasks@0.3.2-next.2
|
||||
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
|
||||
## @backstage/plugin-catalog-backend-module-gitlab@0.1.4-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
|
||||
## @backstage/plugin-catalog-common@1.0.3-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7d8acfc32e: Replaced all usages of `@backstage/search-common` with `@backstage/plugin-search-common`
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
|
||||
## @backstage/plugin-code-coverage-backend@0.1.31-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
|
||||
## @backstage/plugin-codescene@0.1.1-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ee2cd642c5: Updated dependency `rc-progress` to `3.3.3`.
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
|
||||
## @backstage/plugin-cost-insights@0.11.28-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2fc98ac50c: Fix broken app-config in the example in the README
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
|
||||
## @backstage/plugin-graphql-backend@0.1.23-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-jenkins-backend@0.1.23-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-auth-node@0.2.2-next.2
|
||||
|
||||
## @backstage/plugin-kafka-backend@0.2.26-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-kubernetes@0.6.6-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 5553f09e80: ability to configure refresh interval on Kubernetes tab
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
|
||||
## @backstage/plugin-kubernetes-backend@0.6.0-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-org@0.5.6-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 306d0b4fdd: Added the ability to use an additional `filter` when fetching groups in `MyGroupsSidebarItem` component. Example:
|
||||
|
||||
```diff
|
||||
// app/src/components/Root/Root.tsx
|
||||
<SidebarPage>
|
||||
<Sidebar>
|
||||
//...
|
||||
<SidebarGroup label="Menu" icon={<MenuIcon />}>
|
||||
{/* Global nav, not org-specific */}
|
||||
//...
|
||||
<SidebarItem icon={HomeIcon} to="catalog" text="Home" />
|
||||
<MyGroupsSidebarItem
|
||||
singularTitle="My Squad"
|
||||
pluralTitle="My Squads"
|
||||
icon={GroupIcon}
|
||||
+ filter={{ 'spec.type': 'team' }}
|
||||
/>
|
||||
//...
|
||||
</SidebarGroup>
|
||||
</ Sidebar>
|
||||
</SidebarPage>
|
||||
```
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
|
||||
## @backstage/plugin-periskop-backend@0.1.4-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-permission-backend@0.5.8-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-auth-node@0.2.2-next.2
|
||||
- @backstage/plugin-permission-node@0.6.2-next.2
|
||||
|
||||
## @backstage/plugin-permission-node@0.6.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-auth-node@0.2.2-next.2
|
||||
|
||||
## @backstage/plugin-proxy-backend@0.2.27-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-rollbar-backend@0.1.30-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.8-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-scaffolder-backend@1.3.0-next.2
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
|
||||
## @backstage/plugin-scaffolder-backend-module-rails@0.4.1-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-scaffolder-backend@1.3.0-next.2
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
|
||||
## @backstage/plugin-search@0.8.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 5388e6bdc5: Fixed a bug that could cause analytics events in other parts of Backstage to capture nonsensical values resembling search modal state under some circumstances.
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
|
||||
## @backstage/plugin-search-backend@0.5.3-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7d8acfc32e: `RouterOptions` and `createRouter` now marked as public exports
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-search-backend-node@0.6.2-next.2
|
||||
- @backstage/plugin-auth-node@0.2.2-next.2
|
||||
- @backstage/plugin-permission-node@0.6.2-next.2
|
||||
|
||||
## @backstage/plugin-search-backend-module-elasticsearch@0.1.5-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7d8acfc32e: Additional types now exported publicly:
|
||||
|
||||
- ElasticSearchAgentOptions
|
||||
- ElasticSearchConcreteQuery
|
||||
- ElasticSearchQueryTranslator
|
||||
- ElasticSearchConnectionConstructor,
|
||||
- ElasticSearchTransportConstructor,
|
||||
- ElasticSearchNodeOptions,
|
||||
- ElasticSearchOptions,
|
||||
- ElasticSearchAuth,
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/plugin-search-backend-node@0.6.2-next.2
|
||||
|
||||
## @backstage/plugin-search-backend-module-pg@0.3.4-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-search-backend-node@0.6.2-next.2
|
||||
|
||||
## @backstage/plugin-search-backend-node@0.6.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7d8acfc32e: Replaced all `@beta` exports with `@public` exports
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/backend-tasks@0.3.2-next.2
|
||||
|
||||
## @backstage/plugin-search-common@0.3.5-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7d8acfc32e: `@beta` exports now replaced with `@public` exports
|
||||
|
||||
## @backstage/plugin-sonarqube@0.3.6-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ee2cd642c5: Updated dependency `rc-progress` to `3.3.3`.
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
|
||||
## @backstage/plugin-tech-insights-backend@0.4.1-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/backend-tasks@0.3.2-next.2
|
||||
- @backstage/plugin-tech-insights-node@0.3.1-next.1
|
||||
|
||||
## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.17-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-tech-insights-node@0.3.1-next.1
|
||||
|
||||
## @backstage/plugin-tech-insights-node@0.3.1-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
|
||||
## @backstage/plugin-techdocs-backend@1.1.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 61fba6e50b: In order to ensure a good, stable TechDocs user experience when running TechDocs with `techdocs.builder` set to `local`, the number of concurrent builds has been limited to 10. Any additional builds requested concurrently will be queued and handled as prior builds complete. In the unlikely event that you need to handle more concurrent builds, consider scaling out your TechDocs backend deployment or using the `external` option for `techdocs.builder`.
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/plugin-catalog-common@1.0.3-next.1
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/plugin-techdocs-node@1.1.2-next.2
|
||||
|
||||
## @backstage/plugin-techdocs-node@1.1.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
|
||||
## @backstage/plugin-todo-backend@0.1.30-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
|
||||
## example-app@0.2.72-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-scaffolder@1.3.0-next.2
|
||||
- @backstage/cli@0.17.2-next.2
|
||||
- @backstage/plugin-pagerduty@0.4.0-next.2
|
||||
- @backstage/plugin-search-common@0.3.5-next.1
|
||||
- @backstage/plugin-cost-insights@0.11.28-next.2
|
||||
- @backstage/plugin-catalog-common@1.0.3-next.1
|
||||
- @backstage/plugin-kubernetes@0.6.6-next.2
|
||||
- @backstage/core-components@0.9.5-next.2
|
||||
- @backstage/plugin-search@0.8.2-next.2
|
||||
- @backstage/plugin-org@0.5.6-next.2
|
||||
|
||||
## example-backend@0.2.72-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-scaffolder-backend@1.3.0-next.2
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-search-backend@0.5.3-next.2
|
||||
- @backstage/plugin-auth-backend@0.14.1-next.2
|
||||
- @backstage/plugin-search-backend-module-elasticsearch@0.1.5-next.2
|
||||
- @backstage/integration@1.2.1-next.2
|
||||
- @backstage/plugin-techdocs-backend@1.1.2-next.2
|
||||
- @backstage/plugin-search-backend-node@0.6.2-next.2
|
||||
- example-app@0.2.72-next.2
|
||||
- @backstage/backend-tasks@0.3.2-next.2
|
||||
- @backstage/plugin-app-backend@0.3.33-next.2
|
||||
- @backstage/plugin-auth-node@0.2.2-next.2
|
||||
- @backstage/plugin-azure-devops-backend@0.3.12-next.2
|
||||
- @backstage/plugin-badges-backend@0.1.27-next.2
|
||||
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
||||
- @backstage/plugin-code-coverage-backend@0.1.31-next.2
|
||||
- @backstage/plugin-graphql-backend@0.1.23-next.2
|
||||
- @backstage/plugin-jenkins-backend@0.1.23-next.2
|
||||
- @backstage/plugin-kafka-backend@0.2.26-next.2
|
||||
- @backstage/plugin-kubernetes-backend@0.6.0-next.2
|
||||
- @backstage/plugin-permission-backend@0.5.8-next.2
|
||||
- @backstage/plugin-permission-node@0.6.2-next.2
|
||||
- @backstage/plugin-proxy-backend@0.2.27-next.1
|
||||
- @backstage/plugin-rollbar-backend@0.1.30-next.2
|
||||
- @backstage/plugin-scaffolder-backend-module-rails@0.4.1-next.1
|
||||
- @backstage/plugin-search-backend-module-pg@0.3.4-next.2
|
||||
- @backstage/plugin-tech-insights-backend@0.4.1-next.2
|
||||
- @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.17-next.1
|
||||
- @backstage/plugin-tech-insights-node@0.3.1-next.1
|
||||
- @backstage/plugin-todo-backend@0.1.30-next.2
|
||||
|
||||
## @internal/plugin-todo-list-backend@1.0.2-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.14.0-next.2
|
||||
- @backstage/plugin-auth-node@0.2.2-next.2
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: v1.3.0
|
||||
title: v1.3.0
|
||||
description: Backstage Release v1.3.0
|
||||
---
|
||||
|
||||
These are the release notes for the v1.3.0 release of [Backstage](https://backstage.io/).
|
||||
|
||||
A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done.
|
||||
|
||||
## Highlights
|
||||
|
||||
### Scaffolder Dry Run and Template Editor
|
||||
|
||||
The scaffolder plugin now has a new template editor in addition to the form editor, which is accessible via the context menu on the top right hand corner of the Create page. It allows you to load a template from a local directory, edit it with a preview, execute it in dry-run mode, and view the results. Note that the [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) must be supported by your browser for this to be available.
|
||||
|
||||
### TypeScript 4.7
|
||||
|
||||
The recommended TypeScript version has been bumped to `~4.7.0`, and that’s what the main Backstage repository uses right now for its builds. Each Backstage project manages their version separately however, so there is no rush or immediate effect on users - you can update the `typescript` dependency in your root `package.json` once you feel ready to do so.
|
||||
|
||||
### Expiring Backend Tokens
|
||||
|
||||
In 1.2 we introduced expiry times for server-to-server authentication tokens issued from the standard `TokenManager`. At that point in time, the expiry was only added to tokens and not yet enforced. In this release however, it is now also enforced, meaning that expired tokens are considered invalid and will be rejected.
|
||||
|
||||
### Discovery providers
|
||||
|
||||
Several new [entity providers](https://backstage.io/docs/features/software-catalog/life-of-an-entity) have been contributed as replacements for their corresponding discovery processors. Entity providers allow for more control and are [recommended](https://backstage.io/docs/features/software-catalog/external-integrations) over their processing counterparts.
|
||||
|
||||
- `AzureDevOpsEntityProvider` as replacement for `AzureDevOpsDiscoveryProcessor`. PR [#11604](https://github.com/backstage/backstage/pull/11604) contributed by [@goenning](https://github.com/goenning)
|
||||
- `GitlabDiscoveryEntityProvider` as replacement for `GitLabDiscoveryProcessor`. PR [#11886](https://github.com/backstage/backstage/pull/11886) contributed by [@ivangonzalezacuna](https://github.com/ivangonzalezacuna)
|
||||
- `BitbucketCloudEntityProvider` as a replacement for `BitbucketDiscoveryProcessor` (for Bitbucket Cloud only). PR [#11345](https://github.com/backstage/backstage/pull/11345) contributed by [@pjungermann](https://github.com/pjungermann)
|
||||
|
||||
### New plugin: Vault
|
||||
|
||||
View secrets from [HashiCorp Vault](https://www.vaultproject.io/) alongside your components. PR [#11423](https://github.com/backstage/backstage/pull/11423) contributed by [@ivangonzalezacuna](https://github.com/ivangonzalezacuna)
|
||||
|
||||
### New plugin: GitHub Pull Requests Board
|
||||
|
||||
GitHub Pull Requests Board Plugin is a board that helps you visualize all open pull requests from all repositories owned by a team, with the main goal of reducing the time from opening a PR to merging it. PR [#11043](https://github.com/backstage/backstage/pull/11043) contributed by [@gregorytalita](https://github.com/gregorytalita)
|
||||
|
||||
### New plugin: Dynatrace
|
||||
|
||||
Displays tracing data from [Dynatrace](https://www.dynatrace.com/) alongside your components. PR [#11754](https://github.com/backstage/backstage/pull/11754) contributed by [@isand3r](https://github.com/isand3r)
|
||||
|
||||
## Security Fixes
|
||||
|
||||
`@backstage/plugin-scaffolder-backend`, please upgrade to the latest version if you are using this module.
|
||||
`@backstage/plugin-techdocs-node`, please upgrade to the latest version if you are using this module.
|
||||
|
||||
## Upgrade path
|
||||
|
||||
We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated).
|
||||
|
||||
## Links and References
|
||||
|
||||
Below you can find a list of links and references to help you learn about and start using this new release.
|
||||
|
||||
- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/)
|
||||
- [GitHub repository](https://github.com/backstage/backstage)
|
||||
- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy)
|
||||
- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support
|
||||
- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.3.0-changelog.md)
|
||||
- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap), and [Plugins](https://backstage.io/plugins)
|
||||
|
||||
Sign up for our [newsletter](https://mailchi.mp/spotify/backstage-community) if you want to be informed about what is happening in the world of Backstage.
|
||||
Reference in New Issue
Block a user