github.com/bdwilliams/libcompose@v0.3.1-0.20160826154243-d81a9bdacff0/config/schema_helpers.go (about) 1 package config 2 3 import ( 4 "encoding/json" 5 "strings" 6 7 "github.com/docker/go-connections/nat" 8 "github.com/xeipuuv/gojsonschema" 9 ) 10 11 var ( 12 schemaLoader gojsonschema.JSONLoader 13 constraintSchemaLoader gojsonschema.JSONLoader 14 schema map[string]interface{} 15 ) 16 17 type ( 18 environmentFormatChecker struct{} 19 portsFormatChecker struct{} 20 ) 21 22 func (checker environmentFormatChecker) IsFormat(input string) bool { 23 // If the value is a boolean, a warning should be given 24 // However, we can't determine type since gojsonschema converts the value to a string 25 // Adding a function with an interface{} parameter to gojsonschema is probably the best way to handle this 26 return true 27 } 28 29 func (checker portsFormatChecker) IsFormat(input string) bool { 30 _, _, err := nat.ParsePortSpecs([]string{input}) 31 return err == nil 32 } 33 34 func setupSchemaLoaders() error { 35 if schema != nil { 36 return nil 37 } 38 39 var schemaRaw interface{} 40 err := json.Unmarshal([]byte(schemaV1), &schemaRaw) 41 if err != nil { 42 return err 43 } 44 45 schema = schemaRaw.(map[string]interface{}) 46 47 gojsonschema.FormatCheckers.Add("environment", environmentFormatChecker{}) 48 gojsonschema.FormatCheckers.Add("ports", portsFormatChecker{}) 49 gojsonschema.FormatCheckers.Add("expose", portsFormatChecker{}) 50 schemaLoader = gojsonschema.NewGoLoader(schemaRaw) 51 52 definitions := schema["definitions"].(map[string]interface{}) 53 constraints := definitions["constraints"].(map[string]interface{}) 54 service := constraints["service"].(map[string]interface{}) 55 constraintSchemaLoader = gojsonschema.NewGoLoader(service) 56 57 return nil 58 } 59 60 // gojsonschema doesn't provide a list of valid types for a property 61 // This parses the schema manually to find all valid types 62 func parseValidTypesFromSchema(schema map[string]interface{}, context string) []string { 63 contextSplit := strings.Split(context, ".") 64 key := contextSplit[len(contextSplit)-1] 65 66 definitions := schema["definitions"].(map[string]interface{}) 67 service := definitions["service"].(map[string]interface{}) 68 properties := service["properties"].(map[string]interface{}) 69 property := properties[key].(map[string]interface{}) 70 71 var validTypes []string 72 73 if val, ok := property["oneOf"]; ok { 74 validConditions := val.([]interface{}) 75 76 for _, validCondition := range validConditions { 77 condition := validCondition.(map[string]interface{}) 78 validTypes = append(validTypes, condition["type"].(string)) 79 } 80 } else if val, ok := property["$ref"]; ok { 81 reference := val.(string) 82 if reference == "#/definitions/string_or_list" { 83 return []string{"string", "array"} 84 } else if reference == "#/definitions/list_of_strings" { 85 return []string{"array"} 86 } else if reference == "#/definitions/list_or_dict" { 87 return []string{"array", "object"} 88 } 89 } 90 91 return validTypes 92 }