Skip to content

Commit

Permalink
Fix: Self referencial fields are not possible on squidex fields (#14)
Browse files Browse the repository at this point in the history
* - Add commented code to be used for debug purpose
- Added IsSelfReference field to squidex dto for initial creation
- Added check for fields that enabled the self_reference option
- Updates the field with current schema id to fix the self reference
- Update required version of terraform to 1.1.1
- Replaced niksa with admin user in test setup
- Added self-reference scenario in test setup

* - Added func updateSelfReferences

Co-authored-by: Ritseart Oord <ritseart.oord@embracecloud.nl>
  • Loading branch information
TheGoldenDragon and Ritseart Oord authored Feb 14, 2022
1 parent 47fcfff commit 2776579
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 8 deletions.
21 changes: 17 additions & 4 deletions examples/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ terraform {
}
}

required_version = "~> 0.14"
required_version = "~> 1.1.1"
}
provider "squidex" {
client_id = var.client_id
Expand Down Expand Up @@ -58,9 +58,9 @@ resource "squidex_contributor" "test" {
role = squidex_role.test.name
}

resource "squidex_contributor" "niksa_owner" {
resource "squidex_contributor" "admin_owner" {
app_name = squidex_app.test.name
contributor_email = "niksa.sporin@embracecloud.nl"
contributor_email = "admin@embracecloud.nl"
role = "Owner"
}

Expand Down Expand Up @@ -110,6 +110,19 @@ resource "squidex_schema" "test" {
change = "value"
}

fields {
name = "self-reference-field"
partitioning = "invariant"
self_reference = true
hidden = false #
locked = false # should not be used
disabled = false # should not be used
properties {
field_type = "References"
editor = "List"
}
}

fields {
name = "reference-1"
partitioning = "language"
Expand Down Expand Up @@ -248,7 +261,7 @@ resource "squidex_schema" "test" {
}

fields {
name = "bug"
name = "bug"
properties {
field_type = "DateTime"
editor = "DateTime"
Expand Down
15 changes: 13 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@ func main() {
log.SetOutput(os.Stderr)
log.Printf("[TRACE] Running version %s!", meta.SDKVersionString())

plugin.Serve(&plugin.ServeOpts{
opts := &plugin.ServeOpts{
ProviderFunc: squidex.Provider,
})
}

/// Uncomment to debug the plugin
// if true {
// err := plugin.Debug(context.Background(), "terraform.embracecloud.nl/embracecloud/squidex", opts)
// if err != nil {
// log.Fatal(err.Error())
// }
// return
// }

plugin.Serve(opts)
}
2 changes: 2 additions & 0 deletions squidex/internal/squidexclient/model_field_dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type FieldDto struct {
IsLocked bool `json:"isLocked,omitempty"`
// Defines if the field is disabled.
IsDisabled bool `json:"isDisabled,omitempty"`
// Defines if the field is self referencial
IsSelfReference bool `json:"isSelfReference,omitempty"`
// Defines the partitioning of the field.
Partitioning string `json:"partitioning"`
// The field properties.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type UpsertSchemaFieldDto struct {
IsLocked bool `json:"isLocked,omitempty"`
// Defines if the field is disabled.
IsDisabled bool `json:"isDisabled,omitempty"`
// Defines if the field is disabled.
IsSelfReference bool `json:"isSelfReference,omitempty"`
// Determines the optional partitioning of the field.
Partitioning *string `json:"partitioning,omitempty"`
// The field properties.
Expand Down
49 changes: 47 additions & 2 deletions squidex/resource_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,12 @@ func resourceSchema() *schema.Resource {
Default: false,
Description: "Disable field in the UI.",
},
"self_reference": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Enable self-reference field.",
},
"partitioning": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -643,6 +649,7 @@ func setDataFromSchemaDetailsDto(data *schema.ResourceData, schema squidexclient
fields[i]["locked"] = &v.IsLocked
fields[i]["disabled"] = &v.IsDisabled
fields[i]["partitioning"] = v.Partitioning
fields[i]["self_reference"] = &v.IsSelfReference

if (squidexclient.FieldPropertiesDto{}) == v.Properties {
fields[i]["properties"] = nil
Expand Down Expand Up @@ -900,6 +907,9 @@ func getCreateSchemaDtoFromData(data *schema.ResourceData) (squidexclient.Create
if field["disabled"] != nil {
squidexfields[i].IsDisabled = field["disabled"].(bool)
}
if field["self_reference"] != nil {
squidexfields[i].IsSelfReference = field["self_reference"].(bool)
}
if field["properties"] != nil {
properties := field["properties"].([]interface{})
if len(properties) == 1 {
Expand Down Expand Up @@ -1392,8 +1402,9 @@ func resourceSchemaCreate(ctx context.Context, data *schema.ResourceData, meta i
var diags diag.Diagnostics

appName := data.Get("app_name").(string)

name := data.Get("name").(string)
createDto, err := getCreateSchemaDtoFromData(data)

if err != nil {
return diag.FromErr(err)
}
Expand All @@ -1410,6 +1421,8 @@ func resourceSchemaCreate(ctx context.Context, data *schema.ResourceData, meta i
return diag.FromErr(err)
}

updateSelfReferences(ctx, *client, appName, name, createDto, result)

// prevent drift and set ALL values from the result
err = setDataFromSchemaDetailsDto(data, result)
if err != nil {
Expand Down Expand Up @@ -1476,14 +1489,15 @@ func resourceSchemaUpdate(ctx context.Context, data *schema.ResourceData, meta i
schemaFieldRecreateAllowed)

result, response, err := client.SchemasApi.SchemasPutSchemaSync(ctx, appName, name, syncDto)

err = common.HandleAPIError(response, err)

if err != nil {
data.Set("invalidated_state", true)
return diag.FromErr(err)
}

updateSelfReferences(ctx, *client, appName, name, createDto, result)

// TODO: test nofieldeletion & nofieldrecreation in state
// if input fields != output fields (name/type & determine what causes recreation of fields?)
// then invalidate state with data.Set("invalidated_state", true)
Expand Down Expand Up @@ -1554,3 +1568,34 @@ func resourceSchemaDelete(ctx context.Context, data *schema.ResourceData, meta i
data.Set("invalidated_state", false)
return diags
}

// Updates the fields in the created schema for self reference fields if this is specified with the IsSelfReference field.
func updateSelfReferences(ctx context.Context, client squidexclient.APIClient, appName string, schemaName string, createDto squidexclient.CreateSchemaDto, result squidexclient.SchemaDetailsDto) diag.Diagnostics {

var diags diag.Diagnostics

for _, field := range *createDto.Fields {
if field.IsSelfReference {
for _, resultField := range result.Fields {
if resultField.Name == field.Name {
// create dto
dto := field.Properties
dto.SchemaIds = &[]string{result.Id}

// update field
updateFieldDto := squidexclient.UpdateFieldDto{Properties: dto}
updateFieldDtoJson, _ := json.MarshalIndent(updateFieldDto, "", " ")
log.Printf("[TRACE] Creating a new schema, updating self-reference field with dto %s.", string(updateFieldDtoJson))
_, _, fieldErr := client.SchemasApi.SchemaFieldsPutField(ctx, appName, schemaName, resultField.FieldId, updateFieldDto)

if fieldErr != nil {
// TODO: handle errors
return diag.FromErr(fieldErr)
}
// update for drift:
}
}
}
}
return diags
}

0 comments on commit 2776579

Please sign in to comment.