Skip to content

Commit

Permalink
Merge pull request #160 from SpiffyEight77/feat/import-storage-bucket
Browse files Browse the repository at this point in the history
Add source_file to incus_storage_bucket
  • Loading branch information
maveonair authored Nov 21, 2024
2 parents 9ff42c4 + 99c2b6d commit ae4861a
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
12 changes: 12 additions & 0 deletions docs/resources/storage_bucket.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ resource "incus_storage_bucket" "bucket1" {
}
```

## Example to create bucket from backup file

```hcl
resource "incus_storage_bucket" "bucket_from_backup" {
name = "restored-bucket"
pool = "default"
source_file = "/path/to/backup.tar.gz"
}
```

## Argument Reference

* `name` - **Required** - Name of the storage bucket.
Expand All @@ -35,6 +45,8 @@ resource "incus_storage_bucket" "bucket1" {

* `target` - *Optional* - Specify a target node in a cluster.

* `source_file` - *Optional* - Path to a backup file from which the bucket will be created.


## Attribute Reference

Expand Down
67 changes: 66 additions & 1 deletion internal/storage/resource_storage_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package storage
import (
"context"
"fmt"
"os"

"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/attr"
Expand Down Expand Up @@ -33,6 +34,7 @@ type StorageBucketModel struct {
Target types.String `tfsdk:"target"`
Remote types.String `tfsdk:"remote"`
Config types.Map `tfsdk:"config"`
SourceFile types.String `tfsdk:"source_file"`

// Computed.
Location types.String `tfsdk:"location"`
Expand Down Expand Up @@ -110,6 +112,16 @@ func (r StorageBucketResource) Schema(ctx context.Context, req resource.SchemaRe
Default: mapdefault.StaticValue(types.MapValueMust(types.StringType, map[string]attr.Value{})),
},

"source_file": schema.StringAttribute{
Optional: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
},

// Computed.

"location": schema.StringAttribute{
Expand Down Expand Up @@ -143,6 +155,16 @@ func (r StorageBucketResource) Create(ctx context.Context, req resource.CreateRe
return
}

if !plan.SourceFile.IsNull() {
r.importStoragePoolBucket(ctx, resp, &plan)
return
} else {
r.createStoragePoolBucket(ctx, resp, &plan)
return
}
}

func (r StorageBucketResource) createStoragePoolBucket(ctx context.Context, resp *resource.CreateResponse, plan *StorageBucketModel) {
remote := plan.Remote.ValueString()
project := plan.Project.ValueString()
target := plan.Target.ValueString()
Expand Down Expand Up @@ -176,7 +198,50 @@ func (r StorageBucketResource) Create(ctx context.Context, req resource.CreateRe
}

// Update Terraform state.
diags = r.SyncState(ctx, &resp.State, server, plan)
diags = r.SyncState(ctx, &resp.State, server, *plan)
resp.Diagnostics.Append(diags...)
}

func (r StorageBucketResource) importStoragePoolBucket(ctx context.Context, resp *resource.CreateResponse, plan *StorageBucketModel) {
remote := plan.Remote.ValueString()
project := plan.Project.ValueString()
target := plan.Target.ValueString()
sourceFile := plan.SourceFile.ValueString()
server, err := r.provider.InstanceServer(remote, project, target)
if err != nil {
resp.Diagnostics.Append(errors.NewInstanceServerError(err))
return
}

poolName := plan.Pool.ValueString()
bucketName := plan.Name.ValueString()

file, err := os.Open(sourceFile)
if err != nil {
resp.Diagnostics.AddError(fmt.Sprintf("Failed to open source file %q", sourceFile), err.Error())
return
}
defer file.Close()

args := incus.StoragePoolBucketBackupArgs{
Name: bucketName,
BackupFile: file,
}

opImport, err := server.CreateStoragePoolBucketFromBackup(poolName, args)
if err != nil {
resp.Diagnostics.AddError(fmt.Sprintf("Failed to create storage bucket from file %q", bucketName), err.Error())
return
}

err = opImport.Wait()
if err != nil {
resp.Diagnostics.AddError(fmt.Sprintf("Failed to create storage bucket from file %q", bucketName), err.Error())
return
}

// Update Terraform state.
diags := r.SyncState(ctx, &resp.State, server, *plan)
resp.Diagnostics.Append(diags...)
}

Expand Down

0 comments on commit ae4861a

Please sign in to comment.