β οΈ Community-Maintained SDKThis SDK was created by the community due to the lack of an official NetApp StorageGRID SDK for Go. It is designed to fulfill the needs of its maintainers and contributors. If you find something missing or spot a bug, please open an issue or submit a pull request! Contributions are highly encouraged.
Note
This SDK was originally developed by an employee and it's history can be seen in the original repository. The original repository is no longer actively maintained, and this copy serves as the new home for ongoing development and contributions from the community.
storagegrid-sdk-go is an unofficial Go SDK for interacting with NetApp StorageGRID. It provides programmatic access to StorageGRID's REST APIs, enabling you to manage tenants, buckets, users, S3 access keys, health, regions, gateway configs, and more.
NetApp StorageGRID exposes two distinct REST API surfaces:
- Grid Management API: For grid administrators to manage the entire StorageGRID system
- Tenant Management API: For tenant users to manage their specific tenant resources
This SDK reflects this architecture with corresponding client types. For more details on StorageGRID APIs, see the official documentation.
- Tenants: Create, list, update, delete, and monitor tenant usage
- Health: Monitor grid health status (alarms, alerts, node connectivity)
- Regions: List available regions for grid and tenant contexts
- HA Groups: Manage High Availability groups
- Gateway Configs: Configure load balancer endpoints
- Buckets: Create, list, delete, drain buckets; monitor bucket usage and compliance settings
- Users: Manage tenant users with password management
- Groups: Manage tenant groups with policies and permissions
- S3 Access Keys: Generate and manage S3 access keys for users
- Regions: List tenant-specific regions
- Auto-authentication: Automatic token management with expiration handling
- Context support: All operations support Go context for cancellation and timeouts
- Interface-based design: Easy mocking and testing with provided mock implementations
- SSL configuration: Optional SSL verification skip for development environments
- Go 1.25 or newer (see
go.modfor the exact version) - Access to a NetApp StorageGRID instance with appropriate credentials
go get github.com/bedag/storagegrid-sdk-gopackage main
import (
"context"
"fmt"
"log"
"github.com/bedag/storagegrid-sdk-go/client"
"github.com/bedag/storagegrid-sdk-go/models"
)
func main() {
ctx := context.Background()
// Create a grid client for system administration
gridClient, err := client.NewGridClient(
client.WithEndpoint("https://your-storagegrid-endpoint"),
client.WithCredentials(&models.Credentials{
Username: "admin",
Password: "your-password",
}),
)
if err != nil {
log.Fatal(err)
}
// Check grid health
health, err := gridClient.Health().Get(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Grid Status: %s\n", func() string {
if health.AllGreen() {
return "β
Healthy"
}
return "β οΈ Issues detected"
}())
}Both client types support the same configuration options:
import (
"github.com/bedag/storagegrid-sdk-go/client"
"github.com/bedag/storagegrid-sdk-go/models"
)
// Common configuration options
opts := []client.ClientOption{
client.WithEndpoint("https://your-storagegrid.example.com"),
client.WithCredentials(&models.Credentials{
Username: "your-username",
Password: "your-password",
// AccountId: &accountID, // Required for tenant operations only
}),
// client.WithSkipSSL(), // Skip SSL verification (development only)
}Use GridClient for system-wide administration operations. This requires grid administrator privileges.
π§ Setup Grid Client
gridClient, err := client.NewGridClient(
client.WithEndpoint("https://your-storagegrid.example.com"),
client.WithCredentials(&models.Credentials{
Username: "grid-admin",
Password: "admin-password",
// No AccountId needed for grid operations
}),
)
if err != nil {
return fmt.Errorf("failed to create grid client: %w", err)
}// List all tenant accounts
tenants, err := gridClient.Tenant().List(ctx)
if err != nil {
return fmt.Errorf("failed to list tenants: %w", err)
}
// Create a new tenant
tenant := &models.Tenant{
Name: "my-tenant",
Description: "Some description",
Capabilities: []string{"management", "s3"},
Policy: &models.TenantPolicy{
UseAccountIdentitySource: false,
AllowPlatformServices: true,
QuotaObjectBytes: 100 * 1024 * 1024 * 1024, // 100GB
},
}
createdTenant, err := gridClient.Tenant().Create(ctx, tenant)
if err != nil {
return fmt.Errorf("failed to create tenant: %w", err)
}
fmt.Printf("Created tenant: %s (ID: %s)\n", *createdTenant.Name, createdTenant.Id)health, err := gridClient.Health().Get(ctx)
if err != nil {
return fmt.Errorf("failed to get health status: %w", err)
}
// Check overall status
if health.AllGreen() {
log.Println("β
Grid is healthy")
} else {
log.Printf("β οΈ Grid has issues - Connected nodes: %d, Alerts: %d",
*health.Nodes.Connected,
*health.Alerts.Critical + *health.Alerts.Major)
}Use TenantClient for tenant-specific operations. This requires tenant user credentials and an account ID.
π§ Setup Tenant Client
accountID := "12345678901234567890"
tenantClient, err := client.NewTenantClient(
client.WithEndpoint("https://your-storagegrid.example.com"),
client.WithCredentials(&models.Credentials{
Username: "tenant-admin",
Password: "tenant-password",
AccountId: &accountID, // Required for tenant operations
}),
)
if err != nil {
return fmt.Errorf("failed to create tenant client: %w", err)
}// Create a bucket with versioning enabled
bucket := &models.Bucket{
Name: "my-application-data",
Region: "us-east-1",
EnableVersioning: true,
S3ObjectLock: &models.BucketS3ObjectLockSettings{
Enabled: false,
},
}
createdBucket, err := tenantClient.Bucket().Create(ctx, bucket)
if err != nil {
return fmt.Errorf("failed to create bucket: %w", err)
}
// List all buckets in the tenant
buckets, err := tenantClient.Bucket().List(ctx)
if err != nil {
return fmt.Errorf("failed to list buckets: %w", err)
}
for _, bucket := range *buckets {
fmt.Printf("Bucket: %s (Created: %s)\n", bucket.Name, bucket.CreationTime.Format("2006-01-02"))
}// Create a new user
user := &models.User{
UniqueName: "application-user", // Will be prefixed with "user/"
DisplayName: "Application Service User",
Disable: false,
}
createdUser, err := tenantClient.Users().Create(ctx, user)
if err != nil {
return fmt.Errorf("failed to create user: %w", err)
}
// Generate S3 access keys for the user
accessKey := &models.S3AccessKey{
Expires: nil, // No expiration
}
keys, err := tenantClient.S3AccessKeys().CreateForUser(ctx, *createdUser.Id, accessKey)
if err != nil {
return fmt.Errorf("failed to create access keys: %w", err)
}
fmt.Printf("Access Key: %s\n", *keys.AccessKey)
fmt.Printf("Secret Key: %s\n", *keys.SecretAccessKey)Comprehensive examples are available in the examples/ directory:
- Grid Management: Health monitoring, tenant management
- Tenant Operations: Bucket operations, user management
- Testing: Unit tests with mocks, integration tests
health, err := gridClient.Health().Get(ctx)
if err != nil {
log.Fatalf("Health check failed: %v", err)
}
fmt.Printf("Grid Status: All Green = %v\n", health.AllGreen())tenant := &models.Tenant{
Name: "my-tenant",
Capabilities: []string{"s3", "management"},
}
createdTenant, err := gridClient.Tenant().Create(ctx, tenant)bucket := &models.Bucket{
Name: "my-bucket",
Region: "us-east-1",
}
createdBucket, err := tenantClient.Bucket().Create(ctx, bucket)For complete working examples, see the examples/ directory.
The SDK provides comprehensive mock implementations for all service interfaces, making unit testing straightforward:
package main
import (
"context"
"testing"
"github.com/bedag/storagegrid-sdk-go/models"
"github.com/bedag/storagegrid-sdk-go/testing"
)
func TestTenantOperations(t *testing.T) {
ctx := context.Background()
// Create mock tenant service
mockService := &testing.MockTenantService{
ListFunc: func(ctx context.Context) (*[]models.Tenant, error) {
return &[]models.Tenant{
{
Id: "tenant-123",
Name: "Test Tenant",
},
}, nil
},
CreateFunc: func(ctx context.Context, tenant *models.Tenant) (*models.Tenant, error) {
tenant.Id = "new-tenant-456"
return tenant, nil
},
}
// Use mock in your application code
tenants, err := mockService.List(ctx)
if err != nil {
t.Fatalf("Expected no error, got %v", err)
}
if len(*tenants) != 1 {
t.Fatalf("Expected 1 tenant, got %d", len(*tenants))
}
if (*tenants)[0].Id != "tenant-123" {
t.Fatalf("Expected tenant ID 'tenant-123', got %s", (*tenants)[0].Id)
}
}For integration tests against a real StorageGRID instance:
func TestIntegration(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test in short mode")
}
endpoint := os.Getenv("STORAGEGRID_ENDPOINT")
username := os.Getenv("STORAGEGRID_USERNAME")
password := os.Getenv("STORAGEGRID_PASSWORD")
if endpoint == "" || username == "" || password == "" {
t.Skip("Missing required environment variables for integration test")
}
ctx := context.Background()
client, err := client.NewGridClient(
client.WithEndpoint(endpoint),
client.WithCredentials(&models.Credentials{
Username: username,
Password: password,
}),
)
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
// Test actual API calls
health, err := client.Health().Get(ctx)
if err != nil {
t.Fatalf("Failed to get health: %v", err)
}
t.Logf("Grid health status: operative=%v", health.Operative(1))
}The testing package provides mocks for all service interfaces:
MockTenantService- Grid tenant managementMockBucketService- Bucket operationsMockTenantUserService- Tenant user managementMockTenantGroupService- Tenant group managementMockS3AccessKeyService- S3 access key managementMockHealthService- Health monitoringMockHAGroupService- HA group managementMockGatewayConfigService- Gateway configurationMockRegionService- Region management
This SDK provides access to StorageGRID's dual API architecture:
Used for system-wide administration with grid administrator credentials:
| Service | Endpoint | Operations | Description |
|---|---|---|---|
| Tenants | /grid/accounts |
Create, Read, Update, Delete, List | Manage tenant accounts |
| Health | /grid/health |
Read | Monitor grid health, alarms, alerts, node status |
| Regions | /grid/regions |
List | Manage grid-wide regions |
| HA Groups | /private/ha-groups |
Create, Read, Update, Delete, List | Configure High Availability groups |
| Gateways | /private/gateway-configs |
Create, Read, Update, Delete, List | Manage load balancer endpoints |
Used for tenant-specific operations with tenant user credentials:
| Service | Endpoint | Operations | Description |
|---|---|---|---|
| Buckets | /org/containers |
Create, Read, Delete, List, Drain | Manage S3 buckets within tenant |
| Users | /org/users |
Create, Read, Update, Delete, List | Manage tenant users |
| Groups | /org/groups |
Create, Read, Update, Delete, List | Manage tenant groups and permissions |
| S3 Keys | /org/users/*/s3-access-keys |
Create, Read, Delete, List | Generate and manage S3 access credentials |
| Regions | /org/regions |
List | List tenant-accessible regions |
| Usage | /org/usage |
Read | Monitor tenant usage statistics |
π Official Documentation: For comprehensive API documentation, refer to the NetApp StorageGRID REST API Reference.
storagegrid-sdk-go/
βββ client/ # Client implementations
β βββ client.go # Base HTTP client with authentication
β βββ grid.go # Grid administrator client
β βββ tenant.go # Tenant client
βββ models/ # Data models for API requests/responses
β βββ auth.go # Authentication models
β βββ buckets.go # Bucket-related models
β βββ tenants.go # Tenant models
β βββ users.go # User models
β βββ health.go # Health status models
β βββ ... # Other model files
βββ services/ # Service interfaces and implementations
β βββ interface.go # Base HTTP client interface
β βββ tenant.go # Tenant management service
β βββ buckets.go # Bucket management service
β βββ health.go # Health monitoring service
β βββ ... # Other service files
βββ testing/ # Mock implementations for testing
βββ tenant_mock.go # Mock tenant service
βββ bucket_mock.go # Mock bucket service
βββ ... # Other mock files
We welcome contributions! Here's how you can help:
- Report Issues: Found a bug or missing feature? Open an issue
- Submit Pull Requests: Have a fix or new feature? Submit a PR
- Improve Documentation: Help make this README and code comments better
- Add Tests: Increase test coverage for reliability
- Follow Go conventions and best practices
- Add appropriate error handling and logging
- Include tests for new functionality
- Update documentation for new features
- Maintain interface compatibility when possible
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.