Commit 7c1d37bd authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #24464 from matthewrudy/aws-ap-northeast2

Automatic merge from submit-queue AWS: More support for ap-northeast-2 region Issue #24446 The new AWS region for Seoul, Korea (ap-northeast-2) was launched in January 2016 https://aws.amazon.com/blogs/aws/now-open-aws-asia-pacific-seoul-region/ But it requires a few changes. To test: ``` export KUBERNETES_PROVIDER=aws export KUBE_AWS_ZONE=ap-northeast-2a export MASTER_SIZE=t2.medium export NODE_SIZE=t2.medium export NUM_NODES=4 cluster/kube-up.sh ``` I assigned the AMIs by checking the specific version used from `ap-northeast-1`, and finding the same image with the same datestamp. <!-- Reviewable:start --> --- This change is [<img src="http://reviewable.k8s.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](http://reviewable.k8s.io/reviews/kubernetes/kubernetes/24464) <!-- Reviewable:end -->
parents 4f621522 895e4440
...@@ -71,133 +71,133 @@ ...@@ -71,133 +71,133 @@
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws", "ImportPath": "github.com/aws/aws-sdk-go/aws",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr", "ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil", "ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/client", "ImportPath": "github.com/aws/aws-sdk-go/aws/client",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata", "ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers", "ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults", "ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata", "ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/request", "ImportPath": "github.com/aws/aws-sdk-go/aws/request",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/session", "ImportPath": "github.com/aws/aws-sdk-go/aws/session",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/endpoints", "ImportPath": "github.com/aws/aws-sdk-go/private/endpoints",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/signer/v4", "ImportPath": "github.com/aws/aws-sdk-go/private/signer/v4",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/waiter", "ImportPath": "github.com/aws/aws-sdk-go/private/waiter",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling", "ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2", "ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/ecr", "ImportPath": "github.com/aws/aws-sdk-go/service/ecr",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/elb", "ImportPath": "github.com/aws/aws-sdk-go/service/elb",
"Comment": "v1.0.7", "Comment": "v1.0.8",
"Rev": "bf2f8fe7f45e68017086d069498638893feddf64" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/beorn7/perks/quantile", "ImportPath": "github.com/beorn7/perks/quantile",
......
...@@ -365,6 +365,10 @@ function detect-trusty-image () { ...@@ -365,6 +365,10 @@ function detect-trusty-image () {
AWS_IMAGE=ami-93876e93 AWS_IMAGE=ami-93876e93
;; ;;
ap-northeast-2)
AWS_IMAGE=ami-62ac620c
;;
ap-southeast-1) ap-southeast-1)
AWS_IMAGE=ami-66546234 AWS_IMAGE=ami-66546234
;; ;;
......
...@@ -34,6 +34,10 @@ function detect-vivid-image () { ...@@ -34,6 +34,10 @@ function detect-vivid-image () {
AWS_IMAGE=ami-ee023e80 AWS_IMAGE=ami-ee023e80
;; ;;
ap-northeast-2)
AWS_IMAGE=ami-c2df11ac
;;
ap-southeast-1) ap-southeast-1)
AWS_IMAGE=ami-7ad91519 AWS_IMAGE=ami-7ad91519
;; ;;
......
...@@ -33,6 +33,10 @@ function detect-wily-image () { ...@@ -33,6 +33,10 @@ function detect-wily-image () {
AWS_IMAGE=ami-3355505d AWS_IMAGE=ami-3355505d
;; ;;
ap-northeast-2)
AWS_IMAGE=ami-e427e98a
;;
ap-southeast-1) ap-southeast-1)
AWS_IMAGE=ami-60975903 AWS_IMAGE=ami-60975903
;; ;;
......
...@@ -108,7 +108,7 @@ const logRespMsg = `DEBUG: Response %s/%s Details: ...@@ -108,7 +108,7 @@ const logRespMsg = `DEBUG: Response %s/%s Details:
-----------------------------------------------------` -----------------------------------------------------`
func logResponse(r *request.Request) { func logResponse(r *request.Request) {
var msg = "no reponse data" var msg = "no response data"
if r.HTTPResponse != nil { if r.HTTPResponse != nil {
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody) dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody)
......
...@@ -5,4 +5,4 @@ package aws ...@@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go" const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK // SDKVersion is the version of this SDK
const SDKVersion = "1.0.7" const SDKVersion = "1.0.8"
...@@ -78,6 +78,9 @@ ...@@ -78,6 +78,9 @@
"ap-northeast-1/s3": { "ap-northeast-1/s3": {
"endpoint": "s3-{region}.amazonaws.com" "endpoint": "s3-{region}.amazonaws.com"
}, },
"ap-northeast-2/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"sa-east-1/s3": { "sa-east-1/s3": {
"endpoint": "s3-{region}.amazonaws.com" "endpoint": "s3-{region}.amazonaws.com"
}, },
......
...@@ -57,6 +57,9 @@ var endpointsMap = endpointStruct{ ...@@ -57,6 +57,9 @@ var endpointsMap = endpointStruct{
"ap-northeast-1/s3": { "ap-northeast-1/s3": {
Endpoint: "s3-{region}.amazonaws.com", Endpoint: "s3-{region}.amazonaws.com",
}, },
"ap-northeast-2/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
"ap-southeast-1/s3": { "ap-southeast-1/s3": {
Endpoint: "s3-{region}.amazonaws.com", Endpoint: "s3-{region}.amazonaws.com",
}, },
......
...@@ -25,5 +25,5 @@ func Unmarshal(r *request.Request) { ...@@ -25,5 +25,5 @@ func Unmarshal(r *request.Request) {
// UnmarshalMeta unmarshals header response values for an AWS Query service. // UnmarshalMeta unmarshals header response values for an AWS Query service.
func UnmarshalMeta(r *request.Request) { func UnmarshalMeta(r *request.Request) {
// TODO implement unmarshaling of request IDs r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid")
} }
...@@ -11,14 +11,12 @@ import ( ...@@ -11,14 +11,12 @@ import (
"github.com/aws/aws-sdk-go/private/signer/v4" "github.com/aws/aws-sdk-go/private/signer/v4"
) )
// The Amazon EC2 Container Registry makes it easier to manage public and private // Amazon EC2 Container Registry (Amazon ECR) is a managed AWS Docker registry
// Docker images for AWS or on-premises environments. Amazon ECR supports resource-level // service. Customers can use the familiar Docker CLI to push, pull, and manage
// permissions to control who can create, update, use, or delete images. Users // images. Amazon ECR provides a secure, scalable, and reliable registry. Amazon
// and groups can be created individually in AWS Identity and Access Management // ECR supports private Docker repositories with resource-based permissions
// (IAM) or federated with enterprise directories such as Microsoft Active Directory. // using AWS IAM so that specific users or Amazon EC2 instances can access repositories
// Images are stored on highly durable AWS infrastructure and include built-in // and images. Developers can use the Docker CLI to author and manage images.
// caching so that starting hundreds of containers is as fast as starting a
// single container.
//The service client's operations are safe to be used concurrently. //The service client's operations are safe to be used concurrently.
// It is not safe to mutate any of the client's properties though. // It is not safe to mutate any of the client's properties though.
type ECR struct { type ECR struct {
......
testdata/conf_out.ini
ini.sublime-project
ini.sublime-workspace
testdata/conf_reflect.ini
// Copyright 2014 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package ini
import (
"bytes"
"errors"
"fmt"
"reflect"
"time"
"unicode"
)
// NameMapper represents a ini tag name mapper.
type NameMapper func(string) string
// Built-in name getters.
var (
// AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE.
AllCapsUnderscore NameMapper = func(raw string) string {
newstr := make([]rune, 0, len(raw))
for i, chr := range raw {
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
if i > 0 {
newstr = append(newstr, '_')
}
}
newstr = append(newstr, unicode.ToUpper(chr))
}
return string(newstr)
}
// TitleUnderscore converts to format title_underscore.
TitleUnderscore NameMapper = func(raw string) string {
newstr := make([]rune, 0, len(raw))
for i, chr := range raw {
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
if i > 0 {
newstr = append(newstr, '_')
}
chr -= ('A' - 'a')
}
newstr = append(newstr, chr)
}
return string(newstr)
}
)
func (s *Section) parseFieldName(raw, actual string) string {
if len(actual) > 0 {
return actual
}
if s.f.NameMapper != nil {
return s.f.NameMapper(raw)
}
return raw
}
func parseDelim(actual string) string {
if len(actual) > 0 {
return actual
}
return ","
}
var reflectTime = reflect.TypeOf(time.Now()).Kind()
// setWithProperType sets proper value to field based on its type,
// but it does not return error for failing parsing,
// because we want to use default value that is already assigned to strcut.
func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
switch t.Kind() {
case reflect.String:
if len(key.String()) == 0 {
return nil
}
field.SetString(key.String())
case reflect.Bool:
boolVal, err := key.Bool()
if err != nil {
return nil
}
field.SetBool(boolVal)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
durationVal, err := key.Duration()
if err == nil {
field.Set(reflect.ValueOf(durationVal))
return nil
}
intVal, err := key.Int64()
if err != nil {
return nil
}
field.SetInt(intVal)
// byte is an alias for uint8, so supporting uint8 breaks support for byte
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
durationVal, err := key.Duration()
if err == nil {
field.Set(reflect.ValueOf(durationVal))
return nil
}
uintVal, err := key.Uint64()
if err != nil {
return nil
}
field.SetUint(uintVal)
case reflect.Float64:
floatVal, err := key.Float64()
if err != nil {
return nil
}
field.SetFloat(floatVal)
case reflectTime:
timeVal, err := key.Time()
if err != nil {
return nil
}
field.Set(reflect.ValueOf(timeVal))
case reflect.Slice:
vals := key.Strings(delim)
numVals := len(vals)
if numVals == 0 {
return nil
}
sliceOf := field.Type().Elem().Kind()
var times []time.Time
if sliceOf == reflectTime {
times = key.Times(delim)
}
slice := reflect.MakeSlice(field.Type(), numVals, numVals)
for i := 0; i < numVals; i++ {
switch sliceOf {
case reflectTime:
slice.Index(i).Set(reflect.ValueOf(times[i]))
default:
slice.Index(i).Set(reflect.ValueOf(vals[i]))
}
}
field.Set(slice)
default:
return fmt.Errorf("unsupported type '%s'", t)
}
return nil
}
func (s *Section) mapTo(val reflect.Value) error {
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
typ := val.Type()
for i := 0; i < typ.NumField(); i++ {
field := val.Field(i)
tpField := typ.Field(i)
tag := tpField.Tag.Get("ini")
if tag == "-" {
continue
}
fieldName := s.parseFieldName(tpField.Name, tag)
if len(fieldName) == 0 || !field.CanSet() {
continue
}
isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
isStruct := tpField.Type.Kind() == reflect.Struct
if isAnonymous {
field.Set(reflect.New(tpField.Type.Elem()))
}
if isAnonymous || isStruct {
if sec, err := s.f.GetSection(fieldName); err == nil {
if err = sec.mapTo(field); err != nil {
return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
}
continue
}
}
if key, err := s.GetKey(fieldName); err == nil {
if err = setWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
}
}
}
return nil
}
// MapTo maps section to given struct.
func (s *Section) MapTo(v interface{}) error {
typ := reflect.TypeOf(v)
val := reflect.ValueOf(v)
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
val = val.Elem()
} else {
return errors.New("cannot map to non-pointer struct")
}
return s.mapTo(val)
}
// MapTo maps file to given struct.
func (f *File) MapTo(v interface{}) error {
return f.Section("").MapTo(v)
}
// MapTo maps data sources to given struct with name mapper.
func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error {
cfg, err := Load(source, others...)
if err != nil {
return err
}
cfg.NameMapper = mapper
return cfg.MapTo(v)
}
// MapTo maps data sources to given struct.
func MapTo(v, source interface{}, others ...interface{}) error {
return MapToWithMapper(v, nil, source, others...)
}
// reflectWithProperType does the opposite thing with setWithProperType.
func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
switch t.Kind() {
case reflect.String:
key.SetValue(field.String())
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float64,
reflectTime:
key.SetValue(fmt.Sprint(field))
case reflect.Slice:
vals := field.Slice(0, field.Len())
if field.Len() == 0 {
return nil
}
var buf bytes.Buffer
isTime := fmt.Sprint(field.Type()) == "[]time.Time"
for i := 0; i < field.Len(); i++ {
if isTime {
buf.WriteString(vals.Index(i).Interface().(time.Time).Format(time.RFC3339))
} else {
buf.WriteString(fmt.Sprint(vals.Index(i)))
}
buf.WriteString(delim)
}
key.SetValue(buf.String()[:buf.Len()-1])
default:
return fmt.Errorf("unsupported type '%s'", t)
}
return nil
}
func (s *Section) reflectFrom(val reflect.Value) error {
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
typ := val.Type()
for i := 0; i < typ.NumField(); i++ {
field := val.Field(i)
tpField := typ.Field(i)
tag := tpField.Tag.Get("ini")
if tag == "-" {
continue
}
fieldName := s.parseFieldName(tpField.Name, tag)
if len(fieldName) == 0 || !field.CanSet() {
continue
}
if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) ||
(tpField.Type.Kind() == reflect.Struct) {
// Note: The only error here is section doesn't exist.
sec, err := s.f.GetSection(fieldName)
if err != nil {
// Note: fieldName can never be empty here, ignore error.
sec, _ = s.f.NewSection(fieldName)
}
if err = sec.reflectFrom(field); err != nil {
return fmt.Errorf("error reflecting field(%s): %v", fieldName, err)
}
continue
}
// Note: Same reason as secion.
key, err := s.GetKey(fieldName)
if err != nil {
key, _ = s.NewKey(fieldName, "")
}
if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
return fmt.Errorf("error reflecting field(%s): %v", fieldName, err)
}
}
return nil
}
// ReflectFrom reflects secion from given struct.
func (s *Section) ReflectFrom(v interface{}) error {
typ := reflect.TypeOf(v)
val := reflect.ValueOf(v)
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
val = val.Elem()
} else {
return errors.New("cannot reflect from non-pointer struct")
}
return s.reflectFrom(val)
}
// ReflectFrom reflects file from given struct.
func (f *File) ReflectFrom(v interface{}) error {
return f.Section("").ReflectFrom(v)
}
// ReflectFrom reflects data sources from given struct with name mapper.
func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error {
cfg.NameMapper = mapper
return cfg.ReflectFrom(v)
}
// ReflectFrom reflects data sources from given struct.
func ReflectFrom(cfg *File, v interface{}) error {
return ReflectFromWithMapper(cfg, v, nil)
}
language: go
sudo: false
go:
- 1.4
install: go get -v -t ./...
script: make test
Copyright 2015 James Saryerwinnie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
CMD = jpgo
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " test to run all the tests"
@echo " build to build the library and jp executable"
@echo " generate to run codegen"
generate:
go generate ./...
build:
rm -f $(CMD)
go build ./...
rm -f cmd/$(CMD)/$(CMD) && cd cmd/$(CMD)/ && go build ./...
mv cmd/$(CMD)/$(CMD) .
test:
go test -v ./...
check:
go vet ./...
@echo "golint ./..."
@lint=`golint ./...`; \
lint=`echo "$$lint" | grep -v "astnodetype_string.go" | grep -v "toktype_string.go"`; \
echo "$$lint"; \
if [ "$$lint" != "" ]; then exit 1; fi
htmlc:
go test -coverprofile="/tmp/jpcov" && go tool cover -html="/tmp/jpcov" && unlink /tmp/jpcov
buildfuzz:
go-fuzz-build github.com/jmespath/go-jmespath/fuzz
fuzz: buildfuzz
go-fuzz -bin=./jmespath-fuzz.zip -workdir=fuzz/corpus
bench:
go test -bench . -cpuprofile cpu.out
pprof-cpu:
go tool pprof ./go-jmespath.test ./cpu.out
# go-jmespath - A JMESPath implementation in Go
[![Build Status](https://img.shields.io/travis/jmespath/go-jmespath.svg)](https://travis-ci.org/jmespath/go-jmespath)
See http://jmespath.org for more info.
package jmespath
// Search evaluates a JMESPath expression against input data and returns the result.
func Search(expression string, data interface{}) (interface{}, error) {
intr := newInterpreter()
parser := NewParser()
ast, err := parser.Parse(expression)
if err != nil {
return nil, err
}
return intr.Execute(ast, data)
}
// generated by stringer -type astNodeType; DO NOT EDIT
package jmespath
import "fmt"
const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection"
var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307}
func (i astNodeType) String() string {
if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) {
return fmt.Sprintf("astNodeType(%d)", i)
}
return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]]
}
// generated by stringer -type=tokType; DO NOT EDIT
package jmespath
import "fmt"
const _tokType_name = "tUnknowntStartDottFiltertFlattentLparentRparentLbrackettRbrackettLbracetRbracetOrtPipetNumbertUnquotedIdentifiertQuotedIdentifiertCommatColontLTtLTEtGTtGTEtEQtNEtJSONLiteraltStringLiteraltCurrenttExpreftAndtNottEOF"
var _tokType_index = [...]uint8{0, 8, 13, 17, 24, 32, 39, 46, 55, 64, 71, 78, 81, 86, 93, 112, 129, 135, 141, 144, 148, 151, 155, 158, 161, 173, 187, 195, 202, 206, 210, 214}
func (i tokType) String() string {
if i < 0 || i >= tokType(len(_tokType_index)-1) {
return fmt.Sprintf("tokType(%d)", i)
}
return _tokType_name[_tokType_index[i]:_tokType_index[i+1]]
}
package jmespath
import (
"errors"
"reflect"
)
// IsFalse determines if an object is false based on the JMESPath spec.
// JMESPath defines false values to be any of:
// - An empty string array, or hash.
// - The boolean value false.
// - nil
func isFalse(value interface{}) bool {
switch v := value.(type) {
case bool:
return !v
case []interface{}:
return len(v) == 0
case map[string]interface{}:
return len(v) == 0
case string:
return len(v) == 0
case nil:
return true
}
// Try the reflection cases before returning false.
rv := reflect.ValueOf(value)
switch rv.Kind() {
case reflect.Struct:
// A struct type will never be false, even if
// all of its values are the zero type.
return false
case reflect.Slice, reflect.Map:
return rv.Len() == 0
case reflect.Ptr:
if rv.IsNil() {
return true
}
// If it's a pointer type, we'll try to deref the pointer
// and evaluate the pointer value for isFalse.
element := rv.Elem()
return isFalse(element.Interface())
}
return false
}
// ObjsEqual is a generic object equality check.
// It will take two arbitrary objects and recursively determine
// if they are equal.
func objsEqual(left interface{}, right interface{}) bool {
return reflect.DeepEqual(left, right)
}
// SliceParam refers to a single part of a slice.
// A slice consists of a start, a stop, and a step, similar to
// python slices.
type sliceParam struct {
N int
Specified bool
}
// Slice supports [start:stop:step] style slicing that's supported in JMESPath.
func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) {
computed, err := computeSliceParams(len(slice), parts)
if err != nil {
return nil, err
}
start, stop, step := computed[0], computed[1], computed[2]
result := []interface{}{}
if step > 0 {
for i := start; i < stop; i += step {
result = append(result, slice[i])
}
} else {
for i := start; i > stop; i += step {
result = append(result, slice[i])
}
}
return result, nil
}
func computeSliceParams(length int, parts []sliceParam) ([]int, error) {
var start, stop, step int
if !parts[2].Specified {
step = 1
} else if parts[2].N == 0 {
return nil, errors.New("Invalid slice, step cannot be 0")
} else {
step = parts[2].N
}
var stepValueNegative bool
if step < 0 {
stepValueNegative = true
} else {
stepValueNegative = false
}
if !parts[0].Specified {
if stepValueNegative {
start = length - 1
} else {
start = 0
}
} else {
start = capSlice(length, parts[0].N, step)
}
if !parts[1].Specified {
if stepValueNegative {
stop = -1
} else {
stop = length
}
} else {
stop = capSlice(length, parts[1].N, step)
}
return []int{start, stop, step}, nil
}
func capSlice(length int, actual int, step int) int {
if actual < 0 {
actual += length
if actual < 0 {
if step < 0 {
actual = -1
} else {
actual = 0
}
}
} else if actual >= length {
if step < 0 {
actual = length - 1
} else {
actual = length
}
}
return actual
}
// ToArrayNum converts an empty interface type to a slice of float64.
// If any element in the array cannot be converted, then nil is returned
// along with a second value of false.
func toArrayNum(data interface{}) ([]float64, bool) {
// Is there a better way to do this with reflect?
if d, ok := data.([]interface{}); ok {
result := make([]float64, len(d))
for i, el := range d {
item, ok := el.(float64)
if !ok {
return nil, false
}
result[i] = item
}
return result, true
}
return nil, false
}
// ToArrayStr converts an empty interface type to a slice of strings.
// If any element in the array cannot be converted, then nil is returned
// along with a second value of false. If the input data could be entirely
// converted, then the converted data, along with a second value of true,
// will be returned.
func toArrayStr(data interface{}) ([]string, bool) {
// Is there a better way to do this with reflect?
if d, ok := data.([]interface{}); ok {
result := make([]string, len(d))
for i, el := range d {
item, ok := el.(string)
if !ok {
return nil, false
}
result[i] = item
}
return result, true
}
return nil, false
}
func isSliceType(v interface{}) bool {
if v == nil {
return false
}
return reflect.TypeOf(v).Kind() == reflect.Slice
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment