Skip to content

Commit

Permalink
Merge pull request #152 from maveonair/project-datasource
Browse files Browse the repository at this point in the history
Add project as datasource
  • Loading branch information
stgraber authored Nov 1, 2024
2 parents bcc894a + 4ac1af0 commit 996ab67
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 6 deletions.
12 changes: 6 additions & 6 deletions docs/data-sources/profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ resource "incus_instance" "d1" {

* `project` - *Optional* - Name of the project where the profile will be stored.

* `remote` - *Optional* - The remote in which the resource will be created. If
* `remote` - *Optional* - The remote in which the resource was created. If
not provided, the provider's default remote will be used.

## Attribute Reference

* `device` - *Optional* - Device definition. See reference below.
* `device` - Device definition. See reference below.

* `config` - *Optional* - Map of key/value pairs of
* `config` - Map of key/value pairs of
[instance config settings](https://linuxcontainers.org/incus/docs/main/reference/instance_options/).

The `device` block supports:

* `name` - **Required** - Name of the device.
* `name` - Name of the device.

* `type` - **Required** - Type of the device Must be one of none, disk, nic,
* `type` - Type of the device Must be one of none, disk, nic,
unix-char, unix-block, usb, gpu, infiniband, proxy, unix-hotplug, tpm, pci.

* `properties`- **Required** - Map of key/value pairs of
* `properties` - Map of key/value pairs of
[device properties](https://linuxcontainers.org/incus/docs/main/reference/devices/).
32 changes: 32 additions & 0 deletions docs/data-sources/project.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# incus_project

Provides information about an Incus project.

## Example Usage

```hcl
data "incus_project" "default" {
name = "default"
}
resource "incus_instance" "d1" {
project = data.incus_project.default.name
image = "images:debian/12"
name = "d1"
}
```

## Argument Reference

* `name` - **Required** - Name of the project.

* `remote` - *Optional* - The remote in which the resource was created. If
not provided, the provider's default remote will be used.

## Attribute Reference

* `description` - Description of the project.

* `config` - Map of key/value pairs of
[instance config settings](https://linuxcontainers.org/incus/docs/main/reference/instance_options/).

96 changes: 96 additions & 0 deletions internal/project/datasource_project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package project

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/lxc/terraform-provider-incus/internal/common"
"github.com/lxc/terraform-provider-incus/internal/errors"
provider_config "github.com/lxc/terraform-provider-incus/internal/provider-config"
)

type ProjectDataSource struct {
provider *provider_config.IncusProviderConfig
}

func NewProjectDataSource() datasource.DataSource {
return &ProjectDataSource{}
}

func (d *ProjectDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = fmt.Sprintf("%s_project", req.ProviderTypeName)
}

func (d *ProjectDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Required: true,
},
"description": schema.StringAttribute{
Optional: true,
Computed: true,
},
"config": schema.MapAttribute{
Optional: true,
Computed: true,
ElementType: types.StringType,
},
"remote": schema.StringAttribute{
Optional: true,
},
},
}
}

func (d *ProjectDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
data := req.ProviderData
if data == nil {
return
}

provider, ok := data.(*provider_config.IncusProviderConfig)
if !ok {
resp.Diagnostics.Append(errors.NewProviderDataTypeError(req.ProviderData))
return
}

d.provider = provider
}

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

diags := req.Config.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

remote := state.Remote.ValueString()
projectName := state.Name.ValueString()
server, err := d.provider.InstanceServer(remote, projectName, "")
if err != nil {
resp.Diagnostics.Append(errors.NewInstanceServerError(err))
return
}

project, _, err := server.GetProject(projectName)
if err != nil {
resp.Diagnostics.AddError(fmt.Sprintf("Failed to retrieve existing project %q", projectName), err.Error())
return
}

config, diags := common.ToConfigMapType(ctx, common.ToNullableConfig(project.Config), state.Config)

state.Name = types.StringValue(project.Name)
state.Description = types.StringValue(project.Description)
state.Config = config

diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
}
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,5 +284,6 @@ func (p *IncusProvider) DataSources(_ context.Context) []func() datasource.DataS
return []func() datasource.DataSource{
image.NewImageDataSource,
profile.NewProfileDataSource,
project.NewProjectDataSource,
}
}

0 comments on commit 996ab67

Please sign in to comment.