Usando o Go V2

O IBM Cloud® Object Storage SDK para Go v2 fornece recursos para aproveitar ao máximo o IBM Cloud Object Storage.

O IBM Cloud Object Storage SDK for Go v2 é abrangente, com muitos recursos e capacidades que excedem o escopo deste guia. Para obter a documentação detalhada de classes e métodos, consulte a documentação de referência da API Go. O código-fonte pode ser localizado no Repositório GitHub.

O que há de novo em v2

O IBM Cloud Object Storage SDK for Go v2 é uma versão modernizada que se baseia na arquitetura do AWS SDK v2, trazendo melhorias significativas:

  • Arquitetura modular: Novo namespace github.com/IBM/ibm-cos-sdk-go-v2 com organização mais limpa
  • Suporte aprimorado ao contexto: Suporte nativo ao context.Context para todas as operações de API, permitindo um melhor tratamento de tempo limite e cancelamento
  • Tratamento moderno de erros: Tipos de erros estruturados que são mais fáceis de inspecionar e tratar programaticamente
  • Suporte a módulos Go: Suporte de primeira classe para módulos Go com controle de versão semântico

Para desenvolvedores que estão migrando de v1, consulte o Guia de Migração.

Obtendo o SDK

A maneira mais fácil de usar o IBM Cloud Object Storage Go SDK v2 é usar os módulos Go para gerenciar as dependências. Se você não estiver familiarizado com os módulos Go, poderá começar a trabalhar usando o guia Módulos Go em 5 minutos.

Pré-requisitos

  • Go 1.23 ou posterior- O SDK requer uma versão mínima do Go 1.23 ou mais recente
  • Uma instância de IBM Cloud Object Storage
  • Uma chave de API de IBM Cloud Identity and Access Management com pelo menos Writer permissões
  • O ID da instância de IBM Cloud Object Storage com a qual você está trabalhando
  • Ponto de extremidade de aquisição de token
  • Terminal em serviço

Esses valores podem ser encontrados no Console IBM Cloud, gerando uma "credencial de serviço".

Instalando o SDK

Use go get para recuperar o SDK para incluí-lo em sua área de trabalho GOPATH ou nas dependências do módulo Go do projeto. O SDK requer uma versão mínima do Go 1.23.

go get github.com/IBM/ibm-cos-sdk-go-v2/config
go get github.com/IBM/ibm-cos-sdk-go-v2/service/s3
go get github.com/IBM/ibm-cos-sdk-go-v2/credentials/ibmiam

Para atualizar o SDK, use go get -u para obter a versão mais recente do SDK:

go get -u github.com/IBM/ibm-cos-sdk-go-v2/config
go get -u github.com/IBM/ibm-cos-sdk-go-v2/service/s3
go get -u github.com/IBM/ibm-cos-sdk-go-v2/credentials/ibmiam

Importar pacotes

Depois de ter instalado o SDK, será necessário importar os pacotes que você requer em seus aplicativos Go para usar o SDK, conforme mostrado no exemplo a seguir:

import (
    "context"
    "github.com/IBM/ibm-cos-sdk-go-v2/aws"
    "github.com/IBM/ibm-cos-sdk-go-v2/config"
    "github.com/IBM/ibm-cos-sdk-go-v2/credentials/ibmiam"
    "github.com/IBM/ibm-cos-sdk-go-v2/service/s3"
    "github.com/IBM/ibm-cos-sdk-go-v2/service/s3/types"
)

Referências do SDK

Classes Principais

  • s3.Client- Cliente principal para interagir com IBM Cloud Object Storage
  • s3.NewFromConfig- Cria um novo cliente S3 a partir da configuração

Credenciais

  • ibmiam.NewStaticCredentials- IBM Provedor de credenciais IAM para autenticação de chave de API
  • config.WithCredentialsProvider- Opção de configuração para definir o provedor de credenciais

Configuração

  • config.LoadDefaultConfig- Carrega a configuração do SDK com as opções especificadas
  • config.WithRegion- Define a região AWS para o cliente
  • config.WithEndpoint- Define o ponto de extremidade do serviço URL

Criação de um cliente e credenciais de serviço de sourcing

Para se conectar ao IBM Cloud Object Storage, um cliente é criado e configurado fornecendo informações de credenciais (Chave de API e ID da instância de serviço). Esses valores também podem ser originados automaticamente de um arquivo de credenciais ou de variáveis de ambiente.

As credenciais podem ser localizadas criando uma Credencial de serviço ou por meio da CLI.

Usando a autenticação do IAM IBM

O exemplo a seguir mostra como criar um cliente usando a autenticação IAM IBM com uma chave de API:

// IBM COS credentials
apiKey := "<API_KEY>"
serviceInstanceID := "<RESOURCE_INSTANCE_ID>"
authEndpoint := "https://iam.cloud.ibm.com/identity/token"
serviceEndpoint := "https://s3.us-south.cloud-object-storage.appdomain.cloud"
region := "us-south"

// Load configuration with IBM IAM credentials
cfg, err := config.LoadDefaultConfig(context.TODO(),
    config.WithCredentialsProvider(
        ibmiam.NewStaticCredentials(authEndpoint, apiKey, serviceInstanceID),
    ),
    config.WithRegion(region),
    config.WithEndpoint(serviceEndpoint),
)
if err != nil {
    log.Fatalf("Failed to load configuration: %v", err)
}

// Create S3 client
client := s3.NewFromConfig(cfg)

As variáveis necessárias são:

  • apiKey- Sua chave de API IBM Cloud com as permissões apropriadas
  • serviceInstanceID- O CRN (Cloud Resource Name) de sua instância IBM Cloud Object Storage
  • authEndpoint- O ponto de extremidade do token IAM IBM (normalmente https://iam.cloud.ibm.com/identity/token)
  • serviceEndpoint- O endpoint URL para a região do seu bucket IBM Cloud Object Storage
  • region- A região onde seu balde está localizado

Exemplos de código

Os exemplos a seguir pressupõem que você já tenha criado um cliente, conforme mostrado na seção anterior.

Criando um depósito

bucketName := "my-new-bucket"

input := &s3.CreateBucketInput{
    Bucket: aws.String(bucketName),
}

_, err = client.CreateBucket(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to create bucket: %v", err)
}

fmt.Printf("Bucket '%s' created successfully\n", bucketName)

Listagem de baldes disponíveis

result, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
if err != nil {
    log.Fatalf("Failed to list buckets: %v", err)
}

fmt.Println("Buckets:")
for _, bucket := range result.Buckets {
    fmt.Printf("  - %s (created: %v)\n",
        aws.ToString(bucket.Name),
        bucket.CreationDate,
    )
}

Listagem de buckets com informações estendidas

IBM Cloud Object Storage fornece uma operação de listagem estendida que retorna informações adicionais sobre o bucket:

input := &s3.ListBucketsExtendedInput{
    IBMServiceInstanceId: aws.String(serviceInstanceID),
    Prefix:               aws.String("my-bucket-prefix"),
    MaxKeys:              aws.Int32(100),
}

result, err := client.ListBucketsExtended(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to list buckets: %v", err)
}

fmt.Println("Extended Bucket Information:")
for _, bucket := range result.Buckets {
    fmt.Printf("  Bucket: %s\n", aws.ToString(bucket.Name))
    fmt.Printf("    Location: %s\n", aws.ToString(bucket.LocationConstraint))
    fmt.Printf("    Created: %v\n", bucket.CreationDate)
}

Recuperação da localização de um balde

bucketName := "my-bucket"

result, err := client.GetBucketLocation(context.TODO(), &s3.GetBucketLocationInput{
    Bucket: aws.String(bucketName),
})
if err != nil {
    log.Fatalf("Failed to get bucket location: %v", err)
}

fmt.Printf("Bucket '%s' is located in: %s\n",
    bucketName,
    result.LocationConstraint,
)

Excluindo um bucket

bucketName := "my-bucket-to-delete"

_, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{
    Bucket: aws.String(bucketName),
})
if err != nil {
    log.Fatalf("Failed to delete bucket: %v", err)
}

fmt.Printf("Bucket '%s' deleted successfully\n", bucketName)

Um bucket deve estar vazio antes de ser excluído.

Carregamento de um objeto em um bucket

bucketName := "my-bucket"
objectKey := "my-object.txt"
content := "Hello, IBM Cloud Object Storage!"

input := &s3.PutObjectInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
    Body:   strings.NewReader(content),
}

result, err := client.PutObject(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to upload object: %v", err)
}

fmt.Printf("Object '%s' uploaded successfully\n", objectKey)
fmt.Printf("ETag: %s\n", aws.ToString(result.ETag))

Download de um objeto de um bucket

bucketName := "my-bucket"
objectKey := "my-object.txt"

result, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
})
if err != nil {
    log.Fatalf("Failed to download object: %v", err)
}
defer result.Body.Close()

// Read the object content
data, err := io.ReadAll(result.Body)
if err != nil {
    log.Fatalf("Failed to read object data: %v", err)
}

fmt.Printf("Object '%s' downloaded successfully\n", objectKey)
fmt.Printf("Content-Type: %s\n", aws.ToString(result.ContentType))
fmt.Printf("Content-Length: %d bytes\n", result.ContentLength)
fmt.Printf("Content:\n%s\n", string(data))

Listando objetos em um depósito

bucketName := "my-bucket"

input := &s3.ListObjectsV2Input{
    Bucket:  aws.String(bucketName),
    MaxKeys: aws.Int32(1000),
}

result, err := client.ListObjectsV2(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to list objects: %v", err)
}

fmt.Printf("Objects in bucket '%s':\n", bucketName)
for _, object := range result.Contents {
    fmt.Printf("  - %s (size: %d bytes, modified: %v)\n",
        aws.ToString(object.Key),
        object.Size,
        object.LastModified,
    )
}

fmt.Printf("\nTotal objects: %d\n", len(result.Contents))

Cópia de um objeto

sourceBucket := "source-bucket"
sourceKey := "source-object.txt"
destinationBucket := "destination-bucket"
destinationKey := "destination-object.txt"

// CopySource format: /source-bucket/source-key
copySource := fmt.Sprintf("/%s/%s", sourceBucket, sourceKey)

input := &s3.CopyObjectInput{
    Bucket:     aws.String(destinationBucket),
    Key:        aws.String(destinationKey),
    CopySource: aws.String(copySource),
}

result, err := client.CopyObject(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to copy object: %v", err)
}

fmt.Printf("Object copied successfully\n")
fmt.Printf("Copy ETag: %s\n", aws.ToString(result.CopyObjectResult.ETag))

Excluindo um Objeto

bucketName := "my-bucket"
objectKey := "object-to-delete.txt"

_, err = client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
})
if err != nil {
    log.Fatalf("Failed to delete object: %v", err)
}

fmt.Printf("Object '%s' deleted successfully\n", objectKey)

Excluindo múltiplos objetos

bucketName := "my-bucket"
objectsToDelete := []string{
    "object1.txt",
    "object2.txt",
    "object3.txt",
}

// Build delete request
var objects []types.ObjectIdentifier
for _, key := range objectsToDelete {
    objects = append(objects, types.ObjectIdentifier{
        Key: aws.String(key),
    })
}

input := &s3.DeleteObjectsInput{
    Bucket: aws.String(bucketName),
    Delete: &types.Delete{
        Objects: objects,
        Quiet:   aws.Bool(false),
    },
}

result, err := client.DeleteObjects(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to delete objects: %v", err)
}

fmt.Printf("Successfully deleted %d objects\n", len(result.Deleted))
for _, deleted := range result.Deleted {
    fmt.Printf("  - %s\n", aws.ToString(deleted.Key))
}

if len(result.Errors) > 0 {
    fmt.Printf("\nFailed to delete %d objects:\n", len(result.Errors))
    for _, err := range result.Errors {
        fmt.Printf("  - %s: %s\n",
            aws.ToString(err.Key),
            aws.ToString(err.Message),
        )
    }
}

Obtenção de metadados de objetos (HEAD)

bucketName := "my-bucket"
objectKey := "my-object.txt"

result, err := client.HeadObject(context.TODO(), &s3.HeadObjectInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
})
if err != nil {
    log.Fatalf("Failed to get object metadata: %v", err)
}

fmt.Printf("Object Metadata for '%s':\n", objectKey)
fmt.Printf("  Content-Type: %s\n", aws.ToString(result.ContentType))
fmt.Printf("  Content-Length: %d bytes\n", result.ContentLength)
fmt.Printf("  ETag: %s\n", aws.ToString(result.ETag))
fmt.Printf("  Last-Modified: %v\n", result.LastModified)

if len(result.Metadata) > 0 {
    fmt.Println("  Custom Metadata:")
    for key, value := range result.Metadata {
        fmt.Printf("    %s: %s\n", key, value)
    }
}

Usando uploads de múltiplas partes

Para objetos grandes, o upload de várias partes oferece melhor rendimento e a capacidade de retomar os uploads. Cada parte deve ter pelo menos 5 MB (exceto a última parte).

bucketName := "my-bucket"
objectKey := "large-object.dat"

// Step 1: Initiate multipart upload
createResp, err := client.CreateMultipartUpload(context.TODO(),
    &s3.CreateMultipartUploadInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    },
)
if err != nil {
    log.Fatalf("Failed to initiate multipart upload: %v", err)
}
uploadID := aws.ToString(createResp.UploadId)
fmt.Printf("Multipart upload initiated with ID: %s\n", uploadID)

// Step 2: Upload parts (minimum 5MB per part except last)
var completedParts []types.CompletedPart
minPartSize := 5 * 1024 * 1024 // 5MB

// Create sample parts
parts := []string{
    strings.Repeat("A", minPartSize),
    strings.Repeat("B", minPartSize),
}

for i, partData := range parts {
    partNumber := int32(i + 1)

    uploadResp, err := client.UploadPart(context.TODO(), &s3.UploadPartInput{
        Bucket:     aws.String(bucketName),
        Key:        aws.String(objectKey),
        PartNumber: aws.Int32(partNumber),
        UploadId:   aws.String(uploadID),
        Body:       strings.NewReader(partData),
    })
    if err != nil {
        // Abort multipart upload on error
        client.AbortMultipartUpload(context.TODO(), &s3.AbortMultipartUploadInput{
            Bucket:   aws.String(bucketName),
            Key:      aws.String(objectKey),
            UploadId: aws.String(uploadID),
        })
        log.Fatalf("Failed to upload part %d: %v", partNumber, err)
    }

    completedParts = append(completedParts, types.CompletedPart{
        ETag:       uploadResp.ETag,
        PartNumber: aws.Int32(partNumber),
    })
    fmt.Printf("Part %d uploaded (ETag: %s)\n", partNumber, aws.ToString(uploadResp.ETag))
}

// Step 3: Complete multipart upload
completeResp, err := client.CompleteMultipartUpload(context.TODO(),
    &s3.CompleteMultipartUploadInput{
        Bucket:   aws.String(bucketName),
        Key:      aws.String(objectKey),
        UploadId: aws.String(uploadID),
        MultipartUpload: &types.CompletedMultipartUpload{
            Parts: completedParts,
        },
    },
)
if err != nil {
    log.Fatalf("Failed to complete multipart upload: %v", err)
}

fmt.Printf("Multipart upload completed successfully\n")
fmt.Printf("Location: %s\n", aws.ToString(completeResp.Location))
fmt.Printf("ETag: %s\n", aws.ToString(completeResp.ETag))

Listagem de uploads de várias partes

bucketName := "my-bucket"

result, err := client.ListMultipartUploads(context.TODO(),
    &s3.ListMultipartUploadsInput{
        Bucket: aws.String(bucketName),
    },
)
if err != nil {
    log.Fatalf("Failed to list multipart uploads: %v", err)
}

fmt.Printf("In-progress multipart uploads in bucket '%s':\n", bucketName)
for _, upload := range result.Uploads {
    fmt.Printf("  Key: %s\n", aws.ToString(upload.Key))
    fmt.Printf("    Upload ID: %s\n", aws.ToString(upload.UploadId))
    fmt.Printf("    Initiated: %v\n", upload.Initiated)
}

Definição de uma configuração de ciclo de vida do bucket

As políticas de arquivamento permitem que você faça a transição automática de objetos para classes de armazenamento de arquivo após um período de tempo especificado:

bucketName := "my-bucket"

// Configure lifecycle rule to archive objects after 90 days
input := &s3.PutBucketLifecycleConfigurationInput{
    Bucket: aws.String(bucketName),
    LifecycleConfiguration: &types.BucketLifecycleConfiguration{
        Rules: []types.LifecycleRule{
            {
                ID:     aws.String("archive-rule"),
                Status: types.ExpirationStatusEnabled,
                Filter: &types.LifecycleRuleFilterMemberPrefix{
                    Value: "documents/",
                },
                Transitions: []types.Transition{
                    {
                        Days:         aws.Int32(90),
                        StorageClass: types.TransitionStorageClassGlacier,
                    },
                },
            },
        },
    },
}

_, err = client.PutBucketLifecycleConfiguration(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to set lifecycle configuration: %v", err)
}

fmt.Printf("Lifecycle configuration set for bucket '%s'\n", bucketName)

Obter uma configuração do ciclo de vida do bucket

bucketName := "my-bucket"

result, err := client.GetBucketLifecycleConfiguration(context.TODO(),
    &s3.GetBucketLifecycleConfigurationInput{
        Bucket: aws.String(bucketName),
    },
)
if err != nil {
    log.Fatalf("Failed to get lifecycle configuration: %v", err)
}

fmt.Printf("Lifecycle rules for bucket '%s':\n", bucketName)
for _, rule := range result.Rules {
    fmt.Printf("  Rule ID: %s\n", aws.ToString(rule.ID))
    fmt.Printf("    Status: %s\n", rule.Status)

    for _, transition := range rule.Transitions {
        fmt.Printf("    Transition to %s after %d days\n",
            transition.StorageClass,
            aws.ToInt32(transition.Days),
        )
    }
}

Ativação do controle de versão do bucket

bucketName := "my-bucket"

// Enable versioning
_, err = client.PutBucketVersioning(context.TODO(), &s3.PutBucketVersioningInput{
    Bucket: aws.String(bucketName),
    VersioningConfiguration: &types.VersioningConfiguration{
        Status: types.BucketVersioningStatusEnabled,
    },
})
if err != nil {
    log.Fatalf("Failed to enable versioning: %v", err)
}

fmt.Printf("Versioning enabled for bucket '%s'\n", bucketName)

Listagem de versões de objetos

bucketName := "my-bucket"

result, err := client.ListObjectVersions(context.TODO(),
    &s3.ListObjectVersionsInput{
        Bucket: aws.String(bucketName),
    },
)
if err != nil {
    log.Fatalf("Failed to list object versions: %v", err)
}

fmt.Printf("Object versions in bucket '%s':\n", bucketName)
for _, version := range result.Versions {
    fmt.Printf("  Key: %s\n", aws.ToString(version.Key))
    fmt.Printf("    Version ID: %s\n", aws.ToString(version.VersionId))
    fmt.Printf("    Is Latest: %t\n", aws.ToBool(version.IsLatest))
    fmt.Printf("    Last Modified: %v\n", version.LastModified)
}

Definição da configuração do site CORS

bucketName := "my-bucket"

// Set CORS configuration
input := &s3.PutBucketCorsInput{
    Bucket: aws.String(bucketName),
    CORSConfiguration: &types.CORSConfiguration{
        CORSRules: []types.CORSRule{
            {
                AllowedHeaders: []string{"*"},
                AllowedMethods: []string{"GET", "PUT", "POST", "DELETE"},
                AllowedOrigins: []string{"https://example.com"},
                ExposeHeaders:  []string{"ETag"},
                MaxAgeSeconds:  aws.Int32(3000),
            },
        },
    },
}

_, err = client.PutBucketCors(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to set CORS configuration: %v", err)
}

fmt.Printf("CORS configuration set for bucket '%s'\n", bucketName)

Configuração de marcação de objetos

bucketName := "my-bucket"
objectKey := "my-object.txt"

// Set object tags
input := &s3.PutObjectTaggingInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
    Tagging: &types.Tagging{
        TagSet: []types.Tag{
            {
                Key:   aws.String("Department"),
                Value: aws.String("Finance"),
            },
            {
                Key:   aws.String("Project"),
                Value: aws.String("Q4-2024"),
            },
            {
                Key:   aws.String("Classification"),
                Value: aws.String("Confidential"),
            },
        },
    },
}

_, err = client.PutObjectTagging(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to set object tags: %v", err)
}

fmt.Printf("Tags set for object '%s'\n", objectKey)

Obtenção de tags de objeto

bucketName := "my-bucket"
objectKey := "my-object.txt"

result, err := client.GetObjectTagging(context.TODO(), &s3.GetObjectTaggingInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
})
if err != nil {
    log.Fatalf("Failed to get object tags: %v", err)
}

fmt.Printf("Tags for object '%s':\n", objectKey)
for _, tag := range result.TagSet {
    fmt.Printf("  %s: %s\n", aws.ToString(tag.Key), aws.ToString(tag.Value))
}

Restauração de um objeto arquivado

Os objetos nas classes de armazenamento de arquivos devem ser restaurados antes de poderem ser acessados:

bucketName := "my-bucket"
objectKey := "archived-object.txt"

// Restore object with accelerated retrieval (2 hours)
input := &s3.RestoreObjectInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
    RestoreRequest: &types.RestoreRequest{
        Days: aws.Int32(7), // Number of days to keep restored copy
        GlacierJobParameters: &types.GlacierJobParameters{
            Tier: types.TierAccelerated, // Accelerated (2 hours) or Standard (12 hours)
        },
    },
}

_, err = client.RestoreObject(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to restore object: %v", err)
}

fmt.Printf("Restore request submitted for object '%s'\n", objectKey)
fmt.Println("The object will be available for download in approximately 2 hours")

IBM Cloud Object Storage suporta arquivamento acelerado com tempos de restauração de 2 horas ou 12 horas, dependendo da camada selecionada.

Definição da configuração de proteção de caçamba

IBM Cloud Object Storage suporta Immutable Object Storage para evitar que os objetos sejam modificados ou excluídos:

bucketName := "my-protected-bucket"

// Set protection configuration with default retention period
input := &s3.PutBucketProtectionConfigurationInput{
    Bucket: aws.String(bucketName),
    ProtectionConfiguration: &types.ProtectionConfiguration{
        Status:                            types.BucketProtectionStatusRetention,
        MinimumRetention:                  &types.BucketProtectionMinimumRetention{Days: aws.Int32(90)},
        MaximumRetention:                  &types.BucketProtectionMaximumRetention{Days: aws.Int32(365)},
        DefaultRetention:                  &types.BucketProtectionDefaultRetention{Days: aws.Int32(120)},
        EnablePermanentRetention:          aws.Bool(false),
    },
}

_, err = client.PutBucketProtectionConfiguration(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to set protection configuration: %v", err)
}

fmt.Printf("Protection configuration set for bucket '%s'\n", bucketName)
fmt.Println("Objects will be protected with a default retention of 120 days")

Obtendo a configuração da proteção de caçamba

bucketName := "my-protected-bucket"

result, err := client.GetBucketProtectionConfiguration(context.TODO(),
    &s3.GetBucketProtectionConfigurationInput{
        Bucket: aws.String(bucketName),
    },
)
if err != nil {
    log.Fatalf("Failed to get protection configuration: %v", err)
}

fmt.Printf("Protection configuration for bucket '%s':\n", bucketName)
fmt.Printf("  Status: %s\n", result.ProtectionConfiguration.Status)
fmt.Printf("  Minimum Retention: %d days\n",
    aws.ToInt32(result.ProtectionConfiguration.MinimumRetention.Days))
fmt.Printf("  Maximum Retention: %d days\n",
    aws.ToInt32(result.ProtectionConfiguration.MaximumRetention.Days))
fmt.Printf("  Default Retention: %d days\n",
    aws.ToInt32(result.ProtectionConfiguration.DefaultRetention.Days))

Definição da retenção de objetos

bucketName := "my-protected-bucket"
objectKey := "important-document.pdf"

// Set retention until a specific date
retainUntilDate := time.Now().AddDate(0, 6, 0) // 6 months from now

input := &s3.PutObjectRetentionInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
    Retention: &types.ObjectLockRetention{
        Mode:            types.ObjectLockRetentionModeCompliance,
        RetainUntilDate: aws.Time(retainUntilDate),
    },
}

_, err = client.PutObjectRetention(context.TODO(), input)
if err != nil {
    log.Fatalf("Failed to set object retention: %v", err)
}

fmt.Printf("Retention set for object '%s' until %v\n", objectKey, retainUntilDate)

Obtenção de retenção de objetos

bucketName := "my-protected-bucket"
objectKey := "important-document.pdf"

result, err := client.GetObjectRetention(context.TODO(), &s3.GetObjectRetentionInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(objectKey),
})
if err != nil {
    log.Fatalf("Failed to get object retention: %v", err)
}

fmt.Printf("Retention for object '%s':\n", objectKey)
fmt.Printf("  Mode: %s\n", result.Retention.Mode)
fmt.Printf("  Retain Until: %v\n", result.Retention.RetainUntilDate)

Próximas etapas