Skip to main content

Auto Installer in Atlassian Jira Integration via Log Source

Auto Installer for Aquila–Atlassian Jira Integration via log source automation

An Auto Installer for Aquila–Atlassian Jira Integration via log source automation builds upon the structured authentication and API connectivity defined in the referenced guide, but shifts the configuration process into a fully automated workflow. Instead of manually executing each setup step, the integration leverages automated scripts or installers to establish secure communication with Jira using OAuth 2.0 (3LO) and API keys, enabling systems to authenticate and interact with Jira APIs seamlessly. OAuth 2.0 serves as a secure authorization mechanism that allows external applications to access Jira resources on behalf of a user or service account without exposing credentials, while API keys provide an additional method for authenticated requests . By embedding these processes into automation, the installer can dynamically configure credentials, register applications, and connect log sources to Jira, ensuring that system events are automatically transfered to our back-end. This approach not only simplifies deployment but also enhances consistency, scalability, and real-time incident tracking within integrated environments.


Prerequisites:
  • Service User (linux user)
  • Service Group (linux group)
  • Atlassian Cloud ID
  • Atlassian User Email
  • API key

Creating the setup installer

Linux:

  1. Login to the Log Collector.
  2. Open Terminal and type the following commands.
    1. cd Documents
    2. nano setup.sh
  3. Paste this Script.
    1. #!/bin/bash
      # =============================================================================
      # AQUILA - Atlassian Jira Integration Setup Script
      # Automates: API Token Config, Bash Wrapper, Systemd Service/Timer, Logrotate
      # =============================================================================
      
      set -euo pipefail
      
      # -----------------------------------------------
      # Colors for output
      # -----------------------------------------------
      RED='\033[0;31m'
      GREEN='\033[0;32m'
      YELLOW='\033[1;33m'
      CYAN='\033[0;36m'
      NC='\033[0m' # No Color
      
      log_info()    { echo -e "${CYAN}[INFO]${NC}  $1"; }
      log_ok()      { echo -e "${GREEN}[OK]${NC}    $1"; }
      log_warn()    { echo -e "${YELLOW}[WARN]${NC}  $1"; }
      log_error()   { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
      
      # -----------------------------------------------
      # Root check
      # -----------------------------------------------
      if [[ "$EUID" -ne 0 ]]; then
        log_error "Please run this script as root or with sudo."
      fi
      
      # =============================================================================
      # STEP 1: Collect User Inputs
      # =============================================================================
      echo ""
      echo -e "${CYAN}============================================================${NC}"
      echo -e "${CYAN}   AQUILA - Atlassian Jira Integration Setup                ${NC}"
      echo -e "${CYAN}============================================================${NC}"
      echo ""
      
      read -rp "Enter the Linux username to run the service (e.g. testing-jira): " SERVICE_USER
      read -rp "Enter the Linux group for the service user (e.g. testing-jira):   " SERVICE_GROUP
      
      # Validate user exists
      if ! id "$SERVICE_USER" &>/dev/null; then
        log_warn "User '$SERVICE_USER' does not exist. Creating system user..."
        useradd --system --no-create-home --shell /usr/sbin/nologin \
          --comment "AQUILA Jira Service Account" "$SERVICE_USER"
        groupadd --system "$SERVICE_GROUP" 2>/dev/null || true
        usermod -aG "$SERVICE_GROUP" "$SERVICE_USER"
        log_ok "Created system user: $SERVICE_USER"
      fi
      
      HOME_DIR=$(eval echo "~$SERVICE_USER")
      JIRA_DIR="$HOME_DIR/jira"
      
      read -rp "Enter Jira Cloud ID:             " CLOUD_ID
      read -rp "Enter Atlassian Admin Email:      " USER_EMAIL
      read -rsp "Enter API Key (input hidden):    " API_KEY
      echo ""
      read -rp "Enter polling interval in seconds (default 600 for 10 min): " POLL_INTERVAL
      POLL_INTERVAL="${POLL_INTERVAL:-600}"
      
      FLAT_FILE="$JIRA_DIR/flattened.json"
      CHECKPOINT_FILE="$JIRA_DIR/checkpoint.txt"
      LOCK_FILE="/var/lock/jira-events.lock"
      
      # =============================================================================
      # STEP 2: Create Required Directories
      # =============================================================================
      log_info "Creating required directories..."
      
      mkdir -p "$JIRA_DIR"
      chown -R "$SERVICE_USER:$SERVICE_GROUP" "$JIRA_DIR"
      chmod 750 "$JIRA_DIR"
      
      log_ok "Created: $JIRA_DIR"
      
      # =============================================================================
      # STEP 3: Create the Jira Audit Wrapper Script
      # =============================================================================
      log_info "Creating Jira audit wrapper script at /usr/local/bin/jira_audit.sh ..."
      
      cat > /usr/local/bin/jira_audit.sh <<EOF
      #!/bin/bash
      set -euo pipefail
      
      # ----------------------------
      # Config
      # ----------------------------
      FLAT_FILE="${FLAT_FILE}"
      LOCK_FILE="${LOCK_FILE}"
      CHECKPOINT_FILE="${CHECKPOINT_FILE}"
      CLOUD_ID="${CLOUD_ID}"
      USER_EMAIL="${USER_EMAIL}"
      API_KEY="${API_KEY}"
      LIMIT=1000
      OFFSET=0
      BUFFER_SECONDS=120  # 2 min lookback
      
      # Ensure only one instance runs at a time
      exec 200>"\$LOCK_FILE"
      flock -n 200 || exit 1
      
      # ----------------------------
      # Time helpers
      # ----------------------------
      now_iso() {
        date -u +"%Y-%m-%dT%H:%M:%SZ"
      }
      
      iso_to_epoch() {
        date -u -d "\$1" +"%s"
      }
      
      epoch_to_iso() {
        date -u -d "@\$1" +"%Y-%m-%dT%H:%M:%SZ"
      }
      
      # ----------------------------
      # Load checkpoint
      # ----------------------------
      if [[ -f "\$CHECKPOINT_FILE" ]]; then
        LAST_TS=\$(cat "\$CHECKPOINT_FILE")
      else
        LAST_TS=\$(epoch_to_iso 0)
      fi
      
      NOW_TS=\$(now_iso)
      
      # Apply buffer (look back slightly to avoid missing records)
      LAST_EPOCH=\$(iso_to_epoch "\$LAST_TS")
      FROM_EPOCH=\$(( LAST_EPOCH - BUFFER_SECONDS ))
      FROM_TS=\$(epoch_to_iso "\$FROM_EPOCH")
      
      echo "Syncing from \$FROM_TS → \$NOW_TS"
      
      # Temp file for this run
      TMP_FILE=\$(mktemp)
      TOTAL=0
      FETCHED=0
      
      # ----------------------------
      # Pagination loop
      # ----------------------------
      while true; do
        echo "Fetching offset=\$OFFSET..."
        RESPONSE=\$(curl -s --request GET \\
          --url "https://api.atlassian.com/ex/jira/\$CLOUD_ID/rest/api/3/auditing/record?offset=\$OFFSET&limit=\$LIMIT&from=\$FROM_TS&to=\$NOW_TS" \\
          --user "\$USER_EMAIL:\$API_KEY" \\
          --header "Accept: application/json")
      
        # Validate JSON
        if ! echo "\$RESPONSE" | jq . >/dev/null 2>&1; then
          echo "Error: API did not return valid JSON"
          exit 1
        fi
      
        # Extract total once
        if [[ \$TOTAL -eq 0 ]]; then
          TOTAL=\$(echo "\$RESPONSE" | jq '.total // 0')
        fi
      
        COUNT=\$(echo "\$RESPONSE" | jq '(.records // []) | length')
      
        if [[ "\$COUNT" -eq 0 ]]; then
          break
        fi
      
        # Flatten + append to temp
        echo "\$RESPONSE" | jq -c '
          .offset as \$offset
          | .total as \$total
          | (.records // [])[]
          | .offset = \$offset
          | .total = \$total
        ' >> "\$TMP_FILE"
      
        FETCHED=\$(( FETCHED + COUNT ))
        OFFSET=\$(( OFFSET + LIMIT ))
      
        if [[ "\$FETCHED" -ge "\$TOTAL" ]]; then
          break
        fi
      done
      
      # ----------------------------
      # Deduplicate + merge
      # ----------------------------
      if [[ -f "\$FLAT_FILE" ]]; then
        cat "\$FLAT_FILE" "\$TMP_FILE" \\
          | jq -c 'select(.id != null)' \\
          | awk '!seen[\$0]++' \\
          > "\${FLAT_FILE}.tmp"
        mv "\${FLAT_FILE}.tmp" "\$FLAT_FILE"
      else
        cat "\$TMP_FILE" \\
          | jq -c 'select(.id)' \\
          | awk '!seen[\$0]++' \\
          > "\$FLAT_FILE"
      fi
      
      rm "\$TMP_FILE"
      
      # ----------------------------
      # Save checkpoint
      # ----------------------------
      echo "\$NOW_TS" > "\$CHECKPOINT_FILE"
      echo "Synced \$FETCHED records (windowed). Checkpoint → \$NOW_TS"
      EOF
      
      chmod +x /usr/local/bin/jira_audit.sh
      chown "$SERVICE_USER:$SERVICE_GROUP" /usr/local/bin/jira_audit.sh
      log_ok "Wrapper script created and permissions set."
      
      # =============================================================================
      # STEP 4: Create Systemd Service File
      # =============================================================================
      log_info "Creating systemd service file: /etc/systemd/system/jira-audit.service ..."
      
      cat > /etc/systemd/system/jira-audit.service <<EOF
      [Unit]
      Description=Jira Audit Log Fetcher
      After=network.target
      Wants=network-online.target
      
      [Service]
      Type=oneshot
      ExecStart=/usr/local/bin/jira_audit.sh
      
      # Run as your user
      User=${SERVICE_USER}
      WorkingDirectory=${JIRA_DIR}
      
      # Logging
      StandardOutput=journal
      StandardError=journal
      
      # Security (recommended)
      NoNewPrivileges=true
      
      [Install]
      WantedBy=multi-user.target
      EOF
      
      log_ok "Systemd service file created."
      
      # =============================================================================
      # STEP 5: Create Systemd Timer File
      # =============================================================================
      log_info "Creating systemd timer file: /etc/systemd/system/jira-audit.timer ..."
      
      cat > /etc/systemd/system/jira-audit.timer <<EOF
      [Unit]
      Description=Run Atlassian Jira Audit every ${POLL_INTERVAL} seconds
      
      [Timer]
      OnBootSec=60
      OnUnitActiveSec=${POLL_INTERVAL}
      Persistent=true
      Unit=jira-audit.service
      
      [Install]
      WantedBy=timers.target
      EOF
      
      log_ok "Systemd timer file created (interval: ${POLL_INTERVAL}s)."
      
      # =============================================================================
      # STEP 6: Configure Logrotate
      # =============================================================================
      log_info "Configuring logrotate for $FLAT_FILE ..."
      
      cat > /etc/logrotate.d/jira_audit <<EOF
      ${FLAT_FILE} {
          daily
          rotate 7
          missingok
          notifempty
          copytruncate
          compress
          compressoptions -1
          delaycompress
          dateext
          dateformat -%Y%m%d-%H%M%S
          create 0640 ${SERVICE_USER} ${SERVICE_GROUP}
      }
      EOF
      
      log_ok "Logrotate configuration created."
      
      # =============================================================================
      # STEP 7: Enable and Start the Timer
      # =============================================================================
      log_info "Reloading systemd and enabling the jira-audit timer..."
      
      systemctl daemon-reload
      systemctl enable jira-audit.service
      systemctl enable --now jira-audit.timer
      
      log_ok "Timer enabled and started."
      
      # =============================================================================
      # STEP 8: Verify Setup
      # =============================================================================
      echo ""
      log_info "Verifying setup..."
      echo ""
      
      echo -e "${CYAN}--- Active Timers ---${NC}"
      systemctl list-timers --no-pager | grep jira-audit || log_warn "Timer not found in list — check manually."
      
      echo ""
      echo -e "${CYAN}--- Service Status ---${NC}"
      systemctl status jira-audit.service --no-pager || true
      
      # =============================================================================
      # STEP 9: Summary
      # =============================================================================
      echo ""
      echo -e "${GREEN}============================================================${NC}"
      echo -e "${GREEN}   AQUILA Jira Integration Setup Complete!                  ${NC}"
      echo -e "${GREEN}============================================================${NC}"
      echo ""
      echo -e "  ${CYAN}Service User:${NC}       $SERVICE_USER"
      echo -e "  ${CYAN}Jira Directory:${NC}     $JIRA_DIR"
      echo -e "  ${CYAN}Flat File Path:${NC}     $FLAT_FILE"
      echo -e "  ${CYAN}Checkpoint File:${NC}    $CHECKPOINT_FILE"
      echo -e "  ${CYAN}Poll Interval:${NC}      ${POLL_INTERVAL}s"
      echo -e "  ${CYAN}Script Location:${NC}    /usr/local/bin/jira_audit.sh"
      echo -e "  ${CYAN}Service File:${NC}       /etc/systemd/system/jira-audit.service"
      echo -e "  ${CYAN}Timer File:${NC}         /etc/systemd/system/jira-audit.timer"
      echo -e "  ${CYAN}Logrotate Config:${NC}   /etc/logrotate.d/jira_audit"
      echo ""
      echo -e "  ${CYAN}Provide to CyTech:${NC}  $FLAT_FILE"
      echo ""
      echo -e "  Monitor logs with:  ${YELLOW}journalctl -u jira-audit -f${NC}"
      echo ""
      
  4. Save the Script and change it to executable file.
    1. chmod +x setup.sh
  5. Now execute the file in higher privileged.
    1. sudo ./setup.sh
  6. Follow the on screen instruction to fully integrate the system.

If you need further assistance, kindly contact our support at support@cytechint.com for prompt assistance and guidance.