Initial commit: Particle-OS tools repository
- Complete Particle-OS rebranding from uBlue-OS - Professional installation system with standardized paths - Self-initialization system with --init and --reset commands - Enhanced error messages and dependency checking - Comprehensive testing infrastructure - All source scriptlets updated with runtime improvements - Clean codebase with redundant files moved to archive - Complete documentation suite
This commit is contained in:
commit
74c7bede5f
125 changed files with 66318 additions and 0 deletions
641
src/apt-layer/scriptlets/15-multi-tenant.sh
Normal file
641
src/apt-layer/scriptlets/15-multi-tenant.sh
Normal file
|
|
@ -0,0 +1,641 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Multi-Tenant Support for apt-layer
|
||||
# Enables enterprise deployments with multiple organizations, departments, or environments
|
||||
# Provides tenant isolation, resource quotas, and cross-tenant management
|
||||
|
||||
# Multi-tenant configuration
|
||||
MULTI_TENANT_ENABLED="${MULTI_TENANT_ENABLED:-false}"
|
||||
TENANT_ISOLATION_LEVEL="${TENANT_ISOLATION_LEVEL:-strict}" # strict, moderate, permissive
|
||||
TENANT_RESOURCE_QUOTAS="${TENANT_RESOURCE_QUOTAS:-true}"
|
||||
TENANT_CROSS_ACCESS="${TENANT_CROSS_ACCESS:-false}"
|
||||
|
||||
# Tenant management functions
|
||||
init_multi_tenant_system() {
|
||||
log_info "Initializing multi-tenant system..." "multi-tenant"
|
||||
|
||||
# Create tenant directories
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
mkdir -p "$tenant_base"
|
||||
mkdir -p "$tenant_base/shared"
|
||||
mkdir -p "$tenant_base/templates"
|
||||
|
||||
# Initialize tenant database
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
if [[ ! -f "$tenant_db" ]]; then
|
||||
cat > "$tenant_db" << 'EOF'
|
||||
{
|
||||
"tenants": [],
|
||||
"policies": {
|
||||
"default_isolation": "strict",
|
||||
"default_quotas": {
|
||||
"max_layers": 100,
|
||||
"max_storage_gb": 50,
|
||||
"max_users": 10
|
||||
},
|
||||
"cross_tenant_access": false
|
||||
},
|
||||
"metadata": {
|
||||
"created": "",
|
||||
"version": "1.0"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
# Set creation timestamp
|
||||
jq --arg created "$(date -Iseconds)" '.metadata.created = $created' "$tenant_db" > "$tenant_db.tmp" && mv "$tenant_db.tmp" "$tenant_db"
|
||||
fi
|
||||
|
||||
log_success "Multi-tenant system initialized" "multi-tenant"
|
||||
}
|
||||
|
||||
# Tenant creation and management
|
||||
create_tenant() {
|
||||
local tenant_name="$1"
|
||||
local tenant_config="$2"
|
||||
|
||||
if [[ -z "$tenant_name" ]]; then
|
||||
log_error "Tenant name is required" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Validate tenant name
|
||||
if [[ ! "$tenant_name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
||||
log_error "Invalid tenant name: $tenant_name (use alphanumeric, underscore, hyphen only)" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
local tenant_dir="$tenant_base/$tenant_name"
|
||||
|
||||
# Check if tenant already exists
|
||||
if jq -e ".tenants[] | select(.name == \"$tenant_name\")" "$tenant_db" > /dev/null 2>&1; then
|
||||
log_error "Tenant '$tenant_name' already exists" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create tenant directory structure
|
||||
mkdir -p "$tenant_dir"
|
||||
mkdir -p "$tenant_dir/layers"
|
||||
mkdir -p "$tenant_dir/deployments"
|
||||
mkdir -p "$tenant_dir/users"
|
||||
mkdir -p "$tenant_dir/audit"
|
||||
mkdir -p "$tenant_dir/backups"
|
||||
mkdir -p "$tenant_dir/config"
|
||||
|
||||
# Create tenant configuration
|
||||
local tenant_config_file="$tenant_dir/config/tenant.json"
|
||||
cat > "$tenant_config_file" << EOF
|
||||
{
|
||||
"name": "$tenant_name",
|
||||
"created": "$(date -Iseconds)",
|
||||
"status": "active",
|
||||
"isolation_level": "$TENANT_ISOLATION_LEVEL",
|
||||
"quotas": {
|
||||
"max_layers": 100,
|
||||
"max_storage_gb": 50,
|
||||
"max_users": 10,
|
||||
"used_layers": 0,
|
||||
"used_storage_gb": 0,
|
||||
"used_users": 0
|
||||
},
|
||||
"policies": {
|
||||
"allowed_packages": [],
|
||||
"blocked_packages": [],
|
||||
"security_level": "standard",
|
||||
"audit_retention_days": 90
|
||||
},
|
||||
"integrations": {
|
||||
"oci_registries": [],
|
||||
"external_audit": null,
|
||||
"monitoring": null
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Merge custom configuration if provided
|
||||
if [[ -n "$tenant_config" && -f "$tenant_config" ]]; then
|
||||
if jq empty "$tenant_config" 2>/dev/null; then
|
||||
jq -s '.[0] * .[1]' "$tenant_config_file" "$tenant_config" > "$tenant_config_file.tmp" && mv "$tenant_config_file.tmp" "$tenant_config_file"
|
||||
else
|
||||
log_warning "Invalid JSON in tenant configuration, using defaults" "multi-tenant"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Add tenant to database
|
||||
local tenant_info
|
||||
tenant_info=$(jq -r '.' "$tenant_config_file")
|
||||
jq --arg name "$tenant_name" --argjson info "$tenant_info" '.tenants += [$info]' "$tenant_db" > "$tenant_db.tmp" && mv "$tenant_db.tmp" "$tenant_db"
|
||||
|
||||
log_success "Tenant '$tenant_name' created successfully" "multi-tenant"
|
||||
log_info "Tenant directory: $tenant_dir" "multi-tenant"
|
||||
}
|
||||
|
||||
# Tenant deletion
|
||||
delete_tenant() {
|
||||
local tenant_name="$1"
|
||||
local force="${2:-false}"
|
||||
|
||||
if [[ -z "$tenant_name" ]]; then
|
||||
log_error "Tenant name is required" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
local tenant_dir="$tenant_base/$tenant_name"
|
||||
|
||||
# Check if tenant exists
|
||||
if ! jq -e ".tenants[] | select(.name == \"$tenant_name\")" "$tenant_db" > /dev/null 2>&1; then
|
||||
log_error "Tenant '$tenant_name' does not exist" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check for active resources
|
||||
local active_layers=0
|
||||
local active_deployments=0
|
||||
|
||||
if [[ -d "$tenant_dir/layers" ]]; then
|
||||
active_layers=$(find "$tenant_dir/layers" -name "*.squashfs" 2>/dev/null | wc -l)
|
||||
fi
|
||||
|
||||
if [[ -d "$tenant_dir/deployments" ]]; then
|
||||
active_deployments=$(find "$tenant_dir/deployments" -name "*.json" 2>/dev/null | wc -l)
|
||||
fi
|
||||
|
||||
if [[ $active_layers -gt 0 || $active_deployments -gt 0 ]]; then
|
||||
if [[ "$force" != "true" ]]; then
|
||||
log_error "Tenant '$tenant_name' has active resources ($active_layers layers, $active_deployments deployments)" "multi-tenant"
|
||||
log_error "Use --force to delete anyway" "multi-tenant"
|
||||
return 1
|
||||
else
|
||||
log_warning "Force deleting tenant with active resources" "multi-tenant"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove from database
|
||||
jq --arg name "$tenant_name" 'del(.tenants[] | select(.name == $name))' "$tenant_db" > "$tenant_db.tmp" && mv "$tenant_db.tmp" "$tenant_db"
|
||||
|
||||
# Remove tenant directory
|
||||
if [[ -d "$tenant_dir" ]]; then
|
||||
rm -rf "$tenant_dir"
|
||||
fi
|
||||
|
||||
log_success "Tenant '$tenant_name' deleted successfully" "multi-tenant"
|
||||
}
|
||||
|
||||
# Tenant listing and information
|
||||
list_tenants() {
|
||||
local format="${1:-table}"
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
|
||||
if [[ ! -f "$tenant_db" ]]; then
|
||||
log_error "Tenant database not found" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
case "$format" in
|
||||
"json")
|
||||
jq -r '.' "$tenant_db"
|
||||
;;
|
||||
"csv")
|
||||
echo "name,status,created,layers,storage_gb,users"
|
||||
jq -r '.tenants[] | [.name, .status, .created, .quotas.used_layers, .quotas.used_storage_gb, .quotas.used_users] | @csv' "$tenant_db"
|
||||
;;
|
||||
"table"|*)
|
||||
echo "Tenants:"
|
||||
echo "========"
|
||||
jq -r '.tenants[] | "\(.name) (\(.status)) - Layers: \(.quotas.used_layers)/\(.quotas.max_layers), Storage: \(.quotas.used_storage_gb)GB/\(.quotas.max_storage_gb)GB"' "$tenant_db"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Tenant information
|
||||
get_tenant_info() {
|
||||
local tenant_name="$1"
|
||||
local format="${2:-json}"
|
||||
|
||||
if [[ -z "$tenant_name" ]]; then
|
||||
log_error "Tenant name is required" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
|
||||
local tenant_info
|
||||
tenant_info=$(jq -r ".tenants[] | select(.name == \"$tenant_name\")" "$tenant_db" 2>/dev/null)
|
||||
|
||||
if [[ -z "$tenant_info" ]]; then
|
||||
log_error "Tenant '$tenant_name' not found" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
case "$format" in
|
||||
"json")
|
||||
echo "$tenant_info"
|
||||
;;
|
||||
"yaml")
|
||||
echo "$tenant_info" | jq -r '.' | sed 's/^/ /'
|
||||
;;
|
||||
"summary")
|
||||
local name status created layers storage users
|
||||
name=$(echo "$tenant_info" | jq -r '.name')
|
||||
status=$(echo "$tenant_info" | jq -r '.status')
|
||||
created=$(echo "$tenant_info" | jq -r '.created')
|
||||
layers=$(echo "$tenant_info" | jq -r '.quotas.used_layers')
|
||||
storage=$(echo "$tenant_info" | jq -r '.quotas.used_storage_gb')
|
||||
users=$(echo "$tenant_info" | jq -r '.quotas.used_users')
|
||||
|
||||
echo "Tenant: $name"
|
||||
echo "Status: $status"
|
||||
echo "Created: $created"
|
||||
echo "Resources: $layers layers, ${storage}GB storage, $users users"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Tenant quota management
|
||||
update_tenant_quotas() {
|
||||
local tenant_name="$1"
|
||||
local quota_type="$2"
|
||||
local value="$3"
|
||||
|
||||
if [[ -z "$tenant_name" || -z "$quota_type" || -z "$value" ]]; then
|
||||
log_error "Usage: update_tenant_quotas <tenant> <quota_type> <value>" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
|
||||
# Validate quota type
|
||||
case "$quota_type" in
|
||||
"max_layers"|"max_storage_gb"|"max_users")
|
||||
;;
|
||||
*)
|
||||
log_error "Invalid quota type: $quota_type" "multi-tenant"
|
||||
log_error "Valid types: max_layers, max_storage_gb, max_users" "multi-tenant"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Update quota
|
||||
jq --arg name "$tenant_name" --arg type "$quota_type" --arg value "$value" \
|
||||
'.tenants[] | select(.name == $name) | .quotas[$type] = ($value | tonumber)' "$tenant_db" > "$tenant_db.tmp" && mv "$tenant_db.tmp" "$tenant_db"
|
||||
|
||||
log_success "Updated quota for tenant '$tenant_name': $quota_type = $value" "multi-tenant"
|
||||
}
|
||||
|
||||
# Tenant isolation and access control
|
||||
check_tenant_access() {
|
||||
local tenant_name="$1"
|
||||
local user="$2"
|
||||
local operation="$3"
|
||||
|
||||
if [[ -z "$tenant_name" || -z "$user" || -z "$operation" ]]; then
|
||||
log_error "Usage: check_tenant_access <tenant> <user> <operation>" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
|
||||
# Check if tenant exists
|
||||
if ! jq -e ".tenants[] | select(.name == \"$tenant_name\")" "$tenant_db" > /dev/null 2>&1; then
|
||||
log_error "Tenant '$tenant_name' not found" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get tenant isolation level
|
||||
local isolation_level
|
||||
isolation_level=$(jq -r ".tenants[] | select(.name == \"$tenant_name\") | .isolation_level" "$tenant_db")
|
||||
|
||||
# Check user access (simplified - in real implementation, this would check user roles)
|
||||
local user_file="$tenant_base/$tenant_name/users/$user.json"
|
||||
if [[ ! -f "$user_file" ]]; then
|
||||
log_error "User '$user' not found in tenant '$tenant_name'" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check operation permissions
|
||||
local user_role
|
||||
user_role=$(jq -r '.role' "$user_file" 2>/dev/null)
|
||||
|
||||
case "$operation" in
|
||||
"read")
|
||||
[[ "$user_role" =~ ^(admin|package_manager|viewer)$ ]] && return 0
|
||||
;;
|
||||
"write")
|
||||
[[ "$user_role" =~ ^(admin|package_manager)$ ]] && return 0
|
||||
;;
|
||||
"admin")
|
||||
[[ "$user_role" == "admin" ]] && return 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown operation: $operation" "multi-tenant"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
log_error "Access denied: User '$user' with role '$user_role' cannot perform '$operation' operation" "multi-tenant"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Tenant resource usage tracking
|
||||
update_tenant_usage() {
|
||||
local tenant_name="$1"
|
||||
local resource_type="$2"
|
||||
local amount="$3"
|
||||
|
||||
if [[ -z "$tenant_name" || -z "$resource_type" || -z "$amount" ]]; then
|
||||
log_error "Usage: update_tenant_usage <tenant> <resource_type> <amount>" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
|
||||
# Update usage
|
||||
jq --arg name "$tenant_name" --arg type "$resource_type" --arg amount "$amount" \
|
||||
'.tenants[] | select(.name == $name) | .quotas["used_" + $type] = (.quotas["used_" + $type] + ($amount | tonumber))' "$tenant_db" > "$tenant_db.tmp" && mv "$tenant_db.tmp" "$tenant_db"
|
||||
|
||||
log_debug "Updated usage for tenant '$tenant_name': $resource_type += $amount" "multi-tenant"
|
||||
}
|
||||
|
||||
# Tenant quota enforcement
|
||||
enforce_tenant_quotas() {
|
||||
local tenant_name="$1"
|
||||
local resource_type="$2"
|
||||
local requested_amount="$3"
|
||||
|
||||
if [[ -z "$tenant_name" || -z "$resource_type" || -z "$requested_amount" ]]; then
|
||||
log_error "Usage: enforce_tenant_quotas <tenant> <resource_type> <amount>" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
|
||||
# Get current usage and quota
|
||||
local current_usage max_quota
|
||||
current_usage=$(jq -r ".tenants[] | select(.name == \"$tenant_name\") | .quotas.used_$resource_type" "$tenant_db")
|
||||
max_quota=$(jq -r ".tenants[] | select(.name == \"$tenant_name\") | .quotas.max_$resource_type" "$tenant_db")
|
||||
|
||||
# Check if request would exceed quota
|
||||
local new_total=$((current_usage + requested_amount))
|
||||
if [[ $new_total -gt $max_quota ]]; then
|
||||
log_error "Quota exceeded for tenant '$tenant_name': $resource_type" "multi-tenant"
|
||||
log_error "Current: $current_usage, Requested: $requested_amount, Max: $max_quota" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Cross-tenant operations (when enabled)
|
||||
cross_tenant_operation() {
|
||||
local source_tenant="$1"
|
||||
local target_tenant="$2"
|
||||
local operation="$3"
|
||||
local user="$4"
|
||||
|
||||
if [[ "$TENANT_CROSS_ACCESS" != "true" ]]; then
|
||||
log_error "Cross-tenant operations are disabled" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -z "$source_tenant" || -z "$target_tenant" || -z "$operation" || -z "$user" ]]; then
|
||||
log_error "Usage: cross_tenant_operation <source> <target> <operation> <user>" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check user has admin access to both tenants
|
||||
if ! check_tenant_access "$source_tenant" "$user" "admin"; then
|
||||
log_error "User '$user' lacks admin access to source tenant '$source_tenant'" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! check_tenant_access "$target_tenant" "$user" "admin"; then
|
||||
log_error "User '$user' lacks admin access to target tenant '$target_tenant'" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Cross-tenant operation: $operation from '$source_tenant' to '$target_tenant' by '$user'" "multi-tenant"
|
||||
|
||||
# Implement specific cross-tenant operations here
|
||||
case "$operation" in
|
||||
"copy_layer")
|
||||
# Copy layer from source to target tenant
|
||||
log_info "Copying layer between tenants..." "multi-tenant"
|
||||
;;
|
||||
"sync_config")
|
||||
# Sync configuration between tenants
|
||||
log_info "Syncing configuration between tenants..." "multi-tenant"
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown cross-tenant operation: $operation" "multi-tenant"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Tenant backup and restore
|
||||
backup_tenant() {
|
||||
local tenant_name="$1"
|
||||
local backup_path="$2"
|
||||
|
||||
if [[ -z "$tenant_name" ]]; then
|
||||
log_error "Tenant name is required" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_dir="$tenant_base/$tenant_name"
|
||||
|
||||
if [[ ! -d "$tenant_dir" ]]; then
|
||||
log_error "Tenant directory not found: $tenant_dir" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create backup
|
||||
local backup_file
|
||||
if [[ -n "$backup_path" ]]; then
|
||||
backup_file="$backup_path"
|
||||
else
|
||||
backup_file="$tenant_dir/backups/tenant-${tenant_name}-$(date +%Y%m%d-%H%M%S).tar.gz"
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$backup_file")"
|
||||
|
||||
tar -czf "$backup_file" -C "$tenant_base" "$tenant_name"
|
||||
|
||||
log_success "Tenant '$tenant_name' backed up to: $backup_file" "multi-tenant"
|
||||
}
|
||||
|
||||
restore_tenant() {
|
||||
local backup_file="$1"
|
||||
local tenant_name="$2"
|
||||
|
||||
if [[ -z "$backup_file" || -z "$tenant_name" ]]; then
|
||||
log_error "Usage: restore_tenant <backup_file> <tenant_name>" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$backup_file" ]]; then
|
||||
log_error "Backup file not found: $backup_file" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_dir="$tenant_base/$tenant_name"
|
||||
|
||||
# Check if tenant already exists
|
||||
if [[ -d "$tenant_dir" ]]; then
|
||||
log_error "Tenant '$tenant_name' already exists. Delete it first or use a different name." "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Restore tenant
|
||||
tar -xzf "$backup_file" -C "$tenant_base"
|
||||
|
||||
log_success "Tenant '$tenant_name' restored from: $backup_file" "multi-tenant"
|
||||
}
|
||||
|
||||
# Tenant health check
|
||||
check_tenant_health() {
|
||||
local tenant_name="$1"
|
||||
|
||||
if [[ -z "$tenant_name" ]]; then
|
||||
log_error "Tenant name is required" "multi-tenant"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local tenant_base="${WORKSPACE}/tenants"
|
||||
local tenant_dir="$tenant_base/$tenant_name"
|
||||
local tenant_db="$tenant_base/tenants.json"
|
||||
|
||||
echo "Tenant Health Check: $tenant_name"
|
||||
echo "================================"
|
||||
|
||||
# Check tenant exists
|
||||
if [[ ! -d "$tenant_dir" ]]; then
|
||||
echo "❌ Tenant directory not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! jq -e ".tenants[] | select(.name == \"$tenant_name\")" "$tenant_db" > /dev/null 2>&1; then
|
||||
echo "❌ Tenant not found in database"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "✅ Tenant exists"
|
||||
|
||||
# Check directory structure
|
||||
local missing_dirs=()
|
||||
for dir in layers deployments users audit backups config; do
|
||||
if [[ ! -d "$tenant_dir/$dir" ]]; then
|
||||
missing_dirs+=("$dir")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#missing_dirs[@]} -gt 0 ]]; then
|
||||
echo "⚠️ Missing directories: ${missing_dirs[*]}"
|
||||
else
|
||||
echo "✅ Directory structure complete"
|
||||
fi
|
||||
|
||||
# Check quota usage
|
||||
local tenant_info
|
||||
tenant_info=$(jq -r ".tenants[] | select(.name == \"$tenant_name\")" "$tenant_db")
|
||||
|
||||
local layers_used layers_max storage_used storage_max
|
||||
layers_used=$(echo "$tenant_info" | jq -r '.quotas.used_layers')
|
||||
layers_max=$(echo "$tenant_info" | jq -r '.quotas.max_layers')
|
||||
storage_used=$(echo "$tenant_info" | jq -r '.quotas.used_storage_gb')
|
||||
storage_max=$(echo "$tenant_info" | jq -r '.quotas.max_storage_gb')
|
||||
|
||||
echo "📊 Resource Usage:"
|
||||
echo " Layers: $layers_used/$layers_max"
|
||||
echo " Storage: ${storage_used}GB/${storage_max}GB"
|
||||
|
||||
# Check for quota warnings
|
||||
local layer_percent=$((layers_used * 100 / layers_max))
|
||||
local storage_percent=$((storage_used * 100 / storage_max))
|
||||
|
||||
if [[ $layer_percent -gt 80 ]]; then
|
||||
echo "⚠️ Layer quota usage high: ${layer_percent}%"
|
||||
fi
|
||||
|
||||
if [[ $storage_percent -gt 80 ]]; then
|
||||
echo "⚠️ Storage quota usage high: ${storage_percent}%"
|
||||
fi
|
||||
|
||||
echo "✅ Tenant health check complete"
|
||||
}
|
||||
|
||||
# Multi-tenant command handler
|
||||
handle_multi_tenant_command() {
|
||||
local command="$1"
|
||||
shift
|
||||
|
||||
case "$command" in
|
||||
"init")
|
||||
init_multi_tenant_system
|
||||
;;
|
||||
"create")
|
||||
local tenant_name="$1"
|
||||
local config_file="$2"
|
||||
create_tenant "$tenant_name" "$config_file"
|
||||
;;
|
||||
"delete")
|
||||
local tenant_name="$1"
|
||||
local force="$2"
|
||||
delete_tenant "$tenant_name" "$force"
|
||||
;;
|
||||
"list")
|
||||
local format="$1"
|
||||
list_tenants "$format"
|
||||
;;
|
||||
"info")
|
||||
local tenant_name="$1"
|
||||
local format="$2"
|
||||
get_tenant_info "$tenant_name" "$format"
|
||||
;;
|
||||
"quota")
|
||||
local tenant_name="$1"
|
||||
local quota_type="$2"
|
||||
local value="$3"
|
||||
update_tenant_quotas "$tenant_name" "$quota_type" "$value"
|
||||
;;
|
||||
"backup")
|
||||
local tenant_name="$1"
|
||||
local backup_path="$2"
|
||||
backup_tenant "$tenant_name" "$backup_path"
|
||||
;;
|
||||
"restore")
|
||||
local backup_file="$1"
|
||||
local tenant_name="$2"
|
||||
restore_tenant "$backup_file" "$tenant_name"
|
||||
;;
|
||||
"health")
|
||||
local tenant_name="$1"
|
||||
check_tenant_health "$tenant_name"
|
||||
;;
|
||||
"help"|*)
|
||||
echo "Multi-Tenant Commands:"
|
||||
echo "====================="
|
||||
echo " init - Initialize multi-tenant system"
|
||||
echo " create <tenant> [config_file] - Create new tenant"
|
||||
echo " delete <tenant> [--force] - Delete tenant"
|
||||
echo " list [format] - List tenants (json|csv|table)"
|
||||
echo " info <tenant> [format] - Get tenant info (json|yaml|summary)"
|
||||
echo " quota <tenant> <type> <value> - Update tenant quota"
|
||||
echo " backup <tenant> [path] - Backup tenant"
|
||||
echo " restore <backup_file> <tenant> - Restore tenant"
|
||||
echo " health <tenant> - Check tenant health"
|
||||
echo " help - Show this help"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue