Using JQ in Cortex
JQ is a lightweight, flexible command-line JSON processor that allows users to do arbitrary JSON manipulations.
Cortex leverages JQ within CQL to enable complex queries, including queries on YAML files. For instance:
jq(custom("foo"), ".property | length")The above query would cycle through the foo object and retrieve the length of all .property components. This type of query is often used on Kubernetes resources.
JQ and datatypes
JQ can provide additional flexibility around data types. For instance, let's say you have a string associated with a numerical value in your Custom Data.
x-cortex-custom-metadata:
my-key:
line: "100"If you wanted to query on the line value as a number rather than string, the following JQ functionality could be used within CQL:
jq(custom("my-key"), ".line | tonumber") > 99This would result in the respective entity passing this CQL check.
JQ examples
The following examples demonstrate ways you could use JQ in Cortex:
Use JQ to implement conditional logic for selecting file paths dynamically
git.fileContents(jq(custom("git"), "if . != null then .[\"dockerfile-path\"] else \"Dockerfile\" endThis checks if custom git data exists, uses the custom dockerfile path if present, or falls back to the default "Dockerfile" path.
Accessing properties with special characters
Use bracket notation to access JSON properties containing dots, slashes, or other special characters:
jq(k8s.spec().firstOrNull().selector.matchLabels, ".[\"app.kubernetes.io/instance\"]")Handling null values
Prevent errors by checking for null values before accessing properties:
jq(custom("data-key"), 'if .retryConfigurations != null then .retryConfigurations | map(.retryAttemptTime) else "Not Found" end')For Scorecard rules, you can use a similar approach:
custom("retry-circuit-breaker") != nullWildcard pattern matching
Find packages containing specific strings using the matches() function:
jq(custom("data-source").packages.filter((package)=>package.packageName.matches(".*<string-text-here>.*")).map((package) => package.packageVersion), ".")Finding team members by role
Filter team members by role using JQ:
jq(entity.descriptor().info.`x-cortex-team`.members, "map(select(.role == \"engineering-manager\")) | .[].name")Handling complex YAML structures
When working with complex YAML files like GitLab CI configurations:
jq(git.fileContents('gitlab-ci.yaml').split(' ').filter((section) => section.matchesIn('NODE_VERSION:')).firstOrNull(), '.variables.NODE_VERSION')Extract the scheme of an AWS load balancer for resource metadata
jq(aws.details(), ".resources[0].Scheme")Or, for nested metadata:
jq(aws.details(), ".resources[0].metadata.Scheme")Extracting version from pom.xml file
This query extracts the version number from a Maven pom.xml file. You might use this to automate dependency version checks:
jq(jq(git.fileContents("pom.xml").split("<version>"),".[1]").split("</version>"), ".[0]")Display a parent entity name in a CQL report
This query would allow you to display a parent entity name value, rather than an array, in a CQL report:
jq(entity.parents().map((parentEntity) => parentEntity.parents.map((parentEntity) => parentEntity.name)), ".[0]")Last updated
Was this helpful?