Merge pull request #29572 from aramissennyeydd/sennyeya/remove-old-docs

chore: remove old backend system guides
This commit is contained in:
Andre Wanlin
2025-05-02 14:17:38 -05:00
committed by GitHub
40 changed files with 21 additions and 4400 deletions
@@ -1,88 +0,0 @@
---
id: discovery--old
title: AWS S3 Discovery
sidebar_label: Discovery
# prettier-ignore
description: Automatically discovering catalog entities from an AWS S3 Bucket
---
:::info
This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./discovery.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The AWS S3 integration has a special entity provider for discovering catalog
entities located in an S3 Bucket. If you have a bucket that contains multiple
catalog files, and you want to automatically discover them, you can use this
provider. The provider will crawl your S3 bucket and register entities
matching the configured path. This can be useful as an alternative to static
locations or manually adding things to the catalog.
To use the entity provider, you'll need an AWS S3 integration
[set up](locations.md) with `accessKeyId` and `secretAccessKey`, and/or
a `roleArn` or none of these (e.g., profile- or instance-based credentials).
At production deployments, you likely manage these with the permissions attached
to your instance.
In your configuration, you add a provider config per bucket:
```yaml
# app-config.yaml
catalog:
providers:
awsS3:
yourProviderId: # identifies your dataset / provider independent of config changes
bucketName: sample-bucket
prefix: prefix/ # optional
region: us-east-2 # optional, uses the default region otherwise
schedule: # same options as in SchedulerServiceTaskScheduleDefinition
# supports cron, ISO duration, "human duration" as used in code
frequency: { minutes: 30 }
# supports ISO duration, "human duration" as used in code
timeout: { minutes: 3 }
```
For simple setups, you can omit the provider ID at the config
which has the same effect as using `default` for it.
```yaml
# app-config.yaml
catalog:
providers:
awsS3:
# uses "default" as provider ID
bucketName: sample-bucket
prefix: prefix/ # optional
region: us-east-2 # optional, uses the default region otherwise
schedule: # same options as in SchedulerServiceTaskScheduleDefinition
# supports cron, ISO duration, "human duration" as used in code
frequency: { minutes: 30 }
# supports ISO duration, "human duration" as used in code
timeout: { minutes: 3 }
```
As this provider is not one of the default providers, you will first need to install
the AWS catalog plugin:
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-aws
```
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 { AwsS3EntityProvider } from '@backstage/plugin-catalog-backend-module-aws';
const builder = await CatalogBuilder.create(env);
/** ... other processors and/or providers ... */
builder.addEntityProvider(
AwsS3EntityProvider.fromConfig(env.config, {
logger: env.logger,
scheduler: env.scheduler,
}),
);
```
+1 -1
View File
@@ -7,7 +7,7 @@ description: Automatically discovering catalog entities from an AWS S3 Bucket
---
:::info
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](https://github.com/backstage/backstage/blob/v1.37.0/docs/integrations/aws-s3/discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The AWS S3 integration has a special entity provider for discovering catalog
-186
View File
@@ -1,186 +0,0 @@
---
id: discovery--old
title: Azure DevOps Discovery
sidebar_label: Discovery
# prettier-ignore
description: Automatically discovering catalog entities from repositories in an Azure DevOps organization
---
:::info
This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./discovery.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
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
At your configuration, you add one or more provider configs:
```yaml title="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
schedule: # optional; same options as in SchedulerServiceTaskScheduleDefinition
# supports cron, ISO duration, "human duration" as used in code
frequency: { minutes: 30 }
# supports ISO duration, "human duration" as used in code
timeout: { minutes: 3 }
yourSecondProviderId: # identifies your dataset / provider independent of config changes
organization: myorg
project: '*' # this will match all projects
repository: '*' # this will match all repos
path: /catalog-info.yaml
anotherProviderId: # another identifier
organization: myorg
project: myproject
repository: '*' # this will match all repos
path: /src/*/catalog-info.yaml # this will search for files deep inside the /src folder
yetAnotherProviderId: # guess, what? Another one :)
host: selfhostedazure.yourcompany.com
organization: myorg
project: myproject
branch: development
```
The parameters available are:
- **`host:`** _(optional)_ 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:`** _(required)_ Your project slug. Wildcards are supported as shown on the examples above. Using '\*' will search all projects. For a project name containing spaces, use both single and double quotes as in `project: '"My Project Name"'`.
- **`repository:`** _(optional)_ The repository name. Wildcards are supported as show on the examples above. If not set, all repositories will be searched.
- **`path:`** _(optional)_ Where to find catalog-info.yaml files. Defaults to /catalog-info.yaml.
- **`branch:`** _(optional)_ The branch name to use.
- **`schedule`**:
- **`frequency`**:
How often you want the task to run. The system does its best to avoid overlapping invocations.
- **`timeout`**:
The maximum amount of time that a single task invocation can take.
- **`initialDelay`** _(optional)_:
The amount of time that should pass before the first invocation happens.
- **`scope`** _(optional)_:
`'global'` or `'local'`. Sets the scope of concurrency control.
_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).
- To use branch parameters, it is necessary that the desired branch be added to the "Searchable branches" list within Azure DevOps Repositories. To do this, follow the instructions below:
1. Access your Azure DevOps and open the repository in which you want to add the branch.
2. Click on "Settings" in the lower-left corner of the screen.
3. Select the "Options" option in the left navigation bar.
4. In the "Searchable branches" section, click on the "Add" button to add a new branch.
5. In the window that appears, enter the name of the branch you want to add and click "Add".
6. The added branch will now appear in the "Searchable branches" list.
It may take some time before the branch is indexed and searchable.
As this provider is not one of the default providers, you will first need to install
the Azure catalog plugin:
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-azure
```
Once you've done that, you'll also need to add the segment below to `packages/backend/src/plugins/catalog.ts`:
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { AzureDevOpsEntityProvider } from '@backstage/plugin-catalog-backend-module-azure';
const builder = await CatalogBuilder.create(env);
/** ... other processors and/or providers ... */
/* highlight-add-start */
builder.addEntityProvider(
AzureDevOpsEntityProvider.fromConfig(env.config, {
logger: env.logger,
// optional: alternatively, use scheduler with schedule defined in app-config.yaml
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 30 },
timeout: { minutes: 3 },
}),
// optional: alternatively, use schedule
scheduler: env.scheduler,
}),
);
/* highlight-add-end */
```
## Alternative Processor
As an alternative to the entity provider `AzureDevOpsEntityProvider`, you can still use the `AzureDevopsDiscoveryProcessor`.
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { AzureDevOpsDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-azure';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-next-line */
builder.addProcessor(
AzureDevOpsDiscoveryProcessor.fromConfig(env.config, {
logger: env.logger,
}),
);
// ..
}
```
```yaml
catalog:
locations:
# Scan all repositories for a catalog-info.yaml in the root of the default branch
- type: azure-discovery
target: https://dev.azure.com/myorg/myproject
# Or use a custom pattern for a subset of all repositories with default repository
- type: azure-discovery
target: https://dev.azure.com/myorg/myproject/_git/service-*
# Or use a custom file format and location
- type: azure-discovery
target: https://dev.azure.com/myorg/myproject/_git/*?path=/src/*/catalog-info.yaml
# And optionally provide a specific branch name using the version parameter
- type: azure-discovery
target: https://dev.azure.com/myorg/myproject/_git/*?path=/catalog-info.yaml&version=GBtopic/catalog-info
```
Note the `azure-discovery` type, as this is not a regular `url` processor.
When using a custom pattern, the target is composed of these parts:
- The base instance URL, `https://dev.azure.com` in this case
- The organization name which is required, `myorg` in this case
- The project name which is optional, `myproject` in this case. This defaults to \*, which scans all the projects where the token has access to.
- The repository blob to scan, which accepts \* wildcard tokens and must be
added after `_git/`. This can simply be `*` to scan all repositories in the
project.
- 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.
- The repository branch to scan which is optional, `topic/catalog-info` in this case. If omitted, the repo's default branch will be scanned. The `GB` prefix is required, as this is how Azure DevOps identifies the version as a branch.
+1 -1
View File
@@ -7,7 +7,7 @@ description: Automatically discovering catalog entities from repositories in an
---
:::info
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](https://github.com/backstage/backstage/blob/v1.37.0/docs/integrations/azure/discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Azure DevOps integration has a special entity provider for discovering
-273
View File
@@ -1,273 +0,0 @@
---
id: org--old
title: Microsoft Entra Tenant Data
sidebar_label: Org Data
# prettier-ignore
description: Importing users and groups from Microsoft Entra ID into Backstage
---
:::info
This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./org.md) instead.Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Backstage catalog can be set up to ingest organizational data - users and
teams - directly from a tenant in Microsoft Entra ID via the
Microsoft Graph API.
## Installation
The package is not installed by default, therefore you have to add `@backstage/plugin-catalog-backend-module-msgraph` to your backend package.
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-msgraph
```
Next add the basic configuration to `app-config.yaml`
```yaml title="app-config.yaml"
catalog:
providers:
microsoftGraphOrg:
default:
tenantId: ${AZURE_TENANT_ID}
user:
filter: accountEnabled eq true and userType eq 'member'
group:
filter: >
securityEnabled eq false
and mailEnabled eq true
and groupTypes/any(c:c+eq+'Unified')
schedule:
frequency: PT1H
timeout: PT50M
```
Finally, register the plugin in `catalog.ts`.
For large organizations, this plugin can take a long time, so be careful setting low frequency / timeouts and importing a large amount of users / groups for the first try.
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { MicrosoftGraphOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-msgraph';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-start */
builder.addEntityProvider(
MicrosoftGraphOrgEntityProvider.fromConfig(env.config, {
logger: env.logger,
scheduler: env.scheduler,
}),
);
/* highlight-add-end */
// ..
}
```
## Authenticating with Microsoft Graph
### Local Development
For a local dev environment, it's recommended you have the Azure CLI or Azure PowerShell installed, and are logged in to those.
Alternatively you can use VSCode with the Azure extension if you install `@azure/identity-vscode`.
When these are set up, the plugin will authenticate with the Microsoft Graph API without you needing to configure any credentials, or granting any special permissions.
If you can't do this, you'll have to create an App Registration.
### App Registration
If none of the other authentication methods work, you can create an app registration in the azure portal.
By default the graph plugin requires the following Application permissions (not Delegated) for Microsoft Graph:
- `GroupMember.Read.All`
- `User.Read.All`
If your organization required Admin Consent for these permissions, that will need to be granted.
When authenticating with a ClientId/ClientSecret, you can either set the `AZURE_TENANT_ID`, `AZURE_CLIENT_ID` and `AZURE_CLIENT_SECRET` environment variables, or specify the values in configuration
```yaml
microsoftGraphOrg:
default:
##...
clientId: 9ef1aac6-b454-4e69-9cf5-7199df049281
clientSecret: REDACTED
```
To authenticate with a certificate rather than a client secret, you can set the `AZURE_TENANT_ID`, `AZURE_CLIENT_ID` and `AZURE_CLIENT_CERTIFICATE_PATH` environments
### Managed Identity
If deploying to resources that supports Managed Identity, and has identities configured (e.g. Azure App Services, Azure Container Apps), Managed Identity should be picked up without any additional configuration.
If your app has multiple managed identities, you may need to set the `AZURE_CLIENT_ID` environment variable to tell Azure Identity which identity to use.
To grant the managed identity the same permissions as mentioned in _App Registration_ above, [please follow this guide](https://docs.microsoft.com/en-us/azure/app-service/tutorial-connect-app-access-microsoft-graph-as-app-javascript?tabs=azure-powershell)
## Filtering imported Users and Groups
By default, the plugin will import all users and groups from your directory.
This can be customized through [filters](https://learn.microsoft.com/en-us/graph/filter-query-parameter) and [search](https://learn.microsoft.com/en-us/graph/search-query-parameter) queries. Keep in mind that if you omit filters and search queries for the user or group properties, the plugin will automatically import all available users or groups.
### Groups
A smaller set of groups can be obtained by configuring a search query or a filter.
If both `filter` and `search` are provided, then groups must match both to be ingested.
```yaml
microsoftGraphOrg:
providerId:
group:
filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified')
search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
```
In addition to these groups, one additional group will be created for your organization.
All imported groups will be a child of this group.
### Users
There are two modes for importing users - You can import all user objects matching a `filter`.
```yaml
microsoftGraphOrg:
providerId:
user:
filter: accountEnabled eq true and userType eq 'member'
```
Alternatively you can import users that are members of specific groups.
For each group matching the `search` and `filter` query, each group member will be imported.
Only direct group members will be imported, not transient users.
```yaml
microsoftGraphOrg:
providerId:
userGroupMember:
filter: "displayName eq 'Backstage Users'"
search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
```
### User photos
By default, the photos of users will be fetched and added to each user entity. For huge organizations this may be unfeasible, as it will take a _very_ long time, and can be disabled by setting `loadPhotos` to `false`:
```yaml
microsoftGraphOrg:
providerId:
user:
filter: ...
loadPhotos: false
```
## Customizing Transformation
Ingested entities can be customized by providing custom transformers.
These can be used to completely replace the built in logic, or used to tweak it by using the default transformers (`defaultGroupTransformer`, `defaultUserTransformer` and `defaultOrganizationTransformer`
Entities can also be excluded from backstage by returning `undefined`.
These Transformers are be registered when configuring `MicrosoftGraphOrgEntityProvider`
```ts
builder.addEntityProvider(
MicrosoftGraphOrgEntityProvider.fromConfig(env.config, {
// ...
/* highlight-add-start */
groupTransformer: myGroupTransformer,
userTransformer: myUserTransformer,
organizationTransformer: myOrganizationTransformer,
/* highlight-add-end */
}),
);
```
When using custom transformers, you may want to customize the data returned.
Several configuration options can be provided to tweak the Microsoft Graph query to get the data you need
```yaml
microsoftGraphOrg:
providerId:
user:
expand: manager
group:
expand: member
select: ['id', 'displayName', 'description']
```
The following provides an example of each kind of transformer
```ts
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
import {
defaultGroupTransformer,
defaultUserTransformer,
defaultOrganizationTransformer,
} from '@backstage/plugin-catalog-backend-module-msgraph';
import { GroupEntity, UserEntity } from '@backstage/catalog-model';
// This group transformer completely replaces the built in logic with custom logic.
export async function myGroupTransformer(
group: MicrosoftGraph.Group,
groupPhoto?: string,
): Promise<GroupEntity | undefined> {
return {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: group.id!,
annotations: {},
},
spec: {
type: 'Microsoft Entra ID',
children: [],
},
};
}
// This user transformer makes use of the built in logic, but also sets the description field
export async function myUserTransformer(
graphUser: MicrosoftGraph.User,
userPhoto?: string,
): Promise<UserEntity | undefined> {
const backstageUser = await defaultUserTransformer(graphUser, userPhoto);
if (backstageUser) {
backstageUser.metadata.description = 'Loaded from Microsoft Entra ID';
}
return backstageUser;
}
// Example organization transformer that removes the organization group completely
export async function myOrganizationTransformer(
graphOrganization: MicrosoftGraph.Organization,
): Promise<GroupEntity | undefined> {
return undefined;
}
```
## Troubleshooting
### No data
First check your logs for the message `Reading msgraph users and groups`.
If you don't see this, check you've registered the provider, and that the schedule is valid
If you see a log entry `Read 0 msgraph users and 0 msgraph groups`, check your search and filter arguments.
If you see the start message (`Reading msgraph users and groups`) but no end message (`Read X msgraph users and Y msgraph groups`), then it is likely the job is taking a long time due to a large volume of data.
The default behavior is to import all users and groups, which is often more data than needed.
Try importing a smaller set of data (e.g. `filter: displayName eq 'John Smith'`).
### Authentication / Token Errors
See [Troubleshooting Azure Identity Authentication Issues](https://aka.ms/azsdk/js/identity/troubleshoot)
### Error while reading users from Microsoft Graph: Authorization_RequestDenied - Insufficient privileges to complete the operation
- Make sure you've granted all the required permissions to your application registration or managed identity
- Make sure the permissions are `Application` permissions rather than `Delegated`
- If your organization has configured "Admin consent" to be required, make sure this has been granted for your application permissions
- If your group queries are returning Microsoft Teams groups, you may need to grant addition permissions (e.g. `Team.ReadBasic.All`, `TeamMember.Read.All`)
- If you've added additional `select` or `expand` fields, those may need additional permissions granted
+1 -1
View File
@@ -7,7 +7,7 @@ description: Importing users and groups from Microsoft Entra ID into Backstage
---
:::info
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./org--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](https://github.com/backstage/backstage/blob/v1.37.0/docs/integrations/azure/org--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Backstage catalog can be set up to ingest organizational data - users and
@@ -1,123 +0,0 @@
---
id: discovery--old
title: Bitbucket Server Discovery
sidebar_label: Discovery
# prettier-ignore
description: Automatically discovering catalog entities from repositories in Bitbucket Server
---
:::info
This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./discovery.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Bitbucket Server integration has a special entity provider for discovering
catalog files located in Bitbucket Server.
The provider will search your Bitbucket Server account and register catalog files matching the configured path
as Location entity and via following processing steps add all contained catalog entities.
This can be useful as an alternative to static locations or manually adding things to the catalog.
## Installation
You will have to add the entity provider in the catalog initialization code of your
backend. The provider is not installed by default, therefore you have to add a
dependency to `@backstage/plugin-catalog-backend-module-bitbucket-server` to your backend
package.
```bash
# From your Backstage root directory
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-bitbucket-server
```
And then add the entity provider to your catalog builder:
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { BitbucketServerEntityProvider } from '@backstage/plugin-catalog-backend-module-bitbucket-server';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-start */
builder.addEntityProvider(
BitbucketServerEntityProvider.fromConfig(env.config, {
logger: env.logger,
scheduler: env.scheduler,
}),
);
/* highlight-add-end */
// ..
}
```
## Configuration
To use the entity provider, you'll need a [Bitbucket Server integration set up](locations.md).
Additionally, you need to configure your entity provider instance(s):
```yaml title="app-config.yaml"
catalog:
providers:
bitbucketServer:
yourProviderId: # identifies your ingested dataset
host: 'bitbucket.mycompany.com'
catalogPath: /catalog-info.yaml # default value
filters: # optional
projectKey: '^apis-.*$' # optional; RegExp
repoSlug: '^service-.*$' # optional; RegExp
skipArchivedRepos: true # optional; boolean
schedule: # same options as in TaskScheduleDefinition
# supports cron, ISO duration, "human duration" as used in code
frequency: { minutes: 30 }
# supports ISO duration, "human duration" as used in code
timeout: { minutes: 3 }
```
- **`host`**:
The host of the Bitbucket Server instance, **note**: the host needs to registered as an integration as well, see [location](locations.md).
- **`catalogPath`** _(optional)_:
Default: `/catalog-info.yaml`.
Path where to look for `catalog-info.yaml` files.
When started with `/`, it is an absolute path from the repo root.
- **`filters`** _(optional)_:
- **`projectKey`** _(optional)_:
Regular expression used to filter results based on the project key.
- **`repoSlug`** _(optional)_:
Regular expression used to filter results based on the repo slug.
- **`skipArchivedRepos`** _(optional)_:
Boolean flag to filter out archived repositories.
- **`schedule`**:
- **`frequency`**:
How often you want the task to run. The system does its best to avoid overlapping invocations.
- **`timeout`**:
The maximum amount of time that a single task invocation can take.
- **`initialDelay`** _(optional)_:
The amount of time that should pass before the first invocation happens.
- **`scope`** _(optional)_:
`'global'` or `'local'`. Sets the scope of concurrency control.
## Custom location processing
The Bitbucket Server Entity Provider will by default emit a location for each
matching repository. However, it is possible to override this functionality and take full control of how each
matching repository is processed.
`BitbucketServerEntityProvider.fromConfig` takes an optional parameter
`options.parser` where you can set your own parser to be used for each matched
repository.
```typescript
const provider = BitbucketServerEntityProvider.fromConfig(env.config, {
logger: env.logger,
schedule: env.scheduler,
parser: async function* customLocationParser(options: {
location: LocationSpec;
client: BitbucketServerClient;
}) {
// Custom logic for interpreting the matching repository
// See defaultBitbucketServerLocationParser for an example
},
});
```
@@ -7,7 +7,7 @@ description: Automatically discovering catalog entities from repositories in Bit
---
:::info
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](https://github.com/backstage/backstage/blob/v1.37.0/docs/integrations/bitbucketServer/discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Bitbucket Server integration has a special entity provider for discovering
@@ -1,73 +0,0 @@
---
id: discovery--old
title: Gerrit Discovery
sidebar_label: Discovery
# prettier-ignore
description: Automatically discovering catalog entities from Gerrit repositories
---
:::info
This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./discovery.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Gerrit integration has a special entity provider for discovering catalog entities
from Gerrit repositories. The provider uses the "List Projects" API in Gerrit to get
a list of repositories and will automatically ingest all `catalog-info.yaml` files
stored in the root of the matching projects.
## Installation
As this provider is not one of the default providers, you will first need to install
the Gerrit provider plugin:
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gerrit
```
Then add the plugin to the plugin catalog `packages/backend/src/plugins/catalog.ts`:
```ts
/* packages/backend/src/plugins/catalog.ts */
import { GerritEntityProvider } from '@backstage/plugin-catalog-backend-module-gerrit';
const builder = await CatalogBuilder.create(env);
/** ... other processors and/or providers ... */
builder.addEntityProvider(
GerritEntityProvider.fromConfig(env.config, {
logger: env.logger,
scheduler: env.scheduler,
}),
);
```
## Configuration
To use the discovery processor, you'll need a Gerrit integration
[set up](locations.md). Then you can add any number of providers.
```yaml
# app-config.yaml
catalog:
providers:
gerrit:
yourProviderId: # identifies your dataset / provider independent of config changes
host: gerrit-your-company.com
branch: master # Optional
query: 'state=ACTIVE&prefix=webapps'
schedule:
# supports cron, ISO duration, "human duration" as used in code
frequency: { minutes: 30 }
# supports ISO duration, "human duration" as used in code
timeout: { minutes: 3 }
backend:
host: gerrit-your-company.com
branch: master # Optional
query: 'state=ACTIVE&prefix=backend'
```
The provider configuration is composed of three parts:
- **`host`**: the host of the Gerrit integration to use.
- **`branch`** _(optional)_: the branch where we will look for catalog entities (defaults to "master").
- **`query`**: this string is directly used as the argument to the "List Project" API.
Typically, you will want to have some filter here to exclude projects that will
never contain any catalog files.
+1 -1
View File
@@ -7,7 +7,7 @@ description: Automatically discovering catalog entities from Gerrit repositories
---
:::info
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](https://github.com/backstage/backstage/blob/v1.37.0/docs/integrations/gerrit/discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Gerrit integration has a special entity provider for discovering catalog entities
-375
View File
@@ -1,375 +0,0 @@
---
id: discovery--old
title: GitHub Discovery
sidebar_label: Discovery
# prettier-ignore
description: Automatically discovering catalog entities from repositories in a GitHub organization
---
:::info
This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./discovery.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
## GitHub Provider
The GitHub integration has a discovery provider for discovering catalog
entities within a GitHub organization. The provider will crawl the GitHub
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 is the preferred method for ingesting entities into the catalog.
## Installation without Events Support
You will have to add the provider in the catalog initialization code of your
backend. They are not installed by default, therefore you have to add a
dependency on `@backstage/plugin-catalog-backend-module-github` to your backend
package.
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github
```
And then add the entity provider to your catalog builder:
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { GithubEntityProvider } from '@backstage/plugin-catalog-backend-module-github';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-start */
builder.addEntityProvider(
GithubEntityProvider.fromConfig(env.config, {
logger: env.logger,
scheduler: env.scheduler,
}),
);
/* highlight-add-end */
// ..
}
```
## Installation with Events Support
_For the legacy backend system, please read the sub-section below._
The catalog module for GitHub comes with events support enabled.
This will make it subscribe to its relevant topics (`github.push`)
and expects these events to be published via the `EventsService`.
Additionally, you should install the
[event router by `events-backend-module-github`](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md)
which will route received events from the generic topic `github` to more specific ones
based on the event type (e.g., `github.push`).
In order to receive Webhook events by GitHub, you have to decide how you want them
to be ingested into Backstage and published to its `EventsService`.
You can decide between the following options (extensible):
- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md)
- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md)
### Legacy Backend System
Please follow the installation instructions at
- <https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md>
- <https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md>
Additionally, you need to decide how you want to receive events from external sources like
- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md)
- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md)
Set up your provider
```ts title="packages/backend/src/plugins/catalog.ts"
import { CatalogBuilder } from '@backstage/plugin-catalog-backend';
/* highlight-add-next-line */
import { GithubEntityProvider } from '@backstage/plugin-catalog-backend-module-github';
import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
builder.addProcessor(new ScaffolderEntitiesProcessor());
/* highlight-add-start */
const githubProvider = GithubEntityProvider.fromConfig(env.config, {
events: env.events,
logger: env.logger,
scheduler: env.scheduler,
});
builder.addEntityProvider(githubProvider);
/* highlight-add-end */
const { processingEngine, router } = await builder.build();
await processingEngine.start();
return router;
}
```
You can check the official docs to [configure your webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/creating-webhooks) and to [secure your request](https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks). The webhook will need to be configured to forward `push` events.
## Configuration
To use the discovery provider, you'll need a GitHub integration
[set up](locations.md) with either a [Personal Access Token](../../getting-started/config/authentication.md) or [GitHub Apps](./github-apps.md). For Personal Access Tokens you should pay attention to the [required scopes](https://backstage.io/docs/integrations/github/locations/#token-scopes), where you will need at least the `repo` scope for reading components. For GitHub Apps you will need to grant it the [required permissions](https://backstage.io/docs/integrations/github/github-apps#app-permissions) instead, where you will need at least the `Contents: Read-only` permissions for reading components.
Then you can add a `github` config to the catalog providers configuration:
```yaml
catalog:
providers:
github:
# the provider ID can be any camelCase string
providerId:
organization: 'backstage' # string
catalogPath: '/catalog-info.yaml' # string
filters:
branch: 'main' # string
repository: '.*' # Regex
schedule: # same options as in SchedulerServiceTaskScheduleDefinition
# supports cron, ISO duration, "human duration" as used in code
frequency: { minutes: 30 }
# supports ISO duration, "human duration" as used in code
timeout: { minutes: 3 }
customProviderId:
organization: 'new-org' # string
catalogPath: '/custom/path/catalog-info.yaml' # string
filters: # optional filters
branch: 'develop' # optional string
repository: '.*' # optional Regex
wildcardProviderId:
organization: 'new-org' # string
catalogPath: '/groups/**/*.yaml' # this will search all folders for files that end in .yaml
filters: # optional filters
branch: 'develop' # optional string
repository: '.*' # optional Regex
topicProviderId:
organization: 'backstage' # string
catalogPath: '/catalog-info.yaml' # string
filters:
branch: 'main' # string
repository: '.*' # Regex
topic: 'backstage-exclude' # optional string
topicFilterProviderId:
organization: 'backstage' # string
catalogPath: '/catalog-info.yaml' # string
filters:
branch: 'main' # string
repository: '.*' # Regex
topic:
include: ['backstage-include'] # optional array of strings
exclude: ['experiments'] # optional array of strings
validateLocationsExist:
organization: 'backstage' # string
catalogPath: '/catalog-info.yaml' # string
filters:
branch: 'main' # string
repository: '.*' # Regex
validateLocationsExist: true # optional boolean
visibilityProviderId:
organization: 'backstage' # string
catalogPath: '/catalog-info.yaml' # string
filters:
visibility:
- public
- internal
enterpriseProviderId:
host: ghe.example.net
organization: 'backstage' # string
catalogPath: '/catalog-info.yaml' # string
```
This provider supports multiple organizations via unique provider IDs.
> **Note:** It is possible but certainly not recommended to skip the provider ID level.
> If you do so, `default` will be used as provider ID.
- **`catalogPath`** _(optional)_:
Default: `/catalog-info.yaml`.
Path where to look for `catalog-info.yaml` files.
You can use wildcards - `*` or `**` - to search the path and/or the filename.
Wildcards cannot be used if the `validateLocationsExist` option is set to `true`.
- **`filters`** _(optional)_:
- **`branch`** _(optional)_:
String used to filter results based on the branch name.
Defaults to the default Branch of the repository.
- **`repository`** _(optional)_:
Regular expression used to filter results based on the repository name.
- **`topic`** _(optional)_:
Both of the filters below may be used at the same time but the exclusion filter has the highest priority.
In the example above, a repository with the `backstage-include` topic would still be excluded
if it were also carrying the `experiments` topic.
- **`include`** _(optional)_:
An array of strings used to filter in results based on their associated GitHub topics.
If configured, only repositories with one (or more) topic(s) present in the inclusion filter will be ingested
- **`exclude`** _(optional)_:
An array of strings used to filter out results based on their associated GitHub topics.
If configured, all repositories _except_ those with one (or more) topics(s) present in the exclusion filter will be ingested.
- **`visibility`** _(optional)_:
An array of strings used to filter results based on their visibility. Available options are `private`, `internal`, `public`. If configured (non empty), only repositories with visibility present in the filter will be ingested
- **`host`** _(optional)_:
The hostname of your GitHub Enterprise instance. It must match a host defined in [integrations.github](locations.md).
- **`organization`**:
Name of your organization account/workspace.
If you want to add multiple organizations, you need to add one provider config each.
- **`validateLocationsExist`** _(optional)_:
Whether to validate locations that exist before emitting them.
This option avoids generating locations for catalog info files that do not exist in the source repository.
Defaults to `false`.
Due to limitations in the GitHub API's ability to query for repository objects, this option cannot be used in
conjunction with wildcards in the `catalogPath`.
- **`schedule`**:
- **`frequency`**:
How often you want the task to run. The system does its best to avoid overlapping invocations.
- **`timeout`**:
The maximum amount of time that a single task invocation can take.
- **`initialDelay`** _(optional)_:
The amount of time that should pass before the first invocation happens.
- **`scope`** _(optional)_:
`'global'` or `'local'`. Sets the scope of concurrency control.
## GitHub API Rate Limits
GitHub [rate limits](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting) API requests to 5,000 per hour (or more for Enterprise
accounts). The snippet below refreshes the Backstage catalog data every 35 minutes, which issues an API request for each discovered location.
If your requests are too frequent then you may get throttled by
rate limiting. You can change the refresh frequency of the catalog in your `app-config.yaml` file by controlling the `schedule`.
```yaml
schedule:
frequency: { minutes: 35 }
timeout: { minutes: 3 }
```
More information about scheduling can be found on the [SchedulerServiceTaskScheduleDefinition](https://backstage.io/docs/reference/backend-plugin-api.schedulerservicetaskscheduledefinition) page.
Alternatively, or additionally, you can configure [github-apps](github-apps.md) authentication
which carries a much higher rate limit at GitHub.
This is true for any method of adding GitHub entities to the catalog, but
especially easy to hit with automatic discovery.
## GitHub Processor (To Be Deprecated)
The GitHub integration has a special discovery processor for discovering catalog
entities within a GitHub organization. The processor will crawl the GitHub
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.
## 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 on `@backstage/plugin-catalog-backend-module-github` to your backend
package, plus `@backstage/integration` for the basic credentials management:
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/integration @backstage/plugin-catalog-backend-module-github
```
And then add the processors to your catalog builder:
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-start */
import {
GithubDiscoveryProcessor,
GithubOrgReaderProcessor,
} from '@backstage/plugin-catalog-backend-module-github';
import {
ScmIntegrations,
DefaultGithubCredentialsProvider,
} from '@backstage/integration';
/* highlight-add-end */
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-start */
const integrations = ScmIntegrations.fromConfig(env.config);
const githubCredentialsProvider =
DefaultGithubCredentialsProvider.fromIntegrations(integrations);
builder.addProcessor(
GithubDiscoveryProcessor.fromConfig(env.config, {
logger: env.logger,
githubCredentialsProvider,
}),
GithubOrgReaderProcessor.fromConfig(env.config, {
logger: env.logger,
githubCredentialsProvider,
}),
);
/* highlight-add-end */
// ..
}
```
## Configuration
To use the discovery processor, you'll need a GitHub integration
[set up](locations.md) with either a [Personal Access Token](../../getting-started/config/authentication.md) or [GitHub Apps](./github-apps.md).
Then you can add a location target to the catalog configuration:
```yaml
catalog:
locations:
# (since 0.13.5) Scan all repositories for a catalog-info.yaml in the root of the default branch
- type: github-discovery
target: https://github.com/myorg
# Or use a custom pattern for a subset of all repositories with default repository
- type: github-discovery
target: https://github.com/myorg/service-*/blob/-/catalog-info.yaml
# Or use a custom file format and location
- type: github-discovery
target: https://github.com/*/blob/-/docs/your-own-format.yaml
# Or use a specific branch-name
- type: github-discovery
target: https://github.com/*/blob/backstage-docs/catalog-info.yaml
```
Note the `github-discovery` type, as this is not a regular `url` processor.
When using a custom pattern, the target is composed of three parts:
- The base organization URL, `https://github.com/myorg` in this case
- The repository blob to scan, which accepts \* wildcard tokens. This can simply
be `*` to scan all repositories in the organization. This example only looks
for repositories prefixed with `service-`.
- The path within each repository to find the catalog YAML file. This will
usually be `/blob/main/catalog-info.yaml`, `/blob/master/catalog-info.yaml` or
a similar variation for catalog files stored in the root directory of each
repository. You could also use a dash (`-`) for referring to the default
branch.
## GitHub API Rate Limits
GitHub [rate limits](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting) API requests to 5,000 per hour (or more for Enterprise
accounts). The default Backstage catalog backend refreshes data every 100
seconds, which issues an API request for each discovered location.
This means if you have more than ~140 catalog entities, you may get throttled by
rate limiting. You can change the refresh rate of the catalog in your `packages/backend/src/plugins/catalog.ts` file:
```typescript
const builder = await CatalogBuilder.create(env);
// For example, to refresh every 5 minutes (300 seconds).
builder.setProcessingIntervalSeconds(300);
```
Alternatively, or additionally, you can configure [github-apps](github-apps.md) authentication
which carries a much higher rate limit at GitHub.
This is true for any method of adding GitHub entities to the catalog, but
especially easy to hit with automatic discovery.
+1 -1
View File
@@ -7,7 +7,7 @@ description: Automatically discovering catalog entities from repositories in a G
---
:::info
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](https://github.com/backstage/backstage/blob/v1.37.0/docs/integrations/github/discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
## GitHub Provider
-365
View File
@@ -1,365 +0,0 @@
---
id: org--old
title: GitHub Organizational Data
sidebar_label: Org Data
# prettier-ignore
description: Importing users and groups from a GitHub organization into Backstage
---
:::info
This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./org.md) instead.Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Backstage catalog can be set up to ingest organizational data - users and
teams - directly from an organization in GitHub or GitHub Enterprise. The result
is a hierarchy of
[`User`](../../features/software-catalog/descriptor-format.md#kind-user) and
[`Group`](../../features/software-catalog/descriptor-format.md#kind-group) kind
entities that mirror your org setup.
> Note: This adds `User` and `Group` entities to the catalog, but does not
> provide authentication. See the
> [GitHub auth provider](../../auth/github/provider.md) for that.
## Installation without Events Support
This guide will use the Entity Provider method. If you for some reason prefer
the Processor method (not recommended), it is described separately below.
The provider is not installed by default, therefore you have to add a dependency
to `@backstage/plugin-catalog-backend-module-github` to your backend package.
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github
```
> Note: When configuring to use a Provider instead of a Processor you do not
> need to add a _location_ pointing to your GitHub server/organization
Update the catalog plugin initialization in your backend to add the provider and
schedule it:
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { GithubOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-start */
// The org URL below needs to match a configured integrations.github entry
// specified in your app-config.
builder.addEntityProvider(
GithubOrgEntityProvider.fromConfig(env.config, {
id: 'production',
orgUrl: 'https://github.com/backstage',
logger: env.logger,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 60 },
timeout: { minutes: 15 },
}),
}),
);
/* highlight-add-end */
// ..
}
```
Alternatively, if you wish to ingest data from multiple GitHub organizations you can use
the `GithubMultiOrgEntityProvider` instead. Note that by default, this provider will namespace
groups according to the org they originate from to avoid potential name duplicates:
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { GithubMultiOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-start */
// The GitHub URL below needs to match a configured integrations.github entry
// specified in your app-config.
builder.addEntityProvider(
GithubMultiOrgEntityProvider.fromConfig(env.config, {
id: 'production',
githubUrl: 'https://github.com',
// Set the following to list the GitHub orgs you wish to ingest from. You can
// also omit this option to ingest all orgs accessible by your GitHub integration
orgs: ['org-a', 'org-b'],
logger: env.logger,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 60 },
timeout: { minutes: 15 },
}),
}),
);
/* highlight-add-end */
// ..
}
```
## Installation with Events Support
_For the legacy backend system, please read the subsection below._
The catalog module `github-org` comes with events support enabled for the `GithubMultiOrgEntityProvider`.
This will make it subscribe to its relevant topics and expects these events to be published via the `EventsService`.
Topics:
- `github.installation`
- `github.membership`
- `github.organization`
- `github.team`
Additionally, you should install the
[event router by `events-backend-module-github`](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md)
which will route received events from the generic topic `github` to more specific ones
based on the event type (e.g., `github.membership`).
In order to receive Webhook events by GitHub, you have to decide how you want them
to be ingested into Backstage and published to its `EventsService`.
You can decide between the following options (extensible):
- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md)
- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md)
### Legacy Backend System
Please follow the installation instructions at
- <https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md>
- <https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md>
Additionally, you need to decide how you want to receive events from external sources like
- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md)
- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md)
Set up your provider
```ts title="packages/backend/src/plugins/catalog.ts"
import { CatalogBuilder } from '@backstage/plugin-catalog-backend';
/* highlight-add-next-line */
import { GithubOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github';
import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
builder.addProcessor(new ScaffolderEntitiesProcessor());
/* highlight-add-start */
const githubOrgProvider = GithubOrgEntityProvider.fromConfig(env.config, {
id: 'production',
orgUrl: 'https://github.com/backstage',
logger: env.logger,
events: env.events,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 60 },
timeout: { minutes: 15 },
}),
});
builder.addEntityProvider(githubOrgProvider);
/* highlight-add-end */
const { processingEngine, router } = await builder.build();
await processingEngine.start();
return router;
}
```
Or, alternatively, if using the `GithubMultiOrgEntityProvider`:
```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { GithubMultiOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-start */
// The GitHub URL below needs to match a configured integrations.github entry
// specified in your app-config.
builder.addEntityProvider(
GithubMultiOrgEntityProvider.fromConfig(env.config, {
id: 'production',
githubUrl: 'https://github.com',
// Set the following to list the GitHub orgs you wish to ingest from. You can
// also omit this option to ingest all orgs accessible by your GitHub integration
orgs: ['org-a', 'org-b'],
logger: env.logger,
events: env.events,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 60 },
timeout: { minutes: 15 },
}),
}),
);
/* highlight-add-end */
// ..
}
```
You can check the official docs to [configure your webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/creating-webhooks) and to [secure your request](https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks).
The webhook will need to be configured to forward `organization`,`team` and `membership` events.
## Configuration
As mentioned above, you also must have some configuration in your app-config
that describes the targets that you want to import. This lets the entity
provider know what authorization to use, and what the API endpoints are. You may
or may not have such an entry already added since before:
```yaml
integrations:
github:
# example for public github
- host: github.com
token: ${GITHUB_TOKEN}
# example for a private GitHub Enterprise instance
- host: ghe.example.net
apiBaseUrl: https://ghe.example.net/api/v3
token: ${GHE_TOKEN}
```
These examples use `${}` placeholders to reference environment variables. This
is often suitable for production setups, but also means that you will have to
supply those variables to the backend as it starts up. If you want, for local
development in particular, you can experiment first by putting the actual tokens
in a mirrored config directly in your `app-config.local.yaml` as well.
If Backstage is configured to use GitHub Apps authentication you must grant
`Read-Only` access for `Members` under `Organization` in order to ingest users
correctly. You can modify the app's permissions under the organization settings,
`https://github.com/organizations/{ORG}/settings/apps/{APP_NAME}/permissions`.
![permissions](../../assets/integrations/github/permissions.png)
**Please note that when you change permissions, the app owner will get an email
that must be approved first before the changes are applied.**
![email](../../assets/integrations/github/email.png)
### Custom Transformers
You can inject your own transformation logic to help map from GH API responses
into backstage entities. You can do this on the user and team requests to
enable you to do further processing or updates to the entities.
To enable this you pass a function into the `GitHubOrgEntityProvider`. You can
pass a `UserTransformer`, `TeamTransformer` or both. The function is invoked
for each item (user or team) that is returned from the API. You can either
return an Entity (User or Group) or `undefined` if you do not want to import
that item.
There is also a `defaultUserTransformer` and `defaultOrganizationTeamTransformer`.
You could use these and simply decorate the response from the default
transformation if you only need to change a few properties.
### Resolving GitHub users via organization email
When you authenticate users you should resolve them to an entity within the
catalog. Often the authentication you use could be a corporate SSO system that
provides you with email as a key. To enable you to find and resolve GitHub users
it's useful to also import the private domain verified emails into the User
entity in backstage.
The integration attempts to return `organizationVerifiedDomainEmails` from the
GitHub API and makes this available as part of the object passed to
`UserTransformer`. The GitHub API will only return emails that use a domain
that's a verified domain for your GitHub Org. It also relies on the user having
configured such an email in their own account. The API will only return these
values when using GitHub App authentication and with the correct app permission
allowing access to emails.
You can decorate the default `userTransformer` to replace the org email in the
returned identity.
```ts title="packages/backend/src/plugins/catalog.ts"
const githubOrgProvider = GithubOrgEntityProvider.fromConfig(env.config, {
id: 'production',
orgUrl: 'https://github.com/backstage',
logger: env.logger,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 60 },
timeout: { minutes: 15 },
}),
/* highlight-add-start */
userTransformer: async (user, ctx) => {
const entity = await defaultUserTransformer(user, ctx);
if (entity && user.organizationVerifiedDomainEmails?.length) {
entity.spec.profile!.email = user.organizationVerifiedDomainEmails[0];
}
return entity;
},
/* highlight-add-end */
});
```
Once you have imported the emails you can resolve users in your [sign-in resolver](../../auth/github/provider.md) using the catalog entity search via email
```typescript title="packages/backend/src/plugins/auth.ts"
ctx.signInWithCatalogUser({
filter: {
kind: ['User'],
'spec.profile.email': email as string,
},
});
```
## Using a Processor instead of a Provider
An alternative to using the Provider for ingesting organizational entities is to
use a Processor. This is the old way that's based on registering locations with
the proper type and target, triggering the processor to run.
The drawback of this method is that it will leave orphaned Group/User entities
whenever they are deleted on your GitHub server, and you cannot control the
frequency with which they are refreshed, separately from other processors.
### Processor Installation
The `GithubOrgReaderProcessor` is not registered by default, so you have to
install and register it in the catalog plugin:
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github
```
```typescript title="packages/backend/src/plugins/catalog.ts"
import { GithubOrgReaderProcessor } from '@backstage/plugin-catalog-backend-module-github';
builder.addProcessor(
GithubOrgReaderProcessor.fromConfig(env.config, { logger: env.logger }),
);
```
### Processor Configuration
The integration section of your app-config needs to be set up in the same way as
for the Entity Provider - see above.
In addition to that, you typically want to add a few static locations to your
app-config, which reference your organizations to import. The following
configuration enables an import of the teams and users under the org
`https://github.com/my-org-name` on public GitHub.
```yaml
catalog:
locations:
- type: github-org
target: https://github.com/my-org-name
rules:
- allow: [User, Group]
```
+1 -1
View File
@@ -7,7 +7,7 @@ description: Importing users and groups from a GitHub organization into Backstag
---
:::info
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./org--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](https://github.com/backstage/backstage/blob/v1.37.0/docs/integrations/github/org--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)!
:::
The Backstage catalog can be set up to ingest organizational data - users and