Skip to content

Commit 6ab68c8

Browse files
committed
Adding json-schema validation for extra-specs
1 parent b915449 commit 6ab68c8

33 files changed

Lines changed: 6565 additions & 1 deletion

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Garm supports sending opaque json encoded configs to the IaaS providers it hooks
3232
To this end, this provider supports the following extra specs schema:
3333

3434
```json
35+
3536
{
3637
"$schema": "http://cloudbase.it/garm-provider-openstack/schemas/extra_specs#",
3738
"type": "object",
@@ -74,7 +75,8 @@ To this end, this provider supports the following extra specs schema:
7475
},
7576
"description": "A list of image owners to allow when creating the instance. If not specified, all images will be allowed."
7677
}
77-
}
78+
},
79+
"additionalProperties": false
7880
}
7981
```
8082

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ require (
2222
github.com/pkg/errors v0.9.1 // indirect
2323
github.com/pmezard/go-difflib v1.0.0 // indirect
2424
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 // indirect
25+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
26+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
27+
github.com/xeipuuv/gojsonschema v1.2.0
2528
golang.org/x/crypto v0.12.0 // indirect
2629
golang.org/x/sys v0.11.0 // indirect
2730
golang.org/x/text v0.12.0 // indirect

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak
22
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
33
github.com/cloudbase/garm-provider-common v0.1.1 h1:9SbkEevpycI/P3J7jEmjJf6VzdrxAIHkLppnjqaKAWU=
44
github.com/cloudbase/garm-provider-common v0.1.1/go.mod h1:igxJRT3OlykERYc6ssdRQXcb+BCaeSfnucg6I0OSoDc=
5+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
56
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
67
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
78
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@@ -26,10 +27,18 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
2627
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
2728
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2829
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
30+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
31+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
2932
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
3033
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
3134
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI=
3235
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI=
36+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
37+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
38+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
39+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
40+
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
41+
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
3342
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
3443
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
3544
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=

provider/spec.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,61 @@ import (
2626
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
2727
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
2828
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
29+
"github.com/xeipuuv/gojsonschema"
2930

3031
"github.com/cloudbase/garm-provider-openstack/config"
3132
)
3233

3334
var defaultBootDiskSize int64 = 50
3435

36+
const jsonSchema string = `
37+
{
38+
"$schema": "http://cloudbase.it/garm-provider-openstack/schemas/extra_specs#",
39+
"type": "object",
40+
"description": "Schema defining supported extra specs for the Garm OpenStack Provider",
41+
"properties": {
42+
"security_groups": {
43+
"type": "array",
44+
"items": {
45+
"type": "string"
46+
}
47+
},
48+
"network_id": {
49+
"type": "string",
50+
"description": "The tenant network to which runners will be connected to."
51+
},
52+
"storage_backend": {
53+
"type": "string",
54+
"description": "The cinder backend to use when creating volumes."
55+
},
56+
"boot_from_volume": {
57+
"type": "boolean",
58+
"description": "Whether to boot from volume or not. Use this option if the root disk size defined by the flavor is not enough."
59+
},
60+
"boot_disk_size": {
61+
"type": "integer",
62+
"description": "The size of the root disk in GB. Default is 50 GB."
63+
},
64+
"use_config_drive": {
65+
"type": "boolean",
66+
"description": "Use config drive."
67+
},
68+
"enable_boot_debug": {
69+
"type": "boolean",
70+
"description": "Enable cloud-init debug mode. Adds 'set -x' into the cloud-init script."
71+
},
72+
"allow_image_owners": {
73+
"type": "array",
74+
"items": {
75+
"type": "string"
76+
},
77+
"description": "A list of image owners to allow when creating the instance. If not specified, all images will be allowed."
78+
}
79+
},
80+
"additionalProperties": false
81+
}
82+
`
83+
3584
type extraSpecs struct {
3685
SecurityGroups []string `json:"security_groups,omitempty"`
3786
AllowedImageOwners []string `json:"allowed_image_owners,omitempty"`
@@ -44,12 +93,28 @@ type extraSpecs struct {
4493
EnableBootDebug *bool `json:"enable_boot_debug"`
4594
}
4695

96+
func jsonSchemaValidation(schema json.RawMessage) error {
97+
schemaLoader := gojsonschema.NewStringLoader(jsonSchema)
98+
extraSpecsLoader := gojsonschema.NewBytesLoader(schema)
99+
result, err := gojsonschema.Validate(schemaLoader, extraSpecsLoader)
100+
if err != nil {
101+
return fmt.Errorf("failed to validate schema: %w", err)
102+
}
103+
if !result.Valid() {
104+
return fmt.Errorf("schema validation failed: %s", result.Errors())
105+
}
106+
return nil
107+
}
108+
47109
func extraSpecsFromBootstrapData(data params.BootstrapInstance) (extraSpecs, error) {
48110
if len(data.ExtraSpecs) == 0 {
49111
return extraSpecs{}, nil
50112
}
51113

52114
var spec extraSpecs
115+
if err := jsonSchemaValidation(data.ExtraSpecs); err != nil {
116+
return extraSpecs{}, fmt.Errorf("failed to validate extra specs: %w", err)
117+
}
53118
if err := json.Unmarshal(data.ExtraSpecs, &spec); err != nil {
54119
return extraSpecs{}, fmt.Errorf("failed to unmarshal extra_specs: %w", err)
55120
}

vendor/github.com/xeipuuv/gojsonpointer/LICENSE-APACHE-2.0.txt

Lines changed: 202 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/xeipuuv/gojsonpointer/README.md

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)