diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000000..4f3b76b096 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/master/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000000..02236339b9 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@1.3.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "linked": [ + [ + "example-app", + "@backstage/backend-common", + "example-backend", + "@backstage/catalog-model", + "@backstage/cli-common", + "@backstage/cli", + "@backstage/config-loader", + "@backstage/config", + "@backstage/core-api", + "@backstage/core", + "@backstage/create-app", + "@backstage/dev-utils", + "docgen", + "e2e-test", + "storybook", + "@techdocs/cli", + "@backstage/test-utils-core", + "@backstage/test-utils", + "@backstage/theme", + "@backstage/plugin-api-docs", + "@backstage/plugin-app-backend", + "@backstage/plugin-auth-backend", + "@backstage/plugin-catalog-backend", + "@backstage/plugin-catalog", + "@backstage/plugin-circleci", + "@backstage/plugin-gcp-projects", + "@backstage/plugin-github-actions", + "@backstage/plugin-gitops-profiles", + "@backstage/plugin-graphiql", + "@backstage/plugin-graphql-backend", + "@backstage/plugin-identity-backend", + "@backstage/plugin-jenkins", + "@backstage/plugin-lighthouse", + "@backstage/plugin-newrelic", + "@backstage/plugin-proxy-backend", + "@backstage/plugin-register-component", + "@backstage/plugin-rollbar-backend", + "@backstage/plugin-rollbar", + "@backstage/plugin-scaffolder-backend", + "@backstage/plugin-scaffolder", + "@backstage/plugin-sentry-backend", + "@backstage/plugin-sentry", + "@backstage/plugin-tech-radar", + "@backstage/plugin-techdocs-backend", + "@backstage/plugin-techdocs", + "@backstage/plugin-welcome" + ] + ], + "access": "public", + "baseBranch": "master", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml new file mode 100644 index 0000000000..ac7872ea93 --- /dev/null +++ b/.github/workflows/changeset.yml @@ -0,0 +1,19 @@ +name: Changeset + +on: + push: + branches: + - master + +jobs: + create-release-pr: + name: Create Changeset PR + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install Dependencies + run: yarn --frozen-lockfile + - name: Create Release Pull Request + uses: changesets/action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index cf68fad6bd..25360f3e1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ If you encounter issues while upgrading to a newer version, don't hesitate to re > Collect changes for the next release below +### @backstage/core + +- Renamed `SessionStateApi` to `SessionApi` and `logout` to `signOut`. Custom implementations of the `SingInPage` app-component will need to rename their `logout` function. The different auth provider items for the `UserSettingsMenu` have been consolidated into a single `ProviderSettingsItem`, meaning you need to replace existing usages of `OAuthProviderSettings` and `OIDCProviderSettings`. [#2555](https://github.com/spotify/backstage/pull/2555). + ## v0.1.1-alpha.22 ### @backstage/core diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0d6a8db50c..a6f7e5e5e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,6 +72,21 @@ If you're contributing to the backend or CLI tooling, be mindful of cross-platfo Also be sure to skim through our [ADRs](https://github.com/spotify/backstage/tree/master/docs/architecture-decisions) to see if they cover what you're working on. In particular [ADR006: Avoid React.FC and React.SFC](https://github.com/spotify/backstage/blob/master/docs/architecture-decisions/adr006-avoid-react-fc.md) is one to look out for. +# Creating Changesets + +We use [changesets](https://github.com/atlassian/changesets) to help us prepare releases. It helps us make sure that every package affected by a change gets a proper version number and an entry in its `CHANGELOG.md`. To make the process of generating releases easy. it helps when contributors include changesets with their pull requests. + +## To create a changeset + +1. Run `yarn changeset` +2. Select which packages you want to include a changeset for +3. Select impact of change that you're introducing (minor, major or patch) +4. Add generated changset to Git +5. Push the commit with your changeset to the branch associated with your PR +6. Accept our gratitude for making the release process easier on the maintainer + +For more information, checkout [adding a changeset](https://github.com/atlassian/changesets/blob/master/docs/adding-a-changeset.md) documentation in changesets repository. + # Code of Conduct This project adheres to the [Spotify FOSS Code of Conduct][code-of-conduct]. By participating, you are expected to honor this code. diff --git a/docs/auth/index.md b/docs/auth/index.md index 0fa8de3280..aed3a580b0 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -35,6 +35,13 @@ full list of providers, see the ### Identity - WIP +> NOTE: Identity management and the `SignInPage` in Backstage is NOT a method +> for blocking access for unauthorized users, that either requires additional +> backend implementation or a separate service like Google's Identity-Aware +> Proxy. The identity system only serves to provide a personalized experience +> and access to a Backstage Identity Token, which can be passed to backend +> plugins. + Identity management is still work in progress, but there are already a couple of pieces in place that can be used. diff --git a/docs/reference/utility-apis/AlertApi.md b/docs/reference/utility-apis/AlertApi.md index d000a6d6a2..d096276c3b 100644 --- a/docs/reference/utility-apis/AlertApi.md +++ b/docs/reference/utility-apis/AlertApi.md @@ -1,7 +1,7 @@ # AlertApi The AlertApi type is defined at -[packages/core-api/src/apis/definitions/AlertApi.ts:29](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/AlertApi.ts#L29). +[packages/core-api/src/apis/definitions/AlertApi.ts:29](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/AlertApi.ts#L29). The following Utility API implements this type: [alertApiRef](./README.md#alert) @@ -38,7 +38,7 @@ export type AlertMessage = { Defined at -[packages/core-api/src/apis/definitions/AlertApi.ts:19](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/AlertApi.ts#L19). +[packages/core-api/src/apis/definitions/AlertApi.ts:19](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/AlertApi.ts#L19). Referenced by: [post](#post), [alert\$](#alert). @@ -67,7 +67,7 @@ export type Observable<T> = { Defined at -[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L53). +[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L53). Referenced by: [alert\$](#alert). @@ -86,7 +86,7 @@ export type Observer<T> = { Defined at -[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L24). +[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L24). Referenced by: [Observable](#observable). @@ -109,6 +109,6 @@ export type Subscription = { Defined at -[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L33). +[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L33). Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/AppThemeApi.md b/docs/reference/utility-apis/AppThemeApi.md index e7d5296ceb..d37282adea 100644 --- a/docs/reference/utility-apis/AppThemeApi.md +++ b/docs/reference/utility-apis/AppThemeApi.md @@ -1,7 +1,7 @@ # AppThemeApi The AppThemeApi type is defined at -[packages/core-api/src/apis/definitions/AppThemeApi.ts:50](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/AppThemeApi.ts#L50). +[packages/core-api/src/apis/definitions/AppThemeApi.ts:50](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/AppThemeApi.ts#L50). The following Utility API implements this type: [appThemeApiRef](./README.md#apptheme) @@ -76,7 +76,7 @@ export type AppTheme = { Defined at -[packages/core-api/src/apis/definitions/AppThemeApi.ts:24](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/AppThemeApi.ts#L24). +[packages/core-api/src/apis/definitions/AppThemeApi.ts:24](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/AppThemeApi.ts#L24). Referenced by: [getInstalledThemes](#getinstalledthemes). @@ -87,7 +87,7 @@ export type BackstagePalette = Palette & Palette Defined at -[packages/theme/src/types.ts:70](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/theme/src/types.ts#L70). +[packages/theme/src/types.ts:70](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/theme/src/types.ts#L70). Referenced by: [BackstageTheme](#backstagetheme). @@ -100,7 +100,7 @@ export interface BackstageTheme extends Theme { Defined at -[packages/theme/src/types.ts:73](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/theme/src/types.ts#L73). +[packages/theme/src/types.ts:73](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/theme/src/types.ts#L73). Referenced by: [AppTheme](#apptheme). @@ -129,7 +129,7 @@ export type Observable<T> = { Defined at -[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L53). +[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L53). Referenced by: [activeThemeId\$](#activethemeid). @@ -148,7 +148,7 @@ export type Observer<T> = { Defined at -[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L24). +[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L24). Referenced by: [Observable](#observable). @@ -204,7 +204,7 @@ type PaletteAdditions = { Defined at -[packages/theme/src/types.ts:23](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/theme/src/types.ts#L23). +[packages/theme/src/types.ts:23](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/theme/src/types.ts#L23). Referenced by: [BackstagePalette](#backstagepalette). @@ -227,6 +227,6 @@ export type Subscription = { Defined at -[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L33). +[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L33). Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/BackstageIdentityApi.md b/docs/reference/utility-apis/BackstageIdentityApi.md index 87318ecff5..529b73c576 100644 --- a/docs/reference/utility-apis/BackstageIdentityApi.md +++ b/docs/reference/utility-apis/BackstageIdentityApi.md @@ -1,7 +1,7 @@ # BackstageIdentityApi The BackstageIdentityApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:144](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L144). +[packages/core-api/src/apis/definitions/auth.ts:134](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L134). The following Utility APIs implement this type: @@ -15,6 +15,8 @@ The following Utility APIs implement this type: - [microsoftAuthApiRef](./README.md#microsoftauth) +- [oauth2ApiRef](./README.md#oauth2) + - [oktaAuthApiRef](./README.md#oktaauth) ## Members @@ -66,7 +68,7 @@ export type AuthRequestOptions = { Defined at -[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L40). +[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L40). Referenced by: [getBackstageIdentity](#getbackstageidentity). @@ -87,6 +89,6 @@ export type BackstageIdentity = { Defined at -[packages/core-api/src/apis/definitions/auth.ts:157](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L157). +[packages/core-api/src/apis/definitions/auth.ts:147](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L147). Referenced by: [getBackstageIdentity](#getbackstageidentity). diff --git a/docs/reference/utility-apis/Config.md b/docs/reference/utility-apis/Config.md index 9374fb9962..b54e122c03 100644 --- a/docs/reference/utility-apis/Config.md +++ b/docs/reference/utility-apis/Config.md @@ -1,7 +1,7 @@ # Config The Config type is defined at -[packages/config/src/types.ts:32](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/config/src/types.ts#L32). +[packages/config/src/types.ts:32](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/config/src/types.ts#L32). The following Utility API implements this type: [configApiRef](./README.md#config) @@ -140,7 +140,7 @@ export type Config = { Defined at -[packages/config/src/types.ts:32](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/config/src/types.ts#L32). +[packages/config/src/types.ts:32](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/config/src/types.ts#L32). Referenced by: [getConfig](#getconfig), [getOptionalConfig](#getoptionalconfig), [getConfigArray](#getconfigarray), @@ -153,7 +153,7 @@ export type JsonArray = JsonValue[] Defined at -[packages/config/src/types.ts:18](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/config/src/types.ts#L18). +[packages/config/src/types.ts:18](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/config/src/types.ts#L18). Referenced by: [JsonValue](#jsonvalue). @@ -164,7 +164,7 @@ export type JsonObject = { [key in string]?: JsonValue Defined at -[packages/config/src/types.ts:17](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/config/src/types.ts#L17). +[packages/config/src/types.ts:17](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/config/src/types.ts#L17). Referenced by: [JsonValue](#jsonvalue). @@ -181,7 +181,7 @@ export type JsonValue = Defined at -[packages/config/src/types.ts:19](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/config/src/types.ts#L19). +[packages/config/src/types.ts:19](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/config/src/types.ts#L19). Referenced by: [get](#get), [getOptional](#getoptional), [JsonObject](#jsonobject), [JsonArray](#jsonarray), [Config](#config). diff --git a/docs/reference/utility-apis/DiscoveryApi.md b/docs/reference/utility-apis/DiscoveryApi.md index 39902789cd..24371c1729 100644 --- a/docs/reference/utility-apis/DiscoveryApi.md +++ b/docs/reference/utility-apis/DiscoveryApi.md @@ -1,7 +1,7 @@ # DiscoveryApi The DiscoveryApi type is defined at -[packages/core-api/src/apis/definitions/DiscoveryApi.ts:30](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/DiscoveryApi.ts#L30). +[packages/core-api/src/apis/definitions/DiscoveryApi.ts:30](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/DiscoveryApi.ts#L30). The following Utility API implements this type: [discoveryApiRef](./README.md#discovery) diff --git a/docs/reference/utility-apis/ErrorApi.md b/docs/reference/utility-apis/ErrorApi.md index c05f060ec3..4de58b34a1 100644 --- a/docs/reference/utility-apis/ErrorApi.md +++ b/docs/reference/utility-apis/ErrorApi.md @@ -1,7 +1,7 @@ # ErrorApi The ErrorApi type is defined at -[packages/core-api/src/apis/definitions/ErrorApi.ts:53](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/ErrorApi.ts#L53). +[packages/core-api/src/apis/definitions/ErrorApi.ts:53](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/ErrorApi.ts#L53). The following Utility API implements this type: [errorApiRef](./README.md#error) @@ -41,7 +41,7 @@ type Error = { Defined at -[packages/core-api/src/apis/definitions/ErrorApi.ts:24](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/ErrorApi.ts#L24). +[packages/core-api/src/apis/definitions/ErrorApi.ts:24](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/ErrorApi.ts#L24). Referenced by: [post](#post), [error\$](#error). @@ -58,7 +58,7 @@ export type ErrorContext = { Defined at -[packages/core-api/src/apis/definitions/ErrorApi.ts:33](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/ErrorApi.ts#L33). +[packages/core-api/src/apis/definitions/ErrorApi.ts:33](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/ErrorApi.ts#L33). Referenced by: [post](#post), [error\$](#error). @@ -87,7 +87,7 @@ export type Observable<T> = { Defined at -[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L53). +[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L53). Referenced by: [error\$](#error). @@ -106,7 +106,7 @@ export type Observer<T> = { Defined at -[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L24). +[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L24). Referenced by: [Observable](#observable). @@ -129,6 +129,6 @@ export type Subscription = { Defined at -[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L33). +[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L33). Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/FeatureFlagsApi.md b/docs/reference/utility-apis/FeatureFlagsApi.md index 5efdb176a4..8fbcb794fb 100644 --- a/docs/reference/utility-apis/FeatureFlagsApi.md +++ b/docs/reference/utility-apis/FeatureFlagsApi.md @@ -1,7 +1,7 @@ # FeatureFlagsApi The FeatureFlagsApi type is defined at -[packages/core-api/src/apis/definitions/FeatureFlagsApi.ts:41](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L41). +[packages/core-api/src/apis/definitions/FeatureFlagsApi.ts:41](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L41). The following Utility API implements this type: [featureFlagsApiRef](./README.md#featureflags) diff --git a/docs/reference/utility-apis/IdentityApi.md b/docs/reference/utility-apis/IdentityApi.md index 4e37ad5300..5ee5c582b6 100644 --- a/docs/reference/utility-apis/IdentityApi.md +++ b/docs/reference/utility-apis/IdentityApi.md @@ -1,7 +1,7 @@ # IdentityApi The IdentityApi type is defined at -[packages/core-api/src/apis/definitions/IdentityApi.ts:22](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/IdentityApi.ts#L22). +[packages/core-api/src/apis/definitions/IdentityApi.ts:22](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/IdentityApi.ts#L22). The following Utility API implements this type: [identityApiRef](./README.md#identity) @@ -40,12 +40,12 @@ identity, such as a demo user or mocked user for e2e tests. getIdToken(): Promise<string | undefined> -### logout() +### signOut() -Log out the current user +Sign out the current user
-logout(): Promise<void>
+signOut(): Promise<void>
 
## Supporting types @@ -76,6 +76,6 @@ export type ProfileInfo = { Defined at -[packages/core-api/src/apis/definitions/auth.ts:172](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L172). +[packages/core-api/src/apis/definitions/auth.ts:162](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L162). Referenced by: [getProfile](#getprofile). diff --git a/docs/reference/utility-apis/OAuthApi.md b/docs/reference/utility-apis/OAuthApi.md index e73d5f645f..a489db76c5 100644 --- a/docs/reference/utility-apis/OAuthApi.md +++ b/docs/reference/utility-apis/OAuthApi.md @@ -1,7 +1,7 @@ # OAuthApi The OAuthApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:67](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L67). +[packages/core-api/src/apis/definitions/auth.ts:67](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L67). The following Utility APIs implement this type: @@ -50,14 +50,6 @@ getAccessToken( ): Promise<string> -### logout() - -Log out the user's session. This will reload the page. - -
-logout(): Promise<void>
-
- ## Supporting types These types are part of the API declaration, but may not be unique to this API. @@ -90,7 +82,7 @@ export type AuthRequestOptions = { Defined at -[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L40). +[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L40). Referenced by: [getAccessToken](#getaccesstoken). @@ -116,6 +108,6 @@ export type OAuthScope = string | string[] Defined at -[packages/core-api/src/apis/definitions/auth.ts:38](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L38). +[packages/core-api/src/apis/definitions/auth.ts:38](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L38). Referenced by: [getAccessToken](#getaccesstoken). diff --git a/docs/reference/utility-apis/OAuthRequestApi.md b/docs/reference/utility-apis/OAuthRequestApi.md index c6b9e09189..ac11764682 100644 --- a/docs/reference/utility-apis/OAuthRequestApi.md +++ b/docs/reference/utility-apis/OAuthRequestApi.md @@ -1,7 +1,7 @@ # OAuthRequestApi The OAuthRequestApi type is defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:99](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L99). +[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:99](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L99). The following Utility API implements this type: [oauthRequestApiRef](./README.md#oauthrequest) @@ -72,7 +72,7 @@ export type AuthProvider = { Defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:27](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L27). +[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:27](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L27). Referenced by: [AuthRequesterOptions](#authrequesteroptions), [PendingAuthRequest](#pendingauthrequest). @@ -96,7 +96,7 @@ export type AuthRequester<AuthResponse> = ( Defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:66](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L66). +[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:66](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L66). Referenced by: [createAuthRequester](#createauthrequester). @@ -121,7 +121,7 @@ export type AuthRequesterOptions<AuthResponse> = { Defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:43](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L43). +[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:43](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L43). Referenced by: [createAuthRequester](#createauthrequester). @@ -150,7 +150,7 @@ export type Observable<T> = { Defined at -[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L53). +[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L53). Referenced by: [authRequest\$](#authrequest). @@ -169,7 +169,7 @@ export type Observer<T> = { Defined at -[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L24). +[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L24). Referenced by: [Observable](#observable). @@ -204,7 +204,7 @@ export type PendingAuthRequest = { Defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:77](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L77). +[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:77](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L77). Referenced by: [authRequest\$](#authrequest). @@ -227,6 +227,6 @@ export type Subscription = { Defined at -[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L33). +[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L33). Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/OpenIdConnectApi.md b/docs/reference/utility-apis/OpenIdConnectApi.md index 41a3247af6..efd79593d6 100644 --- a/docs/reference/utility-apis/OpenIdConnectApi.md +++ b/docs/reference/utility-apis/OpenIdConnectApi.md @@ -1,7 +1,7 @@ # OpenIdConnectApi The OpenIdConnectApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:104](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L104). +[packages/core-api/src/apis/definitions/auth.ts:99](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L99). The following Utility APIs implement this type: @@ -34,14 +34,6 @@ user rejects the login request. getIdToken(options?: AuthRequestOptions): Promise<string> -### logout() - -Log out the user's session. This will reload the page. - -
-logout(): Promise<void>
-
- ## Supporting types These types are part of the API declaration, but may not be unique to this API. @@ -74,6 +66,6 @@ export type AuthRequestOptions = { Defined at -[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L40). +[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L40). Referenced by: [getIdToken](#getidtoken). diff --git a/docs/reference/utility-apis/ProfileInfoApi.md b/docs/reference/utility-apis/ProfileInfoApi.md index 09c0f88f83..402b5ba504 100644 --- a/docs/reference/utility-apis/ProfileInfoApi.md +++ b/docs/reference/utility-apis/ProfileInfoApi.md @@ -1,7 +1,7 @@ # ProfileInfoApi The ProfileInfoApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:127](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L127). +[packages/core-api/src/apis/definitions/auth.ts:117](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L117). The following Utility APIs implement this type: @@ -65,7 +65,7 @@ export type AuthRequestOptions = { Defined at -[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L40). +[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L40). Referenced by: [getProfile](#getprofile). @@ -93,6 +93,6 @@ export type ProfileInfo = { Defined at -[packages/core-api/src/apis/definitions/auth.ts:172](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L172). +[packages/core-api/src/apis/definitions/auth.ts:162](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L162). Referenced by: [getProfile](#getprofile). diff --git a/docs/reference/utility-apis/README.md b/docs/reference/utility-apis/README.md index cfdc3b6ef8..71931a5d5a 100644 --- a/docs/reference/utility-apis/README.md +++ b/docs/reference/utility-apis/README.md @@ -12,7 +12,7 @@ Used to report alerts and forward them to the app Implemented type: [AlertApi](./AlertApi.md) ApiRef: -[alertApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/AlertApi.ts#L41) +[alertApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/AlertApi.ts#L41) ### appTheme @@ -21,7 +21,7 @@ API Used to configure the app theme, and enumerate options Implemented type: [AppThemeApi](./AppThemeApi.md) ApiRef: -[appThemeApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/AppThemeApi.ts#L74) +[appThemeApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/AppThemeApi.ts#L74) ### auth0Auth @@ -29,11 +29,10 @@ Provides authentication towards Auth0 APIs Implemented types: [OpenIdConnectApi](./OpenIdConnectApi.md), [ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), -[SessionStateApi](./SessionStateApi.md) +[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) ApiRef: -[auth0AuthApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L273) +[auth0AuthApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L275) ### config @@ -42,7 +41,7 @@ Used to access runtime configuration Implemented type: [Config](./Config.md) ApiRef: -[configApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/ConfigApi.ts#L22) +[configApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/ConfigApi.ts#L22) ### discovery @@ -51,7 +50,7 @@ Provides service discovery of backend plugins Implemented type: [DiscoveryApi](./DiscoveryApi.md) ApiRef: -[discoveryApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/DiscoveryApi.ts#L44) +[discoveryApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/DiscoveryApi.ts#L44) ### error @@ -60,7 +59,7 @@ Used to report errors and forward them to the app Implemented type: [ErrorApi](./ErrorApi.md) ApiRef: -[errorApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/ErrorApi.ts#L65) +[errorApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/ErrorApi.ts#L65) ### featureFlags @@ -69,7 +68,7 @@ Used to toggle functionality in features across Backstage Implemented type: [FeatureFlagsApi](./FeatureFlagsApi.md) ApiRef: -[featureFlagsApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L58) +[featureFlagsApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L58) ### githubAuth @@ -77,11 +76,10 @@ Provides authentication towards GitHub APIs Implemented types: [OAuthApi](./OAuthApi.md), [ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), -[SessionStateApi](./SessionStateApi.md) +[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) ApiRef: -[githubAuthApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L230) +[githubAuthApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L232) ### gitlabAuth @@ -89,11 +87,10 @@ Provides authentication towards GitLab APIs Implemented types: [OAuthApi](./OAuthApi.md), [ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), -[SessionStateApi](./SessionStateApi.md) +[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) ApiRef: -[gitlabAuthApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L260) +[gitlabAuthApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L262) ### googleAuth @@ -102,11 +99,10 @@ Provides authentication towards Google APIs and identities Implemented types: [OAuthApi](./OAuthApi.md), [OpenIdConnectApi](./OpenIdConnectApi.md), [ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), -[SessionStateApi](./SessionStateApi.md) +[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) ApiRef: -[googleAuthApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L213) +[googleAuthApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L215) ### identity @@ -115,7 +111,7 @@ Provides access to the identity of the signed in user Implemented type: [IdentityApi](./IdentityApi.md) ApiRef: -[identityApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/IdentityApi.ts#L54) +[identityApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/IdentityApi.ts#L54) ### microsoftAuth @@ -124,11 +120,10 @@ Provides authentication towards Microsoft APIs and identities Implemented types: [OAuthApi](./OAuthApi.md), [OpenIdConnectApi](./OpenIdConnectApi.md), [ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), -[SessionStateApi](./SessionStateApi.md) +[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) ApiRef: -[microsoftAuthApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L287) +[microsoftAuthApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L289) ### oauth2 @@ -136,10 +131,11 @@ Example of how to use oauth2 custom provider Implemented types: [OAuthApi](./OAuthApi.md), [OpenIdConnectApi](./OpenIdConnectApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), [SessionStateApi](./SessionStateApi.md) +[ProfileInfoApi](./ProfileInfoApi.md), +[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) ApiRef: -[oauth2ApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L301) +[oauth2ApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L303) ### oauthRequest @@ -148,7 +144,7 @@ An API for implementing unified OAuth flows in Backstage Implemented type: [OAuthRequestApi](./OAuthRequestApi.md) ApiRef: -[oauthRequestApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L130) +[oauthRequestApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L130) ### oktaAuth @@ -157,11 +153,10 @@ Provides authentication towards Okta APIs Implemented types: [OAuthApi](./OAuthApi.md), [OpenIdConnectApi](./OpenIdConnectApi.md), [ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), -[SessionStateApi](./SessionStateApi.md) +[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) ApiRef: -[oktaAuthApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L243) +[oktaAuthApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L245) ### storage @@ -170,4 +165,4 @@ Provides the ability to store data which is unique to the user Implemented type: [StorageApi](./StorageApi.md) ApiRef: -[storageApiRef](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/StorageApi.ts#L68) +[storageApiRef](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/StorageApi.ts#L68) diff --git a/docs/reference/utility-apis/SessionApi.md b/docs/reference/utility-apis/SessionApi.md new file mode 100644 index 0000000000..5e40b3317b --- /dev/null +++ b/docs/reference/utility-apis/SessionApi.md @@ -0,0 +1,138 @@ +# SessionApi + +The SessionApi type is defined at +[packages/core-api/src/apis/definitions/auth.ts:190](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L190). + +The following Utility APIs implement this type: + +- [auth0AuthApiRef](./README.md#auth0auth) + +- [githubAuthApiRef](./README.md#githubauth) + +- [gitlabAuthApiRef](./README.md#gitlabauth) + +- [googleAuthApiRef](./README.md#googleauth) + +- [microsoftAuthApiRef](./README.md#microsoftauth) + +- [oauth2ApiRef](./README.md#oauth2) + +- [oktaAuthApiRef](./README.md#oktaauth) + +## Members + +### signIn() + +Sign in with a minimum set of permissions. + +
+signIn(): Promise<void>
+
+ +### signOut() + +Sign out from the current session. This will reload the page. + +
+signOut(): Promise<void>
+
+ +### sessionState\$() + +Observe the current state of the auth session. Emits the current state on +subscription. + +
+sessionState$(): Observable<SessionState>
+
+ +## Supporting types + +These types are part of the API declaration, but may not be unique to this API. + +### Observable + +Observable sequence of values and errors, see TC39. + +https://github.com/tc39/proposal-observable + +This is used as a common return type for observable values and can be created +using many different observable implementations, such as zen-observable or +RxJS 5. + +
+export type Observable<T> = {
+  /**
+   * Subscribes to this observable to start receiving new values.
+   */
+  subscribe(observer: Observer<T>): Subscription;
+  subscribe(
+    onNext: (value: T) => void,
+    onError?: (error: Error) => void,
+    onComplete?: () => void,
+  ): Subscription;
+}
+
+ +Defined at +[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L53). + +Referenced by: [sessionState\$](#sessionstate). + +### Observer + +This file contains non-react related core types used throught Backstage. + +Observer interface for consuming an Observer, see TC39. + +
+export type Observer<T> = {
+  next?(value: T): void;
+  error?(error: Error): void;
+  complete?(): void;
+}
+
+ +Defined at +[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L24). + +Referenced by: [Observable](#observable). + +### SessionState + +Session state values passed to subscribers of the SessionApi. + +
+export enum SessionState {
+  SignedIn = 'SignedIn',
+  SignedOut = 'SignedOut',
+}
+
+ +Defined at +[packages/core-api/src/apis/definitions/auth.ts:182](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/auth.ts#L182). + +Referenced by: [sessionState\$](#sessionstate). + +### Subscription + +Subscription returned when subscribing to an Observable, see TC39. + +
+export type Subscription = {
+  /**
+   * Cancels the subscription
+   */
+  unsubscribe(): void;
+
+  /**
+   * Value indicating whether the subscription is closed.
+   */
+  readonly closed: Boolean;
+}
+
+ +Defined at +[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L33). + +Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/StorageApi.md b/docs/reference/utility-apis/StorageApi.md index bee52935da..3fd75a42d6 100644 --- a/docs/reference/utility-apis/StorageApi.md +++ b/docs/reference/utility-apis/StorageApi.md @@ -1,7 +1,7 @@ # StorageApi The StorageApi type is defined at -[packages/core-api/src/apis/definitions/StorageApi.ts:31](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/StorageApi.ts#L31). +[packages/core-api/src/apis/definitions/StorageApi.ts:31](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/StorageApi.ts#L31). The following Utility API implements this type: [storageApiRef](./README.md#storage) @@ -79,7 +79,7 @@ export type Observable<T> = { Defined at -[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L53). +[packages/core-api/src/types.ts:53](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L53). Referenced by: [observe\$](#observe), [StorageApi](#storageapi). @@ -98,7 +98,7 @@ export type Observer<T> = { Defined at -[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L24). +[packages/core-api/src/types.ts:24](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L24). Referenced by: [Observable](#observable). @@ -144,7 +144,7 @@ export interface StorageApi { Defined at -[packages/core-api/src/apis/definitions/StorageApi.ts:31](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/StorageApi.ts#L31). +[packages/core-api/src/apis/definitions/StorageApi.ts:31](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/StorageApi.ts#L31). Referenced by: [forBucket](#forbucket). @@ -158,7 +158,7 @@ export type StorageValueChange<T = any> = { Defined at -[packages/core-api/src/apis/definitions/StorageApi.ts:21](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/StorageApi.ts#L21). +[packages/core-api/src/apis/definitions/StorageApi.ts:21](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/apis/definitions/StorageApi.ts#L21). Referenced by: [observe\$](#observe), [StorageApi](#storageapi). @@ -181,6 +181,6 @@ export type Subscription = { Defined at -[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L33). +[packages/core-api/src/types.ts:33](https://github.com/spotify/backstage/blob/0406ace29aba7332a98ff9ef9feedd65adc75223/packages/core-api/src/types.ts#L33). Referenced by: [Observable](#observable). diff --git a/package.json b/package.json index 2622f1e322..3a77fe6880 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ }, "version": "1.0.0", "devDependencies": { + "@changesets/cli": "2.10.2", "@spotify/eslint-config-oss": "^1.0.1", "@spotify/prettier-config": "^8.0.0", "concurrently": "^5.2.0", diff --git a/packages/app/package.json b/packages/app/package.json index cb61e1ed8c..1262c954cc 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -16,6 +16,7 @@ "@backstage/plugin-gitops-profiles": "^0.1.1-alpha.22", "@backstage/plugin-graphiql": "^0.1.1-alpha.22", "@backstage/plugin-jenkins": "^0.1.1-alpha.22", + "@backstage/plugin-kubernetes": "^0.1.1-alpha.22", "@backstage/plugin-lighthouse": "^0.1.1-alpha.22", "@backstage/plugin-newrelic": "^0.1.1-alpha.22", "@backstage/plugin-register-component": "^0.1.1-alpha.22", diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index c382abc3a8..d96fe9841f 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -29,6 +29,7 @@ import { import { Router as ApiDocsRouter } from '@backstage/plugin-api-docs'; import { Router as SentryRouter } from '@backstage/plugin-sentry'; import { EmbeddedDocsRouter as DocsRouter } from '@backstage/plugin-techdocs'; +import { Router as KubernetesRouter } from '@backstage/plugin-kubernetes'; import React from 'react'; import { AboutCard, @@ -99,6 +100,11 @@ const ServiceEntityPage = ({ entity }: { entity: Entity }) => ( title="Docs" element={} /> + } + /> ); @@ -124,6 +130,11 @@ const WebsiteEntityPage = ({ entity }: { entity: Entity }) => ( title="Docs" element={} /> + } + /> ); const DefaultEntityPage = ({ entity }: { entity: Entity }) => ( diff --git a/packages/app/src/plugins.ts b/packages/app/src/plugins.ts index b36d0323e0..aa68bc5fad 100644 --- a/packages/app/src/plugins.ts +++ b/packages/app/src/plugins.ts @@ -33,3 +33,4 @@ export { plugin as Jenkins } from '@backstage/plugin-jenkins'; export { plugin as ApiDocs } from '@backstage/plugin-api-docs'; export { plugin as GithubPullRequests } from '@roadiehq/backstage-plugin-github-pull-requests'; export { plugin as GcpProjects } from '@backstage/plugin-gcp-projects'; +export { plugin as Kubernetes } from '@backstage/plugin-kubernetes'; diff --git a/packages/backend/package.json b/packages/backend/package.json index aa6f0ad0bf..147ea630c2 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -26,6 +26,7 @@ "@backstage/plugin-catalog-backend": "^0.1.1-alpha.22", "@backstage/plugin-graphql-backend": "^0.1.1-alpha.22", "@backstage/plugin-identity-backend": "^0.1.1-alpha.22", + "@backstage/plugin-kubernetes-backend": "^0.1.1-alpha.22", "@backstage/plugin-proxy-backend": "^0.1.1-alpha.22", "@backstage/plugin-rollbar-backend": "^0.1.1-alpha.22", "@backstage/plugin-scaffolder-backend": "^0.1.1-alpha.22", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index ab32822769..7c52175d76 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -34,6 +34,7 @@ import healthcheck from './plugins/healthcheck'; import auth from './plugins/auth'; import catalog from './plugins/catalog'; import identity from './plugins/identity'; +import kubernetes from './plugins/kubernetes'; import rollbar from './plugins/rollbar'; import scaffolder from './plugins/scaffolder'; import sentry from './plugins/sentry'; @@ -73,6 +74,7 @@ async function main() { const rollbarEnv = useHotMemoize(module, () => createEnv('rollbar')); const sentryEnv = useHotMemoize(module, () => createEnv('sentry')); const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs')); + const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes')); const graphqlEnv = useHotMemoize(module, () => createEnv('graphql')); const appEnv = useHotMemoize(module, () => createEnv('app')); @@ -86,6 +88,7 @@ async function main() { .addRouter('/auth', await auth(authEnv)) .addRouter('/identity', await identity(identityEnv)) .addRouter('/techdocs', await techdocs(techdocsEnv)) + .addRouter('/kubernetes', await kubernetes(kubernetesEnv)) .addRouter('/proxy', await proxy(proxyEnv, '/proxy')) .addRouter('/graphql', await graphql(graphqlEnv)) .addRouter('', await app(appEnv)); diff --git a/packages/backend/src/plugins/kubernetes.ts b/packages/backend/src/plugins/kubernetes.ts new file mode 100644 index 0000000000..42b7722ff6 --- /dev/null +++ b/packages/backend/src/plugins/kubernetes.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createRouter } from '@backstage/plugin-kubernetes-backend'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin({ logger }: PluginEnvironment) { + return await createRouter({ logger }); +} diff --git a/packages/core-api/src/apis/definitions/IdentityApi.ts b/packages/core-api/src/apis/definitions/IdentityApi.ts index 13f4cd24bc..2684422b1e 100644 --- a/packages/core-api/src/apis/definitions/IdentityApi.ts +++ b/packages/core-api/src/apis/definitions/IdentityApi.ts @@ -46,9 +46,9 @@ export type IdentityApi = { // TODO: getProfile(): Promise - We want this to be async when added, but needs more work. /** - * Log out the current user + * Sign out the current user */ - logout(): Promise; + signOut(): Promise; }; export const identityApiRef = createApiRef({ diff --git a/packages/core-api/src/apis/definitions/auth.ts b/packages/core-api/src/apis/definitions/auth.ts index 1ff8c46dad..800a865fea 100644 --- a/packages/core-api/src/apis/definitions/auth.ts +++ b/packages/core-api/src/apis/definitions/auth.ts @@ -90,11 +90,6 @@ export type OAuthApi = { scope?: OAuthScope, options?: AuthRequestOptions, ): Promise; - - /** - * Log out the user's session. This will reload the page. - */ - logout(): Promise; }; /** @@ -114,11 +109,6 @@ export type OpenIdConnectApi = { * The returned promise can be rejected, but only if the user rejects the login request. */ getIdToken(options?: AuthRequestOptions): Promise; - - /** - * Log out the user's session. This will reload the page. - */ - logout(): Promise; }; /** @@ -187,7 +177,7 @@ export type ProfileInfo = { }; /** - * Session state values passed to subscribers of the SessionStateApi. + * Session state values passed to subscribers of the SessionApi. */ export enum SessionState { SignedIn = 'SignedIn', @@ -195,10 +185,22 @@ export enum SessionState { } /** - * This API provides access to an sessionState$ observable which provides an update when the - * user performs a sign in or sign out from an auth provider. + * The SessionApi provides basic controls for any auth provider that is tied to a persistent session. */ -export type SessionStateApi = { +export type SessionApi = { + /** + * Sign in with a minimum set of permissions. + */ + signIn(): Promise; + + /** + * Sign out from the current session. This will reload the page. + */ + signOut(): Promise; + + /** + * Observe the current state of the auth session. Emits the current state on subscription. + */ sessionState$(): Observable; }; @@ -215,7 +217,7 @@ export const googleAuthApiRef = createApiRef< OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & - SessionStateApi + SessionApi >({ id: 'core.auth.google', description: 'Provides authentication towards Google APIs and identities', @@ -228,7 +230,7 @@ export const googleAuthApiRef = createApiRef< * for a full list of supported scopes. */ export const githubAuthApiRef = createApiRef< - OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi + OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >({ id: 'core.auth.github', description: 'Provides authentication towards GitHub APIs', @@ -245,7 +247,7 @@ export const oktaAuthApiRef = createApiRef< OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & - SessionStateApi + SessionApi >({ id: 'core.auth.okta', description: 'Provides authentication towards Okta APIs', @@ -258,7 +260,7 @@ export const oktaAuthApiRef = createApiRef< * for a full list of supported scopes. */ export const gitlabAuthApiRef = createApiRef< - OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi + OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >({ id: 'core.auth.gitlab', description: 'Provides authentication towards GitLab APIs', @@ -271,7 +273,7 @@ export const gitlabAuthApiRef = createApiRef< * for a full list of supported scopes. */ export const auth0AuthApiRef = createApiRef< - OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi + OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >({ id: 'core.auth.auth0', description: 'Provides authentication towards Auth0 APIs', @@ -289,7 +291,7 @@ export const microsoftAuthApiRef = createApiRef< OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & - SessionStateApi + SessionApi >({ id: 'core.auth.microsoft', description: 'Provides authentication towards Microsoft APIs and identities', @@ -302,8 +304,8 @@ export const oauth2ApiRef = createApiRef< OAuthApi & OpenIdConnectApi & ProfileInfoApi & - SessionStateApi & - BackstageIdentityApi + BackstageIdentityApi & + SessionApi >({ id: 'core.auth.oauth2', description: 'Example of how to use oauth2 custom provider', diff --git a/packages/core-api/src/apis/implementations/auth/github/GithubAuth.ts b/packages/core-api/src/apis/implementations/auth/github/GithubAuth.ts index 8b9f807cd8..1d87ff3720 100644 --- a/packages/core-api/src/apis/implementations/auth/github/GithubAuth.ts +++ b/packages/core-api/src/apis/implementations/auth/github/GithubAuth.ts @@ -19,7 +19,7 @@ import { DefaultAuthConnector } from '../../../../lib/AuthConnector'; import { GithubSession } from './types'; import { OAuthApi, - SessionStateApi, + SessionApi, SessionState, ProfileInfo, BackstageIdentity, @@ -61,7 +61,7 @@ const DEFAULT_PROVIDER = { icon: GithubIcon, }; -class GithubAuth implements OAuthApi, SessionStateApi { +class GithubAuth implements OAuthApi, SessionApi { static create({ discoveryApi, environment = 'development', @@ -102,12 +102,20 @@ class GithubAuth implements OAuthApi, SessionStateApi { return new GithubAuth(authSessionStore); } + constructor(private readonly sessionManager: SessionManager) {} + + async signIn() { + await this.getAccessToken(); + } + + async signOut() { + await this.sessionManager.removeSession(); + } + sessionState$(): Observable { return this.sessionManager.sessionState$(); } - constructor(private readonly sessionManager: SessionManager) {} - async getAccessToken(scope?: string, options?: AuthRequestOptions) { const session = await this.sessionManager.getSession({ ...options, @@ -128,10 +136,6 @@ class GithubAuth implements OAuthApi, SessionStateApi { return session?.profile; } - async logout() { - await this.sessionManager.removeSession(); - } - static normalizeScope(scope?: string): Set { if (!scope) { return new Set(); diff --git a/packages/core-api/src/apis/implementations/auth/oauth2/OAuth2.ts b/packages/core-api/src/apis/implementations/auth/oauth2/OAuth2.ts index 27626aac5a..d088ca9798 100644 --- a/packages/core-api/src/apis/implementations/auth/oauth2/OAuth2.ts +++ b/packages/core-api/src/apis/implementations/auth/oauth2/OAuth2.ts @@ -32,7 +32,7 @@ import { ProfileInfo, ProfileInfoApi, SessionState, - SessionStateApi, + SessionApi, BackstageIdentityApi, } from '../../../definitions/auth'; import { OAuth2Session } from './types'; @@ -75,7 +75,7 @@ class OAuth2 OpenIdConnectApi, ProfileInfoApi, BackstageIdentityApi, - SessionStateApi { + SessionApi { static create({ discoveryApi, environment = 'development', @@ -129,6 +129,14 @@ class OAuth2 this.scopeTransform = options.scopeTransform; } + async signIn() { + await this.getAccessToken(); + } + + async signOut() { + await this.sessionManager.removeSession(); + } + sessionState$(): Observable { return this.sessionManager.sessionState$(); } @@ -150,10 +158,6 @@ class OAuth2 return session?.providerInfo.idToken ?? ''; } - async logout() { - await this.sessionManager.removeSession(); - } - async getBackstageIdentity( options: AuthRequestOptions = {}, ): Promise { diff --git a/packages/core-api/src/app/AppIdentity.ts b/packages/core-api/src/app/AppIdentity.ts index 69ee5d28ac..d3e5fe567a 100644 --- a/packages/core-api/src/app/AppIdentity.ts +++ b/packages/core-api/src/app/AppIdentity.ts @@ -26,7 +26,7 @@ export class AppIdentity implements IdentityApi { private userId?: string; private profile?: ProfileInfo; private idTokenFunc?: () => Promise; - private logoutFunc?: () => Promise; + private signOutFunc?: () => Promise; getUserId(): string { if (!this.hasIdentity) { @@ -55,13 +55,13 @@ export class AppIdentity implements IdentityApi { return this.idTokenFunc?.(); } - async logout(): Promise { + async signOut(): Promise { if (!this.hasIdentity) { throw new Error( - 'Tried to access IdentityApi logoutFunc before app was loaded', + 'Tried to access IdentityApi signOutFunc before app was loaded', ); } - await this.logoutFunc?.(); + await this.signOutFunc?.(); location.reload(); } @@ -80,6 +80,6 @@ export class AppIdentity implements IdentityApi { this.userId = result.userId; this.profile = result.profile; this.idTokenFunc = result.getIdToken; - this.logoutFunc = result.logout; + this.signOutFunc = result.signOut; } } diff --git a/packages/core-api/src/app/types.ts b/packages/core-api/src/app/types.ts index 565e073aed..882ecd3d8b 100644 --- a/packages/core-api/src/app/types.ts +++ b/packages/core-api/src/app/types.ts @@ -38,10 +38,11 @@ export type SignInResult = { * Function used to retrieve an ID token for the signed in user. */ getIdToken?: () => Promise; + /** - * Logout handler that will be called if the user requests a logout. + * Sign out handler that will be called if the user requests to sign out. */ - logout?: () => Promise; + signOut?: () => Promise; }; export type SignInPageProps = { diff --git a/packages/core/src/layout/InfoCard/InfoCard.tsx b/packages/core/src/layout/InfoCard/InfoCard.tsx index 6914d396b1..09d31735cd 100644 --- a/packages/core/src/layout/InfoCard/InfoCard.tsx +++ b/packages/core/src/layout/InfoCard/InfoCard.tsx @@ -37,6 +37,7 @@ const useStyles = makeStyles(theme => ({ }, }, header: { + display: 'inline-block', padding: theme.spacing(2, 2, 2, 2.5), }, headerTitle: { @@ -202,7 +203,7 @@ export const InfoCard = ({ }} title={title} subheader={subheader} - style={{ display: 'inline-block', ...headerStyle }} + style={{ ...headerStyle }} {...headerProps} /> diff --git a/packages/core/src/layout/Sidebar/DefaultProviderSettings.tsx b/packages/core/src/layout/Sidebar/DefaultProviderSettings.tsx index 293cefb19a..f96c6adb2f 100644 --- a/packages/core/src/layout/Sidebar/DefaultProviderSettings.tsx +++ b/packages/core/src/layout/Sidebar/DefaultProviderSettings.tsx @@ -25,7 +25,7 @@ import { } from '@backstage/core-api'; import Star from '@material-ui/icons/Star'; import React from 'react'; -import { OAuthProviderSettings, OIDCProviderSettings } from './Settings'; +import { ProviderSettingsItem } from './Settings'; export const DefaultProviderSettings = () => { const configApi = useApi(configApiRef); @@ -35,42 +35,42 @@ export const DefaultProviderSettings = () => { return ( <> {providers.includes('google') && ( - )} {providers.includes('microsoft') && ( - )} {providers.includes('github') && ( - )} {providers.includes('gitlab') && ( - )} {providers.includes('okta') && ( - )} {providers.includes('oauth2') && ( - ; -}; - -export const OAuthProviderSettings: FC = ({ - title, - icon, - apiRef, -}) => { - const api = useApi(apiRef); - const [signedIn, setSignedIn] = useState(false); - - useEffect(() => { - let didCancel = false; - - const checkSession = async () => { - const session = await api.getAccessToken('', { optional: true }); - if (!didCancel) { - setSignedIn(!!session); - } - }; - let subscription: Subscription; - const observeSession = () => { - subscription = api - .sessionState$() - .subscribe((sessionState: SessionState) => { - if (!didCancel) { - setSignedIn(sessionState === SessionState.SignedIn); - } - }); - }; - - checkSession(); - observeSession(); - return () => { - didCancel = true; - subscription.unsubscribe(); - }; - }, [api]); - - return ( - api.getAccessToken()} - /> - ); -}; diff --git a/packages/core/src/layout/Sidebar/Settings/OIDCProviderSettings.tsx b/packages/core/src/layout/Sidebar/Settings/OIDCProviderSettings.tsx deleted file mode 100644 index 19ee00eee1..0000000000 --- a/packages/core/src/layout/Sidebar/Settings/OIDCProviderSettings.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - ApiRef, - OpenIdConnectApi, - SessionStateApi, - useApi, - Subscription, - IconComponent, - SessionState, -} from '@backstage/core-api'; -import React, { FC, useState, useEffect } from 'react'; -import { ProviderSettingsItem } from './ProviderSettingsItem'; - -export type OIDCProviderSidebarProps = { - title: string; - icon: IconComponent; - apiRef: ApiRef; -}; - -export const OIDCProviderSettings: FC = ({ - title, - icon, - apiRef, -}) => { - const api = useApi(apiRef); - const [signedIn, setSignedIn] = useState(false); - - useEffect(() => { - let didCancel = false; - - const checkSession = async () => { - const session = await api.getIdToken({ optional: true }); - if (!didCancel) { - setSignedIn(!!session); - } - }; - - let subscription: Subscription; - const observeSession = () => { - subscription = api - .sessionState$() - .subscribe((sessionState: SessionState) => { - if (!didCancel) { - setSignedIn(sessionState === SessionState.SignedIn); - } - }); - }; - - checkSession(); - observeSession(); - return () => { - didCancel = true; - subscription.unsubscribe(); - }; - }, [api]); - - return ( - api.getIdToken()} - /> - ); -}; diff --git a/packages/core/src/layout/Sidebar/Settings/ProviderSettingsItem.tsx b/packages/core/src/layout/Sidebar/Settings/ProviderSettingsItem.tsx index 653c64575b..4db7ea0823 100644 --- a/packages/core/src/layout/Sidebar/Settings/ProviderSettingsItem.tsx +++ b/packages/core/src/layout/Sidebar/Settings/ProviderSettingsItem.tsx @@ -14,8 +14,7 @@ * limitations under the License. */ -import React from 'react'; -import { IconComponent, OAuthApi, OpenIdConnectApi } from '@backstage/core-api'; +import React, { FC, useState, useEffect } from 'react'; import { ListItem, ListItemIcon, @@ -25,42 +24,67 @@ import { } from '@material-ui/core'; import PowerButton from '@material-ui/icons/PowerSettingsNew'; import { ToggleButton } from '@material-ui/lab'; +import { + ApiRef, + SessionApi, + useApi, + IconComponent, + SessionState, +} from '@backstage/core-api'; -type Props = { +type OAuthProviderSidebarProps = { title: string; icon: IconComponent; - signedIn: boolean; - api: OAuthApi | OpenIdConnectApi; - signInHandler: Function; + apiRef: ApiRef; }; -export const ProviderSettingsItem = ({ +export const ProviderSettingsItem: FC = ({ title, icon: Icon, - signedIn, - api, - signInHandler, -}: Props) => ( - - - - - - - (signedIn ? api.logout() : signInHandler())} - > - { + const api = useApi(apiRef); + const [signedIn, setSignedIn] = useState(false); + + useEffect(() => { + let didCancel = false; + + const subscription = api + .sessionState$() + .subscribe((sessionState: SessionState) => { + if (!didCancel) { + setSignedIn(sessionState === SessionState.SignedIn); + } + }); + + return () => { + didCancel = true; + subscription.unsubscribe(); + }; + }, [api]); + + return ( + + + + + + + (signedIn ? api.signOut() : api.signIn())} > - - - - - -); + + + + + + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/UserSettingsMenu.tsx b/packages/core/src/layout/Sidebar/Settings/UserSettingsMenu.tsx index 9ac287c57e..151ddb6e75 100644 --- a/packages/core/src/layout/Sidebar/Settings/UserSettingsMenu.tsx +++ b/packages/core/src/layout/Sidebar/Settings/UserSettingsMenu.tsx @@ -43,7 +43,7 @@ export const UserSettingsMenu = () => { - identityApi.logout()}> + identityApi.signOut()}> diff --git a/packages/core/src/layout/Sidebar/Settings/index.ts b/packages/core/src/layout/Sidebar/Settings/index.ts index 7abf061620..15042dc85d 100644 --- a/packages/core/src/layout/Sidebar/Settings/index.ts +++ b/packages/core/src/layout/Sidebar/Settings/index.ts @@ -15,6 +15,4 @@ */ export { ProviderSettingsItem } from './ProviderSettingsItem'; -export { OAuthProviderSettings } from './OAuthProviderSettings'; -export { OIDCProviderSettings } from './OIDCProviderSettings'; export { SidebarUserSettings } from './UserSettings'; diff --git a/packages/core/src/layout/Sidebar/Sidebar.stories.tsx b/packages/core/src/layout/Sidebar/Sidebar.stories.tsx index d7451965fe..61975a728a 100644 --- a/packages/core/src/layout/Sidebar/Sidebar.stories.tsx +++ b/packages/core/src/layout/Sidebar/Sidebar.stories.tsx @@ -23,7 +23,7 @@ import { SidebarSearchField, SidebarSpace, SidebarUserSettings, - OAuthProviderSettings, + ProviderSettingsItem, } from '.'; import HomeOutlinedIcon from '@material-ui/icons/HomeOutlined'; import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline'; @@ -60,7 +60,7 @@ export const SampleSidebar = () => ( { profile: profile!, getIdToken: () => auth0AuthApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await auth0AuthApi.logout(); + signOut: async () => { + await auth0AuthApi.signOut(); }, }); } catch (error) { @@ -79,8 +79,8 @@ const loader: ProviderLoader = async apis => { userId: identity.id, profile: profile!, getIdToken: () => auth0AuthApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await auth0AuthApi.logout(); + signOut: async () => { + await auth0AuthApi.signOut(); }, }; }; diff --git a/packages/core/src/layout/SignInPage/commonProvider.tsx b/packages/core/src/layout/SignInPage/commonProvider.tsx index de9452a850..b7480afa49 100644 --- a/packages/core/src/layout/SignInPage/commonProvider.tsx +++ b/packages/core/src/layout/SignInPage/commonProvider.tsx @@ -44,8 +44,8 @@ const Component: ProviderComponent = ({ config, onResult }) => { getIdToken: () => { return authApi.getBackstageIdentity().then(i => i!.idToken); }, - logout: async () => { - await authApi.logout(); + signOut: async () => { + await authApi.signOut(); }, }); } catch (error) { @@ -87,8 +87,8 @@ const loader: ProviderLoader = async (apis, apiRef) => { userId: identity.id, profile: profile!, getIdToken: () => authApi.getBackstageIdentity().then(i => i!.idToken), - logout: async () => { - await authApi.logout(); + signOut: async () => { + await authApi.signOut(); }, }; }; diff --git a/packages/core/src/layout/SignInPage/providers.tsx b/packages/core/src/layout/SignInPage/providers.tsx index ff60eba228..e2c17ab80d 100644 --- a/packages/core/src/layout/SignInPage/providers.tsx +++ b/packages/core/src/layout/SignInPage/providers.tsx @@ -83,14 +83,14 @@ export const useSignInProviders = ( const apiHolder = useApiHolder(); const [loading, setLoading] = useState(true); - // This decorates the result with logout logic from this hook + // This decorates the result with sign out logic from this hook const handleWrappedResult = useCallback( (result: SignInResult) => { onResult({ ...result, - logout: async () => { + signOut: async () => { localStorage.removeItem(PROVIDER_STORAGE_KEY); - await result.logout?.(); + await result.signOut?.(); }, }); }, diff --git a/packages/core/src/layout/SignInPage/types.ts b/packages/core/src/layout/SignInPage/types.ts index 9c501e8095..48945e6988 100644 --- a/packages/core/src/layout/SignInPage/types.ts +++ b/packages/core/src/layout/SignInPage/types.ts @@ -20,19 +20,16 @@ import { SignInResult, ApiHolder, ApiRef, - OAuthApi, ProfileInfoApi, BackstageIdentityApi, - SessionStateApi, + SessionApi, } from '@backstage/core-api'; export type SignInConfig = { id: string; title: string; message: string; - apiRef: ApiRef< - OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi - >; + apiRef: ApiRef; }; export type IdentityProviders = ('guest' | 'custom' | SignInConfig)[]; @@ -43,9 +40,7 @@ export type ProviderComponent = ComponentType< export type ProviderLoader = ( apis: ApiHolder, - apiRef: ApiRef< - OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi - >, + apiRef: ApiRef, ) => Promise; export type SignInProvider = { diff --git a/packages/storybook/.storybook/apis.js b/packages/storybook/.storybook/apis.js index a0a220d3de..878256ff5c 100644 --- a/packages/storybook/.storybook/apis.js +++ b/packages/storybook/.storybook/apis.js @@ -36,7 +36,7 @@ builder.add(identityApiRef, { getUserId: () => 'guest', getProfile: () => ({ email: 'guest@example.com' }), getIdToken: () => undefined, - logout: async () => {}, + signOut: async () => {}, }); const oauthRequestApi = builder.add( diff --git a/packages/techdocs-container/Dockerfile b/packages/techdocs-container/Dockerfile index e910935baf..b34fcbd861 100644 --- a/packages/techdocs-container/Dockerfile +++ b/packages/techdocs-container/Dockerfile @@ -18,7 +18,7 @@ FROM python:3.8-alpine RUN apk update && apk --no-cache add gcc musl-dev openjdk11-jdk curl graphviz ttf-dejavu fontconfig RUN curl -L http://sourceforge.net/projects/plantuml/files/plantuml.1.2020.16.jar/download > /opt/plantuml.jar -RUN pip install --upgrade pip && pip install mkdocs-techdocs-core==0.0.7 +RUN pip install --upgrade pip && pip install mkdocs-techdocs-core==0.0.8 # Create script to call plantuml.jar from a location in path diff --git a/packages/techdocs-container/mock-docs/docs/index.md b/packages/techdocs-container/mock-docs/docs/index.md index 2586b86cfb..3c323d6fc1 100644 --- a/packages/techdocs-container/mock-docs/docs/index.md +++ b/packages/techdocs-container/mock-docs/docs/index.md @@ -3,10 +3,9 @@ !!! test Testing somethin +Abbreviations: Some text about MOCDOC -\*[MOCDOC]: Mock Documentation - This is a paragraph. {: #test_id .test_class } @@ -61,3 +60,40 @@ digraph G { ``` :bulb: + +=== "JavaScript" + + ```javascript + import { test } from 'something'; + + const addThingToThing = (a, b) a + b; + ``` + +=== "Java" + + ```java + public void function() { + test(); + } + ``` + +```java tab="java" + public void function() { + test(); + } +``` + +```java tab="java 2" + public void function() { + test(); + } +``` + +```javascript +import { test } from 'something'; + +const addThingToThing = (a, b) a + b; +``` + + +*[MOCDOC]: Mock Documentation diff --git a/packages/techdocs-container/techdocs-core/README.md b/packages/techdocs-container/techdocs-core/README.md index 36f1437a54..49b9fce4e4 100644 --- a/packages/techdocs-container/techdocs-core/README.md +++ b/packages/techdocs-container/techdocs-core/README.md @@ -48,8 +48,72 @@ python -m black src/ **Note:** This will write to all Python files in `src/` with the formatted code. If you would like to only check to see if it passes, simply append the `--check` flag. +## MkDocs plugins and extensions + +The TechDocs Core MkDocs plugin comes with a set of extensions and plugins that mkdocs supports. Below you can find a list of all extensions and plugins that are included in the +TechDocs Core plugin: + +Plugins: + +- [search](https://www.mkdocs.org/user-guide/configuration/#search) +- [mkdocs-monorepo-plugin](https://github.com/spotify/mkdocs-monorepo-plugin) + +Extensions: + +- [admonition](https://squidfunk.github.io/mkdocs-material/reference/admonitions/#admonitions) +- [toc](https://python-markdown.github.io/extensions/toc/) +- [pymdown](https://facelessuser.github.io/pymdown-extensions/) + - caret + - critic + - details + - emoji + - superfences + - inlinehilite + - magiclink + - mark + - smartsymobls + - highlight + - extra + - tabbed + - tasklist + - tilde +- [markdown_inline_graphviz](https://pypi.org/project/markdown-inline-graphviz/) +- [plantuml_markdown](https://pypi.org/project/plantuml-markdown/) + ## Changelog +### 0.0.8 + +- Superfences and Codehilite doesn't work very well together (squidfunk/mkdocs-material#1604) so therefore the codehilite extension is replaced by pymdownx.highlight + +* Uses pymdownx extensions v.7.1 instead of 8.0.0 to allow legacy_tab_classes config. This makes the techdocs core plugin compatible with the usage of tabs for grouping markdown with the following syntax: + +```` + ```java tab="java 2" + public void function() { + .... + } + ``` +```` + +as well as the new + +```` + === "Java" + + ```java + public void function() { + .... + } + ``` +```` + +The pymdownx extension will be bumped too 8.0.0 in the near future. + +- pymdownx.tabbed is added to support tabs to group markdown content, such as codeblocks. + +- "PyMdown Extensions includes three extensions that are meant to replace their counterpart in the default Python Markdown extensions." Therefore some extensions has been taken away in this version that comes by default from pymdownx.extra which is added now (https://facelessuser.github.io/pymdown-extensions/usage_notes/#incompatible-extensions) + ### 0.0.7 - Fix an issue with configuration of emoji support diff --git a/packages/techdocs-container/techdocs-core/requirements.txt b/packages/techdocs-container/techdocs-core/requirements.txt index 36daaab4d7..75546fa992 100644 --- a/packages/techdocs-container/techdocs-core/requirements.txt +++ b/packages/techdocs-container/techdocs-core/requirements.txt @@ -7,7 +7,7 @@ mkdocs-monorepo-plugin==0.4.5 plantuml-markdown==3.1.2 markdown_inline_graphviz_extension==1.1 pygments==2.6.1 -pymdown-extensions==8.0.0 +pymdown-extensions==7.1 # The linter using for Python # Note: This requires Python 3.6+ to run, but can format Python 2 code too. diff --git a/packages/techdocs-container/techdocs-core/setup.py b/packages/techdocs-container/techdocs-core/setup.py index 3e3fa47caa..e5a8206150 100644 --- a/packages/techdocs-container/techdocs-core/setup.py +++ b/packages/techdocs-container/techdocs-core/setup.py @@ -17,38 +17,34 @@ from setuptools import setup, find_packages setup( - name='mkdocs-techdocs-core', - version='0.0.7', - description='A Mkdocs package that contains TechDocs defaults', - long_description='', - keywords='mkdocs', - url='https://github.com/spotify/backstage', - author='TechDocs Core', - author_email='pulp-fiction@spotify.com', - license='Apache-2.0', - python_requires='>=3.7', + name="mkdocs-techdocs-core", + version="0.0.8", + description="A Mkdocs package that contains TechDocs defaults", + long_description="", + keywords="mkdocs", + url="https://github.com/spotify/backstage", + author="TechDocs Core", + author_email="pulp-fiction@spotify.com", + license="Apache-2.0", + python_requires=">=3.7", install_requires=[ - 'mkdocs>=1.1.2', - 'mkdocs-material==5.3.2', - 'mkdocs-monorepo-plugin==0.4.5', - 'plantuml-markdown==3.1.2', - 'markdown_inline_graphviz_extension==1.1', - 'pygments==2.6.1', - 'pymdown-extensions==8.0.0' + "mkdocs>=1.1.2", + "mkdocs-material==5.3.2", + "mkdocs-monorepo-plugin==0.4.5", + "plantuml-markdown==3.1.2", + "markdown_inline_graphviz_extension==1.1", + "pygments==2.6.1", + "pymdown-extensions==7.1", ], classifiers=[ - 'Development Status :: 1 - Planning', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.7' + "Development Status :: 1 - Planning", + "Intended Audience :: Developers", + "Intended Audience :: Information Technology", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.7", ], packages=find_packages(), - entry_points={ - 'mkdocs.plugins': [ - 'techdocs-core = src.core:TechDocsCore' - ] - } + entry_points={"mkdocs.plugins": ["techdocs-core = src.core:TechDocsCore"]}, ) diff --git a/packages/techdocs-container/techdocs-core/src/core.py b/packages/techdocs-container/techdocs-core/src/core.py index 69e39d401b..ed1eb7c6f6 100644 --- a/packages/techdocs-container/techdocs-core/src/core.py +++ b/packages/techdocs-container/techdocs-core/src/core.py @@ -14,7 +14,7 @@ * limitations under the License. """ -from mkdocs.plugins import BasePlugin, PluginCollection +from mkdocs.plugins import BasePlugin from mkdocs.theme import Theme from mkdocs.contrib.search import SearchPlugin from mkdocs_monorepo_plugin.plugin import MonorepoPlugin @@ -54,25 +54,11 @@ class TechDocsCore(BasePlugin): # Markdown Extensions config["markdown_extensions"].append("admonition") - config["markdown_extensions"].append("abbr") - config["markdown_extensions"].append("attr_list") - config["markdown_extensions"].append("def_list") - config["markdown_extensions"].append("codehilite") - config["mdx_configs"]["codehilite"] = { - "linenums": True, - "guess_lang": False, - "pygments_style": "friendly", - } config["markdown_extensions"].append("toc") config["mdx_configs"]["toc"] = { "permalink": True, } - config["markdown_extensions"].append("footnotes") - config["markdown_extensions"].append("markdown.extensions.tables") - config["markdown_extensions"].append("pymdownx.betterem") - config["mdx_configs"]["pymdownx.betterem"] = { - "smart_enable": "all", - } + config["markdown_extensions"].append("pymdownx.caret") config["markdown_extensions"].append("pymdownx.critic") config["markdown_extensions"].append("pymdownx.details") @@ -83,6 +69,18 @@ class TechDocsCore(BasePlugin): config["markdown_extensions"].append("pymdownx.mark") config["markdown_extensions"].append("pymdownx.smartsymbols") config["markdown_extensions"].append("pymdownx.superfences") + config["mdx_configs"]["pymdownx.superfences"] = { + "legacy_tab_classes": True, + } + config["markdown_extensions"].append("pymdownx.highlight") + config["mdx_configs"]["pymdownx.highlight"] = { + "linenums": True, + } + config["markdown_extensions"].append("pymdownx.extra") + config["mdx_configs"]["pymdownx.betterem"] = { + "smart_enable": "all", + } + config["markdown_extensions"].append("pymdownx.tabbed") config["markdown_extensions"].append("pymdownx.tasklist") config["mdx_configs"]["pymdownx.tasklist"] = { "custom_checkbox": True, diff --git a/plugins/catalog/src/components/CatalogFilter/CatalogFilter.test.tsx b/plugins/catalog/src/components/CatalogFilter/CatalogFilter.test.tsx index a98eec0875..bc23d61d9c 100644 --- a/plugins/catalog/src/components/CatalogFilter/CatalogFilter.test.tsx +++ b/plugins/catalog/src/components/CatalogFilter/CatalogFilter.test.tsx @@ -58,7 +58,7 @@ describe('Catalog Filter', () => { ] as Entity[]), }; - const indentityApi: Partial = { + const identityApi: Partial = { getUserId: () => 'tools@example.com', }; @@ -68,7 +68,7 @@ describe('Catalog Filter', () => { diff --git a/plugins/circleci/src/components/Router.tsx b/plugins/circleci/src/components/Router.tsx index 282eac9111..41764b3d7d 100644 --- a/plugins/circleci/src/components/Router.tsx +++ b/plugins/circleci/src/components/Router.tsx @@ -24,8 +24,7 @@ import { Entity } from '@backstage/catalog-model'; import { WarningPanel } from '@backstage/core'; export const isPluginApplicableToEntity = (entity: Entity) => - Boolean(entity.metadata.annotations?.[CIRCLECI_ANNOTATION]) && - entity.metadata.annotations?.[CIRCLECI_ANNOTATION] !== ''; + Boolean(entity.metadata.annotations?.[CIRCLECI_ANNOTATION]); export const Router = ({ entity }: { entity: Entity }) => !isPluginApplicableToEntity(entity) ? ( diff --git a/plugins/github-actions/src/components/Router.tsx b/plugins/github-actions/src/components/Router.tsx index 7d340fb8b8..fae56a0480 100644 --- a/plugins/github-actions/src/components/Router.tsx +++ b/plugins/github-actions/src/components/Router.tsx @@ -23,13 +23,12 @@ import { GITHUB_ACTIONS_ANNOTATION } from './useProjectName'; import { WarningPanel } from '@backstage/core'; export const isPluginApplicableToEntity = (entity: Entity) => - Boolean(entity.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION]) && - entity.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION] !== ''; + Boolean(entity.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION]); export const Router = ({ entity }: { entity: Entity }) => // TODO(shmidt-i): move warning to a separate standardized component !isPluginApplicableToEntity(entity) ? ( - +
{GITHUB_ACTIONS_ANNOTATION}
annotation is missing on the entity.
diff --git a/plugins/jenkins/src/components/Router.tsx b/plugins/jenkins/src/components/Router.tsx index 56df5456bc..a4c7314691 100644 --- a/plugins/jenkins/src/components/Router.tsx +++ b/plugins/jenkins/src/components/Router.tsx @@ -23,8 +23,7 @@ import { WarningPanel } from '@backstage/core'; import { CITable } from './BuildsPage/lib/CITable'; export const isPluginApplicableToEntity = (entity: Entity) => - Boolean(entity.metadata.annotations?.[JENKINS_ANNOTATION]) && - entity.metadata.annotations?.[JENKINS_ANNOTATION] !== ''; + Boolean(entity.metadata.annotations?.[JENKINS_ANNOTATION]); export const Router = ({ entity }: { entity: Entity }) => { return !isPluginApplicableToEntity(entity) ? ( diff --git a/plugins/kubernetes-backend/.eslintrc.js b/plugins/kubernetes-backend/.eslintrc.js new file mode 100644 index 0000000000..16a033dbc6 --- /dev/null +++ b/plugins/kubernetes-backend/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint.backend')], +}; diff --git a/plugins/kubernetes-backend/README.md b/plugins/kubernetes-backend/README.md new file mode 100644 index 0000000000..0246da24ed --- /dev/null +++ b/plugins/kubernetes-backend/README.md @@ -0,0 +1,11 @@ +# Kubernetes Backend + +WORK IN PROGRESS + +This is the backend part of the Kubernetes plugin. + +It responds to Kubernetes requests from the frontend. + +## Links + +- [The Backstage homepage](https://backstage.io) diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json new file mode 100644 index 0000000000..2e59aaeec0 --- /dev/null +++ b/plugins/kubernetes-backend/package.json @@ -0,0 +1,42 @@ +{ + "name": "@backstage/plugin-kubernetes-backend", + "version": "0.1.1-alpha.22", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": false, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "start": "backstage-cli backend:dev", + "build": "backstage-cli backend:build", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/backend-common": "^0.1.1-alpha.22", + "@types/express": "^4.17.6", + "compression": "^1.7.4", + "cors": "^2.8.5", + "express": "^4.17.1", + "express-promise-router": "^3.0.3", + "fs-extra": "^9.0.0", + "helmet": "^4.0.0", + "morgan": "^1.10.0", + "winston": "^3.2.1", + "yn": "^4.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.22", + "jest-fetch-mock": "^3.0.3" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/kubernetes-backend/src/index.test.ts b/plugins/kubernetes-backend/src/index.test.ts new file mode 100644 index 0000000000..4fca4ca746 --- /dev/null +++ b/plugins/kubernetes-backend/src/index.test.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '@backstage/backend-common'; + +describe('test', () => { + it('unbreaks the test runner', () => { + expect(true).toBeTruthy(); + }); +}); diff --git a/plugins/kubernetes-backend/src/index.ts b/plugins/kubernetes-backend/src/index.ts new file mode 100644 index 0000000000..7612c392a2 --- /dev/null +++ b/plugins/kubernetes-backend/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './service/router'; diff --git a/plugins/kubernetes-backend/src/run.ts b/plugins/kubernetes-backend/src/run.ts new file mode 100644 index 0000000000..995adaff10 --- /dev/null +++ b/plugins/kubernetes-backend/src/run.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import yn from 'yn'; +import { getRootLogger } from '@backstage/backend-common'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 3004; +const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch(err => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/kubernetes-backend/src/service/router.ts b/plugins/kubernetes-backend/src/service/router.ts new file mode 100644 index 0000000000..b200896887 --- /dev/null +++ b/plugins/kubernetes-backend/src/service/router.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; + +export interface RouterOptions { + logger: Logger; +} + +const makeRouter = (logger: Logger): express.Router => { + const router = Router(); + router.use(express.json()); + + router.get('/services/:serviceId', async (req, res) => { + const serviceId = req.params.serviceId; + logger.info(`HERE ${serviceId}`); + res.send({ serviceId }); + }); + + return router; +}; + +export async function createRouter( + options: RouterOptions, +): Promise { + const logger = options.logger; + + logger.info('Initializing Kubernetes backend'); + return makeRouter(logger); +} diff --git a/plugins/kubernetes-backend/src/service/standaloneApplication.ts b/plugins/kubernetes-backend/src/service/standaloneApplication.ts new file mode 100644 index 0000000000..5eea4fb8f5 --- /dev/null +++ b/plugins/kubernetes-backend/src/service/standaloneApplication.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + errorHandler, + notFoundHandler, + requestLoggingHandler, +} from '@backstage/backend-common'; +import compression from 'compression'; +import cors from 'cors'; +import express from 'express'; +import helmet from 'helmet'; +import { Logger } from 'winston'; +import { createRouter } from './router'; + +export interface ApplicationOptions { + enableCors: boolean; + logger: Logger; +} + +export async function createStandaloneApplication( + options: ApplicationOptions, +): Promise { + const { enableCors, logger } = options; + const app = express(); + + app.use(helmet()); + if (enableCors) { + app.use(cors()); + } + app.use(compression()); + app.use(express.json()); + app.use(requestLoggingHandler()); + app.use('/', await createRouter({ logger })); + app.use(notFoundHandler()); + app.use(errorHandler()); + + return app; +} diff --git a/plugins/kubernetes-backend/src/service/standaloneServer.ts b/plugins/kubernetes-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..9831bc986b --- /dev/null +++ b/plugins/kubernetes-backend/src/service/standaloneServer.ts @@ -0,0 +1,50 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createStandaloneApplication } from './standaloneApplication'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'kubernetes-backend' }); + + logger.debug('Creating application...'); + const app = await createStandaloneApplication({ + enableCors: options.enableCors, + logger, + }); + + logger.debug('Starting application server...'); + return await new Promise((resolve, reject) => { + const server = app.listen(options.port, (err?: Error) => { + if (err) { + reject(err); + return; + } + + logger.info(`Listening on port ${options.port}`); + resolve(server); + }); + }); +} diff --git a/plugins/kubernetes-backend/src/setupTests.ts b/plugins/kubernetes-backend/src/setupTests.ts new file mode 100644 index 0000000000..f7b6ca962d --- /dev/null +++ b/plugins/kubernetes-backend/src/setupTests.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +require('jest-fetch-mock').enableMocks(); + +export {}; diff --git a/plugins/kubernetes/.eslintrc.js b/plugins/kubernetes/.eslintrc.js new file mode 100644 index 0000000000..13573efa9c --- /dev/null +++ b/plugins/kubernetes/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint')], +}; diff --git a/plugins/kubernetes/README.md b/plugins/kubernetes/README.md new file mode 100644 index 0000000000..678c9a96a6 --- /dev/null +++ b/plugins/kubernetes/README.md @@ -0,0 +1,13 @@ +# kubernetes + +Welcome to the kubernetes plugin! + +_This plugin was created through the Backstage CLI_ + +## Getting started + +Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/kubernetes](http://localhost:3000/kubernetes). + +You can also serve the plugin in isolation by running `yarn start` in the plugin directory. +This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. +It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. diff --git a/plugins/kubernetes/dev/index.tsx b/plugins/kubernetes/dev/index.tsx new file mode 100644 index 0000000000..f352fb9c34 --- /dev/null +++ b/plugins/kubernetes/dev/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createDevApp } from '@backstage/dev-utils'; +import { plugin } from '../src'; + +createDevApp().registerPlugin(plugin).render(); diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json new file mode 100644 index 0000000000..aa8a7f61e4 --- /dev/null +++ b/plugins/kubernetes/package.json @@ -0,0 +1,47 @@ +{ + "name": "@backstage/plugin-kubernetes", + "version": "0.1.1-alpha.22", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "build": "backstage-cli plugin:build", + "start": "backstage-cli plugin:serve", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "diff": "backstage-cli plugin:diff", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/catalog-model": "^0.1.1-alpha.22", + "@backstage/core": "^0.1.1-alpha.22", + "@backstage/theme": "^0.1.1-alpha.22", + "@material-ui/core": "^4.11.0", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.45", + "react": "^16.13.1", + "react-router-dom": "6.0.0-beta.0", + "react-dom": "^16.13.1", + "react-use": "^15.3.3" + }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.22", + "@backstage/dev-utils": "^0.1.1-alpha.22", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^10.4.1", + "@testing-library/user-event": "^12.0.7", + "@types/jest": "^26.0.7", + "@types/node": "^12.0.0", + "jest-fetch-mock": "^3.0.3" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/kubernetes/src/Router.tsx b/plugins/kubernetes/src/Router.tsx new file mode 100644 index 0000000000..994788bf72 --- /dev/null +++ b/plugins/kubernetes/src/Router.tsx @@ -0,0 +1,47 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Entity } from '@backstage/catalog-model'; +import { Route, Routes } from 'react-router-dom'; + +import { rootCatalogKubernetesRouteRef } from './plugin'; +import { KubernetesContent } from './components/KubernetesContent'; +import { WarningPanel } from '@backstage/core'; + +const KUBERNETES_ANNOTATION = 'backstage.io/kubernetes'; + +export const Router = ({ entity }: { entity: Entity }) => { + const kubernetesAnnotationValue = + entity.metadata.annotations?.[KUBERNETES_ANNOTATION]; + + if (!kubernetesAnnotationValue) { + return ( + +
{KUBERNETES_ANNOTATION}
annotation is missing on the entity. +
+ ); + } + + return ( + + } + /> + + ); +}; diff --git a/plugins/kubernetes/src/api/KubernetesBackendClient.ts b/plugins/kubernetes/src/api/KubernetesBackendClient.ts new file mode 100644 index 0000000000..fed3cd2ed0 --- /dev/null +++ b/plugins/kubernetes/src/api/KubernetesBackendClient.ts @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DiscoveryApi } from '@backstage/core'; +import { KubernetesApi } from './types'; + +export class KubernetesBackendClient implements KubernetesApi { + private readonly discoveryApi: DiscoveryApi; + + constructor(options: { discoveryApi: DiscoveryApi }) { + this.discoveryApi = options.discoveryApi; + } + + private async getRequired(path: string): Promise { + const url = `${await this.discoveryApi.getBaseUrl('kubernetes')}${path}`; + const response = await fetch(url); + + if (!response.ok) { + const payload = await response.text(); + const message = `Request failed with ${response.status} ${response.statusText}, ${payload}`; + throw new Error(message); + } + + return await response.json(); + } + + async getObjectsByServiceId(serviceId: String): Promise<{}> { + return await this.getRequired(`/services/${serviceId}`); + } +} diff --git a/plugins/kubernetes/src/api/types.ts b/plugins/kubernetes/src/api/types.ts new file mode 100644 index 0000000000..2ad6e567f9 --- /dev/null +++ b/plugins/kubernetes/src/api/types.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createApiRef } from '@backstage/core'; + +export const kubernetesApiRef = createApiRef({ + id: 'plugin.kubernetes.service', + description: + 'Used by the Kubernetes plugin to make requests to accompanying backend', +}); + +export interface KubernetesApi { + getObjectsByServiceId(serviceId: String): Promise<{}>; +} diff --git a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx new file mode 100644 index 0000000000..d79454a5d1 --- /dev/null +++ b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx @@ -0,0 +1,72 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { FC, useEffect, useState } from 'react'; +import { Typography, Grid } from '@material-ui/core'; +import { + InfoCard, + Page, + pageTheme, + Content, + ContentHeader, + useApi, +} from '@backstage/core'; +import { Entity } from '@backstage/catalog-model'; +import { kubernetesApiRef } from '../../api/types'; + +// TODO this is a temporary component used to construct the Kubernetes plugin boilerplate + +export const KubernetesContent: FC<{ entity: Entity }> = ({ entity }) => { + const kubernetesApi = useApi(kubernetesApiRef); + const [kubernetesObjects, setKubernetesObjects] = useState<{} | undefined>( + undefined, + ); + const [error, setError] = useState(undefined); + + useEffect(() => { + kubernetesApi + .getObjectsByServiceId(entity.metadata.name) + .then(result => { + setKubernetesObjects(result); + }) + .catch(e => { + setError(e.message); + }); + }, [entity.metadata.name, kubernetesApi]); + + return ( + + + + + + + + {kubernetesObjects === undefined &&
loading....
} + {error !== undefined &&
{error}
} + {kubernetesObjects !== undefined && ( +
+ backend response: {JSON.stringify(kubernetesObjects)} +
+ )} +
+
+
+
+
+
+ ); +}; diff --git a/plugins/kubernetes/src/components/KubernetesContent/index.ts b/plugins/kubernetes/src/components/KubernetesContent/index.ts new file mode 100644 index 0000000000..dc10b08927 --- /dev/null +++ b/plugins/kubernetes/src/components/KubernetesContent/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { KubernetesContent } from './KubernetesContent'; diff --git a/plugins/kubernetes/src/index.ts b/plugins/kubernetes/src/index.ts new file mode 100644 index 0000000000..8b5969666c --- /dev/null +++ b/plugins/kubernetes/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { plugin } from './plugin'; +export { Router } from './Router'; diff --git a/plugins/kubernetes/src/plugin.test.ts b/plugins/kubernetes/src/plugin.test.ts new file mode 100644 index 0000000000..20c50a813a --- /dev/null +++ b/plugins/kubernetes/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { plugin } from './plugin'; + +describe('kubernetes', () => { + it('should export plugin', () => { + expect(plugin).toBeDefined(); + }); +}); diff --git a/plugins/kubernetes/src/plugin.ts b/plugins/kubernetes/src/plugin.ts new file mode 100644 index 0000000000..b7ad9615f5 --- /dev/null +++ b/plugins/kubernetes/src/plugin.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createApiFactory, + createPlugin, + createRouteRef, + discoveryApiRef, +} from '@backstage/core'; +import { KubernetesBackendClient } from './api/KubernetesBackendClient'; +import { kubernetesApiRef } from './api/types'; + +export const rootCatalogKubernetesRouteRef = createRouteRef({ + path: '*', + title: 'Kubernetes', +}); + +export const plugin = createPlugin({ + id: 'kubernetes', + apis: [ + createApiFactory({ + api: kubernetesApiRef, + deps: { discoveryApi: discoveryApiRef }, + factory: ({ discoveryApi }) => + new KubernetesBackendClient({ discoveryApi }), + }), + ], +}); diff --git a/plugins/kubernetes/src/setupTests.ts b/plugins/kubernetes/src/setupTests.ts new file mode 100644 index 0000000000..4b4cdbdaaf --- /dev/null +++ b/plugins/kubernetes/src/setupTests.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; + +require('jest-fetch-mock').enableMocks(); diff --git a/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.test.tsx b/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.test.tsx index bb7faabc9d..10c3d9fcd1 100644 --- a/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.test.tsx +++ b/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.test.tsx @@ -14,53 +14,38 @@ * limitations under the License. */ -import { cleanup, fireEvent, render } from '@testing-library/react'; +import { act, render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import React from 'react'; -import { act } from 'react-dom/test-utils'; -import RegisterComponentForm, { Props } from './RegisterComponentForm'; +import { RegisterComponentForm } from './RegisterComponentForm'; -const setup = (props?: Partial) => { - return { - rendered: render( - , - ), - }; -}; describe('RegisterComponentForm', () => { - afterEach(() => cleanup()); - it('should initially render a disabled button', async () => { - const { rendered } = setup(); + render(); + expect( - await rendered.findByText( - 'Enter the full path to the component.yaml file in GitHub, GitLab, Bitbucket or Azure to start tracking your component.', - ), + await screen.findByText(/Enter the full path to the catalog-info.yaml/), ).toBeInTheDocument(); - const submit = (await rendered.getByRole('button')) as HTMLButtonElement; - expect(submit.disabled).toBeTruthy(); + expect(screen.getByText('Submit').closest('button')).toBeDisabled(); }); - it('should enable a submit form when data when component url is set ', async () => { - const { rendered } = setup(); - const input = (await rendered.getByRole('textbox')) as HTMLInputElement; + it('should enable a submit button when the target url is set ', async () => { + render(); + await act(async () => { - // react-hook-form uses `input` event for changes - fireEvent.input(input, { - target: { value: 'https://example.com/blob/master/component.yaml' }, - }); + await userEvent.type( + await screen.findByLabelText('Entity file URL', { exact: false }), + 'https://example.com/blob/master/component.yaml', + ); }); - const submit = (await rendered.getByRole('button')) as HTMLButtonElement; - expect(submit.disabled).toBeFalsy(); + expect(screen.getByText('Submit').closest('button')).not.toBeDisabled(); + }); + + it('should show spinner while submitting', async () => { + render(); + + expect(screen.getByTestId('loading-progress')).toBeInTheDocument(); }); }); - -it('should show spinner while submitting', async () => { - const { rendered } = setup({ submitting: true }); - expect(rendered.getByTestId('loading-progress')).toBeInTheDocument(); -}); diff --git a/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.tsx b/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.tsx index 4090b2af9c..bc433e1c36 100644 --- a/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.tsx +++ b/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.tsx @@ -19,12 +19,15 @@ import { Button, FormControl, FormHelperText, + InputLabel, LinearProgress, + MenuItem, + Select, TextField, } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import React, { FC } from 'react'; -import { useForm } from 'react-hook-form'; +import React from 'react'; +import { Controller, useForm } from 'react-hook-form'; import { ComponentIdValidators } from '../../util/validate'; const useStyles = makeStyles(theme => ({ @@ -36,15 +39,18 @@ const useStyles = makeStyles(theme => ({ submit: { marginTop: theme.spacing(1), }, + select: { + minWidth: 120, + }, })); export type Props = { onSubmit: (formData: Record) => Promise; - submitting: boolean; + submitting?: boolean; }; -const RegisterComponentForm: FC = ({ onSubmit, submitting }) => { - const { register, handleSubmit, errors, formState } = useForm({ +export const RegisterComponentForm = ({ onSubmit, submitting }: Props) => { + const { control, register, handleSubmit, errors, formState } = useForm({ mode: 'onChange', }); const classes = useStyles(); @@ -64,14 +70,14 @@ const RegisterComponentForm: FC = ({ onSubmit, submitting }) => { = ({ onSubmit, submitting }) => { )} + + + Host type + ( + + )} + /> +