Skip to content
Open
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
13 changes: 13 additions & 0 deletions docs/resources/workspace_group.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ resource "singlestoredb_workspace_group" "this" {
expires_at = "2222-01-01T00:00:00Z"
region_id = data.singlestoredb_regions.all.regions.0.id // Prefer specifying the explicit region ID in production environments as the list of regions may vary.
admin_password = "fooBAR12$"
update_window = {
day = 6
hour = 14
}
}
```

Expand All @@ -43,10 +47,19 @@ resource "singlestoredb_workspace_group" "this" {

- `admin_password` (String, Sensitive) The admin SQL user password for the workspace group. If not provided, the server will automatically generate a secure password. Please note that updates to the admin password might take a brief moment to become effective.
- `expires_at` (String) The expiration timestamp of the workspace group. If not specified, the workspace group never expires. Upon expiration, the workspace group is terminated and all its data is lost. Set the expiration time as an RFC3339 UTC timestamp, e.g., "2221-01-02T15:04:05Z".
- `update_window` (Attributes) Details of the scheduled update window for the workspace group. This is the time period during which any updates to the workspace group will occur. (see [below for nested schema](#nestedatt--update_window))

### Read-Only

- `created_at` (String) The timestamp when the workspace was created.
- `id` (String) The unique identifier of the workspace group.

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

Optional:

- `day` (Number) The day of the week (0-6), where 0 is Sunday and 6 is Saturday, when the update window is scheduled.
- `hour` (Number) The hour of the day, in 24-hour UTC format (0-23), when the update window starts.


4 changes: 4 additions & 0 deletions examples/resources/singlestoredb_workspace_group/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ resource "singlestoredb_workspace_group" "this" {
expires_at = "2222-01-01T00:00:00Z"
region_id = data.singlestoredb_regions.all.regions.0.id // Prefer specifying the explicit region ID in production environments as the list of regions may vary.
admin_password = "fooBAR12$"
update_window = {
day = 6
hour = 14
}
}
4 changes: 4 additions & 0 deletions internal/provider/config/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ const (
TestFirewallFirewallRangeAllTraffic = "0.0.0.0/0"
// TestInitialWorkspaceID is the workspace ID in the example.
TestInitialWorkspaceID = "26171125-ecb8-5944-9896-209fbffc1f15"
// TestInitialUpdateWindowDay is the default update window day in examples.
TestInitialUpdateWindowDay = 6
// TestInitialUpdateWindowHour is the default update window hour in examples.
TestInitialUpdateWindowHour = 14
// TestWorkspaceName is the default workspace name in examples.
TestWorkspaceName = "workspace"
// TestInitialWorkspaceSize is the default workspace size in examples.
Expand Down
59 changes: 52 additions & 7 deletions internal/provider/workspacegroups/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,21 @@ type workspaceGroupResource struct {
management.ClientWithResponsesInterface
}

type updateWindowResourceModel struct {
Hour types.Int64 `tfsdk:"hour"`
Day types.Int64 `tfsdk:"day"`
}

// workspaceGroupResourceModel maps the resource schema data.
type workspaceGroupResourceModel struct {
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
FirewallRanges []types.String `tfsdk:"firewall_ranges"`
CreatedAt types.String `tfsdk:"created_at"`
ExpiresAt types.String `tfsdk:"expires_at"`
RegionID types.String `tfsdk:"region_id"`
AdminPassword types.String `tfsdk:"admin_password"`
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
FirewallRanges []types.String `tfsdk:"firewall_ranges"`
CreatedAt types.String `tfsdk:"created_at"`
ExpiresAt types.String `tfsdk:"expires_at"`
RegionID types.String `tfsdk:"region_id"`
AdminPassword types.String `tfsdk:"admin_password"`
UpdateWindow *updateWindowResourceModel `tfsdk:"update_window"`
}

// NewResource is a helper function to simplify the provider implementation.
Expand Down Expand Up @@ -99,6 +105,20 @@ func (r *workspaceGroupResource) Schema(_ context.Context, _ resource.SchemaRequ
Sensitive: true,
MarkdownDescription: `The admin SQL user password for the workspace group. If not provided, the server will automatically generate a secure password. Please note that updates to the admin password might take a brief moment to become effective.`,
},
"update_window": schema.SingleNestedAttribute{
Optional: true,
MarkdownDescription: "Details of the scheduled update window for the workspace group. This is the time period during which any updates to the workspace group will occur.",
Attributes: map[string]schema.Attribute{
"hour": schema.Int64Attribute{
Optional: true,
MarkdownDescription: "The hour of the day, in 24-hour UTC format (0-23), when the update window starts.",
},
"day": schema.Int64Attribute{
Optional: true,
MarkdownDescription: "The day of the week (0-6), where 0 is Sunday and 6 is Saturday, when the update window is scheduled.",
},
},
},
},
}
}
Expand All @@ -118,6 +138,7 @@ func (r *workspaceGroupResource) Create(ctx context.Context, req resource.Create
FirewallRanges: util.StringFirewallRanges(plan.FirewallRanges),
Name: plan.Name.ValueString(),
RegionID: uuid.MustParse(plan.RegionID.ValueString()),
UpdateWindow: toManagementUpdateWindow(plan.UpdateWindow),
})
if serr := util.StatusOK(workspaceGroupCreateResponse, err); serr != nil {
resp.Diagnostics.AddError(
Expand Down Expand Up @@ -211,6 +232,7 @@ func (r *workspaceGroupResource) Update(ctx context.Context, req resource.Update
ExpiresAt: util.MaybeString(plan.ExpiresAt),
Name: util.MaybeString(plan.Name),
FirewallRanges: util.Ptr(util.StringFirewallRanges(plan.FirewallRanges)),
UpdateWindow: toManagementUpdateWindow(plan.UpdateWindow),
},
)
if serr := util.StatusOK(workspaceGroupUpdateResponse, err); serr != nil {
Expand Down Expand Up @@ -314,6 +336,7 @@ func toWorkspaceGroupResourceModel(workspaceGroup management.WorkspaceGroup, adm
ExpiresAt: util.MaybeStringValue(workspaceGroup.ExpiresAt),
RegionID: util.UUIDStringValue(workspaceGroup.RegionID),
AdminPassword: types.StringValue(adminPassword),
UpdateWindow: toUpdateWindowResourceModel(workspaceGroup.UpdateWindow),
}
}

Expand Down Expand Up @@ -370,3 +393,25 @@ func waitStatusActive(ctx context.Context, c management.ClientWithResponsesInter

return result, nil
}

func toManagementUpdateWindow(uw *updateWindowResourceModel) *management.UpdateWindow {
if uw == nil {
return nil
}

return &management.UpdateWindow{
Hour: float32(uw.Hour.ValueInt64()),
Day: float32(uw.Day.ValueInt64()),
}
}

func toUpdateWindowResourceModel(uw *management.UpdateWindow) *updateWindowResourceModel {
if uw == nil {
return nil
}

return &updateWindowResourceModel{
Hour: types.Int64Value(int64(uw.Hour)),
Day: types.Int64Value(int64(uw.Day)),
}
}
9 changes: 8 additions & 1 deletion internal/provider/workspacegroups/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package workspacegroups_test

import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -45,7 +46,7 @@ func TestCRUDWorkspaceGroup(t *testing.T) {
RegionID: regions[0].RegionID,
State: management.PENDING, // During the first poll, the status will still be PENDING.
TerminatedAt: nil,
UpdateWindow: nil,
UpdateWindow: &management.UpdateWindow{Day: config.TestInitialUpdateWindowDay, Hour: config.TestInitialUpdateWindowHour},
WorkspaceGroupID: workspaceGroupID,
}

Expand Down Expand Up @@ -100,6 +101,8 @@ func TestCRUDWorkspaceGroup(t *testing.T) {
require.Equal(t, []string{config.TestInitialFirewallRange}, input.FirewallRanges)
require.Equal(t, config.TestInitialWorkspaceGroupName, input.Name)
require.Equal(t, regions[0].RegionID, input.RegionID)
require.Equal(t, config.TestInitialUpdateWindowDay, int(input.UpdateWindow.Day))
require.Equal(t, config.TestInitialUpdateWindowHour, int(input.UpdateWindow.Hour))

w.Header().Add("Content-Type", "json")
_, err = w.Write(testutil.MustJSON(
Expand Down Expand Up @@ -211,6 +214,8 @@ func TestCRUDWorkspaceGroup(t *testing.T) {
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "admin_password", config.TestInitialAdminPassword),
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "firewall_ranges.#", "1"),
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "firewall_ranges.0", config.TestInitialFirewallRange),
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "update_window.day", fmt.Sprint(config.TestInitialUpdateWindowDay)),
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "update_window.hour", fmt.Sprint(config.TestInitialUpdateWindowHour)),
),
},
{
Expand Down Expand Up @@ -250,6 +255,8 @@ func TestWorkspaceGroupResourceIntegration(t *testing.T) {
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "admin_password", config.TestInitialAdminPassword),
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "firewall_ranges.#", "1"),
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "firewall_ranges.0", config.TestInitialFirewallRange),
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "update_window", fmt.Sprint(config.TestInitialUpdateWindowDay)),
resource.TestCheckResourceAttr("singlestoredb_workspace_group.this", "update_window.hour", fmt.Sprint(config.TestInitialUpdateWindowHour)),
),
},
{
Expand Down