// ValidateParams tells us whether an unmarshaled JSON object conforms to the // Params for the specific ActionSpec. // Usage: ok, err := ch.Actions()["snapshot"].Validate(jsonParams) func (spec *ActionSpec) ValidateParams(params interface{}) (bool, error) { specSchemaDoc, err := gojsonschema.NewJsonSchemaDocument(spec.Params) if err != nil { return false, err } results := specSchemaDoc.Validate(params) if results.Valid() { return true, nil } var errorStrings []string for _, validationError := range results.Errors() { errorStrings = append(errorStrings, validationError.String()) } return false, fmt.Errorf("JSON validation failed: %s", strings.Join(errorStrings, "; ")) }
// ReadActions builds an Actions spec from a charm's actions.yaml. func ReadActionsYaml(r io.Reader) (*Actions, error) { data, err := ioutil.ReadAll(r) if err != nil { return nil, err } var unmarshaledActions Actions if err := goyaml.Unmarshal(data, &unmarshaledActions); err != nil { return nil, err } for name, actionSpec := range unmarshaledActions.ActionSpecs { if valid := actionNameRule.MatchString(name); !valid { return nil, fmt.Errorf("bad action name %s", name) } // Clean any map[interface{}]interface{}s out so they don't // cause problems with BSON serialization later. cleansedParams, err := cleanse(actionSpec.Params) if err != nil { return nil, err } // JSON-Schema must be a map cleansedParamsMap, ok := cleansedParams.(map[string]interface{}) if !ok { return nil, fmt.Errorf("the params failed to parse as a map") } // Now substitute the cleansed map into the original. var tempSpec = unmarshaledActions.ActionSpecs[name] tempSpec.Params = cleansedParamsMap unmarshaledActions.ActionSpecs[name] = tempSpec // Make sure the new Params doc conforms to JSON-Schema // Draft 4 (http://json-schema.org/latest/json-schema-core.html) _, err = gojsonschema.NewJsonSchemaDocument(unmarshaledActions.ActionSpecs[name].Params) if err != nil { return nil, fmt.Errorf("invalid params schema for action schema %s: %v", name, err) } } return &unmarshaledActions, nil }