Skip to content

Commit

Permalink
Allow setting the default value of nullable
Browse files Browse the repository at this point in the history
.. to true. This is to make the schema more scrictly align with what Terraform actually permits when `nullable` is not set in a variable definition. See the updated README for details.
  • Loading branch information
AislingHPE committed Aug 27, 2024
1 parent 8f3d776 commit 044ec8b
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 3 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ running Terraform.
- `--disallow-additional-properties`: Set additionalProperties to false in the root object and nested objects
(see [JSON Schema definition](https://json-schema.org/understanding-json-schema/reference/object#additionalproperties)).

- `--nullable-all`: Change the default value for `nullable` in a Variable block to 'true'. This is to make the behaviour more closely reflect Terraform's own validation. See 'Nullable Variables' below.

- `--overwrite`: Allow overwriting an existing file at the output location.

- `--debug`: Print debug logs for variable retrieval and errors related to custom validation rules.
Expand Down Expand Up @@ -295,7 +297,10 @@ If `nullable` is true in the `variable` block, then the JSON Schema will be modi
},
```

This is actually a slight behaviour change from the validator used by terraform. If `nullable` is unset, then terraform treats them as `nullable` by default. I chose not to implement that behaviour here and instead am making the Terraform module author specify `nullable = true`. This is because otherwise schema definitions for simple programs would have to become a lot more verbose just to handle this case.
This is actually a slight behaviour change from the validator used by terraform. If `nullable` is unset, then terraform treats them as `nullable` by default. I chose not to implement that default behaviour here and instead am making the Terraform module author specify `nullable = true`. This is because otherwise schema definitions for simple programs would have to become a lot more verbose just to handle this case.

For behaviour more consistent with Terraform, the flag `--nullable-all` can be used to reset the default value for nullable to be true. Note: this rule only applies to variables which have not explicitly set the value of nullable themselves. See [Terraform documentation on nullable](https://developer.hashicorp.com/terraform/language/values/variables#disallowing-null-input-values
).

### Default Handling

Expand Down
6 changes: 6 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var (
allowEmpty bool
requireAll bool
outputStdOut bool
nullableAll bool
inputPath string
outputPath string
)
Expand Down Expand Up @@ -81,6 +82,10 @@ func init() {
"unless an error occurs. Overrides 'debug' and 'output.",
)

rootCmd.Flags().BoolVar(&nullableAll, "nullable-all", false,
"make all variables nullable unless nullable set to false explicitly, to make behavior consistent with Terraform",
)

rootCmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error {
_ = rootCmd.Usage()

Expand Down Expand Up @@ -151,6 +156,7 @@ func runCommand(cmd *cobra.Command, args []string) error {
RequireAll: requireAll,
AllowAdditionalProperties: !disallowAdditionalProperties,
AllowEmpty: allowEmpty,
NullableAll: nullableAll,
})
if err != nil {
return fmt.Errorf("error creating schema: %w", err)
Expand Down
11 changes: 9 additions & 2 deletions pkg/jsonschema/json-schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type CreateSchemaOptions struct {
RequireAll bool
AllowAdditionalProperties bool
AllowEmpty bool
NullableAll bool
}

func CreateSchema(path string, options CreateSchemaOptions) (map[string]any, error) {
Expand Down Expand Up @@ -75,8 +76,14 @@ func createNode(name string, v model.TranslatedVariable, options CreateSchemaOpt
return nil, fmt.Errorf("getting type constraint for %q: %w", name, err)
}

nullableIsTrue := v.Variable.Nullable != nil && *v.Variable.Nullable
node, err := getNodeFromType(name, tc, nullableIsTrue, options)
// The default value for nullable is the value of NullableAll. For the purpose of keeping the JSON Schema relatively
// clean, this is normally set to false. Setting the default value to true is consistent with Terraform behavior.
nullableTranslatedValue := options.NullableAll
if v.Variable.Nullable != nil {
nullableTranslatedValue = *v.Variable.Nullable
}

node, err := getNodeFromType(name, tc, nullableTranslatedValue, options)
if err != nil {
return nil, fmt.Errorf("%q: %w", name, err)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/jsonschema/json-schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func TestCreateSchema(t *testing.T) {
RequireAll: false,
AllowAdditionalProperties: true,
AllowEmpty: true,
NullableAll: false,
})
require.NoError(t, err)

Expand Down

0 comments on commit 044ec8b

Please sign in to comment.