github.com/mmatczuk/gohan@v0.0.0-20170206152520-30e45d9bdb69/cli/client/arguments.go (about)

     1  // Copyright (C) 2015 NTT Innovation Institute, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package client
    17  
    18  import (
    19  	"encoding/json"
    20  	"fmt"
    21  	u "net/url"
    22  	"strconv"
    23  	"strings"
    24  
    25  	"github.com/cloudwan/gohan/schema"
    26  )
    27  
    28  func (gohanClientCLI *GohanClientCLI) getCustomArgsAsMap(
    29  	args []string,
    30  	actionInput string,
    31  	action schema.Action,
    32  ) (argsMap map[string]interface{}, err error) {
    33  	argsMap = map[string]interface{}{}
    34  	if action.InputSchema != nil {
    35  		var value interface{}
    36  		inputType, ok := action.InputSchema["type"].(string)
    37  		if !ok {
    38  			return nil, fmt.Errorf("Invalid input schema")
    39  		}
    40  		switch inputType {
    41  		case "integer", "number":
    42  			value, err = strconv.ParseInt(actionInput, 10, 64)
    43  		case "boolean":
    44  			value, err = strconv.ParseBool(actionInput)
    45  		case "array", "object":
    46  			err = json.Unmarshal([]byte(actionInput), &value)
    47  		default:
    48  			value = actionInput
    49  		}
    50  		if err != nil {
    51  			return nil, fmt.Errorf("Error parsing action input %s:", err)
    52  		}
    53  		argsMap[action.ID] = value
    54  	}
    55  	for i := 0; i < len(args); i += 2 {
    56  		key := strings.TrimPrefix(args[i], "--")
    57  		if _, ok := commonParams[key]; !ok {
    58  			return nil, fmt.Errorf("Error parsing parameter %s", key)
    59  		}
    60  		value := args[i+1]
    61  		argsMap[key] = value
    62  	}
    63  	err = gohanClientCLI.handleCommonArguments(argsMap)
    64  	return
    65  }
    66  
    67  func (gohanClientCLI *GohanClientCLI) handleArguments(args []string, s *schema.Schema) (map[string]interface{}, error) {
    68  	argsMap, err := getArgsAsMap(args, s)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	err = gohanClientCLI.handleCommonArguments(argsMap)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	return argsMap, nil
    77  }
    78  
    79  func getArgsAsMap(args []string, s *schema.Schema) (map[string]interface{}, error) {
    80  	if len(args)%2 != 0 {
    81  		return nil, fmt.Errorf("Parameters should be in [--param-name value]... format")
    82  	}
    83  	result := map[string]interface{}{}
    84  	for i := 0; i < len(args); i += 2 {
    85  		key := strings.TrimPrefix(args[i], "--")
    86  		valueType := "string"
    87  		if property, err := s.GetPropertyByID(key); err == nil {
    88  			valueType = property.Type
    89  		}
    90  		rawValue := args[i+1]
    91  		var value interface{}
    92  		var err error
    93  		if rawValue == "<null>" {
    94  			value = nil
    95  		} else {
    96  			switch valueType {
    97  			case "integer", "number":
    98  				value, err = strconv.ParseInt(rawValue, 10, 64)
    99  			case "boolean":
   100  				value, err = strconv.ParseBool(rawValue)
   101  			case "array", "object":
   102  				err = json.Unmarshal([]byte(rawValue), &value)
   103  			default:
   104  				value = rawValue
   105  			}
   106  			if err != nil {
   107  				return nil, fmt.Errorf("Error parsing parameter '%v': %v", key, err)
   108  			}
   109  		}
   110  		result[key] = value
   111  	}
   112  	return result, nil
   113  }
   114  
   115  func (gohanClientCLI *GohanClientCLI) handleCommonArguments(args map[string]interface{}) error {
   116  	if outputFormatOpt, ok := args[outputFormatKey]; ok {
   117  		outputFormat, err := findOutputFormat(outputFormatOpt)
   118  		if err != nil {
   119  			return err
   120  		}
   121  		delete(args, outputFormatKey)
   122  		gohanClientCLI.opts.outputFormat = outputFormat
   123  		return nil
   124  	}
   125  
   126  	if verbosity, ok := args[logLevelKey]; ok {
   127  		logLevel, err := parseLogLevel(verbosity)
   128  		if err != nil {
   129  			return err
   130  		}
   131  		delete(args, logLevelKey)
   132  		gohanClientCLI.opts.logLevel = logLevel
   133  		setUpLogging(logLevel)
   134  		return nil
   135  	}
   136  	return nil
   137  }
   138  
   139  func (gohanClientCLI *GohanClientCLI) handleRelationArguments(s *schema.Schema, args map[string]interface{}) (map[string]interface{}, error) {
   140  	parsedArgs := map[string]interface{}{}
   141  	for arg, value := range args {
   142  		if arg == s.Parent {
   143  			parentID, err := gohanClientCLI.getResourceIDForSchemaID(s.Parent, value.(string))
   144  			if err != nil {
   145  				return nil, err
   146  			}
   147  			parsedArgs[s.ParentSchemaPropertyID()] = parentID
   148  			continue
   149  		}
   150  		property, _ := s.GetPropertyByID(arg)
   151  		if property == nil {
   152  			property, _ = s.GetPropertyByID(arg + "_id")
   153  			if property != nil && property.Relation != "" {
   154  				relatedID, err := gohanClientCLI.getResourceIDForSchemaID(property.Relation, value.(string))
   155  				if err != nil {
   156  					return nil, err
   157  				}
   158  				parsedArgs[property.ID] = relatedID
   159  				continue
   160  			}
   161  		}
   162  		parsedArgs[arg] = value
   163  	}
   164  	return parsedArgs, nil
   165  }
   166  
   167  func (gohanClientCLI *GohanClientCLI) getResourceIDForSchemaID(schemaID, identifier string) (string, error) {
   168  	relatedSchema, err := gohanClientCLI.getSchemaByID(schemaID)
   169  	if err != nil {
   170  		return "", err
   171  	}
   172  	return gohanClientCLI.getResourceID(relatedSchema, identifier)
   173  }
   174  
   175  func (gohanClientCLI *GohanClientCLI) getResourceID(s *schema.Schema, identifier string) (string, error) {
   176  	url := fmt.Sprintf("%s%s/%s", gohanClientCLI.opts.gohanEndpointURL, s.URL, u.QueryEscape(identifier))
   177  	gohanClientCLI.logRequest("GET", url, gohanClientCLI.provider.TokenID, nil)
   178  	_, err := gohanClientCLI.handleResponse(gohanClientCLI.provider.Get(url, nil, nil))
   179  	if err == nil {
   180  		return identifier, nil
   181  	}
   182  
   183  	url = fmt.Sprintf("%s%s?name=%s", gohanClientCLI.opts.gohanEndpointURL, s.URL, u.QueryEscape(identifier))
   184  	gohanClientCLI.logRequest("GET", url, gohanClientCLI.provider.TokenID, nil)
   185  	result, err := gohanClientCLI.handleResponse(gohanClientCLI.provider.Get(url, nil, nil))
   186  	if err != nil {
   187  		return "", err
   188  	}
   189  	resourcesMap, ok := result.(map[string]interface{})
   190  	if !ok {
   191  		return "", fmt.Errorf(resourceNotFoundError)
   192  	}
   193  	resources, ok := resourcesMap[s.Plural].([]interface{})
   194  	if !ok {
   195  		return "", fmt.Errorf(resourceNotFoundError)
   196  	}
   197  
   198  	if len(resources) == 1 {
   199  		return resources[0].(map[string]interface{})["id"].(string), nil
   200  	}
   201  	if len(resources) > 1 {
   202  		return "", fmt.Errorf(multipleResourcesFoundError, s.Plural, identifier)
   203  	}
   204  
   205  	return "", fmt.Errorf(resourceNotFoundError)
   206  }