Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 09d0b47

Browse files
Merge pull request #28 from matthewhartstonge/feature/framework-update
2 parents 4b92a4d + d20427c commit 09d0b47

File tree

13 files changed

+463
-820
lines changed

13 files changed

+463
-820
lines changed

.github/workflows/go.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
runs-on: ubuntu-latest
3030
strategy:
3131
matrix:
32-
go-version: [ '1.18', '1.19' ]
32+
go-version: [ '1.19', '1.20' ]
3333
steps:
3434
- name: Checkout Repository
3535
uses: actions/checkout@v3

.run/go test terraform-plugin-framework-type-uuid_uuidtype.run.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
~ Copyright (c) 2022 Matthew Hartstonge <[email protected]>
2+
~ Copyright (c) 2023 Matthew Hartstonge <[email protected]>
33
~
44
~ This Source Code Form is subject to the terms of the Mozilla Public
55
~ License, v. 2.0. If a copy of the MPL was not distributed with this

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2022 Matthew Hartstonge <[email protected]>
1+
Copyright (c) 2023 Matthew Hartstonge <[email protected]>
22

33
Mozilla Public License Version 2.0
44
==================================

README.md

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,44 @@
22

33
[![godoc](https://pkg.go.dev/badge/github.com/matthewhartstonge/terraform-plugin-framework-type-uuid)](https://pkg.go.dev/github.com/matthewhartstonge/terraform-plugin-framework-type-uuid)
44

5-
UUID string type and value implementation for the [Terraform Plugin Framework](https://github.com/hashicorp/terraform-plugin-framework).
6-
Provides validation via Google's UUID library for Go based on [RFC 4122](https://www.rfc-editor.org/rfc/rfc4122.html)
7-
and DCE 1.1: Authentication and Security Services.
5+
UUID type and value implementation for the [Terraform Plugin Framework](https://github.com/hashicorp/terraform-plugin-framework).
6+
Provides validation via Hashicorp's UUID library for Go based on [RFC 4122](https://www.rfc-editor.org/rfc/rfc4122.html) (note: not intended to be spec compliant)
87

98
## Getting Started
109

1110
### Schema
1211

13-
Replace usages of `types.StringType` with `uuidtypes.UUIDType{}`.
12+
The Terraform Plugin Framework schema types accept a `CustomType` field. The `uuidtypes.UUID` custom type can be injected into any current `schema.StringAttribute`.
1413

15-
Given the previous schema attribute:
14+
In the following example, the ID field is set to the custom UUID Type.
1615

1716
```go
18-
tfsdk.Attribute{
19-
Required: true
20-
Type: types.StringType
21-
// Potential prior validators...
22-
}
23-
```
24-
25-
The updated schema will look like:
26-
27-
```go
28-
tfsdk.Attribute{
29-
Required: true
30-
Type: uuidtypes.UUIDType{}
17+
func (r *ExampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
18+
resp.Schema = schema.Schema{
19+
// This description is used by the documentation generator and the language server.
20+
MarkdownDescription: "Example resource",
21+
22+
Attributes: map[string]schema.Attribute{
23+
"id": schema.StringAttribute{
24+
CustomType: uuidtypes.UUIDType{},
25+
Required: true,
26+
// ...
27+
},
28+
},
29+
}
3130
}
3231
```
3332

3433
### Schema Data Model
3534

36-
Replace usage of `string`, `*string`, or `types.String` in schema data models
37-
with `uuidtype.UUID`.
35+
Replace usage of `types.String` in schema data models with `uuidtype.UUID`.
3836

3937
Given the previous schema data model:
4038

4139
```go
4240
type ThingResourceModel struct {
4341
// ...
44-
Example types.String `tfsdk:"example"`
42+
ID types.String `tfsdk:"id"`
4543
}
4644
```
4745

@@ -50,27 +48,26 @@ The updated schema data model will look like:
5048
```go
5149
type ThingResourceModel struct {
5250
// ...
53-
Example uuidtypes.UUID `tfsdk:"example"`
51+
ID uuidtypes.UUID `tfsdk:"id"`
5452
}
5553
```
5654

5755
### Accessing Values
5856

5957
Similar to other value types, use the `IsNull()` and `IsUnknown()` methods to
60-
check whether the value is null or unknown. Use the `String()` method to extract
58+
check whether the value is null or unknown. Use the `ValueString()` method to extract
6159
a known `uuid` value.
6260

6361
### Writing Values
6462

6563
Create a `uuidtypes.UUID` by calling one of these functions:
6664

67-
- `UUIDNull() UUID`: creates a `null` value.
68-
- `UUIDUnknown() UUID`: creates an unknown value.
69-
- `UUIDFromString(string, path.Path) (UUID, diag.Diagnostics)`: creates a known
70-
value using the given `string` or returns validation errors if `string` is
71-
not in the expected UUID format.
72-
- `UUIDFromGoogleUUID(uuid.UUID) UUID` creates a known value given a
73-
Google [uuid.UUID](https://pkg.go.dev/github.com/google/uuid#UUID) struct.
65+
- `NewUUIDNull() UUID`: creates a `null` value.
66+
- `NewUUIDUnknown() UUID`: creates an unknown value.
67+
- `NewUUIDValue(string) UUID`: creates a known value using the given `string`.
68+
- `NewUUIDPointerValue(string) UUID`: creates a known value using the given `*string`.
69+
70+
This type implements validation which is called and handled by Terraform.
7471

7572
### Adding the Dependency
7673

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
module github.com/matthewhartstonge/terraform-plugin-framework-type-uuid
22

3-
go 1.18
3+
go 1.19
44

55
require (
66
github.com/google/go-cmp v0.5.9
7-
github.com/google/uuid v1.3.0
7+
github.com/hashicorp/go-uuid v1.0.3
88
github.com/hashicorp/terraform-plugin-framework v1.3.2
99
github.com/hashicorp/terraform-plugin-go v0.18.0
1010
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
33
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
44
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
55
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
6-
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
7-
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
6+
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
7+
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
88
github.com/hashicorp/terraform-plugin-framework v1.3.2 h1:aQ6GSD0CTnvoALEWvKAkcH/d8jqSE0Qq56NYEhCexUs=
99
github.com/hashicorp/terraform-plugin-framework v1.3.2/go.mod h1:oimsRAPJOYkZ4kY6xIGfR0PHjpHLDLaknzuptl6AvnY=
1010
github.com/hashicorp/terraform-plugin-go v0.18.0 h1:IwTkOS9cOW1ehLd/rG0y+u/TGLK9y6fGoBjXVUquzpE=

uuidtypes/doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Matthew Hartstonge <[email protected]>
2+
* Copyright (c) 2023 Matthew Hartstonge <[email protected]>
33
*
44
* This Source Code Form is subject to the terms of the Mozilla Public
55
* License, v. 2.0. If a copy of the MPL was not distributed with this

uuidtypes/uuid.go

Lines changed: 21 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Matthew Hartstonge <[email protected]>
2+
* Copyright (c) 2023 Matthew Hartstonge <[email protected]>
33
*
44
* This Source Code Form is subject to the terms of the Mozilla Public
55
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,127 +9,36 @@
99
package uuidtypes
1010

1111
import (
12-
// Standard Library Imports
13-
"context"
14-
1512
// External Imports
16-
"github.com/google/uuid"
17-
"github.com/hashicorp/terraform-plugin-framework/attr"
18-
"github.com/hashicorp/terraform-plugin-framework/diag"
19-
"github.com/hashicorp/terraform-plugin-framework/path"
20-
"github.com/hashicorp/terraform-plugin-go/tftypes"
21-
)
22-
23-
// Ensure Implementation matches the expected interfaces.
24-
var (
25-
_ attr.Value = UUID{}
13+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
2614
)
2715

28-
// UUIDNull returns a null UUID value.
29-
func UUIDNull() UUID {
30-
return UUID{state: attr.ValueStateNull}
31-
}
32-
33-
// UUIDUnknown returns an unknown UUID value.
34-
func UUIDUnknown() UUID {
35-
return UUID{state: attr.ValueStateUnknown}
36-
}
37-
38-
// UUIDFromString returns a value or any errors when attempting to parse the
39-
// string as a UUID.
40-
func UUIDFromString(value string, schemaPath path.Path) (UUID, diag.Diagnostics) {
41-
validUUID, err := uuid.Parse(value)
42-
if err != nil {
43-
return UUIDUnknown(), diag.Diagnostics{
44-
diag.NewAttributeErrorDiagnostic(
45-
schemaPath,
46-
"Invalid UUID String Value",
47-
"An unexpected error occurred attempting to parse a string value that was expected to be a valid UUID format. "+
48-
"The expected UUID format is 00000000-0000-0000-0000-00000000. "+
49-
"For example, a Version 4 UUID is of the form 7b16fd41-cc23-4ef7-8aa9-c598350ccd18.\n\n"+
50-
"Error: "+err.Error(),
51-
),
52-
}
53-
}
54-
55-
return UUID{
56-
state: attr.ValueStateKnown,
57-
value: validUUID,
58-
}, nil
59-
}
60-
61-
// UUIDFromGoogleUUID expects a valid google/uuid.UUID and returns a Terraform
62-
// UUID Value.
63-
func UUIDFromGoogleUUID(value uuid.UUID) UUID {
64-
return UUID{
65-
state: attr.ValueStateKnown,
66-
value: value,
67-
}
68-
}
69-
70-
// UUID provides a concrete implementation of a UUID tftypes.Value for the
71-
// Terraform Plugin framework.
72-
type UUID struct {
73-
state attr.ValueState
74-
value uuid.UUID
75-
}
76-
77-
// Type returns the UUID type that created the UUID.
78-
func (u UUID) Type(_ context.Context) attr.Type {
79-
return UUIDType{}
80-
}
81-
82-
// ToTerraformValue returns the UUID as a tftypes.Value.
83-
func (u UUID) ToTerraformValue(_ context.Context) (tftypes.Value, error) {
84-
if u.IsNull() {
85-
return tftypes.NewValue(tftypes.String, nil), nil
86-
}
87-
88-
if u.IsUnknown() {
89-
return tftypes.NewValue(tftypes.String, tftypes.UnknownValue), nil
90-
}
16+
type UUID = UUIDValue
9117

92-
return tftypes.NewValue(tftypes.String, u.value.String()), nil
18+
// NewUUIDNull creates a UUID with a null value. Determine whether the value is
19+
// null via the UUID type IsNull method.
20+
func NewUUIDNull() UUIDValue {
21+
return UUIDValue{StringValue: basetypes.NewStringNull()}
9322
}
9423

95-
// IsNull returns true if the uuid represents a null value.
96-
func (u UUID) IsNull() bool {
97-
return u.state == attr.ValueStateNull
24+
// NewUUIDUnknown creartes a UUID with an unknown UUID value. Determine whether
25+
// the value is unknown via the UUID type IsUnknown method.
26+
func NewUUIDUnknown() UUIDValue {
27+
return UUIDValue{StringValue: basetypes.NewStringUnknown()}
9828
}
9929

100-
// IsUnknown returns true if the uuid represents an unknown value.
101-
func (u UUID) IsUnknown() bool {
102-
return u.state == attr.ValueStateUnknown
103-
}
104-
105-
// Equal returns true if the uuid is semantically equal to the Value passed as
106-
// an argument.
107-
func (u UUID) Equal(other attr.Value) bool {
108-
otherValue, ok := other.(UUID)
109-
if !ok {
110-
return false
111-
}
112-
113-
if otherValue.state != u.state {
114-
return false
30+
// NewUUIDValue creates a UUID with a known value. Access the value via the
31+
// String type ValueString method.
32+
func NewUUIDValue(value string) UUIDValue {
33+
return UUIDValue{
34+
StringValue: basetypes.NewStringValue(value),
11535
}
116-
117-
// perform a byte-for-byte comparison.
118-
return otherValue.value == u.value
11936
}
12037

121-
// String returns a summary representation of either the underlying Value,
122-
// or UnknownValueString (`<unknown>`) when IsUnknown() returns true,
123-
// or NullValueString (`<null>`) when IsNull() return true.
124-
func (u UUID) String() string {
125-
switch u.state {
126-
case attr.ValueStateNull:
127-
return attr.NullValueString
128-
129-
case attr.ValueStateUnknown:
130-
return attr.UnknownValueString
131-
132-
default:
133-
return u.value.String()
38+
// NewUUIDPointerValue creates a UUID with a null value if nil or a known
39+
// value. Access the value via the String type ValueStringPointer method.
40+
func NewUUIDPointerValue(value *string) UUIDValue {
41+
return UUIDValue{
42+
StringValue: basetypes.NewStringPointerValue(value),
13443
}
13544
}

0 commit comments

Comments
 (0)