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 }