fix tests. new product advisories enhancements
This commit is contained in:
150
devops/trust-repo-template/scripts/add-target.sh
Normal file
150
devops/trust-repo-template/scripts/add-target.sh
Normal file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# add-target.sh
|
||||
# Sprint: SPRINT_20260125_001_Attestor_tuf_trust_foundation
|
||||
# Task: TUF-006 - Create TUF repository structure template
|
||||
# Description: Add a new target file to the TUF repository
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 <source-file> <target-name> [options]"
|
||||
echo ""
|
||||
echo "Add a target file to the TUF repository."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --repo DIR Repository directory (default: current directory)"
|
||||
echo " --custom-hash HASH Override SHA256 hash (for testing only)"
|
||||
echo " -h, --help Show this help message"
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo " $0 /path/to/rekor-key.pub rekor-key-v1"
|
||||
echo " $0 /path/to/services.json sigstore-services-v1 --repo /var/lib/tuf"
|
||||
exit 1
|
||||
}
|
||||
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
SOURCE_FILE=""
|
||||
TARGET_NAME=""
|
||||
REPO_DIR="."
|
||||
CUSTOM_HASH=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--repo)
|
||||
REPO_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--custom-hash)
|
||||
CUSTOM_HASH="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
if [[ -z "$SOURCE_FILE" ]]; then
|
||||
SOURCE_FILE="$1"
|
||||
elif [[ -z "$TARGET_NAME" ]]; then
|
||||
TARGET_NAME="$1"
|
||||
else
|
||||
log_error "Unknown argument: $1"
|
||||
usage
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$SOURCE_FILE" ]] || [[ -z "$TARGET_NAME" ]]; then
|
||||
log_error "Source file and target name are required"
|
||||
usage
|
||||
fi
|
||||
|
||||
if [[ ! -f "$SOURCE_FILE" ]]; then
|
||||
log_error "Source file not found: $SOURCE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$REPO_DIR/targets.json" ]]; then
|
||||
log_error "Not a TUF repository: $REPO_DIR (targets.json not found)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Calculate file hash and size
|
||||
FILE_SIZE=$(stat -f%z "$SOURCE_FILE" 2>/dev/null || stat -c%s "$SOURCE_FILE")
|
||||
if [[ -n "$CUSTOM_HASH" ]]; then
|
||||
FILE_HASH="$CUSTOM_HASH"
|
||||
else
|
||||
FILE_HASH=$(openssl dgst -sha256 -hex "$SOURCE_FILE" | awk '{print $2}')
|
||||
fi
|
||||
|
||||
log_info "Adding target: $TARGET_NAME"
|
||||
log_info " Source: $SOURCE_FILE"
|
||||
log_info " Size: $FILE_SIZE bytes"
|
||||
log_info " SHA256: $FILE_HASH"
|
||||
|
||||
# Copy file to targets directory
|
||||
TARGETS_DIR="$REPO_DIR/targets"
|
||||
mkdir -p "$TARGETS_DIR"
|
||||
cp "$SOURCE_FILE" "$TARGETS_DIR/$TARGET_NAME"
|
||||
|
||||
# Update targets.json
|
||||
# This is a simplified implementation - production should use proper JSON manipulation
|
||||
TARGETS_JSON="$REPO_DIR/targets.json"
|
||||
|
||||
# Read current version
|
||||
CURRENT_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*[0-9]*' "$TARGETS_JSON" | head -1 | grep -o '[0-9]*')
|
||||
NEW_VERSION=$((CURRENT_VERSION + 1))
|
||||
|
||||
# Calculate new expiry (30 days from now)
|
||||
NEW_EXPIRES=$(date -u -d "+30 days" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v+30d +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
log_info "Updating targets.json (version $CURRENT_VERSION -> $NEW_VERSION)"
|
||||
|
||||
# Create new targets entry
|
||||
python3 - "$TARGETS_JSON" "$TARGET_NAME" "$FILE_SIZE" "$FILE_HASH" "$NEW_VERSION" "$NEW_EXPIRES" << 'PYTHON_SCRIPT'
|
||||
import json
|
||||
import sys
|
||||
|
||||
targets_file = sys.argv[1]
|
||||
target_name = sys.argv[2]
|
||||
file_size = int(sys.argv[3])
|
||||
file_hash = sys.argv[4]
|
||||
new_version = int(sys.argv[5])
|
||||
new_expires = sys.argv[6]
|
||||
|
||||
with open(targets_file, 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
data['signed']['version'] = new_version
|
||||
data['signed']['expires'] = new_expires
|
||||
data['signed']['targets'][target_name] = {
|
||||
'length': file_size,
|
||||
'hashes': {
|
||||
'sha256': file_hash
|
||||
}
|
||||
}
|
||||
|
||||
# Clear signatures (need to re-sign)
|
||||
data['signatures'] = []
|
||||
|
||||
with open(targets_file, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
print(f"Updated {targets_file}")
|
||||
PYTHON_SCRIPT
|
||||
|
||||
log_info ""
|
||||
log_info "Target added successfully!"
|
||||
log_warn "IMPORTANT: targets.json signatures have been cleared."
|
||||
log_warn "Run the signing script to re-sign metadata before publishing."
|
||||
Reference in New Issue
Block a user