diff --git a/README.md b/README.md index 9bef6bec..50065f20 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Discovering artifacts to use with CNCF projects can be difficult. If every CNCF At the moment, the following artifacts kinds are supported *(with plans to support more projects to follow)*: +- [Backstage plugins](https://backstage.io) - [Containers images](https://opencontainers.org) - [CoreDNS plugins](https://coredns.io/) - [Falco configurations](https://falco.org/) diff --git a/charts/artifact-hub/Chart.yaml b/charts/artifact-hub/Chart.yaml index 2cb1e2cc..3d9193b3 100644 --- a/charts/artifact-hub/Chart.yaml +++ b/charts/artifact-hub/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: artifact-hub description: Artifact Hub is a web-based application that enables finding, installing, and publishing Kubernetes packages. type: application -version: 1.12.1-2 +version: 1.12.1-3 appVersion: 1.12.0 kubeVersion: ">= 1.19.0-0" home: https://artifacthub.io @@ -24,6 +24,7 @@ keywords: - gatekeeper - kyverno - knative + - backstage maintainers: - name: Sergio email: tegioz@icloud.com diff --git a/charts/artifact-hub/values.schema.json b/charts/artifact-hub/values.schema.json index 6908bca1..5167df10 100644 --- a/charts/artifact-hub/values.schema.json +++ b/charts/artifact-hub/values.schema.json @@ -93,7 +93,10 @@ "title": "Lifetime after finished execution", "description": "Limits the lifetime of the job after it has finished execution", "default": null, - "type": ["null", "integer"] + "type": [ + "null", + "integer" + ] } }, "required": [ @@ -1066,7 +1069,7 @@ }, "repositoriesKinds": { "title": "Repositories kinds to process ([] = all)", - "description": "The following kinds are supported at the moment: falco, helm, olm, opa, tbaction, krew, helm-plugin, tekton-task, keda-scaler, coredns, keptn, tekton-pipeline, container, kubewarden, gatekeeper, kyverno, knative-client-plugin", + "description": "The following kinds are supported at the moment: falco, helm, olm, opa, tbaction, krew, helm-plugin, tekton-task, keda-scaler, coredns, keptn, tekton-pipeline, container, kubewarden, gatekeeper, kyverno, knative-client-plugin, backstage", "type": "array", "items": { "type": "string" diff --git a/cmd/ah/lint.go b/cmd/ah/lint.go index 9fd0b762..833e9292 100644 --- a/cmd/ah/lint.go +++ b/cmd/ah/lint.go @@ -90,7 +90,7 @@ func newLintCmd() *cobra.Command { return lint(opts, &output{cmd.OutOrStdout()}) }, } - lintCmd.Flags().StringVarP(&opts.kind, "kind", "k", "helm", "repository kind: coredns, falco, helm, helm-plugin, keda-scaler, keptn, krew, kubewarden, olm, opa, tbaction, tekton-task, tekton-pipeline") + lintCmd.Flags().StringVarP(&opts.kind, "kind", "k", "helm", "repository kind: backstage, coredns, falco, gatekeeper, helm, helm-plugin, keda-scaler, keptn, knative-client-plugin, krew, kubewarden, kyverno, olm, opa, tbaction, tekton-task, tekton-pipeline") lintCmd.Flags().StringVarP(&opts.path, "path", "p", ".", "repository's packages path") return lintCmd } @@ -109,11 +109,15 @@ func lint(opts *lintOptions, out *output) error { var report *lintReport switch kind { case + hub.Backstage, hub.CoreDNS, hub.Falco, + hub.Gatekeeper, hub.KedaScaler, hub.Keptn, + hub.KnativeClientPlugin, hub.Kubewarden, + hub.Kyverno, hub.OPA, hub.TBAction: report = lintGeneric(opts.path, kind) @@ -605,11 +609,15 @@ func (out *output) printPkgDetails(pkg *hub.Package) { // Values specific to a repository kind switch pkg.Repository.Kind { case + hub.Backstage, hub.CoreDNS, hub.Falco, + hub.Gatekeeper, hub.KedaScaler, hub.Keptn, + hub.KnativeClientPlugin, hub.Kubewarden, + hub.Kyverno, hub.OPA, hub.TBAction: diff --git a/database/migrations/schema/044_backstage_plugins.sql b/database/migrations/schema/044_backstage_plugins.sql new file mode 100644 index 00000000..090bd034 --- /dev/null +++ b/database/migrations/schema/044_backstage_plugins.sql @@ -0,0 +1,5 @@ +insert into repository_kind values (17, 'Backstage plugins'); + +---- create above / drop below ---- + +delete from repository_kind where repository_kind_id = 17; diff --git a/database/tests/schema/schema.sql b/database/tests/schema/schema.sql index df21ee7a..430c54fe 100644 --- a/database/tests/schema/schema.sql +++ b/database/tests/schema/schema.sql @@ -524,7 +524,8 @@ select results_eq( (13, 'Kubewarden policies'), (14, 'Gatekeeper policies'), (15, 'Kyverno policies'), - (16, 'Knative client plugins') + (16, 'Knative client plugins'), + (17, 'Backstage plugins') $$, 'Repository kinds should exist' ); diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index 864046a4..592b78fd 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -1112,6 +1112,29 @@ paths: $ref: "#/components/responses/TooManyRequests" "500": $ref: "#/components/responses/InternalServerError" + "/packages/backstage/{repoName}/{packageName}": + get: + tags: + - Packages + summary: Get package details + description: Get package details + operationId: getBackstagePluginsDetails + parameters: + - $ref: "#/components/parameters/RepoNameParam" + - $ref: "#/components/parameters/PackageNameParam" + responses: + "200": + description: "" + content: + application/json: + schema: + $ref: "#/components/schemas/BackstagePlugin" + "404": + $ref: "#/components/responses/NotFoundResponse" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" "/packages/container/{repoName}/{packageName}": get: tags: @@ -1503,6 +1526,30 @@ paths: $ref: "#/components/responses/TooManyRequests" "500": $ref: "#/components/responses/InternalServerError" + "/packages/backstage/{repoName}/{packageName}/{version}": + get: + tags: + - Packages + summary: Get package version details + description: Get package version details + operationId: getBackstagePluginsVersionDetails + parameters: + - $ref: "#/components/parameters/RepoNameParam" + - $ref: "#/components/parameters/PackageNameParam" + - $ref: "#/components/parameters/VersionParam" + responses: + "200": + description: "" + content: + application/json: + schema: + $ref: "#/components/schemas/BackstagePlugin" + "404": + $ref: "#/components/responses/NotFoundResponse" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" "/packages/container/{repoName}/{packageName}/{version}": get: tags: @@ -3429,6 +3476,8 @@ components: name: user1 total: 3 filter_key: user + BackstagePlugin: + $ref: "#/components/schemas/Package" ContainerImage: allOf: - $ref: "#/components/schemas/Package" @@ -4311,6 +4360,7 @@ components: * `14` - Gatekeeper policies * `15` - Kyverno policies * `16` - Knative client plugins + * `17` - Backstage plugins RepositoryKindParam: type: string enum: @@ -4331,6 +4381,7 @@ components: - gatekeeper - kyverno - knative-client-plugin + - backstage description: | Repository kind name: * `helm` - Helm charts @@ -4350,6 +4401,7 @@ components: * `gatekeeper` - Gatekeeper policies * `kyverno` - Kyverno policies * `knative-client-plugin` - Knative client plugins + * `backstage` - Backstage plugins RepositorySummary: type: object required: @@ -4848,7 +4900,8 @@ components: * `13` - Kubewarden policies * `14` - Gatekeeper policies * `15` - Kyverno policies - * `15` - Knative client plugins + * `16` - Knative client plugins + * `17` - Backstage plugins PackageNameParam: in: path name: packageName diff --git a/docs/backstage_plugins_repositories.md b/docs/backstage_plugins_repositories.md new file mode 100644 index 00000000..b973339b --- /dev/null +++ b/docs/backstage_plugins_repositories.md @@ -0,0 +1,49 @@ +## Backstage plugins repositories + +Backstage plugins repositories are expected to be hosted in GitHub, GitLab or Bitbucket repos. When adding your repository to Artifact Hub, the url used **must** follow the following format: + +- `https://github.com/user/repo[/path/to/packages]` +- `https://gitlab.com/user/repo[/path/to/packages]` +- `https://bitbucket.org/user/repo[/path/to/packages]` + +By default the `master` branch is used, but it's possible to specify a different one from the UI. + +*Please NOTE that the repository URL used when adding the repository to Artifact Hub **must NOT** contain the git hosting platform specific parts, like **tree/branch**, just the path to your packages like it would show in the filesystem.* + +The *path/to/packages* provided can contain metadata for one or more packages. Each package version **must** be on a separate folder, and it's up to you to decide if you want to publish one or multiple versions of your package. + +The structure of a repository with multiple plugins packages and versions could look something like this: + +```sh +$ tree path/to/packages +path/to/packages +├── artifacthub-repo.yml +├── package1 +│   ├── 1.0.0 +│   │   ├── README.md +│   │   └── artifacthub-pkg.yml +│   └── 2.0.0 +│      ├── README.md +│   └── artifacthub-pkg.yml +└── package2 + └── 1.0.0 +       ├── README.md + └── artifacthub-pkg.yml +``` + +This structure is flexible, and in some cases it can be greatly simplified. In the case of a single package with a single version available at a time (the publisher doesn't want to make previous ones available, for example), the structure could look like this: + +```sh +$ tree path/to/packages +path/to/packages +├── artifacthub-repo.yml +└── package1 +    ├── README.md + └── artifacthub-pkg.yml +``` + +In the previous case, even the `package1` directory could be omitted. The reason is that both packages names and versions are read from the `artifacthub-pkg.yml` metadata file, so directories names are not used at all. + +Each package version **needs** an `artifacthub-pkg.yml` metadata file. Please see the file [spec](https://github.com/artifacthub/hub/blob/master/docs/metadata/artifacthub-pkg.yml) for more details. The [artifacthub-repo.yml](https://github.com/artifacthub/hub/blob/master/docs/metadata/artifacthub-repo.yml) repository metadata file shown above can be used to setup features like [Verified publisher](https://github.com/artifacthub/hub/blob/master/docs/repositories.md#verified-publisher) or [Ownership claim](https://github.com/artifacthub/hub/blob/master/docs/repositories.md#ownership-claim). This file must be located at `/path/to/packages`. + +Once you have added your repository, you are all set up. As you add new versions of your plugins packages or even new packages to your git repository, they'll be automatically indexed and listed in Artifact Hub. diff --git a/docs/repositories.md b/docs/repositories.md index a4e0602a..8b06c4a1 100644 --- a/docs/repositories.md +++ b/docs/repositories.md @@ -4,6 +4,7 @@ Artifact Hub allows publishers to list their content in an automated way. Publis The following repositories kinds are supported at the moment: +- [Backstage plugins repositories](https://github.com/artifacthub/hub/blob/master/docs/backstage_plugins_repositories.md) - [Containers images repositories](https://github.com/artifacthub/hub/blob/master/docs/container_images_repositories.md) - [CoreDNS plugins repositories](https://github.com/artifacthub/hub/blob/master/docs/coredns_plugins_repositories.md) - [Falco rules repositories](https://github.com/artifacthub/hub/blob/master/docs/falco_rules_repositories.md) diff --git a/docs/www/headers/backstage_plugins_repositories b/docs/www/headers/backstage_plugins_repositories new file mode 100644 index 00000000..78e84ce4 --- /dev/null +++ b/docs/www/headers/backstage_plugins_repositories @@ -0,0 +1,6 @@ +--- +title: "Backstage plugins" +aliases: [ + "/backstage_plugins_repositories", +] +--- diff --git a/docs/www/headers/container_images_repositories b/docs/www/headers/container_images_repositories index e7db4b3c..cc240bc6 100644 --- a/docs/www/headers/container_images_repositories +++ b/docs/www/headers/container_images_repositories @@ -1,6 +1,5 @@ --- title: "Containers images" -weight: 1 aliases: [ "/container_images_repositories" ] diff --git a/docs/www/headers/coredns_plugins_repositories b/docs/www/headers/coredns_plugins_repositories index a3e89644..9ccfe607 100644 --- a/docs/www/headers/coredns_plugins_repositories +++ b/docs/www/headers/coredns_plugins_repositories @@ -1,6 +1,5 @@ --- title: "CoreDNS plugins" -weight: 2 aliases: [ "/coredns_plugins_repositories", ] diff --git a/docs/www/headers/falco_rules_repositories b/docs/www/headers/falco_rules_repositories index a5d6624e..afd58a26 100644 --- a/docs/www/headers/falco_rules_repositories +++ b/docs/www/headers/falco_rules_repositories @@ -1,6 +1,5 @@ --- title: "Falco rules" -weight: 3 aliases: [ "/falco_rules_repositories", ] diff --git a/docs/www/headers/gatekeeper_policies_repositories b/docs/www/headers/gatekeeper_policies_repositories index d12d1c00..a7fc11a0 100644 --- a/docs/www/headers/gatekeeper_policies_repositories +++ b/docs/www/headers/gatekeeper_policies_repositories @@ -1,6 +1,5 @@ --- title: "Gatekeeper policies" -weight: 4 aliases: [ "/gatekeeper_policies_repositories", ] diff --git a/docs/www/headers/helm_annotations b/docs/www/headers/helm_annotations index 48f8d5d6..b2f39f40 100644 --- a/docs/www/headers/helm_annotations +++ b/docs/www/headers/helm_annotations @@ -1,6 +1,5 @@ --- title: "Helm" -weight: 1 aliases: [ "/helm_annotations" ] diff --git a/docs/www/headers/helm_charts_repositories b/docs/www/headers/helm_charts_repositories index 5f54da27..a2551064 100644 --- a/docs/www/headers/helm_charts_repositories +++ b/docs/www/headers/helm_charts_repositories @@ -1,6 +1,5 @@ --- title: "Helm charts" -weight: 5 aliases: [ "/helm_charts_repositories", ] diff --git a/docs/www/headers/helm_plugins_repositories b/docs/www/headers/helm_plugins_repositories index 2700fd88..0eec7b43 100644 --- a/docs/www/headers/helm_plugins_repositories +++ b/docs/www/headers/helm_plugins_repositories @@ -1,6 +1,5 @@ --- title: "Helm plugins" -weight: 6 aliases: [ "/helm_plugins_repositories", ] diff --git a/docs/www/headers/keda_scalers_repositories b/docs/www/headers/keda_scalers_repositories index da2ac4b0..530d1ddd 100644 --- a/docs/www/headers/keda_scalers_repositories +++ b/docs/www/headers/keda_scalers_repositories @@ -1,6 +1,5 @@ --- title: "KEDA scalers" -weight: 7 aliases: [ "/keda_scalers_repositories", ] diff --git a/docs/www/headers/keptn_annotations b/docs/www/headers/keptn_annotations index 4712fcd6..dba991ed 100644 --- a/docs/www/headers/keptn_annotations +++ b/docs/www/headers/keptn_annotations @@ -1,6 +1,5 @@ --- title: "Keptn" -weight: 2 aliases: [ "/keptn_annotations", ] diff --git a/docs/www/headers/keptn_integrations_repositories b/docs/www/headers/keptn_integrations_repositories index a33907cd..9c743709 100644 --- a/docs/www/headers/keptn_integrations_repositories +++ b/docs/www/headers/keptn_integrations_repositories @@ -1,6 +1,5 @@ --- title: "Keptn integrations" -weight: 8 aliases: [ "/keptn_integrations_repositories", ] diff --git a/docs/www/headers/knative_client_plugins_repositories b/docs/www/headers/knative_client_plugins_repositories index ba68cab2..b09f54fb 100644 --- a/docs/www/headers/knative_client_plugins_repositories +++ b/docs/www/headers/knative_client_plugins_repositories @@ -1,6 +1,5 @@ --- title: "Knative client plugins" -weight: 9 aliases: [ "/knative_client_plugins_repositories", ] diff --git a/docs/www/headers/krew_annotations b/docs/www/headers/krew_annotations index cc5cf90c..68631cd7 100644 --- a/docs/www/headers/krew_annotations +++ b/docs/www/headers/krew_annotations @@ -1,6 +1,5 @@ --- title: "Krew" -weight: 3 aliases: [ "/krew_annotations", ] diff --git a/docs/www/headers/krew_kubectl_plugins_repositories b/docs/www/headers/krew_kubectl_plugins_repositories index 50711e9f..fe9aca1b 100644 --- a/docs/www/headers/krew_kubectl_plugins_repositories +++ b/docs/www/headers/krew_kubectl_plugins_repositories @@ -1,6 +1,5 @@ --- title: "Krew kubectl plugins" -weight: 10 aliases: [ "/krew_kubectl_plugins_repositories", ] diff --git a/docs/www/headers/kubewarden_annotations b/docs/www/headers/kubewarden_annotations index ba6b002a..f560f86f 100644 --- a/docs/www/headers/kubewarden_annotations +++ b/docs/www/headers/kubewarden_annotations @@ -1,6 +1,5 @@ --- title: "Kubewarden" -weight: 4 aliases: [ "/kubewarden_annotations", ] diff --git a/docs/www/headers/kubewarden_policies_repositories b/docs/www/headers/kubewarden_policies_repositories index 318d70cc..09bb47ac 100644 --- a/docs/www/headers/kubewarden_policies_repositories +++ b/docs/www/headers/kubewarden_policies_repositories @@ -1,6 +1,5 @@ --- title: "Kubewarden policies" -weight: 11 aliases: [ "/kubewarden_policies_repositories", ] diff --git a/docs/www/headers/kyverno_annotations b/docs/www/headers/kyverno_annotations index c8b7f8b2..64234025 100644 --- a/docs/www/headers/kyverno_annotations +++ b/docs/www/headers/kyverno_annotations @@ -1,6 +1,5 @@ --- title: "Kyverno" -weight: 5 aliases: [ "/kyverno_annotations" ] diff --git a/docs/www/headers/kyverno_policies_repositories b/docs/www/headers/kyverno_policies_repositories index 031c3dcf..04d7a0b2 100644 --- a/docs/www/headers/kyverno_policies_repositories +++ b/docs/www/headers/kyverno_policies_repositories @@ -1,6 +1,5 @@ --- title: "Kyverno policies" -weight: 12 aliases: [ "/kyverno_policies_repositories", ] diff --git a/docs/www/headers/olm_annotations b/docs/www/headers/olm_annotations index 81add935..5b41b72f 100644 --- a/docs/www/headers/olm_annotations +++ b/docs/www/headers/olm_annotations @@ -1,6 +1,5 @@ --- title: "OLM" -weight: 6 aliases: [ "/olm_annotations", ] diff --git a/docs/www/headers/olm_operators_repositories b/docs/www/headers/olm_operators_repositories index eaa8c39e..5eb87daf 100644 --- a/docs/www/headers/olm_operators_repositories +++ b/docs/www/headers/olm_operators_repositories @@ -1,6 +1,5 @@ --- title: "OLM operators" -weight: 13 aliases: [ "/olm_operators_repositories", ] diff --git a/docs/www/headers/opa_policies_repositories b/docs/www/headers/opa_policies_repositories index c8fc1996..45ae2ec7 100644 --- a/docs/www/headers/opa_policies_repositories +++ b/docs/www/headers/opa_policies_repositories @@ -1,6 +1,5 @@ --- title: "OPA policies" -weight: 14 aliases: [ "/opa_policies_repositories", ] diff --git a/docs/www/headers/tekton_annotations b/docs/www/headers/tekton_annotations index b44d1f66..3f42ec6f 100644 --- a/docs/www/headers/tekton_annotations +++ b/docs/www/headers/tekton_annotations @@ -1,6 +1,5 @@ --- title: "Tekton" -weight: 7 aliases: [ "/tekton_annotations", ] diff --git a/docs/www/headers/tekton_pipelines_repositories b/docs/www/headers/tekton_pipelines_repositories index c6d86b09..a10fdc97 100644 --- a/docs/www/headers/tekton_pipelines_repositories +++ b/docs/www/headers/tekton_pipelines_repositories @@ -1,6 +1,5 @@ --- title: "Tekton pipelines" -weight: 15 aliases: [ "/tekton_pipelines_repositories", ] diff --git a/docs/www/headers/tekton_tasks_repositories b/docs/www/headers/tekton_tasks_repositories index 1684860a..aa990c34 100644 --- a/docs/www/headers/tekton_tasks_repositories +++ b/docs/www/headers/tekton_tasks_repositories @@ -1,6 +1,5 @@ --- title: "Tekton tasks" -weight: 16 aliases: [ "/tekton_tasks_repositories" ] diff --git a/docs/www/headers/tinkerbell_actions_repositories b/docs/www/headers/tinkerbell_actions_repositories index 1ea72474..c55022ed 100644 --- a/docs/www/headers/tinkerbell_actions_repositories +++ b/docs/www/headers/tinkerbell_actions_repositories @@ -1,6 +1,5 @@ --- title: "Tinkerbell actions" -weight: 17 aliases: [ "/tinkerbell_actions_repositories", ] diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 95759179..e48f4ed3 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -264,7 +264,7 @@ func (h *Handlers) setupRouter() { r.Get("/stats", h.Packages.GetStats) r.With(corsMW).Get("/search", h.Packages.Search) r.With(h.Users.RequireLogin).Get("/starred", h.Packages.GetStarredByUser) - r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin$}/{repoName}/{packageName}", func(r chi.Router) { + r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage$}/{repoName}/{packageName}", func(r chi.Router) { r.Get("/feed/rss", h.Packages.RssFeed) r.With(corsMW).Get("/summary", h.Packages.GetSummary) r.Get("/{version}", h.Packages.Get) @@ -421,7 +421,7 @@ func (h *Handlers) setupRouter() { // Index special entry points r.Route("/packages", func(r chi.Router) { - r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin$}/{repoName}/{packageName}", func(r chi.Router) { + r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage$}/{repoName}/{packageName}", func(r chi.Router) { r.With(h.Packages.InjectIndexMeta).Get("/{version}", h.Static.Index) r.With(h.Packages.InjectIndexMeta).Get("/", h.Static.Index) }) diff --git a/internal/handlers/pkg/handlers_test.go b/internal/handlers/pkg/handlers_test.go index 8b82d605..c6c89666 100644 --- a/internal/handlers/pkg/handlers_test.go +++ b/internal/handlers/pkg/handlers_test.go @@ -2069,6 +2069,17 @@ func TestBuildURL(t *testing.T) { "2.0.0", baseURL + "/packages/knative-client-plugin/repo1/pkg1/2.0.0", }, + { + &hub.Package{ + NormalizedName: "pkg1", + Repository: &hub.Repository{ + Kind: hub.Backstage, + Name: "repo1", + }, + }, + "2.0.0", + baseURL + "/packages/backstage/repo1/pkg1/2.0.0", + }, } for _, tc := range testCases { tc := tc diff --git a/internal/hub/repo.go b/internal/hub/repo.go index fa581a98..8042bd41 100644 --- a/internal/hub/repo.go +++ b/internal/hub/repo.go @@ -97,11 +97,16 @@ const ( // KnativeClientPlugin represents a repository with Knative client plugins. KnativeClientPlugin RepositoryKind = 16 + + // Backstage represents a repository with Backstage plugins. + Backstage RepositoryKind = 17 ) // GetKindName returns the name of the provided repository kind. func GetKindName(kind RepositoryKind) string { switch kind { + case Backstage: + return "backstage" case Container: return "container" case CoreDNS: @@ -145,6 +150,8 @@ func GetKindName(kind RepositoryKind) string { // provided. func GetKindFromName(kind string) (RepositoryKind, error) { switch kind { + case "backstage": + return Backstage, nil case "container": return Container, nil case "coredns": diff --git a/internal/repo/manager.go b/internal/repo/manager.go index bc80cebf..0689753d 100644 --- a/internal/repo/manager.go +++ b/internal/repo/manager.go @@ -78,6 +78,7 @@ var ( // validRepositoryKinds contains the repository kinds supported. validRepositoryKinds = []hub.RepositoryKind{ + hub.Backstage, hub.Container, hub.CoreDNS, hub.Falco, @@ -274,6 +275,7 @@ func (m *Manager) ClaimOwnership(ctx context.Context, repoName, orgName string) var basePath string switch r.Kind { case + hub.Backstage, hub.CoreDNS, hub.Falco, hub.Gatekeeper, @@ -448,6 +450,7 @@ func (m *Manager) locateMetadataFile(r *hub.Repository, basePath string) string mdFile = r.URL } case + hub.Backstage, hub.CoreDNS, hub.Falco, hub.Gatekeeper, @@ -806,6 +809,7 @@ func (m *Manager) validateURL(r *hub.Repository) error { } } case + hub.Backstage, hub.CoreDNS, hub.Falco, hub.Gatekeeper, diff --git a/internal/tracker/helpers.go b/internal/tracker/helpers.go index 9def9469..d52d5271 100644 --- a/internal/tracker/helpers.go +++ b/internal/tracker/helpers.go @@ -113,6 +113,7 @@ func SetupSource(i *hub.TrackerSourceInput) hub.TrackerSource { case hub.OLM: source = olm.NewTrackerSource(i) case + hub.Backstage, hub.CoreDNS, hub.Gatekeeper, hub.KedaScaler, diff --git a/internal/tracker/tracker.go b/internal/tracker/tracker.go index eecefd08..55288ad9 100644 --- a/internal/tracker/tracker.go +++ b/internal/tracker/tracker.go @@ -176,6 +176,7 @@ func (t *Tracker) cloneRepository() (string, string, error) { tmpDir, packagesPath, err = t.svc.Rc.CloneRepository(t.svc.Ctx, t.r) } case + hub.Backstage, hub.CoreDNS, hub.Falco, hub.Gatekeeper, diff --git a/scripts/prepare-docs.sh b/scripts/prepare-docs.sh index 422a1ebf..3863b49b 100755 --- a/scripts/prepare-docs.sh +++ b/scripts/prepare-docs.sh @@ -6,6 +6,7 @@ cat docs/www/headers/dev docs/dev.md > docs/www/content/topics/dev.md cat docs/www/headers/infrastructure docs/infrastructure.md > docs/www/content/topics/infrastructure.md mkdir -p docs/www/content/topics/repositories cat docs/www/headers/repositories docs/repositories.md > docs/www/content/topics/repositories/_index.md +cat docs/www/headers/backstage_plugins_repositories docs/backstage_plugins_repositories.md > docs/www/content/topics/repositories/backstage-plugins.md cat docs/www/headers/container_images_repositories docs/container_images_repositories.md > docs/www/content/topics/repositories/container-images.md cat docs/www/headers/coredns_plugins_repositories docs/coredns_plugins_repositories.md > docs/www/content/topics/repositories/coredns-plugins.md cat docs/www/headers/falco_rules_repositories docs/falco_rules_repositories.md > docs/www/content/topics/repositories/falco-rules.md diff --git a/web/public/static/media/backstage-light.svg b/web/public/static/media/backstage-light.svg new file mode 100644 index 00000000..c9a2462e --- /dev/null +++ b/web/public/static/media/backstage-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/public/static/media/backstage.svg b/web/public/static/media/backstage.svg new file mode 100644 index 00000000..fd0f1e90 --- /dev/null +++ b/web/public/static/media/backstage.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/public/static/media/backstage_icon.png b/web/public/static/media/backstage_icon.png new file mode 100644 index 00000000..0169bb81 Binary files /dev/null and b/web/public/static/media/backstage_icon.png differ diff --git a/web/public/static/media/placeholder_pkg_backstage.png b/web/public/static/media/placeholder_pkg_backstage.png new file mode 100644 index 00000000..d520dd81 Binary files /dev/null and b/web/public/static/media/placeholder_pkg_backstage.png differ diff --git a/web/src/layout/common/Image.tsx b/web/src/layout/common/Image.tsx index d960ff62..c851784a 100644 --- a/web/src/layout/common/Image.tsx +++ b/web/src/layout/common/Image.tsx @@ -62,6 +62,8 @@ const Image = (props: Props) => { return '/static/media/placeholder_pkg_kyverno.png'; case RepositoryKind.KnativeClientPlugin: return '/static/media/placeholder_pkg_knative.png'; + case RepositoryKind.Backstage: + return '/static/media/placeholder_pkg_backstage.png'; default: return PLACEHOLDER_SRC; } diff --git a/web/src/layout/common/RepositoryIcon.test.tsx b/web/src/layout/common/RepositoryIcon.test.tsx index f053de6d..75d01512 100644 --- a/web/src/layout/common/RepositoryIcon.test.tsx +++ b/web/src/layout/common/RepositoryIcon.test.tsx @@ -128,6 +128,13 @@ describe('RepositoryIcon', () => { expect(icon).toHaveProperty('src', 'http://localhost/static/media/knative-light.svg'); }); + it('renders Backstage plugin icon', () => { + render(); + const icon = screen.getByAltText('Icon'); + expect(icon).toBeInTheDocument(); + expect(icon).toHaveProperty('src', 'http://localhost/static/media/backstage-light.svg'); + }); + it('renders Chart icon - default type', () => { render(); const icons = screen.getAllByAltText('Icon'); diff --git a/web/src/layout/common/RepositoryIcon.tsx b/web/src/layout/common/RepositoryIcon.tsx index cbb3ce7d..7acd4062 100644 --- a/web/src/layout/common/RepositoryIcon.tsx +++ b/web/src/layout/common/RepositoryIcon.tsx @@ -77,6 +77,10 @@ const ICONS = { default: '/static/media/knative.svg', white: '/static/media/knative-light.svg', }, + [RepositoryKind.Backstage]: { + default: '/static/media/backstage.svg', + white: '/static/media/backstage-light.svg', + }, }; const RepositoryIcon = (props: Props) => { diff --git a/web/src/layout/common/SampleQueries.test.tsx b/web/src/layout/common/SampleQueries.test.tsx index e39ac539..c352d26b 100644 --- a/web/src/layout/common/SampleQueries.test.tsx +++ b/web/src/layout/common/SampleQueries.test.tsx @@ -82,6 +82,10 @@ jest.mock('../../utils/getSampleQueries', () => () => { name: 'Knative client plugings', querystring: 'kind=16', }, + { + name: 'Backstage plugings', + querystring: 'kind=17', + }, ]; }); diff --git a/web/src/layout/controlPanel/repositories/Modal.tsx b/web/src/layout/controlPanel/repositories/Modal.tsx index c84306c8..c5bf1e6a 100644 --- a/web/src/layout/controlPanel/repositories/Modal.tsx +++ b/web/src/layout/controlPanel/repositories/Modal.tsx @@ -431,6 +431,17 @@ const RepositoryModal = (props: Props) => { ); break; + case RepositoryKind.Backstage: + link = ( + + Backstage plugins + + ); + break; } if (isUndefined(link)) return; @@ -455,6 +466,7 @@ const RepositoryModal = (props: Props) => { case RepositoryKind.Gatekeeper: case RepositoryKind.Kyverno: case RepositoryKind.KnativeClientPlugin: + case RepositoryKind.Backstage: return ( <>

{ RepositoryKind.Gatekeeper, RepositoryKind.Kyverno, RepositoryKind.KnativeClientPlugin, + RepositoryKind.Backstage, ].includes(selectedKind) && (

{ RepositoryKind.Gatekeeper, RepositoryKind.Kyverno, RepositoryKind.KnativeClientPlugin, + RepositoryKind.Backstage, ].includes(selectedKind) && (
diff --git a/web/src/layout/controlPanel/repositories/__snapshots__/Modal.test.tsx.snap b/web/src/layout/controlPanel/repositories/__snapshots__/Modal.test.tsx.snap index fde178b7..64bbb012 100644 --- a/web/src/layout/controlPanel/repositories/__snapshots__/Modal.test.tsx.snap +++ b/web/src/layout/controlPanel/repositories/__snapshots__/Modal.test.tsx.snap @@ -59,6 +59,11 @@ exports[`Repository Modal - repositories section creates snapshot 1`] = ` name="repoKind" required="" > +