Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor extensions docs to enable versioning #12355

Merged
merged 3 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docusaurus/docs/extensions/extensions-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Some common model properties to overwrite are:
Components in the PromptRemove folder are used to customize the removal prompt for specific resource types. Components added to this folder should have the same file name as the resource they're intended for. These components do not control the actual removal action - they are intended to allow the developer to supply additional information about consequences of removing a given resource, eg the Global Role removal prompt warns how many users are bound to that role.

### l10n
Extension translation strings are merged with those already present in `shell/assets/translations`. Translation strings with duplicate keys of those present in the relevant shell translation file will overwrite those shell translation strings _across the app_: be mindful if adding translation strings that are not explicitly scoped to your extension. Read more about translations [here](../extensions/advanced/localization.md)
Extension translation strings are merged with those already present in `shell/assets/translations`. Translation strings with duplicate keys of those present in the relevant shell translation file will overwrite those shell translation strings _across the app_: be mindful if adding translation strings that are not explicitly scoped to your extension. Read more about translations [here](./advanced/localization)

### Extension Package Metadata

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Some common model properties to overwrite are:
* `detailLocation`: route for the detail view of one instance of the resource

### Overlapping Model Names
It's possible that different products will use the same kubernetes resource, but need to add different model functionality (eg Harvester has a 'node' model). Files in a extension's `models` folder will overwrite any files in the `shell/models` directory across the application. To extend or overwrite model functionality for a given store, nest models within a subfolder with the same name as the vuex module's `namespace`. see [Extensions Configuration](../../extensions/extensions-configuration.md) for more information on configuring an extension store.
It's possible that different products will use the same kubernetes resource, but need to add different model functionality (eg Harvester has a 'node' model). Files in a extension's `models` folder will overwrite any files in the `shell/models` directory across the application. To extend or overwrite model functionality for a given store, nest models within a subfolder with the same name as the vuex module's `namespace`. see [Extensions Configuration](/extensions/next/extensions-configuration) for more information on configuring an extension store.

## promptRemove**
Components in the PromptRemove folder are used to customize the removal prompt for specific resource types. Components added to this folder should have the same file name as the resource they're intended for. These components do not control the actual removal action - they are intended to allow the developer to supply additional information about consequences of removing a given resource, eg the Global Role removal prompt warns how many users are bound to that role.
Expand Down
2 changes: 1 addition & 1 deletion docusaurus/docs/internal/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ This documentation is intended to help developers contribute to the Dashboard UI

The [Getting Started](getting-started/concepts) section documents general concepts, the development environment and provides a walk-through of the Rancher Dashboard UI.

Extension developers should head over to the [Extensions](extensions/introduction) section and start their journey there.
Extension developers should head over to the [Extensions](/extensions/next/introduction) section and start their journey there.

66 changes: 45 additions & 21 deletions docusaurus/docusaurus.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion

const lightCodeTheme = require('prism-react-renderer/themes/github');
const darkCodeTheme = require('prism-react-renderer/themes/dracula');

Expand All @@ -16,13 +14,9 @@ const config = {
trailingSlash: false,

// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
organizationName: 'rancher', // Usually your GitHub org/user name.
projectName: 'dashboard', // Usually your repo name.
organizationName: 'rancher',
projectName: 'dashboard',

// Even if you don't use internalization, you can use this field to set useful
// metadata like html lang. For example, if your site is Chinese, you may want
// to replace "en" with "zh-Hans".
i18n: {
defaultLocale: 'en',
locales: ['en'],
Expand All @@ -33,28 +27,51 @@ const config = {
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
routeBasePath: '/',
sidebarPath: require.resolve('./sidebars.js'),
showLastUpdateTime: true,
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
},
docs: false,
blog: {
showReadingTime: true,
blogTitle: 'Rancher UX/UI Blog',
blogDescription: 'Recent and upcoming changes to Rancher Manager and associated projects and products',
postsPerPage: 'ALL',
blogSidebarCount: 'ALL',
blogSidebarTitle: 'All Posts',
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
},
theme: { customCss: require.resolve('./src/css/custom.css') },
}),
],
],

plugins: [
[
'@docusaurus/plugin-content-docs',
{
id: 'extensions',
path: 'docs/extensions',
routeBasePath: 'extensions',
sidebarPath: require.resolve('./extensionSidebar.js'),
showLastUpdateTime: true,
// Enable versioning for extensions
lastVersion: 'current',
versions: {
current: {
label: '3.x.x',
path: 'next',
},
},
},
],
[
'@docusaurus/plugin-content-docs',
{
id: 'internal',
path: 'docs/internal',
routeBasePath: 'internal',
sidebarPath: require.resolve('./internalSidebar.js'),
showLastUpdateTime: true
},
],
],

themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
Expand All @@ -67,10 +84,17 @@ const config = {
},
items: [
{
type: 'doc',
docId: 'extensions/home',
position: 'right',
label: 'Docs',
type: 'docsVersionDropdown',
docsPluginId: 'extensions',
position: 'left',
dropdownActiveClassDisabled: true,
},
{
type: 'doc',
docId: 'home',
docsPluginId: 'extensions',
position: 'right',
label: 'Docs',
},
{
to: '/blog', label: 'Blog', position: 'right'
Expand Down
117 changes: 117 additions & 0 deletions docusaurus/extensionSidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
extensionsSidebar: [
{
type: 'category',
label: 'Extensions',
link: {
type: 'doc',
id: 'home',
},
items: [
'introduction',
{
type: 'category',
label: 'Changelog',
link: {
type: 'doc',
id: 'changelog',
},
items: ['rancher-2.9-support', 'rancher-2.10-support']
},
'support-matrix',
'extensions-getting-started',
'extensions-configuration',
{
type: 'category',
label: 'Extensions API',
link: {
type: 'doc',
id: 'api/overview',
},
items: [
'api/concepts',
'api/metadata',
{
type: 'category',
label: 'Navigation & Pages',
items: [
'api/nav/products',
'api/nav/custom-page',
'api/nav/resource-page',
'api/nav/side-menu',
'api/nav/routing',
]
},
'api/actions',
'api/cards',
'api/panels',
'api/tabs',
'api/table-columns',
{
type: 'category',
label: 'Components',
link: {
type: 'doc',
id: 'api/components/components',
},
items: [
'api/components/resources',
'api/components/node-drivers',
'api/components/auto-import',
]
},
'api/common',
]
},
{
type: 'category',
label: 'Advanced',
items: [
'advanced/air-gapped-environments',
'advanced/provisioning',
'advanced/localization',
'advanced/hooks',
'advanced/stores',
'advanced/version-compatibility',
'advanced/safe-mode',
'advanced/yarn-link',
]
},
'publishing',
{
type: 'category',
label: 'Use cases/Examples',
link: {
type: 'doc',
id: 'usecases/overview',
},
items: [
'usecases/top-level-product',
'usecases/cluster-level-product',
{
type: 'category',
label: 'Node Driver',
link: {
type: 'doc',
id: 'usecases/node-driver/overview',
},
items: [
'usecases/node-driver/about-drivers',
'usecases/node-driver/cloud-credential',
'usecases/node-driver/machine-config',
'usecases/node-driver/node-driver-icon',
'usecases/node-driver/advanced',
'usecases/node-driver/proxying',
'usecases/node-driver/about-example',
]
}
]
},
'known-issues',
]
},
]
};

module.exports = sidebars;
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Air-gapped Environments

In order to load an extension within an air-gapped instance of Rancher, you will need to import an Extension Catalog Image to provide the extension assets, which are then served within the "Available" tab of the Extensions page and can be installed as normal.

The Extension Catalog Image (ECI) contains the assets of each extension which give the [ui-plugin-operator](https://github.com/rancher/ui-plugin-operator) the necessary files to load an extension into the Rancher Dashboard.

We have implemented an action within the Extensions page to take care of the heavy lifting for you by creating the necessary resources.

> Note: The ECI is comprised of a hardened [SLE BCI](https://registry.suse.com/bci/bci-base-15sp4/index.html) image with an [NGINX](https://nginx.org/en/) service which supplies the minified extension files.

## Prerequisites

Loading an extension into an air-gapped envrionment requires a few prerequisites, namely:

- The Extension needs to be bundled into the ECI
- A registry to house the ECI
- Access to this registry within the air-gapped Cluster

> Note: Any Secrets that are required to authenticate with the registry ***MUST*** be created in the `cattle-ui-plugin-system` namespace.

## Building the Extension Catalog Image

Currently there are two options available for building your extension into an ECI. You can use the predefined Github Workflow, if you plan on housing the extension within a Github repository, or you can manually build and publish your extension to a specified registry.

In either case, the ECI will need to be published to a registry that is accessible from the air-gapped cluster.

### Github Workflow

If using the provided Github workflow with your extension, the extension will be built and published for each package version to the [Github Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) (`ghcr`).

> Note: The extension image that is built will contain Helm charts for each subsequent package (i.e. `./pkg/<EXTENSION_NAME>`). In order to release a new version of a package, the root extension will need to be published with an updated tag within `./package.json`.

Once the extension has been published you will then be able to pull, tag, and push the ECI into your desired registry.

From a machine that has access to both the desired registry and `ghcr.io`, pull the image:

```sh
docker pull ghcr.io/<ORGANIZATION>/ui-extension-<REPO>:<TAG>
```

Then re-tag and push the image to your registry:

```sh
docker tag ghcr.io/<ORGANIZATION>/ui-extension-<REPO>:<TAG> <MY_REGISTRY>/<ORGANIZATION>/ui-extension-<REPO>:TAG
docker push <MY_REGISTRY>/<ORGANIZATION>/ui-extension-<REPO>:TAG
```

Proceed to the [Importing the Extension Catalog Image](#importing-the-catalog-image) step.

### Manual Build

The ECI can also be built manually using the `yarn publish-pkgs -c` command.

___Building Prerequisites___

This method requires a few tools to be installed:

- [make](https://www.gnu.org/software/make/)
- [docker](https://docs.docker.com/get-docker/)
- [go](https://go.dev/dl/)
- [nodejs](https://nodejs.org/en/download) ( >= `12.0.0` < `17.0.0` )
- [yarn](https://yarnpkg.com/getting-started/install)
- [jq](https://stedolan.github.io/jq/)
- [yq](https://github.com/mikefarah/yq/#install) ( >= `4.0.0` )
- [helm](https://helm.sh/docs/intro/install/) ( >= `3.0.0` )

___Running the Build Manually___

To build, simply run the following:

```sh
yarn publish-pkgs -cp -r <REGISTRY> -o <ORGANIZATION>
```

| Option | Argument | Description |
| -- | ---- | -------- |
| `-c` | | specifies the container build |
| `-p` | | Option to push the built image into the registry |
| `-r` | `<registry>` | specifies the registry where the image will be housed |
| `-o` | `<organization>` | specifies the organization namespace for the registry |

Reference the [Manually Publishing an Extension Catalog Image](../publishing#manually-publishing-an-extension-catalog-image) step in the Publishing section for more information.

## Importing the Extension Catalog Image

Importing the ECI is fairly straightforward, you will need the Catalog Image Reference from your registry and any secrets necessary to authenticate with the registry.

> Note: Any Secrets that are required to authenticate with the registry ***MUST*** be created in the `cattle-ui-plugin-system` namespace.

Within the Extensions page, select "Manage Extension Catalog" from the action menu in the top right. From here you will be able to see any Extension Catalog Images loaded previously along with their state, name, image used for the deployment, and cache state (used by the `ui-plugin-operator`).

To import an ECI, click on the "Import Extension Catalog" button:

![Manage Catalog Action](../screenshots/manage-catalog-action.png)

Fill out the form within the modal with your Catalog Reference Image URI (for example: `<MY_REGISTRY>/<ORGANIZATION>/ui-extension-<REPO>:TAG`) and any secrets necessary to pull the image.

> Note: If the registry is not supplied within the URI, it will default to `hub.docker.io`.

> Note: If the version of the image is omitted, this will default to `latest`.

![Extension Catalog Import](../screenshots/import-catalog-dialog.png)

The resources mentioned [above](#air-gapped-environments) will be created. You can navigate back to the main Extensions page by selecting breadcrumb link for "Extension" button from the header title in the top left of the screen.

![Navigate Charts List](../screenshots/navigate-chart-list.png)

Within the "Available", tab the newly imported extensions are now available to be installed normally.

![Available Charts](../screenshots/available-charts.png)
Loading
Loading