|
| 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