Skip to content

Commit

Permalink
Merge pull request #81 from cudoventures/storage-disks
Browse files Browse the repository at this point in the history
Storage disks
  • Loading branch information
ArthurVerrept authored Apr 11, 2024
2 parents 1c733d0 + 6472f46 commit 97845d6
Show file tree
Hide file tree
Showing 16 changed files with 868 additions and 28 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ See docs directory

If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).

The Cudo API client is generated in the cudo-compute-market repo using the "make tf" command, copy the generated "compute" folder from cudo-compute-market/clients/go-grpc/ to terraform-provider-cudo/internal/.
The Cudo API client is generated in the cudo-compute-market repo using the `make tf` command, copy the generated "compute" folder from cudo-compute-market/clients/go-grpc/ to terraform-provider-cudo/internal/.

To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.

Expand Down
35 changes: 35 additions & 0 deletions docs/data-sources/storage_disk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "cudo_storage_disk Data Source - terraform-provider-cudo"
subcategory: ""
description: |-
Disk data source
---

# cudo_storage_disk (Data Source)

Disk data source

## Example Usage

```terraform
data "cudo_storage_disk" "storage_disk_datasource" {
id = "my-disk"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `id` (String) Storage disk ID.

### Optional

- `project_id` (String) The unique identifier of the project the disk is in.

### Read-Only

- `data_center_id` (String) The unique identifier of the datacenter where the disk is located.
- `size_gib` (Number) Size of the storage disk in GiB
34 changes: 34 additions & 0 deletions docs/resources/storage_disk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "cudo_storage_disk Resource - terraform-provider-cudo"
subcategory: ""
description: |-
Storage disk resource
---

# cudo_storage_disk (Resource)

Storage disk resource

## Example Usage

```terraform
resource "cudo_storage_disk" "my-storage-disk" {
data_center_id = "gb-bournemouth-1"
id = "my-disk"
size_gib = 100
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `data_center_id` (String) The unique identifier of the datacenter where the disk is located.
- `id` (String) The unique identifier of the storage disk
- `size_gib` (Number) Size of the storage disk in GiB

### Optional

- `project_id` (String) The project the storage disk is in.
22 changes: 21 additions & 1 deletion docs/resources/vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,15 @@ resource "cudo_vm" "my-vm-max-price" {
]
}
resource "cudo_storage_disk" "my-storage-disk" {
data_center_id = "gb-bournemouth-1"
id = "my-disk"
size_gib = 100
}
# pick a specific data center and machine type
resource "cudo_vm" "my-vm" {
depends_on = [cudo_storage_disk.my-storage-disk]
id = "terra-vm-1"
machine_type = "standard"
data_center_id = "gb-bournemouth-1"
Expand All @@ -41,6 +48,11 @@ resource "cudo_vm" "my-vm" {
image_id = "debian-11"
size_gib = 50
}
storage_disks = [
{
disk_id = "my-disk"
}
]
ssh_key_source = "project"
start_script = <<EOF
touch /multiline-script.txt
Expand All @@ -64,7 +76,6 @@ resource "cudo_vm" "my-vm" {
- `gpu_model` (String) The model of the GPU.
- `gpus` (Number) Number of GPUs
- `machine_type` (String) VM machine type, from machine type data source
- `max_price_hr` (String) The maximum price per hour for the VM instance
- `memory_gib` (Number) Amount of VM memory in GiB
- `metadata` (Map of String) Metadata values to associate with the VM instance
- `networks` (Attributes List) Network adapters for private networks (see [below for nested schema](#nestedatt--networks))
Expand All @@ -74,6 +85,7 @@ resource "cudo_vm" "my-vm" {
- `ssh_key_source` (String) Which SSH keys to add to the VM: project (default), user or custom
- `ssh_keys` (List of String) List of SSH keys to add to the VM, ssh_key_source must be set to custom
- `start_script` (String) A script to run when VM boots
- `storage_disks` (Attributes Set) Specification for storage disks (see [below for nested schema](#nestedatt--storage_disks))
- `vcpus` (Number) Number of VCPUs

### Read-Only
Expand Down Expand Up @@ -111,3 +123,11 @@ Read-Only:

- `external_ip_address` (String) The external IP address of the NIC.
- `internal_ip_address` (String) The internal IP address of the NIC.


<a id="nestedatt--storage_disks"></a>
### Nested Schema for `storage_disks`

Required:

- `disk_id` (String) ID of storage disk to attach to vm
3 changes: 3 additions & 0 deletions examples/data-sources/cudo_storage_disk/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "cudo_storage_disk" "storage_disk_datasource" {
id = "my-disk"
}
5 changes: 5 additions & 0 deletions examples/resources/cudo_storage_disk/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "cudo_storage_disk" "my-storage-disk" {
data_center_id = "gb-bournemouth-1"
id = "my-disk"
size_gib = 100
}
12 changes: 12 additions & 0 deletions examples/resources/cudo_vm/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ resource "cudo_vm" "my-vm-max-price" {
]
}

resource "cudo_storage_disk" "my-storage-disk" {
data_center_id = "gb-bournemouth-1"
id = "my-disk"
size_gib = 100
}

# pick a specific data center and machine type
resource "cudo_vm" "my-vm" {
depends_on = [cudo_storage_disk.my-storage-disk]
id = "terra-vm-1"
machine_type = "standard"
data_center_id = "gb-bournemouth-1"
Expand All @@ -26,6 +33,11 @@ resource "cudo_vm" "my-vm" {
image_id = "debian-11"
size_gib = 50
}
storage_disks = [
{
disk_id = "my-disk"
}
]
ssh_key_source = "project"
start_script = <<EOF
touch /multiline-script.txt
Expand Down
8 changes: 5 additions & 3 deletions internal/provider/network_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,11 @@ func (r *NetworkResource) Create(ctx context.Context, req resource.CreateRequest
return
}

state.Gateway = types.StringValue(network.Gateway)
state.ExternalIPAddress = types.StringValue(network.ExternalIpAddress)
state.InternalIPAddress = types.StringValue(network.InternalIpAddress)
if network != nil {
state.Gateway = types.StringValue(network.Gateway)
state.ExternalIPAddress = types.StringValue(network.ExternalIpAddress)
state.InternalIPAddress = types.StringValue(network.InternalIpAddress)
}

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ func (p *CudoProvider) Configure(ctx context.Context, req provider.ConfigureRequ
func (p *CudoProvider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
NewSecurityGroupResource,
NewStorageDiskResource,
NewNetworkResource,
NewVMImageResource,
NewVMResource,
Expand All @@ -206,6 +207,7 @@ func (p *CudoProvider) Resources(ctx context.Context) []func() resource.Resource

func (p *CudoProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewStorageDiskDataSource,
NewVMImagesDataSource,
NewVMDataCentersDataSource,
NewVMDataSource,
Expand Down
1 change: 0 additions & 1 deletion internal/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServe
}

func getProviderConfig() string {

return fmt.Sprintf(`
provider "cudo" {
api_key = "%s"
Expand Down
112 changes: 112 additions & 0 deletions internal/provider/storage_disk_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package provider

import (
"context"
"fmt"

"github.com/CudoVentures/terraform-provider-cudo/internal/compute/vm"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

// Ensure provider defined types fully satisfy framework interfaces.
var _ datasource.DataSource = &StorageDiskDataSource{}

func NewStorageDiskDataSource() datasource.DataSource {
return &StorageDiskDataSource{}
}

// SecurityGroupsDataSource defines the data source implementation.
type StorageDiskDataSource struct {
client *CudoClientData
}

// SecurityGroupDataSourceModel describes the resource data model.
type StorageDiskDataSourceModel struct {
ID types.String `tfsdk:"id"`
ProjectID types.String `tfsdk:"project_id"`
DataCenterID types.String `tfsdk:"data_center_id"`
SizeGib types.Int64 `tfsdk:"size_gib"`
}

func (d *StorageDiskDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = "cudo_storage_disk"
}

func (d *StorageDiskDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Disk data source",
Description: "Gets a Disk",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "Storage disk ID.",
Required: true,
},
"project_id": schema.StringAttribute{
Description: "The unique identifier of the project the disk is in.",
Optional: true,
},
"data_center_id": schema.StringAttribute{
Description: "The unique identifier of the datacenter where the disk is located.",
Computed: true,
},
"size_gib": schema.Int64Attribute{
Description: "Size of the storage disk in GiB",
Computed: true,
},
},
}
}

func (d *StorageDiskDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*CudoClientData)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *CudoClient, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

d.client = client
}

func (d *StorageDiskDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var state StorageDiskDataSourceModel

resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)

if resp.Diagnostics.HasError() {
return
}

projectId := d.client.DefaultProjectID
if !state.ProjectID.IsNull() {
projectId = state.ProjectID.ValueString()
}

res, err := d.client.VMClient.GetDisk(ctx, &vm.GetDiskRequest{
ProjectId: projectId,
Id: state.ID.ValueString(),
})
if err != nil {
resp.Diagnostics.AddError(
"Unable to read storage disks",
err.Error(),
)
return
}

state.DataCenterID = types.StringValue(res.Disk.DataCenterId)
state.SizeGib = types.Int64Value(int64(res.Disk.SizeGib))

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
71 changes: 71 additions & 0 deletions internal/provider/storage_disk_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package provider

import (
"context"
"fmt"
"testing"

"github.com/CudoVentures/terraform-provider-cudo/internal/compute/vm"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
)

func TestAcc_StorageDiskDataSource(t *testing.T) {
var cancel context.CancelFunc
ctx := context.Background()
deadline, ok := t.Deadline()
if ok {
ctx, cancel = context.WithDeadline(ctx, deadline)
defer cancel()
}
name := "storage-disk-data-source" + testRunID

resourcesConfig := fmt.Sprintf(`
resource "cudo_storage_disk" "disk_ds" {
data_center_id = "black-mesa"
id = "%s"
size_gib = 15
}`, name)

testAccStorageDiskDataSourceConfig := fmt.Sprintf(`
data "cudo_storage_disk" "storage_disk_datasource" {
id = "%s"
}`, name)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
CheckDestroy: func(state *terraform.State) error {
cl, _ := getClients(t)

ins, err := cl.GetDisk(ctx, &vm.GetDiskRequest{
Id: name,
ProjectId: projectID,
})

if err == nil && ins.Disk.DiskState != vm.Disk_DISK_STATE_DELETE {
res, err := cl.DeleteStorageDisk(ctx, &vm.DeleteStorageDiskRequest{
Id: name,
ProjectId: projectID,
})
t.Logf("(%s) %#v: %v", ins.Disk.DiskState, res, err)

return fmt.Errorf("disk resource not destroyed %s , %s", ins.Disk.Id, ins.Disk.DiskState)
}
return nil
},

ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: getProviderConfig() + resourcesConfig,
},
{
Config: getProviderConfig() + resourcesConfig + testAccStorageDiskDataSourceConfig,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.cudo_storage_disk.storage_disk_datasource", "id", name),
resource.TestCheckResourceAttr("data.cudo_storage_disk.storage_disk_datasource", "size_gib", "15"),
),
},
},
})
}
Loading

0 comments on commit 97845d6

Please sign in to comment.