A Kubernetes operator that bridges Hardware Security Module (HSM) data storage with Kubernetes Secrets, providing true secret portability th
1#!/bin/bash
2
3# Import existing Kubernetes Secret to HSM via REST API
4# Usage: ./import-from-k8s.sh [secret-name] [namespace] [target-label] [target-id]
5
6set -e
7
8API_BASE_URL=${API_BASE_URL:-"http://localhost:8090"}
9SOURCE_SECRET=${1:-""}
10SOURCE_NAMESPACE=${2:-"default"}
11TARGET_LABEL=${3:-""}
12TARGET_ID=${4:-"$(date +%s)"}
13
14if [ -z "$SOURCE_SECRET" ]; then
15 echo "Usage: $0 <source-secret-name> [namespace] [target-label] [target-id]"
16 echo ""
17 echo "Available secrets in namespace '$SOURCE_NAMESPACE':"
18 kubectl get secrets -n "$SOURCE_NAMESPACE" --field-selector type=Opaque -o name | sed 's/secret\///'
19 exit 1
20fi
21
22if [ -z "$TARGET_LABEL" ]; then
23 TARGET_LABEL="$SOURCE_SECRET-hsm"
24fi
25
26echo "📦 Importing Kubernetes Secret to HSM..."
27echo "Source Secret: $SOURCE_SECRET"
28echo "Source Namespace: $SOURCE_NAMESPACE"
29echo "Target Label: $TARGET_LABEL"
30echo "Target ID: $TARGET_ID"
31echo "API Base URL: $API_BASE_URL"
32echo ""
33
34# Check if source secret exists
35echo "🔍 Checking source secret..."
36if ! kubectl get secret "$SOURCE_SECRET" -n "$SOURCE_NAMESPACE" >/dev/null 2>&1; then
37 echo "❌ Source secret '$SOURCE_SECRET' not found in namespace '$SOURCE_NAMESPACE'"
38 exit 1
39fi
40
41# Show source secret info
42echo "📋 Source secret info:"
43kubectl describe secret "$SOURCE_SECRET" -n "$SOURCE_NAMESPACE"
44echo ""
45
46# Create the import request payload
47payload=$(cat <<EOF
48{
49 "source": "kubernetes",
50 "secret_name": "$SOURCE_SECRET",
51 "secret_namespace": "$SOURCE_NAMESPACE",
52 "target_label": "$TARGET_LABEL",
53 "target_id": $TARGET_ID,
54 "format": "json",
55 "key_mapping": {
56 "username": "db_username",
57 "password": "db_password"
58 }
59}
60EOF
61)
62
63echo "📝 Import Request:"
64echo "$payload" | jq '.'
65echo ""
66
67# Make the import API call
68echo "📤 Sending import request..."
69response=$(curl -s -X POST \
70 -H "Content-Type: application/json" \
71 -d "$payload" \
72 "$API_BASE_URL/api/v1/hsm/secrets/import")
73
74echo "📥 Response:"
75echo "$response" | jq '.'
76
77# Check if the import was successful
78success=$(echo "$response" | jq -r '.success')
79if [ "$success" = "true" ]; then
80 echo ""
81 echo "✅ Secret imported successfully!"
82
83 # Extract imported secret info
84 label=$(echo "$response" | jq -r '.data.label // "N/A"')
85 id=$(echo "$response" | jq -r '.data.id // "N/A"')
86 path=$(echo "$response" | jq -r '.data.path // "N/A"')
87
88 echo " Target Label: $label"
89 echo " Target ID: $id"
90 echo " HSM Path: $path"
91
92 echo ""
93 echo "🔍 Verification commands:"
94 echo " # Check HSM secret via kubectl plugin:"
95 echo " kubectl hsm get $label"
96 echo ""
97 echo " # Check HSM secret via API:"
98 echo " curl $API_BASE_URL/api/v1/hsm/secrets/$label"
99 echo ""
100 echo " # Check HSMSecret resource:"
101 echo " kubectl get hsmsecret $label"
102 echo ""
103 echo " # Check created Kubernetes Secret:"
104 echo " kubectl get secret $label"
105
106 echo ""
107 echo "📊 Comparison:"
108 echo " Original Secret: kubectl get secret $SOURCE_SECRET -n $SOURCE_NAMESPACE -o yaml"
109 echo " HSM Secret: kubectl get secret $label -o yaml"
110
111else
112 echo ""
113 echo "❌ Failed to import secret!"
114 error_code=$(echo "$response" | jq -r '.error.code // "unknown"')
115 error_message=$(echo "$response" | jq -r '.error.message // "No error message"')
116 echo " Error Code: $error_code"
117 echo " Error Message: $error_message"
118
119 # Show detailed error if available
120 if echo "$response" | jq -e '.error.details' >/dev/null; then
121 echo " Error Details:"
122 echo "$response" | jq '.error.details'
123 fi
124
125 exit 1
126fi