Skip to content
This repository has been archived by the owner on Jun 16, 2021. It is now read-only.

Commit

Permalink
Validation for v2 services
Browse files Browse the repository at this point in the history
Signed-off-by: Josh Curl <[email protected]>
  • Loading branch information
joshwget committed Aug 31, 2016
1 parent c7c4bb7 commit 5295494
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 103 deletions.
12 changes: 12 additions & 0 deletions config/merge_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ func MergeServicesV2(existingServices *ServiceConfigs, environmentLookup Environ
}
}

if options.Validate {
if err := validateV2(datas); err != nil {
return nil, err
}
}

for name, data := range datas {
data, err := parseV2(resourceLookup, environmentLookup, file, data, datas, options)
if err != nil {
Expand Down Expand Up @@ -155,6 +161,12 @@ func parseV2(resourceLookup ResourceLookup, environmentLookup EnvironmentLookup,
}
}

if options.Validate {
if err := validate(baseRawServices); err != nil {
return nil, err
}
}

baseService, ok = baseRawServices[service]
if !ok {
return nil, fmt.Errorf("Failed to find service %s in file %s", service, file)
Expand Down
51 changes: 11 additions & 40 deletions config/schema.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package config

var schemaV1 = `{
var schemaDataV1 = `{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v1.json",
Expand Down Expand Up @@ -87,6 +87,7 @@ var schemaV1 = `{
"mac_address": {"type": "string"},
"mem_limit": {"type": ["number", "string"]},
"memswap_limit": {"type": ["number", "string"]},
"mem_swappiness": {"type": "integer"},
"net": {"type": "string"},
"pid": {"type": ["string", "null"]},
Expand Down Expand Up @@ -189,46 +190,14 @@ var schemaV1 = `{
}
`

var schemaV2 = `{
var servicesSchemaDataV2 = `{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v2.0.json",
"type": "object",
"properties": {
"version": {
"type": "string"
},
"services": {
"id": "#/properties/services",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/service"
}
},
"additionalProperties": false
},
"networks": {
"id": "#/properties/networks",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/network"
}
}
},
"volumes": {
"id": "#/properties/volumes",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/volume"
}
},
"additionalProperties": false
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/service"
}
},
Expand Down Expand Up @@ -330,6 +299,7 @@ var schemaV2 = `{
"mac_address": {"type": "string"},
"mem_limit": {"type": ["number", "string"]},
"memswap_limit": {"type": ["number", "string"]},
"mem_swappiness": {"type": "integer"},
"network_mode": {"type": "string"},
"networks": {
Expand Down Expand Up @@ -357,6 +327,7 @@ var schemaV2 = `{
}
]
},
"oom_score_adj": {"type": "integer", "minimum": -1000, "maximum": 1000},
"pid": {"type": ["string", "null"]},
"ports": {
Expand Down Expand Up @@ -436,7 +407,8 @@ var schemaV2 = `{
"name": {"type": "string"}
},
"additionalProperties": false
}
},
"internal": {"type": "boolean"}
},
"additionalProperties": false
},
Expand All @@ -457,8 +429,7 @@ var schemaV2 = `{
"properties": {
"name": {"type": "string"}
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
Expand Down
23 changes: 13 additions & 10 deletions config/schema_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import (
)

var (
schemaLoader gojsonschema.JSONLoader
constraintSchemaLoader gojsonschema.JSONLoader
schema map[string]interface{}
schemaLoaderV1 gojsonschema.JSONLoader
constraintSchemaLoaderV1 gojsonschema.JSONLoader
schemaLoaderV2 gojsonschema.JSONLoader
constraintSchemaLoaderV2 gojsonschema.JSONLoader
schemaV1 map[string]interface{}
schemaV2 map[string]interface{}
)

type (
Expand All @@ -31,28 +34,28 @@ func (checker portsFormatChecker) IsFormat(input string) bool {
return err == nil
}

func setupSchemaLoaders() error {
if schema != nil {
func setupSchemaLoaders(schemaData string, schema *map[string]interface{}, schemaLoader, constraintSchemaLoader *gojsonschema.JSONLoader) error {
if *schema != nil {
return nil
}

var schemaRaw interface{}
err := json.Unmarshal([]byte(schemaV1), &schemaRaw)
err := json.Unmarshal([]byte(schemaData), &schemaRaw)
if err != nil {
return err
}

schema = schemaRaw.(map[string]interface{})
*schema = schemaRaw.(map[string]interface{})

gojsonschema.FormatCheckers.Add("environment", environmentFormatChecker{})
gojsonschema.FormatCheckers.Add("ports", portsFormatChecker{})
gojsonschema.FormatCheckers.Add("expose", portsFormatChecker{})
schemaLoader = gojsonschema.NewGoLoader(schemaRaw)
*schemaLoader = gojsonschema.NewGoLoader(schemaRaw)

definitions := schema["definitions"].(map[string]interface{})
definitions := (*schema)["definitions"].(map[string]interface{})
constraints := definitions["constraints"].(map[string]interface{})
service := constraints["service"].(map[string]interface{})
constraintSchemaLoader = gojsonschema.NewGoLoader(service)
*constraintSchemaLoader = gojsonschema.NewGoLoader(service)

return nil
}
Expand Down
23 changes: 13 additions & 10 deletions config/testdata/build.v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ services:
simple1:
build: .
simple2:
context: ./dir
build:
context: ./dir
simple3:
context: ./another
dockerfile: alternate
args:
buildno: 1
user: vincent
build:
context: ./another
dockerfile: alternate
args:
buildno: 1
user: vincent
simple4:
context: ./another
args:
buildno: 2
user: josh
build:
context: ./another
args:
buildno: 2
user: josh
31 changes: 26 additions & 5 deletions config/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,21 +189,42 @@ func invalidTypeMessage(service, key string, err gojsonschema.ResultError) strin
}

func validate(serviceMap RawServiceMap) error {
if err := setupSchemaLoaders(); err != nil {
if err := setupSchemaLoaders(schemaDataV1, &schemaV1, &schemaLoaderV1, &constraintSchemaLoaderV1); err != nil {
return err
}

serviceMap = convertServiceMapKeysToStrings(serviceMap)

var validationErrors []string
dataLoader := gojsonschema.NewGoLoader(serviceMap)

result, err := gojsonschema.Validate(schemaLoaderV1, dataLoader)
if err != nil {
return err
}

return generateErrorMessages(serviceMap, schemaV1, result)
}

func validateV2(serviceMap RawServiceMap) error {
if err := setupSchemaLoaders(servicesSchemaDataV2, &schemaV2, &schemaLoaderV2, &constraintSchemaLoaderV2); err != nil {
return err
}

serviceMap = convertServiceMapKeysToStrings(serviceMap)

dataLoader := gojsonschema.NewGoLoader(serviceMap)

result, err := gojsonschema.Validate(schemaLoader, dataLoader)
result, err := gojsonschema.Validate(schemaLoaderV2, dataLoader)
if err != nil {
return err
}

return generateErrorMessages(serviceMap, schemaV2, result)
}

func generateErrorMessages(serviceMap RawServiceMap, schema map[string]interface{}, result *gojsonschema.Result) error {
var validationErrors []string

// gojsonschema can create extraneous "additional_property_not_allowed" errors in some cases
// If this is set, and the error is at root level, skip over that error
skipRootAdditionalPropertyError := false
Expand Down Expand Up @@ -261,7 +282,7 @@ func validate(serviceMap RawServiceMap) error {
}

func validateServiceConstraints(service RawService, serviceName string) error {
if err := setupSchemaLoaders(); err != nil {
if err := setupSchemaLoaders(schemaDataV1, &schemaV1, &schemaLoaderV1, &constraintSchemaLoaderV1); err != nil {
return err
}

Expand All @@ -271,7 +292,7 @@ func validateServiceConstraints(service RawService, serviceName string) error {

dataLoader := gojsonschema.NewGoLoader(service)

result, err := gojsonschema.Validate(constraintSchemaLoader, dataLoader)
result, err := gojsonschema.Validate(constraintSchemaLoaderV1, dataLoader)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 5295494

Please sign in to comment.