Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CP-49366: Implement xenserver_sr provider data source #15

Merged
merged 2 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions DEVELOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ This is the best practice document for XenServer terraform provider development,

2. For each new added component, add the according "NewXX" function into the return value of provider function `Resources`, `DataSources` or `Functions` under `xenserver/provider.go`.

3. For each new added component, create an acceptance test file `<name>_<component_type>_test.go` under folder `xenserver/`. The test configuration can be written together under `xenserver/test.config.go`.
3. For each new added component, create an acceptance test file `<name>_<component_type>_test.go` under folder `xenserver/`.

4. For each new added component, requires to add an example for it under folder `examples/`.
4. For each new added component, create a utils file `<name>_utils.go` under folder `xenserver/` to store the type definitions and common functions.

5. For each new added component, requires to add an example for it under folder `examples/`.

- `provider`

Expand All @@ -32,7 +34,7 @@ This is the best practice document for XenServer terraform provider development,

create a file `function.tf` under folder `examples/functions/<function_name>/` to show how to use this function.

5. Generate new documents base on changes, run `go generate ./...`.
6. Generate new documents base on changes, run `go generate ./...`.

### Local Checking and Testing

Expand All @@ -55,20 +57,24 @@ golangci-lint run --config=/app/.golangci.yml

- component name, like resource, data-source, function, follow `xenserver_<name>`. eg.

```shell
```
xenserver_vm
```

- function name follow `Pascal`, eg.
- function name and var name follow `Camel-Case`, eg.

```shell
func GetFirstTemplate(){}
```
func getFirstTemplate(){}
var srRef string
```

- var name follow `Camel-Case`, eg.
- struct key follow `Pascal`, eg.

```shell
var dataState VMResourceModel
```
type vmResourceModel struct {
NameLabel types.String `tfsdk:"name_label"`
TemplateName types.String `tfsdk:"template_name"``
}
```

## Development Process For Community Contributors
Expand Down
62 changes: 62 additions & 0 deletions docs/data-sources/sr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "xenserver_sr Data Source - xenserver"
subcategory: ""
description: |-
The data source of XenServer storage repository
---

# xenserver_sr (Data Source)

The data source of XenServer storage repository

## Example Usage

```terraform
data "xenserver_sr" "sr" {
name_label = "Local storage"
}

output "local_storage_output" {
value = data.xenserver_sr.sr.data_items
}
```

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

### Optional

- `name_label` (String) The name of the storage repository
- `uuid` (String) The UUID of the storage repository

### Read-Only

- `data_items` (Attributes List) The return items of storage repositories (see [below for nested schema](#nestedatt--data_items))

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

Read-Only:

- `allowed_operations` (List of String) The list of the operations allowed in this state
- `blobs` (Map of String) The binary blobs associated with this SR
- `clustered` (Boolean) True if the SR is using aggregated local storage
- `content_type` (String) The type of the SR's content, if required (e.g. ISOs)
- `current_operations` (Map of String) The links each of the running tasks using this object (by reference) to a current_operation enum which describes the nature of the task
- `introduced_by` (String) The disaster recovery task which introduced this SR
- `is_tools_sr` (Boolean) True if this is the SR that contains the Tools ISO VDIs
- `local_cache_enabled` (Boolean) True if this SR is assigned to be the local cache for its host
- `name_description` (String) The human-readable description of the storage repository
- `name_label` (String) The name of the storage repository
- `other_config` (Map of String) The additional configuration
- `pbds` (List of String) Describes how particular hosts can see this storage repository
- `physical_size` (Number) The total physical size of the storage repository (in bytes)
- `physical_utilisation` (Number) The physical space currently utilised on this storage repository (in bytes)
- `shared` (Boolean) True if this SR is (capable of being) shared between multiple hosts
- `sm_config` (Map of String) The SM dependent data
- `tags` (List of String) The user-specified tags for categorization purposes
- `type` (String) The type of the storage repository
- `uuid` (String) The UUID of the storage repository
- `vdis` (List of String) The all virtual disks known to this storage repository
- `virtual_allocation` (Number) The sum of virtual_sizes of all VDIs in this storage repository (in bytes)
7 changes: 7 additions & 0 deletions examples/data-sources/xenserver_sr/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
data "xenserver_sr" "sr" {
name_label = "Local storage"
}

output "local_storage_output" {
value = data.xenserver_sr.sr.data_items
}
8 changes: 8 additions & 0 deletions examples/terraform-main/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,11 @@ resource "xenserver_vm" "vm" {
output "vm_out" {
value = xenserver_vm.vm
}

data "xenserver_sr" "sr" {
name_label = "Local storage"
}

output "local_storage_output" {
value = data.xenserver_sr.sr.data_items
}
6 changes: 0 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,8 @@ github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVW
github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg=
github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec=
github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A=
github.com/hashicorp/terraform-plugin-docs v0.19.2 h1:YjdKa1vuqt9EnPYkkrv9HnGZz175HhSJ7Vsn8yZeWus=
github.com/hashicorp/terraform-plugin-docs v0.19.2/go.mod h1:gad2aP6uObFKhgNE8DR9nsEuEQnibp7il0jZYYOunWY=
github.com/hashicorp/terraform-plugin-docs v0.19.3 h1:xoxpeIuBfnoGxXY0dTajdj4GjEv6TihZdj0lHNXbKew=
github.com/hashicorp/terraform-plugin-docs v0.19.3/go.mod h1:4pLASsatTmRynVzsjEhbXZ6s7xBlUw/2Kt0zfrq8HxA=
github.com/hashicorp/terraform-plugin-docs v0.19.4 h1:G3Bgo7J22OMtegIgn8Cd/CaSeyEljqjH3G39w28JK4c=
github.com/hashicorp/terraform-plugin-docs v0.19.4/go.mod h1:4pLASsatTmRynVzsjEhbXZ6s7xBlUw/2Kt0zfrq8HxA=
github.com/hashicorp/terraform-plugin-framework v1.8.0 h1:P07qy8RKLcoBkCrY2RHJer5AEvJnDuXomBgou6fD8kI=
github.com/hashicorp/terraform-plugin-framework v1.8.0/go.mod h1:/CpTukO88PcL/62noU7cuyaSJ4Rsim+A/pa+3rUVufY=
github.com/hashicorp/terraform-plugin-framework v1.9.0 h1:caLcDoxiRucNi2hk8+j3kJwkKfvHznubyFsJMWfZqKU=
github.com/hashicorp/terraform-plugin-framework v1.9.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM=
github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co=
Expand Down
27 changes: 10 additions & 17 deletions xenserver/pif_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,27 @@ import (

// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &PIFDataSource{}
_ datasource.DataSourceWithConfigure = &PIFDataSource{}
_ datasource.DataSource = &pifDataSource{}
_ datasource.DataSourceWithConfigure = &pifDataSource{}
)

// NewPIFDataSource is a helper function to simplify the provider implementation.
func NewPIFDataSource() datasource.DataSource {
return &PIFDataSource{}
return &pifDataSource{}
}

// PIFDataSource is the data source implementation.
type PIFDataSource struct {
// pifDataSource is the data source implementation.
type pifDataSource struct {
session *xenapi.Session
}

// PIFDataSourceModel describes the data source data model.
type PIFDataSourceModel struct {
Device types.String `tfsdk:"device"`
Management types.Bool `tfsdk:"management"`
Network types.String `tfsdk:"network"`
}

// Metadata returns the data source type name.
func (d *PIFDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
func (d *pifDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_pif"
}

// Schema defines the schema for the data source.
func (d *PIFDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
func (d *pifDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
// This description is used by the documentation generator and the language server.
MarkdownDescription: "PIF data source",
Expand All @@ -65,7 +58,7 @@ func (d *PIFDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, re
}
}

func (d *PIFDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
func (d *pifDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
Expand All @@ -81,8 +74,8 @@ func (d *PIFDataSource) Configure(_ context.Context, req datasource.ConfigureReq
}

// Read refreshes the Terraform state with the latest data.
func (d *PIFDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data PIFDataSourceModel
func (d *pifDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data pifDataSourceModel

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
Expand Down
10 changes: 10 additions & 0 deletions xenserver/pif_data_source_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
package xenserver

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func testAccPifDataSourceConfig(device string) string {
return fmt.Sprintf(`
data "xenserver_pif" "test_pif_data" {
device = "%s"
management = true
}
`, device)
}

func TestAccPifDataSource(t *testing.T) {
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Expand Down
12 changes: 12 additions & 0 deletions xenserver/pif_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package xenserver

import (
"github.com/hashicorp/terraform-plugin-framework/types"
)

// pifDataSourceModel describes the data source data model.
type pifDataSourceModel struct {
Device types.String `tfsdk:"device"`
Management types.Bool `tfsdk:"management"`
Network types.String `tfsdk:"network"`
}
35 changes: 17 additions & 18 deletions xenserver/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import (
)

// Ensure Provider satisfies various provider interfaces.
var _ provider.Provider = &Provider{}
var _ provider.ProviderWithFunctions = &Provider{}
var _ provider.Provider = &xsProvider{}
var _ provider.ProviderWithFunctions = &xsProvider{}

// Provider defines the provider implementation.
type Provider struct {
// xsProvider defines the provider implementation.
type xsProvider struct {
// version is set to the provider version on release, "dev" when the
// provider is built and ran locally, and "test" when running acceptance
// testing.
Expand All @@ -30,25 +30,25 @@ type Provider struct {

func New(version string) func() provider.Provider {
return func() provider.Provider {
return &Provider{
return &xsProvider{
version: version,
}
}
}

// ProviderModel describes the provider data model.
type ProviderModel struct {
// providerModel describes the provider data model.
type providerModel struct {
Host types.String `tfsdk:"host"`
Username types.String `tfsdk:"username"`
Password types.String `tfsdk:"password"`
}

func (p *Provider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
func (p *xsProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
resp.TypeName = "xenserver"
resp.Version = p.version
}

func (p *Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
func (p *xsProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"host": schema.StringAttribute{
Expand All @@ -68,9 +68,9 @@ func (p *Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *pro
}
}

func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
func (p *xsProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
tflog.Debug(ctx, "Configuring XenServer Client")
var data ProviderModel
var data providerModel

resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
Expand Down Expand Up @@ -171,33 +171,32 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest,
_, err := session.LoginWithPassword(username, password, "1.0", "terraform provider")
if err != nil {
resp.Diagnostics.AddError(
"Unable to Create XENSERVER API Client",
"Unable to create XENSERVER API client",
"An unexpected error occurred when creating the XENSERVER API client. "+
"If the error is not clear, please contact the provider developers.\n\n"+
"XENSERVER client Error: "+err.Error(),
)
return
}
tflog.Debug(ctx, "api version: "+session.APIVersion.String())
tflog.Debug(ctx, "xapi rpm version: "+session.XAPIVersion)

resp.DataSourceData = session
resp.ResourceData = session
}

func (p *Provider) Resources(_ context.Context) []func() resource.Resource {
// return nil
func (p *xsProvider) Resources(_ context.Context) []func() resource.Resource {
return []func() resource.Resource{
NewVMResource,
}
}

func (p *Provider) DataSources(_ context.Context) []func() datasource.DataSource {
func (p *xsProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewPIFDataSource,
NewSRDataSource,
}
}

func (p *Provider) Functions(_ context.Context) []func() function.Function {
func (p *xsProvider) Functions(_ context.Context) []func() function.Function {
return nil
// return []func() function.Function{
// NewExampleFunction,
Expand Down
13 changes: 13 additions & 0 deletions xenserver/provider_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package xenserver

import (
"fmt"
"os"

"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
)
Expand All @@ -12,3 +15,13 @@ import (
var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"xenserver": providerserver.NewProtocol6WithError(New("test")()),
}

var (
providerConfig = fmt.Sprintf(`
provider "xenserver" {
host = "%s"
username = "%s"
password = "%s"
}
`, os.Getenv("XENSERVER_HOST"), os.Getenv("XENSERVER_USERNAME"), os.Getenv("XENSERVER_PASSWORD"))
)
Loading
Loading