init commit
This commit is contained in:
5
templates/openapi/.redocly.yaml
Normal file
5
templates/openapi/.redocly.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
apis:
|
||||
main:
|
||||
root: ./openapi.yaml
|
||||
rules:
|
||||
no-unused-components: off
|
||||
120
templates/openapi/generate_docs.sh
Executable file
120
templates/openapi/generate_docs.sh
Executable file
@@ -0,0 +1,120 @@
|
||||
#!/bin/bash
|
||||
|
||||
# vStash OpenAPI Documentation Generator
|
||||
# This script compiles the OpenAPI YAML files and generates HTML documentation
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}🚀 vStash API Documentation Generator${NC}"
|
||||
echo "================================================"
|
||||
|
||||
# Check if we're in the right directory
|
||||
if [ ! -f "templates/openapi/v1.yaml" ]; then
|
||||
echo -e "${RED}❌ Error: templates/openapi/v1.yaml not found${NC}"
|
||||
echo "Please run this script from the project root directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd templates/openapi
|
||||
|
||||
# Check for required tools
|
||||
echo -e "${BLUE}🔍 Checking dependencies...${NC}"
|
||||
|
||||
if ! command -v redocly &> /dev/null; then
|
||||
echo -e "${YELLOW}⚠️ redocly not found. Installing...${NC}"
|
||||
npm install -g @redocly/cli@latest
|
||||
fi
|
||||
|
||||
# Try to install modern swagger tools
|
||||
if ! command -v swagger-cli &> /dev/null; then
|
||||
echo -e "${YELLOW}⚠️ swagger-cli not found. Installing modern version...${NC}"
|
||||
npm install -g @apidevtools/swagger-cli
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ Dependencies check complete${NC}"
|
||||
|
||||
# Create output directory
|
||||
mkdir -p html
|
||||
|
||||
# Step 1: Bundle YAML files
|
||||
echo -e "${BLUE}📦 Bundling YAML files...${NC}"
|
||||
|
||||
# Try redocly first (better multi-file support)
|
||||
if redocly bundle v1.yaml --output openapi.yaml; then
|
||||
echo -e "${GREEN}✅ YAML bundling complete (using redocly)${NC}"
|
||||
fi
|
||||
|
||||
# Step 2: Validate the bundled YAML
|
||||
echo -e "${BLUE}🔍 Validating OpenAPI specification...${NC}"
|
||||
redocly lint openapi.yaml
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✅ OpenAPI validation passed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ OpenAPI validation warnings (proceeding anyway)${NC}"
|
||||
fi
|
||||
|
||||
# Step 3: Generate HTML documentation
|
||||
echo -e "${BLUE}📖 Generating HTML documentation...${NC}"
|
||||
redocly build-docs openapi.yaml --output=html/index.html
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✅ HTML documentation generated${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ HTML documentation generation failed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 4: Generate additional formats (optional)
|
||||
echo -e "${BLUE}📄 Generating additional documentation formats...${NC}"
|
||||
|
||||
# Generate a cleaner JSON version
|
||||
if command -v yq &> /dev/null; then
|
||||
yq eval openapi.yaml -o=json > openapi.json
|
||||
echo -e "${GREEN}✅ JSON format generated${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ yq not found, skipping JSON generation${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 Documentation generation complete!${NC}"
|
||||
echo "================================================"
|
||||
echo -e "${BLUE}📁 Generated files:${NC}"
|
||||
echo " • templates/openapi/openapi.yaml (bundled spec)"
|
||||
echo " • templates/openapi/openapi.json (JSON format)"
|
||||
echo " • templates/openapi/html/index.html (main docs)"
|
||||
echo ""
|
||||
echo -e "${BLUE}🌐 To view the documentation:${NC}"
|
||||
echo " Local: file://$(pwd)/html/index.html"
|
||||
echo " Or serve with: python -m http.server 8080 -d html"
|
||||
echo ""
|
||||
echo -e "${BLUE}📋 Next steps:${NC}"
|
||||
echo " 1. Review the generated documentation"
|
||||
echo " 2. Deploy html/index.html to your web server"
|
||||
echo " 3. Update API endpoints if needed"
|
||||
echo " 4. Share with your team!"
|
||||
echo ""
|
||||
|
||||
# Optional: Open documentation in browser (macOS/Linux)
|
||||
if command -v open &> /dev/null; then
|
||||
read -p "Open documentation in browser? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
open html/index.html
|
||||
fi
|
||||
elif command -v xdg-open &> /dev/null; then
|
||||
read -p "Open documentation in browser? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
xdg-open html/index.html
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✨ All done!${NC}"
|
||||
847
templates/openapi/html/index.html
Normal file
847
templates/openapi/html/index.html
Normal file
File diff suppressed because one or more lines are too long
1605
templates/openapi/openapi.yaml
Normal file
1605
templates/openapi/openapi.yaml
Normal file
File diff suppressed because it is too large
Load Diff
266
templates/openapi/parameters.yaml
Normal file
266
templates/openapi/parameters.yaml
Normal file
@@ -0,0 +1,266 @@
|
||||
BucketName:
|
||||
name: bucket
|
||||
in: path
|
||||
required: true
|
||||
description: Name of the S3 bucket
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^[a-z0-9\-\.]+$'
|
||||
minLength: 3
|
||||
maxLength: 63
|
||||
example: "my-bucket"
|
||||
|
||||
ObjectKey:
|
||||
name: key
|
||||
in: path
|
||||
required: true
|
||||
description: Object key (file path) within the bucket
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 255
|
||||
example: "folder/file.txt"
|
||||
style: simple
|
||||
explode: false
|
||||
|
||||
CredentialId:
|
||||
name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Unique identifier for the credential
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
example: 1
|
||||
|
||||
Prefix:
|
||||
name: prefix
|
||||
in: query
|
||||
description: Limits the response to keys that begin with the specified prefix
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 255
|
||||
example: "photos/"
|
||||
|
||||
Marker:
|
||||
name: marker
|
||||
in: query
|
||||
description: Specifies the key to start with when listing objects
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 255
|
||||
example: "photos/2023/"
|
||||
|
||||
MaxKeys:
|
||||
name: max-keys
|
||||
in: query
|
||||
description: Maximum number of keys to return
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 1000
|
||||
default: 1000
|
||||
example: 100
|
||||
|
||||
Delimiter:
|
||||
name: delimiter
|
||||
in: query
|
||||
description: Character used to group keys
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 1
|
||||
example: "/"
|
||||
|
||||
PartNumber:
|
||||
name: partNumber
|
||||
in: query
|
||||
description: Part number for multipart upload (1-10,000)
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 10000
|
||||
example: 1
|
||||
|
||||
UploadId:
|
||||
name: uploadId
|
||||
in: query
|
||||
description: Upload ID for multipart upload operations
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 64
|
||||
example: "upload_12345_abcdef"
|
||||
|
||||
VersionId:
|
||||
name: versionId
|
||||
in: query
|
||||
description: Version ID of the object (if versioning is enabled)
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 64
|
||||
example: "version_123"
|
||||
|
||||
ContentMD5:
|
||||
name: Content-MD5
|
||||
in: header
|
||||
description: MD5 digest of the request body
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^[A-Za-z0-9+/]+=*$'
|
||||
example: "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg="
|
||||
|
||||
ContentType:
|
||||
name: Content-Type
|
||||
in: header
|
||||
description: MIME type of the object
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 255
|
||||
default: "application/octet-stream"
|
||||
example: "image/jpeg"
|
||||
|
||||
ContentLength:
|
||||
name: Content-Length
|
||||
in: header
|
||||
description: Size of the object in bytes
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
example: 1024000
|
||||
|
||||
Range:
|
||||
name: Range
|
||||
in: header
|
||||
description: Downloads the specified range bytes of an object
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^bytes=\d+-\d*$'
|
||||
example: "bytes=0-1023"
|
||||
|
||||
IfMatch:
|
||||
name: If-Match
|
||||
in: header
|
||||
description: Return the object only if its ETag matches the specified value
|
||||
schema:
|
||||
type: string
|
||||
example: "\"9bb58f26192e4ba00f01e2e7b136bbd8\""
|
||||
|
||||
IfNoneMatch:
|
||||
name: If-None-Match
|
||||
in: header
|
||||
description: Return the object only if its ETag does not match the specified value
|
||||
schema:
|
||||
type: string
|
||||
example: "\"9bb58f26192e4ba00f01e2e7b136bbd8\""
|
||||
|
||||
IfModifiedSince:
|
||||
name: If-Modified-Since
|
||||
in: header
|
||||
description: Return the object only if it has been modified since the specified time
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "Wed, 15 Jan 2023 10:30:00 GMT"
|
||||
|
||||
IfUnmodifiedSince:
|
||||
name: If-Unmodified-Since
|
||||
in: header
|
||||
description: Return the object only if it has not been modified since the specified time
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "Wed, 15 Jan 2023 10:30:00 GMT"
|
||||
|
||||
CacheControl:
|
||||
name: Cache-Control
|
||||
in: header
|
||||
description: Specifies caching behavior for the object
|
||||
schema:
|
||||
type: string
|
||||
example: "max-age=3600"
|
||||
|
||||
ContentDisposition:
|
||||
name: Content-Disposition
|
||||
in: header
|
||||
description: Specifies presentational information for the object
|
||||
schema:
|
||||
type: string
|
||||
example: "attachment; filename=\"file.txt\""
|
||||
|
||||
ContentEncoding:
|
||||
name: Content-Encoding
|
||||
in: header
|
||||
description: Specifies what content encodings have been applied to the object
|
||||
schema:
|
||||
type: string
|
||||
example: "gzip"
|
||||
|
||||
ContentLanguage:
|
||||
name: Content-Language
|
||||
in: header
|
||||
description: Language the content is in
|
||||
schema:
|
||||
type: string
|
||||
example: "en-US"
|
||||
|
||||
Expires:
|
||||
name: Expires
|
||||
in: header
|
||||
description: Date and time when the object expires
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "Wed, 15 Jan 2024 10:30:00 GMT"
|
||||
|
||||
ServerSideEncryption:
|
||||
name: x-amz-server-side-encryption
|
||||
in: header
|
||||
description: Server-side encryption algorithm to use
|
||||
schema:
|
||||
type: string
|
||||
enum: ["AES256", "aws:kms"]
|
||||
example: "AES256"
|
||||
|
||||
StorageClass:
|
||||
name: x-amz-storage-class
|
||||
in: header
|
||||
description: Storage class for the object
|
||||
schema:
|
||||
type: string
|
||||
enum: ["STANDARD", "REDUCED_REDUNDANCY", "GLACIER", "DEEP_ARCHIVE"]
|
||||
default: "STANDARD"
|
||||
example: "STANDARD"
|
||||
|
||||
Tagging:
|
||||
name: x-amz-tagging
|
||||
in: header
|
||||
description: Object tag set as a query string
|
||||
schema:
|
||||
type: string
|
||||
example: "key1=value1&key2=value2"
|
||||
|
||||
MetadataDirective:
|
||||
name: x-amz-metadata-directive
|
||||
in: header
|
||||
description: Specifies whether metadata is copied from the source object or replaced
|
||||
schema:
|
||||
type: string
|
||||
enum: ["COPY", "REPLACE"]
|
||||
default: "COPY"
|
||||
example: "REPLACE"
|
||||
|
||||
CopySource:
|
||||
name: x-amz-copy-source
|
||||
in: header
|
||||
description: Source bucket and object for copy operations
|
||||
schema:
|
||||
type: string
|
||||
example: "/source-bucket/source-object"
|
||||
|
||||
ACL:
|
||||
name: x-amz-acl
|
||||
in: header
|
||||
description: Canned ACL to apply to the object
|
||||
schema:
|
||||
type: string
|
||||
enum: ["private", "public-read", "public-read-write", "authenticated-read"]
|
||||
default: "private"
|
||||
example: "public-read"
|
||||
582
templates/openapi/paths.yaml
Normal file
582
templates/openapi/paths.yaml
Normal file
@@ -0,0 +1,582 @@
|
||||
# S3 API Endpoints
|
||||
|
||||
# List all buckets
|
||||
/s3/:
|
||||
get:
|
||||
operationId: listBuckets
|
||||
tags:
|
||||
- S3 Buckets
|
||||
summary: List buckets
|
||||
description: Returns a list of all buckets owned by the authenticated sender of the request
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/CreatePresignedUrlResponse'#/ListAllMyBucketsResult'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
|
||||
# Bucket operations
|
||||
/s3/{bucket}:
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/BucketName'
|
||||
|
||||
head:
|
||||
operationId: headBucket
|
||||
tags:
|
||||
- S3 Buckets
|
||||
summary: Check if bucket exists
|
||||
description: Determines if a bucket exists and you have permission to access it
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
responses:
|
||||
'200':
|
||||
description: Bucket exists and you have access
|
||||
|
||||
|
||||
put:
|
||||
operationId: createBucket
|
||||
tags:
|
||||
- S3 Buckets
|
||||
summary: Create bucket
|
||||
description: Creates a new S3 bucket
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
responses:
|
||||
'200':
|
||||
description: Bucket created successfully
|
||||
headers:
|
||||
Location:
|
||||
description: Location of the created bucket
|
||||
schema:
|
||||
type: string
|
||||
'409':
|
||||
description: Bucket already exists
|
||||
|
||||
delete:
|
||||
operationId: deleteBucket
|
||||
tags:
|
||||
- S3 Buckets
|
||||
summary: Delete bucket
|
||||
description: Deletes the S3 bucket. The bucket must be empty before it can be deleted
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
responses:
|
||||
'204':
|
||||
description: Bucket deleted successfully
|
||||
'409':
|
||||
description: Bucket not empty
|
||||
|
||||
get:
|
||||
operationId: listObjects
|
||||
tags:
|
||||
- S3 Buckets
|
||||
summary: List objects in bucket
|
||||
description: Returns some or all of the objects in a bucket
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/Prefix'
|
||||
- $ref: './parameters.yaml#/Marker'
|
||||
- $ref: './parameters.yaml#/MaxKeys'
|
||||
- $ref: './parameters.yaml#/Delimiter'
|
||||
- name: uploads
|
||||
in: query
|
||||
description: List multipart uploads when present
|
||||
schema:
|
||||
type: string
|
||||
enum: ['']
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: './schemas.yaml#/ListBucketResult'
|
||||
- $ref: './schemas.yaml#/ListMultipartUploadsResult'
|
||||
|
||||
|
||||
# Object operations
|
||||
/s3/{bucket}/{key}:
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/BucketName'
|
||||
- $ref: './parameters.yaml#/ObjectKey'
|
||||
|
||||
head:
|
||||
operationId: headObject
|
||||
tags:
|
||||
- S3 Objects
|
||||
summary: Get object metadata
|
||||
description: Retrieves metadata from an object without returning the object itself
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
headers:
|
||||
Content-Length:
|
||||
schema:
|
||||
type: integer
|
||||
Content-Type:
|
||||
schema:
|
||||
type: string
|
||||
ETag:
|
||||
schema:
|
||||
type: string
|
||||
Last-Modified:
|
||||
schema:
|
||||
type: string
|
||||
|
||||
get:
|
||||
operationId: getObject
|
||||
tags:
|
||||
- S3 Objects
|
||||
summary: Get object
|
||||
description: Retrieves objects from Amazon S3
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
parameters:
|
||||
- name: uploadId
|
||||
in: query
|
||||
description: List parts when present with upload ID
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/ListPartsResult'
|
||||
'404':
|
||||
description: Object not found
|
||||
|
||||
put:
|
||||
operationId: putObject
|
||||
tags:
|
||||
- S3 Objects
|
||||
summary: Put object
|
||||
description: Adds an object to a bucket
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
parameters:
|
||||
- name: partNumber
|
||||
in: query
|
||||
description: Part number for multipart upload
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 10000
|
||||
- name: uploadId
|
||||
in: query
|
||||
description: Upload ID for multipart upload part
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
description: Object data
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
headers:
|
||||
ETag:
|
||||
schema:
|
||||
type: string
|
||||
|
||||
delete:
|
||||
operationId: deleteObject
|
||||
tags:
|
||||
- S3 Objects
|
||||
summary: Delete object
|
||||
description: Removes the null version of an object and inserts a delete marker
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
parameters:
|
||||
- name: uploadId
|
||||
in: query
|
||||
description: Abort multipart upload when present
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'204':
|
||||
description: Object deleted successfully
|
||||
|
||||
post:
|
||||
operationId: multipartUpload
|
||||
tags:
|
||||
- S3 Multipart
|
||||
summary: Initiate or complete multipart upload
|
||||
description: Initiates a multipart upload or completes a multipart upload by assembling uploaded parts
|
||||
security:
|
||||
- AWS4-HMAC-SHA256: []
|
||||
parameters:
|
||||
- name: uploads
|
||||
in: query
|
||||
description: Initiate multipart upload when present
|
||||
schema:
|
||||
type: string
|
||||
enum: ['']
|
||||
- name: uploadId
|
||||
in: query
|
||||
description: Complete multipart upload with this upload ID
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
description: Complete multipart upload request
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/CompleteMultipartUpload'
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: './schemas.yaml#/InitiateMultipartUploadResult'
|
||||
- $ref: './schemas.yaml#/CompleteMultipartUploadResult'
|
||||
|
||||
# Management API Endpoints
|
||||
|
||||
/api/stats:
|
||||
get:
|
||||
operationId: getSystemStats
|
||||
tags:
|
||||
- Management - Stats
|
||||
summary: Get system statistics
|
||||
description: Returns overall system statistics including storage usage, object counts, etc.
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/SystemStats'
|
||||
|
||||
/api/credentials:
|
||||
get:
|
||||
operationId: listCredentials
|
||||
tags:
|
||||
- Management - Credentials
|
||||
summary: List credentials
|
||||
description: Returns a list of all access credentials
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/CredentialsList'
|
||||
|
||||
post:
|
||||
operationId: createCredential
|
||||
tags:
|
||||
- Management - Credentials
|
||||
summary: Create credential
|
||||
description: Creates a new access credential
|
||||
security:
|
||||
- ApiKey: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/CreateCredentialRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Credential created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/Credential'
|
||||
|
||||
/api/credentials/{id}:
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/CredentialId'
|
||||
|
||||
get:
|
||||
operationId: getCredential
|
||||
tags:
|
||||
- Management - Credentials
|
||||
summary: Get credential details
|
||||
description: Returns detailed information about a specific credential
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/CredentialDetail'
|
||||
|
||||
put:
|
||||
operationId: updateCredential
|
||||
tags:
|
||||
- Management - Credentials
|
||||
summary: Update credential
|
||||
description: Updates an existing credential
|
||||
security:
|
||||
- ApiKey: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/UpdateCredentialRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Credential updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/ApiResponse'
|
||||
|
||||
delete:
|
||||
operationId: deleteCredential
|
||||
tags:
|
||||
- Management - Credentials
|
||||
summary: Delete credential
|
||||
description: Deletes an access credential
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Credential deleted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/ApiResponse'
|
||||
|
||||
/api/buckets:
|
||||
get:
|
||||
operationId: listBucketsManagement
|
||||
tags:
|
||||
- Management - Buckets
|
||||
summary: List all buckets
|
||||
description: Returns a list of all buckets with detailed information
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/BucketsList'
|
||||
|
||||
post:
|
||||
operationId: createBucketManagement
|
||||
tags:
|
||||
- Management - Buckets
|
||||
summary: Create bucket
|
||||
description: Creates a new bucket via management API
|
||||
security:
|
||||
- ApiKey: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/CreateBucketRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Bucket created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/BucketDetail'
|
||||
|
||||
/api/buckets/{bucketName}:
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/BucketName'
|
||||
|
||||
get:
|
||||
operationId: getBucketDetails
|
||||
tags:
|
||||
- Management - Buckets
|
||||
summary: Get bucket details
|
||||
description: Returns detailed information about a specific bucket including objects
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/BucketDetail'
|
||||
|
||||
delete:
|
||||
operationId: deleteBucketManagement
|
||||
tags:
|
||||
- Management - Buckets
|
||||
summary: Delete bucket
|
||||
description: Deletes a bucket via management API
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Bucket deleted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/ApiResponse'
|
||||
|
||||
/api/buckets/{bucketName}/objects:
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/BucketName'
|
||||
|
||||
get:
|
||||
operationId: listObjectsManagement
|
||||
tags:
|
||||
- Management - Objects
|
||||
summary: List objects in bucket
|
||||
description: Returns a list of objects in the specified bucket
|
||||
security:
|
||||
- ApiKey: []
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/Prefix'
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/ObjectsList'
|
||||
|
||||
delete:
|
||||
operationId: deleteMultipleObjects
|
||||
tags:
|
||||
- Management - Objects
|
||||
summary: Delete multiple objects
|
||||
description: Deletes multiple objects from a bucket
|
||||
security:
|
||||
- ApiKey: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/DeleteObjectsRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Objects deleted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/DeleteObjectsResponse'
|
||||
|
||||
/api/buckets/{bucketName}/objects/{objectKey}:
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/BucketName'
|
||||
- $ref: './parameters.yaml#/ObjectKey'
|
||||
|
||||
get:
|
||||
operationId: getObjectDetails
|
||||
tags:
|
||||
- Management - Objects
|
||||
summary: Get object details
|
||||
description: Returns detailed information about a specific object
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/ObjectDetail'
|
||||
|
||||
delete:
|
||||
operationId: deleteObjectManagement
|
||||
tags:
|
||||
- Management - Objects
|
||||
summary: Delete object
|
||||
description: Deletes a specific object
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Object deleted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/ApiResponse'
|
||||
|
||||
/api/buckets/{bucketName}/multipart-uploads:
|
||||
parameters:
|
||||
- $ref: './parameters.yaml#/BucketName'
|
||||
|
||||
get:
|
||||
operationId: listMultipartUploads
|
||||
tags:
|
||||
- Management - Objects
|
||||
summary: List multipart uploads
|
||||
description: Returns active multipart uploads for a bucket
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/MultipartUploadsList'
|
||||
|
||||
/api/presigned-urls:
|
||||
get:
|
||||
operationId: listPresignedUrls
|
||||
tags:
|
||||
- Management - Presigned URLs
|
||||
summary: List presigned URLs
|
||||
description: Returns active presigned URLs
|
||||
security:
|
||||
- ApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/PresignedUrlsList'
|
||||
|
||||
post:
|
||||
operationId: createPresignedUrl
|
||||
tags:
|
||||
- Management - Presigned URLs
|
||||
summary: Create presigned URL
|
||||
description: Generates a new presigned URL
|
||||
security:
|
||||
- ApiKey: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/CreatePresignedUrlRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Presigned URL created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './schemas.yaml#/CreatePresignedUrlResponse'
|
||||
633
templates/openapi/schemas.yaml
Normal file
633
templates/openapi/schemas.yaml
Normal file
@@ -0,0 +1,633 @@
|
||||
# S3 API Schemas
|
||||
|
||||
S3Error:
|
||||
type: object
|
||||
xml:
|
||||
name: Error
|
||||
properties:
|
||||
Code:
|
||||
type: string
|
||||
example: "NoSuchBucket"
|
||||
Message:
|
||||
type: string
|
||||
example: "The specified bucket does not exist"
|
||||
Resource:
|
||||
type: string
|
||||
example: "/mybucket"
|
||||
RequestId:
|
||||
type: string
|
||||
example: "4442587FB7D0A2F9"
|
||||
|
||||
ListAllMyBucketsResult:
|
||||
type: object
|
||||
xml:
|
||||
name: ListAllMyBucketsResult
|
||||
namespace: http://s3.amazonaws.com/doc/2006-03-01/
|
||||
properties:
|
||||
Buckets:
|
||||
type: object
|
||||
properties:
|
||||
Bucket:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/Bucket'
|
||||
|
||||
Bucket:
|
||||
type: object
|
||||
properties:
|
||||
Name:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
CreationDate:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00.000Z"
|
||||
|
||||
ListBucketResult:
|
||||
type: object
|
||||
xml:
|
||||
name: ListBucketResult
|
||||
namespace: http://s3.amazonaws.com/doc/2006-03-01/
|
||||
properties:
|
||||
Name:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
Prefix:
|
||||
type: string
|
||||
example: "photos/"
|
||||
Marker:
|
||||
type: string
|
||||
example: "photos/2023/"
|
||||
MaxKeys:
|
||||
type: integer
|
||||
example: 1000
|
||||
IsTruncated:
|
||||
type: boolean
|
||||
example: false
|
||||
Contents:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/ObjectSummary'
|
||||
|
||||
ObjectSummary:
|
||||
type: object
|
||||
properties:
|
||||
Key:
|
||||
type: string
|
||||
example: "photos/2023/vacation.jpg"
|
||||
LastModified:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00.000Z"
|
||||
ETag:
|
||||
type: string
|
||||
example: "\"9bb58f26192e4ba00f01e2e7b136bbd8\""
|
||||
Size:
|
||||
type: integer
|
||||
example: 1024000
|
||||
StorageClass:
|
||||
type: string
|
||||
example: "STANDARD"
|
||||
|
||||
InitiateMultipartUploadResult:
|
||||
type: object
|
||||
xml:
|
||||
name: InitiateMultipartUploadResult
|
||||
namespace: http://s3.amazonaws.com/doc/2006-03-01/
|
||||
properties:
|
||||
Bucket:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
Key:
|
||||
type: string
|
||||
example: "large-file.zip"
|
||||
UploadId:
|
||||
type: string
|
||||
example: "upload_12345_abcdef"
|
||||
|
||||
CompleteMultipartUpload:
|
||||
type: object
|
||||
xml:
|
||||
name: CompleteMultipartUpload
|
||||
properties:
|
||||
Part:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
PartNumber:
|
||||
type: integer
|
||||
example: 1
|
||||
ETag:
|
||||
type: string
|
||||
example: "\"9bb58f26192e4ba00f01e2e7b136bbd8\""
|
||||
|
||||
CompleteMultipartUploadResult:
|
||||
type: object
|
||||
xml:
|
||||
name: CompleteMultipartUploadResult
|
||||
namespace: http://s3.amazonaws.com/doc/2006-03-01/
|
||||
properties:
|
||||
Location:
|
||||
type: string
|
||||
example: "/my-bucket/large-file.zip"
|
||||
Bucket:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
Key:
|
||||
type: string
|
||||
example: "large-file.zip"
|
||||
ETag:
|
||||
type: string
|
||||
example: "\"9bb58f26192e4ba00f01e2e7b136bbd8-5\""
|
||||
|
||||
ListPartsResult:
|
||||
type: object
|
||||
xml:
|
||||
name: ListPartsResult
|
||||
namespace: http://s3.amazonaws.com/doc/2006-03-01/
|
||||
properties:
|
||||
Bucket:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
Key:
|
||||
type: string
|
||||
example: "large-file.zip"
|
||||
UploadId:
|
||||
type: string
|
||||
example: "upload_12345_abcdef"
|
||||
StorageClass:
|
||||
type: string
|
||||
example: "STANDARD"
|
||||
PartNumberMarker:
|
||||
type: integer
|
||||
example: 0
|
||||
NextPartNumberMarker:
|
||||
type: integer
|
||||
example: 5
|
||||
MaxParts:
|
||||
type: integer
|
||||
example: 1000
|
||||
IsTruncated:
|
||||
type: boolean
|
||||
example: false
|
||||
Part:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/Part'
|
||||
|
||||
Part:
|
||||
type: object
|
||||
properties:
|
||||
PartNumber:
|
||||
type: integer
|
||||
example: 1
|
||||
LastModified:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00.000Z"
|
||||
ETag:
|
||||
type: string
|
||||
example: "\"9bb58f26192e4ba00f01e2e7b136bbd8\""
|
||||
Size:
|
||||
type: integer
|
||||
example: 5242880
|
||||
|
||||
ListMultipartUploadsResult:
|
||||
type: object
|
||||
xml:
|
||||
name: ListMultipartUploadsResult
|
||||
namespace: http://s3.amazonaws.com/doc/2006-03-01/
|
||||
properties:
|
||||
Bucket:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
KeyMarker:
|
||||
type: string
|
||||
example: ""
|
||||
UploadIdMarker:
|
||||
type: string
|
||||
example: ""
|
||||
NextKeyMarker:
|
||||
type: string
|
||||
example: ""
|
||||
NextUploadIdMarker:
|
||||
type: string
|
||||
example: ""
|
||||
MaxUploads:
|
||||
type: integer
|
||||
example: 1000
|
||||
IsTruncated:
|
||||
type: boolean
|
||||
example: false
|
||||
Upload:
|
||||
type: array
|
||||
|
||||
MultipartUpload:
|
||||
type: object
|
||||
properties:
|
||||
Key:
|
||||
type: string
|
||||
example: "large-file.zip"
|
||||
UploadId:
|
||||
type: string
|
||||
example: "upload_12345_abcdef"
|
||||
Initiated:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00.000Z"
|
||||
StorageClass:
|
||||
type: string
|
||||
example: "STANDARD"
|
||||
|
||||
# Management API Schemas
|
||||
|
||||
ApiError:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
example: "Resource not found"
|
||||
code:
|
||||
type: string
|
||||
example: "NOT_FOUND"
|
||||
message:
|
||||
type: string
|
||||
example: "The requested resource could not be found"
|
||||
|
||||
ApiResponse:
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
example: "Operation completed successfully"
|
||||
|
||||
SystemStats:
|
||||
type: object
|
||||
properties:
|
||||
credentials:
|
||||
type: integer
|
||||
example: 5
|
||||
description: Total number of access credentials
|
||||
buckets:
|
||||
type: integer
|
||||
example: 12
|
||||
description: Total number of buckets
|
||||
objects:
|
||||
type: integer
|
||||
example: 1250
|
||||
description: Total number of objects
|
||||
total_storage:
|
||||
type: integer
|
||||
example: 1073741824
|
||||
description: Total storage used in bytes
|
||||
total_storage_human:
|
||||
type: string
|
||||
example: "1.0 GB"
|
||||
description: Human-readable storage size
|
||||
active_multipart_uploads:
|
||||
type: integer
|
||||
example: 3
|
||||
description: Number of active multipart uploads
|
||||
active_presigned_urls:
|
||||
type: integer
|
||||
example: 15
|
||||
description: Number of active presigned URLs
|
||||
|
||||
Credential:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
example: 1
|
||||
access_key:
|
||||
type: string
|
||||
example: "AKIAIOSFODNN7EXAMPLE"
|
||||
secret_key:
|
||||
type: string
|
||||
example: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
description: Only returned when creating credential
|
||||
user_name:
|
||||
type: string
|
||||
example: "john-doe"
|
||||
nullable: true
|
||||
is_active:
|
||||
type: boolean
|
||||
example: true
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00Z"
|
||||
|
||||
CredentialSummary:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
example: 1
|
||||
access_key:
|
||||
type: string
|
||||
example: "AKIAIOSFODNN7EXAMPLE"
|
||||
user_name:
|
||||
type: string
|
||||
example: "john-doe"
|
||||
nullable: true
|
||||
is_active:
|
||||
type: boolean
|
||||
example: true
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00Z"
|
||||
bucket_count:
|
||||
type: integer
|
||||
example: 3
|
||||
|
||||
CredentialDetail:
|
||||
allOf:
|
||||
- $ref: '#/CredentialSummary'
|
||||
- type: object
|
||||
properties:
|
||||
buckets:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/BucketSummary'
|
||||
|
||||
CredentialsList:
|
||||
type: object
|
||||
properties:
|
||||
credentials:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/CredentialSummary'
|
||||
|
||||
CreateCredentialRequest:
|
||||
type: object
|
||||
properties:
|
||||
user_name:
|
||||
type: string
|
||||
example: "john-doe"
|
||||
description: Optional user name
|
||||
access_key:
|
||||
type: string
|
||||
example: "AKIAIOSFODNN7EXAMPLE"
|
||||
description: Optional custom access key (auto-generated if not provided)
|
||||
secret_key:
|
||||
type: string
|
||||
example: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
description: Optional custom secret key (auto-generated if not provided)
|
||||
|
||||
UpdateCredentialRequest:
|
||||
type: object
|
||||
properties:
|
||||
user_name:
|
||||
type: string
|
||||
example: "john-doe"
|
||||
is_active:
|
||||
type: boolean
|
||||
example: true
|
||||
|
||||
BucketSummary:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
region:
|
||||
type: string
|
||||
example: "us-east-1"
|
||||
owner:
|
||||
type: string
|
||||
example: "john-doe"
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00Z"
|
||||
object_count:
|
||||
type: integer
|
||||
example: 150
|
||||
total_size:
|
||||
type: integer
|
||||
example: 1073741824
|
||||
total_size_human:
|
||||
type: string
|
||||
example: "1.0 GB"
|
||||
|
||||
BucketDetail:
|
||||
allOf:
|
||||
- $ref: '#/BucketSummary'
|
||||
- type: object
|
||||
properties:
|
||||
objects:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/ObjectInfo'
|
||||
|
||||
BucketsList:
|
||||
type: object
|
||||
properties:
|
||||
buckets:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/BucketSummary'
|
||||
|
||||
CreateBucketRequest:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- owner_id
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: "my-new-bucket"
|
||||
pattern: '^[a-z0-9\-\.]+$'
|
||||
owner_id:
|
||||
type: integer
|
||||
example: 1
|
||||
region:
|
||||
type: string
|
||||
example: "us-east-1"
|
||||
default: "us-east-1"
|
||||
|
||||
ObjectInfo:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
example: "photos/vacation.jpg"
|
||||
size:
|
||||
type: integer
|
||||
example: 1024000
|
||||
size_human:
|
||||
type: string
|
||||
example: "1.0 MB"
|
||||
content_type:
|
||||
type: string
|
||||
example: "image/jpeg"
|
||||
etag:
|
||||
type: string
|
||||
example: "9bb58f26192e4ba00f01e2e7b136bbd8"
|
||||
is_multipart:
|
||||
type: boolean
|
||||
example: false
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00Z"
|
||||
|
||||
ObjectDetail:
|
||||
allOf:
|
||||
- $ref: '#/ObjectInfo'
|
||||
- type: object
|
||||
properties:
|
||||
part_count:
|
||||
type: integer
|
||||
example: 0
|
||||
metadata:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
example:
|
||||
user-id: "12345"
|
||||
category: "photos"
|
||||
storage_path:
|
||||
type: string
|
||||
example: "my-bucket/objects/ab/cd/abcdef123456..."
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00Z"
|
||||
|
||||
ObjectsList:
|
||||
type: object
|
||||
properties:
|
||||
objects:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/ObjectInfo'
|
||||
|
||||
DeleteObjectsRequest:
|
||||
type: object
|
||||
required:
|
||||
- keys
|
||||
properties:
|
||||
keys:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: ["file1.txt", "file2.txt", "folder/file3.txt"]
|
||||
|
||||
DeleteObjectsResponse:
|
||||
type: object
|
||||
properties:
|
||||
deleted:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: ["file1.txt", "file2.txt"]
|
||||
|
||||
MultipartUploadInfo:
|
||||
type: object
|
||||
properties:
|
||||
upload_id:
|
||||
type: string
|
||||
example: "upload_12345_abcdef"
|
||||
object_key:
|
||||
type: string
|
||||
example: "large-file.zip"
|
||||
initiated_by:
|
||||
type: string
|
||||
example: "john-doe"
|
||||
content_type:
|
||||
type: string
|
||||
example: "application/zip"
|
||||
initiated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00Z"
|
||||
part_count:
|
||||
type: integer
|
||||
example: 5
|
||||
total_size:
|
||||
type: integer
|
||||
example: 26214400
|
||||
total_size_human:
|
||||
type: string
|
||||
example: "25.0 MB"
|
||||
|
||||
MultipartUploadsList:
|
||||
type: object
|
||||
properties:
|
||||
uploads:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/MultipartUploadInfo'
|
||||
|
||||
PresignedUrlInfo:
|
||||
type: object
|
||||
properties:
|
||||
bucket_name:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
object_key:
|
||||
type: string
|
||||
example: "file.txt"
|
||||
method:
|
||||
type: string
|
||||
enum: [GET, PUT, POST, DELETE]
|
||||
example: "GET"
|
||||
access_key:
|
||||
type: string
|
||||
example: "AKIAIOSFODNN7EXAMPLE"
|
||||
expires_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T11:30:00Z"
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2023-01-15T10:30:00Z"
|
||||
|
||||
PresignedUrlsList:
|
||||
type: object
|
||||
properties:
|
||||
urls:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/PresignedUrlInfo'
|
||||
|
||||
CreatePresignedUrlRequest:
|
||||
type: object
|
||||
required:
|
||||
- bucket_name
|
||||
- object_key
|
||||
- access_key
|
||||
properties:
|
||||
bucket_name:
|
||||
type: string
|
||||
example: "my-bucket"
|
||||
object_key:
|
||||
type: string
|
||||
example: "file.txt"
|
||||
method:
|
||||
type: string
|
||||
enum: [GET, PUT, POST, DELETE]
|
||||
default: "GET"
|
||||
example: "GET"
|
||||
expires_in:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 604800
|
||||
default: 3600
|
||||
example: 3600
|
||||
description: Expiration time in seconds (max 7 days)
|
||||
access_key:
|
||||
type: string
|
||||
example: "AKIAIOSFODNN7EXAMPLE"
|
||||
|
||||
CreatePresignedUrlResponse:
|
||||
type: object
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
example: "/my-bucket/file.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20230115%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230115T103000Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=abc123&hash=def456"
|
||||
101
templates/openapi/security.yaml
Normal file
101
templates/openapi/security.yaml
Normal file
@@ -0,0 +1,101 @@
|
||||
AWS4-HMAC-SHA256:
|
||||
type: apiKey
|
||||
description: |
|
||||
AWS Signature Version 4 authentication for S3 API endpoints.
|
||||
|
||||
## Authentication Process
|
||||
1. Create a canonical request
|
||||
2. Create a string to sign
|
||||
3. Calculate the signature using HMAC-SHA256
|
||||
4. Add the authorization header or query parameters
|
||||
|
||||
## Authorization Header Format
|
||||
```
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=<AccessKey>/<Date>/<Region>/s3/aws4_request,SignedHeaders=<SignedHeaders>,Signature=<Signature>
|
||||
```
|
||||
|
||||
## Query String Format (for presigned URLs)
|
||||
```
|
||||
?X-Amz-Algorithm=AWS4-HMAC-SHA256
|
||||
&X-Amz-Credential=<AccessKey>/<Date>/<Region>/s3/aws4_request
|
||||
&X-Amz-Date=<Timestamp>
|
||||
&X-Amz-Expires=<ExpirationTime>
|
||||
&X-Amz-SignedHeaders=<SignedHeaders>
|
||||
&X-Amz-Signature=<Signature>
|
||||
```
|
||||
|
||||
## Required Headers
|
||||
- `Authorization`: The calculated authorization value
|
||||
- `x-amz-date`: Timestamp in ISO 8601 format (YYYYMMDDTHHMMSSZ)
|
||||
- `x-amz-content-sha256`: SHA256 hash of the request payload
|
||||
|
||||
## Example
|
||||
```
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20230115/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024
|
||||
x-amz-date: 20230115T103000Z
|
||||
x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
```
|
||||
name: Authorization
|
||||
in: header
|
||||
|
||||
ApiKey:
|
||||
type: apiKey
|
||||
description: |
|
||||
API key authentication for management console endpoints.
|
||||
|
||||
## Usage
|
||||
Include your API key in the `X-API-Key` header for all management API requests.
|
||||
|
||||
## Example
|
||||
```
|
||||
X-API-Key: your-api-key-here
|
||||
```
|
||||
|
||||
## Obtaining an API Key
|
||||
API keys can be generated through the management console or by contacting your administrator.
|
||||
|
||||
## Permissions
|
||||
API keys have full access to the management API and should be kept secure.
|
||||
name: X-API-Key
|
||||
in: header
|
||||
|
||||
BearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
JWT Bearer token authentication (optional alternative for management API).
|
||||
|
||||
## Usage
|
||||
Include the JWT token in the Authorization header:
|
||||
```
|
||||
Authorization: Bearer <jwt-token>
|
||||
```
|
||||
|
||||
## Token Structure
|
||||
The JWT token contains claims about the user's permissions and expires after a set period.
|
||||
|
||||
## Example
|
||||
```
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
BasicAuth:
|
||||
type: http
|
||||
scheme: basic
|
||||
description: |
|
||||
HTTP Basic authentication (for simple setups).
|
||||
|
||||
## Usage
|
||||
Encode username:password in Base64 and include in Authorization header:
|
||||
```
|
||||
Authorization: Basic <base64-encoded-credentials>
|
||||
```
|
||||
|
||||
## Example
|
||||
```
|
||||
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
|
||||
```
|
||||
|
||||
## Note
|
||||
Basic auth should only be used over HTTPS in production environments.
|
||||
117
templates/openapi/v1.yaml
Normal file
117
templates/openapi/v1.yaml
Normal file
@@ -0,0 +1,117 @@
|
||||
openapi: "3.0.0"
|
||||
|
||||
info:
|
||||
version: "1.0.0"
|
||||
title: vStash S3 Compatible API
|
||||
description: |
|
||||
A high-performance S3-compatible object storage API with management console.
|
||||
|
||||
## Features
|
||||
- Full S3 API compatibility for basic operations
|
||||
- Multipart upload support
|
||||
- Presigned URLs
|
||||
- Management console API
|
||||
- Enterprise storage backend
|
||||
|
||||
## Authentication
|
||||
Uses AWS Signature Version 4 for S3 API endpoints and API keys for management endpoints.
|
||||
contact:
|
||||
email: support@vultr.com
|
||||
name: 'vStash Support'
|
||||
url: https://www.vultr.com
|
||||
x-logo:
|
||||
url: 'https://www.vultr.com/dist/img/brand/vultr-logo-onwhite.svg'
|
||||
backgroundColor: '#fafafa'
|
||||
altText: 'vStash - S3 Compatible API and Management'
|
||||
|
||||
servers:
|
||||
- url: https://vstash.vultr.com
|
||||
description: Production server
|
||||
- url: https://vstash-staging.vultr.com
|
||||
description: Staging server
|
||||
- url: http://localhost:8000
|
||||
description: Development server
|
||||
|
||||
tags:
|
||||
- name: S3 Buckets
|
||||
description: S3 bucket operations
|
||||
- name: S3 Objects
|
||||
description: S3 object operations
|
||||
- name: S3 Multipart
|
||||
description: S3 multipart upload operations
|
||||
- name: Management - Stats
|
||||
description: System statistics and monitoring
|
||||
- name: Management - Credentials
|
||||
description: Access key and credential management
|
||||
- name: Management - Buckets
|
||||
description: Bucket management via console
|
||||
- name: Management - Objects
|
||||
description: Object management via console
|
||||
- name: Management - Presigned URLs
|
||||
description: Presigned URL management
|
||||
|
||||
paths:
|
||||
$ref: './paths.yaml'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
$ref: './schemas.yaml'
|
||||
parameters:
|
||||
$ref: './parameters.yaml'
|
||||
securitySchemes:
|
||||
$ref: './security.yaml'
|
||||
responses:
|
||||
'400':
|
||||
description: Bad Request
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/S3Error'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/S3Error'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
'403':
|
||||
description: Forbidden
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/S3Error'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
'404':
|
||||
description: Not Found
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/S3Error'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
'409':
|
||||
description: Conflict
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/S3Error'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
'500':
|
||||
description: Internal Server Error
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/S3Error'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
20
templates/openapi/yaml_check_script.sh
Executable file
20
templates/openapi/yaml_check_script.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd templates/openapi
|
||||
|
||||
echo "Checking YAML syntax..."
|
||||
|
||||
echo "Checking v1.yaml..."
|
||||
python3 -c "import yaml; yaml.safe_load(open('v1.yaml'))" && echo "✅ v1.yaml is valid" || echo "❌ v1.yaml has syntax errors"
|
||||
|
||||
echo "Checking paths.yaml..."
|
||||
python3 -c "import yaml; yaml.safe_load(open('paths.yaml'))" && echo "✅ paths.yaml is valid" || echo "❌ paths.yaml has syntax errors"
|
||||
|
||||
echo "Checking schemas.yaml..."
|
||||
python3 -c "import yaml; yaml.safe_load(open('schemas.yaml'))" && echo "✅ schemas.yaml is valid" || echo "❌ schemas.yaml has syntax errors"
|
||||
|
||||
echo "Checking parameters.yaml..."
|
||||
python3 -c "import yaml; yaml.safe_load(open('parameters.yaml'))" && echo "✅ parameters.yaml is valid" || echo "❌ parameters.yaml has syntax errors"
|
||||
|
||||
echo "Checking security.yaml..."
|
||||
python3 -c "import yaml; yaml.safe_load(open('security.yaml'))" && echo "✅ security.yaml is valid" || echo "❌ security.yaml has syntax errors"
|
||||
Reference in New Issue
Block a user