If you search for information about ConfigMap in OpenShift or Kubernetes
then you find it’s a mechanism to abstract your application from configuration.
ConfigMap is then way to define configuration values (usually in form of a yaml file)
while the configuration is then injected to the running application which can utilize
the information as it likes.
There is not many information that the ConfigMap primitives can be used
from inside of the pod (and from the application itself) to persist data
which is then available via OpenShift API calls.
see more details about OpenShift API calls at article http://blog.chalda.cz/2018/02/28/Querying-Open-Shift-API.html
|
Note
|
As the first step is good to scan the documentation pages from OpenShift or Kubernetes to get overview of the usage. |
To create a simple ConfigMap object let’s use the oc command while naming the
it special-config and filling it with two keys (special.how, special.type)
and matched values.
$ oc create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
We can use the oc create to get the ConfigMap being created from json data format.
cat <<EOF | oc create -f -
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"name": "special-config"
}
}
EOF
When using the oc command we can utilize argument describe to find
the content of just created ConfigMap special-config.
$ oc describe cm special-config
Name: special-config
Namespace: myproject
Labels: <none>
Annotations: <none>
Data
====
special.how:
----
very
special.type:
----
charm
Events: <none
To get the same information by querying OpenShift API we will call
ENDPOINT=$(minishift ip):8443
TOKEN=$(oc whoami -t)
NAMESPACE=$(oc project -q)
CONFIG_MAP_NAME=special-config
curl -k -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json'\
https://$ENDPOINT/api/v1/namespaces/$NAMESPACE/configmaps/$CONFIG_MAP_NAME
The output will be similar to this
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"name": "special-config",
"namespace": "myproject",
"selfLink": "/api/v1/namespaces/myproject/configmaps/special-config",
...
},
"data": {
"special.how": "very",
"special.type": "charm"
}
}
As said we can not only query ConfigMap data but we can write them too.
Here we use the PUT operation wile we re-write all data saved in the special-config
ConfigMap and replace them with data from json we’re providing.
curl -k -X PUT -d @- -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json'\
-H 'Content-Type: application/json'\
https://$ENDPOINT/api/v1/namespaces/$NAMESPACE/configmaps/$CONFIG_MAP_NAME <<'EOF'
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"name": "special-config"
},
"data": {
"Samwise": "Gamgee",
"Rosie": "Cotton"
}
}
EOF
This is good but what if we don’t want just override the content of the existing
ConfigMap but we would like to add new data or change the value of a single existing key.
Here we got to the point to find out there are strategies that could be used
while working with the ConfigMaps. We can patch the existing ConfigMaps
by, surprisingly, calling with method PATH and defining Content-Type.
We can use either merge strategy application/merge-patch+json or patch
strategy application/json-patch+json. For the summary of the approaches I like
article at http://erosb.github.io/post/json-patch-vs-merge-patch.
With merge-patch we use PATCH with json format (as we used with PUT above)
and the ConfigMap will be merged (instead of replaced).
curl -k -X PATCH -d @- -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json'\
-H 'Content-Type: application/merge-patch+json'\
https://$ENDPOINT/api/v1/namespaces/$NAMESPACE/configmaps/$CONFIG_MAP_NAME <<EOF
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"name": "special-config"
},
"data": {
"Rosie": "Gamgee"
}
}
EOF
After executing this the patch the data will look like
"data": {
"Rosie": "Gamgee",
"Samwise": "Gamgee"
}
With the json-patch is needed to define what is operation to be processed
over the particular key. Let’s make the value removal while changing the other one.
curl -k -X PATCH -d @- -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json'\
-H 'Content-Type: application/json-patch+json'\
https://$ENDPOINT/api/v1/namespaces/$NAMESPACE/configmaps/$CONFIG_MAP_NAME <<EOF
[
{
"op": "replace",
"path": "/data/Samwise",
"value": "Baggins"
},
{
"op": "remove",
"path": "/data/Rosie"
}
]
EOF
For you can update the ConfigMap from inside of the pod, the service account
the pod is running at has to be permitted to do changes in the ConfigMap.
You should create a new service account with such permissions and configure
your pod to run with that service account. Here is an example of the configuration
json which defines a new service account and declares it to be of role edit
which provides permissions to make changes (to edit) most of the things in the
current namespace (project). Of course you can define permissions
in more granular way.
For importing it you can use oc create -f <path-to-file-with-this-json> and then
applying imported template by oc new-app --template=role-testing.
{
"kind": "Template",
"apiVersion": "v1",
"metadata": {
"name": "role-testing"
},
"parameters": [
{
"displayName": "Application name",
"name": "APPLICATION_NAME",
"value": "myproject",
"required": true
}
],
"objects": [
{
"apiVersion": "v1",
"kind": "ServiceAccount",
"metadata": {
"name": "${APPLICATION_NAME}-sa"
}
},
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"name": "special-config"
},
"data": {}
},
{
"apiVersion": "v1",
"kind": "RoleBinding",
"metadata": {
"name": "${APPLICATION_NAME}-role-binding"
},
"subjects": [
{
"kind": "ServiceAccount",
"name": "${APPLICATION_NAME}-sa"
}
],
"roleRef": {
"kind": "Role",
"name": "edit"
}
}
]
}