Skip to content
Closed
Changes from 2 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
64bbe8c
Add RFC for basic schema requirements in cluster apps
marians Nov 25, 2022
c2bba6a
Add TOC
marians Dec 1, 2022
7284043
Maintain uppercase MUST
marians Dec 8, 2022
6c9dc6a
Cahnge "below" to "above"
marians Dec 8, 2022
679a970
Change "brakes" to "breaks"
marians Dec 8, 2022
3a1eedb
Mention enum to list valid values
marians Dec 8, 2022
636a28a
Extended R8 on required properties
marians Dec 8, 2022
736151f
Replace payload with instance
marians Dec 8, 2022
9c6e189
Update TODO list
marians Dec 8, 2022
f4e634a
Add requirement regarding anyOf/oneOf
marians Dec 12, 2022
afe2672
Add link to R9
marians Jan 10, 2023
296d9cd
Add R10 on how to use deprecated=true
marians Jan 10, 2023
25e0fa1
Clarify description requirements
marians Jan 10, 2023
314d99e
Remove line on patternProperties
marians Jan 10, 2023
57af1a0
Fix exclusiveMaximum -> exclusiveMinimum
marians Jan 10, 2023
c0b6eff
Require draft 2020-12
marians Jan 10, 2023
02fe1e1
Add TODO
marians Jan 11, 2023
3073423
Update and improve requirements regarding title (R4)
marians Jan 16, 2023
ac661ee
Update description requirements (R5)
marians Jan 16, 2023
9ce8eed
Fix: example -> examples
marians Jan 16, 2023
bdd7107
Add R11 on providing distinct string values
marians Jan 17, 2023
6dc44d8
Update requirement regarding type
marians Jan 19, 2023
70c15b4
Add details to title requirements
marians Jan 19, 2023
e906823
Add details to description requirements
marians Jan 19, 2023
1bb5ae9
Require draft 2019-09 instead of 202-12
marians Jan 30, 2023
a075697
Add TODO items
marians Feb 3, 2023
0d6ba39
Clarify examples requirements
marians Feb 3, 2023
83f0c87
Clarify requirements for string and numeric field restrictions
marians Feb 3, 2023
9630507
Add type requirements
marians Feb 5, 2023
4720417
Add requirement to void recursion
marians Feb 5, 2023
2b7e16e
Add requirement to avoid if, then, else
marians Feb 5, 2023
9363c0b
Add requirement to avoid unevaluated properties/items
marians Feb 5, 2023
9d9a8a5
Add requirement to avoid tuple validation
marians Feb 5, 2023
d424fac
Add requirement regarding 'contains'
marians Feb 5, 2023
35031cb
Fix casing
marians Feb 6, 2023
4c0f5ae
Refine R9 (allOf, anyOf)
marians Feb 7, 2023
7163aab
Boolean properties don't need examples
marians Feb 13, 2023
0a3d632
Change draft to 2020-12
marians Feb 13, 2023
a55d389
Update section numbering
marians Feb 13, 2023
c5fdaff
Add R17 on common schema structure
marians Feb 13, 2023
d2a2f35
Rephrase and refine R3
marians Mar 1, 2023
211488e
Extend R17 for compatibility reasons
marians Mar 1, 2023
172a47b
R17: Add /cluster-shared to allowed properties
marians Mar 1, 2023
4b54af0
Fix table headings
marians Mar 2, 2023
10637bc
Update R7 on examples
marians Mar 9, 2023
521379e
Add missing condition to R7
marians Mar 9, 2023
650c139
Fix typos
marians Mar 9, 2023
d345df7
Add R18 for empty defaults
mogottsch Apr 11, 2023
3ee3e0b
Fix r18 heading
mogottsch Apr 11, 2023
6a26e98
Adapt common schema structure requirements to cluster-aws
mogottsch Apr 12, 2023
29e256a
Add recommendations for default values (merge vs. replace)
AndiDog Apr 17, 2023
0f8706d
Add recommendations for node pools
AndiDog Apr 18, 2023
6545e82
Link to gitops-template example of using different environments and m…
AndiDog Apr 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions cluster-app-values-schema/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Basic requirements for cluster app values schema

Cluster apps are apps which are used to configure and provision clusters based on Cluster API in the Giant Swarm platform. Like all helm charts, these apps are configured using so-called values YAML files, which are passed to the app as a ConfigMap for cluster creation. The allowed structure of the values YAML is defined by the app's values schema.

This RFC defines basic requirements for all cluster apps provided by Giant Swarm.

## Overview

- [R1: JSON Schema dialect must be specified](#r1)
- [R2: Schema must explicitly cover all allowed properties](#r2)
- [R3: Array item schema must be defined](#r3)
- [R4: Properties must have a title](#r4)
- [R5: Properties should have descriptions](#r5)
- [R6: Properties should provide examples](#r6)
- [R7: Constrain values as much as possible](#r7)
- [R8: Required properties must be marked as such](#r8)

## Background

TODO: Some more info regarding the rationale.

- In-place documentation of properties
- Better validation to catch configuration errors before they are applied
- Generated entry forms
- Generated information display
- Enabling processes and communication about explicit contracts instead of implicit behaviour

## Definitions

- **Cluster app**: App (as defined by the Giant Swarm app platform) that allows for provisioning a cluster in a Giant Swarm installation.
- **JSON Schema**: declarative language that allows to annotate and validate documents that are compatible with JSON.
- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119.html)

## Requirements

Requirements carry identifiers with prefix `R` and a unique number, for easy referencing.

### R1: JSON Schema dialect must be specified {#r1}

Each cluster app's values schema file MUST specify the schema dialect (also called draft) used via the `$schema` keyword on the top level, with the draft URI as a value.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning and possible values of specific keywords changed over the course of different drafts. Supporting all drafts would increase the complexity of our tooling, e.g. schemalint. I would suggests that we initially only support the newest draft (2020-12) and add support for newer drafts as they are released.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the latest restrictions we discussed (e.g. forbid prefixItems), does it still make sense to require 2019-09? Or can we go back to 2020-12?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if we make sure that we are indifferent to all the changes between 2019-09 and 2020-12.
That would be:

  • forbid prefixItems (2020)
  • forbid additionalItems (2019)
  • forbid items with tuple values (2019)
  • forbid $dynamicRef and $dynamicAnchor (2020)
  • forbid $recursiveRef and $recursiveAnchor (2019)
    As far as I know, we already wanted to forbid all of these. So we could go back to 2020-12.


Example:

```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
...
}
```

The example below shows an excerpt of a JSON Schema which uses draft 2020-12.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add negative examples, or particularly recommendations regarding null?

### R2: Schema must explicitly cover all allowed properties {#r2}

All properties that can be used in values MUST be covered in the schema explicitly.

To enforce this and to disable the use of any undefined properties, the keyword `additionalProperties` SHOULD be set to `false` on all object schemas.

The `patternProperties` keyword MUST NOT be used.

### R3: Array item schema must be defined {#r3}

The items schema for all array properties must be defined using the `items` keyword.

### R4: Properties must have a title {#r4}

Each property MUST be annotated via the `title` keyword.

Example:

```json
{
...
"properties": {
"name": {
"type": "string",
"title": "Cluster name",
...
}
}
}
```

Rationale: These annotations (just like description and examples, see R5 and R6) are mainly useful for users during data entry, but also when reasoning about an cluster configuration.

Best practices:

- Ue sentence case.
- Do not use punctuation.
- Do not repeat the parent title.
- Example: if `.controlPlane` is titled `Control plane`, then `.controlPlane.availabilityZones` should be titled `Availability zones`, not `Control plane availability zones`.

### R5: Properties should have descriptions {#r5}

Each property SHOULD be annotated and via the `description` keyword.

Example:

```json
{
...
"properties": {
"name": {
"type": "string",
"description": "Identifies this cluster uniquely within the installation.",
...
}
}
}
```

Best practices:

- Do not repeat the property name or title in the description.
- Write descriptions between 50 and 200 characters long.
- Use simple language.
- Use no formatting syntax, nor hyperlinks.
- Use no line brakes.
- Use sentence case and punctuation.

### R6: Properties should provide examples {#r6}

Each property SHOULD provide one or more examples using the `example` keyword.

Example:

```json
{
...
"properties": {
"name": {
"type": "string",
"examples": ["devel001"],
...
}
}
}
```

Best practices:

- Ideally, provide one example.
- Provide more than one example if you want to highlight that very different values are accepted.
- Provide no more than five examples

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a MUST/SHOULD rather than a best practice?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will clarify this.


TODO

- We could decide to use the examples for testing purposes, replacing ci-values.yaml and the likes. In that case, we should make it a MUST requirement.

### R7: Constrain values as much as possible {#r7}

Property schema SHOULD explicitly restrict values as much as possible.

There are several ways this requirement can/has to be fulfilled, depending on the property type and the use case.

Properties of type `string`:

- Use of the keywords `minLength` and `maxLength` to specify the valid length.
- If applicable, use the `pattern` keyword to specify a regular expression for validation. This is useful for example to restrict the value to ASCII characters, or to lowercase etc.
- Use the `format` keyword to restrict the property to a common string format, like a URL or an email address. Watch out to use only formats which are available in the JSON schema dialect used (see also R1).

Numeric properties (type `number`, `integer`):

- Restrict the values range using `minimum` or `exclusiveMaximum` and `maximum` or `exclusiveMaximum`.
- Use `multipleOf` if the value must be a multiple of a certain number.

Example:

```json
"diskSizeInGb": {
"type": "integer",
"minimum": 10,
"maximum": 200,
"multipleOf": 10
}
```

### R8: Required properties must be marked as such {#r8}

If a property is required to be set, it MUST be included in the `required` keyword.

In terms of a lifecycle, this means that the property must be defined when submitting the values for validation or for cluster creation.


Copy link

@mogottsch mogottsch Apr 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we forbid empty objects, I suggest adding that to the RFC (related issue).

Suggested change
### R19: Avoid empty objects {#r19}
All objects MUST specify at least one property through at least one of the following keywords: `properties`, `additionalProperties`, `patternProperties`.

## TODO

I haven't gotten to these yet, or I'm not sure about them.

- Each property must declare the `type`. Not sure this is required by JSON schema.

- Use of the `default` keyword. As per JSON Schema documentation, it is for annotation only. It is not meant to automatically fill in missing values for validation.

- How to specify whether a property can be modified or not. `"readOnly": true` mit be the right one for that.

- Use of the `deprecated` keyword to phase out properties. Documentation says: "The deprecated keyword is a boolean that indicates that the instance value the keyword applies to should not be used and may be removed in the future."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about "How to verify/format JSON schema files" (in your editor)

## Resources

- [Understanding JSON Schema](https://json-schema.org/understanding-json-schema/)