Skip to content

Commit

Permalink
CP-50592 [TF provider] Implement Pool Join
Browse files Browse the repository at this point in the history
Signed-off-by: Fei Su <fei.su@cloud.com>
  • Loading branch information
acefei committed Nov 1, 2024
1 parent 21269c5 commit b2ed041
Show file tree
Hide file tree
Showing 32 changed files with 723 additions and 275 deletions.
12 changes: 9 additions & 3 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ default: testacc
# Run acceptance tests
.PHONY: testacc
testacc: provider ## make testacc
source .env && TF_ACC=1 go test ./xenserver/ -v $(TESTARGS) -timeout 120m
source .env \
&& TF_ACC=1 go test -v $(TESTARGS) -timeout 60m ./xenserver/ \
&& TF_ACC=1 TEST_POOL=1 go test -v -run TestAccPoolResource -timeout 60m ./xenserver/

testpool: provider
source .env \
&& TF_ACC=1 TEST_POOL=1 go test -v -run TestAccPoolResource -timeout 60m ./xenserver/

doc: ## make doc for terraform provider documentation
go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs generate --provider-name xenserver
Expand All @@ -16,7 +22,7 @@ provider: go.mod ## make provider
rm -f $(GOBIN)/terraform-provider-xenserver
go mod tidy
go install .
ls -l $(GOBIN)/terraform-provider-xenserver
md5sum $(GOBIN)/terraform-provider-xenserver

apply: .env provider ## make apply
cd $(WORKDIR) && \
Expand Down Expand Up @@ -53,4 +59,4 @@ destroy_vm:
$(MAKE) WORKDIR=examples/vm-main destroy

destroy_pool:
$(MAKE) WORKDIR=examples/pool-main destroy
$(MAKE) WORKDIR=examples/pool-main destroy
1 change: 1 addition & 0 deletions docs/data-sources/host.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ output "host_output" {
### Optional

- `address` (String) The address by which this host can be contacted from any other host in the pool.
- `is_coordinator` (Boolean) If true, show only coordinator of the pool, if false, show only supporter of the pool, if not set, show all hosts.
- `name_label` (String) The name of the host.
- `uuid` (String) The UUID of the host.

Expand Down
8 changes: 6 additions & 2 deletions docs/resources/pif_configure.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
page_title: "xenserver_pif_configure Resource - xenserver"
subcategory: ""
description: |-
Provides an PIF configure resource to update the exist PIF parameters.
PIF configuration resource which is used to update the existing PIF parameters.
Noted that no new PIF will be deployed when terraform apply is executed. Additionally, when it comes to terraform destroy, it actually has no effect on this resource.
---

# xenserver_pif_configure (Resource)

Provides an PIF configure resource to update the exist PIF parameters.
PIF configuration resource which is used to update the existing PIF parameters.

Noted that no new PIF will be deployed when `terraform apply` is executed. Additionally, when it comes to `terraform destroy`, it actually has no effect on this resource.

## Example Usage

Expand Down Expand Up @@ -70,6 +73,7 @@ Optional:
- `dns` (String) Comma separated list of the IP addresses of the DNS servers to use.
- `gateway` (String) The IP gateway.
- `ip` (String) The IP address.
- `name_label` (String) The name of the interface in IP Address Configuration.
- `netmask` (String) The IP netmask.

## Import
Expand Down
92 changes: 82 additions & 10 deletions docs/resources/pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,115 @@
page_title: "xenserver_pool Resource - xenserver"
subcategory: ""
description: |-
Provides a pool resource.
This provides a pool resource. During the execution of terraform destroy for this particular resource, all of the hosts that are part of the pool will be separated and converted into standalone hosts.
---

# xenserver_pool (Resource)

Provides a pool resource.


This provides a pool resource. During the execution of `terraform destroy` for this particular resource, all of the hosts that are part of the pool will be separated and converted into standalone hosts.

## Example Usage

```terraform
resource "xenserver_sr_nfs" "nfs" {
name_label = "NFS shared storage"
name_description = "A test NFS storage repository"
version = "3"
storage_location = format("%s:%s", local.env_vars["NFS_SERVER"], local.env_vars["NFS_SERVER_PATH"])
}
data "xenserver_pif" "pif" {
device = "eth0"
}
data "xenserver_pif" "pif1" {
device = "eth3"
}
locals {
pif1_data = tomap({for element in data.xenserver_pif.pif1.data_items: element.uuid => element})
}
resource "xenserver_pif_configure" "pif_update" {
for_each = local.pif1_data
uuid = each.key
interface = {
mode = "DHCP"
}
}
# Configure default SR and Management Network of the pool
resource "xenserver_pool" "pool" {
name_label = "pool"
default_sr = xenserver_sr_nfs.nfs.uuid
management_network = data.xenserver_pif.pif.data_items[0].network
}
# Join supporter into the pool
resource "xenserver_pool" "pool" {
name_label = "pool"
join_supporters = [
{
host = local.env_vars["SUPPORTER_HOST"]
username = local.env_vars["SUPPORTER_USERNAME"]
password = local.env_vars["SUPPORTER_PASSWORD"]
}
]
}
# Eject supporter from the pool
data "xenserver_host" "supporter" {
is_coordinator = false
}
resource "xenserver_pool" "pool" {
name_label = "pool"
eject_supporters = [ data.xenserver_host.supporter.data_items[1].uuid ]
}
```

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

### Required

- `default_sr` (String) The default SR UUID of the pool.
- `name_label` (String) The name of the pool.

### Optional

- `default_sr` (String) The default SR UUID of the pool. this SR should be shared SR.
- `eject_supporters` (Set of String) The set of pool supporters which will be ejected from the pool.
- `join_supporters` (Attributes Set) The set of pool supporters which will join the pool.

-> **Note:**
1. It would raise error if a supporter is in both join_supporters and eject_supporters.
2. The join operation would be performed only when the host, username, and password are provided. (see [below for nested schema](#nestedatt--join_supporters))
- `management_network` (String) The management network UUID of the pool.

-> **Note:**
1. The management network would be reconfigured only when the management network UUID is provided.
2. All of the hosts in the pool should have the same management network with network configuration, you can set network configuration by `resource pif_configure`.
3.
- `name_description` (String) The description of the pool, default to be `""`.
- `supporters` (Attributes Set) The set of pool supporters which will join the pool. (see [below for nested schema](#nestedatt--supporters))

### Read-Only

- `id` (String) The test ID of the pool.
- `uuid` (String) The UUID of the pool.

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

Optional:

- `host` (String) The address of the host.
- `password` (String, Sensitive) The password of the host.
- `username` (String) The user name of the host.

Read-Only:
## Import

Import is supported using the following syntax:

- `uuid` (String) The UUID of the host.
```shell
terraform import xenserver_pool.pool 00000000-0000-0000-0000-000000000000
```
4 changes: 2 additions & 2 deletions docs/resources/snapshot.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ resource "xenserver_snapshot" "snapshot" {
-> **Note:** When `revert` is true, the snapshot resource will be updated with new configuration first and then revert to VM.

~> **Warning:** After revert, the VM `hard_drive` will be updated. If snapshot revert to the VM resource defined in 'main.tf', it'll cause issue when continue execute terraform commands. There's a suggest solution to resolve this issue, follow the steps: 1. run `terraform state show xenserver_snapshot.<snapshot_resource_name>`, get the revert VM's UUID 'vm_uuid' and revert VDIs' UUID 'vdi_uuid'. 2. run `terraform state rm xenserver_vm.<vm_resource_name>` to remove the VM resource state. 3. run `terraform import xenserver_vm.<vm_resource_name> <vm_uuid>` to import the VM resource new state. 4. run `terraform state rm xenserver_vdi.<vdi_resource_name>` to remove the VDI resource state. Be careful, you only need to remove the VDI resource used in above VM resource. If there're multiple VDI resources, remove them all. 5. run `terraform import xenserver_vdi.<vdi_resource_name> <vdi_uuid>` to import the VDI resource new state. If there're multiple VDI resources, import them all.
- `with_memory` (Boolean) True if snapshot with the VM's memory (VM must in running state), default to be `false`.
- `with_memory` (Boolean) True if snapshot with the VM's memory, default to be `false`.

-> **Note:** `with_memory` is not allowed to be updated.
-> **Note:** 1. `with_memory` field is not allowed to be updated. 2. the VM must be in a running state and have the [XenServer VM Tool](https://www.xenserver.com/downloads) installed.

### Read-Only

Expand Down
34 changes: 26 additions & 8 deletions examples/pool-main/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ provider "xenserver" {
password = local.env_vars["XENSERVER_PASSWORD"]
}

data "xenserver_sr" "sr" {
name_label = "Local storage"
resource "xenserver_sr_nfs" "nfs" {
name_label = "NFS shared storage"
name_description = "A test NFS storage repository"
version = "3"
storage_location = format("%s:%s", local.env_vars["NFS_SERVER"], local.env_vars["NFS_SERVER_PATH"])
}

data "xenserver_host" "host" {}

data "xenserver_pif" "pif" {
device = "eth0"
}
Expand All @@ -43,7 +44,24 @@ resource "xenserver_pif_configure" "pif_update" {
}

resource "xenserver_pool" "pool" {
name_label = "pool-1"
default_sr = data.xenserver_sr.sr.data_items[0].uuid
management_network = data.xenserver_pif.pif.data_items[0].network
}
name_label = "pool"
# default_sr = xenserver_sr_nfs.nfs.uuid
# management_network = data.xenserver_pif.pif.data_items[0].network
join_supporters = [
{
host = local.env_vars["SUPPORTER_HOST"]
username = local.env_vars["SUPPORTER_USERNAME"]
password = local.env_vars["SUPPORTER_PASSWORD"]
}
]
}

# comment out the following block for the second run
# data "xenserver_host" "supporter" {
# is_coordinator = false
# }

# resource "xenserver_pool" "pool" {
# name_label = "pool"
# eject_supporters = [ data.xenserver_host.supporter.data_items[1].uuid ]
# }
1 change: 1 addition & 0 deletions examples/resources/xenserver_pool/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import xenserver_pool.pool 00000000-0000-0000-0000-000000000000
55 changes: 55 additions & 0 deletions examples/resources/xenserver_pool/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
resource "xenserver_sr_nfs" "nfs" {
name_label = "NFS shared storage"
name_description = "A test NFS storage repository"
version = "3"
storage_location = format("%s:%s", local.env_vars["NFS_SERVER"], local.env_vars["NFS_SERVER_PATH"])
}

data "xenserver_pif" "pif" {
device = "eth0"
}

data "xenserver_pif" "pif1" {
device = "eth3"
}

locals {
pif1_data = tomap({for element in data.xenserver_pif.pif1.data_items: element.uuid => element})
}

resource "xenserver_pif_configure" "pif_update" {
for_each = local.pif1_data
uuid = each.key
interface = {
mode = "DHCP"
}
}

# Configure default SR and Management Network of the pool
resource "xenserver_pool" "pool" {
name_label = "pool"
default_sr = xenserver_sr_nfs.nfs.uuid
management_network = data.xenserver_pif.pif.data_items[0].network
}

# Join supporter into the pool
resource "xenserver_pool" "pool" {
name_label = "pool"
join_supporters = [
{
host = local.env_vars["SUPPORTER_HOST"]
username = local.env_vars["SUPPORTER_USERNAME"]
password = local.env_vars["SUPPORTER_PASSWORD"]
}
]
}

# Eject supporter from the pool
data "xenserver_host" "supporter" {
is_coordinator = false
}

resource "xenserver_pool" "pool" {
name_label = "pool"
eject_supporters = [ data.xenserver_host.supporter.data_items[1].uuid ]
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.2
replace xenapi => ./goSDK

require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/hashicorp/terraform-plugin-docs v0.19.4
github.com/hashicorp/terraform-plugin-framework v1.12.0
github.com/hashicorp/terraform-plugin-framework-validators v0.14.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwN
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cloudflare/circl v1.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI=
github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
Expand Down
31 changes: 28 additions & 3 deletions xenserver/host_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ func (d *hostDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, r
MarkdownDescription: "The address by which this host can be contacted from any other host in the pool.",
Optional: true,
},
"is_coordinator": schema.BoolAttribute{
MarkdownDescription: "If true, show only coordinator of the pool, if false, show only supporter of the pool, if not set, show all hosts.",
Optional: true,
},
"data_items": schema.ListNestedAttribute{
MarkdownDescription: "The return items of host.",
Computed: true,
Expand All @@ -63,15 +67,15 @@ func (d *hostDataSource) Configure(_ context.Context, req datasource.ConfigureRe
if req.ProviderData == nil {
return
}
session, ok := req.ProviderData.(*xenapi.Session)
providerData, ok := req.ProviderData.(*xsProvider)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *xenapi.Session, got: %T. Please report this issue to the provider developers.", req.ProviderData),
fmt.Sprintf("Expected *xenserver.xsProvider, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}
d.session = session
d.session = providerData.session
}

// Read refreshes the Terraform state with the latest data.
Expand Down Expand Up @@ -104,6 +108,27 @@ func (d *hostDataSource) Read(ctx context.Context, req datasource.ReadRequest, r
if !data.Address.IsNull() && hostRecord.Address != data.Address.ValueString() {
continue
}
if !data.IsCoordinator.IsNull() {
_, coordinatorUUID, err := getCoordinatorRef(d.session)
if err != nil {
resp.Diagnostics.AddError(
"Unable to get coordinator ref",
err.Error(),
)
return
}

isCoordinator := hostRecord.UUID == coordinatorUUID
if data.IsCoordinator.ValueBool() {
if !isCoordinator {
continue
}
} else {
if isCoordinator {
continue
}
}
}

var hostData hostRecordData
err = updateHostRecordData(ctx, d.session, hostRecord, &hostData)
Expand Down
Loading

0 comments on commit b2ed041

Please sign in to comment.