diff --git a/.github/workflows/nightly-upgrade-test.yaml b/.github/workflows/nightly-upgrade-test.yaml
index c933edd73..6b7a16dad 100644
--- a/.github/workflows/nightly-upgrade-test.yaml
+++ b/.github/workflows/nightly-upgrade-test.yaml
@@ -15,8 +15,10 @@ jobs:
from_version:
- 1.3
- 1.4
+ - 1.5
to_branch:
- main
+ - release-1.5
- release-1.4
- release-1.3
exclude:
@@ -28,6 +30,13 @@ jobs:
- from_version: 1.4
to_branch: release-1.4
+ - from_version: 1.5
+ to_branch: release-1.3
+ - from_version: 1.5
+ to_branch: release-1.4
+ - from_version: 1.5
+ to_branch: release-1.5
+
name: 'E2E Upgrade: ${{ matrix.from_version }} => ${{ matrix.to_branch }}'
concurrency:
group: '${{ github.workflow }}-${{ matrix.to_branch }}-${{ matrix.from_version }}'
diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml
index 4f33e71fd..886f3dedc 100644
--- a/.github/workflows/nightly.yaml
+++ b/.github/workflows/nightly.yaml
@@ -14,6 +14,7 @@ jobs:
matrix:
branch:
- main
+ - release-1.5
- release-1.4
- release-1.3
name: 'E2E Tests on ${{ matrix.branch }}'
diff --git a/.github/workflows/pr-bundle-diff-checks.yaml b/.github/workflows/pr-bundle-diff-checks.yaml
index 8a9e0b8b6..b12daaef5 100644
--- a/.github/workflows/pr-bundle-diff-checks.yaml
+++ b/.github/workflows/pr-bundle-diff-checks.yaml
@@ -50,12 +50,12 @@ jobs:
- name: Check for outdated bundle or manifests
id: manifests-diff-checker
run: |
- make bundles
+ make bundles build-installers
git status --porcelain
# Since operator-sdk 1.26.0, `make bundle` changes the `createdAt` field from the bundle every time we run it.
# The `git diff` below checks if only the createdAt field has changed. If is the only change, it is ignored.
# Inspired from https://github.com/operator-framework/operator-sdk/issues/6285#issuecomment-1415350333
- echo "MANIFESTS_CHANGED=$(if git diff --quiet -I'^ createdAt: ' bundle config; then echo "false"; else echo "true"; fi)" >> $GITHUB_OUTPUT
+ echo "MANIFESTS_CHANGED=$(if git diff --quiet -I'^ createdAt: ' bundle config dist; then echo "false"; else echo "true"; fi)" >> $GITHUB_OUTPUT
- name: Commit any manifest changes
if: ${{ steps.manifests-diff-checker.outputs.MANIFESTS_CHANGED == 'true' }}
@@ -66,11 +66,11 @@ jobs:
git pull --rebase --autostash
git add -A .
git commit \
- -m "Regenerate bundle manifests" \
+ -m "Regenerate bundle/installer manifests" \
-m "Co-authored-by: $GITHUB_ACTOR <$GITHUB_ACTOR@users.noreply.github.com>"
git push
- - name: Comment on PR if bundle manifests were updated
+ - name: Comment on PR if manifests were updated
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
if: ${{ !cancelled() && steps.manifests-diff-checker.outputs.MANIFESTS_CHANGED == 'true' }}
continue-on-error: true
@@ -82,5 +82,5 @@ jobs:
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
- body: '⚠️ Files changed in bundle generation!
Those changes to the operator bundle manifests should have been pushed automatically to your PR branch.'
+ body: '⚠️ Files changed in bundle and installer generation!
Those changes to the operator bundle/installer manifests should have been pushed automatically to your PR branch.'
})
diff --git a/Makefile b/Makefile
index a18b099f1..11bda04b7 100644
--- a/Makefile
+++ b/Makefile
@@ -256,6 +256,12 @@ docker-buildx: ## Build and push docker image for the manager for cross-platform
- $(CONTAINER_TOOL) buildx rm project-v3-builder
rm -f Dockerfile.cross
+.PHONY: build-installers
+build-installers: ## Generate a consolidated YAML with CRDs and deployment for all available profiles.
+ @for profile in $(PROFILES); do \
+ $(MAKE) build-installer PROFILE=$$profile; \
+ done
+
.PHONY: build-installer
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
mkdir -p dist/$(PROFILE)
@@ -265,8 +271,8 @@ build-installer: manifests generate kustomize ## Generate a consolidated YAML wi
.PHONY: deployment-manifest
deployment-manifest: build-installer ## Generate manifest to deploy operator. Deprecated. Use 'make build-installer' instead.
- cp -f dist/$(PROFILE)/install.yaml rhdh-operator-${VERSION}.yaml
- @echo "Generated operator script rhdh-operator-${VERSION}.yaml"
+ cp -f dist/$(PROFILE)/install.yaml $(PROFILE)-operator-${VERSION}.yaml
+ @echo "Generated operator script $(PROFILE)-operator-${VERSION}.yaml"
# A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0).
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index ca4d7a346..9b7acdd38 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -5,7 +5,7 @@
package v1alpha1
import (
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
diff --git a/api/v1alpha2/zz_generated.deepcopy.go b/api/v1alpha2/zz_generated.deepcopy.go
index 1357c08bd..c3ecd6b25 100644
--- a/api/v1alpha2/zz_generated.deepcopy.go
+++ b/api/v1alpha2/zz_generated.deepcopy.go
@@ -5,7 +5,7 @@
package v1alpha2
import (
- v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
diff --git a/api/v1alpha3/zz_generated.deepcopy.go b/api/v1alpha3/zz_generated.deepcopy.go
index 6613a8896..b315b789e 100644
--- a/api/v1alpha3/zz_generated.deepcopy.go
+++ b/api/v1alpha3/zz_generated.deepcopy.go
@@ -5,7 +5,7 @@
package v1alpha3
import (
- v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
diff --git a/bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml b/bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml
index 18f1933fd..e91d32ecb 100644
--- a/bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml
+++ b/bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml
@@ -35,7 +35,7 @@ metadata:
}
}
]
- createdAt: "2025-02-11T17:40:38Z"
+ createdAt: "2025-02-17T10:12:56Z"
description: Backstage Operator
operators.operatorframework.io/builder: operator-sdk-v1.37.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
diff --git a/bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml b/bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml
index 7c51476c3..c2fc4bd87 100644
--- a/bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml
+++ b/bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml
@@ -39,7 +39,7 @@ metadata:
categories: Developer Tools
certified: "true"
containerImage: registry.redhat.io/rhdh/rhdh-rhel9-operator:1.5
- createdAt: "2025-02-11T17:40:40Z"
+ createdAt: "2025-02-17T10:12:59Z"
description: Red Hat Developer Hub is a Red Hat supported version of Backstage.
It comes with pre-built plug-ins and configuration settings, supports use of
an external database, and can help streamline the process of setting up a self-managed
diff --git a/dist/backstage.io/install.yaml b/dist/backstage.io/install.yaml
new file mode 100644
index 000000000..379759fed
--- /dev/null
+++ b/dist/backstage.io/install.yaml
@@ -0,0 +1,1826 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ labels:
+ app.kubernetes.io/component: manager
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: system
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: namespace
+ app.kubernetes.io/part-of: backstage-operator
+ control-plane: controller-manager
+ name: backstage-system
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.14.0
+ name: backstages.rhdh.redhat.com
+spec:
+ group: rhdh.redhat.com
+ names:
+ kind: Backstage
+ listKind: BackstageList
+ plural: backstages
+ singular: backstage
+ scope: Namespaced
+ versions:
+ - deprecated: true
+ deprecationWarning: Since 1.3.0 spec.application.image, spec.application.replicas,
+ spec.application.imagePullSecrets are deprecated in favor of corresponding spec.deployment
+ fields
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: false
+ subresources:
+ status: {}
+ - name: v1alpha2
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ deployment:
+ description: |-
+ Configuration for Backstage Deployment resource.
+ Optional.
+ properties:
+ patch:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: false
+ subresources:
+ status: {}
+ - name: v1alpha3
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ pvcs:
+ description: |-
+ List of references to Persistent Volume Claim objects mounted as extra files
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ mountPath:
+ description: Path to mount PVC. If not specified default-path/Name
+ will be used
+ type: string
+ name:
+ description: Name of the object
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ deployment:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ properties:
+ patch:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: controller-manager
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: serviceaccount
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-controller-manager
+ namespace: backstage-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: leader-election-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: role
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-leader-election-role
+ namespace: backstage-system
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - coordination.k8s.io
+ resources:
+ - leases
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - patch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: backstage-editor-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-backstage-editor-role
+rules:
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: backstage-viewer-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-backstage-viewer-role
+rules:
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: backstage-manager-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ - persistentvolumeclaims
+ - secrets
+ - services
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - ""
+ resources:
+ - persistentvolumes
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apps
+ resources:
+ - deployments
+ - statefulsets
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+ - patch
+ - update
+- apiGroups:
+ - route.openshift.io
+ resources:
+ - routes
+ - routes/custom-host
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-auth-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: metrics-auth-role
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-metrics-auth-role
+rules:
+- apiGroups:
+ - authentication.k8s.io
+ resources:
+ - tokenreviews
+ verbs:
+ - create
+- apiGroups:
+ - authorization.k8s.io
+ resources:
+ - subjectaccessreviews
+ verbs:
+ - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: metrics-rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-reader
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-metrics-reader
+rules:
+- nonResourceURLs:
+ - /metrics
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: leader-election-rolebinding
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: rolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-leader-election-rolebinding
+ namespace: backstage-system
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: backstage-leader-election-role
+subjects:
+- kind: ServiceAccount
+ name: backstage-controller-manager
+ namespace: backstage-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: manager-rolebinding
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-manager-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: backstage-manager-role
+subjects:
+- kind: ServiceAccount
+ name: backstage-controller-manager
+ namespace: backstage-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-auth-rolebinding
+ app.kubernetes.io/name: metrics-auth-rolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: backstage-metrics-auth-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: backstage-metrics-auth-role
+subjects:
+- kind: ServiceAccount
+ name: backstage-controller-manager
+ namespace: backstage-system
+---
+apiVersion: v1
+data:
+ app-config.yaml: |
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: my-backstage-config-cm1 # placeholder for -default-appconfig
+ data:
+ default.app-config.yaml: |
+ backend:
+ auth:
+ externalAccess:
+ - type: legacy
+ options:
+ subject: legacy-default-config
+ # This is a default value, which you should change by providing your own app-config
+ secret: "pl4s3Ch4ng3M3"
+ db-secret.yaml: |-
+ apiVersion: v1
+ kind: Secret
+ metadata:
+ name: postgres-secrets # will be replaced
+ type: Opaque
+ #stringData:
+ # POSTGRES_PASSWORD:
+ # POSTGRES_PORT: "5432"
+ # POSTGRES_USER: postgres
+ # POSTGRESQL_ADMIN_PASSWORD: admin123
+ # POSTGRES_HOST: bs1-db-service #placeholder -db-service
+ db-service.yaml: |
+ apiVersion: v1
+ kind: Service
+ metadata:
+ name: backstage-psql # placeholder for 'backstage-psql-' .NOTE: For the time it is static and linked to Secret-> postgres-secrets -> OSTGRES_HOST
+ spec:
+ selector:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ clusterIP: None
+ ports:
+ - port: 5432
+ db-statefulset.yaml: |-
+ apiVersion: apps/v1
+ kind: StatefulSet
+ metadata:
+ name: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ spec:
+ podManagementPolicy: OrderedReady
+ replicas: 1
+ selector:
+ matchLabels:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ serviceName: backstage-psql-cr1-hl # placeholder for 'backstage-psql--hl'
+ template:
+ metadata:
+ labels:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ spec:
+ # fsGroup does not work for Openshift
+ # AKS/EKS does not work w/o it
+ #securityContext:
+ # fsGroup: 26
+ automountServiceAccountToken: false
+ ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
+ ## The optional .spec.persistentVolumeClaimRetentionPolicy field controls if and how PVCs are deleted during the lifecycle of a StatefulSet.
+ ## You must enable the StatefulSetAutoDeletePVC feature gate on the API server and the controller manager to use this field.
+ # persistentVolumeClaimRetentionPolicy:
+ # whenDeleted: Retain
+ # whenScaled: Retain
+ containers:
+ - env:
+ - name: POSTGRESQL_PORT_NUMBER
+ value: "5432"
+ - name: POSTGRESQL_VOLUME_DIR
+ value: /var/lib/pgsql/data
+ - name: PGDATA
+ value: /var/lib/pgsql/data/userdata
+ image: quay.io/fedora/postgresql-15:latest # will be replaced with the actual image
+ imagePullPolicy: IfNotPresent
+ securityContext:
+ # runAsUser:26 does not work for Openshift but looks work for AKS/EKS
+ # runAsUser: 26
+ runAsGroup: 0
+ runAsNonRoot: true
+ allowPrivilegeEscalation: false
+ seccompProfile:
+ type: RuntimeDefault
+ capabilities:
+ drop:
+ - ALL
+ livenessProbe:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - exec pg_isready -U ${POSTGRES_USER} -h 127.0.0.1 -p 5432
+ failureThreshold: 6
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ name: postgresql
+ ports:
+ - containerPort: 5432
+ name: tcp-postgresql
+ protocol: TCP
+ readinessProbe:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - -e
+ - |
+ exec pg_isready -U ${POSTGRES_USER} -h 127.0.0.1 -p 5432
+ failureThreshold: 6
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ resources:
+ requests:
+ cpu: 250m
+ memory: 256Mi
+ limits:
+ cpu: 250m
+ memory: 1024Mi
+ ephemeral-storage: 20Mi
+ volumeMounts:
+ - mountPath: /dev/shm
+ name: dshm
+ - mountPath: /var/lib/pgsql/data
+ name: data
+ restartPolicy: Always
+ serviceAccountName: default
+ volumes:
+ - emptyDir:
+ medium: Memory
+ name: dshm
+ updateStrategy:
+ rollingUpdate:
+ partition: 0
+ type: RollingUpdate
+ volumeClaimTemplates:
+ - apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: data
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ deployment.yaml: |-
+ # kubernetes/backstage.yaml
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: backstage
+ spec:
+ selector:
+ matchLabels:
+ app: backstage
+ template:
+ metadata:
+ labels:
+ app: backstage
+ spec:
+ containers:
+ - name: backstage-backend
+ image: ghcr.io/backstage/backstage:1.28.4
+ imagePullPolicy: IfNotPresent
+ command:
+ - "node"
+ - "packages/backend"
+ - "--no-node-snapshot"
+ args:
+ - "--config"
+ - "app-config.yaml"
+ - "--config"
+ - "app-config.production.yaml"
+ ports:
+ - name: http
+ containerPort: 7007
+ # envFrom:
+ # - secretRef:
+ # name: postgres-secrets
+ # - secretRef:
+ # name: backstage-secrets
+ service.yaml: |-
+ apiVersion: v1
+ kind: Service
+ metadata:
+ name: backstage # placeholder for 'backstage-'
+ spec:
+ type: ClusterIP
+ selector:
+ rhdh.redhat.com/app: # placeholder for 'backstage-'
+ ports:
+ - name: http-backend
+ port: 80
+ targetPort: backend
+ - name: http-metrics
+ protocol: TCP
+ port: 9464
+ targetPort: 9464
+kind: ConfigMap
+metadata:
+ name: backstage-default-config
+ namespace: backstage-system
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app.kubernetes.io/component: metrics
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: controller-manager-metrics-service
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: service
+ app.kubernetes.io/part-of: backstage-operator
+ control-plane: controller-manager
+ name: backstage-controller-manager-metrics-service
+ namespace: backstage-system
+spec:
+ ports:
+ - name: metrics
+ port: 8443
+ protocol: TCP
+ targetPort: metrics
+ selector:
+ control-plane: controller-manager
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ app: operator
+ control-plane: controller-manager
+ name: backstage-operator
+ namespace: backstage-system
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: operator
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ kubectl.kubernetes.io/default-container: manager
+ labels:
+ app: operator
+ control-plane: controller-manager
+ spec:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: kubernetes.io/arch
+ operator: In
+ values:
+ - amd64
+ - key: kubernetes.io/os
+ operator: In
+ values:
+ - linux
+ automountServiceAccountToken: true
+ containers:
+ - args:
+ - --health-probe-bind-address=:8081
+ - --metrics-bind-address=:8443
+ - --metrics-secure=true
+ - --leader-elect
+ command:
+ - /manager
+ image: quay.io/rhdh-community/operator:0.6.0
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: health
+ initialDelaySeconds: 15
+ periodSeconds: 20
+ name: manager
+ ports:
+ - containerPort: 8081
+ name: health
+ - containerPort: 8443
+ name: metrics
+ readinessProbe:
+ httpGet:
+ path: /readyz
+ port: health
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ resources:
+ limits:
+ cpu: 500m
+ ephemeral-storage: 20Mi
+ memory: 1Gi
+ requests:
+ cpu: 10m
+ memory: 128Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ volumeMounts:
+ - mountPath: /default-config
+ name: default-config
+ securityContext:
+ runAsNonRoot: true
+ serviceAccountName: backstage-controller-manager
+ terminationGracePeriodSeconds: 10
+ volumes:
+ - configMap:
+ name: backstage-default-config
+ name: default-config
diff --git a/dist/rhdh/install.yaml b/dist/rhdh/install.yaml
new file mode 100644
index 000000000..da0a5c79c
--- /dev/null
+++ b/dist/rhdh/install.yaml
@@ -0,0 +1,2025 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ labels:
+ app.kubernetes.io/component: manager
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: system
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: namespace
+ app.kubernetes.io/part-of: backstage-operator
+ control-plane: controller-manager
+ name: rhdh-operator
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.14.0
+ name: backstages.rhdh.redhat.com
+spec:
+ group: rhdh.redhat.com
+ names:
+ kind: Backstage
+ listKind: BackstageList
+ plural: backstages
+ singular: backstage
+ scope: Namespaced
+ versions:
+ - deprecated: true
+ deprecationWarning: Since 1.3.0 spec.application.image, spec.application.replicas,
+ spec.application.imagePullSecrets are deprecated in favor of corresponding spec.deployment
+ fields
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: false
+ subresources:
+ status: {}
+ - name: v1alpha2
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ deployment:
+ description: |-
+ Configuration for Backstage Deployment resource.
+ Optional.
+ properties:
+ patch:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: false
+ subresources:
+ status: {}
+ - name: v1alpha3
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ pvcs:
+ description: |-
+ List of references to Persistent Volume Claim objects mounted as extra files
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ mountPath:
+ description: Path to mount PVC. If not specified default-path/Name
+ will be used
+ type: string
+ name:
+ description: Name of the object
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ deployment:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ properties:
+ patch:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: controller-manager
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: serviceaccount
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-controller-manager
+ namespace: rhdh-operator
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: leader-election-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: role
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-leader-election-role
+ namespace: rhdh-operator
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - coordination.k8s.io
+ resources:
+ - leases
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - patch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: backstage-editor-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-backstage-editor-role
+rules:
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: backstage-viewer-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-backstage-viewer-role
+rules:
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: rhdh-manager-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ - persistentvolumeclaims
+ - secrets
+ - services
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - ""
+ resources:
+ - persistentvolumes
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apps
+ resources:
+ - deployments
+ - statefulsets
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+ - patch
+ - update
+- apiGroups:
+ - route.openshift.io
+ resources:
+ - routes
+ - routes/custom-host
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-auth-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: metrics-auth-role
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-metrics-auth-role
+rules:
+- apiGroups:
+ - authentication.k8s.io
+ resources:
+ - tokenreviews
+ verbs:
+ - create
+- apiGroups:
+ - authorization.k8s.io
+ resources:
+ - subjectaccessreviews
+ verbs:
+ - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: metrics-rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-reader
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-metrics-reader
+rules:
+- nonResourceURLs:
+ - /metrics
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: leader-election-rolebinding
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: rolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-leader-election-rolebinding
+ namespace: rhdh-operator
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: rhdh-leader-election-role
+subjects:
+- kind: ServiceAccount
+ name: rhdh-controller-manager
+ namespace: rhdh-operator
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: manager-rolebinding
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-manager-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: rhdh-manager-role
+subjects:
+- kind: ServiceAccount
+ name: rhdh-controller-manager
+ namespace: rhdh-operator
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-auth-rolebinding
+ app.kubernetes.io/name: metrics-auth-rolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-metrics-auth-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: rhdh-metrics-auth-role
+subjects:
+- kind: ServiceAccount
+ name: rhdh-controller-manager
+ namespace: rhdh-operator
+---
+apiVersion: v1
+data:
+ app-config.yaml: |
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: my-backstage-config-cm1 # placeholder for -default-appconfig
+ data:
+ default.app-config.yaml: |
+ backend:
+ auth:
+ externalAccess:
+ - type: legacy
+ options:
+ subject: legacy-default-config
+ # This is a default value, which you should change by providing your own app-config
+ secret: "pl4s3Ch4ng3M3"
+ auth:
+ providers: {}
+ db-secret.yaml: |-
+ apiVersion: v1
+ kind: Secret
+ metadata:
+ name: postgres-secrets # will be replaced
+ type: Opaque
+ #stringData:
+ # POSTGRES_PASSWORD:
+ # POSTGRES_PORT: "5432"
+ # POSTGRES_USER: postgres
+ # POSTGRESQL_ADMIN_PASSWORD: admin123
+ # POSTGRES_HOST: bs1-db-service #placeholder -db-service
+ db-service.yaml: |
+ apiVersion: v1
+ kind: Service
+ metadata:
+ name: backstage-psql # placeholder for 'backstage-psql-' .NOTE: For the time it is static and linked to Secret-> postgres-secrets -> OSTGRES_HOST
+ spec:
+ selector:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ clusterIP: None
+ ports:
+ - port: 5432
+ db-statefulset.yaml: |-
+ apiVersion: apps/v1
+ kind: StatefulSet
+ metadata:
+ name: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ spec:
+ podManagementPolicy: OrderedReady
+ replicas: 1
+ selector:
+ matchLabels:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ serviceName: backstage-psql-cr1-hl # placeholder for 'backstage-psql--hl'
+ template:
+ metadata:
+ labels:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ spec:
+ # fsGroup does not work for Openshift
+ # AKS/EKS does not work w/o it
+ #securityContext:
+ # fsGroup: 26
+ automountServiceAccountToken: false
+ ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
+ ## The optional .spec.persistentVolumeClaimRetentionPolicy field controls if and how PVCs are deleted during the lifecycle of a StatefulSet.
+ ## You must enable the StatefulSetAutoDeletePVC feature gate on the API server and the controller manager to use this field.
+ # persistentVolumeClaimRetentionPolicy:
+ # whenDeleted: Retain
+ # whenScaled: Retain
+ containers:
+ - env:
+ - name: POSTGRESQL_PORT_NUMBER
+ value: "5432"
+ - name: POSTGRESQL_VOLUME_DIR
+ value: /var/lib/pgsql/data
+ - name: PGDATA
+ value: /var/lib/pgsql/data/userdata
+ image: quay.io/fedora/postgresql-15:latest # will be replaced with the actual image
+ imagePullPolicy: IfNotPresent
+ securityContext:
+ # runAsUser:26 does not work for Openshift but looks work for AKS/EKS
+ # runAsUser: 26
+ runAsGroup: 0
+ runAsNonRoot: true
+ allowPrivilegeEscalation: false
+ seccompProfile:
+ type: RuntimeDefault
+ capabilities:
+ drop:
+ - ALL
+ livenessProbe:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - exec pg_isready -U ${POSTGRES_USER} -h 127.0.0.1 -p 5432
+ failureThreshold: 6
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ name: postgresql
+ ports:
+ - containerPort: 5432
+ name: tcp-postgresql
+ protocol: TCP
+ readinessProbe:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - -e
+ - |
+ exec pg_isready -U ${POSTGRES_USER} -h 127.0.0.1 -p 5432
+ failureThreshold: 6
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ resources:
+ requests:
+ cpu: 250m
+ memory: 256Mi
+ limits:
+ cpu: 250m
+ memory: 1024Mi
+ ephemeral-storage: 20Mi
+ volumeMounts:
+ - mountPath: /dev/shm
+ name: dshm
+ - mountPath: /var/lib/pgsql/data
+ name: data
+ restartPolicy: Always
+ serviceAccountName: default
+ volumes:
+ - emptyDir:
+ medium: Memory
+ name: dshm
+ updateStrategy:
+ rollingUpdate:
+ partition: 0
+ type: RollingUpdate
+ volumeClaimTemplates:
+ - apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: data
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ db-statefulset.yaml.k8s: |-
+ # if securityContext not present in AKS/EKS, the error is like this:
+ # Error: EACCES: permission denied, open '/dynamic-plugins-root/backstage-plugin-scaffolder-backend-module-github-dynamic-0.2.2.tgz'
+ # fsGroup doesn not work for Openshift
+ spec:
+ template:
+ spec:
+ securityContext:
+ # any group id
+ fsGroup: 1001
+ deployment.yaml: |
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: backstage # placeholder for 'backstage-'
+ spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ rhdh.redhat.com/app: # placeholder for 'backstage-'
+ template:
+ metadata:
+ labels:
+ rhdh.redhat.com/app: # placeholder for 'backstage-'
+ spec:
+ automountServiceAccountToken: false
+ # if securityContext not present in AKS/EKS, the error is like this:
+ #Error: EACCES: permission denied, open '/dynamic-plugins-root/backstage-plugin-scaffolder-backend-module-github-dynamic-0.2.2.tgz'
+ # fsGroup doesn not work for Openshift
+ #securityContext:
+ # fsGroup: 1001
+ volumes:
+ - ephemeral:
+ volumeClaimTemplate:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 2Gi
+ name: dynamic-plugins-root
+ - name: dynamic-plugins-npmrc
+ secret:
+ defaultMode: 420
+ optional: true
+ secretName: dynamic-plugins-npmrc
+ - name: dynamic-plugins-registry-auth
+ secret:
+ defaultMode: 416
+ optional: true
+ secretName: dynamic-plugins-registry-auth
+ - emptyDir: {}
+ name: npmcacache
+ - name: temp
+ emptyDir: {}
+ initContainers:
+ - name: install-dynamic-plugins
+ command:
+ - ./install-dynamic-plugins.sh
+ - /dynamic-plugins-root
+ # image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
+ image: quay.io/rhdh/rhdh-hub-rhel9:next
+ imagePullPolicy: IfNotPresent
+ securityContext:
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ allowPrivilegeEscalation: false
+ seccompProfile:
+ type: RuntimeDefault
+ capabilities:
+ drop:
+ - ALL
+ env:
+ - name: NPM_CONFIG_USERCONFIG
+ value: /opt/app-root/src/.npmrc.dynamic-plugins
+ volumeMounts:
+ - mountPath: /dynamic-plugins-root
+ name: dynamic-plugins-root
+ - mountPath: /opt/app-root/src/.npmrc.dynamic-plugins
+ name: dynamic-plugins-npmrc
+ readOnly: true
+ subPath: .npmrc
+ - mountPath: /opt/app-root/src/.config/containers
+ name: dynamic-plugins-registry-auth
+ readOnly: true
+ - mountPath: /opt/app-root/src/.npm/_cacache
+ name: npmcacache
+ - mountPath: /tmp
+ name: temp
+ workingDir: /opt/app-root/src
+ resources:
+ requests:
+ cpu: 250m
+ memory: 256Mi
+ limits:
+ cpu: 1000m
+ memory: 2.5Gi
+ ephemeral-storage: 5Gi
+ containers:
+ - name: backstage-backend
+ # image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
+ image: quay.io/rhdh/rhdh-hub-rhel9:next
+ imagePullPolicy: IfNotPresent
+ args:
+ - "--config"
+ - "dynamic-plugins-root/app-config.dynamic-plugins.yaml"
+ securityContext:
+ capabilities:
+ drop:
+ - ALL
+ seccompProfile:
+ type: RuntimeDefault
+ runAsNonRoot: true
+ allowPrivilegeEscalation: false
+ startupProbe:
+ # This gives enough time upon container startup before the liveness and readiness probes are triggered.
+ # Giving (120s = initialDelaySeconds + failureThreshold * periodSeconds) to account for the worst case scenario.
+ httpGet:
+ path: /.backstage/health/v1/liveness
+ port: backend
+ scheme: HTTP
+ initialDelaySeconds: 30
+ timeoutSeconds: 4
+ periodSeconds: 20
+ successThreshold: 1
+ failureThreshold: 3
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /.backstage/health/v1/readiness
+ port: backend
+ scheme: HTTP
+ # Both liveness and readiness probes won't be triggered until the startup probe is successful.
+ # The startup probe is already configured to give enough time for the application to be started.
+ # So removing the additional delay here allows the readiness probe to be checked right away after the startup probe,
+ # which helps make the application available faster to the end-user.
+ #initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 2
+ timeoutSeconds: 4
+ livenessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /.backstage/health/v1/liveness
+ port: backend
+ scheme: HTTP
+ # Both liveness and readiness probes won't be triggered until the startup probe is successful.
+ # The startup probe is already configured to give enough time for the application to be started.
+ # So removing the additional delay here allows the readiness probe to be checked right away after the startup probe,
+ # which helps make the application available faster to the end-user.
+ #initialDelaySeconds: 60
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 4
+ ports:
+ - name: backend
+ containerPort: 7007
+ env:
+ - name: APP_CONFIG_backend_listen_port
+ value: "7007"
+ volumeMounts:
+ - mountPath: /opt/app-root/src/dynamic-plugins-root
+ name: dynamic-plugins-root
+ - mountPath: /tmp
+ name: temp
+ resources:
+ requests:
+ cpu: 250m
+ memory: 256Mi
+ limits:
+ cpu: 1000m
+ memory: 2.5Gi
+ ephemeral-storage: 5Gi
+ workingDir: /opt/app-root/src
+ deployment.yaml.k8s: |-
+ # if securityContext not present in AKS/EKS, the error is like this:
+ # Error: EACCES: permission denied, open '/dynamic-plugins-root/backstage-plugin-scaffolder-backend-module-github-dynamic-0.2.2.tgz'
+ # fsGroup doesn not work for Openshift
+ spec:
+ template:
+ spec:
+ securityContext:
+ # any group id
+ fsGroup: 1001
+ dynamic-plugins.yaml: |-
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: default-dynamic-plugins # must be the same as (deployment.yaml).spec.template.spec.volumes.name.dynamic-plugins-conf.configMap.name
+ data:
+ "dynamic-plugins.yaml": |
+ includes:
+ - dynamic-plugins.default.yaml
+ plugins: []
+ route.yaml: |-
+ apiVersion: route.openshift.io/v1
+ kind: Route
+ metadata:
+ name: route # placeholder for 'backstage-'
+ spec:
+ port:
+ targetPort: http-backend
+ path: /
+ tls:
+ insecureEdgeTerminationPolicy: Redirect
+ termination: edge
+ to:
+ kind: Service
+ name: # placeholder for 'backstage-'
+ secret-envs.yaml: |
+ apiVersion: v1
+ kind: Secret
+ metadata:
+ name: backend-auth-secret
+ stringData:
+ # generated with the command below (from https://janus-idp.io/docs/auth/service-to-service-auth/#setup):
+ # node -p 'require("crypto").randomBytes(24).toString("base64")'
+ BACKEND_SECRET: "R2FxRVNrcmwzYzhhN3l0V1VRcnQ3L1pLT09WaVhDNUEK" # notsecret
+ service.yaml: |-
+ apiVersion: v1
+ kind: Service
+ metadata:
+ name: backstage # placeholder for 'backstage-'
+ spec:
+ type: ClusterIP
+ selector:
+ rhdh.redhat.com/app: # placeholder for 'backstage-'
+ ports:
+ - name: http-backend
+ port: 80
+ targetPort: backend
+ - name: http-metrics
+ protocol: TCP
+ port: 9464
+ targetPort: 9464
+ service.yaml.k8s: |
+ spec:
+ type: NodePort
+kind: ConfigMap
+metadata:
+ name: rhdh-default-config
+ namespace: rhdh-operator
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app.kubernetes.io/component: metrics
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: controller-manager-metrics-service
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: service
+ app.kubernetes.io/part-of: backstage-operator
+ control-plane: controller-manager
+ name: rhdh-controller-manager-metrics-service
+ namespace: rhdh-operator
+spec:
+ ports:
+ - name: metrics
+ port: 8443
+ protocol: TCP
+ targetPort: metrics
+ selector:
+ control-plane: controller-manager
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ app: rhdh-operator
+ control-plane: controller-manager
+ name: rhdh-operator
+ namespace: rhdh-operator
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: rhdh-operator
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ kubectl.kubernetes.io/default-container: manager
+ labels:
+ app: rhdh-operator
+ app.kubernetes.io/component: rhdh-operator
+ control-plane: controller-manager
+ spec:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: kubernetes.io/arch
+ operator: In
+ values:
+ - amd64
+ - key: kubernetes.io/os
+ operator: In
+ values:
+ - linux
+ automountServiceAccountToken: true
+ containers:
+ - args:
+ - --health-probe-bind-address=:8081
+ - --metrics-bind-address=:8443
+ - --metrics-secure=true
+ - --leader-elect
+ command:
+ - /manager
+ env:
+ - name: OPERATOR_NAME
+ value: rhdh-operator
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: RELATED_IMAGE_postgresql
+ value: quay.io/fedora/postgresql-15:latest
+ - name: RELATED_IMAGE_backstage
+ value: quay.io/rhdh/rhdh-hub-rhel9:next
+ image: quay.io/rhdh/rhdh-rhel9-operator:1.6
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: health
+ initialDelaySeconds: 15
+ periodSeconds: 20
+ name: manager
+ ports:
+ - containerPort: 8081
+ name: health
+ - containerPort: 8443
+ name: metrics
+ readinessProbe:
+ httpGet:
+ path: /readyz
+ port: health
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ resources:
+ limits:
+ cpu: 500m
+ ephemeral-storage: 20Mi
+ memory: 1Gi
+ requests:
+ cpu: 10m
+ memory: 128Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ volumeMounts:
+ - mountPath: /default-config
+ name: default-config
+ securityContext:
+ runAsNonRoot: true
+ serviceAccountName: rhdh-controller-manager
+ terminationGracePeriodSeconds: 10
+ volumes:
+ - configMap:
+ name: rhdh-default-config
+ name: default-config
diff --git a/tests/e2e/testdata/rhdh-operator-1.3.yaml b/tests/e2e/testdata/rhdh-operator-1.3.yaml
index 6afb9ed9f..6ed1315cc 100644
--- a/tests/e2e/testdata/rhdh-operator-1.3.yaml
+++ b/tests/e2e/testdata/rhdh-operator-1.3.yaml
@@ -1478,7 +1478,7 @@ spec:
value: quay.io/fedora/postgresql-15:latest
- name: RELATED_IMAGE_backstage
value: quay.io/rhdh/rhdh-hub-rhel9:1.3
- image: quay.io/rhdh-community/operator:0.3.4
+ image: quay.io/rhdh-community/operator:0.3.6
livenessProbe:
httpGet:
path: /healthz
diff --git a/tests/e2e/testdata/rhdh-operator-1.4.yaml b/tests/e2e/testdata/rhdh-operator-1.4.yaml
index 67d567d76..4ba75ef2c 100644
--- a/tests/e2e/testdata/rhdh-operator-1.4.yaml
+++ b/tests/e2e/testdata/rhdh-operator-1.4.yaml
@@ -1952,7 +1952,7 @@ spec:
value: quay.io/fedora/postgresql-15:latest
- name: RELATED_IMAGE_backstage
value: quay.io/rhdh/rhdh-hub-rhel9:1.4
- image: quay.io/rhdh-community/operator:0.4.1
+ image: quay.io/rhdh-community/operator:0.4.2
livenessProbe:
httpGet:
path: /healthz
diff --git a/tests/e2e/testdata/rhdh-operator-1.5.yaml b/tests/e2e/testdata/rhdh-operator-1.5.yaml
new file mode 100644
index 000000000..2c4e268e0
--- /dev/null
+++ b/tests/e2e/testdata/rhdh-operator-1.5.yaml
@@ -0,0 +1,2025 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ labels:
+ app.kubernetes.io/component: manager
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: system
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: namespace
+ app.kubernetes.io/part-of: backstage-operator
+ control-plane: controller-manager
+ name: rhdh-operator
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.14.0
+ name: backstages.rhdh.redhat.com
+spec:
+ group: rhdh.redhat.com
+ names:
+ kind: Backstage
+ listKind: BackstageList
+ plural: backstages
+ singular: backstage
+ scope: Namespaced
+ versions:
+ - deprecated: true
+ deprecationWarning: Since 1.3.0 spec.application.image, spec.application.replicas,
+ spec.application.imagePullSecrets are deprecated in favor of corresponding spec.deployment
+ fields
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: false
+ subresources:
+ status: {}
+ - name: v1alpha2
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ deployment:
+ description: |-
+ Configuration for Backstage Deployment resource.
+ Optional.
+ properties:
+ patch:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: false
+ subresources:
+ status: {}
+ - name: v1alpha3
+ schema:
+ openAPIV3Schema:
+ description: |-
+ Backstage is the Schema for the Red Hat Developer Hub backstages API.
+ It comes with pre-built plug-ins, configuration settings, and deployment mechanisms,
+ which can help streamline the process of setting up a self-managed internal
+ developer portal for adopters who are just starting out.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BackstageSpec defines the desired state of Backstage
+ properties:
+ application:
+ description: Configuration for Backstage. Optional.
+ properties:
+ appConfig:
+ description: |-
+ References to existing app-configs ConfigMap objects, that will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret,
+ and will be mounted inside the main application container under a specified mount directory.
+ Additionally, each file will be passed as a `--config /mount/path/to/configmap/key` to the
+ main container args in the order of the entries defined in the AppConfigs list.
+ But bear in mind that for a single ConfigMap element containing several filenames,
+ the order in which those files will be appended to the main container args cannot be guaranteed.
+ So if you want to pass multiple app-config files, it is recommended to pass one ConfigMap per app-config file.
+ properties:
+ configMaps:
+ description: |-
+ List of ConfigMaps storing the app-config files. Will be mounted as files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ Bear in mind not to put sensitive data in those ConfigMaps. Instead, your app-config content can reference
+ environment variables (which you can set with the ExtraEnvs field) and/or include extra files (see the ExtraFiles field).
+ More details on https://backstage.io/docs/conf/writing/.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all app-config files listed in
+ the ConfigMapRefs field
+ type: string
+ type: object
+ dynamicPluginsConfigMapName:
+ description: |-
+ Reference to an existing ConfigMap for Dynamic Plugins.
+ A new one will be generated with the default config if not set.
+ The ConfigMap object must have an existing key named: 'dynamic-plugins.yaml'.
+ type: string
+ extraEnvs:
+ description: Extra environment variables
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as an additional environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ envs:
+ description: List of name and value pairs to add as environment
+ variables.
+ items:
+ properties:
+ name:
+ description: Name of the environment variable
+ type: string
+ value:
+ description: Value of the environment variable
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects to inject as additional environment variables.
+ For each item in this array, if a key is not specified, it means that all keys in the Secret will be injected as additional environment variables.
+ Otherwise, only the specified key will be injected as environment variable.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ name:
+ description: |-
+ Name of the object
+ We support only ConfigMaps and Secrets.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ extraFiles:
+ description: |-
+ References to existing Config objects to use as extra config files.
+ They will be mounted as files in the specified mount path.
+ Each element can be a reference to any ConfigMap or Secret.
+ properties:
+ configMaps:
+ description: |-
+ List of references to ConfigMaps objects mounted as extra files under the MountPath specified.
+ For each item in this array, if a key is not specified, it means that all keys in the ConfigMap will be mounted as files.
+ Otherwise, only the specified key will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ mountPath:
+ default: /opt/app-root/src
+ description: Mount path for all extra configuration files
+ listed in the Items field
+ type: string
+ pvcs:
+ description: |-
+ List of references to Persistent Volume Claim objects mounted as extra files
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ mountPath:
+ description: Path to mount PVC. If not specified default-path/Name
+ will be used
+ type: string
+ name:
+ description: Name of the object
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ secrets:
+ description: |-
+ List of references to Secrets objects mounted as extra files under the MountPath specified.
+ For each item in this array, a key must be specified that will be mounted as a file.
+ items:
+ properties:
+ key:
+ description: Key in the object
+ type: string
+ mountPath:
+ description: Path to mount the Object. If not specified
+ default-path/Name will be used
+ type: string
+ name:
+ description: |-
+ Name of the object
+ Supported ConfigMaps and Secrets
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ image:
+ description: |-
+ Custom image to use in all containers (including Init Containers).
+ It is your responsibility to make sure the image is from trusted sources and has been validated for security compliance
+ type: string
+ imagePullSecrets:
+ description: Image Pull Secrets to use in all containers (including
+ Init Containers)
+ items:
+ type: string
+ type: array
+ replicas:
+ default: 1
+ description: |-
+ Number of desired replicas to set in the Backstage Deployment.
+ Defaults to 1.
+ format: int32
+ type: integer
+ route:
+ description: Route configuration. Used for OpenShift only.
+ properties:
+ enabled:
+ default: true
+ description: Control the creation of a Route on OpenShift.
+ type: boolean
+ host:
+ description: |-
+ Host is an alias/DNS that points to the service. Optional.
+ Ignored if Enabled is false.
+ If not specified a route name will typically be automatically
+ chosen. Must follow DNS952 subdomain conventions.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ subdomain:
+ description: |-
+ Subdomain is a DNS subdomain that is requested within the ingress controller's
+ domain (as a subdomain).
+ Ignored if Enabled is false.
+ Example: subdomain `frontend` automatically receives the router subdomain
+ `apps.mycluster.com` to have a full hostname `frontend.apps.mycluster.com`.
+ maxLength: 253
+ pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
+ type: string
+ tls:
+ description: |-
+ The tls field provides the ability to configure certificates for the route.
+ Ignored if Enabled is false.
+ properties:
+ caCertificate:
+ description: caCertificate provides the cert authority
+ certificate contents
+ type: string
+ certificate:
+ description: |-
+ certificate provides certificate contents. This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate.
+ type: string
+ externalCertificateSecretName:
+ description: |-
+ ExternalCertificateSecretName provides certificate contents as a secret reference.
+ This should be a single serving certificate, not a certificate
+ chain. Do not include a CA certificate. The secret referenced should
+ be present in the same namespace as that of the Route.
+ Forbidden when `certificate` is set.
+ Note that securing Routes with external certificates in TLS secrets is a Technology Preview feature in OpenShift,
+ and requires enabling the `RouteExternalCertificate` OpenShift Feature Gate and might not be functionally complete.
+ type: string
+ key:
+ description: key provides key file contents
+ type: string
+ type: object
+ type: object
+ type: object
+ database:
+ description: Configuration for database access. Optional.
+ properties:
+ authSecretName:
+ description: |-
+ Name of the secret for database authentication. Optional.
+ For a local database deployment (EnableLocalDb=true), a secret will be auto generated if it does not exist.
+ The secret shall include information used for the database access.
+ An example for PostgreSQL DB access:
+ "POSTGRES_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_PORT": "5432"
+ "POSTGRES_USER": "postgres"
+ "POSTGRESQL_ADMIN_PASSWORD": "rl4s3Fh4ng3M4"
+ "POSTGRES_HOST": "backstage-psql-bs1" # For local database, set to "backstage-psql-".
+ type: string
+ enableLocalDb:
+ default: true
+ description: Control the creation of a local PostgreSQL DB. Set
+ to false if using for example an external Database for Backstage.
+ type: boolean
+ type: object
+ deployment:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ properties:
+ patch:
+ description: |-
+ Valid fragment of Deployment to be merged with default/raw configuration.
+ Set the Deployment's metadata and|or spec fields you want to override or add.
+ Optional.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ rawRuntimeConfig:
+ description: Raw Runtime RuntimeObjects configuration. For Advanced
+ scenarios.
+ properties:
+ backstageConfig:
+ description: Name of ConfigMap containing Backstage runtime objects
+ configuration
+ type: string
+ localDbConfig:
+ description: Name of ConfigMap containing LocalDb (PostgreSQL)
+ runtime objects configuration
+ type: string
+ type: object
+ type: object
+ status:
+ description: BackstageStatus defines the observed state of Backstage
+ properties:
+ conditions:
+ description: Conditions is the list of conditions describing the state
+ of the runtime
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: controller-manager
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: serviceaccount
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-controller-manager
+ namespace: rhdh-operator
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: leader-election-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: role
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-leader-election-role
+ namespace: rhdh-operator
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - coordination.k8s.io
+ resources:
+ - leases
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - patch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: backstage-editor-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-backstage-editor-role
+rules:
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: backstage-viewer-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-backstage-viewer-role
+rules:
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: rhdh-manager-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ - persistentvolumeclaims
+ - secrets
+ - services
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - ""
+ resources:
+ - persistentvolumes
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apps
+ resources:
+ - deployments
+ - statefulsets
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - rhdh.redhat.com
+ resources:
+ - backstages/status
+ verbs:
+ - get
+ - patch
+ - update
+- apiGroups:
+ - route.openshift.io
+ resources:
+ - routes
+ - routes/custom-host
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-auth-role
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: metrics-auth-role
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-metrics-auth-role
+rules:
+- apiGroups:
+ - authentication.k8s.io
+ resources:
+ - tokenreviews
+ verbs:
+ - create
+- apiGroups:
+ - authorization.k8s.io
+ resources:
+ - subjectaccessreviews
+ verbs:
+ - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: metrics-rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-reader
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-metrics-reader
+rules:
+- nonResourceURLs:
+ - /metrics
+ verbs:
+ - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: leader-election-rolebinding
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: rolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-leader-election-rolebinding
+ namespace: rhdh-operator
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: rhdh-leader-election-role
+subjects:
+- kind: ServiceAccount
+ name: rhdh-controller-manager
+ namespace: rhdh-operator
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: manager-rolebinding
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: clusterrolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-manager-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: rhdh-manager-role
+subjects:
+- kind: ServiceAccount
+ name: rhdh-controller-manager
+ namespace: rhdh-operator
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: metrics-auth-rolebinding
+ app.kubernetes.io/name: metrics-auth-rolebinding
+ app.kubernetes.io/part-of: backstage-operator
+ name: rhdh-metrics-auth-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: rhdh-metrics-auth-role
+subjects:
+- kind: ServiceAccount
+ name: rhdh-controller-manager
+ namespace: rhdh-operator
+---
+apiVersion: v1
+data:
+ app-config.yaml: |
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: my-backstage-config-cm1 # placeholder for -default-appconfig
+ data:
+ default.app-config.yaml: |
+ backend:
+ auth:
+ externalAccess:
+ - type: legacy
+ options:
+ subject: legacy-default-config
+ # This is a default value, which you should change by providing your own app-config
+ secret: "pl4s3Ch4ng3M3"
+ auth:
+ providers: {}
+ db-secret.yaml: |-
+ apiVersion: v1
+ kind: Secret
+ metadata:
+ name: postgres-secrets # will be replaced
+ type: Opaque
+ #stringData:
+ # POSTGRES_PASSWORD:
+ # POSTGRES_PORT: "5432"
+ # POSTGRES_USER: postgres
+ # POSTGRESQL_ADMIN_PASSWORD: admin123
+ # POSTGRES_HOST: bs1-db-service #placeholder -db-service
+ db-service.yaml: |
+ apiVersion: v1
+ kind: Service
+ metadata:
+ name: backstage-psql # placeholder for 'backstage-psql-' .NOTE: For the time it is static and linked to Secret-> postgres-secrets -> OSTGRES_HOST
+ spec:
+ selector:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ clusterIP: None
+ ports:
+ - port: 5432
+ db-statefulset.yaml: |-
+ apiVersion: apps/v1
+ kind: StatefulSet
+ metadata:
+ name: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ spec:
+ podManagementPolicy: OrderedReady
+ replicas: 1
+ selector:
+ matchLabels:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ serviceName: backstage-psql-cr1-hl # placeholder for 'backstage-psql--hl'
+ template:
+ metadata:
+ labels:
+ rhdh.redhat.com/app: backstage-psql-cr1 # placeholder for 'backstage-psql-'
+ spec:
+ # fsGroup does not work for Openshift
+ # AKS/EKS does not work w/o it
+ #securityContext:
+ # fsGroup: 26
+ automountServiceAccountToken: false
+ ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
+ ## The optional .spec.persistentVolumeClaimRetentionPolicy field controls if and how PVCs are deleted during the lifecycle of a StatefulSet.
+ ## You must enable the StatefulSetAutoDeletePVC feature gate on the API server and the controller manager to use this field.
+ # persistentVolumeClaimRetentionPolicy:
+ # whenDeleted: Retain
+ # whenScaled: Retain
+ containers:
+ - env:
+ - name: POSTGRESQL_PORT_NUMBER
+ value: "5432"
+ - name: POSTGRESQL_VOLUME_DIR
+ value: /var/lib/pgsql/data
+ - name: PGDATA
+ value: /var/lib/pgsql/data/userdata
+ image: quay.io/fedora/postgresql-15:latest # will be replaced with the actual image
+ imagePullPolicy: IfNotPresent
+ securityContext:
+ # runAsUser:26 does not work for Openshift but looks work for AKS/EKS
+ # runAsUser: 26
+ runAsGroup: 0
+ runAsNonRoot: true
+ allowPrivilegeEscalation: false
+ seccompProfile:
+ type: RuntimeDefault
+ capabilities:
+ drop:
+ - ALL
+ livenessProbe:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - exec pg_isready -U ${POSTGRES_USER} -h 127.0.0.1 -p 5432
+ failureThreshold: 6
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ name: postgresql
+ ports:
+ - containerPort: 5432
+ name: tcp-postgresql
+ protocol: TCP
+ readinessProbe:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - -e
+ - |
+ exec pg_isready -U ${POSTGRES_USER} -h 127.0.0.1 -p 5432
+ failureThreshold: 6
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ resources:
+ requests:
+ cpu: 250m
+ memory: 256Mi
+ limits:
+ cpu: 250m
+ memory: 1024Mi
+ ephemeral-storage: 20Mi
+ volumeMounts:
+ - mountPath: /dev/shm
+ name: dshm
+ - mountPath: /var/lib/pgsql/data
+ name: data
+ restartPolicy: Always
+ serviceAccountName: default
+ volumes:
+ - emptyDir:
+ medium: Memory
+ name: dshm
+ updateStrategy:
+ rollingUpdate:
+ partition: 0
+ type: RollingUpdate
+ volumeClaimTemplates:
+ - apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: data
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ db-statefulset.yaml.k8s: |-
+ # if securityContext not present in AKS/EKS, the error is like this:
+ # Error: EACCES: permission denied, open '/dynamic-plugins-root/backstage-plugin-scaffolder-backend-module-github-dynamic-0.2.2.tgz'
+ # fsGroup doesn not work for Openshift
+ spec:
+ template:
+ spec:
+ securityContext:
+ # any group id
+ fsGroup: 1001
+ deployment.yaml: |
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: backstage # placeholder for 'backstage-'
+ spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ rhdh.redhat.com/app: # placeholder for 'backstage-'
+ template:
+ metadata:
+ labels:
+ rhdh.redhat.com/app: # placeholder for 'backstage-'
+ spec:
+ automountServiceAccountToken: false
+ # if securityContext not present in AKS/EKS, the error is like this:
+ #Error: EACCES: permission denied, open '/dynamic-plugins-root/backstage-plugin-scaffolder-backend-module-github-dynamic-0.2.2.tgz'
+ # fsGroup doesn not work for Openshift
+ #securityContext:
+ # fsGroup: 1001
+ volumes:
+ - ephemeral:
+ volumeClaimTemplate:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 2Gi
+ name: dynamic-plugins-root
+ - name: dynamic-plugins-npmrc
+ secret:
+ defaultMode: 420
+ optional: true
+ secretName: dynamic-plugins-npmrc
+ - name: dynamic-plugins-registry-auth
+ secret:
+ defaultMode: 416
+ optional: true
+ secretName: dynamic-plugins-registry-auth
+ - emptyDir: {}
+ name: npmcacache
+ - name: temp
+ emptyDir: {}
+ initContainers:
+ - name: install-dynamic-plugins
+ command:
+ - ./install-dynamic-plugins.sh
+ - /dynamic-plugins-root
+ # image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
+ image: quay.io/rhdh/rhdh-hub-rhel9:next
+ imagePullPolicy: IfNotPresent
+ securityContext:
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ allowPrivilegeEscalation: false
+ seccompProfile:
+ type: RuntimeDefault
+ capabilities:
+ drop:
+ - ALL
+ env:
+ - name: NPM_CONFIG_USERCONFIG
+ value: /opt/app-root/src/.npmrc.dynamic-plugins
+ volumeMounts:
+ - mountPath: /dynamic-plugins-root
+ name: dynamic-plugins-root
+ - mountPath: /opt/app-root/src/.npmrc.dynamic-plugins
+ name: dynamic-plugins-npmrc
+ readOnly: true
+ subPath: .npmrc
+ - mountPath: /opt/app-root/src/.config/containers
+ name: dynamic-plugins-registry-auth
+ readOnly: true
+ - mountPath: /opt/app-root/src/.npm/_cacache
+ name: npmcacache
+ - mountPath: /tmp
+ name: temp
+ workingDir: /opt/app-root/src
+ resources:
+ requests:
+ cpu: 250m
+ memory: 256Mi
+ limits:
+ cpu: 1000m
+ memory: 2.5Gi
+ ephemeral-storage: 5Gi
+ containers:
+ - name: backstage-backend
+ # image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
+ image: quay.io/rhdh/rhdh-hub-rhel9:next
+ imagePullPolicy: IfNotPresent
+ args:
+ - "--config"
+ - "dynamic-plugins-root/app-config.dynamic-plugins.yaml"
+ securityContext:
+ capabilities:
+ drop:
+ - ALL
+ seccompProfile:
+ type: RuntimeDefault
+ runAsNonRoot: true
+ allowPrivilegeEscalation: false
+ startupProbe:
+ # This gives enough time upon container startup before the liveness and readiness probes are triggered.
+ # Giving (120s = initialDelaySeconds + failureThreshold * periodSeconds) to account for the worst case scenario.
+ httpGet:
+ path: /.backstage/health/v1/liveness
+ port: backend
+ scheme: HTTP
+ initialDelaySeconds: 30
+ timeoutSeconds: 4
+ periodSeconds: 20
+ successThreshold: 1
+ failureThreshold: 3
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /.backstage/health/v1/readiness
+ port: backend
+ scheme: HTTP
+ # Both liveness and readiness probes won't be triggered until the startup probe is successful.
+ # The startup probe is already configured to give enough time for the application to be started.
+ # So removing the additional delay here allows the readiness probe to be checked right away after the startup probe,
+ # which helps make the application available faster to the end-user.
+ #initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 2
+ timeoutSeconds: 4
+ livenessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /.backstage/health/v1/liveness
+ port: backend
+ scheme: HTTP
+ # Both liveness and readiness probes won't be triggered until the startup probe is successful.
+ # The startup probe is already configured to give enough time for the application to be started.
+ # So removing the additional delay here allows the readiness probe to be checked right away after the startup probe,
+ # which helps make the application available faster to the end-user.
+ #initialDelaySeconds: 60
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 4
+ ports:
+ - name: backend
+ containerPort: 7007
+ env:
+ - name: APP_CONFIG_backend_listen_port
+ value: "7007"
+ volumeMounts:
+ - mountPath: /opt/app-root/src/dynamic-plugins-root
+ name: dynamic-plugins-root
+ - mountPath: /tmp
+ name: temp
+ resources:
+ requests:
+ cpu: 250m
+ memory: 256Mi
+ limits:
+ cpu: 1000m
+ memory: 2.5Gi
+ ephemeral-storage: 5Gi
+ workingDir: /opt/app-root/src
+ deployment.yaml.k8s: |-
+ # if securityContext not present in AKS/EKS, the error is like this:
+ # Error: EACCES: permission denied, open '/dynamic-plugins-root/backstage-plugin-scaffolder-backend-module-github-dynamic-0.2.2.tgz'
+ # fsGroup doesn not work for Openshift
+ spec:
+ template:
+ spec:
+ securityContext:
+ # any group id
+ fsGroup: 1001
+ dynamic-plugins.yaml: |-
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: default-dynamic-plugins # must be the same as (deployment.yaml).spec.template.spec.volumes.name.dynamic-plugins-conf.configMap.name
+ data:
+ "dynamic-plugins.yaml": |
+ includes:
+ - dynamic-plugins.default.yaml
+ plugins: []
+ route.yaml: |-
+ apiVersion: route.openshift.io/v1
+ kind: Route
+ metadata:
+ name: route # placeholder for 'backstage-'
+ spec:
+ port:
+ targetPort: http-backend
+ path: /
+ tls:
+ insecureEdgeTerminationPolicy: Redirect
+ termination: edge
+ to:
+ kind: Service
+ name: # placeholder for 'backstage-'
+ secret-envs.yaml: |
+ apiVersion: v1
+ kind: Secret
+ metadata:
+ name: backend-auth-secret
+ stringData:
+ # generated with the command below (from https://janus-idp.io/docs/auth/service-to-service-auth/#setup):
+ # node -p 'require("crypto").randomBytes(24).toString("base64")'
+ BACKEND_SECRET: "R2FxRVNrcmwzYzhhN3l0V1VRcnQ3L1pLT09WaVhDNUEK" # notsecret
+ service.yaml: |-
+ apiVersion: v1
+ kind: Service
+ metadata:
+ name: backstage # placeholder for 'backstage-'
+ spec:
+ type: ClusterIP
+ selector:
+ rhdh.redhat.com/app: # placeholder for 'backstage-'
+ ports:
+ - name: http-backend
+ port: 80
+ targetPort: backend
+ - name: http-metrics
+ protocol: TCP
+ port: 9464
+ targetPort: 9464
+ service.yaml.k8s: |
+ spec:
+ type: NodePort
+kind: ConfigMap
+metadata:
+ name: rhdh-default-config
+ namespace: rhdh-operator
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app.kubernetes.io/component: metrics
+ app.kubernetes.io/created-by: backstage-operator
+ app.kubernetes.io/instance: controller-manager-metrics-service
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/name: service
+ app.kubernetes.io/part-of: backstage-operator
+ control-plane: controller-manager
+ name: rhdh-controller-manager-metrics-service
+ namespace: rhdh-operator
+spec:
+ ports:
+ - name: metrics
+ port: 8443
+ protocol: TCP
+ targetPort: metrics
+ selector:
+ control-plane: controller-manager
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ app: rhdh-operator
+ control-plane: controller-manager
+ name: rhdh-operator
+ namespace: rhdh-operator
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: rhdh-operator
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ kubectl.kubernetes.io/default-container: manager
+ labels:
+ app: rhdh-operator
+ app.kubernetes.io/component: rhdh-operator
+ control-plane: controller-manager
+ spec:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: kubernetes.io/arch
+ operator: In
+ values:
+ - amd64
+ - key: kubernetes.io/os
+ operator: In
+ values:
+ - linux
+ automountServiceAccountToken: true
+ containers:
+ - args:
+ - --health-probe-bind-address=:8081
+ - --metrics-bind-address=:8443
+ - --metrics-secure=true
+ - --leader-elect
+ command:
+ - /manager
+ env:
+ - name: OPERATOR_NAME
+ value: rhdh-operator
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: RELATED_IMAGE_postgresql
+ value: quay.io/fedora/postgresql-15:latest
+ - name: RELATED_IMAGE_backstage
+ value: quay.io/rhdh/rhdh-hub-rhel9:1.5
+ image: quay.io/rhdh-community/operator:0.5.0
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: health
+ initialDelaySeconds: 15
+ periodSeconds: 20
+ name: manager
+ ports:
+ - containerPort: 8081
+ name: health
+ - containerPort: 8443
+ name: metrics
+ readinessProbe:
+ httpGet:
+ path: /readyz
+ port: health
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ resources:
+ limits:
+ cpu: 500m
+ ephemeral-storage: 20Mi
+ memory: 1Gi
+ requests:
+ cpu: 10m
+ memory: 128Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ volumeMounts:
+ - mountPath: /default-config
+ name: default-config
+ securityContext:
+ runAsNonRoot: true
+ serviceAccountName: rhdh-controller-manager
+ terminationGracePeriodSeconds: 10
+ volumes:
+ - configMap:
+ name: rhdh-default-config
+ name: default-config