Merge branch 'master' into HACKATHON_SB_1/scaffolder_docs
Signed-off-by: Steven Billington <39339008+green2jello@users.noreply.github.com>
This commit is contained in:
@@ -86,12 +86,17 @@ contains more information about the required fields.
|
||||
Once we have a `template.yaml` ready, we can then add it to the software catalog
|
||||
for use by the scaffolder.
|
||||
|
||||
> Note: When you add or modify a template, you will need to refresh the location entity.
|
||||
> Otherwise, Backstage won't display the template in the available templates,
|
||||
> or it will keep showing the old template. You can refresh the location instance by
|
||||
> going into `Catalog` web page, choosing `Locations` instead of `Components`, and selecting the correct location entity.
|
||||
> From there, you can click on the refresh icon representing "Scheduled entity refresh" action.
|
||||
> Afterwards, you should see your template updated.
|
||||
:::note Note
|
||||
|
||||
When you add or modify a template, you will need to refresh the location entity.
|
||||
Otherwise, Backstage won't display the template in the available templates,
|
||||
or it will keep showing the old template. You can refresh the location instance by
|
||||
going into `Catalog` web page, choosing `Locations` instead of `Components`, and selecting the correct
|
||||
location entity.
|
||||
From there, you can click on the refresh icon representing "Scheduled entity refresh" action.
|
||||
Afterwards, you should see your template updated.
|
||||
|
||||
:::
|
||||
|
||||
You can add the template files to the catalog through
|
||||
[static location configuration](../software-catalog/configuration.md#static-location-configuration),
|
||||
|
||||
+67
-6
@@ -1,10 +1,10 @@
|
||||
---
|
||||
id: authorizing-parameters-steps-and-actions
|
||||
title: 'Authorizing parameters, steps and actions'
|
||||
description: How to authorize part of a template
|
||||
id: authorizing-scaffolder-template-details
|
||||
title: 'Authorizing scaffolder tasks, parameters, steps, and actions'
|
||||
description: How to authorize parts of a template and authorize scaffolder task access
|
||||
---
|
||||
|
||||
The scaffolder plugin integrates with the Backstage [permission framework](../../permissions/overview.md), which allows you to control access to certain parameters and steps in your templates based on the user executing the template.
|
||||
The scaffolder plugin integrates with the Backstage [permission framework](../../permissions/overview.md), which allows you to control access to certain parameters and steps in your templates based on the user executing the template. It also allows you to control access to scaffolder tasks.
|
||||
|
||||
### Authorizing parameters and steps
|
||||
|
||||
@@ -174,7 +174,64 @@ class ExamplePermissionPolicy implements PermissionPolicy {
|
||||
}
|
||||
```
|
||||
|
||||
Although the rules exported by the scaffolder are simple, combining them can help you achieve more complex cases.
|
||||
### Authorizing scaffolder tasks
|
||||
|
||||
The scaffolder plugin also exposes permissions that can restrict access to tasks, task logs, task creation, and task cancellation. This can be useful if you want to control who has access to these areas of the scaffolder.
|
||||
|
||||
```ts title="packages/src/backend/plugins/permissions.ts"
|
||||
/* highlight-add-start */
|
||||
import {
|
||||
taskCancelPermission,
|
||||
taskCreatePermission,
|
||||
taskReadPermission,
|
||||
} from '@backstage/plugin-scaffolder-common/alpha';
|
||||
/* highlight-add-end */
|
||||
|
||||
class ExamplePermissionPolicy implements PermissionPolicy {
|
||||
async handle(
|
||||
request: PolicyQuery,
|
||||
user?: BackstageIdentityResponse,
|
||||
): Promise<PolicyDecision> {
|
||||
/* highlight-add-start */
|
||||
if (isPermission(request.permission, taskCreatePermission)) {
|
||||
if (user?.identity.userEntityRef === 'user:default/spiderman') {
|
||||
return {
|
||||
result: AuthorizeResult.ALLOW,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (isPermission(request.permission, taskCancelPermission)) {
|
||||
if (user?.identity.userEntityRef === 'user:default/spiderman') {
|
||||
return {
|
||||
result: AuthorizeResult.ALLOW,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (isPermission(request.permission, taskReadPermission)) {
|
||||
if (user?.identity.userEntityRef === 'user:default/spiderman') {
|
||||
return {
|
||||
result: AuthorizeResult.ALLOW,
|
||||
};
|
||||
}
|
||||
}
|
||||
/* highlight-add-end */
|
||||
|
||||
return {
|
||||
result: AuthorizeResult.DENY,
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the provided example permission policy, we only grant the `spiderman` user permissions to perform/access the following actions/resources:
|
||||
|
||||
- Read all scaffolder tasks and their associated events/logs.
|
||||
- Cancel any ongoing scaffolder tasks.
|
||||
- Trigger software templates, which effectively creates new scaffolder tasks.
|
||||
|
||||
Any other user would be denied access to these actions/resources.
|
||||
|
||||
Although the rules exported by the scaffolder are simple, combining them can help you achieve more complex use cases.
|
||||
|
||||
### Authorizing in the New Backend System
|
||||
|
||||
@@ -229,4 +286,8 @@ backend.add(customPermissionBackendModule);
|
||||
/* highlight-add-end */
|
||||
```
|
||||
|
||||
> Note: the `ExamplePermissionPolicy` here could be the one from the [Authorizing parameters and steps](#authorizing-parameters-and-steps) example or from the [Authorizing actions](#authorizing-actions) example. It would work the same way for both of them.
|
||||
:::note Note
|
||||
|
||||
The `ExamplePermissionPolicy` here could be the one from the [Authorizing parameters and steps](#authorizing-parameters-and-steps) example or from the [Authorizing actions](#authorizing-actions) example. It would work the same way for both of them.
|
||||
|
||||
:::
|
||||
@@ -57,7 +57,11 @@ backend.add(import('@backstage/plugin-scaffolder-backend-module-github'));
|
||||
backend.start();
|
||||
```
|
||||
|
||||
> Note: This is a simplified example of what your backend may look like, you may have more code in here then this.
|
||||
:::note Note
|
||||
|
||||
This is a simplified example of what your backend may look like, you may have more code in here then this.
|
||||
|
||||
:::
|
||||
|
||||
## Listing Actions
|
||||
|
||||
|
||||
@@ -12,7 +12,11 @@ This is done in your `app-config.yaml` by adding
|
||||
[Backstage integrations](https://backstage.io/docs/integrations/) for the
|
||||
appropriate source code repository for your organization.
|
||||
|
||||
> Note: Integrations may already be set up as part of your `app-config.yaml`.
|
||||
:::note Note
|
||||
|
||||
Integrations may already be set up as part of your `app-config.yaml`.
|
||||
|
||||
:::
|
||||
|
||||
The next step is to [add templates](http://backstage.io/docs/features/software-templates/adding-templates)
|
||||
to your Backstage app.
|
||||
|
||||
@@ -20,10 +20,14 @@ locations like GitHub or GitLab.
|
||||
> Be sure to have covered
|
||||
> [Getting Started with Backstage](../../getting-started) before proceeding.
|
||||
|
||||
> Note: if you're running Backstage with Node 20 or later, you'll need to pass the flag `--no-node-snapshot` to Node in order to
|
||||
> use the templates feature.
|
||||
> One way to do this is to specify the `NODE_OPTIONS` environment variable before starting Backstage:
|
||||
> `export NODE_OPTIONS=--no-node-snapshot`
|
||||
:::note Note
|
||||
|
||||
If you're running Backstage with Node 20 or later, you'll need to pass the flag `--no-node-snapshot` to Node in order to
|
||||
use the templates feature.
|
||||
One way to do this is to specify the `NODE_OPTIONS` environment variable before starting Backstage:
|
||||
`export NODE_OPTIONS=--no-node-snapshot`
|
||||
|
||||
:::
|
||||
|
||||
The Software Templates are available under `/create`. For local development you
|
||||
should be able to reach them at `http://localhost:3000/create`.
|
||||
@@ -103,3 +107,17 @@ from `backstage/packages/app/src/App.tsx`:
|
||||
```
|
||||
|
||||
After the change, you should no longer see the button.
|
||||
|
||||
## Previewing and Executing Previous Template Tasks
|
||||
|
||||
Each execution of a template is treated as a unique task, identifiable by its own unique ID. To view a list of previously executed template tasks, navigate to the "Create" page and access the "Task List" from the context menu (represented by the vertical ellipsis, or 'kebab menu', icon in the upper right corner).
|
||||
|
||||

|
||||
|
||||
If you wish to re-run a previously executed template, navigate to the template tasks page. Locate the desired task and select the "Start Over" option from the context menu.
|
||||
|
||||

|
||||
|
||||
This action will initiate a new execution of the selected template, pre-populated with the same parameters as the previous run, but these parameters can be edited before re-execution.
|
||||
|
||||
In the event of a failed template execution, the "Start Over" option can be used to re-execute the template. The parameters from the original run will be pre-filled, but they can be adjusted as needed before retrying the template.
|
||||
|
||||
@@ -5,7 +5,11 @@ title: 'Migrating to react-jsonschema-form@v5'
|
||||
description: Docs on migrating to `react-jsonschema-form`@v5 and the new designs
|
||||
---
|
||||
|
||||
> Note: If you were previously using the `/alpha` imports to test out the `scaffolder/next` work, those imports have been promoted to the default exports from the respective packages. You should just have to remove the `/alpha` from the import path, and remove the `Next` from the import name. `NextScaffolderPage` -> `ScaffolderPage`, `createNextScaffolderFieldExtension` -> `createScaffolderFieldExtension` etc.
|
||||
:::note Note
|
||||
|
||||
If you were previously using the `/alpha` imports to test out the `scaffolder/next` work, those imports have been promoted to the default exports from the respective packages. You should just have to remove the `/alpha` from the import path, and remove the `Next` from the import name. `NextScaffolderPage` -> `ScaffolderPage`, `createNextScaffolderFieldExtension` -> `createScaffolderFieldExtension` etc.
|
||||
|
||||
:::
|
||||
|
||||
## What's `react-jsonschema-form`?
|
||||
|
||||
|
||||
@@ -8,10 +8,14 @@ If you want to extend the functionality of the Scaffolder, you can do so
|
||||
by writing custom actions which can be used alongside our
|
||||
[built-in actions](./builtin-actions.md).
|
||||
|
||||
> Note: When adding custom actions, the actions array will **replace the
|
||||
> built-in actions too**. Meaning, you will no longer be able to use them.
|
||||
> If you want to continue using the builtin actions, include them in the actions
|
||||
> array when registering your custom actions, as seen below.
|
||||
:::note Note
|
||||
|
||||
When adding custom actions, the actions array will **replace the
|
||||
built-in actions too**. Meaning, you will no longer be able to use them.
|
||||
If you want to continue using the builtin actions, include them in the actions
|
||||
array when registering your custom actions, as seen below.
|
||||
|
||||
:::
|
||||
|
||||
## Writing your Custom Action
|
||||
|
||||
|
||||
@@ -681,6 +681,8 @@ how to use them in the Scaffolder templates. It's important to mention that Back
|
||||
native filters from the Nunjucks library. For a complete list of these native filters and their usage,
|
||||
refer to the [Nunjucks documentation](https://mozilla.github.io/nunjucks/templating.html#builtin-filters).
|
||||
|
||||
To create your own custom filters, look to the section [Custom Filters](#custom-filters) hereafter.
|
||||
|
||||
### parseRepoUrl
|
||||
|
||||
The `parseRepoUrl` filter parse a repository URL into
|
||||
@@ -765,3 +767,150 @@ The `projectSlug` filter generates a project slug from a repository URL
|
||||
|
||||
- **Input**: `github.com?repo=backstage&org=backstage`
|
||||
- **Output**: `backstage/backstage`
|
||||
|
||||
## Custom Filters
|
||||
|
||||
Whenever it is needed to extend the built-in filters with yours `${{ parameters.name | my-filter1 | my-filter2 | etc }}`, then you can add them
|
||||
using the property `additionalTemplateFilters`.
|
||||
|
||||
The `additionalTemplateFilters` property accepts as type a `Record`
|
||||
|
||||
```ts title="plugins/scaffolder-backend/src/service/Router.ts"
|
||||
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
||||
```
|
||||
|
||||
where the first parameter is the name of the filter and the second receives a list of `JSON value` arguments. The `templateFilter()` function must return a JsonValue which is either a Json array, object or primitive.
|
||||
|
||||
```ts title="plugins/scaffolder-node/src/types.ts"
|
||||
export type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined;
|
||||
```
|
||||
|
||||
From a practical coding point of view, you will translate that into the following snippet code handling 2 filters:
|
||||
|
||||
```ts"
|
||||
...
|
||||
additionalTemplateFilters: {
|
||||
base64: (...args: JsonValue[]) => btoa(args.join("")),
|
||||
betterFilter: (...args: JsonValue[]) => { return `This is a much better string than "${args}", don't you think?` }
|
||||
}
|
||||
```
|
||||
|
||||
And within your template, you will be able to use the filters using a parameter and the filter passed using the pipe symbol
|
||||
|
||||
```yaml
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
metadata:
|
||||
name: test
|
||||
title: Test
|
||||
spec:
|
||||
owner: user:guest
|
||||
type: service
|
||||
|
||||
parameters:
|
||||
- title: Test custom filters
|
||||
properties:
|
||||
userName:
|
||||
title: Name of the user
|
||||
type: string
|
||||
|
||||
steps:
|
||||
- id: debug
|
||||
name: debug
|
||||
action: debug:log
|
||||
input:
|
||||
message: ${{ parameters.userName | betterFilter | base64 }}
|
||||
```
|
||||
|
||||
Next, you will have to register the property `addTemplateFilters` using the `scaffolderTemplatingExtensionPoint` of a new `BackendModule` [created](../../backend-system/architecture/06-modules.md).
|
||||
|
||||
Here is a very simplified example of how to do that:
|
||||
|
||||
```ts title="packages/backend-next/src/index.ts"
|
||||
/* highlight-add-start */
|
||||
import { scaffolderTemplatingExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
/* highlight-add-end */
|
||||
|
||||
/* highlight-add-start */
|
||||
const scaffolderModuleCustomFilters = createBackendModule({
|
||||
pluginId: 'scaffolder', // name of the plugin that the module is targeting
|
||||
moduleId: 'custom-filters',
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
scaffolder: scaffolderTemplatingExtensionPoint,
|
||||
// ... and other dependencies as needed
|
||||
},
|
||||
async init({ scaffolder /* ..., other dependencies */ }) {
|
||||
scaffolder.addTemplateFilters({
|
||||
base64: (...args: JsonValue[]) => btoa(args.join('')),
|
||||
betterFilter: (...args: JsonValue[]) => {
|
||||
return `This is a much better string than "${args}", don't you think?`;
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
/* highlight-add-end */
|
||||
|
||||
const backend = createBackend();
|
||||
backend.add(import('@backstage/plugin-scaffolder-backend/alpha'));
|
||||
/* highlight-add-next-line */
|
||||
backend.add(scaffolderModuleCustomFilters());
|
||||
```
|
||||
|
||||
If you still use the legacy backend system, then you will use the `createRouter()` function of the `Scaffolder plugin`
|
||||
|
||||
```ts title="packages/backend/src/plugins/scaffolder.ts"
|
||||
export default async function createPlugin({
|
||||
logger,
|
||||
config,
|
||||
}: PluginEnvironment): Promise<Router> {
|
||||
...
|
||||
return await createRouter({
|
||||
logger,
|
||||
config,
|
||||
|
||||
additionalTemplateFilters: {
|
||||
<YOUR_FILTERS>
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Template Editor
|
||||
|
||||
Writing template is most of the times an iterative process. You will need to test your template to make sure it has a good user experience and that it works as expected. To help on this process the scaffolder comes with a build in template editor that allows you to test your template in a real environment for querying data and execute the actions on dry-run mode to see the results of those one.
|
||||
|
||||
To access to the template editor you can go to the templates page and select "Template Editor" from the context menu or navigate to the `{scaffolder-path}/edit` url. (i.e. the default route would be `/create/edit`)
|
||||
|
||||

|
||||
|
||||
The template editor has 3 main sections:
|
||||
|
||||
1. **Load Template Directory**: Load a local template directory, allowing you to both edit and try executing your own template.
|
||||
2. **Edit Template Form**: Preview and edit a template form, either using a sample template or by loading a template from the catalog.
|
||||
3. **Custom Field Explorer**: View and play around with available installed custom field extensions.
|
||||
|
||||
### Load Template Directory
|
||||
|
||||
Allow to load a directory on your local file system that contains a template and editing the files in it while previewing the form and executing the template.
|
||||
|
||||

|
||||
|
||||
If you complete the form in the right side and click on `Create` button, the template will be executed in dry-run mode and the result will be shown in the `Dry-run result` drawer that will pop-up at the bottom of the screen.
|
||||
|
||||
Here we could find all the file system results of the template execution as well as the logs of each action that was executed.
|
||||
|
||||

|
||||
|
||||
### Edit Template Form
|
||||
|
||||
This is a reduced version of the template editor that allows you to select any template from the catalog and do some modifications on the form presented to the user to test some changes.
|
||||
|
||||
Have in mind that changes in this form will not be saved on the template and is meant to test out changes to replicate them manually on the template file after.
|
||||
|
||||
### Custom Field Explorer
|
||||
|
||||
The custom filed explorer allows you to select any custom field loaded on the backstage instance and test different values and configurations.
|
||||
|
||||
Reference in New Issue
Block a user