Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bea1783
fix: remove default task but let task show list of tasks
grubmeshi Jan 16, 2026
b9009fe
fix(depguard): do not allow github.com/hashicorp/terraform-plugin-sdk…
grubmeshi Jan 15, 2026
85c2c98
feat: add util/maps package with MapValues, SortedFunc
grubmeshi Jan 21, 2026
b6a5233
refactor: rename name to better term 'kind' in internal.MeshObjectClient
grubmeshi Jan 15, 2026
3d68ff9
refactor: move Secret DTO from platform to commonly shared client/typ…
grubmeshi Jan 21, 2026
a810fec
feat: add ptr.To helper in client/types/ptr
grubmeshi Jan 21, 2026
8cd1f3f
feat: support modifying provider client to inject client mocks during…
grubmeshi Jan 16, 2026
68e9bf6
feat: add util/reflect Walk() and util/iter
grubmeshi Jan 29, 2026
314f087
feat: add hash.Hasher{}.Hash utility for BBD version_spec content hash
grubmeshi Jan 22, 2026
76b492e
feat: support defining Go enum strings
grubmeshi Jan 30, 2026
c3c09d1
feat: add Variant[X, Y] in client/types/variant
grubmeshi Jan 30, 2026
f1ee4db
feat: add internal/clientmock package to be used in provider tests
grubmeshi Jan 30, 2026
eed4bfc
feat: add examples.Config.String() with ReplaceAll and SetupMockClien…
grubmeshi Feb 4, 2026
9ba08a9
feat: add mock client and resource test for meshstack_tag_definition
grubmeshi Feb 4, 2026
71d385c
feat: add mock client and resource/datasource test for meshstack_plat…
grubmeshi Feb 4, 2026
e3557c3
fix: also add custom platform to datasource
grubmeshi Feb 11, 2026
a4cc395
feat: add mock client and extend resource test for meshstack_location
grubmeshi Feb 4, 2026
a2ed167
feat: add mock client and resource/datasource test for meshstack_plat…
grubmeshi Feb 4, 2026
3f9a353
feat: implement meshstack_integration resource with mock client
grubmeshi Feb 5, 2026
1ddf0ee
refactor: reflect/walk explicit path steps types, add SliceIndexVisitor
grubmeshi Feb 6, 2026
a3ac330
feat: implement generic.ValueTo with generic.Get and generic.ValueFro…
grubmeshi Feb 6, 2026
cfc3562
feat: use generic.Converter for Secret handling
grubmeshi Feb 6, 2026
5fd8213
feat: add utils for provider ref schema and test support
grubmeshi Feb 11, 2026
1d37eb7
feat: use default runner in meshstack_integration if omitted, add ref…
grubmeshi Feb 8, 2026
dbbe2cc
feat: add client.BuildingBlockDefinition(version) with model
grubmeshi Jan 10, 2026
be2fa2d
feat: add meshstack_building_block_definition
grubmeshi Feb 11, 2026
1f32117
chore: add changelog entry
grubmeshi Feb 11, 2026
91fd52a
fix: handle empty argument/defaultValue correctly in SecretOrAny
grubmeshi Feb 11, 2026
5364187
chore: align meshstack_integration docs with API
grubmeshi Feb 12, 2026
e42d82a
chore: align meshstack_building_block_definition docs with API
grubmeshi Feb 12, 2026
2700cc5
feat: add permissions to meshstack_building_block_definition.version_…
grubmeshi Feb 13, 2026
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
42 changes: 40 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,30 @@ linters:
files:
- "!$test"
- "!**/client/**/*.go"
- "!**/internal/clientmock/*.go"
list-mode: strict
deny:
- pkg: log # as $gostd is allowed
desc: Always use 'hclog' or SDK logging
- pkg: github.com/meshcloud/terraform-provider-meshstack/internal/clientmock
desc: clientmock package must only be used in tests
allow:
- $gostd
# explicitly specifying 'client' and 'internal' suffixes prevents 'examples' package to be included in non-test files
# explicitly specifying 'client' and 'internal' suffixes
# prevents 'examples' package to be included in non-test files
- github.com/meshcloud/terraform-provider-meshstack/client
- github.com/meshcloud/terraform-provider-meshstack/internal
- github.com/hashicorp/terraform-plugin-framework/
- github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry
- github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes # for 'any' value support
- github.com/hashicorp/terraform-plugin-framework-validators
- github.com/hashicorp/terraform-plugin-go
- github.com/hashicorp/terraform-plugin-sdk
- github.com/hashicorp/terraform-plugin-log
provider-test:
files:
- "$test"
- "**/internal/clientmock/**/*.go"
- "!**/internal/types/**/*.go"
- "!**/client/**/*_test.go"
- "!**/internal/provider/provider_test.go" # contains common adapters for all tests, using non-testing deps.
list-mode: strict
Expand All @@ -87,4 +94,35 @@ linters:
- $gostd
- github.com/meshcloud/terraform-provider-meshstack # any packages are included in tests
- github.com/hashicorp/terraform-plugin-testing
- github.com/hashicorp/terraform-plugin-framework/diag
- github.com/stretchr/testify
types:
files:
- "**/internal/types/**/*.go"
- "!$test"
list-mode: strict
deny:
- pkg: log # as $gostd is allowed
desc: Always use 'hclog' or SDK logging
allow:
- $gostd
- github.com/meshcloud/terraform-provider-meshstack/client/types # only types should be used from client, if at all!
- github.com/meshcloud/terraform-provider-meshstack/internal/util/
- github.com/meshcloud/terraform-provider-meshstack/internal/types/
- github.com/hashicorp/terraform-plugin-framework/
- github.com/hashicorp/terraform-plugin-go/tftypes
types-test:
files:
- "**/internal/types/**/*_test.go"
list-mode: strict
deny:
- pkg: log # as $gostd is allowed
desc: Always use 'hclog' or SDK logging
allow:
- $gostd
- github.com/meshcloud/terraform-provider-meshstack/internal/util/
- github.com/meshcloud/terraform-provider-meshstack/internal/types/
- github.com/hashicorp/terraform-plugin-framework/
- github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes
- github.com/hashicorp/terraform-plugin-go/tftypes
- github.com/stretchr/testify
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## v0.18.0

FEATURES:

- New resource: `meshstack_building_block_definition`
- New resource: `meshstack_integration`

FIXES:

- `meshstack_platform`: Support custom platform in datasource as well

BREAKING CHANGES:

- Proper secret handling for data source `meshstack_integrations`,
as only the hash is returned from the API now.

## v0.17.5

FEATURES:
Expand Down
5 changes: 0 additions & 5 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ version: '3'
dotenv: ['.env']

tasks:
default:
desc: Run acceptance tests (default task)
cmds:
- task: testacc

testacc:
desc: Run acceptance tests
env:
Expand Down
86 changes: 86 additions & 0 deletions client/api_permissions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package client

import (
"github.com/meshcloud/terraform-provider-meshstack/client/types/enum"
)

// API Permissions as defined in https://docs.meshcloud.io/api/authentication/api-permissions/

type ApiPermission string

// Workspace Permissions (non-admin).
var (
WorkspacePermissions = enum.Enum[ApiPermission]{}

PermissionBuildingBlockDefinitionDelete = WorkspacePermissions.Entry("BUILDINGBLOCKDEFINITION_DELETE")
PermissionBuildingBlockDefinitionList = WorkspacePermissions.Entry("BUILDINGBLOCKDEFINITION_LIST")
PermissionBuildingBlockDefinitionSave = WorkspacePermissions.Entry("BUILDINGBLOCKDEFINITION_SAVE")

PermissionBuildingBlockRunnerDelete = WorkspacePermissions.Entry("BUILDINGBLOCKRUNNER_DELETE")
PermissionBuildingBlockRunnerList = WorkspacePermissions.Entry("BUILDINGBLOCKRUNNER_LIST")
PermissionBuildingBlockRunnerSave = WorkspacePermissions.Entry("BUILDINGBLOCKRUNNER_SAVE")

PermissionBuildingBlockDelete = WorkspacePermissions.Entry("BUILDINGBLOCK_DELETE")
PermissionBuildingBlockList = WorkspacePermissions.Entry("BUILDINGBLOCK_LIST")
PermissionBuildingBlockSave = WorkspacePermissions.Entry("BUILDINGBLOCK_SAVE")

PermissionCommunicationDefinitionDelete = WorkspacePermissions.Entry("COMMUNICATIONDEFINITION_DELETE")
PermissionCommunicationDefinitionList = WorkspacePermissions.Entry("COMMUNICATIONDEFINITION_LIST")
PermissionCommunicationDefinitionSave = WorkspacePermissions.Entry("COMMUNICATIONDEFINITION_SAVE")

PermissionCommunicationDelete = WorkspacePermissions.Entry("COMMUNICATION_DELETE")
PermissionCommunicationList = WorkspacePermissions.Entry("COMMUNICATION_LIST")
PermissionCommunicationSave = WorkspacePermissions.Entry("COMMUNICATION_SAVE")

PermissionEventLogList = WorkspacePermissions.Entry("EVENTLOG_LIST")

PermissionIntegrationDelete = WorkspacePermissions.Entry("INTEGRATION_DELETE")
PermissionIntegrationList = WorkspacePermissions.Entry("INTEGRATION_LIST")
PermissionIntegrationSave = WorkspacePermissions.Entry("INTEGRATION_SAVE")

PermissionLandingZoneDelete = WorkspacePermissions.Entry("LANDINGZONE_DELETE")
PermissionLandingZoneList = WorkspacePermissions.Entry("LANDINGZONE_LIST")
PermissionLandingZoneSave = WorkspacePermissions.Entry("LANDINGZONE_SAVE")

PermissionManagedBuildingBlockRunSourceSave = WorkspacePermissions.Entry("MANAGED_BUILDINGBLOCKRUNSOURCE_SAVE")
PermissionManagedBuildingBlockRunList = WorkspacePermissions.Entry("MANAGED_BUILDINGBLOCKRUN_LIST")
PermissionManagedBuildingBlockRunSave = WorkspacePermissions.Entry("MANAGED_BUILDINGBLOCKRUN_SAVE")
PermissionManagedBuildingBlockList = WorkspacePermissions.Entry("MANAGED_BUILDINGBLOCK_LIST")
PermissionManagedTenantImport = WorkspacePermissions.Entry("MANAGED_TENANT_IMPORT")

PermissionPaymentMethodList = WorkspacePermissions.Entry("PAYMENTMETHOD_LIST")

PermissionPlatformInstanceDelete = WorkspacePermissions.Entry("PLATFORMINSTANCE_DELETE")
PermissionPlatformInstanceList = WorkspacePermissions.Entry("PLATFORMINSTANCE_LIST")
PermissionPlatformInstanceSave = WorkspacePermissions.Entry("PLATFORMINSTANCE_SAVE")

PermissionProjectPrincipalRoleDelete = WorkspacePermissions.Entry("PROJECTPRINCIPALROLE_DELETE")
PermissionProjectPrincipalRoleList = WorkspacePermissions.Entry("PROJECTPRINCIPALROLE_LIST")
PermissionProjectPrincipalRoleSave = WorkspacePermissions.Entry("PROJECTPRINCIPALROLE_SAVE")

PermissionProjectDelete = WorkspacePermissions.Entry("PROJECT_DELETE")
PermissionProjectList = WorkspacePermissions.Entry("PROJECT_LIST")
PermissionProjectSave = WorkspacePermissions.Entry("PROJECT_SAVE")

PermissionServiceInstanceDelete = WorkspacePermissions.Entry("SERVICEINSTANCE_DELETE")
PermissionServiceInstanceList = WorkspacePermissions.Entry("SERVICEINSTANCE_LIST")
PermissionServiceInstanceSave = WorkspacePermissions.Entry("SERVICEINSTANCE_SAVE")

PermissionTenantDelete = WorkspacePermissions.Entry("TENANT_DELETE")
PermissionTenantList = WorkspacePermissions.Entry("TENANT_LIST")
PermissionTenantSave = WorkspacePermissions.Entry("TENANT_SAVE")

PermissionTfStateDelete = WorkspacePermissions.Entry("TFSTATE_DELETE")
PermissionTfStateList = WorkspacePermissions.Entry("TFSTATE_LIST")
PermissionTfStateSave = WorkspacePermissions.Entry("TFSTATE_SAVE")

PermissionWorkspacePrincipalBindingDelete = WorkspacePermissions.Entry("WORKSPACEPRINCIPALBINDING_DELETE")
PermissionWorkspacePrincipalBindingList = WorkspacePermissions.Entry("WORKSPACEPRINCIPALBINDING_LIST")
PermissionWorkspacePrincipalBindingSave = WorkspacePermissions.Entry("WORKSPACEPRINCIPALBINDING_SAVE")

PermissionWorkspaceUserGroupList = WorkspacePermissions.Entry("WORKSPACEUSERGROUP_LIST")

PermissionWorkspaceDelete = WorkspacePermissions.Entry("WORKSPACE_DELETE")
PermissionWorkspaceList = WorkspacePermissions.Entry("WORKSPACE_LIST")
PermissionWorkspaceSave = WorkspacePermissions.Entry("WORKSPACE_SAVE")
)
110 changes: 110 additions & 0 deletions client/buildingblock_definition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package client

import (
"context"

"github.com/meshcloud/terraform-provider-meshstack/client/internal"
"github.com/meshcloud/terraform-provider-meshstack/client/types/enum"
)

type MeshBuildingBlockType string

var (
MeshBuildingBlockTypes = enum.Enum[MeshBuildingBlockType]{}
MeshBuildingBlockTypeTenantLevel = MeshBuildingBlockTypes.Entry("TENANT_LEVEL")
MeshBuildingBlockTypeWorkspaceLevel = MeshBuildingBlockTypes.Entry("WORKSPACE_LEVEL")
)

type MeshBuildingBlockDefinitionMetadata struct {
Uuid *string `json:"uuid,omitempty" tfsdk:"uuid"`
OwnedByWorkspace string `json:"ownedByWorkspace" tfsdk:"owned_by_workspace"`
Tags map[string][]string `json:"tags" tfsdk:"tags"`
}

type BuildingBlockDefinitionSupportedPlatform string

type MeshBuildingBlockDefinitionSpec struct {
DisplayName string `json:"displayName" tfsdk:"display_name"`
TargetType MeshBuildingBlockType `json:"targetType" tfsdk:"target_type"`
Description string `json:"description" tfsdk:"description"`
Readme *string `json:"readme,omitempty" tfsdk:"readme"`
RunTransparency bool `json:"runTransparency" tfsdk:"run_transparency"`
UseInLandingZonesOnly bool `json:"useInLandingZonesOnly" tfsdk:"use_in_landing_zones_only"`
SupportURL *string `json:"supportUrl,omitempty" tfsdk:"support_url"`
DocumentationURL *string `json:"documentationUrl,omitempty" tfsdk:"documentation_url"`
// NotificationSubscribers can also specify emails with prefix 'email:', so it's not only usernames (as the JSON field name suggests)!
NotificationSubscribers []string `json:"notificationSubscriberUsernames,omitempty" tfsdk:"notification_subscribers"`
Symbol *string `json:"symbol,omitempty" tfsdk:"symbol"`
// SupportedPlatforms are currently platform types only. Specifying single platforms is currently unsupported.
// Have this list of string with a dedicated type, to convert it to/from Platform Type refs.
SupportedPlatforms []BuildingBlockDefinitionSupportedPlatform `json:"supportedPlatforms" tfsdk:"supported_platforms"`
}

type MeshBuildingBlockDefinitionStatusVersion struct {
VersionUuid string `json:"versionUuid"`
VersionNumber int64 `json:"versionNumber"`
State MeshBuildingBlockDefinitionVersionState `json:"state"`
}

type MeshBuildingBlockDefinitionStatus struct {
UsageCount *int64 `json:"usageCount"`
Versions []MeshBuildingBlockDefinitionStatusVersion `json:"versions"`
LatestVersion int64 `json:"latestVersion"`
LatestVersionUuid string `json:"latestVersionUuid"`
LatestReleasedVersion *int64 `json:"latestReleasedVersion"`
LatestReleasedVersionUuid *string `json:"latestReleasedVersionUuid"`
}

type MeshBuildingBlockDefinition struct {
ApiVersion string `json:"apiVersion"`
Kind string `json:"kind"`
Metadata MeshBuildingBlockDefinitionMetadata `json:"metadata"`
Spec MeshBuildingBlockDefinitionSpec `json:"spec"`
Status *MeshBuildingBlockDefinitionStatus `json:"status,omitempty"`
}

type MeshBuildingBlockDefinitionClient interface {
List(ctx context.Context, workspaceIdentifier *string) ([]MeshBuildingBlockDefinition, error)
Read(ctx context.Context, uuid string) (*MeshBuildingBlockDefinition, error)
Create(ctx context.Context, definition MeshBuildingBlockDefinition) (*MeshBuildingBlockDefinition, error)
Update(ctx context.Context, uuid string, definition MeshBuildingBlockDefinition) (*MeshBuildingBlockDefinition, error)
Delete(ctx context.Context, uuid string) error
}

type meshBuildingBlockDefinitionClient struct {
meshObject internal.MeshObjectClient[MeshBuildingBlockDefinition]
}

func newBuildingBlockDefinitionClient(ctx context.Context, httpClient *internal.HttpClient) MeshBuildingBlockDefinitionClient {
return meshBuildingBlockDefinitionClient{
meshObject: internal.NewMeshObjectClient[MeshBuildingBlockDefinition](ctx, httpClient, "v1-preview"),
}
}

func (c meshBuildingBlockDefinitionClient) List(ctx context.Context, workspaceIdentifier *string) ([]MeshBuildingBlockDefinition, error) {
var options []internal.RequestOption
if workspaceIdentifier != nil {
options = append(options, internal.WithUrlQuery("workspaceIdentifier", *workspaceIdentifier))
}
return c.meshObject.List(ctx, options...)
}

func (c meshBuildingBlockDefinitionClient) Read(ctx context.Context, uuid string) (*MeshBuildingBlockDefinition, error) {
return c.meshObject.Get(ctx, uuid)
}

func (c meshBuildingBlockDefinitionClient) Create(ctx context.Context, definition MeshBuildingBlockDefinition) (*MeshBuildingBlockDefinition, error) {
definition.Kind = c.meshObject.Kind
definition.ApiVersion = c.meshObject.ApiVersion
return c.meshObject.Post(ctx, definition)
}

func (c meshBuildingBlockDefinitionClient) Update(ctx context.Context, uuid string, definition MeshBuildingBlockDefinition) (*MeshBuildingBlockDefinition, error) {
definition.Kind = c.meshObject.Kind
definition.ApiVersion = c.meshObject.ApiVersion
return c.meshObject.Put(ctx, uuid, definition)
}

func (c meshBuildingBlockDefinitionClient) Delete(ctx context.Context, uuid string) error {
return c.meshObject.Delete(ctx, uuid)
}
Loading