Skip to content

Commit 866c044

Browse files
committed
feat: add client.BuildingBlockDefinition(version) with model
1 parent ffe1014 commit 866c044

12 files changed

+598
-21
lines changed

client/buildingblock_definition.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package client
2+
3+
import (
4+
"context"
5+
6+
"github.com/meshcloud/terraform-provider-meshstack/client/internal"
7+
"github.com/meshcloud/terraform-provider-meshstack/client/types/enum"
8+
)
9+
10+
type MeshBuildingBlockType string
11+
12+
var (
13+
MeshBuildingBlockTypes = enum.Enum[MeshBuildingBlockType]{}
14+
MeshBuildingBlockTypeTenantLevel = MeshBuildingBlockTypes.Entry("TENANT_LEVEL")
15+
MeshBuildingBlockTypeWorkspaceLevel = MeshBuildingBlockTypes.Entry("WORKSPACE_LEVEL")
16+
)
17+
18+
type MeshBuildingBlockDefinitionMetadata struct {
19+
Uuid *string `json:"uuid,omitempty" tfsdk:"uuid"`
20+
OwnedByWorkspace string `json:"ownedByWorkspace" tfsdk:"owned_by_workspace"`
21+
Tags map[string][]string `json:"tags" tfsdk:"tags"`
22+
}
23+
24+
type MeshBuildingBlockDefinitionSpecBase struct {
25+
}
26+
27+
type BuildingBlockDefinitionSupportedPlatform string
28+
29+
type MeshBuildingBlockDefinitionSpec struct {
30+
DisplayName string `json:"displayName" tfsdk:"display_name"`
31+
TargetType MeshBuildingBlockType `json:"targetType" tfsdk:"target_type"`
32+
Description string `json:"description" tfsdk:"description"`
33+
Readme *string `json:"readme,omitempty" tfsdk:"readme"`
34+
RunTransparency bool `json:"runTransparency" tfsdk:"run_transparency"`
35+
UseInLandingZonesOnly bool `json:"useInLandingZonesOnly" tfsdk:"use_in_landing_zones_only"`
36+
SupportURL *string `json:"supportUrl,omitempty" tfsdk:"support_url"`
37+
DocumentationURL *string `json:"documentationUrl,omitempty" tfsdk:"documentation_url"`
38+
// NotificationSubscribers can also specify emails with prefix 'email:', so it's not only usernames (as the JSON field name suggests)!
39+
NotificationSubscribers []string `json:"notificationSubscriberUsernames,omitempty" tfsdk:"notification_subscribers"`
40+
Symbol *string `json:"symbol,omitempty" tfsdk:"symbol"`
41+
// SupportedPlatforms are currently platform types only. Specifying single platforms is currently unsupported.
42+
// Have this list of string with a dedicated type, to convert it to/from Platform Type refs.
43+
SupportedPlatforms []BuildingBlockDefinitionSupportedPlatform `json:"supportedPlatforms" tfsdk:"supported_platforms"`
44+
}
45+
46+
type MeshBuildingBlockDefinitionStatusVersion struct {
47+
VersionUuid string `json:"versionUuid"`
48+
VersionNumber int64 `json:"versionNumber" `
49+
State MeshBuildingBlockDefinitionVersionState `json:"state"`
50+
}
51+
52+
type MeshBuildingBlockDefinitionStatus struct {
53+
UsageCount *int64 `json:"usageCount"`
54+
Versions []MeshBuildingBlockDefinitionStatusVersion `json:"versions"`
55+
LatestVersion int64 `json:"latestVersion"`
56+
LatestVersionUuid string `json:"latestVersionUuid" `
57+
LatestReleasedVersion *int64 `json:"latestReleasedVersion"`
58+
LatestReleasedVersionUuid *string `json:"latestReleasedVersionUuid"`
59+
}
60+
61+
type MeshBuildingBlockDefinition struct {
62+
ApiVersion string `json:"apiVersion"`
63+
Kind string `json:"kind"`
64+
Metadata MeshBuildingBlockDefinitionMetadata `json:"metadata" `
65+
Spec MeshBuildingBlockDefinitionSpec `json:"spec"`
66+
Status *MeshBuildingBlockDefinitionStatus `json:"status,omitempty"`
67+
}
68+
69+
type MeshBuildingBlockDefinitionClient interface {
70+
List(ctx context.Context, workspaceIdentifier *string) ([]MeshBuildingBlockDefinition, error)
71+
Read(ctx context.Context, uuid string) (*MeshBuildingBlockDefinition, error)
72+
Create(ctx context.Context, definition MeshBuildingBlockDefinition) (*MeshBuildingBlockDefinition, error)
73+
Update(ctx context.Context, uuid string, definition MeshBuildingBlockDefinition) (*MeshBuildingBlockDefinition, error)
74+
Delete(ctx context.Context, uuid string) error
75+
}
76+
77+
type meshBuildingBlockDefinitionClient struct {
78+
meshObject internal.MeshObjectClient[MeshBuildingBlockDefinition]
79+
}
80+
81+
func newBuildingBlockDefinitionClient(ctx context.Context, httpClient *internal.HttpClient) MeshBuildingBlockDefinitionClient {
82+
return meshBuildingBlockDefinitionClient{
83+
meshObject: internal.NewMeshObjectClient[MeshBuildingBlockDefinition](ctx, httpClient, "v1-preview"),
84+
}
85+
}
86+
87+
func (c meshBuildingBlockDefinitionClient) List(ctx context.Context, workspaceIdentifier *string) ([]MeshBuildingBlockDefinition, error) {
88+
var options []internal.RequestOption
89+
if workspaceIdentifier != nil {
90+
options = append(options, internal.WithUrlQuery("workspaceIdentifier", *workspaceIdentifier))
91+
}
92+
return c.meshObject.List(ctx, options...)
93+
}
94+
95+
func (c meshBuildingBlockDefinitionClient) Read(ctx context.Context, uuid string) (*MeshBuildingBlockDefinition, error) {
96+
return c.meshObject.Get(ctx, uuid)
97+
}
98+
99+
func (c meshBuildingBlockDefinitionClient) Create(ctx context.Context, definition MeshBuildingBlockDefinition) (*MeshBuildingBlockDefinition, error) {
100+
definition.Kind = c.meshObject.Kind
101+
definition.ApiVersion = c.meshObject.ApiVersion
102+
return c.meshObject.Post(ctx, definition)
103+
}
104+
105+
func (c meshBuildingBlockDefinitionClient) Update(ctx context.Context, uuid string, definition MeshBuildingBlockDefinition) (*MeshBuildingBlockDefinition, error) {
106+
definition.Kind = c.meshObject.Kind
107+
definition.ApiVersion = c.meshObject.ApiVersion
108+
return c.meshObject.Put(ctx, uuid, definition)
109+
}
110+
111+
func (c meshBuildingBlockDefinitionClient) Delete(ctx context.Context, uuid string) error {
112+
return c.meshObject.Delete(ctx, uuid)
113+
}
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"errors"
7+
"fmt"
8+
9+
"github.com/meshcloud/terraform-provider-meshstack/client/internal"
10+
"github.com/meshcloud/terraform-provider-meshstack/client/types"
11+
"github.com/meshcloud/terraform-provider-meshstack/client/types/enum"
12+
)
13+
14+
// Enums
15+
16+
type MeshBuildingBlockDefinitionVersionState string
17+
18+
var (
19+
MeshBuildingBlockDefinitionVersionStates = enum.Enum[MeshBuildingBlockDefinitionVersionState]{}
20+
MeshBuildingBlockDefinitionVersionStateDraft = MeshBuildingBlockDefinitionVersionStates.Entry("DRAFT")
21+
MeshBuildingBlockDefinitionVersionStateReleased = MeshBuildingBlockDefinitionVersionStates.Entry("RELEASED")
22+
)
23+
24+
type BuildingBlockDeletionMode string
25+
26+
var (
27+
BuildingBlockDeletionModes = enum.Enum[BuildingBlockDeletionMode]{}
28+
BuildingBlockDeletionModeDelete = BuildingBlockDeletionModes.Entry("DELETE")
29+
BuildingBlockDeletionModePurge = BuildingBlockDeletionModes.Entry("PURGE")
30+
)
31+
32+
type MeshBuildingBlockIOType string
33+
34+
var (
35+
MeshBuildingBlockIOTypes = enum.Enum[MeshBuildingBlockIOType]{}
36+
MeshBuildingBlockIOTypeString = MeshBuildingBlockIOTypes.Entry("STRING")
37+
MeshBuildingBlockIOTypeCode = MeshBuildingBlockIOTypes.Entry("CODE")
38+
MeshBuildingBlockIOTypeInteger = MeshBuildingBlockIOTypes.Entry("INTEGER")
39+
MeshBuildingBlockIOTypeBoolean = MeshBuildingBlockIOTypes.Entry("BOOLEAN")
40+
MeshBuildingBlockIOTypeFile = MeshBuildingBlockIOTypes.Entry("FILE")
41+
MeshBuildingBlockIOTypeList = MeshBuildingBlockIOTypes.Entry("LIST")
42+
MeshBuildingBlockIOTypeSingleSelect = MeshBuildingBlockIOTypes.Entry("SINGLE_SELECT")
43+
MeshBuildingBlockIOTypeMultiSelect = MeshBuildingBlockIOTypes.Entry("MULTI_SELECT")
44+
)
45+
46+
type MeshBuildingBlockInputAssignmentType string
47+
48+
var (
49+
MeshBuildingBlockInputAssignmentTypes = enum.Enum[MeshBuildingBlockInputAssignmentType]{}
50+
MeshBuildingBlockInputAssignmentTypeAuthor = MeshBuildingBlockInputAssignmentTypes.Entry("AUTHOR")
51+
MeshBuildingBlockInputAssignmentTypeUserInput = MeshBuildingBlockInputAssignmentTypes.Entry("USER_INPUT")
52+
MeshBuildingBlockInputAssignmentTypePlatformOperatorManualInput = MeshBuildingBlockInputAssignmentTypes.Entry("PLATFORM_OPERATOR_MANUAL_INPUT")
53+
MeshBuildingBlockInputAssignmentTypeBuildingBlockOutput = MeshBuildingBlockInputAssignmentTypes.Entry("BUILDING_BLOCK_OUTPUT")
54+
MeshBuildingBlockInputAssignmentTypePlatformTenantID = MeshBuildingBlockInputAssignmentTypes.Entry("PLATFORM_TENANT_ID")
55+
MeshBuildingBlockInputAssignmentTypeWorkspaceIdentifier = MeshBuildingBlockInputAssignmentTypes.Entry("WORKSPACE_IDENTIFIER")
56+
MeshBuildingBlockInputAssignmentTypeProjectIdentifier = MeshBuildingBlockInputAssignmentTypes.Entry("PROJECT_IDENTIFIER")
57+
MeshBuildingBlockInputAssignmentTypeFullPlatformIdentifier = MeshBuildingBlockInputAssignmentTypes.Entry("FULL_PLATFORM_IDENTIFIER")
58+
MeshBuildingBlockInputAssignmentTypeTenantBuildingBlockUuid = MeshBuildingBlockInputAssignmentTypes.Entry("TENANT_BUILDING_BLOCK_UUID")
59+
MeshBuildingBlockInputAssignmentTypeStatic = MeshBuildingBlockInputAssignmentTypes.Entry("STATIC")
60+
MeshBuildingBlockInputAssignmentTypeUserPermissions = MeshBuildingBlockInputAssignmentTypes.Entry("USER_PERMISSIONS")
61+
)
62+
63+
type MeshBuildingBlockDefinitionOutputAssignmentType string
64+
65+
var (
66+
MeshBuildingBlockDefinitionOutputAssignmentTypes = enum.Enum[MeshBuildingBlockDefinitionOutputAssignmentType]{}
67+
MeshBuildingBlockDefinitionOutputAssignmentTypeNone = MeshBuildingBlockDefinitionOutputAssignmentTypes.Entry("NONE")
68+
MeshBuildingBlockDefinitionOutputAssignmentTypePlatformTenantID = MeshBuildingBlockDefinitionOutputAssignmentTypes.Entry("PLATFORM_TENANT_ID")
69+
MeshBuildingBlockDefinitionOutputAssignmentTypeSignInURL = MeshBuildingBlockDefinitionOutputAssignmentTypes.Entry("SIGN_IN_URL")
70+
MeshBuildingBlockDefinitionOutputAssignmentTypeResourceURL = MeshBuildingBlockDefinitionOutputAssignmentTypes.Entry("RESOURCE_URL")
71+
MeshBuildingBlockDefinitionOutputAssignmentTypeSummary = MeshBuildingBlockDefinitionOutputAssignmentTypes.Entry("SUMMARY")
72+
)
73+
74+
// Ref types
75+
76+
type BuildingBlockDefinitionRef struct {
77+
Uuid string `json:"uuid"`
78+
Kind string `json:"kind"`
79+
}
80+
81+
type MeshIntegrationRef struct {
82+
Uuid string `json:"uuid" tfsdk:"uuid"`
83+
Kind string `json:"kind" tfsdk:"kind"`
84+
}
85+
86+
// Input and Output types
87+
88+
type MeshBuildingBlockDefinitionInput struct {
89+
DisplayName string `json:"displayName" tfsdk:"display_name"`
90+
Type MeshBuildingBlockIOType `json:"type" tfsdk:"type"`
91+
AssignmentType MeshBuildingBlockInputAssignmentType `json:"assignmentType" tfsdk:"assignment_type"`
92+
IsEnvironment bool `json:"isEnvironment" tfsdk:"is_environment"`
93+
IsSensitive bool `json:"isSensitive" tfsdk:"-"`
94+
// If IsSensitive is true, the [types.Variant] (typedef [types.SecretOrAny]) for fields
95+
// MeshBuildingBlockDefinitionInputAdapter.Argument and
96+
// MeshBuildingBlockDefinitionInputAdapter.DefaultValue
97+
// is of [types.Secret] (case [types.Variant.X]).
98+
// Otherwise, the [types.Variant] is of [types.Any] (case [types.Variant.Y]).
99+
// As this is a fallback detection when JSON (un)marshaling,
100+
// types.Any must go second as [types.Variant] intentionally prefers X over Y.
101+
Argument types.SecretOrAny `json:"argument,omitempty" tfsdk:"argument"`
102+
DefaultValue types.SecretOrAny `json:"defaultValue,omitempty" tfsdk:"default_value"`
103+
UpdateableByConsumer bool `json:"updateableByConsumer" tfsdk:"updateable_by_consumer"`
104+
SelectableValues []types.SetElem `json:"selectableValues,omitempty" tfsdk:"selectable_values"`
105+
Description *string `json:"description,omitempty" tfsdk:"description"`
106+
ValueValidationRegex *string `json:"valueValidationRegex,omitempty" tfsdk:"value_validation_regex"`
107+
ValidationRegexErrorMessage *string `json:"validationRegexErrorMessage,omitempty" tfsdk:"validation_regex_error_message"`
108+
}
109+
110+
func (m *MeshBuildingBlockDefinitionInput) UnmarshalJSON(bytes []byte) error {
111+
type wrapped MeshBuildingBlockDefinitionInput
112+
var target wrapped
113+
if err := json.Unmarshal(bytes, &target); err != nil {
114+
return err
115+
}
116+
*m = MeshBuildingBlockDefinitionInput(target)
117+
switch {
118+
case !m.IsSensitive:
119+
// ensure "any" struct fields never end up in X accidentally,
120+
// as X is only set when IsSensitive is true!
121+
var errs []error
122+
moveXtoYIfPresent := func(v *types.SecretOrAny) {
123+
if v.HasX() {
124+
xJson, err := json.Marshal(v.X)
125+
errs = append(errs, err)
126+
v.X = types.Secret{}
127+
errs = append(errs, json.Unmarshal(xJson, &v.Y))
128+
}
129+
}
130+
moveXtoYIfPresent(&m.Argument)
131+
moveXtoYIfPresent(&m.DefaultValue)
132+
return errors.Join(errs...)
133+
case m.Argument.HasY(), m.DefaultValue.HasY():
134+
return fmt.Errorf("got sensitive argument or default_value but variant Y is set instead")
135+
default:
136+
return nil
137+
}
138+
}
139+
140+
type MeshBuildingBlockDefinitionOutput struct {
141+
DisplayName string `json:"displayName" tfsdk:"display_name"`
142+
Type MeshBuildingBlockIOType `json:"type" tfsdk:"type"`
143+
AssignmentType MeshBuildingBlockDefinitionOutputAssignmentType `json:"assignmentType" tfsdk:"assignment_type"`
144+
}
145+
146+
// Main version types
147+
148+
type MeshBuildingBlockDefinitionVersionMetadata struct {
149+
Uuid string `json:"uuid"`
150+
OwnedByWorkspace string `json:"ownedByWorkspace"`
151+
CreatedOn string `json:"createdOn"`
152+
}
153+
154+
type BuildingBlockDependencyRef string
155+
type MeshBuildingBlockDefinitionVersionSpec struct {
156+
BuildingBlockDefinitionRef *BuildingBlockDefinitionRef `json:"buildingBlockDefinitionRef" tfsdk:"-"`
157+
OnlyApplyOncePerTenant bool `json:"onlyApplyOncePerTenant" tfsdk:"only_apply_once_per_tenant"`
158+
DeletionMode BuildingBlockDeletionMode `json:"deletionMode" tfsdk:"deletion_mode"`
159+
Outputs map[string]MeshBuildingBlockDefinitionOutput `json:"outputs" tfsdk:"outputs"`
160+
VersionNumber *int64 `json:"versionNumber,omitempty" tfsdk:"version_number"`
161+
State *MeshBuildingBlockDefinitionVersionState `json:"state,omitempty" tfsdk:"state"`
162+
RunnerRef *BuildingBlockRunnerRef `json:"runnerRef" tfsdk:"runner_ref"`
163+
DependencyDefinitionUUIDs []BuildingBlockDependencyRef `json:"dependencyDefinitionUuids,omitempty" tfsdk:"dependency_refs"`
164+
Implementation MeshBuildingBlockDefinitionImplementation `json:"implementation" tfsdk:"implementation"`
165+
Inputs map[string]*MeshBuildingBlockDefinitionInput `json:"inputs" tfsdk:"inputs"`
166+
}
167+
168+
type MeshBuildingBlockDefinitionVersionStatus struct {
169+
State MeshBuildingBlockDefinitionVersionState `json:"state" tfsdk:"state"`
170+
UsageCount int64 `json:"usageCount" tfsdk:"usage_count"`
171+
}
172+
173+
type MeshBuildingBlockDefinitionVersion struct {
174+
ApiVersion string `json:"apiVersion" tfsdk:"api_version"`
175+
Kind string `json:"kind" tfsdk:"kind"`
176+
Metadata MeshBuildingBlockDefinitionVersionMetadata `json:"metadata" tfsdk:"metadata"`
177+
Spec MeshBuildingBlockDefinitionVersionSpec `json:"spec" tfsdk:"spec"`
178+
Status *MeshBuildingBlockDefinitionVersionStatus `json:"status,omitempty" tfsdk:"status"`
179+
}
180+
181+
type MeshBuildingBlockDefinitionVersionClient interface {
182+
List(ctx context.Context, buildingBlockDefinitionUuid string) ([]MeshBuildingBlockDefinitionVersion, error)
183+
Create(ctx context.Context, ownedByWorkspace string, versionSpec MeshBuildingBlockDefinitionVersionSpec) (*MeshBuildingBlockDefinitionVersion, error)
184+
Update(ctx context.Context, uuid, ownedByWorkspace string, versionSpec MeshBuildingBlockDefinitionVersionSpec) (*MeshBuildingBlockDefinitionVersion, error)
185+
}
186+
187+
type meshBuildingBlockDefinitionVersionClient struct {
188+
meshObject internal.MeshObjectClient[MeshBuildingBlockDefinitionVersion]
189+
}
190+
191+
func newBuildingBlockDefinitionVersionClient(ctx context.Context, httpClient *internal.HttpClient) MeshBuildingBlockDefinitionVersionClient {
192+
return meshBuildingBlockDefinitionVersionClient{
193+
meshObject: internal.NewMeshObjectClient[MeshBuildingBlockDefinitionVersion](ctx, httpClient, "v1-preview"),
194+
}
195+
}
196+
197+
func (c meshBuildingBlockDefinitionVersionClient) List(ctx context.Context, buildingBlockDefinitionUuid string) ([]MeshBuildingBlockDefinitionVersion, error) {
198+
return c.meshObject.List(ctx, internal.WithUrlQuery("buildingBlockDefinitionUuid", buildingBlockDefinitionUuid))
199+
}
200+
201+
func (c meshBuildingBlockDefinitionVersionClient) Create(ctx context.Context, ownedByWorkspace string, versionSpec MeshBuildingBlockDefinitionVersionSpec) (*MeshBuildingBlockDefinitionVersion, error) {
202+
return c.meshObject.Post(ctx, MeshBuildingBlockDefinitionVersion{
203+
ApiVersion: c.meshObject.ApiVersion,
204+
Kind: c.meshObject.Kind,
205+
Metadata: MeshBuildingBlockDefinitionVersionMetadata{
206+
OwnedByWorkspace: ownedByWorkspace,
207+
},
208+
Spec: versionSpec,
209+
})
210+
}
211+
212+
func (c meshBuildingBlockDefinitionVersionClient) Update(ctx context.Context, uuid, ownedByWorkspace string, versionSpec MeshBuildingBlockDefinitionVersionSpec) (*MeshBuildingBlockDefinitionVersion, error) {
213+
return c.meshObject.Put(ctx, uuid, MeshBuildingBlockDefinitionVersion{
214+
ApiVersion: c.meshObject.ApiVersion,
215+
Kind: c.meshObject.Kind,
216+
Metadata: MeshBuildingBlockDefinitionVersionMetadata{
217+
Uuid: uuid,
218+
OwnedByWorkspace: ownedByWorkspace,
219+
},
220+
Spec: versionSpec,
221+
})
222+
}

0 commit comments

Comments
 (0)