Skip to content

Commit

Permalink
Add data source to automatically select system software versions
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-helmich committed Nov 10, 2023
1 parent 59b55e0 commit f1a0de5
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 6 deletions.
30 changes: 30 additions & 0 deletions docs/data-sources/systemsoftware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "mittwald_systemsoftware Data Source - terraform-provider-mittwald"
subcategory: ""
description: |-
A data source that selects versions of system components, such as PHP, MySQL, etc.
---

# mittwald_systemsoftware (Data Source)

A data source that selects versions of system components, such as PHP, MySQL, etc.



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

### Required

- `name` (String) The system software name

### Optional

- `recommended` (Boolean) Set this to just select the recommended version
- `selector` (String) A version selector, such as `>= 7.4`

### Read-Only

- `version` (String) The selected version
- `version_id` (String) The selected version ID
1 change: 1 addition & 0 deletions docs/resources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ resource "mittwald_project" "foobar" {

### Read-Only

- `default_ips` (List of String) Contains a list of default IP addresses for the project
- `directories` (Map of String) Contains a map of data directories within the project
- `id` (String) The generated project ID
27 changes: 21 additions & 6 deletions examples/resources/mittwald_app/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ variable "admin_password" {
sensitive = true
}

data "mittwald_systemsoftware" "php" {
name = "php"
selector = "^8.2"
}

data "mittwald_systemsoftware" "composer" {
name = "composer"
recommended = true
}

data "mittwald_systemsoftware" "mysql" {
name = "composer"
recommended = true
}

resource "mittwald_app" "wordpress" {
project_id = mittwald_project.foobar.id

Expand Down Expand Up @@ -33,17 +48,17 @@ resource "mittwald_app" "custom_php" {
update_policy = "none"

dependencies = {
"php" = {
version = "8.2.8"
(data.mittwald_systemsoftware.php.name) = {
version = data.mittwald_systemsoftware.php.version
update_policy = "patchLevel"
}
"composer" = {
(data.mittwald_systemsoftware.composer.name) = {
version = data.mittwald_systemsoftware.composer.version
update_policy = "patchLevel"
version = "2.3.10"
},
"mysql" = {
(data.mittwald_systemsoftware.mysql.name) = {
version = data.mittwald_systemsoftware.mysql.version
update_policy = "patchLevel"
version = "8.0.28"
},
}
}
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (p *MittwaldProvider) Resources(ctx context.Context) []func() resource.Reso
func (p *MittwaldProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewProjectByShortIdDataSource,
NewSystemSoftwareDataSource,
NewAppDataSource,
}
}
Expand Down
136 changes: 136 additions & 0 deletions internal/provider/systemsoftware_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package provider

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/mittwald/terraform-provider-mittwald/api/mittwaldv2"
)

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

func NewSystemSoftwareDataSource() datasource.DataSource {
return &SystemSoftwareDataSource{}
}

// ProjectByShortIdDataSource defines the data source implementation.
type SystemSoftwareDataSource struct {
client mittwaldv2.ClientBuilder
}

// SystemSoftwareDataSourceModel describes the data source data model.
type SystemSoftwareDataSourceModel struct {
Name types.String `tfsdk:"name"`
Recommended types.Bool `tfsdk:"recommended"`
Selector types.String `tfsdk:"selector"`

Version types.String `tfsdk:"version"`
VersionID types.String `tfsdk:"version_id"`
}

func (m *SystemSoftwareDataSourceModel) SelectorOrDefault() string {
if m.Selector.IsNull() {
return "*"
}
return m.Selector.ValueString()
}

func (d *SystemSoftwareDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_systemsoftware"
}

func (d *SystemSoftwareDataSource) 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: "A data source that selects versions of system components, such as PHP, MySQL, etc.",

Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
MarkdownDescription: "The system software name",
Required: true,
},
"recommended": schema.BoolAttribute{
MarkdownDescription: "Set this to just select the recommended version",
Optional: true,
},
"selector": schema.StringAttribute{
MarkdownDescription: "A version selector, such as `>= 7.4`",
Optional: true,
},
"version": schema.StringAttribute{
MarkdownDescription: "The selected version",
Computed: true,
},
"version_id": schema.StringAttribute{
MarkdownDescription: "The selected version ID",
Computed: true,
},
},
}
}

func (d *SystemSoftwareDataSource) Configure(_ 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.(mittwaldv2.ClientBuilder)

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

return
}

d.client = client
}

func (d *SystemSoftwareDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data SystemSoftwareDataSourceModel

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

systemSoftware, ok, err := d.client.App().GetSystemSoftwareByName(ctx, data.Name.ValueString())
if err != nil {
resp.Diagnostics.AddError("Failed to get system software", err.Error())
return
} else if !ok {
resp.Diagnostics.AddError("System software not found", fmt.Sprintf("System software '%s' not found", data.Name.ValueString()))
return
}

versions, err := d.client.App().SelectSystemSoftwareVersion(ctx, systemSoftware.Id, data.SelectorOrDefault())
if err != nil {
resp.Diagnostics.AddError("Failed to get recommended system software version", err.Error())
return
}

if data.Recommended.ValueBool() {
recommended, ok := versions.Recommended()
if !ok {
resp.Diagnostics.AddError("No recommended system software version found", fmt.Sprintf("No recommended version found for '%s'", data.Name.ValueString()))
return
}

data.Version = types.StringValue(recommended.InternalVersion)
data.VersionID = types.StringValue(recommended.Id.String())
} else {
data.Version = types.StringValue(versions[len(versions)-1].InternalVersion)
data.VersionID = types.StringValue(versions[len(versions)-1].Id.String())
}

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

0 comments on commit f1a0de5

Please sign in to comment.