mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +00:00 
			
		
		
		
	godep restore pushd $GOPATH/src/github.com/appc/spec git co master popd go get go4.org/errorutil rm -rf Godeps godep save ./... git add vendor git add -f $(git ls-files --other vendor/) git co -- Godeps/LICENSES Godeps/.license_file_state Godeps/OWNERS
		
			
				
	
	
		
			272 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			272 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package gophercloud
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"net/url"
 | 
						|
	"reflect"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
// EnabledState is a convenience type, mostly used in Create and Update
 | 
						|
// operations. Because the zero value of a bool is FALSE, we need to use a
 | 
						|
// pointer instead to indicate zero-ness.
 | 
						|
type EnabledState *bool
 | 
						|
 | 
						|
// Convenience vars for EnabledState values.
 | 
						|
var (
 | 
						|
	iTrue  = true
 | 
						|
	iFalse = false
 | 
						|
 | 
						|
	Enabled  EnabledState = &iTrue
 | 
						|
	Disabled EnabledState = &iFalse
 | 
						|
)
 | 
						|
 | 
						|
// IntToPointer is a function for converting integers into integer pointers.
 | 
						|
// This is useful when passing in options to operations.
 | 
						|
func IntToPointer(i int) *int {
 | 
						|
	return &i
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
MaybeString is an internal function to be used by request methods in individual
 | 
						|
resource packages.
 | 
						|
 | 
						|
It takes a string that might be a zero value and returns either a pointer to its
 | 
						|
address or nil. This is useful for allowing users to conveniently omit values
 | 
						|
from an options struct by leaving them zeroed, but still pass nil to the JSON
 | 
						|
serializer so they'll be omitted from the request body.
 | 
						|
*/
 | 
						|
func MaybeString(original string) *string {
 | 
						|
	if original != "" {
 | 
						|
		return &original
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
MaybeInt is an internal function to be used by request methods in individual
 | 
						|
resource packages.
 | 
						|
 | 
						|
Like MaybeString, it accepts an int that may or may not be a zero value, and
 | 
						|
returns either a pointer to its address or nil. It's intended to hint that the
 | 
						|
JSON serializer should omit its field.
 | 
						|
*/
 | 
						|
func MaybeInt(original int) *int {
 | 
						|
	if original != 0 {
 | 
						|
		return &original
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
var t time.Time
 | 
						|
 | 
						|
func isZero(v reflect.Value) bool {
 | 
						|
	switch v.Kind() {
 | 
						|
	case reflect.Func, reflect.Map, reflect.Slice:
 | 
						|
		return v.IsNil()
 | 
						|
	case reflect.Array:
 | 
						|
		z := true
 | 
						|
		for i := 0; i < v.Len(); i++ {
 | 
						|
			z = z && isZero(v.Index(i))
 | 
						|
		}
 | 
						|
		return z
 | 
						|
	case reflect.Struct:
 | 
						|
		if v.Type() == reflect.TypeOf(t) {
 | 
						|
			if v.Interface().(time.Time).IsZero() {
 | 
						|
				return true
 | 
						|
			}
 | 
						|
			return false
 | 
						|
		}
 | 
						|
		z := true
 | 
						|
		for i := 0; i < v.NumField(); i++ {
 | 
						|
			z = z && isZero(v.Field(i))
 | 
						|
		}
 | 
						|
		return z
 | 
						|
	}
 | 
						|
	// Compare other types directly:
 | 
						|
	z := reflect.Zero(v.Type())
 | 
						|
	return v.Interface() == z.Interface()
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
BuildQueryString is an internal function to be used by request methods in
 | 
						|
individual resource packages.
 | 
						|
 | 
						|
It accepts a tagged structure and expands it into a URL struct. Field names are
 | 
						|
converted into query parameters based on a "q" tag. For example:
 | 
						|
 | 
						|
	type struct Something {
 | 
						|
	   Bar string `q:"x_bar"`
 | 
						|
	   Baz int    `q:"lorem_ipsum"`
 | 
						|
	}
 | 
						|
 | 
						|
	instance := Something{
 | 
						|
	   Bar: "AAA",
 | 
						|
	   Baz: "BBB",
 | 
						|
	}
 | 
						|
 | 
						|
will be converted into "?x_bar=AAA&lorem_ipsum=BBB".
 | 
						|
 | 
						|
The struct's fields may be strings, integers, or boolean values. Fields left at
 | 
						|
their type's zero value will be omitted from the query.
 | 
						|
*/
 | 
						|
func BuildQueryString(opts interface{}) (*url.URL, error) {
 | 
						|
	optsValue := reflect.ValueOf(opts)
 | 
						|
	if optsValue.Kind() == reflect.Ptr {
 | 
						|
		optsValue = optsValue.Elem()
 | 
						|
	}
 | 
						|
 | 
						|
	optsType := reflect.TypeOf(opts)
 | 
						|
	if optsType.Kind() == reflect.Ptr {
 | 
						|
		optsType = optsType.Elem()
 | 
						|
	}
 | 
						|
 | 
						|
	params := url.Values{}
 | 
						|
 | 
						|
	if optsValue.Kind() == reflect.Struct {
 | 
						|
		for i := 0; i < optsValue.NumField(); i++ {
 | 
						|
			v := optsValue.Field(i)
 | 
						|
			f := optsType.Field(i)
 | 
						|
			qTag := f.Tag.Get("q")
 | 
						|
 | 
						|
			// if the field has a 'q' tag, it goes in the query string
 | 
						|
			if qTag != "" {
 | 
						|
				tags := strings.Split(qTag, ",")
 | 
						|
 | 
						|
				// if the field is set, add it to the slice of query pieces
 | 
						|
				if !isZero(v) {
 | 
						|
					switch v.Kind() {
 | 
						|
					case reflect.String:
 | 
						|
						params.Add(tags[0], v.String())
 | 
						|
					case reflect.Int:
 | 
						|
						params.Add(tags[0], strconv.FormatInt(v.Int(), 10))
 | 
						|
					case reflect.Bool:
 | 
						|
						params.Add(tags[0], strconv.FormatBool(v.Bool()))
 | 
						|
					case reflect.Slice:
 | 
						|
						switch v.Type().Elem() {
 | 
						|
						case reflect.TypeOf(0):
 | 
						|
							for i := 0; i < v.Len(); i++ {
 | 
						|
								params.Add(tags[0], strconv.FormatInt(v.Index(i).Int(), 10))
 | 
						|
							}
 | 
						|
						default:
 | 
						|
							for i := 0; i < v.Len(); i++ {
 | 
						|
								params.Add(tags[0], v.Index(i).String())
 | 
						|
							}
 | 
						|
						}
 | 
						|
					}
 | 
						|
				} else {
 | 
						|
					// Otherwise, the field is not set.
 | 
						|
					if len(tags) == 2 && tags[1] == "required" {
 | 
						|
						// And the field is required. Return an error.
 | 
						|
						return nil, fmt.Errorf("Required query parameter [%s] not set.", f.Name)
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return &url.URL{RawQuery: params.Encode()}, nil
 | 
						|
	}
 | 
						|
	// Return an error if the underlying type of 'opts' isn't a struct.
 | 
						|
	return nil, fmt.Errorf("Options type is not a struct.")
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
BuildHeaders is an internal function to be used by request methods in
 | 
						|
individual resource packages.
 | 
						|
 | 
						|
It accepts an arbitrary tagged structure and produces a string map that's
 | 
						|
suitable for use as the HTTP headers of an outgoing request. Field names are
 | 
						|
mapped to header names based in "h" tags.
 | 
						|
 | 
						|
  type struct Something {
 | 
						|
    Bar string `h:"x_bar"`
 | 
						|
    Baz int    `h:"lorem_ipsum"`
 | 
						|
  }
 | 
						|
 | 
						|
  instance := Something{
 | 
						|
    Bar: "AAA",
 | 
						|
    Baz: "BBB",
 | 
						|
  }
 | 
						|
 | 
						|
will be converted into:
 | 
						|
 | 
						|
  map[string]string{
 | 
						|
    "x_bar": "AAA",
 | 
						|
    "lorem_ipsum": "BBB",
 | 
						|
  }
 | 
						|
 | 
						|
Untagged fields and fields left at their zero values are skipped. Integers,
 | 
						|
booleans and string values are supported.
 | 
						|
*/
 | 
						|
func BuildHeaders(opts interface{}) (map[string]string, error) {
 | 
						|
	optsValue := reflect.ValueOf(opts)
 | 
						|
	if optsValue.Kind() == reflect.Ptr {
 | 
						|
		optsValue = optsValue.Elem()
 | 
						|
	}
 | 
						|
 | 
						|
	optsType := reflect.TypeOf(opts)
 | 
						|
	if optsType.Kind() == reflect.Ptr {
 | 
						|
		optsType = optsType.Elem()
 | 
						|
	}
 | 
						|
 | 
						|
	optsMap := make(map[string]string)
 | 
						|
	if optsValue.Kind() == reflect.Struct {
 | 
						|
		for i := 0; i < optsValue.NumField(); i++ {
 | 
						|
			v := optsValue.Field(i)
 | 
						|
			f := optsType.Field(i)
 | 
						|
			hTag := f.Tag.Get("h")
 | 
						|
 | 
						|
			// if the field has a 'h' tag, it goes in the header
 | 
						|
			if hTag != "" {
 | 
						|
				tags := strings.Split(hTag, ",")
 | 
						|
 | 
						|
				// if the field is set, add it to the slice of query pieces
 | 
						|
				if !isZero(v) {
 | 
						|
					switch v.Kind() {
 | 
						|
					case reflect.String:
 | 
						|
						optsMap[tags[0]] = v.String()
 | 
						|
					case reflect.Int:
 | 
						|
						optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10)
 | 
						|
					case reflect.Bool:
 | 
						|
						optsMap[tags[0]] = strconv.FormatBool(v.Bool())
 | 
						|
					}
 | 
						|
				} else {
 | 
						|
					// Otherwise, the field is not set.
 | 
						|
					if len(tags) == 2 && tags[1] == "required" {
 | 
						|
						// And the field is required. Return an error.
 | 
						|
						return optsMap, fmt.Errorf("Required header not set.")
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
		}
 | 
						|
		return optsMap, nil
 | 
						|
	}
 | 
						|
	// Return an error if the underlying type of 'opts' isn't a struct.
 | 
						|
	return optsMap, fmt.Errorf("Options type is not a struct.")
 | 
						|
}
 | 
						|
 | 
						|
// IDSliceToQueryString takes a slice of elements and converts them into a query
 | 
						|
// string. For example, if name=foo and slice=[]int{20, 40, 60}, then the
 | 
						|
// result would be `?name=20&name=40&name=60'
 | 
						|
func IDSliceToQueryString(name string, ids []int) string {
 | 
						|
	str := ""
 | 
						|
	for k, v := range ids {
 | 
						|
		if k == 0 {
 | 
						|
			str += "?"
 | 
						|
		} else {
 | 
						|
			str += "&"
 | 
						|
		}
 | 
						|
		str += fmt.Sprintf("%s=%s", name, strconv.Itoa(v))
 | 
						|
	}
 | 
						|
	return str
 | 
						|
}
 | 
						|
 | 
						|
// IntWithinRange returns TRUE if an integer falls within a defined range, and
 | 
						|
// FALSE if not.
 | 
						|
func IntWithinRange(val, min, max int) bool {
 | 
						|
	return val > min && val < max
 | 
						|
}
 |