Automating Jenkins Job Metadata Retrieval with Bash Script

Introduction

Jenkins is a widely used automation server that facilitates continuous integration and delivery (CI/CD) processes. In this blog post, we’ll explore a Bash script that automates the retrieval of metadata for Jenkins jobs, such as build timestamps, using the Jenkins API.

Script Overview

The provided Bash script interacts with the Jenkins API to fetch job information, specifically focusing on jobs within folders. It retrieves details like job names, build timestamps, and organizes the data in a tabular format for easy readability.

Script Components

  • Jenkins URL: The base URL of your Jenkins instance.
  • Endpoints:
  • JOB_NAMES_ENDPOINT: Endpoint for fetching job names.
  • BUILD_TIMESTAMP_ENDPOINT: Endpoint for obtaining build timestamps for a specific job.
  • Authentication: Username and password for Jenkins API access.
  • Dependencies: curl for making HTTP requests and jq for parsing JSON responses.

Script Execution

The script performs the following steps:

  1. Fetch Folder Names: Makes a GET request to the Jenkins API to retrieve folder names.
  2. Iterate Over Folders: For each folder, it fetches the job names within that folder.
  3. Retrieve Build Timestamps: For each job, it obtains the build timestamp.
  4. Format and Display: The script organizes the obtained data into a tabular format, displaying folder names, job names, and build timestamps.

Prerequisites

Before running the script, ensure the following:

  • Jenkins instance is accessible.
  • Authentication credentials (username and password) are valid.
  • Required Bash utilities (curl, jq) are installed.

Script Output

The script generates a table containing the following columns:

  1. Folder: The name of the Jenkins folder.
  2. Job: The name of the Jenkins job.
  3. Month: The month of the last build.
  4. Date: The date of the last build.
  5. Year: The year of the last build.
#!/bin/bash

# Jenkins Configuration
JENKINS_URL="https://<Jenkins-url>"
JOB_NAMES_ENDPOINT="/api/json"
BUILD_TIMESTAMP_ENDPOINT="/job/{job_name}/lastBuild/buildTimestamp"
USERNAME="anusha.kanneganti"
PASSWORD="password"

# Make a GET request to the job names endpoint and filter by class
folder_names=$(curl -s -X GET "$JENKINS_URL$JOB_NAMES_ENDPOINT" --user "$USERNAME:$PASSWORD" | jq -r '.jobs[] | select(._class == "com.cloudbees.hudson.plugins.folder.Folder") | .name')

# Print the table headers
printf "%-20s | %-20s | %-6s | %-6s | %-6s\n" "Folder" "Job" "Month" "Date" "Year"
printf "%s\n" "-----------------------------------------------------------------"

# Iterate over the folder names
for folder_name in $folder_names; do
  # Construct the URL for the folder's job names endpoint
  folder_job_names_endpoint="/job/$folder_name/api/json"

  # Make a GET request to the folder's job names endpoint
  job_names=$(curl -s -X GET "$JENKINS_URL$folder_job_names_endpoint" --user "$USERNAME:$PASSWORD" | jq -r '.jobs[].name')

  # Check if there are any job names
  if [[ -z "$job_names" ]]; then
    # Print "No jobs found" for the folder
    printf "%-20s | %-20s | %-6s | %-6s | %-6s\n" "$folder_name" "No jobs found" "" "" ""
  else
    # Iterate over the job names
    for job_name in $job_names; do
      # Construct the URL for the job's build timestamp
      job_timestamp_endpoint="/job/$folder_name/job/$job_name/lastBuild/buildTimestamp"

      # Make a GET request to the job's build timestamp
      build_timestamp=$(curl -s -X GET "$JENKINS_URL$job_timestamp_endpoint" --user "$USERNAME:$PASSWORD")

      # Check if the build timestamp is not found or returns a 404 error
      if [[ "$build_timestamp" == *"HTTP ERROR 404"* ]]; then
        build_timestamp=""
      else
        # Extract date, month, and year using awk
        date=$(echo "$build_timestamp" | awk '{split($1, a, "/"); split(a[1], b, " "); split(b[1], c, "/"); print c[2]}')
        month=$(echo "$build_timestamp" | awk '{split($1, a, "/"); split(a[1], b, " "); split(b[1], c, "/"); print c[1]}')
        year=$(echo "$build_timestamp" | awk '{split($1, a, "/"); split(a[1], b, " "); split(b[1], c, "/"); print c[3]}')
      fi

      # Print the table row for the job
      printf "%-20s | %-20s | %-6s | %-6s | %-6s\n" "$folder_name" "$job_name" "$month" "$date" "$year"
    done
  fi
done

Explanation:

Jenkins Configuration:

  • JENKINS_URL: URL of your Jenkins server.
  • JOB_NAMES_ENDPOINT: Endpoint to get the list of job names.
  • BUILD_TIMESTAMP_ENDPOINT: Endpoint to get the build timestamp for a job (replace {job_name} with the actual job name).
  • USERNAME and PASSWORD: Jenkins credentials for authentication.

GET Request for Job Names:

  • Use curl to make a GET request to the Jenkins server, fetching job names.
  • jq is used to filter jobs based on their class, selecting only folders.

Print Table Headers:

  • Print headers for the output table.

Iterate Over Folder Names:

  • For each folder, construct the URL for the folder’s job names endpoint.

GET Request for Job Names in a Folder:

  • Use curl to fetch job names within a folder.

Check for Jobs:

  • If no jobs are found, print a row indicating “No jobs found” for the folder.

Iterate Over Job Names:

  • For each job, construct the URL for the job’s build timestamp.

GET Request for Build Timestamp:

  • Use curl to get the build timestamp for a job.

Check for Build Timestamp:

  • If the build timestamp is not found or returns a 404 error, set it to an empty string.

Extract Date, Month, and Year:

  • Use awk to extract the date, month, and year from the build timestamp.

Print Table Row:

  • Print a row in the table with folder name, job name, and extracted date, month, and year.

Conclusion

This Bash script provides a practical example of automating Jenkins API interactions for retrieving job metadata. You can customize and extend this script to suit your specific requirements or integrate it into your automation workflows.

This script provides a tabular representation of Jenkins job information, including folder names, job names, and build timestamps.

Feel free to explore, modify, and enhance the script based on your needs. Happy automating!