// ParseRequestParameter applies parameters of request from body and query. func (c RootController) ParseRequestParameter(p parameters.RequestParameter) error { req := c.GetContext().Request() // Request Body if b := req.Body(); len(b) > 0 { if err := json.Unmarshal(b, p); err != nil { return err } } // Request Query query := map[string]interface{}{} // Modify query into parsable one for k, v := range req.Query() { if strings.HasSuffix(k, "[]") { // e.g.) foo[]=[]string => foo=[]string query[k[:len(k)-2]] = v } else { // e.g.) foo=[]string => foo=string query[k] = v[0] } } mapcfg := &mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: p, } decoder, err := mapstructure.NewDecoder(mapcfg) if err != nil { return err } if err = decoder.Decode(query); err != nil { return err } return nil }
// CreateParamList tries to match a CBOR-RPC parameter list to a specific // callable's parameter list. funcv is the reflected method to eventually // call, and params is the list of parameters from the CBOR-RPC request. // On success, the return value is a list of parameter values that can be // passed to funcv.Call(). func CreateParamList(funcv reflect.Value, params []interface{}) ([]reflect.Value, error) { funct := funcv.Type() numParams := funct.NumIn() if len(params) != numParams { return nil, errors.New("wrong number of parameters") } results := make([]reflect.Value, numParams) for i := 0; i < numParams; i++ { paramType := funct.In(i) paramValue := reflect.New(paramType) param := paramValue.Interface() config := mapstructure.DecoderConfig{ DecodeHook: DecodeBytesAsString, Result: param, } decoder, err := mapstructure.NewDecoder(&config) if err != nil { return nil, err } err = decoder.Decode(params[i]) if err != nil { return nil, err } results[i] = paramValue.Elem() } return results, nil }
func saveConfigRequestUnmarshaler(r *http.Request) (atc.Config, db.PipelinePausedState, error) { var configStructure interface{} pausedState, err := requestToConfig(r.Header.Get("Content-Type"), r.Body, &configStructure) if err != nil { return atc.Config{}, db.PipelineNoChange, err } var config atc.Config var md mapstructure.Metadata msConfig := &mapstructure.DecoderConfig{ Metadata: &md, Result: &config, WeaklyTypedInput: true, DecodeHook: atc.SanitizeDecodeHook, } decoder, err := mapstructure.NewDecoder(msConfig) if err != nil { return atc.Config{}, db.PipelineNoChange, ErrFailedToConstructDecoder } if err := decoder.Decode(configStructure); err != nil { return atc.Config{}, db.PipelineNoChange, ErrCouldNotDecode } if len(md.Unused) != 0 { return atc.Config{}, db.PipelineNoChange, ExtraKeysError{extraKeys: md.Unused} } return config, pausedState, nil }
func (r *ResourceProvisioner) decodeConfig(c *terraform.ResourceConfig) (*Provisioner, error) { // decodes configuration from terraform and builds out a provisioner p := new(Provisioner) decoderConfig := &mapstructure.DecoderConfig{ ErrorUnused: true, WeaklyTypedInput: true, Result: p, } decoder, err := mapstructure.NewDecoder(decoderConfig) if err != nil { return nil, err } // build a map of all configuration values, by default this is going to // pass in all configuration elements for the base configuration as // well as extra values. Build a single value and then from there, continue forth! m := make(map[string]interface{}) for k, v := range c.Raw { m[k] = v } for k, v := range c.Config { m[k] = v } err = decoder.Decode(m) if err != nil { return nil, err } return p, nil }
func parseTokenData(data string, into interface{}) (err error) { m := make(map[string]string) tuples := strings.Split(strings.TrimSpace(data), " ") for _, tuple := range tuples { keyValue := strings.SplitN(tuple, ":", 2) if len(keyValue) != 2 { err = errors.New("Malformed token data") return } m[keyValue[0]] = keyValue[1] } decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ Metadata: nil, Result: into, WeaklyTypedInput: true, }) if err != nil { return } return decoder.Decode(m) }
// Decode from object to data structure using `mapstructure` func Decode(obj ast.Node, excludeKeys []string, defaultValues map[string]interface{}, data interface{}) error { var m map[string]interface{} if err := hcl.DecodeObject(&m, obj); err != nil { return maskAny(err) } for _, key := range excludeKeys { delete(m, key) } for k, v := range defaultValues { if _, ok := m[k]; !ok { m[k] = v } } decoderConfig := &mapstructure.DecoderConfig{ ErrorUnused: true, WeaklyTypedInput: true, Metadata: nil, Result: data, } decoder, err := mapstructure.NewDecoder(decoderConfig) if err != nil { return maskAny(err) } return maskAny(decoder.Decode(m)) }
func parseUpdate(result *structs.UpdateStrategy, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'update' block allowed per job") } // Get our resource object o := list.Items[0] var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } // Check for invalid keys valid := []string{ "stagger", "max_parallel", } if err := checkHCLKeys(o.Val, valid); err != nil { return err } dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, Result: result, }) if err != nil { return err } return dec.Decode(m) }
func parseRestartPolicy(final **structs.RestartPolicy, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'restart' block allowed") } // Get our job object obj := list.Items[0] var m map[string]interface{} if err := hcl.DecodeObject(&m, obj.Val); err != nil { return err } var result structs.RestartPolicy dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, Result: &result, }) if err != nil { return err } if err := dec.Decode(m); err != nil { return err } *final = &result return nil }
// GetSource resolves source from a map. // Source must contain at least one property with name "type", which will be // used to select proper source implementation. func GetSource(rawSource map[string]interface{}) (Source, error) { sourceType, found := configMappings[rawSource["type"].(string)] if !found { return nil, fmt.Errorf("Failed to find source type: %s", rawSource["type"]) } delete(rawSource, "type") var metadata mapstructure.Metadata loader := reflect.New(sourceType).Interface().(Source) decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ Metadata: &metadata, Result: loader, }) if err != nil { return nil, err } if err := decoder.Decode(rawSource); err != nil { return nil, err } if len(metadata.Unused) > 0 { return nil, fmt.Errorf("unknown configuration keys: %v", metadata.Unused) } return loader, nil }
// DecodeConfig reads the configuration from the given reader in JSON // format and decodes it into a proper Config structure. func DecodeConfig(r io.Reader) (*Config, error) { var raw interface{} dec := json.NewDecoder(r) if err := dec.Decode(&raw); err != nil { return nil, err } // Decode var md mapstructure.Metadata var result Config msdec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ Metadata: &md, Result: &result, }) if err != nil { return nil, err } if err := msdec.Decode(raw); err != nil { return nil, err } // If we never set the protocol, then set it to the default if !containsKey(md.Keys, "protocol") { result.Protocol = DefaultConfig.Protocol } return &result, nil }
func NewTimetail(cfg map[string]interface{}) (t parsing.Fetcher, err error) { var ( config TimetailConfig decoder_config = mapstructure.DecoderConfig{ // To allow decoder parses []uint8 as string WeaklyTypedInput: true, Result: &config, } ) decoder, err := mapstructure.NewDecoder(&decoder_config) if err != nil { return nil, err } err = decoder.Decode(cfg) if err != nil { return nil, err } if config.ConnTimeout <= 0 { config.ConnTimeout = CONNECTION_TIMEOUT } if config.ReadTimeout <= 0 { config.ReadTimeout = RW_TIMEOUT } t = &Timetail{ TimetailConfig: config, } return }
// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality func decode(input interface{}, config *mapstructure.DecoderConfig) error { decoder, err := mapstructure.NewDecoder(config) if err != nil { return err } return decoder.Decode(input) }
// Extract interprets any serverResult as a Server, if possible. func (r serverResult) Extract() (*Server, error) { if r.Err != nil { return nil, r.Err } var response struct { Server Server `mapstructure:"server"` } config := &mapstructure.DecoderConfig{ DecodeHook: toMapFromString, Result: &response, } decoder, err := mapstructure.NewDecoder(config) if err != nil { return nil, err } err = decoder.Decode(r.Body) if err != nil { return nil, err } return &response.Server, nil }
// ParseSSHConfig is used to convert the ConnInfo of the ResourceState into // a SSHConfig struct func ParseSSHConfig(s *terraform.ResourceState) (*SSHConfig, error) { sshConf := &SSHConfig{} decConf := &mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: sshConf, } dec, err := mapstructure.NewDecoder(decConf) if err != nil { return nil, err } if err := dec.Decode(s.ConnInfo); err != nil { return nil, err } if sshConf.User == "" { sshConf.User = DefaultUser } if sshConf.Port == 0 { sshConf.Port = DefaultPort } if sshConf.ScriptPath == "" { sshConf.ScriptPath = DefaultScriptPath } if sshConf.Timeout != "" { sshConf.TimeoutVal = safeDuration(sshConf.Timeout, DefaultTimeout) } else { sshConf.TimeoutVal = DefaultTimeout } return sshConf, nil }
// ConvertValue converts input (e.g. a map[string]interface{}) to an instance of inputType. func ConvertValue(inputType reflect.Type, input interface{}, customUnpack bool, baseConfig *DecoderConfig, defaultTagName string) (output reflect.Value, err error) { output = reflect.New(inputType) parameters := output.Interface() if customUnpack { if err := parameters.(Unpacker).Unpack(input); err != nil { return reflect.ValueOf(nil), fmt.Errorf("Failed to convert parameters to type %v: %s", inputType, err) } } else { var config *mapstructure.DecoderConfig if baseConfig != nil { config = &mapstructure.DecoderConfig{ Result: parameters, TagName: baseConfig.TagName, ErrorUnused: baseConfig.ErrorUnused, ZeroFields: baseConfig.ZeroFields, WeaklyTypedInput: baseConfig.WeaklyTypedInput, DecodeHook: baseConfig.DecodeHook, } } else { config = &mapstructure.DecoderConfig{ Metadata: nil, Result: parameters, TagName: defaultTagName, } } decoder, err := mapstructure.NewDecoder(config) if err != nil { return reflect.ValueOf(nil), fmt.Errorf("Failed to construct decoder: %s", err) } if err = decoder.Decode(input); err != nil { return reflect.ValueOf(nil), fmt.Errorf("Failed to convert parameters to type %v: %s", inputType, err) } } return }
// DecodeConfig is a helper that handles decoding raw configuration using // mapstructure. It returns the metadata and any errors that may happen. // If you need extra configuration for mapstructure, you should configure // it manually and not use this helper function. func DecodeConfig(target interface{}, raws ...interface{}) (*mapstructure.Metadata, error) { decodeHook, err := decodeConfigHook(raws) if err != nil { return nil, err } var md mapstructure.Metadata decoderConfig := &mapstructure.DecoderConfig{ DecodeHook: decodeHook, Metadata: &md, Result: target, WeaklyTypedInput: true, } decoder, err := mapstructure.NewDecoder(decoderConfig) if err != nil { return nil, err } for _, raw := range raws { err := decoder.Decode(raw) if err != nil { return nil, err } } return &md, nil }
// Start starts the mock driver func (m *MockDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) { var driverConfig MockDriverConfig dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, Result: &driverConfig, }) if err != nil { return nil, err } if err := dec.Decode(task.Config); err != nil { return nil, err } h := mockDriverHandle{ taskName: task.Name, runFor: driverConfig.RunFor, killAfter: driverConfig.KillAfter, killTimeout: task.KillTimeout, exitCode: driverConfig.ExitCode, exitSignal: driverConfig.ExitSignal, logger: m.logger, doneCh: make(chan struct{}), waitCh: make(chan *dstructs.WaitResult, 1), } if driverConfig.ExitErrMsg != "" { h.exitErr = errors.New(driverConfig.ExitErrMsg) } m.logger.Printf("[DEBUG] driver.mock: starting task %q", task.Name) go h.run() return &h, nil }
func parseChecks(service *structs.Service, checkObjs *ast.ObjectList) error { service.Checks = make([]*structs.ServiceCheck, len(checkObjs.Items)) for idx, co := range checkObjs.Items { var check structs.ServiceCheck var cm map[string]interface{} if err := hcl.DecodeObject(&cm, co.Val); err != nil { return err } dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, Result: &check, }) if err != nil { return err } if err := dec.Decode(cm); err != nil { return err } service.Checks[idx] = &check } return nil }
// NewMapDecoder returns decoder configured for decoding data into result with all registered hooks. func newMapDecoder(result interface{}) (*mapstructure.Decoder, error) { return mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.ComposeDecodeHookFunc(mapDecoderHooks...), Metadata: nil, Result: result, TagName: TagName, }) }
// DecodeConfig reads the configuration from the given reader in JSON // format and decodes it into a proper Config structure. func DecodeConfig(r io.Reader) (*Config, error) { var raw interface{} dec := json.NewDecoder(r) if err := dec.Decode(&raw); err != nil { return nil, err } // Decode var md mapstructure.Metadata var result Config msdec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ Metadata: &md, Result: &result, ErrorUnused: true, }) if err != nil { return nil, err } if err := msdec.Decode(raw); err != nil { return nil, err } // Decode the time values if result.ReconnectIntervalRaw != "" { dur, err := time.ParseDuration(result.ReconnectIntervalRaw) if err != nil { return nil, err } result.ReconnectInterval = dur } if result.ReconnectTimeoutRaw != "" { dur, err := time.ParseDuration(result.ReconnectTimeoutRaw) if err != nil { return nil, err } result.ReconnectTimeout = dur } if result.TombstoneTimeoutRaw != "" { dur, err := time.ParseDuration(result.TombstoneTimeoutRaw) if err != nil { return nil, err } result.TombstoneTimeout = dur } if result.RetryIntervalRaw != "" { dur, err := time.ParseDuration(result.RetryIntervalRaw) if err != nil { return nil, err } result.RetryInterval = dur } return &result, nil }
func saveConfigRequestUnmarshler(r *http.Request) (atc.Config, db.PipelinePausedState, error) { configStructure, pausedState, err := requestToConfig(r.Header.Get("Content-Type"), r.Body) if err != nil { return atc.Config{}, db.PipelineNoChange, err } var config atc.Config var md mapstructure.Metadata msConfig := &mapstructure.DecoderConfig{ Metadata: &md, Result: &config, WeaklyTypedInput: true, DecodeHook: func( dataKind reflect.Kind, valKind reflect.Kind, data interface{}, ) (interface{}, error) { if valKind == reflect.Map { if dataKind == reflect.Map { return sanitize(data) } } if dataKind == reflect.String { val, err := time.ParseDuration(data.(string)) if err == nil { return val, nil } } if valKind == reflect.String { if dataKind == reflect.String { return data, nil } // format it as JSON/YAML would return json.Marshal(data) } return data, nil }, } decoder, err := mapstructure.NewDecoder(msConfig) if err != nil { return atc.Config{}, db.PipelineNoChange, ErrFailedToConstructDecoder } if err := decoder.Decode(configStructure); err != nil { return atc.Config{}, db.PipelineNoChange, ErrCouldNotDecode } if len(md.Unused) != 0 { return atc.Config{}, db.PipelineNoChange, ExtraKeysError{extraKeys: md.Unused} } return config, pausedState, nil }
// parseConnectionInfo is used to convert the ConnInfo of the InstanceState into // a ConnectionInfo struct func parseConnectionInfo(s *terraform.InstanceState) (*connectionInfo, error) { connInfo := &connectionInfo{} decConf := &mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: connInfo, } dec, err := mapstructure.NewDecoder(decConf) if err != nil { return nil, err } if err := dec.Decode(s.Ephemeral.ConnInfo); err != nil { return nil, err } // To default Agent to true, we need to check the raw string, since the // decoded boolean can't represent "absence of config". // // And if SSH_AUTH_SOCK is not set, there's no agent to connect to, so we // shouldn't try. if s.Ephemeral.ConnInfo["agent"] == "" && os.Getenv("SSH_AUTH_SOCK") != "" { connInfo.Agent = true } if connInfo.User == "" { connInfo.User = DefaultUser } if connInfo.Port == 0 { connInfo.Port = DefaultPort } if connInfo.ScriptPath == "" { connInfo.ScriptPath = DefaultScriptPath } if connInfo.Timeout != "" { connInfo.TimeoutVal = safeDuration(connInfo.Timeout, DefaultTimeout) } else { connInfo.TimeoutVal = DefaultTimeout } // Default all bastion config attrs to their non-bastion counterparts if connInfo.BastionHost != "" { if connInfo.BastionUser == "" { connInfo.BastionUser = connInfo.User } if connInfo.BastionPassword == "" { connInfo.BastionPassword = connInfo.Password } if connInfo.BastionKeyFile == "" { connInfo.BastionKeyFile = connInfo.KeyFile } if connInfo.BastionPort == 0 { connInfo.BastionPort = connInfo.Port } } return connInfo, nil }
func getDecoder(serializer interface{}) *mapstructure.Decoder { decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ TagName: "json", Result: serializer, }) if err != nil { panic(err) } return decoder }
func (r *ResourceProvisioner) decodeConfig(c *terraform.ResourceConfig) (*Provisioner, error) { p := new(Provisioner) decConf := &mapstructure.DecoderConfig{ ErrorUnused: true, WeaklyTypedInput: true, Result: p, } dec, err := mapstructure.NewDecoder(decConf) if err != nil { return nil, err } // We need to decode this twice. Once for the Raw config and once // for the parsed Config. This makes sure that all values are there // even if some still need to be interpolated later on. // Without this the validation will fail when using a variable for // a required parameter (the node_name for example). if err := dec.Decode(c.Raw); err != nil { return nil, err } if err := dec.Decode(c.Config); err != nil { return nil, err } if p.Environment == "" { p.Environment = defaultEnv } for i, hint := range p.OhaiHints { hintPath, err := homedir.Expand(hint) if err != nil { return nil, fmt.Errorf("Error expanding the path %s: %v", hint, err) } p.OhaiHints[i] = hintPath } if p.ValidationKeyPath != "" { keyPath, err := homedir.Expand(p.ValidationKeyPath) if err != nil { return nil, fmt.Errorf("Error expanding the validation key path: %v", err) } p.ValidationKeyPath = keyPath } if attrs, ok := c.Config["attributes"]; ok { p.Attributes, err = rawToJSON(attrs) if err != nil { return nil, fmt.Errorf("Error parsing the attributes: %v", err) } } return p, nil }
func (d *Decoder) decode(ch chan<- interface{}, pairs consul.KVPairs) error { raw := make(map[string]interface{}) for _, p := range pairs { // Trim the prefix off our key first key := strings.TrimPrefix(p.Key, d.Prefix) // Determine what map we're writing the value to. We split by '/' // to determine any sub-maps that need to be created. m := raw children := strings.Split(key, "/") if len(children) > 0 { key = children[len(children)-1] children = children[:len(children)-1] for _, child := range children { if m[child] == nil { m[child] = make(map[string]interface{}) } subm, ok := m[child].(map[string]interface{}) if !ok { return fmt.Errorf("child is both a data item and dir: %s", child) } m = subm } } m[key] = string(p.Value) } // First copy our initial value target, err := copystructure.Copy(d.Target) if err != nil { return err } // Now decode into it decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ Metadata: nil, Result: target, WeaklyTypedInput: true, TagName: "consul", }) if err != nil { return err } if err := decoder.Decode(raw); err != nil { return err } // Send it ch <- target return nil }
// DecodeRaw decodes a raw interface into the target structure func DecodeRaw(raw interface{}, result interface{}) error { decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ ErrorUnused: true, WeaklyTypedInput: true, Result: result, }) if err != nil { return err } return decoder.Decode(raw) }
// decode is a helper that uses the mapstructure library to decode a // string-keyed map into a structure. func decode(result interface{}, options map[string]interface{}) error { config := mapstructure.DecoderConfig{ DecodeHook: cborrpc.DecodeBytesAsString, Result: result, } decoder, err := mapstructure.NewDecoder(&config) if err == nil { err = decoder.Decode(options) } return err }
// UnmarshalKey unmarshals a single config key into a struct. func (c *Config) UnmarshalKey(key string, rawVal interface{}) error { config := &mapstructure.DecoderConfig{ Result: rawVal, TagName: "json", } decoder, err := mapstructure.NewDecoder(config) if err != nil { return err } return decoder.Decode(c.viper.Get(key)) }
// ReadConfig obtains the configuration defined by the user merged with the defaults. func ReadConfig(conf *api.ConfigMap) config.Configuration { if len(conf.Data) == 0 { return config.NewDefault() } errors := make([]int, 0) skipUrls := make([]string, 0) whitelist := make([]string, 0) if val, ok := conf.Data[customHTTPErrors]; ok { delete(conf.Data, customHTTPErrors) for _, i := range strings.Split(val, ",") { j, err := strconv.Atoi(i) if err != nil { glog.Warningf("%v is not a valid http code: %v", i, err) } else { errors = append(errors, j) } } } if val, ok := conf.Data[skipAccessLogUrls]; ok { delete(conf.Data, skipAccessLogUrls) skipUrls = strings.Split(val, ",") } if val, ok := conf.Data[whitelistSourceRange]; ok { delete(conf.Data, whitelistSourceRange) whitelist = append(whitelist, strings.Split(val, ",")...) } to := config.Configuration{} to.Backend = defaults.Backend{ CustomHTTPErrors: filterErrors(errors), SkipAccessLogURLs: skipUrls, WhitelistSourceRange: whitelist, } def := config.NewDefault() if err := mergo.Merge(&to, def); err != nil { glog.Warningf("unexpected error merging defaults: %v", err) } metadata := &mapstructure.Metadata{} decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ TagName: "structs", Result: &to, WeaklyTypedInput: true, Metadata: metadata, }) err = decoder.Decode(conf.Data) if err != nil { glog.Infof("%v", err) } return to }
func Decode(data interface{}, structPtr interface{}) { decoderConfig := &mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: structPtr, ZeroFields: true, } decoder, err := mapstructure.NewDecoder(decoderConfig) if err == nil { decoder.Decode(data) } }