--- title: "Use QLKube to query the Kubernetes API" date: 2019-06-07T00:00:00+02:00 opensource: - OpenShift topic: - GraphQL --- [QLKube](https://github.com/qlkube/qlkube) is a project that exposes the Kubernetes API as GraphQL. [GraphQL](https://en.wikipedia.org/wiki/GraphQL) is a data query and manipulation language for APIs developed initially by Facebook and released as open-source. It strives to reduce the chattiness clients can experience when querying REST APIs. It is very useful for mobile application and web development: by reducing the number of roundtrips needed to fetch the relevant data and by fetching only the needed field, the network usage is greatly reduced. To install QLKube in OpenShift, use the NodeJS Source-to-Image builder: ```sh oc new-project qlkube --display-name=QLKube oc new-app nodejs~https://github.com/qlkube/qlkube.git --name=qlkube ``` Disable TLS certificate validation to accommodate your self-signed certificates: ```sh oc set env dc/qlkube NODE_TLS_REJECT_UNAUTHORIZED=0 ``` And enable the NodeJS development mode to enable the GraphQL explorer (disabled in production mode): ```sh oc set env dc/qlkube NODE_ENV=development ``` Give the GLKube's Service Account the right to query the Kubernetes API for its own namespace: ```sh oc adm policy add-role-to-user view -z default ``` Once deployed, open the QLKube URL in your web browser: ```sh open $(oc get route qlkube -o go-template --template="http://{{.spec.host}}") ``` You can try the following queries in the GraphQL explorer. ## Get all pods in the current namespace Unless you gave the `cluster-admin` right to the QLKube Service Account, you will have to specify a target namespace in all your queries. The `all` type is a [meta type defined by QLKube](https://github.com/qlkube/qlkube/blob/9274405bb46592646220c099affdd24211875eed/src/schema.js#L25-L39) to ease the use of common types such as `services`, `deployments`, `pods`, `daemonSets`, `replicaSets`, `statefulSets`, `jobs` or `cronJobs`. **Query:** ```graphql query getAllPodsInCurrentNamespace { all(namespace: "qlkube") { pods { items { metadata { name creationTimestamp } status { phase } } } } } ``` **Response:** ```json { "data": { "all": { "pods": { "items": [ { "metadata": { "name": "qlkube-1-build", "creationTimestamp": "2019-06-07T07:56:53Z" }, "status": { "phase": "Succeeded" } }, { "metadata": { "name": "qlkube-3-jplpc", "creationTimestamp": "2019-06-07T14:03:48Z" }, "status": { "phase": "Running" } } ] } } } } ``` ## Get a service by name To get an object by name, you can use the `fieldSelector` parameter (in this example, we are filtering on the `name` field in the `metadata` section). **Query:** ```graphql query getServiceByNameAndNamespace { all(namespace: "qlkube", fieldSelector: "metadata.name=qlkube") { services { items{ metadata { name namespace } spec { clusterIP } } } } } ``` **Response:** ```json { "data": { "all": { "services": { "items": [ { "metadata": { "name": "qlkube", "namespace": "qlkube" }, "spec": { "clusterIP": "172.30.213.61" } } ] } } } } ``` ## Type introspection Playing with the built-in types of GLKube is nice but you might soon be limited. To discover all the available types, run this query: ```graphql { __schema { types { name } } } ``` This query returns a list of all the available types (truncated here for brevity): ```json { "data": { "__schema": { "types": [ { "name": "Query" }, { "name": "String" }, { "name": "Boolean" }, { "name": "Int" }, { "name": "ComGithubOpenshiftApiAppsV1DeploymentConfig" }, { "name": "ComGithubOpenshiftApiRouteV1Route" }, { "name": "ComGithubOpenshiftApiRouteV1RouteList" } ] } } } ``` ## Get a Deployment Config by name and namespace Once the desired data type discovered, you can use it directly. - If the data type represents an item (such as `ComGithubOpenshiftApiRouteV1Route`) you will need to specify the `name` and `namespace` parameters. - If the data type is a list (such as `ComGithubOpenshiftApiRouteV1RouteList`) you will need to specify the `namespace` and optionally a `fieldSelector` parameters. **Query:** ```graphql query getDeploymentConfigByNameAndNamespace { comGithubOpenshiftApiAppsV1DeploymentConfig(name: "qlkube", namespace: "qlkube") { metadata { name } status { replicas availableReplicas } } } ``` **Reponse:** ```json { "data": { "comGithubOpenshiftApiAppsV1DeploymentConfig": { "metadata": { "name": "qlkube" }, "status": { "replicas": 1, "availableReplicas": 1 } } } } ``` ## Get routes by hostname and namespace This query use a `fieldSelector` on the `host` field in the `spec` section and uses aliasing to rename the `status` field. **Query:** ```graphql query getRouteByHostnameAndNamespace { routes: comGithubOpenshiftApiRouteV1RouteList(namespace: "qlkube" fieldSelector: "spec.host=qlkube-qlkube.app.itix.fr") { items { metadata { name } status { ingress { routerName conditions { deployed: status } } } } } } ``` **Reponse:** ```json { "data": { "routes": { "items": [ { "metadata": { "name": "qlkube" }, "status": { "ingress": [ { "routerName": "router", "conditions": [ { "deployed": "True" } ] } ] } } ] } } } ``` ## Sending your GraphQL request from curl Once your GraphQL queries refined in the GraphQL Explorer, you can send them directly using curl or any HTTP client. ```sh export GLKUBE_HOSTNAME=$(oc get route qlkube -o go-template --template="{{.spec.host}}") cat <