293 lines
10 KiB
Python
293 lines
10 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test file for datacube S3 access with limited permissions
|
|
File test truy cập S3 qua datacube với quyền hạn chế
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import boto3
|
|
from botocore.exceptions import ClientError, NoCredentialsError
|
|
|
|
|
|
def load_credentials(credential_file='train_files/crediential.txt'):
|
|
"""Load AWS credentials from file"""
|
|
credentials = {}
|
|
try:
|
|
with open(credential_file, 'r') as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if line.startswith('export '):
|
|
line = line[7:]
|
|
if '=' in line:
|
|
key, value = line.split('=', 1)
|
|
value = value.strip('"')
|
|
credentials[key] = value
|
|
|
|
print("✓ Credentials loaded successfully")
|
|
print(f" - AWS_ACCESS_KEY_ID: {credentials.get('AWS_ACCESS_KEY_ID', 'N/A')[:20]}...")
|
|
return credentials
|
|
except Exception as e:
|
|
print(f"✗ Error loading credentials: {e}")
|
|
return None
|
|
|
|
|
|
def set_aws_credentials(credentials):
|
|
"""Set AWS credentials as environment variables"""
|
|
if not credentials:
|
|
return False
|
|
|
|
try:
|
|
os.environ['AWS_ACCESS_KEY_ID'] = credentials.get('AWS_ACCESS_KEY_ID', '')
|
|
os.environ['AWS_SECRET_ACCESS_KEY'] = credentials.get('AWS_SECRET_ACCESS_KEY', '')
|
|
os.environ['AWS_SESSION_TOKEN'] = credentials.get('AWS_SESSION_TOKEN', '')
|
|
print("✓ AWS credentials set in environment")
|
|
return True
|
|
except Exception as e:
|
|
print(f"✗ Error setting credentials: {e}")
|
|
return False
|
|
|
|
|
|
def test_s3_specific_bucket(bucket_name='deafrica-sentinel-2', region='ap-southeast-1', prefix=''):
|
|
"""
|
|
Test access to a specific S3 bucket without requiring ListAllMyBuckets permission
|
|
Kiểm tra truy cập bucket S3 cụ thể mà không cần quyền ListAllMyBuckets
|
|
"""
|
|
try:
|
|
print(f"\n=== Testing Specific Bucket Access ===")
|
|
print(f"Bucket: {bucket_name}")
|
|
print(f"Region: {region}")
|
|
|
|
# Create S3 client
|
|
s3_client = boto3.client('s3', region_name=region)
|
|
|
|
# Try to access bucket with head_bucket (checks if bucket exists and we have access)
|
|
try:
|
|
s3_client.head_bucket(Bucket=bucket_name)
|
|
print(f"✓ Successfully verified access to bucket: {bucket_name}")
|
|
except ClientError as e:
|
|
error_code = e.response.get('Error', {}).get('Code', 'Unknown')
|
|
if error_code == '404':
|
|
print(f"✗ Bucket {bucket_name} does not exist or you don't have access")
|
|
return None
|
|
elif error_code == '403' or error_code == 'AccessDenied':
|
|
print(f"✗ Access denied to bucket: {bucket_name}")
|
|
return None
|
|
else:
|
|
print(f"✗ Error: {error_code}")
|
|
return None
|
|
|
|
# Try to list some objects
|
|
print(f"\n✓ Attempting to list objects (max 5)...")
|
|
response = s3_client.list_objects_v2(
|
|
Bucket=bucket_name,
|
|
MaxKeys=5,
|
|
Prefix=prefix
|
|
)
|
|
|
|
if 'Contents' in response:
|
|
print(f"✓ Found {len(response['Contents'])} objects:")
|
|
for i, obj in enumerate(response['Contents'], 1):
|
|
size_mb = obj['Size'] / (1024 * 1024)
|
|
print(f" {i}. {obj['Key']}")
|
|
print(f" Size: {size_mb:.2f} MB")
|
|
else:
|
|
print(f"✓ No objects found with prefix '{prefix}'")
|
|
|
|
return s3_client
|
|
|
|
except NoCredentialsError:
|
|
print("\n✗ Error: No AWS credentials found")
|
|
return None
|
|
except ClientError as e:
|
|
error_code = e.response.get('Error', {}).get('Code', 'Unknown')
|
|
print(f"\n✗ AWS Client Error: {e}")
|
|
print(f"✗ Error Code: {error_code}")
|
|
|
|
if error_code == 'ExpiredToken':
|
|
print("✗ AWS session token has expired. Please refresh your credentials.")
|
|
elif error_code == 'AccessDenied':
|
|
print("✗ Access denied. You may not have permission for this bucket.")
|
|
return None
|
|
except Exception as e:
|
|
print(f"\n✗ Unexpected error: {e}")
|
|
return None
|
|
|
|
|
|
def test_datacube_s3_access():
|
|
"""
|
|
Test S3 access using datacube pattern
|
|
Kiểm tra truy cập S3 theo pattern của datacube
|
|
"""
|
|
try:
|
|
print("\n=== Testing Datacube S3 Access Pattern ===")
|
|
|
|
# Import datacube S3 utilities
|
|
try:
|
|
from datacube.utils.rio import configure_s3_access
|
|
print("✓ datacube library found")
|
|
|
|
# Configure S3 access for rasterio/datacube
|
|
aws_unsigned = False # We have credentials
|
|
region_name = 'ap-southeast-1'
|
|
|
|
print(f"✓ Configuring S3 access for region: {region_name}")
|
|
configure_s3_access(
|
|
aws_unsigned=aws_unsigned,
|
|
region_name=region_name,
|
|
cloud_defaults=True
|
|
)
|
|
print("✓ S3 access configured for datacube/rasterio")
|
|
|
|
return True
|
|
|
|
except ImportError:
|
|
print("✗ datacube library not found")
|
|
print(" You can install it with: pip install datacube")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"\n✗ Error configuring datacube S3 access: {e}")
|
|
return False
|
|
|
|
|
|
def test_simple_s3_operations(bucket_name, s3_client):
|
|
"""
|
|
Test basic S3 operations that work with limited permissions
|
|
Kiểm tra các thao tác S3 cơ bản với quyền hạn chế
|
|
"""
|
|
try:
|
|
print("\n=== Testing Basic S3 Operations ===")
|
|
|
|
# Test 1: Get bucket location
|
|
try:
|
|
response = s3_client.get_bucket_location(Bucket=bucket_name)
|
|
location = response.get('LocationConstraint', 'us-east-1')
|
|
print(f"✓ Bucket location: {location}")
|
|
except ClientError as e:
|
|
print(f"✗ Cannot get bucket location: {e.response.get('Error', {}).get('Code', 'Unknown')}")
|
|
|
|
# Test 2: Check if we can read objects
|
|
try:
|
|
# Try to list with a common prefix
|
|
response = s3_client.list_objects_v2(
|
|
Bucket=bucket_name,
|
|
MaxKeys=1,
|
|
Delimiter='/'
|
|
)
|
|
|
|
if 'CommonPrefixes' in response:
|
|
print(f"✓ Found {len(response['CommonPrefixes'])} top-level folders")
|
|
for prefix in response['CommonPrefixes'][:3]:
|
|
print(f" - {prefix['Prefix']}")
|
|
|
|
except ClientError as e:
|
|
print(f"✗ Cannot list objects: {e.response.get('Error', {}).get('Code', 'Unknown')}")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"\n✗ Error in S3 operations: {e}")
|
|
return False
|
|
|
|
|
|
def test_multiple_buckets():
|
|
"""
|
|
Test access to multiple common S3 buckets
|
|
Kiểm tra truy cập nhiều bucket S3 phổ biến
|
|
"""
|
|
# Common buckets used in remote sensing / datacube projects
|
|
test_buckets = [
|
|
('deafrica-sentinel-2', 'af-south-1', 'sentinel-s2-l2a-cogs'),
|
|
('sentinel-cogs', 'us-west-2', 'sentinel-s2-l2a'),
|
|
('usgs-landsat', 'us-west-2', 'collection02'),
|
|
# EASI bucket might be private
|
|
('easi-asia-csiro', 'ap-southeast-1', ''),
|
|
]
|
|
|
|
results = []
|
|
|
|
for bucket_name, region, prefix in test_buckets:
|
|
print(f"\n{'='*60}")
|
|
print(f"Testing bucket: {bucket_name}")
|
|
print(f"Region: {region}")
|
|
|
|
s3_client = test_s3_specific_bucket(bucket_name, region, prefix)
|
|
|
|
if s3_client:
|
|
results.append((bucket_name, True))
|
|
# If successful, try some operations
|
|
test_simple_s3_operations(bucket_name, s3_client)
|
|
else:
|
|
results.append((bucket_name, False))
|
|
|
|
return results
|
|
|
|
|
|
def main():
|
|
"""Main test function"""
|
|
print("=" * 60)
|
|
print("AWS S3 Datacube Access Test")
|
|
print("Test Truy Cập S3 Datacube (với quyền hạn chế)")
|
|
print("=" * 60)
|
|
|
|
# Step 1: Load credentials
|
|
print("\n[Step 1] Loading credentials from file...")
|
|
credentials = load_credentials()
|
|
|
|
if not credentials:
|
|
print("\n✗ Test failed: Could not load credentials")
|
|
return False
|
|
|
|
# Step 2: Set credentials in environment
|
|
print("\n[Step 2] Setting AWS credentials...")
|
|
if not set_aws_credentials(credentials):
|
|
print("\n✗ Test failed: Could not set credentials")
|
|
return False
|
|
|
|
# Step 3: Test datacube S3 access configuration
|
|
print("\n[Step 3] Testing datacube S3 access configuration...")
|
|
test_datacube_s3_access()
|
|
|
|
# Step 4: Test access to multiple buckets
|
|
print("\n[Step 4] Testing access to common S3 buckets...")
|
|
results = test_multiple_buckets()
|
|
|
|
# Summary
|
|
print("\n" + "=" * 60)
|
|
print("Test Summary / Tổng kết:")
|
|
print("=" * 60)
|
|
|
|
success_count = sum(1 for _, success in results if success)
|
|
total_count = len(results)
|
|
|
|
print(f"\nSuccessful connections: {success_count}/{total_count}")
|
|
for bucket_name, success in results:
|
|
status = "✓" if success else "✗"
|
|
print(f"{status} {bucket_name}")
|
|
|
|
print("\n" + "=" * 60)
|
|
if success_count > 0:
|
|
print("✓ Test completed! You have access to some buckets.")
|
|
print("✓ Test hoàn thành! Bạn có quyền truy cập một số bucket.")
|
|
else:
|
|
print("⚠ No buckets accessible with current credentials.")
|
|
print("⚠ Không có bucket nào truy cập được với credentials hiện tại.")
|
|
print("=" * 60)
|
|
|
|
return success_count > 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
success = main()
|
|
sys.exit(0 if success else 1)
|
|
except KeyboardInterrupt:
|
|
print("\n\n✗ Test interrupted by user")
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(f"\n✗ Fatal error: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1)
|