Chapter 5. Using credentials and configurations in workspaces

You can use your credentials and configurations in your workspaces.

To do so, mount your credentials and configurations to the DevWorkspace containers in the OpenShift cluster of your organization’s OpenShift Dev Spaces instance:

If you need to allow the DevWorkspace Pods in the cluster to access container registries that require authentication, create an image pull Secret for the DevWorkspace Pods.

The mounting process uses the standard Kubernetes mounting mechanism and requires applying additional labels and annotations to your existing resources. Resources are mounted when starting a new workspace or restarting an existing one.

You can create permanent mount points for various components:

  • Maven configuration, such as the settings.xml file
  • SSH key pairs
  • AWS authorization tokens
  • Configuration files
  • Persistent storage
  • Git credentials store files

5.1. Using a Git credentials store

As an alternative to the OAuth for GitHub, GitLab, or Bitbucket that is configured by the administrator of your organization’s OpenShift Dev Spaces instance, you can apply your Git credentials store as a Kubernetes Secret.

Apply the Kubernetes Secret in your user project of the OpenShift cluster of your organization’s OpenShift Dev Spaces instance.

When you apply the Secret, a Git configuration file with the path to the mounted Git credentials store is automatically configured and mounted to the DevWorkspace containers in the cluster at /etc/gitconfig. This makes your Git credentials store available in your workspaces.

Prerequisites

  • An active oc session with administrative permissions to the destination OpenShift cluster. See Getting started with the CLI.
  • base64 command line tools are installed in the operating system you are using.

Procedure

  1. In your home directory, locate and open your .git-credentials file if you already have it. Alternatively, if you do not have this file, save a new .git-credentials file, using the Git credentials storage format. Each credential is stored on its own line in the file:

    https://<username>:<token>@<git_server_hostname>

    Example 5.1. A line in a .git-credentials file

    https://trailblazer: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@github.com
  2. Select credentials from your .git-credentials file for the Secret. Encode the selected credentials to Base64 for the next step.

    Tip
    • To encode all lines in the file:

      $ cat .git-credentials | base64 | tr -d '\n'

    • To encode a selected line:

      $ echo -n '<copied_and_pasted_line_from_.git-credentials>' | base64

  3. Create a new OpenShift Secret in your user project.

    apiVersion: v1
    kind: Secret
    metadata:
      name: git-credentials-secret
      labels:
        controller.devfile.io/git-credential: 'true' 1
        controller.devfile.io/watch-secret: 'true'
      annotations:
        controller.devfile.io/mount-path: /etc/secret 2
    data:
      credentials: <Base64_content_of_.git-credentials> 3
    1
    The controller.devfile.io/git-credential label marks the Secret as containing Git credentials.
    2
    A custom absolute path in the DevWorkspace containers. The Secret is mounted as the credentials file at this path. The default path is /.
    3
    The selected content from .git-credentials that you encoded to Base64 in the previous step.
    Tip

    You can create and apply multiple Git credentials Secrets in your user project. All of them will be copied into one Secret that will be mounted to the DevWorkspace containers. For example, if you set the mount path to /etc/secret, then the one Secret with all of your Git credentials will be mounted at /etc/secret/credentials. You must set all Git credentials Secrets in your user project to the same mount path. You can set the mount path to an arbitrary path because the mount path will be automatically set in the Git configuration file configured at /etc/gitconfig.

  4. Apply the Secret:

    $ oc apply -f - <<EOF
    <Secret_prepared_in_the_previous_step>
    EOF

5.2. Enabling artifact repositories in a restricted environment

By configuring technology stacks, you can work with artifacts from in-house repositories using self-signed certificates:

5.2.1. Enabling Maven artifact repositories

You can enable a Maven artifact repository in Maven workspaces that run in a restricted environment.

Prerequisites

  • You are not running any Maven workspace.

Procedure

  1. Apply the Secret for the TLS certificate:

    kind: Secret
    apiVersion: v1
    metadata:
      name: tls-cer
      annotations:
        controller.devfile.io/mount-path: /home/user/certs
        controller.devfile.io/mount-as: file
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-secret: 'true'
    data:
      tls.cer: >-
        <Base64_encoded_content_of_public_cert> 1
    1
    Base64 encoding with disabled line wrapping.
  2. Apply the ConfigMap to create the settings.xml file:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: settings-xml
      annotations:
        controller.devfile.io/mount-as: subpath
        controller.devfile.io/mount-path: /home/user/.m2
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      settings.xml: |
        <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
          <localRepository/>
          <interactiveMode/>
          <offline/>
          <pluginGroups/>
          <servers/>
          <mirrors>
            <mirror>
              <id>redhat-ga-mirror</id>
              <name>Red Hat GA</name>
              <url>https://<maven_artifact_repository_route>/repository/redhat-ga/</url>
              <mirrorOf>redhat-ga</mirrorOf>
            </mirror>
            <mirror>
              <id>maven-central-mirror</id>
              <name>Maven Central</name>
              <url>https://<maven_artifact_repository_route>/repository/maven-central/</url>
              <mirrorOf>maven-central</mirrorOf>
            </mirror>
            <mirror>
              <id>jboss-public-repository-mirror</id>
              <name>JBoss Public Maven Repository</name>
              <url>https://<maven_artifact_repository_route>/repository/jboss-public/</url>
              <mirrorOf>jboss-public-repository</mirrorOf>
            </mirror>
          </mirrors>
          <proxies/>
          <profiles/>
          <activeProfiles/>
        </settings>
  3. Apply the ConfigMap for the TrustStore initialization script:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: init-truststore
      annotations:
        controller.devfile.io/mount-as: subpath
        controller.devfile.io/mount-path: /home/user/
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      init-truststore.sh: |
        #!/usr/bin/env bash
    
        keytool -importcert -noprompt -file /home/user/certs/tls.cer -cacerts -storepass changeit
  4. Start a Maven workspace.
  5. Open a new terminal in the tools container.
  6. Run ~/init-truststore.sh.

5.2.2. Enabling Gradle artifact repositories

You can enable a Gradle artifact repository in Gradle workspaces that run in a restricted environment.

Prerequisites

  • You are not running any Gradle workspace.

Procedure

  1. Apply the Secret for the TLS certificate:

    kind: Secret
    apiVersion: v1
    metadata:
      name: tls-cer
      annotations:
        controller.devfile.io/mount-path: /home/user/certs
        controller.devfile.io/mount-as: file
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-secret: 'true'
    data:
      tls.cer: >-
        <Base64_encoded_content_of_public_cert> 1
    1
    Base64 encoding with disabled line wrapping.
  2. Apply the ConfigMap for the TrustStore initialization script:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: init-truststore
      annotations:
        controller.devfile.io/mount-as: subpath
        controller.devfile.io/mount-path: /home/user/
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      init-truststore.sh: |
        #!/usr/bin/env bash
    
        keytool -importcert -noprompt -file /home/user/certs/tls.cer -cacerts -storepass changeit
  3. Apply the ConfigMap for the Gradle init script:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: init-gradle
      annotations:
        controller.devfile.io/mount-as: subpath
        controller.devfile.io/mount-path: /home/user/.gradle
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      init.gradle: |
        allprojects {
          repositories {
            mavenLocal ()
            maven {
              url "https://<gradle_artifact_repository_route>/repository/maven-public/"
              credentials {
                username "admin"
                password "passwd"
              }
            }
          }
        }
  4. Start a Gradle workspace.
  5. Open a new terminal in the tools container.
  6. Run ~/init-truststore.sh.

5.2.3. Enabling npm artifact repositories

You can enable an npm artifact repository in npm workspaces that run in a restricted environment.

Prerequisites

  • You are not running any npm workspace.
Warning

Applying a ConfigMap that sets environment variables might cause a workspace boot loop.

If you encounter this behavior, remove the ConfigMap and edit the devfile directly.

Procedure

  1. Apply the Secret for the TLS certificate:

    kind: Secret
    apiVersion: v1
    metadata:
      name: tls-cer
      annotations:
        controller.devfile.io/mount-path: /home/user/certs
        controller.devfile.io/mount-as: file
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-secret: 'true'
    data:
      tls.cer: >-
        <Base64_encoded_content_of_public_cert> 1
    1
    Base64 encoding with disabled line wrapping.
  2. Apply the ConfigMap to set the following environment variables in the tools container:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: disconnected-env
      annotations:
        controller.devfile.io/mount-as: env
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      NODE_EXTRA_CA_CERTS: /home/user/certs/tls.cer
      NPM_CONFIG_REGISTRY: >-
        https://<npm_artifact_repository_route>/repository/npm-all/

5.2.4. Enabling Python artifact repositories

You can enable a Python artifact repository in Python workspaces that run in a restricted environment.

Prerequisites

  • You are not running any Python workspace.
Warning

Applying a ConfigMap that sets environment variables might cause a workspace boot loop.

If you encounter this behavior, remove the ConfigMap and edit the devfile directly.

Procedure

  1. Apply the Secret for the TLS certificate:

    kind: Secret
    apiVersion: v1
    metadata:
      name: tls-cer
      annotations:
        controller.devfile.io/mount-path: /home/user/certs
        controller.devfile.io/mount-as: file
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-secret: 'true'
    data:
      tls.cer: >-
        <Base64_encoded_content_of_public_cert> 1
    1
    Base64 encoding with disabled line wrapping.
  2. Apply the ConfigMap to set the following environment variables in the tools container:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: disconnected-env
      annotations:
        controller.devfile.io/mount-as: env
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      PIP_INDEX_URL: >-
        https://<python_artifact_repository_route>/repository/pypi-all/
      PIP_CERT: /home/user/certs/tls.cer

5.2.5. Enabling Go artifact repositories

You can enable a Go artifact repository in Go workspaces that run in a restricted environment.

Prerequisites

  • You are not running any Go workspace.
Warning

Applying a ConfigMap that sets environment variables might cause a workspace boot loop.

If you encounter this behavior, remove the ConfigMap and edit the devfile directly.

Procedure

  1. Apply the Secret for the TLS certificate:

    kind: Secret
    apiVersion: v1
    metadata:
      name: tls-cer
      annotations:
        controller.devfile.io/mount-path: /home/user/certs
        controller.devfile.io/mount-as: file
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-secret: 'true'
    data:
      tls.cer: >-
        <Base64_encoded_content_of_public_cert> 1
    1
    Base64 encoding with disabled line wrapping.
  2. Apply the ConfigMap to set the following environment variables in the tools container:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: disconnected-env
      annotations:
        controller.devfile.io/mount-as: env
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      GOPROXY: >-
        http://<athens_proxy_route>
      SSL_CERT_FILE: /home/user/certs/tls.cer

5.2.6. Enabling NuGet artifact repositories

You can enable a NuGet artifact repository in NuGet workspaces that run in a restricted environment.

Prerequisites

  • You are not running any NuGet workspace.
Warning

Applying a ConfigMap that sets environment variables might cause a workspace boot loop.

If you encounter this behavior, remove the ConfigMap and edit the devfile directly.

Procedure

  1. Apply the Secret for the TLS certificate:

    kind: Secret
    apiVersion: v1
    metadata:
      name: tls-cer
      annotations:
        controller.devfile.io/mount-path: /home/user/certs
        controller.devfile.io/mount-as: file
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-secret: 'true'
    data:
      tls.cer: >-
        <Base64_encoded_content_of_public_cert> 1
    1
    Base64 encoding with disabled line wrapping.
  2. Apply the ConfigMap to set the environment variable for the path of the TLS certificate file in the tools container:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: disconnected-env
      annotations:
        controller.devfile.io/mount-as: env
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      SSL_CERT_FILE: /home/user/certs/tls.cer
  3. Apply the ConfigMap to create the nuget.config file:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: init-nuget
      annotations:
        controller.devfile.io/mount-as: subpath
        controller.devfile.io/mount-path: /projects
      labels:
        controller.devfile.io/mount-to-devworkspace: 'true'
        controller.devfile.io/watch-configmap: 'true'
    data:
      nuget.config: |
        <?xml version="1.0" encoding="UTF-8"?>
        <configuration>
          <packageSources>
            <add key="nexus2" value="https://<nuget_artifact_repository_route>/repository/nuget-group/"/>
          </packageSources>
          <packageSourceCredentials>
            <nexus2>
                <add key="Username" value="admin" />
                <add key="Password" value="passwd" />
            </nexus2>
          </packageSourceCredentials>
        </configuration>

5.3. Creating image pull Secrets

To allow the DevWorkspace Pods in the OpenShift cluster of your organization’s OpenShift Dev Spaces instance to access container registries that require authentication, create an image pull Secret.

You can create image pull Secrets by using oc or a .dockercfg file or a config.json file.

5.3.1. Creating an image pull Secret with oc

Prerequisites

Procedure

  1. In your user project, create an image pull Secret with your private container registry details and credentials:

    $ oc create secret docker-registry <Secret_name> \
        --docker-server=<registry_server> \
        --docker-username=<username> \
        --docker-password=<password> \
        --docker-email=<email_address>
  2. Add the following label to the image pull Secret:

    $ oc label secret <Secret_name> controller.devfile.io/devworkspace_pullsecret=true controller.devfile.io/watch-secret=true

5.3.2. Creating an image pull Secret from a .dockercfg file

If you already store the credentials for the private container registry in a .dockercfg file, you can use that file to create an image pull Secret.

Prerequisites

  • An active oc session with administrative permissions to the destination OpenShift cluster. See Getting started with the CLI.
  • base64 command line tools are installed in the operating system you are using.

Procedure

  1. Encode the .dockercfg file to Base64:

    $ cat .dockercfg | base64 | tr -d '\n'
  2. Create a new OpenShift Secret in your user project:

    apiVersion: v1
    kind: Secret
    metadata:
      name: <Secret_name>
      labels:
        controller.devfile.io/devworkspace_pullsecret: 'true'
        controller.devfile.io/watch-secret: 'true'
    data:
      .dockercfg: <Base64_content_of_.dockercfg>
    type: kubernetes.io/dockercfg
  3. Apply the Secret:

    $ oc apply -f - <<EOF
    <Secret_prepared_in_the_previous_step>
    EOF

5.3.3. Creating an image pull Secret from a config.json file

If you already store the credentials for the private container registry in a $HOME/.docker/config.json file, you can use that file to create an image pull Secret.

Prerequisites

  • An active oc session with administrative permissions to the destination OpenShift cluster. See Getting started with the CLI.
  • base64 command line tools are installed in the operating system you are using.

Procedure

  1. Encode the $HOME/.docker/config.json file to Base64.

    $ cat config.json | base64 | tr -d '\n'
  2. Create a new OpenShift Secret in your user project:

    apiVersion: v1
    kind: Secret
    metadata:
      name: <Secret_name>
      labels:
        controller.devfile.io/devworkspace_pullsecret: 'true'
        controller.devfile.io/watch-secret: 'true'
    data:
      .dockerconfigjson: <Base64_content_of_config.json>
    type: kubernetes.io/dockerconfigjson
  3. Apply the Secret:

    $ oc apply -f - <<EOF
    <Secret_prepared_in_the_previous_step>
    EOF

5.4. Mounting Secrets

To mount confidential data into your workspaces, use Kubernetes Secrets.

Using Kubernetes Secrets, you can mount usernames, passwords, SSH key pairs, authentication tokens (for example, for AWS), and sensitive configurations.

Mount Kubernetes Secrets to the DevWorkspace containers in the OpenShift cluster of your organization’s OpenShift Dev Spaces instance.

Prerequisites

  • An active oc session with administrative permissions to the destination OpenShift cluster. See Getting started with the CLI.
  • You have created a new Secret or determined an existing one in your user project to mount to all DevWorkspace containers.

Procedure

  1. Determine an existing ConfigMap or Secret in your user project to mount to all workspace containers.
  2. Set the required labels for mounting.

    $ oc label secret <Secret_name> \
            controller.devfile.io/mount-to-devworkspace=true \
            controller.devfile.io/watch-secret=true
  3. Optional: Use the annotations to configure how the Secret is mounted.

    Table 5.1. Optional annotations

    AnnotationDescription

    controller.devfile.io/mount-path:

    Specifies the mount path.

    Defaults to /etc/secret/<Secret_name>.

    controller.devfile.io/mount-as:

    Specifies how the resource should be mounted: file, subpath, or env.

    Defaults to file.

    mount-as: file mounts the keys and values as files within the mount path.

    mount-as: subpath mounts the keys and values within the mount path using subpath volume mounts.

    mount-as: env mounts the keys and values as environment variables in all DevWorkspace containers.

Example 5.2. Mounting a Secret as a file

apiVersion: v1
kind: Secret
metadata:
  name: mvn-settings-secret
  labels:
    controller.devfile.io/mount-to-devworkspace: 'true'
    controller.devfile.io/watch-secret: 'true'
  annotations:
    controller.devfile.io/mount-path: '/home/user/.m2'
data:
  settings.xml: <Base64_encoded_content>

When you start a workspace, the /home/user/.m2/settings.xml file will be available in the DevWorkspace containers.

With Maven, you can set a custom path for the settings.xml file. For example:

$ mvn --settings /home/user/.m2/settings.xml clean install

5.5. Mounting ConfigMaps

To mount non-confidential configuration data into your workspaces, use Kubernetes ConfigMaps.

Using Kubernetes ConfigMaps, you can mount non-sensitive data such as configuration values for an application.

Mount Kubernetes ConfigMaps to the DevWorkspace containers in the OpenShift cluster of your organization’s OpenShift Dev Spaces instance.

Prerequisites

  • An active oc session with administrative permissions to the destination OpenShift cluster. See Getting started with the CLI.
  • You have created a new ConfigMap or determined an existing one in your user project to mount to all DevWorkspace containers.

Procedure

  1. Determine an existing ConfigMap in your user project to mount to all workspace containers.
  2. Set the required labels for mounting.

    $ oc label configmap <ConfigMap_name> \
            controller.devfile.io/mount-to-devworkspace=true \
            controller.devfile.io/watch-configmap=true
  3. Optional: Use the annotations to configure how the ConfigMap is mounted.

    Table 5.2. Optional annotations

    AnnotationDescription

    controller.devfile.io/mount-path:

    Specifies the mount path.

    Defaults to /etc/config/<ConfigMap_name>.

    controller.devfile.io/mount-as:

    Specifies how the resource should be mounted: file, subpath, or env.

    Defaults to file.

    mount-as:file mounts the keys and values as files within the mount path.

    mount-as:subpath mounts the keys and values within the mount path using subpath volume mounts.

    mount-as:env mounts the keys and values as environment variables in all DevWorkspace containers.

Example 5.3. Mounting a ConfigMap as environment variables

kind: ConfigMap
apiVersion: v1
metadata:
  name: my-settings
  labels:
    controller.devfile.io/mount-to-devworkspace: 'true'
    controller.devfile.io/watch-configmap: 'true'
  annotations:
    controller.devfile.io/mount-as: env
data:
  <env_var_1>: <value_1>
  <env_var_2>: <value_2>

When you start a workspace, the <env_var_1> and <env_var_2> environment variables will be available in the DevWorkspace containers.