Skip to content

Commit

Permalink
Merge pull request #42 from mittwald/feature/vhosts
Browse files Browse the repository at this point in the history
Add `mittwald_virtualhost` resource
  • Loading branch information
martin-helmich authored Apr 16, 2024
2 parents 1ea9eb7 + 2c00572 commit 23f8c86
Show file tree
Hide file tree
Showing 14 changed files with 471 additions and 63 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ This provider offers the following resources:
- [`mittwald_app`](https://registry.terraform.io/providers/mittwald/mittwald/latest/docs/resources/app)
- [`mittwald_mysql_database`](https://registry.terraform.io/providers/mittwald/mittwald/latest/docs/resources/mysql_database)
- [`mittwald_cronjob`](https://registry.terraform.io/providers/mittwald/mittwald/latest/docs/resources/cronjob)
- [`mittwald_virtualhost`](https://registry.terraform.io/providers/mittwald/mittwald/latest/docs/resources/virtualhost)

and the following data sources:

Expand Down
7 changes: 7 additions & 0 deletions api/mittwaldv2/client_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type ClientBuilder interface {
App() AppClient
Database() DatabaseClient
Cronjob() CronjobClient
Domain() DomainClient
User() UserClient
}

Expand Down Expand Up @@ -36,6 +37,12 @@ func (b *clientBuilder) Cronjob() CronjobClient {
}
}

func (b *clientBuilder) Domain() DomainClient {
return &domainClient{
client: b.internalClient,
}
}

func (b *clientBuilder) User() UserClient {
return &userClient{
client: b.internalClient,
Expand Down
71 changes: 71 additions & 0 deletions api/mittwaldv2/client_domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package mittwaldv2

import (
"context"
"github.com/google/uuid"
)

type DomainClient interface {
GetIngress(ctx context.Context, ingressID string) (*DeMittwaldV1IngressIngress, error)
CreateIngress(ctx context.Context, projectID string, body IngressCreateIngressJSONRequestBody) (string, error)
UpdateIngressPaths(ctx context.Context, ingressID string, body IngressUpdateIngressPathsJSONRequestBody) error
DeleteIngress(ctx context.Context, ingressID string) error
}

type domainClient struct {
client ClientWithResponsesInterface
}

func (c *domainClient) GetIngress(ctx context.Context, ingressID string) (*DeMittwaldV1IngressIngress, error) {
resp, err := c.client.IngressGetIngressWithResponse(ctx, uuid.MustParse(ingressID))
if err != nil {
return nil, err
}

if resp.JSON200 == nil {
return nil, errUnexpectedStatus(resp.StatusCode(), resp.Body)
}

return resp.JSON200, nil
}

func (c *domainClient) CreateIngress(ctx context.Context, projectID string, body IngressCreateIngressJSONRequestBody) (string, error) {
resp, err := c.client.IngressCreateIngressWithResponse(ctx, body)
if err != nil {
return "", err
}

body.ProjectId = uuid.MustParse(projectID)

if resp.JSON201 == nil {
return "", errUnexpectedStatus(resp.StatusCode(), resp.Body)
}

return resp.JSON201.Id.String(), nil
}

func (c *domainClient) UpdateIngressPaths(ctx context.Context, ingressID string, body IngressUpdateIngressPathsJSONRequestBody) error {
resp, err := c.client.IngressUpdateIngressPathsWithResponse(ctx, uuid.MustParse(ingressID), body)
if err != nil {
return err
}

if resp.StatusCode() != 204 {
return errUnexpectedStatus(resp.StatusCode(), resp.Body)
}

return nil
}

func (c *domainClient) DeleteIngress(ctx context.Context, ingressID string) error {
resp, err := c.client.IngressDeleteIngressWithResponse(ctx, uuid.MustParse(ingressID))
if err != nil {
return err
}

if resp.StatusCode() != 204 {
return errUnexpectedStatus(resp.StatusCode(), resp.Body)
}

return nil
}
8 changes: 4 additions & 4 deletions docs/resources/cronjob.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ resource "mittwald_cronjob" "demo" {

### Required

- `app_id` (String) The ID of the app the cron job belongs to
- `description` (String) Description for your cron job
- `app_id` (String) The ID of the app the cronjob belongs to
- `description` (String) Description for your cronjob
- `destination` (Attributes) Models the action to be executed by the cron job. Exactly one of `url` or `command` must be set. (see [below for nested schema](#nestedatt--destination))
- `interval` (String) The interval of the cron job; this should be a cron expression
- `project_id` (String) The ID of the project the cron job belongs to
- `project_id` (String) The ID of the project the cronjob belongs to

### Optional

- `email` (String) The email address to send the cron job's output to

### Read-Only

- `id` (String) The generated cron job ID
- `id` (String) The generated cronjob ID

<a id="nestedatt--destination"></a>
### Nested Schema for `destination`
Expand Down
4 changes: 2 additions & 2 deletions docs/resources/mysql_database.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ resource "mittwald_mysql_database" "foobar_database" {
### Required

- `description` (String) Description for your database
- `project_id` (String) ID of the project this database belongs to
- `project_id` (String) The ID of the project the database belongs to
- `user` (Attributes) (see [below for nested schema](#nestedatt--user))
- `version` (String) Version of the database, e.g. `5.7`

Expand All @@ -53,7 +53,7 @@ resource "mittwald_mysql_database" "foobar_database" {
### Read-Only

- `hostname` (String) Hostname of the database; this is the hostname that you should use within the platform to connect to the database.
- `id` (String) ID of this database
- `id` (String) The generated database ID
- `name` (String) Name of the database, e.g. `db-XXXXX`

<a id="nestedatt--user"></a>
Expand Down
34 changes: 34 additions & 0 deletions docs/resources/virtualhost.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: "mittwald_virtualhost Resource - terraform-provider-mittwald"
subcategory: ""
description: |-
This resource models a virtualhost.
---

# mittwald_virtualhost (Resource)

This resource models a virtualhost.



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

### Required

- `hostname` (String) The desired hostname for the virtualhost.
- `paths` (Attributes Map) The desired paths for the virtualhost. (see [below for nested schema](#nestedatt--paths))
- `project_id` (String) The ID of the project the virtualhost belongs to

### Read-Only

- `id` (String) The generated virtualhost ID

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

Optional:

- `app` (String) The ID of an app installation that this path should point to.
- `redirect` (String) The URL to redirect to.
2 changes: 2 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/mittwald/terraform-provider-mittwald/internal/provider/resource/cronjobresource"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/resource/mysqldatabaseresource"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/resource/projectresource"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/resource/virtualhostresource"
"os"

"github.com/hashicorp/terraform-plugin-framework/datasource"
Expand Down Expand Up @@ -107,6 +108,7 @@ func (p *MittwaldProvider) Resources(_ context.Context) []func() resource.Resour
appresource.New,
mysqldatabaseresource.New,
cronjobresource.New,
virtualhostresource.New,
}
}

Expand Down
55 changes: 55 additions & 0 deletions internal/provider/resource/common/attrbuilder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package common

import (
"fmt"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
)

type AttributeBuilder struct {
resourceName string
}

func AttributeBuilderFor(name string) *AttributeBuilder {
return &AttributeBuilder{
resourceName: name,
}
}

func (b *AttributeBuilder) Id() schema.Attribute {
return schema.StringAttribute{
Computed: true,
MarkdownDescription: fmt.Sprintf("The generated %s ID", b.resourceName),
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
}
}

func (b *AttributeBuilder) ProjectId() schema.Attribute {
return schema.StringAttribute{
MarkdownDescription: fmt.Sprintf("The ID of the project the %s belongs to", b.resourceName),
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
}
}

func (b *AttributeBuilder) AppId() schema.Attribute {
return schema.StringAttribute{
MarkdownDescription: fmt.Sprintf("The ID of the app the %s belongs to", b.resourceName),
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
}
}

func (b *AttributeBuilder) Description() schema.Attribute {
return schema.StringAttribute{
Required: true,
MarkdownDescription: fmt.Sprintf("Description for your %s", b.resourceName),
}
}
33 changes: 6 additions & 27 deletions internal/provider/resource/cronjobresource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import (
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/mittwald/terraform-provider-mittwald/api/mittwaldv2"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/providerutil"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/resource/common"
)

// Ensure provider defined types fully satisfy framework interfaces.
Expand All @@ -30,35 +29,15 @@ func (r *Resource) Metadata(_ context.Context, req resource.MetadataRequest, res
}

func (r *Resource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
builder := common.AttributeBuilderFor("cronjob")
resp.Schema = schema.Schema{
MarkdownDescription: "This resource models a cron job.",

Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
MarkdownDescription: "The generated cron job ID",
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"project_id": schema.StringAttribute{
MarkdownDescription: "The ID of the project the cron job belongs to",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"app_id": schema.StringAttribute{
MarkdownDescription: "The ID of the app the cron job belongs to",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"description": schema.StringAttribute{
Required: true,
MarkdownDescription: "Description for your cron job",
},
"id": builder.Id(),
"project_id": builder.ProjectId(),
"app_id": builder.AppId(),
"description": builder.Description(),
"destination": modelDestinationSchema,
"interval": schema.StringAttribute{
Required: true,
Expand Down
23 changes: 5 additions & 18 deletions internal/provider/resource/mysqldatabaseresource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/mittwald/terraform-provider-mittwald/api/mittwaldv2"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/providerutil"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/resource/common"
"time"
)

Expand All @@ -34,17 +35,12 @@ func (d *Resource) Metadata(_ context.Context, request resource.MetadataRequest,
}

func (d *Resource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) {
builder := common.AttributeBuilderFor("database")
response.Schema = schema.Schema{
MarkdownDescription: "Models a MySQL database on the mittwald plattform",

Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
MarkdownDescription: "ID of this database",
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"id": builder.Id(),
"version": schema.StringAttribute{
Required: true,
MarkdownDescription: "Version of the database, e.g. `5.7`",
Expand All @@ -59,17 +55,8 @@ func (d *Resource) Schema(_ context.Context, _ resource.SchemaRequest, response
stringplanmodifier.UseStateForUnknown(),
},
},
"project_id": schema.StringAttribute{
MarkdownDescription: "ID of the project this database belongs to",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"description": schema.StringAttribute{
Required: true,
MarkdownDescription: "Description for your database",
},
"project_id": builder.ProjectId(),
"description": builder.Description(),
"hostname": schema.StringAttribute{
Computed: true,
MarkdownDescription: "Hostname of the database; this is the hostname that you should use within the platform to connect to the database.",
Expand Down
16 changes: 4 additions & 12 deletions internal/provider/resource/projectresource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/mapplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/mittwald/terraform-provider-mittwald/api/mittwaldv2"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/providerutil"
"github.com/mittwald/terraform-provider-mittwald/internal/provider/resource/common"
"time"
)

Expand All @@ -34,6 +34,7 @@ func (r *Resource) Metadata(_ context.Context, req resource.MetadataRequest, res
}

func (r *Resource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
builder := common.AttributeBuilderFor("project")
resp.Schema = schema.Schema{
MarkdownDescription: "This resource models a project on the mittwald cloud platform; a project is either provisioned on a server (in which case a `server_id` is required), or as a stand-alone project (currently not supported).",

Expand All @@ -42,17 +43,8 @@ func (r *Resource) Schema(_ context.Context, _ resource.SchemaRequest, resp *res
MarkdownDescription: "ID of the server this project belongs to",
Optional: true,
},
"id": schema.StringAttribute{
Computed: true,
MarkdownDescription: "The generated project ID",
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"description": schema.StringAttribute{
Required: true,
MarkdownDescription: "Description for your project",
},
"id": builder.Id(),
"description": builder.Description(),
"directories": schema.MapAttribute{
Computed: true,
MarkdownDescription: "Contains a map of data directories within the project",
Expand Down
Loading

0 comments on commit 23f8c86

Please sign in to comment.