A Kubernetes operator that bridges Hardware Security Module (HSM) data storage with Kubernetes Secrets, providing true secret portability th
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 296 lines 8.6 kB view raw
1#!/bin/bash 2 3# Bulk operations for HSM secrets 4# Automatically uses kubectl-hsm plugin if available, falls back to REST API 5# Usage: ./bulk-operations.sh [operation] [config-file] 6 7set -e 8 9API_BASE_URL=${API_BASE_URL:-"http://localhost:8090"} 10OPERATION=${1:-"create"} 11CONFIG_FILE=${2:-"bulk-secrets.json"} 12 13# Function to create bulk secrets config if it doesn't exist 14create_sample_config() { 15 cat > "$CONFIG_FILE" <<EOF 16{ 17 "secrets": [ 18 { 19 "label": "app1-database", 20 "id": 1001, 21 "format": "json", 22 "description": "Database credentials for app1", 23 "tags": { 24 "app": "app1", 25 "environment": "production", 26 "type": "database" 27 }, 28 "data": { 29 "database_url": "postgresql://app1:password123@db.example.com:5432/app1", 30 "username": "app1", 31 "password": "password123" 32 } 33 }, 34 { 35 "label": "app2-api-keys", 36 "id": 1002, 37 "format": "json", 38 "description": "External API keys for app2", 39 "tags": { 40 "app": "app2", 41 "environment": "production", 42 "type": "api-keys" 43 }, 44 "data": { 45 "stripe_key": "sk_live_example123", 46 "sendgrid_key": "SG.example456", 47 "aws_access_key": "AKIA1234567890" 48 } 49 }, 50 { 51 "label": "shared-tls-cert", 52 "id": 1003, 53 "format": "text", 54 "description": "Shared TLS certificate", 55 "tags": { 56 "type": "tls", 57 "scope": "shared", 58 "environment": "production" 59 }, 60 "data": { 61 "tls.crt": "-----BEGIN CERTIFICATE-----\\nMIIC...\\n-----END CERTIFICATE-----", 62 "tls.key": "-----BEGIN PRIVATE KEY-----\\nMIIE...\\n-----END PRIVATE KEY-----" 63 } 64 } 65 ] 66} 67EOF 68 echo "📝 Created sample config file: $CONFIG_FILE" 69} 70 71# Function to create a single secret 72create_secret() { 73 local secret_data="$1" 74 local label=$(echo "$secret_data" | jq -r '.label') 75 76 echo " Creating secret: $label" 77 78 # Try using kubectl-hsm first if available, fallback to API 79 if command -v kubectl >/dev/null && kubectl hsm --help >/dev/null 2>&1; then 80 # Convert secret_data to create command format 81 local temp_file=$(mktemp) 82 echo "$secret_data" | jq '.data' > "$temp_file" 83 84 if kubectl hsm create "$label" --from-file="$temp_file" >/dev/null 2>&1; then 85 rm "$temp_file" 86 echo " ✅ Created successfully (kubectl-hsm)" 87 return 0 88 else 89 rm "$temp_file" 90 echo " ⚠️ kubectl-hsm failed, trying API..." 91 fi 92 fi 93 94 # Fallback to API 95 response=$(curl -s -X POST \ 96 -H "Content-Type: application/json" \ 97 -d "$secret_data" \ 98 "$API_BASE_URL/api/v1/hsm/secrets") 99 100 success=$(echo "$response" | jq -r '.success') 101 if [ "$success" = "true" ]; then 102 echo " ✅ Created successfully (API)" 103 return 0 104 else 105 error_message=$(echo "$response" | jq -r '.error.message // "Unknown error"') 106 echo " ❌ Failed: $error_message" 107 return 1 108 fi 109} 110 111# Function to delete a secret 112delete_secret() { 113 local label="$1" 114 115 echo " Deleting secret: $label" 116 117 # Try using kubectl-hsm first if available, fallback to API 118 if command -v kubectl >/dev/null && kubectl hsm --help >/dev/null 2>&1; then 119 if kubectl hsm delete "$label" --force >/dev/null 2>&1; then 120 echo " ✅ Deleted successfully (kubectl-hsm)" 121 return 0 122 else 123 echo " ⚠️ kubectl-hsm failed, trying API..." 124 fi 125 fi 126 127 # Fallback to API 128 response=$(curl -s -X DELETE "$API_BASE_URL/api/v1/hsm/secrets/$label") 129 130 success=$(echo "$response" | jq -r '.success') 131 if [ "$success" = "true" ]; then 132 echo " ✅ Deleted successfully (API)" 133 return 0 134 else 135 error_message=$(echo "$response" | jq -r '.error.message // "Unknown error"') 136 echo " ❌ Failed: $error_message" 137 return 1 138 fi 139} 140 141# Function to get secret info 142get_secret() { 143 local label="$1" 144 145 # Try using kubectl-hsm first if available, fallback to API 146 if command -v kubectl >/dev/null && kubectl hsm --help >/dev/null 2>&1; then 147 if kubectl hsm get "$label" >/dev/null 2>&1; then 148 echo "$label (available via kubectl-hsm)" 149 return 0 150 fi 151 fi 152 153 # Fallback to API for detailed status 154 response=$(curl -s "$API_BASE_URL/api/v1/hsm/secrets/$label") 155 success=$(echo "$response" | jq -r '.success') 156 157 if [ "$success" = "true" ]; then 158 checksum=$(echo "$response" | jq -r '.data.metadata.checksum[0:8]') 159 replicated=$(echo "$response" | jq -r '.data.metadata.is_replicated') 160 echo "$label (checksum: $checksum, replicated: $replicated)" 161 return 0 162 else 163 echo "$label (not found or error)" 164 return 1 165 fi 166} 167 168echo "🔄 HSM Secrets Bulk Operations" 169echo "Operation: $OPERATION" 170echo "Config File: $CONFIG_FILE" 171echo "API Base URL: $API_BASE_URL" 172echo "" 173 174# Check if config file exists 175if [ ! -f "$CONFIG_FILE" ]; then 176 echo "⚠️ Config file not found. Creating sample..." 177 create_sample_config 178 echo "" 179fi 180 181# Validate config file 182if ! jq empty "$CONFIG_FILE" 2>/dev/null; then 183 echo "❌ Invalid JSON in config file: $CONFIG_FILE" 184 exit 1 185fi 186 187# Extract secret labels for operations 188secret_labels=$(jq -r '.secrets[].label' "$CONFIG_FILE") 189secret_count=$(echo "$secret_labels" | wc -l) 190 191echo "📊 Found $secret_count secrets in config file" 192echo "" 193 194case "$OPERATION" in 195 "create") 196 echo "🔐 Creating secrets..." 197 success_count=0 198 failure_count=0 199 200 # Process each secret 201 while IFS= read -r secret_json; do 202 if create_secret "$secret_json"; then 203 ((success_count++)) 204 else 205 ((failure_count++)) 206 fi 207 done < <(jq -c '.secrets[]' "$CONFIG_FILE") 208 209 echo "" 210 echo "📈 Results:" 211 echo " ✅ Successful: $success_count" 212 echo " ❌ Failed: $failure_count" 213 ;; 214 215 "delete") 216 echo "🗑️ Deleting secrets..." 217 success_count=0 218 failure_count=0 219 220 # Delete each secret 221 while IFS= read -r label; do 222 if delete_secret "$label"; then 223 ((success_count++)) 224 else 225 ((failure_count++)) 226 fi 227 done <<< "$secret_labels" 228 229 echo "" 230 echo "📈 Results:" 231 echo " ✅ Deleted: $success_count" 232 echo " ❌ Failed: $failure_count" 233 ;; 234 235 "status") 236 echo "📊 Checking secret status..." 237 available_count=0 238 missing_count=0 239 240 # Check each secret 241 while IFS= read -r label; do 242 if get_secret "$label"; then 243 ((available_count++)) 244 else 245 ((missing_count++)) 246 fi 247 done <<< "$secret_labels" 248 249 echo "" 250 echo "📈 Results:" 251 echo " ✅ Available: $available_count" 252 echo " ❌ Missing: $missing_count" 253 ;; 254 255 "backup") 256 echo "💾 Backing up secrets..." 257 backup_file="secrets-backup-$(date +%Y%m%d-%H%M%S).json" 258 259 echo '{"secrets": [' > "$backup_file" 260 first=true 261 262 while IFS= read -r label; do 263 response=$(curl -s "$API_BASE_URL/api/v1/hsm/secrets/$label") 264 success=$(echo "$response" | jq -r '.success') 265 266 if [ "$success" = "true" ]; then 267 if [ "$first" = true ]; then 268 first=false 269 else 270 echo "," >> "$backup_file" 271 fi 272 echo "$response" | jq '.data' >> "$backup_file" 273 echo " ✅ Backed up: $label" 274 else 275 echo " ❌ Failed to backup: $label" 276 fi 277 done <<< "$secret_labels" 278 279 echo ']}' >> "$backup_file" 280 echo "" 281 echo "📁 Backup saved to: $backup_file" 282 ;; 283 284 *) 285 echo "❌ Unknown operation: $OPERATION" 286 echo "" 287 echo "Available operations:" 288 echo " create - Create all secrets from config file" 289 echo " delete - Delete all secrets from config file" 290 echo " status - Check status of all secrets" 291 echo " backup - Backup all secrets to file" 292 echo "" 293 echo "Usage: $0 [operation] [config-file]" 294 exit 1 295 ;; 296esac