func getStringField(data *framework.FieldData, key string) (string, *logical.Response) {
	valueIface, ok, err := data.GetOkErr(key)
	if err != nil {
		return "", logical.ErrorResponse(fmt.Sprintf("%v: could not extract '%s' from request", err, key))
	}
	// the convention (in e.g. https://github.com/hashicorp/vault/blob/8142b42d951119a73ce46daa3331921b5e21cdee/builtin/logical/aws/path_config_lease.go
	// seems to be to return logical.ErrorResponse for invalid requests, and error for internal errors)
	if !ok {
		return "", errMissingField(key)
	}
	value, ok := valueIface.(string)
	if !ok {
		return "", logical.ErrorResponse(fmt.Sprintf("invalid type for param '%s' (expected string but got %T)", key, valueIface))
	}
	return value, nil
}
func getStringField(data *framework.FieldData, key string) (string, *logical.Response) {
	valueIface, ok, err := data.GetOkErr(key)
	if err != nil {
		return "", logical.ErrorResponse(fmt.Sprintf("%v: could not extract '%s' from request", err, key))
	}
	// the convention (in e.g. https://github.com/hashicorp/vault/blob/8142b42d951119a73ce46daa3331921b5e21cdee/builtin/logical/aws/path_config_lease.go
	// seems to be to return logical.ErrorResponse for invalid requests, and error for internal errors)
	if !ok {
		return "", errMissingField(key)
	}
	value, ok := valueIface.(string)
	if !ok {
		return "", logical.ErrorResponse(fmt.Sprintf("invalid type for param '%s' (expected string but got %T)", key, valueIface))
	}
	return value, nil
}
// getStringField extracts 'key' from 'req', and either returns the value as a
// string or an error response (vault path handlers seem to return
// ErrorResponse rather than actual errors for malformed requests)