When using OpenShift many of the tasks that you need to do can be performed through the OpenShift web console or directly using the oc command line tool. In those cases where you may need to do something a bit more complicated, you can dip below the covers and edit OpenShift configuration objects to make the changes you need.

The way that OpenShift configuration objects are usually modified is using the oc edit command if working from the command line, or by editing the YAML for the object definition via the OpenShift web console.

In this blog post I am going to show you how you can explore what can be set within a configuration object, as well as describe some other ways you can edit OpenShift configuration objects.

Configuration objects

What exactly do I mean by configuration objects. Here I am referring to the build configurations, deployment configurations, service configurations and other definitions within OpenShift which dictate how your application is going to be built and deployed. Referring to these as objects derives from Kubernetes. You may also find them referred to as resources, such as in the OpenShift web console, but they are the same definitions.

All these terms and the concepts they represent can be a lot to learn when first starting out with OpenShift. The OpenShift documentation goes a long way to explaining these core concepts, but sometimes it may be a bit inconvenient to have to go back and dig through the documentation when you forget what something means.

As it happens, if you are using the oc command line tool there is a quick way to get a brief summary of the different concepts and types. This is by running the oc types command.

$ oc types
Concepts and Types

Kubernetes and OpenShift help developers and operators build, test, and deploy
applications in a containerized cloud environment. Applications may be composed
of all of the components below, although most developers will be concerned with
Services, Deployments, and Builds for delivering changes.

Concepts:

* Containers:
A definition of how to run one or more processes inside of a portable Linux
environment. Containers are started from an Image and are usually isolated
from other containers on the same machine.

...

Definitely worth a quick review if you didn't know about the types option to the oc command.

Identifying a configuration

One of the useful things that oc types displays is the shorthand label for referring to the different configuration object types. For example, for a service configuration it displays:

* Services [svc]:
A name representing a set of pods (or external servers) that are
accessed by other pods. The service gets an IP and a DNS name, and can be
exposed externally to the cluster via a port or a Route. It's also easy
to consume services from pods because an environment variable with the
name <SERVICE>_HOST is automatically injected into other pods.

The label I am referring to is the svc in the square brackets. This comes into play when needing to query on a configuration object or edit it.

If needing to list all the services in a project, you could for example run the command:

oc get svc

Just to confuse you when new to OpenShift (I know I was), there are actually multiple labels you could use for the same configuration object type. All the following are actually equivalent.

oc get svc

oc get service
oc get services

oc get Service
oc get Services

You therefore can use either the shorthand label or the full configuration object type name. The labels when interpreted are done so in a case insensitive manner and can also be written in plural form.

If needing to refer to a configuration object for a particular application, when for example needing to edit it using the oc edit command, you are presented with multiple choices here as well. The help message for a command shown when using the --help option doesn't always show all possibilities.

The help message for oc edit shows for example:

Usage:
oc edit (RESOURCE/NAME | -f FILENAME) [options]

If our application was called wombat, we edit its build configuration by using the command:

oc edit bc/wombat

One can also though use:

oc edit bc wombat

That is, replacing the / with a space.

All commands will accept both forms. If you see the different styles in any documentation or help messages, know that they are equivalent.

Values that can be set

The oc types command is great to get a high level summary of what a configuration object is for, but what about the values that can be set within it. This is where the oc explain command can be used.

$ oc explain bc
DESCRIPTION:
BuildConfig is a template which can be used to create new builds.

FIELDS:
apiVersion <string>
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:
http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources

kind <string>
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:
http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds

metadata <Object>
Standard object's metadata.

spec <Object> -required-
Spec holds all the input necessary to produce a new build, and the
conditions when to trigger them.

status <Object> -required-
Status holds any relevant information about a build config

Object definitions aren't presented in a flat namespace but are in fact described using an object hierarchy. When you run oc explain it will only show what exists at the level you specified.

This means that if you want to know more about what is in the spec object within the build configuration, you would run oc explain again as:

$ oc explain bc.spec
RESOURCE: spec <Object>

DESCRIPTION:
Spec holds all the input necessary to produce a new build, and the
conditions when to trigger them.

BuildConfigSpec describes when and how builds are created

FIELDS:
serviceAccount <string>
ServiceAccount is the name of the ServiceAccount to use to run the pod
created by this build. The pod will be allowed to use secrets referenced by
the ServiceAccount

...

You can keep traversing in this way right down to the bottom most values.

$ oc explain bc.spec.serviceAccount
FIELD: serviceAccount <string>

DESCRIPTION:
ServiceAccount is the name of the ServiceAccount to use to run the pod
created by this build. The pod will be allowed to use secrets referenced by
the ServiceAccount

When you run oc edit it will not present you with all possible values that could be set. If something is not used, or the builtin default is to be applied, then that path down into the object hierarchy will simply be left out.

The oc explain command is therefore useful as a quick way of exploring what values can be set, again meaning you don't always have to be referring back to the documentation on the OpenShift web site. If you do need the more in-depth documentation, you can find it in the REST API documentation.

Editing the configuration

As I keep mentioning, when it comes to editing the configuration, you can use oc edit. This will drop you into an editor where you can make changes to the YAML definition for the configuration object. Prefer to work with JSON, you can use the -o json option.

If we now wanted to add a serviceAccount definition to a build configuration, we would look for the spec object and add serviceAccount as a member.

    "spec": {
"serviceAccount": "secret:spy",
"triggers": [
{
"type": "GitHub",
"github": {
"secret": "PUvC9TgFAPXhw9f_8qHi"
}
},

Using oc edit isn't the only way of updating a configuration object from the command line though.

Another way which can be used and which is easier to incorporate into scripts is to use the oc patch command.

For the oc patch command, rather than being dropped into an editor, you can provide a JSON object definition for just the setting you want to add or update. This needs to include the full object path down to the setting, which could be a literal value, or a structured object in itself.

To update the serviceAccount setting using oc patch, we can use the command:

$ oc patch bc/wombat --patch '{"spec":{"serviceAccount": "secret:spy"}}'
"wombat" patched

A final way of updating a configuration object is to perform the edits offline and then replace the existing definition.

For this method you first need to extract the existing definition. This can be done using the oc get command.

$ oc get bc/wombat -o json > config.json

This will save into the file config.json the JSON definition of the configuration object. You can then separately edit the definition to add the required setting.

To now load this back into OpenShift, replacing the existing definition, the oc replace command is used.

$ oc replace -f config.json
buildconfig "wombat" replaced

There is no need when running this command to specify what object configuration is being targeted as all that information is already a part of the JSON definition within the config.json file.