Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Default secrets #609

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 62 additions & 27 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ The Default Configuration defines the structure of all Backstage instances withi

### Default Configuration Files

| Key/File Name | Object Kind | Object Name | Mandatory | Multi| Version | Notes |
|----------------------|------------------------------|--------------------------------------------|--------------|-----|---------|-------------------------------------------------|
| deployment.yaml | appsv1.Deployment | backstage-<cr-name> | Yes | No | >=0.1.x | Backstage deployment |
| service.yaml | corev1.Service | backstage-<cr-name> | Yes | No | >=0.1.x | Backstage Service |
| db-statefulset.yaml | appsv1.StatefulSet | backstage-psql-<cr-name> | For local DB | No | >=0.1.x | PostgreSQL StatefulSet |
| db-service.yaml | corev1.Service | backstage-psql-<cr-name> | For local DB | No | >=0.1.x | PostgreSQL Service |
| db-secret.yaml | corev1.Secret | backstage-psql-secret-<cr-name> | For local DB | No | >=0.1.x | Secret to connect Backstage to PGSQL |
| route.yaml | openshift.Route | backstage-<cr-name> | No (for OCP) | No | >=0.1.x | Route exposing Backstage service |
| app-config.yaml | corev1.ConfigMap | backstage-appconfig-<cr-name> | No | No | >=0.2.x | Backstage app-config.yaml |
| configmap-files.yaml | corev1.ConfigMap | backstage-files-<cr-name> | No | No | >=0.2.x | Backstage config file inclusions from configMap |
| configmap-envs.yaml | corev1.ConfigMap | backstage-envs-<cr-name> | No | No | >=0.2.x | Backstage environment variables from ConfigMap |
| secret-files.yaml | corev1.Secret | backstage-files-<cr-name> | No | No | >=0.2.x | Backstage config file inclusions from Secret |
| secret-envs.yaml | corev1.Secret | backstage-envs-<cr-name> | No | No | >=0.2.x | Backstage environment variables from Secret |
| dynamic-plugins.yaml | corev1.ConfigMap | backstage-dynamic-plugins-<cr-name> | No | No | >=0.2.x | Dynamic plugins configuration |
| pvcs.yaml | corev1.PersistentVolumeClaim | backstage-&lt;cr-name&gt;-&lt;pvc-name&gt; | No | Yes | >=0.4.x | List of PVC objects to be mounted to containers |
| Key/File Name | Object Kind | Object Name | Mandatory | Multi | Version | Notes |
|----------------------|--------------------------------|--------------------------------------------|--------------|-------|---------|-------------------------------------------------|
| deployment.yaml | appsv1.Deployment | backstage-<cr-name> | Yes | No | >=0.1.x | Backstage deployment |
| service.yaml | corev1.Service | backstage-<cr-name> | Yes | No | >=0.1.x | Backstage Service |
| db-statefulset.yaml | appsv1.StatefulSet | backstage-psql-<cr-name> | For local DB | No | >=0.1.x | PostgreSQL StatefulSet |
| db-service.yaml | corev1.Service | backstage-psql-<cr-name> | For local DB | No | >=0.1.x | PostgreSQL Service |
| db-secret.yaml | corev1.Secret | backstage-psql-secret-<cr-name> | For local DB | No | >=0.1.x | Secret to connect Backstage to PGSQL |
| route.yaml | openshift.Route | backstage-<cr-name> | No (for OCP) | No | >=0.1.x | Route exposing Backstage service |
| app-config.yaml | corev1.ConfigMap | backstage-appconfig-<cr-name> | No | No | >=0.2.x | Backstage app-config.yaml |
| configmap-files.yaml | corev1.ConfigMap | backstage-files-<cr-name> | No | No | >=0.2.x | Backstage config file inclusions from configMap |
| configmap-envs.yaml | corev1.ConfigMap | backstage-envs-<cr-name> | No | No | >=0.2.x | Backstage environment variables from ConfigMap |
| secret-files.yaml | []corev1.Secret | backstage-files-<cr-name> | No | Yes | >=0.2.x | Backstage config file inclusions from Secret |
| secret-envs.yaml | []corev1.Secret | backstage-envs-<cr-name> | No | Yes | >=0.2.x | Backstage environment variables from Secret |
| dynamic-plugins.yaml | corev1.ConfigMap | backstage-dynamic-plugins-<cr-name> | No | No | >=0.2.x | Dynamic plugins configuration |
| pvcs.yaml | []corev1.PersistentVolumeClaim | backstage-&lt;cr-name&gt;-&lt;pvc-name&gt; | No | Yes | >=0.4.x | List of PVC objects to be mounted to containers |

**Meanings of "Mandatory" Column:**
- **Yes** - Must be configured; deployment will fail otherwise.
Expand All @@ -36,13 +36,22 @@ The Default Configuration defines the structure of all Backstage instances withi

You can see examples of default configurations as part of the [Operator Profiles](../config/profile) in the **default-config** directory.

#### Default mount path
### Default mount path

Some objects, such as: app-config, configmap-files, secret-files, dynamic-plugins, pvcs, are mounted to the Backstage Container as files or directories. Default mount path is Container's WorkingDir, if not defined it falls to "/opt/app-root/src".

#### Object annotation for mounting a PVC volume to a specific path
### Annotations

Use **rhdh.redhat.com/mount-path** annotation to configure mount path for **PersistentVolumeClaim** volume.
We use annotations to configure some objects. The following annotations are supported:

#### rhdh.redhat.com/mount-path to configure mount path.

If specified, the object will be mounted to the specified path, otherwise [Default mount path](#default-mount-path) will ve used.
It is possible to specify relative path, which will be appended to the default mount path.

Supported objects: **pvcs, secret-files**.

Examples:

_**pvcs.yaml**_
```yaml
Expand All @@ -57,16 +66,30 @@ metadata:

In the example above the PVC called **myclaim** will be mounted to **/mount/path/from/annotation** directory

#### Object annotation for mounting a PVC volume to specific container(s)
_**secret-files.yaml**_
```yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
annotations:
rhdh.redhat.com/mount-path: /mount/path/from/annotation
...
```
In the example above the Secret called **mysecret** will be mounted to **/mount/path/from/annotation** directory

#### rhdh.redhat.com/containers for mounting volume to specific container(s)
gazarenkov marked this conversation as resolved.
Show resolved Hide resolved

Use **rhdh.redhat.com/containers** annotation to configure containers where **PersistentVolumeClaim** volume will be mounted.
Supported objects: **pvcs, secret-files, secret-envs**.

Options:

* No or empty annotation means the volume will be mounted to the Backstage container only
* \* (asterisk) means the volume will be mounted to all the containers
* No or empty annotation: the volume will be mounted to the Backstage container only
* \* (asterisk): the volume will be mounted to all the containers
* Otherwise, container names separated by commas will be used

Examples:

_**pvcs.yaml**_
```yaml
apiVersion: v1
Expand All @@ -79,6 +102,18 @@ metadata:
```
In the example above the PVC called **myclaim** will be mounted to **init-dynamic-plugins** and **backstage-backend** containers

_**secret-envs.yaml**_

```yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
annotations:
rhdh.redhat.com/containers: "*"
...
```
In the example above the PVC called **myclaim** will be mounted to all the containers

### Metadata Generation

Expand Down Expand Up @@ -138,7 +173,7 @@ spec:
The desired state of resources created by the Backstage Operator is defined in the Backstage Custom Resource Spec. Here’s an example of a simple Backstage CR:

```yaml
apiVersion: rhdh.redhat.com/v1alpha2
apiVersion: rhdh.redhat.com/v1alpha3
kind: Backstage
metadata:
name: mybackstage
Expand All @@ -160,7 +195,7 @@ For API version **v1alpha2** (Operator version **0.3.x**), the Backstage CR Spec

* [application](#application-configuration)
* [deployment](#deployment-configuration)
* [database](#local-database-configuration)
* [database](#database-configuration)
* [rawRuntimeConfig](#raw-configuration)

### Application Configuration
Expand Down Expand Up @@ -209,7 +244,7 @@ The ConfigMap key/value defines the file name and content, and this app-config w
**Note**: It is possible to define several **app-config** files inside one ConfigMap (even if there are no visible reasons for it) but since it is a Map, the order of how they are applied is not guaranteed.
On the other hand, Backstage application merges the chain of **app-config** files from first to last, so order is important. Taking this into account, keeping several **app-config** files inside one ConfigMap is **NOT recommended**. For this case consider defining several one-entry ConfigMaps instead.

[Includes and Dynamic Data](https://backstage.io/docs/conf/writing/#includes-and-dynamic-data) (including [extra files](#extra-files) and [extra environment variables](#extra-env-variables)) support configuring additional ConfigMaps and Secrets.
[Includes and Dynamic Data](https://backstage.io/docs/conf/writing/#includes-and-dynamic-data) (including [extra files](#extra-files) and [extra environment variables](#extra-environment-variables)) support configuring additional ConfigMaps and Secrets.

#### Extra Files

Expand Down Expand Up @@ -417,7 +452,7 @@ MY_VAR = my-value

#### Dynamic Plugins

The Operator can configure [Dynamic Plugins](https://github.com/janus-idp/backstage-showcase/blob/main/docs/dynamic-plugins.md). To support Dynamic Plugins, the Backstage deployment should contain a dedicated initContainer called **install-dynamic-plugins** (see [RHDH deployment.yaml](../config/manager/default-config/deployment.yaml)). To enable the Operator to configure Dynamic Plugins for a specific Backstage instance (CR), the user must create a ConfigMap with an entry called **dynamic-plugins.yaml**.
The Operator can configure [Dynamic Plugins](https://github.com/janus-idp/backstage-showcase/blob/main/docs/dynamic-plugins.md). To support Dynamic Plugins, the Backstage deployment should contain a dedicated initContainer called **install-dynamic-plugins** (see [RHDH deployment.yaml](../config/profile/rhdh/default-config/deployment.yaml)). To enable the Operator to configure Dynamic Plugins for a specific Backstage instance (CR), the user must create a ConfigMap with an entry called **dynamic-plugins.yaml**.

For example, the **dynamic-plugins-config** ConfigMap contains a simple Dynamic Plugins configuration, which includes predefined default plugins in **dynamic-plugins.default.yaml** and the GitHub plugin provided in the package located at `./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic`.

Expand Down Expand Up @@ -543,7 +578,7 @@ This is dictated by the following configuration:
```yaml
spec:
database:
enableLocalDb: [true]|false
enableLocalDb: [true] or false
```

If local DB is enabled (which is simpler but not recommended for production), the Operator will:
Expand Down
14 changes: 6 additions & 8 deletions pkg/model/appconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (

"golang.org/x/exp/maps"

appsv1 "k8s.io/api/apps/v1"

"sigs.k8s.io/controller-runtime/pkg/client"

"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -46,8 +44,8 @@ func addAppConfigsFromSpec(spec bsv1.BackstageSpec, model *BackstageModel) error

for _, specCm := range spec.Application.AppConfig.ConfigMaps {
mp, wSubpath := model.backstageDeployment.mountPath(specCm.MountPath, specCm.Key, spec.Application.AppConfig.MountPath)
updatePodWithAppConfig(model.backstageDeployment.deployment, model.backstageDeployment.container(), specCm.Name,
mp, specCm.Key, wSubpath /*model.ExternalConfig.AppConfigs[specCm.Name].Data*/, model.ExternalConfig.AppConfigKeys[specCm.Name])
updatePodWithAppConfig(model.backstageDeployment, model.backstageDeployment.container(), specCm.Name,
mp, specCm.Key, wSubpath, model.ExternalConfig.AppConfigKeys[specCm.Name])
}
return nil
}
Expand Down Expand Up @@ -80,8 +78,8 @@ func (b *AppConfig) addToModel(model *BackstageModel, _ bsv1.Backstage) (bool, e
}

// implementation of RuntimeObject interface
func (b *AppConfig) updateAndValidate(m *BackstageModel, backstage bsv1.Backstage) error {
updatePodWithAppConfig(m.backstageDeployment.deployment, m.backstageDeployment.container(), b.ConfigMap.Name, m.backstageDeployment.defaultMountPath(), "", true, maps.Keys(b.ConfigMap.Data))
func (b *AppConfig) updateAndValidate(m *BackstageModel, _ bsv1.Backstage) error {
updatePodWithAppConfig(m.backstageDeployment, m.backstageDeployment.container(), b.ConfigMap.Name, m.backstageDeployment.defaultMountPath(), "", true, maps.Keys(b.ConfigMap.Data))
return nil
}

Expand All @@ -91,8 +89,8 @@ func (b *AppConfig) setMetaInfo(backstage bsv1.Backstage, scheme *runtime.Scheme
}

// updatePodWithAppConfig contrubutes to Volumes, container.VolumeMounts and contaiter.Args
func updatePodWithAppConfig(deployment *appsv1.Deployment, container *corev1.Container, cmName, mountPath, key string, withSubPath bool, cmData []string) {
utils.MountFilesFrom(&deployment.Spec.Template.Spec, container, utils.ConfigMapObjectKind,
func updatePodWithAppConfig(bsd *BackstageDeployment, container *corev1.Container, cmName, mountPath, key string, withSubPath bool, cmData []string) {
bsd.mountFilesFrom([]string{container.Name}, ConfigMapObjectKind,
cmName, mountPath, key, withSubPath, cmData)

for _, file := range cmData {
Expand Down
1 change: 0 additions & 1 deletion pkg/model/appconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ var (

func TestDefaultAppConfig(t *testing.T) {

//bs := simpleTestBackstage()
bs := *appConfigTestBackstage.DeepCopy()

testObj := createBackstageTest(bs).withDefaultConfig(true).addToDefaultConfig("app-config.yaml", "raw-app-config.yaml")
Expand Down
4 changes: 2 additions & 2 deletions pkg/model/configmapenvs.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func addConfigMapEnvsFromSpec(spec bsv1.BackstageSpec, model *BackstageModel) {
}

for _, specCm := range spec.Application.ExtraEnvs.ConfigMaps {
utils.AddEnvVarsFrom(model.backstageDeployment.container(), utils.ConfigMapObjectKind, specCm.Name, specCm.Key)
model.backstageDeployment.addEnvVarsFrom([]string{BackstageContainerName()}, ConfigMapObjectKind, specCm.Name, specCm.Key)
}
}

Expand Down Expand Up @@ -63,7 +63,7 @@ func (p *ConfigMapEnvs) addToModel(model *BackstageModel, _ bsv1.Backstage) (boo

// implementation of RuntimeObject interface
func (p *ConfigMapEnvs) updateAndValidate(m *BackstageModel, _ bsv1.Backstage) error {
utils.AddEnvVarsFrom(m.backstageDeployment.container(), utils.ConfigMapObjectKind,
m.backstageDeployment.addEnvVarsFrom([]string{BackstageContainerName()}, ConfigMapObjectKind,
p.ConfigMap.Name, "")
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/model/configmapfiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func addConfigMapFilesFromSpec(spec bsv1.BackstageSpec, model *BackstageModel) e

mp, wSubpath := model.backstageDeployment.mountPath(specCm.MountPath, specCm.Key, spec.Application.ExtraFiles.MountPath)
keys := model.ExternalConfig.ExtraFileConfigMapKeys[specCm.Name].All()
utils.MountFilesFrom(&model.backstageDeployment.deployment.Spec.Template.Spec, model.backstageDeployment.container(), utils.ConfigMapObjectKind,
model.backstageDeployment.mountFilesFrom([]string{BackstageContainerName()}, ConfigMapObjectKind,
specCm.Name, mp, specCm.Key, wSubpath, keys)
}
return nil
Expand Down Expand Up @@ -70,7 +70,7 @@ func (p *ConfigMapFiles) addToModel(model *BackstageModel, _ bsv1.Backstage) (bo
func (p *ConfigMapFiles) updateAndValidate(m *BackstageModel, _ bsv1.Backstage) error {

keys := append(maps.Keys(p.ConfigMap.Data), maps.Keys(p.ConfigMap.BinaryData)...)
utils.MountFilesFrom(&m.backstageDeployment.deployment.Spec.Template.Spec, m.backstageDeployment.container(), utils.ConfigMapObjectKind,
m.backstageDeployment.mountFilesFrom([]string{BackstageContainerName()}, ConfigMapObjectKind,
p.ConfigMap.Name, m.backstageDeployment.defaultMountPath(), "", true, keys)

return nil
Expand Down
12 changes: 10 additions & 2 deletions pkg/model/db-statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ func (b *DbStatefulSet) updateAndValidate(model *BackstageModel, backstage bsv1.
}

if backstage.Spec.IsAuthSecretSpecified() {
utils.SetDbSecretEnvVar(b.container(), backstage.Spec.Database.AuthSecretName)
b.setDbSecretEnvVar(b.container(), backstage.Spec.Database.AuthSecretName)
} else if model.LocalDbSecret != nil {
utils.SetDbSecretEnvVar(b.container(), model.LocalDbSecret.secret.Name)
b.setDbSecretEnvVar(b.container(), model.LocalDbSecret.secret.Name)
}
return nil
}
Expand All @@ -112,3 +112,11 @@ func (b *DbStatefulSet) container() *corev1.Container {
func (b *DbStatefulSet) podSpec() *corev1.PodSpec {
return &b.statefulSet.Spec.Template.Spec
}

func (b *DbStatefulSet) setDbSecretEnvVar(container *corev1.Container, secretName string) {
//AddEnvVarsFrom(container, SecretObjectKind, secretName, "")
envFromSrc := corev1.EnvFromSource{}
envFromSrc.SecretRef = &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{Name: secretName}}
container.EnvFrom = append(container.EnvFrom, envFromSrc)
}
Loading
Loading