Bump deps

This commit is contained in:
Jeff Mitchell
2016-09-30 09:50:46 -04:00
parent ad62b32ff0
commit 023aa9640f
81 changed files with 2176 additions and 712 deletions

View File

@@ -106,8 +106,8 @@ func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTer
if indexStar || index != nil {
nextvals = []reflect.Value{}
for _, value := range values {
value := reflect.Indirect(value)
for _, valItem := range values {
value := reflect.Indirect(valItem)
if value.Kind() != reflect.Slice {
continue
}

View File

@@ -1,5 +1,3 @@
// +build go1.5
package request
import (
@@ -9,20 +7,13 @@ import (
)
func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
req := &http.Request{
URL: &url.URL{},
Header: http.Header{},
Close: r.Close,
Body: body,
Host: r.Host,
Method: r.Method,
Proto: r.Proto,
ContentLength: r.ContentLength,
// Cancel will be deprecated in 1.7 and will be replaced with Context
Cancel: r.Cancel,
}
req := new(http.Request)
*req = *r
req.URL = &url.URL{}
*req.URL = *r.URL
req.Body = body
req.Header = http.Header{}
for k, v := range r.Header {
for _, vv := range v {
req.Header.Add(k, vv)

View File

@@ -1,31 +0,0 @@
// +build !go1.5
package request
import (
"io"
"net/http"
"net/url"
)
func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
req := &http.Request{
URL: &url.URL{},
Header: http.Header{},
Close: r.Close,
Body: body,
Host: r.Host,
Method: r.Method,
Proto: r.Proto,
ContentLength: r.ContentLength,
}
*req.URL = *r.URL
for k, v := range r.Header {
for _, vv := range v {
req.Header.Add(k, vv)
}
}
return req
}

View File

@@ -179,7 +179,12 @@ type Options struct {
// SharedConfigState: SharedConfigEnable,
// })
func NewSessionWithOptions(opts Options) (*Session, error) {
envCfg := loadEnvConfig()
var envCfg envConfig
if opts.SharedConfigState == SharedConfigEnable {
envCfg = loadSharedEnvConfig()
} else {
envCfg = loadEnvConfig()
}
if len(opts.Profile) > 0 {
envCfg.Profile = opts.Profile

View File

@@ -11,6 +11,7 @@ import (
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"sort"
@@ -175,6 +176,12 @@ type signingCtx struct {
// is not needed as the full request context will be captured by the http.Request
// value. It is included for reference though.
//
// Sign will set the request's Body to be the `body` parameter passed in. If
// the body is not already an io.ReadCloser, it will be wrapped within one. If
// a `nil` body parameter passed to Sign, the request's Body field will be
// also set to nil. Its important to note that this functionality will not
// change the request's ContentLength of the request.
//
// Sign differs from Presign in that it will sign the request using HTTP
// header values. This type of signing is intended for http.Request values that
// will not be shared, or are shared in a way the header values on the request
@@ -258,6 +265,20 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
ctx.assignAmzQueryValues()
ctx.build(v4.DisableHeaderHoisting)
// If the request is not presigned the body should be attached to it. This
// prevents the confusion of wanting to send a signed request without
// the body the request was signed for attached.
if !ctx.isPresign {
var reader io.ReadCloser
if body != nil {
var ok bool
if reader, ok = body.(io.ReadCloser); !ok {
reader = ioutil.NopCloser(body)
}
}
r.Body = reader
}
if v4.Debug.Matches(aws.LogDebugWithSigning) {
v4.logSigningInfo(ctx)
}
@@ -356,7 +377,7 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time
req.LastSignedAt = curTimeFn()
}
const logSignInfoMsg = `DEBUG: Request Signiture:
const logSignInfoMsg = `DEBUG: Request Signature:
---[ CANONICAL STRING ]-----------------------------
%s
---[ STRING TO SIGN ]--------------------------------

View File

@@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK
const SDKVersion = "1.4.8"
const SDKVersion = "1.4.14"

View File

@@ -13,6 +13,55 @@ import (
"github.com/aws/aws-sdk-go/private/protocol/ec2query"
)
const opAcceptReservedInstancesExchangeQuote = "AcceptReservedInstancesExchangeQuote"
// AcceptReservedInstancesExchangeQuoteRequest generates a "aws/request.Request" representing the
// client's request for the AcceptReservedInstancesExchangeQuote operation. The "output" return
// value can be used to capture response data after the request's "Send" method
// is called.
//
// Creating a request object using this method should be used when you want to inject
// custom logic into the request's lifecycle using a custom handler, or if you want to
// access properties on the request object before or after sending the request. If
// you just want the service response, call the AcceptReservedInstancesExchangeQuote method directly
// instead.
//
// Note: You must call the "Send" method on the returned request object in order
// to execute the request.
//
// // Example sending a request using the AcceptReservedInstancesExchangeQuoteRequest method.
// req, resp := client.AcceptReservedInstancesExchangeQuoteRequest(params)
//
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
//
func (c *EC2) AcceptReservedInstancesExchangeQuoteRequest(input *AcceptReservedInstancesExchangeQuoteInput) (req *request.Request, output *AcceptReservedInstancesExchangeQuoteOutput) {
op := &request.Operation{
Name: opAcceptReservedInstancesExchangeQuote,
HTTPMethod: "POST",
HTTPPath: "/",
}
if input == nil {
input = &AcceptReservedInstancesExchangeQuoteInput{}
}
req = c.newRequest(op, input, output)
output = &AcceptReservedInstancesExchangeQuoteOutput{}
req.Data = output
return
}
// Purchases Convertible Reserved Instance offerings described in the GetReservedInstancesExchangeQuote
// call.
func (c *EC2) AcceptReservedInstancesExchangeQuote(input *AcceptReservedInstancesExchangeQuoteInput) (*AcceptReservedInstancesExchangeQuoteOutput, error) {
req, out := c.AcceptReservedInstancesExchangeQuoteRequest(input)
err := req.Send()
return out, err
}
const opAcceptVpcPeeringConnection = "AcceptVpcPeeringConnection"
// AcceptVpcPeeringConnectionRequest generates a "aws/request.Request" representing the
@@ -282,8 +331,10 @@ func (c *EC2) AssociateAddressRequest(input *AssociateAddressInput) (req *reques
// Elastic IP address is already associated with a different instance or a network
// interface, you get an error unless you allow reassociation.
//
// This is an idempotent operation. If you perform the operation more than
// once, Amazon EC2 doesn't return an error.
// This is an idempotent operation. If you perform the operation more than
// once, Amazon EC2 doesn't return an error, and you may be charged for each
// time the Elastic IP address is remapped to the same instance. For more information,
// see the Elastic IP Addresses section of Amazon EC2 Pricing (http://aws.amazon.com/ec2/pricing/).
func (c *EC2) AssociateAddress(input *AssociateAddressInput) (*AssociateAddressOutput, error) {
req, out := c.AssociateAddressRequest(input)
err := req.Send()
@@ -2182,23 +2233,23 @@ func (c *EC2) CreateReservedInstancesListingRequest(input *CreateReservedInstanc
return
}
// Creates a listing for Amazon EC2 Reserved Instances to be sold in the Reserved
// Instance Marketplace. You can submit one Reserved Instance listing at a time.
// To get a list of your Reserved Instances, you can use the DescribeReservedInstances
// operation.
// Creates a listing for Amazon EC2 Standard Reserved Instances to be sold in
// the Reserved Instance Marketplace. You can submit one Standard Reserved Instance
// listing at a time. To get a list of your Standard Reserved Instances, you
// can use the DescribeReservedInstances operation.
//
// The Reserved Instance Marketplace matches sellers who want to resell Reserved
// Instance capacity that they no longer need with buyers who want to purchase
// additional capacity. Reserved Instances bought and sold through the Reserved
// Instance Marketplace work like any other Reserved Instances.
// The Reserved Instance Marketplace matches sellers who want to resell Standard
// Reserved Instance capacity that they no longer need with buyers who want
// to purchase additional capacity. Reserved Instances bought and sold through
// the Reserved Instance Marketplace work like any other Reserved Instances.
//
// To sell your Reserved Instances, you must first register as a seller in
// the Reserved Instance Marketplace. After completing the registration process,
// To sell your Standard Reserved Instances, you must first register as a seller
// in the Reserved Instance Marketplace. After completing the registration process,
// you can create a Reserved Instance Marketplace listing of some or all of
// your Reserved Instances, and specify the upfront price to receive for them.
// Your Reserved Instance listings then become available for purchase. To view
// the details of your Reserved Instance listing, you can use the DescribeReservedInstancesListings
// operation.
// your Standard Reserved Instances, and specify the upfront price to receive
// for them. Your Standard Reserved Instance listings then become available
// for purchase. To view the details of your Standard Reserved Instance listing,
// you can use the DescribeReservedInstancesListings operation.
//
// For more information, see Reserved Instance Marketplace (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-market-general.html)
// in the Amazon Elastic Compute Cloud User Guide.
@@ -7070,6 +7121,9 @@ func (c *EC2) DescribeSpotFleetRequestsRequest(input *DescribeSpotFleetRequestsI
}
// Describes your Spot fleet requests.
//
// Spot fleet requests are deleted 48 hours after they are canceled and their
// instances are terminated.
func (c *EC2) DescribeSpotFleetRequests(input *DescribeSpotFleetRequestsInput) (*DescribeSpotFleetRequestsOutput, error) {
req, out := c.DescribeSpotFleetRequestsRequest(input)
err := req.Send()
@@ -7154,6 +7208,9 @@ func (c *EC2) DescribeSpotInstanceRequestsRequest(input *DescribeSpotInstanceReq
// the instance ID appears in the response and contains the identifier of the
// instance. Alternatively, you can use DescribeInstances with a filter to look
// for instances where the instance lifecycle is spot.
//
// Spot instance requests are deleted 4 hours after they are canceled and their
// instances are terminated.
func (c *EC2) DescribeSpotInstanceRequests(input *DescribeSpotInstanceRequestsInput) (*DescribeSpotInstanceRequestsOutput, error) {
req, out := c.DescribeSpotInstanceRequestsRequest(input)
err := req.Send()
@@ -9107,6 +9164,56 @@ func (c *EC2) GetPasswordData(input *GetPasswordDataInput) (*GetPasswordDataOutp
return out, err
}
const opGetReservedInstancesExchangeQuote = "GetReservedInstancesExchangeQuote"
// GetReservedInstancesExchangeQuoteRequest generates a "aws/request.Request" representing the
// client's request for the GetReservedInstancesExchangeQuote operation. The "output" return
// value can be used to capture response data after the request's "Send" method
// is called.
//
// Creating a request object using this method should be used when you want to inject
// custom logic into the request's lifecycle using a custom handler, or if you want to
// access properties on the request object before or after sending the request. If
// you just want the service response, call the GetReservedInstancesExchangeQuote method directly
// instead.
//
// Note: You must call the "Send" method on the returned request object in order
// to execute the request.
//
// // Example sending a request using the GetReservedInstancesExchangeQuoteRequest method.
// req, resp := client.GetReservedInstancesExchangeQuoteRequest(params)
//
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
//
func (c *EC2) GetReservedInstancesExchangeQuoteRequest(input *GetReservedInstancesExchangeQuoteInput) (req *request.Request, output *GetReservedInstancesExchangeQuoteOutput) {
op := &request.Operation{
Name: opGetReservedInstancesExchangeQuote,
HTTPMethod: "POST",
HTTPPath: "/",
}
if input == nil {
input = &GetReservedInstancesExchangeQuoteInput{}
}
req = c.newRequest(op, input, output)
output = &GetReservedInstancesExchangeQuoteOutput{}
req.Data = output
return
}
// Returns details about the values and term of your specified Convertible Reserved
// Instances. When an offering ID is specified it returns information about
// whether the exchange is valid and can be performed.
func (c *EC2) GetReservedInstancesExchangeQuote(input *GetReservedInstancesExchangeQuoteInput) (*GetReservedInstancesExchangeQuoteOutput, error) {
req, out := c.GetReservedInstancesExchangeQuoteRequest(input)
err := req.Send()
return out, err
}
const opImportImage = "ImportImage"
// ImportImageRequest generates a "aws/request.Request" representing the
@@ -9823,9 +9930,9 @@ func (c *EC2) ModifyReservedInstancesRequest(input *ModifyReservedInstancesInput
}
// Modifies the Availability Zone, instance count, instance type, or network
// platform (EC2-Classic or EC2-VPC) of your Reserved Instances. The Reserved
// Instances to be modified must be identical, except for Availability Zone,
// network platform, and instance type.
// platform (EC2-Classic or EC2-VPC) of your Standard Reserved Instances. The
// Reserved Instances to be modified must be identical, except for Availability
// Zone, network platform, and instance type.
//
// For more information, see Modifying Reserved Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-modifying.html)
// in the Amazon Elastic Compute Cloud User Guide.
@@ -10437,9 +10544,7 @@ func (c *EC2) PurchaseReservedInstancesOfferingRequest(input *PurchaseReservedIn
}
// Purchases a Reserved Instance for use with your account. With Reserved Instances,
// you obtain a capacity reservation for a certain instance configuration over
// a specified period of time and pay a lower hourly rate compared to On-Demand
// instance pricing.
// you pay a lower hourly rate compared to On-Demand instance pricing.
//
// Use DescribeReservedInstancesOfferings to get a list of Reserved Instance
// offerings that match your specifications. After you've purchased a Reserved
@@ -11939,6 +12044,9 @@ func (c *EC2) TerminateInstancesRequest(input *TerminateInstancesInput) (req *re
// Shuts down one or more instances. This operation is idempotent; if you terminate
// an instance more than once, each call succeeds.
//
// If you specify multiple instances and the request fails (for example, because
// of a single incorrect instance ID), none of the instances are terminated.
//
// Terminated instances remain visible after termination (for approximately
// one hour).
//
@@ -12064,6 +12172,76 @@ func (c *EC2) UnmonitorInstances(input *UnmonitorInstancesInput) (*UnmonitorInst
return out, err
}
// Contains the parameters for accepting the quote.
type AcceptReservedInstancesExchangeQuoteInput struct {
_ struct{} `type:"structure"`
// Checks whether you have the required permissions for the action, without
// actually making the request, and provides an error response. If you have
// the required permissions, the error response is DryRunOperation. Otherwise,
// it is UnauthorizedOperation.
DryRun *bool `type:"boolean"`
// The IDs of the Convertible Reserved Instances that you want to exchange for
// other Convertible Reserved Instances of the same or higher value.
ReservedInstanceIds []*string `locationName:"ReservedInstanceId" locationNameList:"ReservedInstanceId" type:"list" required:"true"`
// The configurations of the Convertible Reserved Instance offerings you are
// purchasing in this exchange.
TargetConfigurations []*TargetConfigurationRequest `locationName:"TargetConfiguration" locationNameList:"TargetConfigurationRequest" type:"list"`
}
// String returns the string representation
func (s AcceptReservedInstancesExchangeQuoteInput) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s AcceptReservedInstancesExchangeQuoteInput) GoString() string {
return s.String()
}
// Validate inspects the fields of the type to determine if they are valid.
func (s *AcceptReservedInstancesExchangeQuoteInput) Validate() error {
invalidParams := request.ErrInvalidParams{Context: "AcceptReservedInstancesExchangeQuoteInput"}
if s.ReservedInstanceIds == nil {
invalidParams.Add(request.NewErrParamRequired("ReservedInstanceIds"))
}
if s.TargetConfigurations != nil {
for i, v := range s.TargetConfigurations {
if v == nil {
continue
}
if err := v.Validate(); err != nil {
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TargetConfigurations", i), err.(request.ErrInvalidParams))
}
}
}
if invalidParams.Len() > 0 {
return invalidParams
}
return nil
}
// The result of the exchange and whether it was successful.
type AcceptReservedInstancesExchangeQuoteOutput struct {
_ struct{} `type:"structure"`
// The ID of the successful exchange.
ExchangeId *string `locationName:"exchangeId" type:"string"`
}
// String returns the string representation
func (s AcceptReservedInstancesExchangeQuoteOutput) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s AcceptReservedInstancesExchangeQuoteOutput) GoString() string {
return s.String()
}
// Contains the parameters for AcceptVpcPeeringConnection.
type AcceptVpcPeeringConnectionInput struct {
_ struct{} `type:"structure"`
@@ -15007,11 +15185,11 @@ type CreateReservedInstancesListingInput struct {
// ID specified in this call.
InstanceCount *int64 `locationName:"instanceCount" type:"integer" required:"true"`
// A list specifying the price of the Reserved Instance for each month remaining
// in the Reserved Instance term.
// A list specifying the price of the Standard Reserved Instance for each month
// remaining in the Reserved Instance term.
PriceSchedules []*PriceScheduleSpecification `locationName:"priceSchedules" locationNameList:"item" type:"list" required:"true"`
// The ID of the active Reserved Instance.
// The ID of the active Standard Reserved Instance.
ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string" required:"true"`
}
@@ -15051,7 +15229,7 @@ func (s *CreateReservedInstancesListingInput) Validate() error {
type CreateReservedInstancesListingOutput struct {
_ struct{} `type:"structure"`
// Information about the Reserved Instance listing.
// Information about the Standard Reserved Instance listing.
ReservedInstancesListings []*ReservedInstancesListing `locationName:"reservedInstancesListingsSet" locationNameList:"item" type:"list"`
}
@@ -17652,9 +17830,6 @@ type DescribeConversionTasksInput struct {
// the required permissions, the error response is DryRunOperation. Otherwise,
// it is UnauthorizedOperation.
DryRun *bool `locationName:"dryRun" type:"boolean"`
// One or more filters.
Filters []*Filter `locationName:"filter" locationNameList:"Filter" type:"list"`
}
// String returns the string representation
@@ -19786,6 +19961,8 @@ type DescribeReservedInstancesInput struct {
//
// instance-type - The instance type that is covered by the reservation.
//
// scope - The scope of the Reserved Instance (Region or Availability Zone).
//
// product-description - The Reserved Instance product platform description.
// Instances that include (Amazon VPC) in the product platform description will
// only be displayed to EC2-Classic account holders and are for use with Amazon
@@ -19820,6 +19997,9 @@ type DescribeReservedInstancesInput struct {
// example, 0.84).
Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"`
// Describes whether the Reserved Instance is Standard or Convertible.
OfferingClass *string `type:"string" enum:"OfferingClassType"`
// The Reserved Instance offering type. If you are using tools that predate
// the 2011-11-01 API version, you only have access to the Medium Utilization
// Reserved Instance offering type.
@@ -19856,7 +20036,7 @@ type DescribeReservedInstancesListingsInput struct {
// | cancelled | closed).
//
// status-message - The reason for the status.
Filters []*Filter `locationName:"filters" locationNameList:"Filter" type:"list"`
Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"`
// One or more Reserved Instance IDs.
ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"`
@@ -20014,6 +20194,8 @@ type DescribeReservedInstancesOfferingsInput struct {
//
// reserved-instances-offering-id - The Reserved Instances offering ID.
//
// scope - The scope of the Reserved Instance (Availability Zone or Region).
//
// usage-price - The usage price of the Reserved Instance, per hour (for
// example, 0.84).
Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"`
@@ -20058,6 +20240,9 @@ type DescribeReservedInstancesOfferingsInput struct {
// The token to retrieve the next page of results.
NextToken *string `locationName:"nextToken" type:"string"`
// The offering class of the Reserved Instance. Can be standard or convertible.
OfferingClass *string `type:"string" enum:"OfferingClassType"`
// The Reserved Instance offering type. If you are using tools that predate
// the 2011-11-01 API version, you only have access to the Medium Utilization
// Reserved Instance offering type.
@@ -23826,6 +24011,99 @@ func (s GetPasswordDataOutput) GoString() string {
return s.String()
}
// Contains the parameters for GetReservedInstanceExchangeQuote.
type GetReservedInstancesExchangeQuoteInput struct {
_ struct{} `type:"structure"`
// Checks whether you have the required permissions for the action, without
// actually making the request, and provides an error response. If you have
// the required permissions, the error response is DryRunOperation. Otherwise,
// it is UnauthorizedOperation.
DryRun *bool `type:"boolean"`
// The ID/s of the Convertible Reserved Instances you want to exchange.
ReservedInstanceIds []*string `locationName:"ReservedInstanceId" locationNameList:"ReservedInstanceId" type:"list" required:"true"`
// The configuration requirements of the Convertible Reserved Instances you
// want in exchange for your current Convertible Reserved Instances.
TargetConfigurations []*TargetConfigurationRequest `locationName:"TargetConfiguration" locationNameList:"TargetConfigurationRequest" type:"list"`
}
// String returns the string representation
func (s GetReservedInstancesExchangeQuoteInput) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s GetReservedInstancesExchangeQuoteInput) GoString() string {
return s.String()
}
// Validate inspects the fields of the type to determine if they are valid.
func (s *GetReservedInstancesExchangeQuoteInput) Validate() error {
invalidParams := request.ErrInvalidParams{Context: "GetReservedInstancesExchangeQuoteInput"}
if s.ReservedInstanceIds == nil {
invalidParams.Add(request.NewErrParamRequired("ReservedInstanceIds"))
}
if s.TargetConfigurations != nil {
for i, v := range s.TargetConfigurations {
if v == nil {
continue
}
if err := v.Validate(); err != nil {
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TargetConfigurations", i), err.(request.ErrInvalidParams))
}
}
}
if invalidParams.Len() > 0 {
return invalidParams
}
return nil
}
// Contains the output of GetReservedInstancesExchangeQuote.
type GetReservedInstancesExchangeQuoteOutput struct {
_ struct{} `type:"structure"`
// The currency of the transaction.
CurrencyCode *string `locationName:"currencyCode" type:"string"`
// If true, the exchange is valid. If false, the exchange cannot be performed.
IsValidExchange *bool `locationName:"isValidExchange" type:"boolean"`
// The new end date of the reservation term.
OutputReservedInstancesWillExpireAt *time.Time `locationName:"outputReservedInstancesWillExpireAt" type:"timestamp" timestampFormat:"iso8601"`
// The total true upfront charge for the exchange.
PaymentDue *string `locationName:"paymentDue" type:"string"`
// The cost associated with the Reserved Instance.
ReservedInstanceValueRollup *ReservationValue `locationName:"reservedInstanceValueRollup" type:"structure"`
// The configuration of your Convertible Reserved Instances.
ReservedInstanceValueSet []*ReservedInstanceReservationValue `locationName:"reservedInstanceValueSet" locationNameList:"item" type:"list"`
// The cost associated with the Reserved Instance.
TargetConfigurationValueRollup *ReservationValue `locationName:"targetConfigurationValueRollup" type:"structure"`
// The values of the target Convertible Reserved Instances.
TargetConfigurationValueSet []*TargetReservationValue `locationName:"targetConfigurationValueSet" locationNameList:"item" type:"list"`
// Describes the reason why the exchange can not be completed.
ValidationFailureReason *string `locationName:"validationFailureReason" type:"string"`
}
// String returns the string representation
func (s GetReservedInstancesExchangeQuoteOutput) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s GetReservedInstancesExchangeQuoteOutput) GoString() string {
return s.String()
}
// Describes a security group.
type GroupIdentifier struct {
_ struct{} `type:"structure"`
@@ -25327,16 +25605,19 @@ type InstanceNetworkInterfaceSpecification struct {
NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"`
// The private IP address of the network interface. Applies only if creating
// a network interface when launching an instance.
// a network interface when launching an instance. You cannot specify this option
// if you're launching more than one instance in a RunInstances request.
PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"`
// One or more private IP addresses to assign to the network interface. Only
// one private IP address can be designated as primary.
// one private IP address can be designated as primary. You cannot specify this
// option if you're launching more than one instance in a RunInstances request.
PrivateIpAddresses []*PrivateIpAddressSpecification `locationName:"privateIpAddressesSet" queryName:"PrivateIpAddresses" locationNameList:"item" type:"list"`
// The number of secondary private IP addresses. You can't specify this option
// and specify more than one private IP address using the private IP addresses
// option.
// option. You cannot specify this option if you're launching more than one
// instance in a RunInstances request.
SecondaryPrivateIpAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"`
// The ID of the subnet associated with the network string. Applies only if
@@ -29110,6 +29391,31 @@ func (s Reservation) GoString() string {
return s.String()
}
// The cost associated with the Reserved Instance.
type ReservationValue struct {
_ struct{} `type:"structure"`
// The hourly rate of the reservation.
HourlyPrice *string `locationName:"hourlyPrice" type:"string"`
// The balance of the total value (the sum of remainingUpfrontValue + hourlyPrice
// * number of hours remaining).
RemainingTotalValue *string `locationName:"remainingTotalValue" type:"string"`
// The remaining upfront cost of the reservation.
RemainingUpfrontValue *string `locationName:"remainingUpfrontValue" type:"string"`
}
// String returns the string representation
func (s ReservationValue) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s ReservationValue) GoString() string {
return s.String()
}
// Describes the limit price of a Reserved Instance offering.
type ReservedInstanceLimitPrice struct {
_ struct{} `type:"structure"`
@@ -29133,6 +29439,27 @@ func (s ReservedInstanceLimitPrice) GoString() string {
return s.String()
}
// The total value of the Convertible Reserved Instance.
type ReservedInstanceReservationValue struct {
_ struct{} `type:"structure"`
// The total value of the Convertible Reserved Instance that you are exchanging.
ReservationValue *ReservationValue `locationName:"reservationValue" type:"structure"`
// The ID of the Convertible Reserved Instance that you are exchanging.
ReservedInstanceId *string `locationName:"reservedInstanceId" type:"string"`
}
// String returns the string representation
func (s ReservedInstanceReservationValue) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s ReservedInstanceReservationValue) GoString() string {
return s.String()
}
// Describes a Reserved Instance.
type ReservedInstances struct {
_ struct{} `type:"structure"`
@@ -29162,6 +29489,9 @@ type ReservedInstances struct {
// The instance type on which the Reserved Instance can be used.
InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"`
// The offering class of the Reserved Instance.
OfferingClass *string `locationName:"offeringClass" type:"string" enum:"OfferingClassType"`
// The Reserved Instance offering type.
OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"`
@@ -29174,6 +29504,9 @@ type ReservedInstances struct {
// The ID of the Reserved Instance.
ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"`
// The scope of the Reserved Instance.
Scope *string `locationName:"scope" type:"string" enum:"scope"`
// The date and time the Reserved Instance started.
Start *time.Time `locationName:"start" type:"timestamp" timestampFormat:"iso8601"`
@@ -29213,6 +29546,9 @@ type ReservedInstancesConfiguration struct {
// The network platform of the modified Reserved Instances, which is either
// EC2-Classic or EC2-VPC.
Platform *string `locationName:"platform" type:"string"`
// Whether the Reserved Instance is standard or convertible.
Scope *string `locationName:"scope" type:"string" enum:"scope"`
}
// String returns the string representation
@@ -29386,6 +29722,11 @@ type ReservedInstancesOffering struct {
// this is true.
Marketplace *bool `locationName:"marketplace" type:"boolean"`
// If convertible it can be exchanged for Reserved Instances of the same or
// higher monetary value, with different configurations. If standard, it is
// not possible to perform an exchange.
OfferingClass *string `locationName:"offeringClass" type:"string" enum:"OfferingClassType"`
// The Reserved Instance offering type.
OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"`
@@ -29398,9 +29739,14 @@ type ReservedInstancesOffering struct {
// The recurring charge tag assigned to the resource.
RecurringCharges []*RecurringCharge `locationName:"recurringCharges" locationNameList:"item" type:"list"`
// The ID of the Reserved Instance offering.
// The ID of the Reserved Instance offering. This is the offering ID used in
// GetReservedInstancesExchangeQuote to confirm that an exchange can be made.
ReservedInstancesOfferingId *string `locationName:"reservedInstancesOfferingId" type:"string"`
// Whether the Reserved Instance is applied to instances in a region or an Availability
// Zone.
Scope *string `locationName:"scope" type:"string" enum:"scope"`
// The usage price of the Reserved Instance, per hour.
UsagePrice *float64 `locationName:"usagePrice" type:"float"`
}
@@ -30092,6 +30438,9 @@ type RunInstancesInput struct {
// can't specify this parameter if PrivateIpAddresses.n.Primary is set to true
// and PrivateIpAddresses.n.PrivateIpAddress is set to an IP address.
//
// You cannot specify this option if you're launching more than one instance
// in the request.
//
// Default: We select an IP address from the IP address range of the subnet.
PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"`
@@ -31949,6 +32298,89 @@ func (s TagDescription) GoString() string {
return s.String()
}
// Information about the Convertible Reserved Instance offering.
type TargetConfiguration struct {
_ struct{} `type:"structure"`
// The number of instances the Convertible Reserved Instance offering can be
// applied to. This parameter is reserved and cannot be specified in a request
InstanceCount *int64 `locationName:"instanceCount" type:"integer"`
// The ID of the Convertible Reserved Instance offering.
OfferingId *string `locationName:"offeringId" type:"string"`
}
// String returns the string representation
func (s TargetConfiguration) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s TargetConfiguration) GoString() string {
return s.String()
}
// Details about the target configuration.
type TargetConfigurationRequest struct {
_ struct{} `type:"structure"`
// The number of instances the Covertible Reserved Instance offering can be
// applied to. This parameter is reserved and cannot be specified in a request
InstanceCount *int64 `type:"integer"`
// The Convertible Reserved Instance offering ID. If this isn't included in
// the request, the response lists your current Convertible Reserved Instance/s
// and their value/s.
OfferingId *string `type:"string" required:"true"`
}
// String returns the string representation
func (s TargetConfigurationRequest) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s TargetConfigurationRequest) GoString() string {
return s.String()
}
// Validate inspects the fields of the type to determine if they are valid.
func (s *TargetConfigurationRequest) Validate() error {
invalidParams := request.ErrInvalidParams{Context: "TargetConfigurationRequest"}
if s.OfferingId == nil {
invalidParams.Add(request.NewErrParamRequired("OfferingId"))
}
if invalidParams.Len() > 0 {
return invalidParams
}
return nil
}
// The total value of the new Convertible Reserved Instances.
type TargetReservationValue struct {
_ struct{} `type:"structure"`
// The total value of the Convertible Reserved Instances that make up the exchange.
// This is the sum of the list value, remaining upfront price, and additional
// upfront cost of the exchange.
ReservationValue *ReservationValue `locationName:"reservationValue" type:"structure"`
// The configuration of the Convertible Reserved Instances that make up the
// exchange.
TargetConfiguration *TargetConfiguration `locationName:"targetConfiguration" type:"structure"`
}
// String returns the string representation
func (s TargetReservationValue) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s TargetReservationValue) GoString() string {
return s.String()
}
// Contains the parameters for TerminateInstances.
type TerminateInstancesInput struct {
_ struct{} `type:"structure"`
@@ -31960,6 +32392,9 @@ type TerminateInstancesInput struct {
DryRun *bool `locationName:"dryRun" type:"boolean"`
// One or more instance IDs.
//
// Constraints: Up to 1000 instance IDs. We recommend breaking up this request
// into smaller batches.
InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"`
}
@@ -33328,6 +33763,8 @@ const (
// @enum InstanceType
InstanceTypeM410xlarge = "m4.10xlarge"
// @enum InstanceType
InstanceTypeM416xlarge = "m4.16xlarge"
// @enum InstanceType
InstanceTypeM2Xlarge = "m2.xlarge"
// @enum InstanceType
InstanceTypeM22xlarge = "m2.2xlarge"
@@ -33346,10 +33783,6 @@ const (
// @enum InstanceType
InstanceTypeR38xlarge = "r3.8xlarge"
// @enum InstanceType
InstanceTypeX14xlarge = "x1.4xlarge"
// @enum InstanceType
InstanceTypeX18xlarge = "x1.8xlarge"
// @enum InstanceType
InstanceTypeX116xlarge = "x1.16xlarge"
// @enum InstanceType
InstanceTypeX132xlarge = "x1.32xlarge"
@@ -33400,6 +33833,12 @@ const (
// @enum InstanceType
InstanceTypeCg14xlarge = "cg1.4xlarge"
// @enum InstanceType
InstanceTypeP2Xlarge = "p2.xlarge"
// @enum InstanceType
InstanceTypeP28xlarge = "p2.8xlarge"
// @enum InstanceType
InstanceTypeP216xlarge = "p2.16xlarge"
// @enum InstanceType
InstanceTypeD2Xlarge = "d2.xlarge"
// @enum InstanceType
InstanceTypeD22xlarge = "d2.2xlarge"
@@ -33491,6 +33930,13 @@ const (
NetworkInterfaceTypeNatGateway = "natGateway"
)
const (
// @enum OfferingClassType
OfferingClassTypeStandard = "standard"
// @enum OfferingClassType
OfferingClassTypeConvertible = "convertible"
)
const (
// @enum OfferingTypeValues
OfferingTypeValuesHeavyUtilization = "Heavy Utilization"
@@ -33929,3 +34375,10 @@ const (
// @enum VpnStaticRouteSource
VpnStaticRouteSourceStatic = "Static"
)
const (
// @enum scope
ScopeAvailabilityZone = "Availability Zone"
// @enum scope
ScopeRegion = "Region"
)

View File

@@ -54,7 +54,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
ServiceName: ServiceName,
SigningRegion: signingRegion,
Endpoint: endpoint,
APIVersion: "2016-04-01",
APIVersion: "2016-09-15",
},
handlers,
),

View File

@@ -5487,6 +5487,11 @@ type GetObjectInput struct {
Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
// Part number of the object being read. This is a positive integer between
// 1 and 10,000. Effectively performs a 'ranged' GET request for the part specified.
// Useful for downloading just a part of an object.
PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer"`
// Downloads the specified range bytes of an object. For more information about
// the HTTP Range header, go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.
Range *string `location:"header" locationName:"Range" type:"string"`
@@ -5623,6 +5628,9 @@ type GetObjectOutput struct {
// you can create metadata whose values are not legal HTTP headers.
MissingMeta *int64 `location:"header" locationName:"x-amz-missing-meta" type:"integer"`
// The count of parts this object has.
PartsCount *int64 `location:"header" locationName:"x-amz-mp-parts-count" type:"integer"`
ReplicationStatus *string `location:"header" locationName:"x-amz-replication-status" type:"string" enum:"ReplicationStatus"`
// If present, indicates that the requester was successfully charged for the
@@ -5877,6 +5885,12 @@ type HeadObjectInput struct {
Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
// Part number of the object being read. This is a positive integer between
// 1 and 10,000. Effectively performs a 'ranged' HEAD request for the part specified.
// Useful querying about the size of the part and the number of parts in this
// object.
PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer"`
// Downloads the specified range bytes of an object. For more information about
// the HTTP Range header, go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.
Range *string `location:"header" locationName:"Range" type:"string"`
@@ -5989,6 +6003,9 @@ type HeadObjectOutput struct {
// you can create metadata whose values are not legal HTTP headers.
MissingMeta *int64 `location:"header" locationName:"x-amz-missing-meta" type:"integer"`
// The count of parts this object has.
PartsCount *int64 `location:"header" locationName:"x-amz-mp-parts-count" type:"integer"`
ReplicationStatus *string `location:"header" locationName:"x-amz-replication-status" type:"string" enum:"ReplicationStatus"`
// If present, indicates that the requester was successfully charged for the
@@ -6552,6 +6569,12 @@ type ListObjectsInput struct {
// Limits the response to keys that begin with the specified prefix.
Prefix *string `location:"querystring" locationName:"prefix" type:"string"`
// Confirms that the requester knows that she or he will be charged for the
// request. Bucket owners need not specify this parameter in their requests.
// Documentation on downloading objects from requester pays buckets can be found
// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
}
// String returns the string representation
@@ -6650,6 +6673,12 @@ type ListObjectsV2Input struct {
// Limits the response to keys that begin with the specified prefix.
Prefix *string `location:"querystring" locationName:"prefix" type:"string"`
// Confirms that the requester knows that she or he will be charged for the
// request. Bucket owners need not specify this parameter in their requests.
// Documentation on downloading objects from requester pays buckets can be found
// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
// StartAfter is where you want Amazon S3 to start listing from. Amazon S3 starts
// listing after this specified key. StartAfter can be any key in the bucket
StartAfter *string `location:"querystring" locationName:"start-after" type:"string"`

View File

@@ -70,7 +70,8 @@ func main() {
// desired set this explicitly so that the current hostname will not be used.
cmc.CheckManager.Check.InstanceID = ""
// Search tag - a specific tag which, when coupled with the instanceId serves to identify the
// origin and/or grouping of the metrics
// origin and/or grouping of the metrics. Multiple tags may be used, separate with comma.
// (e.g. service:consul,service_role:server)
// default: service:application name (e.g. service:consul)
cmc.CheckManager.Check.SearchTag = ""
// Check secret, default: generated when a check needs to be created

View File

@@ -168,7 +168,6 @@ func (a *API) apiCall(reqMethod string, reqPath string, data []byte) ([]byte, er
// errors and may relate to outages on the server side. This will catch
// invalid response codes as well, like 0 and 999.
if resp.StatusCode == 0 || resp.StatusCode >= 500 {
defer resp.Body.Close()
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
lastHTTPError = fmt.Errorf("- last HTTP error: %d %+v", resp.StatusCode, readErr)

View File

@@ -70,7 +70,9 @@ func (a *API) BrokerSearch(query SearchQueryType) ([]Broker, error) {
}
var brokers []Broker
json.Unmarshal(result, &brokers)
if err := json.Unmarshal(result, &brokers); err != nil {
return nil, err
}
return brokers, nil
}
@@ -83,7 +85,9 @@ func (a *API) FetchBrokerList() ([]Broker, error) {
}
var response []Broker
json.Unmarshal(result, &response)
if err := json.Unmarshal(result, &response); err != nil {
return nil, err
}
return response, nil
}

View File

@@ -40,7 +40,9 @@ func (a *API) FetchCheckByCID(cid CIDType) (*Check, error) {
}
check := new(Check)
json.Unmarshal(result, check)
if err := json.Unmarshal(result, check); err != nil {
return nil, err
}
return check, nil
}
@@ -56,16 +58,15 @@ func (a *API) FetchCheckBySubmissionURL(submissionURL URLType) (*Check, error) {
// valid trap url: scheme://host[:port]/module/httptrap/UUID/secret
// does it smell like a valid trap url path
if u.Path[:17] != "/module/httptrap/" {
if !strings.Contains(u.Path, "/module/httptrap/") {
return nil, fmt.Errorf("[ERROR] Invalid submission URL '%s', unrecognized path", submissionURL)
}
// extract uuid/secret
pathParts := strings.Split(u.Path[17:len(u.Path)], "/")
// extract uuid
pathParts := strings.Split(strings.Replace(u.Path, "/module/httptrap/", "", 1), "/")
if len(pathParts) != 2 {
return nil, fmt.Errorf("[ERROR] Invalid submission URL '%s', UUID not where expected", submissionURL)
}
uuid := pathParts[0]
query := SearchQueryType(fmt.Sprintf("f__check_uuid=%s", uuid))
@@ -107,7 +108,9 @@ func (a *API) CheckSearch(query SearchQueryType) ([]Check, error) {
}
var checks []Check
json.Unmarshal(result, &checks)
if err := json.Unmarshal(result, &checks); err != nil {
return nil, err
}
return checks, nil
}

View File

@@ -14,6 +14,13 @@ type CheckBundleConfig struct {
AsyncMetrics bool `json:"async_metrics"`
Secret string `json:"secret"`
SubmissionURL string `json:"submission_url"`
ReverseSecret string `json:"reverse:secret_key"`
HTTPVersion string `json:"http_version,omitempty"`
Method string `json:"method,omitempty"`
Payload string `json:"payload,omitempty"`
Port string `json:"port,omitempty"`
ReadLimit string `json:"read_limit,omitempty"`
URL string `json:"url,omitempty"`
}
// CheckBundleMetric individual metric configuration
@@ -32,7 +39,7 @@ type CheckBundle struct {
Created int `json:"_created,omitempty"`
LastModified int `json:"_last_modified,omitempty"`
LastModifedBy string `json:"_last_modifed_by,omitempty"`
ReverseConnectUrls []string `json:"_reverse_connection_urls,omitempty"`
ReverseConnectURLs []string `json:"_reverse_connection_urls"`
Brokers []string `json:"brokers"`
Config CheckBundleConfig `json:"config"`
DisplayName string `json:"display_name"`
@@ -61,7 +68,9 @@ func (a *API) FetchCheckBundleByCID(cid CIDType) (*CheckBundle, error) {
}
checkBundle := &CheckBundle{}
json.Unmarshal(result, checkBundle)
if err := json.Unmarshal(result, checkBundle); err != nil {
return nil, err
}
return checkBundle, nil
}
@@ -77,9 +86,8 @@ func (a *API) CheckBundleSearch(searchCriteria SearchQueryType) ([]CheckBundle,
}
var results []CheckBundle
err = json.Unmarshal(response, &results)
if err != nil {
return nil, fmt.Errorf("[ERROR] Parsing JSON response %+v", err)
if err := json.Unmarshal(response, &results); err != nil {
return nil, err
}
return results, nil
@@ -98,8 +106,7 @@ func (a *API) CreateCheckBundle(config CheckBundle) (*CheckBundle, error) {
}
checkBundle := &CheckBundle{}
err = json.Unmarshal(response, checkBundle)
if err != nil {
if err := json.Unmarshal(response, checkBundle); err != nil {
return nil, err
}
@@ -123,8 +130,7 @@ func (a *API) UpdateCheckBundle(config *CheckBundle) (*CheckBundle, error) {
}
checkBundle := &CheckBundle{}
err = json.Unmarshal(response, checkBundle)
if err != nil {
if err := json.Unmarshal(response, checkBundle); err != nil {
return nil, err
}

View File

@@ -74,8 +74,7 @@ func (cm *CheckManager) fetchCert() ([]byte, error) {
}
cadata := new(CACert)
err = json.Unmarshal(response, cadata)
if err != nil {
if err := json.Unmarshal(response, cadata); err != nil {
return nil, err
}

View File

@@ -32,6 +32,8 @@ func (cm *CheckManager) initializeTrapURL() error {
cm.trapmu.Lock()
defer cm.trapmu.Unlock()
// special case short-circuit: just send to a url, no check management
// up to user to ensure that if url is https that it will work (e.g. not self-signed)
if cm.checkSubmissionURL != "" {
if !cm.enabled {
cm.trapURL = cm.checkSubmissionURL
@@ -54,6 +56,9 @@ func (cm *CheckManager) initializeTrapURL() error {
if err != nil {
return err
}
if !check.Active {
return fmt.Errorf("[ERROR] Check ID %v is not active", check.Cid)
}
// extract check id from check object returned from looking up using submission url
// set m.CheckId to the id
// set m.SubmissionUrl to "" to prevent trying to search on it going forward
@@ -75,6 +80,9 @@ func (cm *CheckManager) initializeTrapURL() error {
if err != nil {
return err
}
if !check.Active {
return fmt.Errorf("[ERROR] Check ID %v is not active", check.Cid)
}
} else {
searchCriteria := fmt.Sprintf(
"(active:1)(host:\"%s\")(type:\"%s\")(tags:%s)",
@@ -116,8 +124,19 @@ func (cm *CheckManager) initializeTrapURL() error {
cm.checkBundle = checkBundle
cm.inventoryMetrics()
// url to which metrics should be PUT
cm.trapURL = api.URLType(checkBundle.Config.SubmissionURL)
// determine the trap url to which metrics should be PUT
if checkBundle.Type == "httptrap" {
cm.trapURL = api.URLType(checkBundle.Config.SubmissionURL)
} else {
// build a submission_url for non-httptrap checks out of mtev_reverse url
if len(checkBundle.ReverseConnectURLs) == 0 {
return fmt.Errorf("%s is not an HTTPTRAP check and no reverse connection urls found", checkBundle.Checks[0])
}
mtevURL := checkBundle.ReverseConnectURLs[0]
mtevURL = strings.Replace(mtevURL, "mtev_reverse", "https", 1)
mtevURL = strings.Replace(mtevURL, "check", "module/httptrap", 1)
cm.trapURL = api.URLType(fmt.Sprintf("%s/%s", mtevURL, checkBundle.Config.ReverseSecret))
}
// used when sending as "ServerName" get around certs not having IP SANS
// (cert created with server name as CN but IP used in trap url)

View File

@@ -246,7 +246,13 @@ func (m *CirconusMetrics) Flush() {
}
}
m.submit(output, newMetrics)
if len(output) > 0 {
m.submit(output, newMetrics)
} else {
if m.Debug {
m.Log.Println("[DEBUG] No metrics to send, skipping")
}
}
m.flushmu.Lock()
m.flushing = false

View File

@@ -8,6 +8,7 @@ import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net"
@@ -53,8 +54,32 @@ func (m *CirconusMetrics) trapCall(payload []byte) (int, error) {
if err != nil {
return 0, err
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
// keep last HTTP error in the event of retry failure
var lastHTTPError error
retryPolicy := func(resp *http.Response, err error) (bool, error) {
if err != nil {
lastHTTPError = err
return true, err
}
// Check the response code. We retry on 500-range responses to allow
// the server time to recover, as 500's are typically not permanent
// errors and may relate to outages on the server side. This will catch
// invalid response codes as well, like 0 and 999.
if resp.StatusCode == 0 || resp.StatusCode >= 500 {
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
lastHTTPError = fmt.Errorf("- last HTTP error: %d %+v", resp.StatusCode, readErr)
} else {
lastHTTPError = fmt.Errorf("- last HTTP error: %d %s", resp.StatusCode, string(body))
}
return true, nil
}
return false, nil
}
client := retryablehttp.NewClient()
if trap.URL.Scheme == "https" {
client.HTTPClient.Transport = &http.Transport{
@@ -86,6 +111,7 @@ func (m *CirconusMetrics) trapCall(payload []byte) (int, error) {
client.RetryWaitMax = 50 * time.Millisecond
client.RetryMax = 3
client.Logger = m.Log
client.CheckRetry = retryPolicy
attempts := -1
client.RequestLogHook = func(logger *log.Logger, req *http.Request, retryNumber int) {
@@ -94,6 +120,9 @@ func (m *CirconusMetrics) trapCall(payload []byte) (int, error) {
resp, err := client.Do(req)
if err != nil {
if lastHTTPError != nil {
return 0, fmt.Errorf("[ERROR] submitting: %+v %+v", err, lastHTTPError)
}
if attempts == client.RetryMax {
m.check.RefreshTrap()
}
@@ -107,9 +136,8 @@ func (m *CirconusMetrics) trapCall(payload []byte) (int, error) {
}
var response map[string]interface{}
err = json.Unmarshal(body, &response)
if err != nil {
m.Log.Printf("[ERROR] parsing body, proceeding. %s\n", err)
if err := json.Unmarshal(body, &response); err != nil {
m.Log.Printf("[ERROR] parsing body, proceeding. %v (%s)\n", err, body)
}
if resp.StatusCode != 200 {

View File

@@ -33,7 +33,7 @@ const (
)
var (
plog = capnslog.NewPackageLogger("github.com/coreos/etcd/pkg", "fileutil")
plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/fileutil")
)
// IsDirWriteable checks if dir is writable by writing and removing a file

View File

@@ -208,6 +208,9 @@ func (info TLSInfo) ServerConfig() (*tls.Config, error) {
cfg.ClientCAs = cp
}
// "h2" NextProtos is necessary for enabling HTTP2 for go's HTTP server
cfg.NextProtos = []string{"h2"}
return cfg, nil
}

View File

@@ -1,27 +1,22 @@
Copyright (c) 2012 The Go Authors. All rights reserved.
The MIT License (MIT)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)
Portions copyright (c) 2015-2016 go-ldap Authors
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -334,18 +334,18 @@ func DecodeControl(packet *ber.Packet) Control {
for _, child := range sequence.Children {
if child.Tag == 0 {
//Warning
child := child.Children[0]
packet := ber.DecodePacket(child.Data.Bytes())
warningPacket := child.Children[0]
packet := ber.DecodePacket(warningPacket.Data.Bytes())
val, ok := packet.Value.(int64)
if ok {
if child.Tag == 0 {
if warningPacket.Tag == 0 {
//timeBeforeExpiration
c.Expire = val
child.Value = c.Expire
} else if child.Tag == 1 {
warningPacket.Value = c.Expire
} else if warningPacket.Tag == 1 {
//graceAuthNsRemaining
c.Grace = val
child.Value = c.Grace
warningPacket.Value = c.Grace
}
}
} else if child.Tag == 1 {

View File

@@ -153,16 +153,47 @@ func addLDAPDescriptions(packet *ber.Packet) (err error) {
func addControlDescriptions(packet *ber.Packet) {
packet.Description = "Controls"
for _, child := range packet.Children {
var value *ber.Packet
controlType := ""
child.Description = "Control"
child.Children[0].Description = "Control Type (" + ControlTypeMap[child.Children[0].Value.(string)] + ")"
value := child.Children[1]
if len(child.Children) == 3 {
child.Children[1].Description = "Criticality"
value = child.Children[2]
}
value.Description = "Control Value"
switch len(child.Children) {
case 0:
// at least one child is required for control type
continue
switch child.Children[0].Value.(string) {
case 1:
// just type, no criticality or value
controlType = child.Children[0].Value.(string)
child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")"
case 2:
controlType = child.Children[0].Value.(string)
child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")"
// Children[1] could be criticality or value (both are optional)
// duck-type on whether this is a boolean
if _, ok := child.Children[1].Value.(bool); ok {
child.Children[1].Description = "Criticality"
} else {
child.Children[1].Description = "Control Value"
value = child.Children[1]
}
case 3:
// criticality and value present
controlType = child.Children[0].Value.(string)
child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")"
child.Children[1].Description = "Criticality"
child.Children[2].Description = "Control Value"
value = child.Children[2]
default:
// more than 3 children is invalid
continue
}
if value == nil {
continue
}
switch controlType {
case ControlTypePaging:
value.Description += " (Paging)"
if value.Value != nil {
@@ -188,18 +219,18 @@ func addControlDescriptions(packet *ber.Packet) {
for _, child := range sequence.Children {
if child.Tag == 0 {
//Warning
child := child.Children[0]
packet := ber.DecodePacket(child.Data.Bytes())
warningPacket := child.Children[0]
packet := ber.DecodePacket(warningPacket.Data.Bytes())
val, ok := packet.Value.(int64)
if ok {
if child.Tag == 0 {
if warningPacket.Tag == 0 {
//timeBeforeExpiration
value.Description += " (TimeBeforeExpiration)"
child.Value = val
} else if child.Tag == 1 {
warningPacket.Value = val
} else if warningPacket.Tag == 1 {
//graceAuthNsRemaining
value.Description += " (GraceAuthNsRemaining)"
child.Value = val
warningPacket.Value = val
}
}
} else if child.Tag == 1 {

View File

@@ -1,12 +1,12 @@
# Contributing to gocql
**TL;DR** - this manifesto sets out the bare mimimum requirements for submitting a patch to gocql.
**TL;DR** - this manifesto sets out the bare minimum requirements for submitting a patch to gocql.
This guide outlines the process of landing patches in gocql and the general approach to maintaining the code base.
## Background
The goal of the gocql project is to provide a stable and robust CQL driver for Golang. gocql is a community driven project that is coordinated by a small team of core developers.
The goal of the gocql project is to provide a stable and robust CQL driver for Go. gocql is a community driven project that is coordinated by a small team of core developers.
## Minimum Requirement Checklist
@@ -22,7 +22,7 @@ The following is a check list of requirements that need to be satisfied in order
* `go fmt` has been applied to the submitted code
* Functional changes (i.e. new features or changed behavior) are appropriately documented, either as a godoc or in the README (non-functional changes such as bug fixes may not require documentation)
If there are any requirements that can't be reasonably satifisfied, please state this either on the pull request or as part of discussion on the mailing list. Where appropriate, the core team may apply discretion and make an exception to these requirements.
If there are any requirements that can't be reasonably satisfied, please state this either on the pull request or as part of discussion on the mailing list. Where appropriate, the core team may apply discretion and make an exception to these requirements.
## Beyond The Checklist
@@ -49,11 +49,11 @@ Examples of pull requests that have been accepted without tests include:
### Sign Off Procedure
Generally speaking, a pull request can get merged by any one of the core gocql team. If your change is minor, chances are that one team member will just go ahead and merge it there and then. As stated earlier, suitable test coverage will increase the likelihood that a single reviewer will assess and merge your change. If your change has no test coverage, or looks like it may have wider implications for the health and stability of the library, the reviewer may elect to refer the change to another team member to acheive consensus before proceeding. Therefore, the tighter and cleaner your patch is, the quicker it will go through the review process.
Generally speaking, a pull request can get merged by any one of the core gocql team. If your change is minor, chances are that one team member will just go ahead and merge it there and then. As stated earlier, suitable test coverage will increase the likelihood that a single reviewer will assess and merge your change. If your change has no test coverage, or looks like it may have wider implications for the health and stability of the library, the reviewer may elect to refer the change to another team member to achieve consensus before proceeding. Therefore, the tighter and cleaner your patch is, the quicker it will go through the review process.
### Supported Features
gocql is a low level wire driver for Cassandra CQL. By and large, we would like to keep the functional scope of the library as narrow as possible. We think that gocql should be tight and focussed, and we will be naturally sceptical of things that could just as easily be implemented in a higher layer. Inevitably you will come accross something that could be implemented in a higher layer, save for a minor change to the core API. In this instance, please strike up a conversation with the gocql team. Chances are we will understand what you are trying to acheive and will try to accommodate this in a maintainable way.
gocql is a low level wire driver for Cassandra CQL. By and large, we would like to keep the functional scope of the library as narrow as possible. We think that gocql should be tight and focused, and we will be naturally skeptical of things that could just as easily be implemented in a higher layer. Inevitably you will come across something that could be implemented in a higher layer, save for a minor change to the core API. In this instance, please strike up a conversation with the gocql team. Chances are we will understand what you are trying to achieve and will try to accommodate this in a maintainable way.
### Longer Term Evolution
@@ -61,7 +61,7 @@ There are some long term plans for gocql that have to be taken into account when
## Officially Supported Server Versions
Currently, the officiallly supported versions of the Cassandra server include:
Currently, the officially supported versions of the Cassandra server include:
* 1.2.18
* 2.0.9

View File

@@ -1,27 +1,27 @@
Copyright (c) 2016 The gocql Authors. All rights reserved.
Copyright (c) 2016, The Gocql authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -14,7 +14,7 @@ Discussions: https://groups.google.com/forum/#!forum/gocql
Production Stability
--------------------
The method in which the driver maintains and discovers hosts in the Cassandra cluster changed when adding support for event driven discovery using serverside events. This has meant many things in the driver internally have been touched and changed, as such if you would like to go back to the historical node discovery the tag `pre-node-events` is a tree which uses the old polling based discovery.
The method in which the driver maintains and discovers hosts in the Cassandra cluster changed when adding support for event driven discovery using server-side events. This has meant many things in the driver internally have been touched and changed, as such if you would like to go back to the historical node discovery the tag `pre-node-events` is a tree which uses the old polling based discovery.
If you run into bugs related to node discovery using events please open a ticket.
@@ -25,8 +25,8 @@ The following matrix shows the versions of Go and Cassandra that are tested with
Go/Cassandra | 2.0.x | 2.1.x | 2.2.x
-------------| -------| ------| ---------
1.4 | yes | yes | yes
1.5 | yes | yes | yes
1.6 | yes | yes | yes
1.7 | yes | yes | yes
Gocql has been tested in production against many different versions of Cassandra. Due to limits in our CI setup we only test against the latest 3 major releases, which coincide with the official support from the Apache project.
@@ -36,7 +36,7 @@ NOTE: as of Cassandra 3.0 it requires Java 8, currently (06/02/2016) we can not
Sunsetting Model
----------------
In general, the gocql team will focus on supporting the current and previous versions of Golang. gocql may still work with older versions of Golang, but offical support for these versions will have been sunset.
In general, the gocql team will focus on supporting the current and previous versions of Go. gocql may still work with older versions of Go, but official support for these versions will have been sunset.
Installation
------------
@@ -48,10 +48,10 @@ Features
--------
* Modern Cassandra client using the native transport
* Automatic type conversations between Cassandra and Go
* Automatic type conversions between Cassandra and Go
* Support for all common types including sets, lists and maps
* Custom types can implement a `Marshaler` and `Unmarshaler` interface
* Strict type conversations without any loss of precision
* Strict type conversions without any loss of precision
* Built-In support for UUIDs (version 1 and 4)
* Support for logged, unlogged and counter batches
* Cluster management
@@ -84,9 +84,9 @@ its read buffer is when it Unmarshal's data into supplied types.
Some tips for getting more performance from the driver:
* Use the TokenAware policy
* Use many goroutines when doing inserts, the driver is asynchronous but provides a synchronous api, it can execute many queries concurrently
* Use many goroutines when doing inserts, the driver is asynchronous but provides a synchronous API, it can execute many queries concurrently
* Tune query page size
* Reading data from the network to unmarshal will incur a large ammount of allocations, this can adversly affect the garbage collector, tune `GOGC`
* Reading data from the network to unmarshal will incur a large amount of allocations, this can adversely affect the garbage collector, tune `GOGC`
* Close iterators after use to recycle byte buffers
Important Default Keyspace Changes
@@ -189,7 +189,7 @@ There are various ways to bind application level data structures to CQL statemen
* [gocassa](https://github.com/hailocab/gocassa) is an external project that layers on top of gocql to provide convenient query building and data binding.
* [gocqltable](https://github.com/kristoiv/gocqltable) provides an ORM-style convenience layer to make CRUD operations with gocql easier.
Ecosphere
Ecosystem
---------
The following community maintained tools are known to integrate with gocql:
@@ -197,21 +197,21 @@ The following community maintained tools are known to integrate with gocql:
* [migrate](https://github.com/mattes/migrate) is a migration handling tool written in Go with Cassandra support.
* [negronicql](https://github.com/mikebthun/negronicql) is gocql middleware for Negroni.
* [cqlr](https://github.com/relops/cqlr) adds the ability to auto-bind a CQL iterator to a struct or to bind a struct to an INSERT statement.
* [cqlc](http://relops.com/cqlc) which generates gocql compliant code from your Cassandra schema so that you can write type safe CQL statements in Go with a natural query syntax.
* [cqlc](http://relops.com/cqlc) generates gocql compliant code from your Cassandra schema so that you can write type safe CQL statements in Go with a natural query syntax.
* [gocassa](https://github.com/hailocab/gocassa) provides query building, adds data binding, and provides easy-to-use "recipe" tables for common query use-cases.
* [gocqltable](https://github.com/kristoiv/gocqltable) is a wrapper around gocql that aims to simplify common operations whilst working the library.
* [gocqltable](https://github.com/kristoiv/gocqltable) is a wrapper around gocql that aims to simplify common operations.
* [gockle](https://github.com/willfaught/gockle) provides simple, mockable interfaces that wrap gocql types
* [scylladb](https://github.com/scylladb/scylla) is a fast Apache Cassandra-compatible NoSQL database
Other Projects
--------------
* [gocqldriver](https://github.com/tux21b/gocqldriver) is the predecessor of gocql based on Go's "database/sql" package. This project isn't maintained anymore, because Cassandra wasn't a good fit for the traditional "database/sql" API. Use this package instead.
* [gocqldriver](https://github.com/tux21b/gocqldriver) is the predecessor of gocql based on Go's `database/sql` package. This project isn't maintained anymore, because Cassandra wasn't a good fit for the traditional `database/sql` API. Use this package instead.
SEO
---
For some reason, when you google `golang cassandra`, this project doesn't feature very highly in the result list. But if you google `go cassandra`, then we're a bit higher up the list. So this is note to try to convince Google that Golang is an alias for Go.
For some reason, when you Google `golang cassandra`, this project doesn't feature very highly in the result list. But if you Google `go cassandra`, then we're a bit higher up the list. So this is note to try to convince Google that golang is an alias for Go.
License
-------

View File

@@ -22,27 +22,6 @@ func (p PoolConfig) buildPool(session *Session) *policyConnPool {
return newPolicyConnPool(session)
}
type DiscoveryConfig struct {
// If not empty will filter all discovered hosts to a single Data Centre (default: "")
DcFilter string
// If not empty will filter all discovered hosts to a single Rack (default: "")
RackFilter string
// ignored
Sleep time.Duration
}
func (d DiscoveryConfig) matchFilter(host *HostInfo) bool {
if d.DcFilter != "" && d.DcFilter != host.DataCenter() {
return false
}
if d.RackFilter != "" && d.RackFilter != host.Rack() {
return false
}
return true
}
// ClusterConfig is a struct to configure the default cluster implementation
// of gocoql. It has a variety of attributes that can be used to modify the
// behavior to fit the most common use cases. Applications that require a
@@ -70,8 +49,6 @@ type ClusterConfig struct {
// configuration of host selection and connection selection policies.
PoolConfig PoolConfig
Discovery DiscoveryConfig
// If not zero, gocql attempt to reconnect known DOWN nodes in every ReconnectSleep.
ReconnectInterval time.Duration

View File

@@ -192,12 +192,7 @@ func (s *Session) handleNewNode(host net.IP, port int, waitForBinary bool) {
hostInfo.setPeer(addr)
}
if s.cfg.HostFilter != nil {
if !s.cfg.HostFilter.Accept(hostInfo) {
return
}
} else if !s.cfg.Discovery.matchFilter(hostInfo) {
// TODO: remove this when the host selection policy is more sophisticated
if s.cfg.HostFilter != nil && !s.cfg.HostFilter.Accept(hostInfo) {
return
}
@@ -254,12 +249,7 @@ func (s *Session) handleNodeUp(ip net.IP, port int, waitForBinary bool) {
host.setPeer(addr)
}
if s.cfg.HostFilter != nil {
if !s.cfg.HostFilter.Accept(host) {
return
}
} else if !s.cfg.Discovery.matchFilter(host) {
// TODO: remove this when the host selection policy is more sophisticated
if s.cfg.HostFilter != nil && !s.cfg.HostFilter.Accept(host) {
return
}

View File

@@ -39,6 +39,8 @@ func goType(t TypeInfo) reflect.Type {
return reflect.TypeOf(*new(int))
case TypeSmallInt:
return reflect.TypeOf(*new(int16))
case TypeTinyInt:
return reflect.TypeOf(*new(int8))
case TypeDecimal:
return reflect.TypeOf(*new(*inf.Dec))
case TypeUUID, TypeTimeUUID:

View File

@@ -339,30 +339,25 @@ func (r *ringDescriber) GetHosts() (hosts []*HostInfo, partitioner string, err e
hosts = []*HostInfo{localHost}
iter := r.session.control.query("SELECT rpc_address, data_center, rack, host_id, tokens, release_version FROM system.peers")
if iter == nil {
rows := r.session.control.query("SELECT rpc_address, data_center, rack, host_id, tokens, release_version FROM system.peers").Scanner()
if rows == nil {
return r.prevHosts, r.prevPartitioner, nil
}
var (
host = &HostInfo{port: r.session.cfg.Port}
versionBytes []byte
)
for iter.Scan(&host.peer, &host.dataCenter, &host.rack, &host.hostId, &host.tokens, &versionBytes) {
if err = host.version.unmarshal(versionBytes); err != nil {
log.Printf("invalid peer entry: peer=%s host_id=%s tokens=%v version=%s\n", host.peer, host.hostId, host.tokens, versionBytes)
for rows.Next() {
host := &HostInfo{port: r.session.cfg.Port}
err := rows.Scan(&host.peer, &host.dataCenter, &host.rack, &host.hostId, &host.tokens, &host.version)
if err != nil {
log.Println(err)
continue
}
if r.matchFilter(host) {
hosts = append(hosts, host)
}
host = &HostInfo{
port: r.session.cfg.Port,
}
}
if err = iter.Close(); err != nil {
if err = rows.Err(); err != nil {
return nil, "", err
}

View File

@@ -31,7 +31,7 @@ import (
// whole Cassandra cluster.
//
// This type extends the Node interface by adding a convinient query builder
// and automatically sets a default consinstency level on all operations
// and automatically sets a default consistency level on all operations
// that do not have a consistency level set.
type Session struct {
cons Consistency
@@ -145,7 +145,6 @@ func NewSession(cfg ClusterConfig) (*Session, error) {
}
var hosts []*HostInfo
if !cfg.disableControlConn {
s.control = createControlConn(s)
if err := s.control.connect(cfg.Hosts); err != nil {
@@ -1041,6 +1040,128 @@ func (iter *Iter) Columns() []ColumnInfo {
return iter.meta.columns
}
type Scanner interface {
Next() bool
Scan(...interface{}) error
Err() error
}
type iterScanner struct {
iter *Iter
cols [][]byte
}
// Next advances the row pointer to point at the next row, the row is valid until
// the next call of Next. It returns true if there is a row which is available to be
// scanned into with Scan.
// Next must be called before every call to Scan.
func (is *iterScanner) Next() bool {
iter := is.iter
if iter.err != nil {
return false
}
if iter.pos >= iter.numRows {
if iter.next != nil {
is.iter = iter.next.fetch()
return is.Next()
}
return false
}
cols := make([][]byte, len(iter.meta.columns))
for i := 0; i < len(cols); i++ {
col, err := iter.readColumn()
if err != nil {
iter.err = err
return false
}
cols[i] = col
}
is.cols = cols
iter.pos++
return true
}
func scanColumn(p []byte, col ColumnInfo, dest []interface{}) (int, error) {
if dest[0] == nil {
return 1, nil
}
if col.TypeInfo.Type() == TypeTuple {
// this will panic, actually a bug, please report
tuple := col.TypeInfo.(TupleTypeInfo)
count := len(tuple.Elems)
// here we pass in a slice of the struct which has the number number of
// values as elements in the tuple
if err := Unmarshal(col.TypeInfo, p, dest[:count]); err != nil {
return 0, err
}
return count, nil
} else {
if err := Unmarshal(col.TypeInfo, p, dest[0]); err != nil {
return 0, err
}
return 1, nil
}
}
// Scan copies the current row's columns into dest. If the length of dest does not equal
// the number of columns returned in the row an error is returned. If an error is encountered
// when unmarshalling a column into the value in dest an error is returned and the row is invalidated
// until the next call to Next.
// Next must be called before calling Scan, if it is not an error is returned.
func (is *iterScanner) Scan(dest ...interface{}) error {
if is.cols == nil {
return errors.New("gocql: Scan called without calling Next")
}
iter := is.iter
// currently only support scanning into an expand tuple, such that its the same
// as scanning in more values from a single column
if len(dest) != iter.meta.actualColCount {
return fmt.Errorf("gocql: not enough columns to scan into: have %d want %d", len(dest), iter.meta.actualColCount)
}
// i is the current position in dest, could posible replace it and just use
// slices of dest
i := 0
var err error
for _, col := range iter.meta.columns {
var n int
n, err = scanColumn(is.cols[i], col, dest[i:])
if err != nil {
break
}
i += n
}
is.cols = nil
return err
}
// Err returns the if there was one during iteration that resulted in iteration being unable to complete.
// Err will also release resources held by the iterator and should not used after being called.
func (is *iterScanner) Err() error {
iter := is.iter
is.iter = nil
is.cols = nil
return iter.Close()
}
// Scanner returns a row Scanner which provides an interface to scan rows in a manner which is
// similar to database/sql. The iter should NOT be used again after calling this method.
func (iter *Iter) Scanner() Scanner {
if iter == nil {
return nil
}
return &iterScanner{iter: iter}
}
func (iter *Iter) readColumn() ([]byte, error) {
return iter.framer.readBytesInternal()
}
@@ -1080,37 +1201,19 @@ func (iter *Iter) Scan(dest ...interface{}) bool {
// i is the current position in dest, could posible replace it and just use
// slices of dest
i := 0
for c := range iter.meta.columns {
col := &iter.meta.columns[c]
for _, col := range iter.meta.columns {
colBytes, err := iter.readColumn()
if err != nil {
iter.err = err
return false
}
if dest[i] == nil {
i++
continue
}
switch col.TypeInfo.Type() {
case TypeTuple:
// this will panic, actually a bug, please report
tuple := col.TypeInfo.(TupleTypeInfo)
count := len(tuple.Elems)
// here we pass in a slice of the struct which has the number number of
// values as elements in the tuple
iter.err = Unmarshal(col.TypeInfo, colBytes, dest[i:i+count])
i += count
default:
iter.err = Unmarshal(col.TypeInfo, colBytes, dest[i])
i++
}
if iter.err != nil {
n, err := scanColumn(colBytes, col, dest[i:])
if err != nil {
iter.err = err
return false
}
i += n
}
iter.pos++
@@ -1454,7 +1557,7 @@ var (
ErrTooManyStmts = errors.New("too many statements")
ErrUseStmt = errors.New("use statements aren't supported. Please see https://github.com/gocql/gocql for explaination.")
ErrSessionClosed = errors.New("session has been closed")
ErrNoConnections = errors.New("qocql: no hosts available in the pool")
ErrNoConnections = errors.New("gocql: no hosts available in the pool")
ErrNoKeyspace = errors.New("no keyspace provided")
ErrNoMetadata = errors.New("no metadata available")
)

View File

@@ -45,6 +45,10 @@ func (e *Event) Payload() (payload interface{}) {
payload = &ForkEvent{}
case "GollumEvent":
payload = &GollumEvent{}
case "IntegrationInstallationEvent":
payload = &IntegrationInstallationEvent{}
case "IntegrationInstallationRepositoriesEvent":
payload = &IntegrationInstallationRepositoriesEvent{}
case "IssueActivityEvent":
payload = &IssueActivityEvent{}
case "IssueCommentEvent":

View File

@@ -146,6 +146,40 @@ type EditChange struct {
} `json:"body,omitempty"`
}
// IntegrationInstallationEvent is triggered when an integration is created or deleted.
// The Webhook event name is "integration_installation".
//
// GitHub docs: https://developer.github.com/early-access/integrations/webhooks/#integrationinstallationevent
type IntegrationInstallationEvent struct {
// The action that was performed. Possible values for an "integration_installation"
// event are: "created", "deleted".
Action *string `json:"action,omitempty"`
Installation *Installation `json:"installation,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// IntegrationInstallationRepositoriesEvent is triggered when an integration repository
// is added or removed. The Webhook event name is "integration_installation_repositories".
//
// GitHub docs: https://developer.github.com/early-access/integrations/webhooks/#integrationinstallationrepositoriesevent
type IntegrationInstallationRepositoriesEvent struct {
// The action that was performed. Possible values for an "integration_installation_repositories"
// event are: "added", "removed".
Action *string `json:"action,omitempty"`
Installation *Installation `json:"installation,omitempty"`
RepositoriesAdded []*Repository `json:"repositories_added,omitempty"`
RepositoriesRemoved []*Repository `json:"repositories_removed,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// Installation represents a GitHub integration installation.
type Installation struct {
ID *int `json:"id,omitempty"`
Account *User `json:"account,omitempty"`
AccessTokensURL *string `json:"access_tokens_url,omitempty"`
RepositoriesURL *string `json:"repositories_url,omitempty"`
}
// IssueCommentEvent is triggered when an issue comment is created on an issue
// or pull request.
// The Webhook event name is "issue_comment".

View File

@@ -14,6 +14,7 @@ import (
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"hash"
@@ -30,6 +31,37 @@ const (
sha512Prefix = "sha512"
// signatureHeader is the GitHub header key used to pass the HMAC hexdigest.
signatureHeader = "X-Hub-Signature"
// eventTypeHeader is the Github header key used to pass the event type.
eventTypeHeader = "X-Github-Event"
)
var (
// eventTypeMapping maps webhooks types to their corresponding go-github struct types.
eventTypeMapping = map[string]string{
"commit_comment": "CommitCommentEvent",
"create": "CreateEvent",
"delete": "DeleteEvent",
"deployment": "DeploymentEvent",
"deployment_status": "DeploymentStatusEvent",
"fork": "ForkEvent",
"gollum": "GollumEvent",
"integration_installation": "IntegrationInstallationEvent",
"integration_installation_repositories": "IntegrationInstallationRepositoriesEvent",
"issue_comment": "IssueCommentEvent",
"issues": "IssuesEvent",
"member": "MemberEvent",
"membership": "MembershipEvent",
"page_build": "PageBuildEvent",
"public": "PublicEvent",
"pull_request_review_comment": "PullRequestReviewCommentEvent",
"pull_request": "PullRequestEvent",
"push": "PushEvent",
"repository": "RepositoryEvent",
"release": "ReleaseEvent",
"status": "StatusEvent",
"team_add": "TeamAddEvent",
"watch": "WatchEvent",
}
)
// genMAC generates the HMAC signature for a message provided the secret key
@@ -117,3 +149,42 @@ func validateSignature(signature string, payload, secretKey []byte) error {
}
return nil
}
// WebHookType returns the event type of webhook request r.
func WebHookType(r *http.Request) string {
return r.Header.Get(eventTypeHeader)
}
// ParseWebHook parses the event payload. For recognized event types, a
// value of the corresponding struct type will be returned (as returned
// by Event.Payload()). An error will be returned for unrecognized event
// types.
//
// Example usage:
//
// func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// payload, err := github.ValidatePayload(r, s.webhookSecretKey)
// if err != nil { ... }
// event, err := github.ParseWebHook(github.WebHookType(r), payload)
// if err != nil { ... }
// switch event := event.(type) {
// case CommitCommentEvent:
// processCommitCommentEvent(event)
// case CreateEvent:
// processCreateEvent(event)
// ...
// }
// }
//
func ParseWebHook(messageType string, payload []byte) (interface{}, error) {
eventType, ok := eventTypeMapping[messageType]
if !ok {
return nil, fmt.Errorf("unknown X-Github-Event in message: %v", messageType)
}
event := Event{
Type: &eventType,
RawPayload: (*json.RawMessage)(&payload),
}
return event.Payload(), nil
}

View File

@@ -44,6 +44,7 @@ type PullRequest struct {
PatchURL *string `json:"patch_url,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Assignees []*User `json:"assignees,omitempty"`
Milestone *Milestone `json:"milestone,omitempty"`
Head *PullRequestBranch `json:"head,omitempty"`
Base *PullRequestBranch `json:"base,omitempty"`

View File

@@ -11,13 +11,35 @@ import (
// KVPair is used to represent a single K/V entry
type KVPair struct {
Key string
// Key is the name of the key. It is also part of the URL path when accessed
// via the API.
Key string
// CreateIndex holds the index corresponding the creation of this KVPair. This
// is a read-only field.
CreateIndex uint64
// ModifyIndex is used for the Check-And-Set operations and can also be fed
// back into the WaitIndex of the QueryOptions in order to perform blocking
// queries.
ModifyIndex uint64
LockIndex uint64
Flags uint64
Value []byte
Session string
// LockIndex holds the index corresponding to a lock on this key, if any. This
// is a read-only field.
LockIndex uint64
// Flags are any user-defined flags on the key. It is up to the implementer
// to check these values, since Consul does not treat them specially.
Flags uint64
// Value is the value for the key. This can be any value, but it will be
// base64 encoded upon transport.
Value []byte
// Session is a string representing the ID of the session. Any other
// interactions with this key over the same session must specify the same
// session ID.
Session string
}
// KVPairs is a list of KVPair objects

View File

@@ -32,8 +32,8 @@ import (
var (
// Default retry configuration
defaultRetryWaitMin = 1 * time.Second
defaultRetryWaitMax = 5 * time.Minute
defaultRetryMax = 32
defaultRetryWaitMax = 30 * time.Second
defaultRetryMax = 4
// defaultClient is used for performing requests without explicitly making
// a new client. It is purposely private to avoid modifications.

View File

@@ -6,6 +6,7 @@ fmt: generate
go fmt ./...
test: generate
go get -t ./...
go test $(TEST) $(TESTARGS)
generate:

View File

@@ -12,5 +12,8 @@ install:
go version
go env
go get -t ./...
build_script:
- cmd: go test -v ./...

View File

@@ -409,7 +409,6 @@ func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value)
if result.Kind() == reflect.Interface {
result = result.Elem()
}
// Create the slice if it isn't nil
resultType := result.Type()
resultElemType := resultType.Elem()
@@ -443,6 +442,12 @@ func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value)
// Decode
val := reflect.Indirect(reflect.New(resultElemType))
// if item is an object that was decoded from ambiguous JSON and
// flattened, make sure it's expanded if it needs to decode into a
// defined structure.
item := expandObject(item, val)
if err := d.decode(fieldName, item, val); err != nil {
return err
}
@@ -455,6 +460,57 @@ func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value)
return nil
}
// expandObject detects if an ambiguous JSON object was flattened to a List which
// should be decoded into a struct, and expands the ast to properly deocode.
func expandObject(node ast.Node, result reflect.Value) ast.Node {
item, ok := node.(*ast.ObjectItem)
if !ok {
return node
}
elemType := result.Type()
// our target type must be a struct
switch elemType.Kind() {
case reflect.Ptr:
switch elemType.Elem().Kind() {
case reflect.Struct:
//OK
default:
return node
}
case reflect.Struct:
//OK
default:
return node
}
// A list value will have a key and field name. If it had more fields,
// it wouldn't have been flattened.
if len(item.Keys) != 2 {
return node
}
keyToken := item.Keys[0].Token
item.Keys = item.Keys[1:]
// we need to un-flatten the ast enough to decode
newNode := &ast.ObjectItem{
Keys: []*ast.ObjectKey{
&ast.ObjectKey{
Token: keyToken,
},
},
Val: &ast.ObjectType{
List: &ast.ObjectList{
Items: []*ast.ObjectItem{item},
},
},
}
return newNode
}
func (d *decoder) decodeString(name string, node ast.Node, result reflect.Value) error {
switch n := node.(type) {
case *ast.LiteralType:
@@ -606,6 +662,7 @@ func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value)
// match (only object with the field), then we decode it exactly.
// If it is a prefix match, then we decode the matches.
filter := list.Filter(fieldName)
prefixMatches := filter.Children()
matches := filter.Elem()
if len(matches.Items) == 0 && len(prefixMatches.Items) == 0 {

View File

@@ -2,7 +2,6 @@ package colorable
import (
"bytes"
"fmt"
"io"
"math"
"os"
@@ -361,7 +360,8 @@ func (w *Writer) Write(data []byte) (n int, err error) {
var csbi consoleScreenBufferInfo
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
er := bytes.NewBuffer(data)
er := bytes.NewReader(data)
var bw [1]byte
loop:
for {
r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
@@ -369,32 +369,33 @@ loop:
break loop
}
c1, _, err := er.ReadRune()
c1, err := er.ReadByte()
if err != nil {
break loop
}
if c1 != 0x1b {
fmt.Fprint(w.out, string(c1))
bw[0] = c1
w.out.Write(bw[:])
continue
}
c2, _, err := er.ReadRune()
c2, err := er.ReadByte()
if err != nil {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteByte(c1)
break loop
}
if c2 != 0x5b {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
w.lastbuf.WriteByte(c1)
w.lastbuf.WriteByte(c2)
continue
}
var buf bytes.Buffer
var m rune
var m byte
for {
c, _, err := er.ReadRune()
c, err := er.ReadByte()
if err != nil {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
w.lastbuf.WriteByte(c1)
w.lastbuf.WriteByte(c2)
w.lastbuf.Write(buf.Bytes())
break loop
}
@@ -466,7 +467,7 @@ loop:
continue
}
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
csbi.cursorPosition.x = short(n-1)
csbi.cursorPosition.x = short(n - 1)
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
case 'H':
token := strings.Split(buf.String(), ";")
@@ -481,8 +482,8 @@ loop:
if err != nil {
continue
}
csbi.cursorPosition.x = short(n2-1)
csbi.cursorPosition.y = short(n1-1)
csbi.cursorPosition.x = short(n2 - 1)
csbi.cursorPosition.y = short(n1 - 1)
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
case 'J':
n, err := strconv.Atoi(buf.String())

View File

@@ -2,7 +2,6 @@ package colorable
import (
"bytes"
"fmt"
"io"
)
@@ -16,34 +15,36 @@ func NewNonColorable(w io.Writer) io.Writer {
}
func (w *NonColorable) Write(data []byte) (n int, err error) {
er := bytes.NewBuffer(data)
er := bytes.NewReader(data)
var bw [1]byte
loop:
for {
c1, _, err := er.ReadRune()
c1, err := er.ReadByte()
if err != nil {
break loop
}
if c1 != 0x1b {
fmt.Fprint(w.out, string(c1))
bw[0] = c1
w.out.Write(bw[:])
continue
}
c2, _, err := er.ReadRune()
c2, err := er.ReadByte()
if err != nil {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteByte(c1)
break loop
}
if c2 != 0x5b {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
w.lastbuf.WriteByte(c1)
w.lastbuf.WriteByte(c2)
continue
}
var buf bytes.Buffer
for {
c, _, err := er.ReadRune()
c, err := er.ReadByte()
if err != nil {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
w.lastbuf.WriteByte(c1)
w.lastbuf.WriteByte(c2)
w.lastbuf.Write(buf.Bytes())
break loop
}

View File

@@ -1,6 +1,7 @@
package copystructure
import (
"errors"
"reflect"
"sync"
@@ -27,6 +28,8 @@ type CopierFunc func(interface{}) (interface{}, error)
// this map as well as to Copy in a mutex.
var Copiers map[reflect.Type]CopierFunc = make(map[reflect.Type]CopierFunc)
var errPointerRequired = errors.New("Copy argument must be a pointer when Lock is true")
type Config struct {
// Lock any types that are a sync.Locker and are not a mutex while copying.
// If there is an RLocker method, use that to get the sync.Locker.
@@ -38,6 +41,10 @@ type Config struct {
}
func (c Config) Copy(v interface{}) (interface{}, error) {
if c.Lock && reflect.ValueOf(v).Kind() != reflect.Ptr {
return nil, errPointerRequired
}
w := new(walker)
if c.Lock {
w.useLocks = true
@@ -288,12 +295,24 @@ func (w *walker) StructField(f reflect.StructField, v reflect.Value) error {
return nil
}
// If PkgPath is non-empty, this is a private (unexported) field.
// We do not set this unexported since the Go runtime doesn't allow us.
if f.PkgPath != "" {
w.ignore()
return nil
}
// Push the field onto the stack, we'll handle it when we exit
// the struct field in Exit...
w.valPush(reflect.ValueOf(f))
return nil
}
// ignore causes the walker to ignore any more values until we exit this on
func (w *walker) ignore() {
w.ignoreDepth = w.depth
}
func (w *walker) ignoring() bool {
return w.ignoreDepth > 0 && w.depth >= w.ignoreDepth
}
@@ -350,19 +369,20 @@ func (w *walker) lock(v reflect.Value) {
var locker sync.Locker
// first check if we can get a locker from the value
switch l := v.Interface().(type) {
case rlocker:
// don't lock a mutex directly
if _, ok := l.(*sync.RWMutex); !ok {
locker = l.RLocker()
// We can't call Interface() on a value directly, since that requires
// a copy. This is OK, since the pointer to a value which is a sync.Locker
// is also a sync.Locker.
if v.Kind() == reflect.Ptr {
switch l := v.Interface().(type) {
case rlocker:
// don't lock a mutex directly
if _, ok := l.(*sync.RWMutex); !ok {
locker = l.RLocker()
}
case sync.Locker:
locker = l
}
case sync.Locker:
locker = l
}
// the value itself isn't a locker, so check the method on a pointer too
if locker == nil && v.CanAddr() {
} else if v.CanAddr() {
switch l := v.Addr().Interface().(type) {
case rlocker:
// don't lock a mutex directly

View File

@@ -4,9 +4,7 @@
// those elements.
package reflectwalk
import (
"reflect"
)
import "reflect"
// PrimitiveWalker implementations are able to handle primitive values
// within complex structures. Primitive values are numbers, strings,
@@ -79,10 +77,26 @@ func Walk(data, walker interface{}) (err error) {
func walk(v reflect.Value, w interface{}) (err error) {
// Determine if we're receiving a pointer and if so notify the walker.
// The logic here is convoluted but very important (tests will fail if
// almost any part is changed). I will try to explain here.
//
// First, we check if the value is an interface, if so, we really need
// to check the interface's VALUE to see whether it is a pointer (pointers
// to interfaces are not allowed).
//
// Check whether the value is then an interface. If so, then set pointer
// to true to notify the user.
//
// At this time, we also set "v" to be the dereferenced value. This is
// because once we've unwrapped the pointer we want to use that value.
pointer := false
if v.Kind() == reflect.Ptr {
pointerV := v
if pointerV.Kind() == reflect.Interface {
pointerV = pointerV.Elem()
}
if pointerV.Kind() == reflect.Ptr {
pointer = true
v = reflect.Indirect(v)
v = reflect.Indirect(pointerV)
}
if pw, ok := w.(PointerWalker); ok {
if err = pw.PointerEnter(pointer); err != nil {

View File

@@ -1,4 +1,4 @@
MIT LICENSE
Copyright (c) 2016 Ryan Uber
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) [2016] [Seth Ammons]
Copyright (c) SendGrid 2016
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -163,6 +163,15 @@ type DecodeOptions struct {
// Note: Handles will be smart when using the intern functionality.
// So everything will not be interned.
InternString bool
// PreferArrayOverSlice controls whether to decode to an array or a slice.
//
// This only impacts decoding into a nil interface{}.
// Consequently, it has no effect on codecgen.
//
// *Note*: This only applies if using go1.5 and above,
// as it requires reflect.ArrayOf support which was absent before go1.5.
PreferArrayOverSlice bool
}
// ------------------------------------
@@ -611,8 +620,11 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
n.ss = append(n.ss, nil)
var v2 interface{} = &n.ss[l]
d.decode(v2)
rvn = reflect.ValueOf(v2).Elem()
n.ss = n.ss[:l]
rvn = reflect.ValueOf(v2).Elem()
if reflectArrayOfSupported && d.stid == 0 && d.h.PreferArrayOverSlice {
rvn = reflectArrayOf(rvn)
}
} else {
rvn = reflect.New(d.h.SliceType).Elem()
d.decodeValue(rvn, nil)

16
vendor/github.com/ugorji/go/codec/decode_go.go generated vendored Normal file
View File

@@ -0,0 +1,16 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.5
package codec
import "reflect"
const reflectArrayOfSupported = true
func reflectArrayOf(rvn reflect.Value) (rvn2 reflect.Value) {
rvn2 = reflect.New(reflect.ArrayOf(rvn.Len(), intfTyp)).Elem()
reflect.Copy(rvn2, rvn)
return
}

14
vendor/github.com/ugorji/go/codec/decode_go14.go generated vendored Normal file
View File

@@ -0,0 +1,14 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build !go1.5
package codec
import "reflect"
const reflectArrayOfSupported = false
func reflectArrayOf(rvn reflect.Value) (rvn2 reflect.Value) {
panic("reflect.ArrayOf unsupported")
}

View File

@@ -1,4 +1,4 @@
// //+build ignore
// // +build ignore
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.

View File

@@ -1,4 +1,4 @@
// //+build ignore
// // +build ignore
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.

View File

@@ -212,7 +212,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn
x.genRefPkgs(t)
}
if buildTags != "" {
x.line("//+build " + buildTags)
x.line("// +build " + buildTags)
x.line("")
}
x.line(`

View File

@@ -1,4 +1,4 @@
//+build !unsafe
// +build !unsafe
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.

View File

@@ -1,4 +1,4 @@
//+build unsafe
// +build unsafe
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.

View File

@@ -197,12 +197,20 @@ func (e *jsonEncDriver) EncodeBool(b bool) {
}
func (e *jsonEncDriver) EncodeFloat32(f float32) {
e.w.writeb(strconv.AppendFloat(e.b[:0], float64(f), 'E', -1, 32))
e.encodeFloat(float64(f), 32)
}
func (e *jsonEncDriver) EncodeFloat64(f float64) {
// e.w.writestr(strconv.FormatFloat(f, 'E', -1, 64))
e.w.writeb(strconv.AppendFloat(e.b[:0], f, 'E', -1, 64))
e.encodeFloat(f, 64)
}
func (e *jsonEncDriver) encodeFloat(f float64, numbits int) {
x := strconv.AppendFloat(e.b[:0], f, 'G', -1, numbits)
e.w.writeb(x)
if bytes.IndexByte(x, 'E') == -1 && bytes.IndexByte(x, '.') == -1 {
e.w.writen2('.', '0')
}
}
func (e *jsonEncDriver) EncodeInt(v int64) {

View File

@@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"sync"
"time"
"golang.org/x/crypto/ssh"
)
@@ -18,6 +19,7 @@ import (
type privKey struct {
signer ssh.Signer
comment string
expire *time.Time
}
type keyring struct {
@@ -48,15 +50,9 @@ func (r *keyring) RemoveAll() error {
return nil
}
// Remove removes all identities with the given public key.
func (r *keyring) Remove(key ssh.PublicKey) error {
r.mu.Lock()
defer r.mu.Unlock()
if r.locked {
return errLocked
}
want := key.Marshal()
// removeLocked does the actual key removal. The caller must already be holding the
// keyring mutex.
func (r *keyring) removeLocked(want []byte) error {
found := false
for i := 0; i < len(r.keys); {
if bytes.Equal(r.keys[i].signer.PublicKey().Marshal(), want) {
@@ -75,7 +71,18 @@ func (r *keyring) Remove(key ssh.PublicKey) error {
return nil
}
// Lock locks the agent. Sign and Remove will fail, and List will empty an empty list.
// Remove removes all identities with the given public key.
func (r *keyring) Remove(key ssh.PublicKey) error {
r.mu.Lock()
defer r.mu.Unlock()
if r.locked {
return errLocked
}
return r.removeLocked(key.Marshal())
}
// Lock locks the agent. Sign and Remove will fail, and List will return an empty list.
func (r *keyring) Lock(passphrase []byte) error {
r.mu.Lock()
defer r.mu.Unlock()
@@ -104,6 +111,17 @@ func (r *keyring) Unlock(passphrase []byte) error {
return nil
}
// expireKeysLocked removes expired keys from the keyring. If a key was added
// with a lifetimesecs contraint and seconds >= lifetimesecs seconds have
// ellapsed, it is removed. The caller *must* be holding the keyring mutex.
func (r *keyring) expireKeysLocked() {
for _, k := range r.keys {
if k.expire != nil && time.Now().After(*k.expire) {
r.removeLocked(k.signer.PublicKey().Marshal())
}
}
}
// List returns the identities known to the agent.
func (r *keyring) List() ([]*Key, error) {
r.mu.Lock()
@@ -113,6 +131,7 @@ func (r *keyring) List() ([]*Key, error) {
return nil, nil
}
r.expireKeysLocked()
var ids []*Key
for _, k := range r.keys {
pub := k.signer.PublicKey()
@@ -146,7 +165,17 @@ func (r *keyring) Add(key AddedKey) error {
}
}
r.keys = append(r.keys, privKey{signer, key.Comment})
p := privKey{
signer: signer,
comment: key.Comment,
}
if key.LifetimeSecs > 0 {
t := time.Now().Add(time.Duration(key.LifetimeSecs) * time.Second)
p.expire = &t
}
r.keys = append(r.keys, p)
return nil
}
@@ -159,6 +188,7 @@ func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
return nil, errLocked
}
r.expireKeysLocked()
wanted := key.Marshal()
for _, k := range r.keys {
if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) {
@@ -176,6 +206,7 @@ func (r *keyring) Signers() ([]ssh.Signer, error) {
return nil, errLocked
}
r.expireKeysLocked()
s := make([]ssh.Signer, 0, len(r.keys))
for _, k := range r.keys {
s = append(s, k.signer)

View File

@@ -371,7 +371,16 @@ func (t *handshakeTransport) enterKeyExchangeLocked(otherInitPacket []byte) erro
}
// We don't send FirstKexFollows, but we handle receiving it.
if otherInit.FirstKexFollows && algs.kex != otherInit.KexAlgos[0] {
//
// RFC 4253 section 7 defines the kex and the agreement method for
// first_kex_packet_follows. It states that the guessed packet
// should be ignored if the "kex algorithm and/or the host
// key algorithm is guessed wrong (server and client have
// different preferred algorithm), or if any of the other
// algorithms cannot be agreed upon". The other algorithms have
// already been checked above so the kex algorithm and host key
// algorithm are checked here.
if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) {
// other side sent a kex message for the wrong algorithm,
// which we have to ignore.
if _, err := t.conn.readPacket(); err != nil {

View File

@@ -731,6 +731,14 @@ func ParsePrivateKey(pemBytes []byte) (Signer, error) {
return NewSignerFromKey(key)
}
// encryptedBlock tells whether a private key is
// encrypted by examining its Proc-Type header
// for a mention of ENCRYPTED
// according to RFC 1421 Section 4.6.1.1.
func encryptedBlock(block *pem.Block) bool {
return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
}
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys.
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
@@ -739,6 +747,10 @@ func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
return nil, errors.New("ssh: no key found")
}
if encryptedBlock(block) {
return nil, errors.New("ssh: cannot decode encrypted private keys")
}
switch block.Type {
case "RSA PRIVATE KEY":
return x509.ParsePKCS1PrivateKey(block.Bytes)

View File

@@ -737,7 +737,7 @@ func (f *Framer) WriteSettings(settings ...Setting) error {
return f.endWrite()
}
// WriteSettings writes an empty SETTINGS frame with the ACK bit set.
// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.
//
// It will perform exactly one Write to the underlying Writer.
// It is the caller's responsibility to not call other Write methods concurrently.

View File

@@ -39,6 +39,13 @@ type clientTrace httptrace.ClientTrace
func reqContext(r *http.Request) context.Context { return r.Context() }
func (t *Transport) idleConnTimeout() time.Duration {
if t.t1 != nil {
return t.t1.IdleConnTimeout
}
return 0
}
func setResponseUncompressed(res *http.Response) { res.Uncompressed = true }
func traceGotConn(req *http.Request, cc *ClientConn) {
@@ -92,3 +99,8 @@ func requestTrace(req *http.Request) *clientTrace {
trace := httptrace.ContextClientTrace(req.Context())
return (*clientTrace)(trace)
}
// Ping sends a PING frame to the server and waits for the ack.
func (cc *ClientConn) Ping(ctx context.Context) error {
return cc.ping(ctx)
}

View File

@@ -57,7 +57,7 @@ func (hf HeaderField) String() string {
return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
}
// Size returns the size of an entry per RFC 7540 section 5.2.
// Size returns the size of an entry per RFC 7541 section 4.1.
func (hf HeaderField) Size() uint32 {
// http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
// "The size of the dynamic table is the sum of the size of

View File

@@ -343,7 +343,7 @@ func (s *sorter) Keys(h http.Header) []string {
}
func (s *sorter) SortStrings(ss []string) {
// Our sorter works on s.v, which sorter owners, so
// Our sorter works on s.v, which sorter owns, so
// stash it away while we sort the user's buffer.
save := s.v
s.v = ss
@@ -352,11 +352,14 @@ func (s *sorter) SortStrings(ss []string) {
}
// validPseudoPath reports whether v is a valid :path pseudo-header
// value. It must be a non-empty string starting with '/', and not
// start with two slashes.
// value. It must be either:
//
// *) a non-empty string starting with '/', but not with with "//",
// *) the string '*', for OPTIONS requests.
//
// For now this is only used a quick check for deciding when to clean
// up Opaque URLs before sending requests from the Transport.
// See golang.org/issue/16847
func validPseudoPath(v string) bool {
return len(v) > 0 && v[0] == '/' && (len(v) == 1 || v[1] != '/')
return (len(v) > 0 && v[0] == '/' && (len(v) == 1 || v[1] != '/')) || v == "*"
}

View File

@@ -10,9 +10,13 @@ import (
"crypto/tls"
"net"
"net/http"
"time"
)
type contextContext interface{}
type contextContext interface {
Done() <-chan struct{}
Err() error
}
type fakeContext struct{}
@@ -75,3 +79,9 @@ func cloneTLSConfig(c *tls.Config) *tls.Config {
CurvePreferences: c.CurvePreferences,
}
}
func (cc *ClientConn) Ping(ctx contextContext) error {
return cc.ping(ctx)
}
func (t *Transport) idleConnTimeout() time.Duration { return 0 }

View File

@@ -10,6 +10,7 @@ import (
"bufio"
"bytes"
"compress/gzip"
"crypto/rand"
"crypto/tls"
"errors"
"fmt"
@@ -26,6 +27,7 @@ import (
"time"
"golang.org/x/net/http2/hpack"
"golang.org/x/net/idna"
"golang.org/x/net/lex/httplex"
)
@@ -149,6 +151,9 @@ type ClientConn struct {
readerDone chan struct{} // closed on error
readerErr error // set before readerDone is closed
idleTimeout time.Duration // or 0 for never
idleTimer *time.Timer
mu sync.Mutex // guards following
cond *sync.Cond // hold mu; broadcast on flow/closed changes
flow flow // our conn-level flow control quota (cs.flow is per stream)
@@ -159,6 +164,7 @@ type ClientConn struct {
goAwayDebug string // goAway frame's debug data, retained as a string
streams map[uint32]*clientStream // client-initiated
nextStreamID uint32
pings map[[8]byte]chan struct{} // in flight ping data to notification channel
bw *bufio.Writer
br *bufio.Reader
fr *Framer
@@ -285,14 +291,18 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
// and returns a host:port. The port 443 is added if needed.
func authorityAddr(scheme string, authority string) (addr string) {
if _, _, err := net.SplitHostPort(authority); err == nil {
return authority
host, port, err := net.SplitHostPort(authority)
if err != nil { // authority didn't have a port
port = "443"
if scheme == "http" {
port = "80"
}
host = authority
}
port := "443"
if scheme == "http" {
port = "80"
if a, err := idna.ToASCII(host); err == nil {
host = a
}
return net.JoinHostPort(authority, port)
return net.JoinHostPort(host, port)
}
// RoundTripOpt is like RoundTrip, but takes options.
@@ -426,6 +436,11 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
streams: make(map[uint32]*clientStream),
singleUse: singleUse,
wantSettingsAck: true,
pings: make(map[[8]byte]chan struct{}),
}
if d := t.idleConnTimeout(); d != 0 {
cc.idleTimeout = d
cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
}
if VerboseLogs {
t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
@@ -503,6 +518,16 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool {
cc.nextStreamID < math.MaxInt32
}
// onIdleTimeout is called from a time.AfterFunc goroutine. It will
// only be called when we're idle, but because we're coming from a new
// goroutine, there could be a new request coming in at the same time,
// so this simply calls the synchronized closeIfIdle to shut down this
// connection. The timer could just call closeIfIdle, but this is more
// clear.
func (cc *ClientConn) onIdleTimeout() {
cc.closeIfIdle()
}
func (cc *ClientConn) closeIfIdle() {
cc.mu.Lock()
if len(cc.streams) > 0 {
@@ -644,6 +669,9 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
if err := checkConnHeaders(req); err != nil {
return nil, err
}
if cc.idleTimer != nil {
cc.idleTimer.Stop()
}
trailers, err := commaSeparatedTrailers(req)
if err != nil {
@@ -651,9 +679,6 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
}
hasTrailers := trailers != ""
body, contentLen := bodyAndLength(req)
hasBody := body != nil
cc.mu.Lock()
cc.lastActive = time.Now()
if cc.closed || !cc.canTakeNewRequestLocked() {
@@ -661,6 +686,9 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
return nil, errClientConnUnusable
}
body, contentLen := bodyAndLength(req)
hasBody := body != nil
// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
var requestedGzip bool
if !cc.t.disableCompression() &&
@@ -997,6 +1025,10 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
if host == "" {
host = req.URL.Host
}
host, err := httplex.PunycodeHostPort(host)
if err != nil {
return nil, err
}
var path string
if req.Method != "CONNECT" {
@@ -1037,7 +1069,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
cc.writeHeader(":method", req.Method)
if req.Method != "CONNECT" {
cc.writeHeader(":path", path)
cc.writeHeader(":scheme", "https")
cc.writeHeader(":scheme", req.URL.Scheme)
}
if trailers != "" {
cc.writeHeader("trailer", trailers)
@@ -1164,6 +1196,9 @@ func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
if andRemove && cs != nil && !cc.closed {
cc.lastActive = time.Now()
delete(cc.streams, id)
if len(cc.streams) == 0 && cc.idleTimer != nil {
cc.idleTimer.Reset(cc.idleTimeout)
}
close(cs.done)
cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
}
@@ -1220,6 +1255,10 @@ func (rl *clientConnReadLoop) cleanup() {
defer cc.t.connPool().MarkDead(cc)
defer close(cc.readerDone)
if cc.idleTimer != nil {
cc.idleTimer.Stop()
}
// Close any response bodies if the server closes prematurely.
// TODO: also do this if we've written the headers but not
// gotten a response yet.
@@ -1806,10 +1845,56 @@ func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {
return nil
}
// Ping sends a PING frame to the server and waits for the ack.
// Public implementation is in go17.go and not_go17.go
func (cc *ClientConn) ping(ctx contextContext) error {
c := make(chan struct{})
// Generate a random payload
var p [8]byte
for {
if _, err := rand.Read(p[:]); err != nil {
return err
}
cc.mu.Lock()
// check for dup before insert
if _, found := cc.pings[p]; !found {
cc.pings[p] = c
cc.mu.Unlock()
break
}
cc.mu.Unlock()
}
cc.wmu.Lock()
if err := cc.fr.WritePing(false, p); err != nil {
cc.wmu.Unlock()
return err
}
if err := cc.bw.Flush(); err != nil {
cc.wmu.Unlock()
return err
}
cc.wmu.Unlock()
select {
case <-c:
return nil
case <-ctx.Done():
return ctx.Err()
case <-cc.readerDone:
// connection closed
return cc.readerErr
}
}
func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
if f.IsAck() {
// 6.7 PING: " An endpoint MUST NOT respond to PING frames
// containing this flag."
cc := rl.cc
cc.mu.Lock()
defer cc.mu.Unlock()
// If ack, notify listener if any
if c, ok := cc.pings[f.Data]; ok {
close(c)
delete(cc.pings, f.Data)
}
return nil
}
cc := rl.cc

68
vendor/golang.org/x/net/idna/idna.go generated vendored Normal file
View File

@@ -0,0 +1,68 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package idna implements IDNA2008 (Internationalized Domain Names for
// Applications), defined in RFC 5890, RFC 5891, RFC 5892, RFC 5893 and
// RFC 5894.
package idna // import "golang.org/x/net/idna"
import (
"strings"
"unicode/utf8"
)
// TODO(nigeltao): specify when errors occur. For example, is ToASCII(".") or
// ToASCII("foo\x00") an error? See also http://www.unicode.org/faq/idn.html#11
// acePrefix is the ASCII Compatible Encoding prefix.
const acePrefix = "xn--"
// ToASCII converts a domain or domain label to its ASCII form. For example,
// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
// ToASCII("golang") is "golang".
func ToASCII(s string) (string, error) {
if ascii(s) {
return s, nil
}
labels := strings.Split(s, ".")
for i, label := range labels {
if !ascii(label) {
a, err := encode(acePrefix, label)
if err != nil {
return "", err
}
labels[i] = a
}
}
return strings.Join(labels, "."), nil
}
// ToUnicode converts a domain or domain label to its Unicode form. For example,
// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
// ToUnicode("golang") is "golang".
func ToUnicode(s string) (string, error) {
if !strings.Contains(s, acePrefix) {
return s, nil
}
labels := strings.Split(s, ".")
for i, label := range labels {
if strings.HasPrefix(label, acePrefix) {
u, err := decode(label[len(acePrefix):])
if err != nil {
return "", err
}
labels[i] = u
}
}
return strings.Join(labels, "."), nil
}
func ascii(s string) bool {
for i := 0; i < len(s); i++ {
if s[i] >= utf8.RuneSelf {
return false
}
}
return true
}

200
vendor/golang.org/x/net/idna/punycode.go generated vendored Normal file
View File

@@ -0,0 +1,200 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package idna
// This file implements the Punycode algorithm from RFC 3492.
import (
"fmt"
"math"
"strings"
"unicode/utf8"
)
// These parameter values are specified in section 5.
//
// All computation is done with int32s, so that overflow behavior is identical
// regardless of whether int is 32-bit or 64-bit.
const (
base int32 = 36
damp int32 = 700
initialBias int32 = 72
initialN int32 = 128
skew int32 = 38
tmax int32 = 26
tmin int32 = 1
)
// decode decodes a string as specified in section 6.2.
func decode(encoded string) (string, error) {
if encoded == "" {
return "", nil
}
pos := 1 + strings.LastIndex(encoded, "-")
if pos == 1 {
return "", fmt.Errorf("idna: invalid label %q", encoded)
}
if pos == len(encoded) {
return encoded[:len(encoded)-1], nil
}
output := make([]rune, 0, len(encoded))
if pos != 0 {
for _, r := range encoded[:pos-1] {
output = append(output, r)
}
}
i, n, bias := int32(0), initialN, initialBias
for pos < len(encoded) {
oldI, w := i, int32(1)
for k := base; ; k += base {
if pos == len(encoded) {
return "", fmt.Errorf("idna: invalid label %q", encoded)
}
digit, ok := decodeDigit(encoded[pos])
if !ok {
return "", fmt.Errorf("idna: invalid label %q", encoded)
}
pos++
i += digit * w
if i < 0 {
return "", fmt.Errorf("idna: invalid label %q", encoded)
}
t := k - bias
if t < tmin {
t = tmin
} else if t > tmax {
t = tmax
}
if digit < t {
break
}
w *= base - t
if w >= math.MaxInt32/base {
return "", fmt.Errorf("idna: invalid label %q", encoded)
}
}
x := int32(len(output) + 1)
bias = adapt(i-oldI, x, oldI == 0)
n += i / x
i %= x
if n > utf8.MaxRune || len(output) >= 1024 {
return "", fmt.Errorf("idna: invalid label %q", encoded)
}
output = append(output, 0)
copy(output[i+1:], output[i:])
output[i] = n
i++
}
return string(output), nil
}
// encode encodes a string as specified in section 6.3 and prepends prefix to
// the result.
//
// The "while h < length(input)" line in the specification becomes "for
// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
func encode(prefix, s string) (string, error) {
output := make([]byte, len(prefix), len(prefix)+1+2*len(s))
copy(output, prefix)
delta, n, bias := int32(0), initialN, initialBias
b, remaining := int32(0), int32(0)
for _, r := range s {
if r < 0x80 {
b++
output = append(output, byte(r))
} else {
remaining++
}
}
h := b
if b > 0 {
output = append(output, '-')
}
for remaining != 0 {
m := int32(0x7fffffff)
for _, r := range s {
if m > r && r >= n {
m = r
}
}
delta += (m - n) * (h + 1)
if delta < 0 {
return "", fmt.Errorf("idna: invalid label %q", s)
}
n = m
for _, r := range s {
if r < n {
delta++
if delta < 0 {
return "", fmt.Errorf("idna: invalid label %q", s)
}
continue
}
if r > n {
continue
}
q := delta
for k := base; ; k += base {
t := k - bias
if t < tmin {
t = tmin
} else if t > tmax {
t = tmax
}
if q < t {
break
}
output = append(output, encodeDigit(t+(q-t)%(base-t)))
q = (q - t) / (base - t)
}
output = append(output, encodeDigit(q))
bias = adapt(delta, h+1, h == b)
delta = 0
h++
remaining--
}
delta++
n++
}
return string(output), nil
}
func decodeDigit(x byte) (digit int32, ok bool) {
switch {
case '0' <= x && x <= '9':
return int32(x - ('0' - 26)), true
case 'A' <= x && x <= 'Z':
return int32(x - 'A'), true
case 'a' <= x && x <= 'z':
return int32(x - 'a'), true
}
return 0, false
}
func encodeDigit(digit int32) byte {
switch {
case 0 <= digit && digit < 26:
return byte(digit + 'a')
case 26 <= digit && digit < 36:
return byte(digit + ('0' - 26))
}
panic("idna: internal error in punycode encoding")
}
// adapt is the bias adaptation function specified in section 6.1.
func adapt(delta, numPoints int32, firstTime bool) int32 {
if firstTime {
delta /= damp
} else {
delta /= 2
}
delta += delta / numPoints
k := int32(0)
for delta > ((base-tmin)*tmax)/2 {
delta /= base - tmin
k += base
}
return k + (base-tmin+1)*delta/(delta+skew)
}

View File

@@ -10,8 +10,11 @@
package httplex
import (
"net"
"strings"
"unicode/utf8"
"golang.org/x/net/idna"
)
var isTokenTable = [127]bool{
@@ -310,3 +313,39 @@ func ValidHeaderFieldValue(v string) bool {
}
return true
}
func isASCII(s string) bool {
for i := 0; i < len(s); i++ {
if s[i] >= utf8.RuneSelf {
return false
}
}
return true
}
// PunycodeHostPort returns the IDNA Punycode version
// of the provided "host" or "host:port" string.
func PunycodeHostPort(v string) (string, error) {
if isASCII(v) {
return v, nil
}
host, port, err := net.SplitHostPort(v)
if err != nil {
// The input 'v' argument was just a "host" argument,
// without a port. This error should not be returned
// to the caller.
host = v
port = ""
}
host, err = idna.ToASCII(host)
if err != nil {
// Non-UTF-8? Not representable in Punycode, in any
// case.
return "", err
}
if port == "" {
return host, nil
}
return net.JoinHostPort(host, port), nil
}

View File

@@ -72,18 +72,20 @@ func ParseDirent(buf []byte, max int, names []string) (consumed int, count int,
return origlen - len(buf), count, names
}
func pipe() (r uintptr, w uintptr, err uintptr)
//sysnb pipe(p *[2]_C_int) (n int, err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
r0, w0, e1 := pipe()
if e1 != 0 {
err = syscall.Errno(e1)
var pp [2]_C_int
n, err := pipe(&pp)
if n != 0 {
return err
}
p[0], p[1] = int(r0), int(w0)
return
p[0] = int(pp[0])
p[1] = int(pp[1])
return nil
}
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
@@ -269,24 +271,34 @@ func (w WaitStatus) StopSignal() syscall.Signal {
func (w WaitStatus) TrapCause() int { return -1 }
func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
//sys wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error)
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
if e1 != 0 {
err = syscall.Errno(e1)
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (int, error) {
var status _C_int
rpid, err := wait4(int32(pid), &status, options, rusage)
wpid := int(rpid)
if wpid == -1 {
return wpid, err
}
return int(r0), err
if wstatus != nil {
*wstatus = WaitStatus(status)
}
return wpid, nil
}
func gethostname() (name string, err uintptr)
//sys gethostname(buf []byte) (n int, err error)
func Gethostname() (name string, err error) {
name, e1 := gethostname()
if e1 != 0 {
err = syscall.Errno(e1)
var buf [MaxHostNameLen]byte
n, err := gethostname(buf[:])
if n != 0 {
return "", err
}
return name, err
n = clen(buf[:])
if n < 1 {
return "", EFAULT
}
return string(buf[:n]), nil
}
//sys utimes(path string, times *[2]Timeval) (err error)

View File

@@ -22,6 +22,7 @@ package unix
#define __USE_LEGACY_PROTOTYPES__ // iovec
#include <dirent.h>
#include <fcntl.h>
#include <netdb.h>
#include <limits.h>
#include <signal.h>
#include <termios.h>
@@ -81,6 +82,7 @@ const (
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
PathMax = C.PATH_MAX
MaxHostNameLen = C.MAXHOSTNAMELEN
)
// Basic types

View File

@@ -10,10 +10,13 @@ import (
"unsafe"
)
//go:cgo_import_dynamic libc_pipe pipe "libc.so"
//go:cgo_import_dynamic libc_getsockname getsockname "libsocket.so"
//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
//go:cgo_import_dynamic libc_gethostname gethostname "libc.so"
//go:cgo_import_dynamic libc_utimes utimes "libc.so"
//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
@@ -125,10 +128,13 @@ import (
//go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so"
//go:cgo_import_dynamic libc_sysconf sysconf "libc.so"
//go:linkname procpipe libc_pipe
//go:linkname procgetsockname libc_getsockname
//go:linkname procGetcwd libc_getcwd
//go:linkname procgetgroups libc_getgroups
//go:linkname procsetgroups libc_setgroups
//go:linkname procwait4 libc_wait4
//go:linkname procgethostname libc_gethostname
//go:linkname procutimes libc_utimes
//go:linkname procutimensat libc_utimensat
//go:linkname procfcntl libc_fcntl
@@ -241,10 +247,13 @@ import (
//go:linkname procsysconf libc_sysconf
var (
procpipe,
procgetsockname,
procGetcwd,
procgetgroups,
procsetgroups,
procwait4,
procgethostname,
procutimes,
procutimensat,
procfcntl,
@@ -357,6 +366,15 @@ var (
procsysconf syscallFunc
)
func pipe(p *[2]_C_int) (n int, err error) {
r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe)), 1, uintptr(unsafe.Pointer(p)), 0, 0, 0, 0, 0)
n = int(r0)
if e1 != 0 {
err = e1
}
return
}
func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetsockname)), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
if e1 != 0 {
@@ -395,6 +413,28 @@ func setgroups(ngid int, gid *_Gid_t) (err error) {
return
}
func wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error) {
r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwait4)), 4, uintptr(pid), uintptr(unsafe.Pointer(statusp)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
wpid = int32(r0)
if e1 != 0 {
err = e1
}
return
}
func gethostname(buf []byte) (n int, err error) {
var _p0 *byte
if len(buf) > 0 {
_p0 = &buf[0]
}
r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgethostname)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0, 0, 0, 0)
n = int(r0)
if e1 != 0 {
err = e1
}
return
}
func utimes(path string, times *[2]Timeval) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)

View File

@@ -1,6 +1,6 @@
// +build amd64,solaris
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_solaris.go
// cgo -godefs types_solaris.go | go run mkpost.go
package unix
@@ -11,6 +11,7 @@ const (
sizeofLong = 0x8
sizeofLongLong = 0x8
PathMax = 0x400
MaxHostNameLen = 0x100
)
type (

View File

@@ -38,6 +38,7 @@ import (
"sync"
"golang.org/x/net/context"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/naming"
)
@@ -52,6 +53,14 @@ type Address struct {
Metadata interface{}
}
// BalancerConfig specifies the configurations for Balancer.
type BalancerConfig struct {
// DialCreds is the transport credential the Balancer implementation can
// use to dial to a remote load balancer server. The Balancer implementations
// can ignore this if it does not need to talk to another party securely.
DialCreds credentials.TransportCredentials
}
// BalancerGetOptions configures a Get call.
// This is the EXPERIMENTAL API and may be changed or extended in the future.
type BalancerGetOptions struct {
@@ -66,11 +75,11 @@ type Balancer interface {
// Start does the initialization work to bootstrap a Balancer. For example,
// this function may start the name resolution and watch the updates. It will
// be called when dialing.
Start(target string) error
Start(target string, config BalancerConfig) error
// Up informs the Balancer that gRPC has a connection to the server at
// addr. It returns down which is called once the connection to addr gets
// lost or closed.
// TODO: It is not clear how to construct and take advantage the meaningful error
// TODO: It is not clear how to construct and take advantage of the meaningful error
// parameter for down. Need realistic demands to guide.
Up(addr Address) (down func(error))
// Get gets the address of a server for the RPC corresponding to ctx.
@@ -205,7 +214,12 @@ func (rr *roundRobin) watchAddrUpdates() error {
return nil
}
func (rr *roundRobin) Start(target string) error {
func (rr *roundRobin) Start(target string, config BalancerConfig) error {
rr.mu.Lock()
defer rr.mu.Unlock()
if rr.done {
return ErrClientConnClosing
}
if rr.r == nil {
// If there is no name resolver installed, it is not needed to
// do name resolution. In this case, target is added into rr.addrs

View File

@@ -270,31 +270,47 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
if cc.dopts.bs == nil {
cc.dopts.bs = DefaultBackoffConfig
}
var (
ok bool
addrs []Address
)
if cc.dopts.balancer == nil {
// Connect to target directly if balancer is nil.
addrs = append(addrs, Address{Addr: target})
creds := cc.dopts.copts.TransportCredentials
if creds != nil && creds.Info().ServerName != "" {
cc.authority = creds.Info().ServerName
} else {
if err := cc.dopts.balancer.Start(target); err != nil {
return nil, err
}
ch := cc.dopts.balancer.Notify()
if ch == nil {
// There is no name resolver installed.
addrs = append(addrs, Address{Addr: target})
} else {
addrs, ok = <-ch
if !ok || len(addrs) == 0 {
return nil, errNoAddr
}
colonPos := strings.LastIndex(target, ":")
if colonPos == -1 {
colonPos = len(target)
}
cc.authority = target[:colonPos]
}
var ok bool
waitC := make(chan error, 1)
go func() {
var addrs []Address
if cc.dopts.balancer == nil {
// Connect to target directly if balancer is nil.
addrs = append(addrs, Address{Addr: target})
} else {
var credsClone credentials.TransportCredentials
if creds != nil {
credsClone = creds.Clone()
}
config := BalancerConfig{
DialCreds: credsClone,
}
if err := cc.dopts.balancer.Start(target, config); err != nil {
waitC <- err
return
}
ch := cc.dopts.balancer.Notify()
if ch == nil {
// There is no name resolver installed.
addrs = append(addrs, Address{Addr: target})
} else {
addrs, ok = <-ch
if !ok || len(addrs) == 0 {
waitC <- errNoAddr
return
}
}
}
for _, a := range addrs {
if err := cc.resetAddrConn(a, false, nil); err != nil {
waitC <- err
@@ -322,16 +338,6 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
if ok {
go cc.lbWatcher()
}
creds := cc.dopts.copts.TransportCredentials
if creds != nil && creds.Info().ServerName != "" {
cc.authority = creds.Info().ServerName
} else {
colonPos := strings.LastIndex(target, ":")
if colonPos == -1 {
colonPos = len(target)
}
cc.authority = target[:colonPos]
}
return cc, nil
}
@@ -685,7 +691,7 @@ func (ac *addrConn) resetTransport(closeTransport bool) error {
if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() {
return err
}
grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, ac.addr)
grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %v", err, ac.addr)
ac.mu.Lock()
if ac.state == Shutdown {
// ac.tearDown(...) has been invoked.

View File

@@ -109,6 +109,12 @@ type TransportCredentials interface {
ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
// Info provides the ProtocolInfo of this TransportCredentials.
Info() ProtocolInfo
// Clone makes a copy of this TransportCredentials.
Clone() TransportCredentials
// OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server.
// gRPC internals also use it to override the virtual hosting name if it is set.
// It must be called before dialing. Currently, this is only used by grpclb.
OverrideServerName(string) error
}
// TLSInfo contains the auth information for a TLS authenticated connection.
@@ -136,16 +142,6 @@ func (c tlsCreds) Info() ProtocolInfo {
}
}
// GetRequestMetadata returns nil, nil since TLS credentials does not have
// metadata.
func (c *tlsCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return nil, nil
}
func (c *tlsCreds) RequireTransportSecurity() bool {
return true
}
func (c *tlsCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) {
// use local cfg to avoid clobbering ServerName if using multiple endpoints
cfg := cloneTLSConfig(c.config)
@@ -182,6 +178,15 @@ func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error)
return conn, TLSInfo{conn.ConnectionState()}, nil
}
func (c *tlsCreds) Clone() TransportCredentials {
return NewTLS(c.config)
}
func (c *tlsCreds) OverrideServerName(serverNameOverride string) error {
c.config.ServerName = serverNameOverride
return nil
}
// NewTLS uses c to construct a TransportCredentials based on TLS.
func NewTLS(c *tls.Config) TransportCredentials {
tc := &tlsCreds{cloneTLSConfig(c)}
@@ -190,16 +195,16 @@ func NewTLS(c *tls.Config) TransportCredentials {
}
// NewClientTLSFromCert constructs a TLS from the input certificate for client.
// serverNameOverwrite is for testing only. If set to a non empty string,
// it will overwrite the virtual host name of authority (e.g. :authority header field) in requests.
func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverwrite string) TransportCredentials {
return NewTLS(&tls.Config{ServerName: serverNameOverwrite, RootCAs: cp})
// serverNameOverride is for testing only. If set to a non empty string,
// it will override the virtual host name of authority (e.g. :authority header field) in requests.
func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials {
return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp})
}
// NewClientTLSFromFile constructs a TLS from the input certificate file for client.
// serverNameOverwrite is for testing only. If set to a non empty string,
// it will overwrite the virtual host name of authority (e.g. :authority header field) in requests.
func NewClientTLSFromFile(certFile, serverNameOverwrite string) (TransportCredentials, error) {
// serverNameOverride is for testing only. If set to a non empty string,
// it will override the virtual host name of authority (e.g. :authority header field) in requests.
func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) {
b, err := ioutil.ReadFile(certFile)
if err != nil {
return nil, err
@@ -208,7 +213,7 @@ func NewClientTLSFromFile(certFile, serverNameOverwrite string) (TransportCreden
if !cp.AppendCertsFromPEM(b) {
return nil, fmt.Errorf("credentials: failed to append certificates")
}
return NewTLS(&tls.Config{ServerName: serverNameOverwrite, RootCAs: cp}), nil
return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil
}
// NewServerTLSFromCert constructs a TLS from the input certificate for server.

View File

@@ -117,10 +117,17 @@ func (md MD) Len() int {
// Copy returns a copy of md.
func (md MD) Copy() MD {
return Join(md)
}
// Join joins any number of MDs into a single MD.
// The order of values for each key is determined by the order in which
// the MDs containing those values are presented to Join.
func Join(mds ...MD) MD {
out := MD{}
for k, v := range md {
for _, i := range v {
out[k] = append(out[k], i)
for _, md := range mds {
for k, v := range md {
out[k] = append(out[k], v...)
}
}
return out

View File

@@ -873,25 +873,28 @@ func SendHeader(ctx context.Context, md metadata.MD) error {
}
stream, ok := transport.StreamFromContext(ctx)
if !ok {
return fmt.Errorf("grpc: failed to fetch the stream from the context %v", ctx)
return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx)
}
t := stream.ServerTransport()
if t == nil {
grpclog.Fatalf("grpc: SendHeader: %v has no ServerTransport to send header metadata.", stream)
}
return t.WriteHeader(stream, md)
if err := t.WriteHeader(stream, md); err != nil {
return toRPCErr(err)
}
return nil
}
// SetTrailer sets the trailer metadata that will be sent when an RPC returns.
// It may be called at most once from a unary RPC handler. The ctx is the RPC
// handler's Context or one derived from it.
// When called more than once, all the provided metadata will be merged.
// The ctx is the RPC handler's Context or one derived from it.
func SetTrailer(ctx context.Context, md metadata.MD) error {
if md.Len() == 0 {
return nil
}
stream, ok := transport.StreamFromContext(ctx)
if !ok {
return fmt.Errorf("grpc: failed to fetch the stream from the context %v", ctx)
return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx)
}
return stream.SetTrailer(md)
}

View File

@@ -414,8 +414,8 @@ type ServerStream interface {
// after SendProto. It fails if called multiple times or if
// called after SendProto.
SendHeader(metadata.MD) error
// SetTrailer sets the trailer metadata which will be sent with the
// RPC status.
// SetTrailer sets the trailer metadata which will be sent with the RPC status.
// When called more than once, all the provided metadata will be merged.
SetTrailer(metadata.MD)
Stream
}

View File

@@ -252,8 +252,10 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
s.windowHandler = func(n int) {
t.updateWindow(s, uint32(n))
}
// Make a stream be able to cancel the pending operations by itself.
s.ctx, s.cancel = context.WithCancel(ctx)
// The client side stream context should have exactly the same life cycle with the user provided context.
// That means, s.ctx should be read-only. And s.ctx is done iff ctx is done.
// So we use the original context here instead of creating a copy.
s.ctx = ctx
s.dec = &recvBufferReader{
ctx: s.ctx,
goAway: s.goAway,
@@ -265,16 +267,6 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
// NewStream creates a stream and register it into the transport as "active"
// streams.
func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) {
// Record the timeout value on the context.
var timeout time.Duration
if dl, ok := ctx.Deadline(); ok {
timeout = dl.Sub(time.Now())
}
select {
case <-ctx.Done():
return nil, ContextErr(ctx.Err())
default:
}
pr := &peer.Peer{
Addr: t.conn.RemoteAddr(),
}
@@ -381,9 +373,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
if callHdr.SendCompress != "" {
t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress})
}
if timeout > 0 {
if dl, ok := ctx.Deadline(); ok {
// Send out timeout regardless its value. The server can detect timeout context by itself.
timeout := dl.Sub(time.Now())
t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: encodeTimeout(timeout)})
}
for k, v := range authData {
// Capital header names are illegal in HTTP/2.
k = strings.ToLower(k)

View File

@@ -253,6 +253,9 @@ func div(d, r time.Duration) int64 {
// TODO(zhaoq): It is the simplistic and not bandwidth efficient. Improve it.
func encodeTimeout(t time.Duration) string {
if t <= 0 {
return "0n"
}
if d := div(t, time.Nanosecond); d <= maxTimeoutValue {
return strconv.FormatInt(d, 10) + "n"
}
@@ -349,7 +352,7 @@ func decodeGrpcMessageUnchecked(msg string) string {
for i := 0; i < lenMsg; i++ {
c := msg[i]
if c == percentByte && i+2 < lenMsg {
parsed, err := strconv.ParseInt(msg[i+1:i+3], 16, 8)
parsed, err := strconv.ParseUint(msg[i+1:i+3], 16, 8)
if err != nil {
buf.WriteByte(c)
} else {

View File

@@ -39,7 +39,6 @@ package transport // import "google.golang.org/grpc/transport"
import (
"bytes"
"errors"
"fmt"
"io"
"net"
@@ -169,7 +168,8 @@ type Stream struct {
// nil for client side Stream.
st ServerTransport
// ctx is the associated context of the stream.
ctx context.Context
ctx context.Context
// cancel is always nil for client side Stream.
cancel context.CancelFunc
// done is closed when the final status arrives.
done chan struct{}
@@ -286,19 +286,12 @@ func (s *Stream) StatusDesc() string {
return s.statusDesc
}
// ErrIllegalTrailerSet indicates that the trailer has already been set or it
// is too late to do so.
var ErrIllegalTrailerSet = errors.New("transport: trailer has been set")
// SetTrailer sets the trailer metadata which will be sent with the RPC status
// by the server. This can only be called at most once. Server side only.
// by the server. This can be called multiple times. Server side only.
func (s *Stream) SetTrailer(md metadata.MD) error {
s.mu.Lock()
defer s.mu.Unlock()
if s.trailer != nil {
return ErrIllegalTrailerSet
}
s.trailer = md.Copy()
s.trailer = metadata.Join(s.trailer, md)
return nil
}

482
vendor/vendor.json vendored
View File

@@ -21,8 +21,8 @@
{
"checksumSHA1": "T1DpzOaZGsKlUq16elkdwF6ddsU=",
"path": "github.com/Azure/azure-sdk-for-go/storage",
"revision": "a9e8b991cde41aeef7dde53fc1ee2c74af5ed30b",
"revisionTime": "2016-09-08T17:03:40Z"
"revision": "5dbdd3e002c0c232938bf953a5e7fa9a58ee749e",
"revisionTime": "2016-09-27T20:53:54Z"
},
{
"checksumSHA1": "eWlbQbXextN77vRiVuIBV6kSwuE=",
@@ -67,196 +67,196 @@
"revisionTime": "2016-07-15T17:06:12Z"
},
{
"checksumSHA1": "ZjseNd/AQukVRV7YONYPweD1FxQ=",
"checksumSHA1": "dq1GRxE/Qsvp1pawHFQ3vaFoYX4=",
"path": "github.com/aws/aws-sdk-go/aws",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=",
"path": "github.com/aws/aws-sdk-go/aws/awserr",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "ppmwInOtC5Mj/dBBWVxL0KPEI0I=",
"checksumSHA1": "+q4vdl3l1Wom8K1wfIpJ4jlFsbY=",
"path": "github.com/aws/aws-sdk-go/aws/awsutil",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "H/tMKHZU+Qka6RtYiGB50s2uA0s=",
"path": "github.com/aws/aws-sdk-go/aws/client",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=",
"path": "github.com/aws/aws-sdk-go/aws/client/metadata",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "gNWirlrTfSLbOe421hISBAhTqa4=",
"path": "github.com/aws/aws-sdk-go/aws/corehandlers",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "dNZNaOPfBPnzE2CBnfhXXZ9g9jU=",
"path": "github.com/aws/aws-sdk-go/aws/credentials",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "KQiUK/zr3mqnAXD7x/X55/iNme0=",
"path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=",
"path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "4Ipx+5xN0gso+cENC2MHMWmQlR4=",
"path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "nCMd1XKjgV21bEl7J8VZFqTV8PE=",
"path": "github.com/aws/aws-sdk-go/aws/defaults",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "U0SthWum+t9ACanK7SDJOg3dO6M=",
"path": "github.com/aws/aws-sdk-go/aws/ec2metadata",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "NyUg1P8ZS/LHAAQAk/4C5O4X3og=",
"checksumSHA1": "UeUNU97No2/+pICBYrFevJAaShs=",
"path": "github.com/aws/aws-sdk-go/aws/request",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "44uohX3kLsfZHHOqunr+qJnSCdw=",
"checksumSHA1": "BXuya7NrVg2BtHOM4ED5zAwDkg4=",
"path": "github.com/aws/aws-sdk-go/aws/session",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "7lla+sckQeF18wORAGuU2fFMlp4=",
"checksumSHA1": "9YaNtvwUeP1i0GLQ/gmGFS3VlDs=",
"path": "github.com/aws/aws-sdk-go/aws/signer/v4",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "Bm6UrYb2QCzpYseLwwgw6aetgRc=",
"path": "github.com/aws/aws-sdk-go/private/endpoints",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "wk7EyvDaHwb5qqoOP/4d3cV0708=",
"path": "github.com/aws/aws-sdk-go/private/protocol",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "uNmSKXAF8B9HWEciW+iyUwZ99qQ=",
"path": "github.com/aws/aws-sdk-go/private/protocol/ec2query",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "pNeF0Ey7TfBArH5LBQhKOQXQbLY=",
"path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "H9TymcQkQnXSXSVfjggiiS4bpzM=",
"path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "isoix7lTx4qIq2zI2xFADtti5SI=",
"path": "github.com/aws/aws-sdk-go/private/protocol/query",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "5xzix1R8prUyWxgLnzUQoxTsfik=",
"path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "TW/7U+/8ormL7acf6z2rv2hDD+s=",
"path": "github.com/aws/aws-sdk-go/private/protocol/rest",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "Y6Db2GGfGD9LPpcJIPj8vXE8BbQ=",
"path": "github.com/aws/aws-sdk-go/private/protocol/restxml",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "eUEkjyMPAuekKBE4ou+nM9tXEas=",
"path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=",
"path": "github.com/aws/aws-sdk-go/private/waiter",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "y+pZPK8hcTDwq1zHuRduWE14flw=",
"path": "github.com/aws/aws-sdk-go/service/dynamodb",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "8AWdT91H4VKCApsqaIfHaXWV/BQ=",
"path": "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "Unj4a0f5m6vhgXzIFjcgzWAcr3c=",
"checksumSHA1": "wo+0n7gevYlsXAb6gJmG3F/+7pg=",
"path": "github.com/aws/aws-sdk-go/service/ec2",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "dH2W7lR17dgn4a4OYiEzjpQH8hI=",
"path": "github.com/aws/aws-sdk-go/service/iam",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "imxJucuPrgaPRMPtAgsu+Y7soB4=",
"checksumSHA1": "ACgH34RTtZEhDCUJS06LM6wrg7U=",
"path": "github.com/aws/aws-sdk-go/service/s3",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "nH/itbdeFHpl4ysegdtgww9bFSA=",
"path": "github.com/aws/aws-sdk-go/service/sts",
"revision": "1eda36db14da389a03c5e7d41f2172e353c2ce57",
"revisionTime": "2016-09-12T14:27:56Z"
"revision": "388802d0cf038f72020ee99b51781d181e894c1c",
"revisionTime": "2016-09-29T23:03:56Z"
},
{
"checksumSHA1": "ta8SSP0z1c4mWWiJc9srvj2WirE=",
@@ -265,22 +265,22 @@
"revisionTime": "2016-08-13T19:06:34Z"
},
{
"checksumSHA1": "ZAdLZ0e/hin4AXxdS9F8y0yi/bg=",
"checksumSHA1": "V9F/IrT7OeILqNh5PZaFj2uZrzI=",
"path": "github.com/circonus-labs/circonus-gometrics",
"revision": "dee2600b79d017675f2a0e9ff1cb8984e4f21d35",
"revisionTime": "2016-08-30T17:50:13Z"
"revision": "02e91ce11e80e4ee29de4fec93250f04ba47f222",
"revisionTime": "2016-09-14T15:02:40Z"
},
{
"checksumSHA1": "2hV0W0wM75u+OJ4kGv0i7B95cmY=",
"checksumSHA1": "QnP+40EFUbVqLQYe1lCP2YJv5MA=",
"path": "github.com/circonus-labs/circonus-gometrics/api",
"revision": "dee2600b79d017675f2a0e9ff1cb8984e4f21d35",
"revisionTime": "2016-08-30T17:50:13Z"
"revision": "02e91ce11e80e4ee29de4fec93250f04ba47f222",
"revisionTime": "2016-09-14T15:02:40Z"
},
{
"checksumSHA1": "r3XLF0s89Y7UJgS9YP3NbdyafNY=",
"checksumSHA1": "TiHBDvWEmVcipHV+gJJ2SoDsSyE=",
"path": "github.com/circonus-labs/circonus-gometrics/checkmgr",
"revision": "dee2600b79d017675f2a0e9ff1cb8984e4f21d35",
"revisionTime": "2016-08-30T17:50:13Z"
"revision": "02e91ce11e80e4ee29de4fec93250f04ba47f222",
"revisionTime": "2016-09-14T15:02:40Z"
},
{
"checksumSHA1": "C4Z7+l5GOpOCW5DcvNYzheGvQRE=",
@@ -297,44 +297,44 @@
{
"checksumSHA1": "7L6uBG7lWAyD76IejiKVB4P3GVY=",
"path": "github.com/coreos/etcd/client",
"revision": "840f4d48c8e050606c0c66b79ed1adfce546f76b",
"revisionTime": "2016-09-11T02:38:53Z"
"revision": "c349e089b168e28629d0db6ac2819000abbaf6a7",
"revisionTime": "2016-09-29T18:12:25Z"
},
{
"checksumSHA1": "Iv11QZIn/DLcduKSRYApU9l01L8=",
"checksumSHA1": "ga3jt9r+dQBMSXG0gnpNcXp2xYA=",
"path": "github.com/coreos/etcd/pkg/fileutil",
"revision": "840f4d48c8e050606c0c66b79ed1adfce546f76b",
"revisionTime": "2016-09-11T02:38:53Z"
"revision": "c349e089b168e28629d0db6ac2819000abbaf6a7",
"revisionTime": "2016-09-29T18:12:25Z"
},
{
"checksumSHA1": "mKIXx1kDwmVmdIpZ3pJtRBuUKso=",
"path": "github.com/coreos/etcd/pkg/pathutil",
"revision": "840f4d48c8e050606c0c66b79ed1adfce546f76b",
"revisionTime": "2016-09-11T02:38:53Z"
"revision": "c349e089b168e28629d0db6ac2819000abbaf6a7",
"revisionTime": "2016-09-29T18:12:25Z"
},
{
"checksumSHA1": "rMyIh9PsSvPs6Yd+YgKITQzQJx8=",
"path": "github.com/coreos/etcd/pkg/tlsutil",
"revision": "840f4d48c8e050606c0c66b79ed1adfce546f76b",
"revisionTime": "2016-09-11T02:38:53Z"
"revision": "c349e089b168e28629d0db6ac2819000abbaf6a7",
"revisionTime": "2016-09-29T18:12:25Z"
},
{
"checksumSHA1": "HsWrvEjuu5zM8IaOlCFqc80Jb+M=",
"checksumSHA1": "985rsigkh9SZlDXm6qK6cBloQg0=",
"path": "github.com/coreos/etcd/pkg/transport",
"revision": "840f4d48c8e050606c0c66b79ed1adfce546f76b",
"revisionTime": "2016-09-11T02:38:53Z"
"revision": "c349e089b168e28629d0db6ac2819000abbaf6a7",
"revisionTime": "2016-09-29T18:12:25Z"
},
{
"checksumSHA1": "gx1gJIMU6T0UNQ0bPZ/drQ8cpCI=",
"path": "github.com/coreos/etcd/pkg/types",
"revision": "840f4d48c8e050606c0c66b79ed1adfce546f76b",
"revisionTime": "2016-09-11T02:38:53Z"
"revision": "c349e089b168e28629d0db6ac2819000abbaf6a7",
"revisionTime": "2016-09-29T18:12:25Z"
},
{
"checksumSHA1": "d50/+u/LFlXvEV10HiEoXB9OsGg=",
"path": "github.com/coreos/go-systemd/journal",
"revision": "2f344660b11f7285b0af86195c4456e92970f640",
"revisionTime": "2016-09-07T12:16:35Z"
"revision": "a63dfec412dc3675ec36888f359f8a1e5c3f740d",
"revisionTime": "2016-09-20T09:21:07Z"
},
{
"checksumSHA1": "XOoETj0U8GXE7B51aYwBBde6XaM=",
@@ -391,10 +391,10 @@
"revisionTime": "2016-08-27T06:11:18Z"
},
{
"checksumSHA1": "1jSAj7TTewbyk+MaG8CBGlYR37w=",
"checksumSHA1": "yblAAYi+XR0UvMkEwLUDC1gAX1o=",
"path": "github.com/go-ldap/ldap",
"revision": "d0a5ced67b4dc310b9158d63a2c6f9c5ec13f105",
"revisionTime": "2016-08-08T14:54:09Z"
"revision": "e33f0a345ea7c37c15a0c8ee0e796e479c37d640",
"revisionTime": "2016-09-26T17:55:29Z"
},
{
"checksumSHA1": "jEXpLrWXoQvH/zk1lW5Si0swr6Y=",
@@ -403,34 +403,34 @@
"revisionTime": "2016-08-02T11:38:42Z"
},
{
"checksumSHA1": "ezJ1F90fdaIrTyRGowSeAQpMmCo=",
"checksumSHA1": "X3aO3d9K9ALtg4/XI4I9L57FPkM=",
"path": "github.com/gocql/gocql",
"revision": "58b3c7120a7ef9a077e4d089dd1badcb9ec756a8",
"revisionTime": "2016-09-11T13:21:20Z"
"revision": "ffae44103aa14ada9e2b342329f44ce354f399fd",
"revisionTime": "2016-09-27T08:26:32Z"
},
{
"checksumSHA1": "Z3N6HDGWcvcNu0FloZRq54uO3h4=",
"path": "github.com/gocql/gocql/internal/lru",
"revision": "58b3c7120a7ef9a077e4d089dd1badcb9ec756a8",
"revisionTime": "2016-09-11T13:21:20Z"
"revision": "ffae44103aa14ada9e2b342329f44ce354f399fd",
"revisionTime": "2016-09-27T08:26:32Z"
},
{
"checksumSHA1": "ctK9mwZKnt/8dHxx2Ef6nZTljZs=",
"path": "github.com/gocql/gocql/internal/murmur",
"revision": "58b3c7120a7ef9a077e4d089dd1badcb9ec756a8",
"revisionTime": "2016-09-11T13:21:20Z"
"revision": "ffae44103aa14ada9e2b342329f44ce354f399fd",
"revisionTime": "2016-09-27T08:26:32Z"
},
{
"checksumSHA1": "tZQDfMMTKrYMXqen0zjJWLtOf1A=",
"path": "github.com/gocql/gocql/internal/streams",
"revision": "58b3c7120a7ef9a077e4d089dd1badcb9ec756a8",
"revisionTime": "2016-09-11T13:21:20Z"
"revision": "ffae44103aa14ada9e2b342329f44ce354f399fd",
"revisionTime": "2016-09-27T08:26:32Z"
},
{
"checksumSHA1": "sZSeW3Dc6lUqm1CzMUdu3poimoA=",
"path": "github.com/golang/protobuf/proto",
"revision": "1f49d83d9aa00e6ce4fc8258c71cc7786aec968a",
"revisionTime": "2016-08-24T20:12:15Z"
"revision": "87c000235d3d852c1628dc9490cd21ab36a7d69f",
"revisionTime": "2016-09-26T18:56:24Z"
},
{
"checksumSHA1": "W+E/2xXcE1GmJ0Qb784ald0Fn6I=",
@@ -439,10 +439,10 @@
"revisionTime": "2016-05-29T05:00:41Z"
},
{
"checksumSHA1": "S9c3CJIvvicl+Tmd55aBPqvYaGc=",
"checksumSHA1": "lgk38ggoIH2I3nzcgerykYAf8pY=",
"path": "github.com/google/go-github/github",
"revision": "a32b73b3f7165492568dbf7bf6663b5c369034db",
"revisionTime": "2016-09-05T07:07:36Z"
"revision": "e4194fe26c3379788dc1671da379f719351f093e",
"revisionTime": "2016-09-28T04:39:25Z"
},
{
"checksumSHA1": "yyAzHoiVLu+xywYI2BDyRq6sOqE=",
@@ -457,16 +457,16 @@
"revisionTime": "2016-01-25T11:53:50Z"
},
{
"checksumSHA1": "BMEJLBjl91k5k3vMMzzT7G2SO1U=",
"checksumSHA1": "gPi7fIH7BzYjebIeXKn4vWO+bfI=",
"path": "github.com/hashicorp/consul/api",
"revision": "0a34741d7266af34eed36048d1a8e8880a7b17a1",
"revisionTime": "2016-09-06T14:50:06Z"
"revision": "d5b7530ec593f1ec2a8f8a7c145bcadafa88b572",
"revisionTime": "2016-09-28T15:32:28Z"
},
{
"checksumSHA1": "0DPAA2cTBjrCGgXaxXil0vILcFs=",
"path": "github.com/hashicorp/consul/lib",
"revision": "0a34741d7266af34eed36048d1a8e8880a7b17a1",
"revisionTime": "2016-09-06T14:50:06Z"
"revision": "d5b7530ec593f1ec2a8f8a7c145bcadafa88b572",
"revisionTime": "2016-09-28T15:32:28Z"
},
{
"checksumSHA1": "cdOCt0Yb+hdErz8NAQqayxPmRsY=",
@@ -493,10 +493,10 @@
"revisionTime": "2016-08-11T01:57:21Z"
},
{
"checksumSHA1": "GBDE1KDl/7c5hlRPYRZ7+C0WQ0g=",
"checksumSHA1": "ErJHGU6AVPZM9yoY/xV11TwSjQs=",
"path": "github.com/hashicorp/go-retryablehttp",
"revision": "f4ed9b0fa01a2ac614afe7c897ed2e3d8208f3e8",
"revisionTime": "2016-08-10T17:22:55Z"
"revision": "6e85be8fee1dcaa02c0eaaac2df5a8fbecf94145",
"revisionTime": "2016-09-30T03:51:02Z"
},
{
"checksumSHA1": "A1PcINvF3UiwHRKn8UcgARgvGRs=",
@@ -529,58 +529,58 @@
"revisionTime": "2016-08-13T22:13:03Z"
},
{
"checksumSHA1": "fa9G5tEr4oJJc3vtgn/B0NWZXfA=",
"checksumSHA1": "8OPDk+bKyRGJoKcS4QNw9F7dpE8=",
"path": "github.com/hashicorp/hcl",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "67DfevLBglV52Y2eAuhFc/xQni0=",
"path": "github.com/hashicorp/hcl/hcl/ast",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "l2oQxBsZRwn6eZjf+whXr8c9+8c=",
"path": "github.com/hashicorp/hcl/hcl/parser",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "lgR7PSAZ0RtvAc9OCtCnNsF/x8g=",
"path": "github.com/hashicorp/hcl/hcl/scanner",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "JlZmnzqdmFFyb1+2afLyR3BOE/8=",
"path": "github.com/hashicorp/hcl/hcl/strconv",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "c6yprzj06ASwCo18TtbbNNBHljA=",
"path": "github.com/hashicorp/hcl/hcl/token",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "jQ45CCc1ed/nlV7bbSnx6z72q1M=",
"path": "github.com/hashicorp/hcl/json/parser",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "YdvFsNOMSWMLnY6fcliWQa0O5Fw=",
"path": "github.com/hashicorp/hcl/json/scanner",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "fNlXQCQEnb+B3k5UDL/r15xtSJY=",
"path": "github.com/hashicorp/hcl/json/token",
"revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-09-02T16:52:19Z"
"revision": "ef8133da8cda503718a74741312bf50821e6de79",
"revisionTime": "2016-09-16T13:01:00Z"
},
{
"checksumSHA1": "qnlqWJYV81ENr61SZk9c65R1mDo=",
@@ -603,8 +603,8 @@
{
"checksumSHA1": "E3Xcanc9ouQwL+CZGOUyA/+giLg=",
"path": "github.com/hashicorp/serf/coordinate",
"revision": "9432bc08aa8d486e497e27f84878ebbe8c1eab66",
"revisionTime": "2016-08-16T23:01:54Z"
"revision": "b7a120a5fc494f6dd5e858f42fd0fd4022d6320f",
"revisionTime": "2016-09-26T16:36:01Z"
},
{
"checksumSHA1": "ZhK6IO2XN81Y+3RAjTcVm1Ic7oU=",
@@ -691,10 +691,10 @@
"revisionTime": "2016-08-31T22:25:20Z"
},
{
"checksumSHA1": "ZAlzPBSsaGe/k5pbISRQvSiVhfc=",
"checksumSHA1": "ugnSryGF6VPBb5s87QgoRH6730g=",
"path": "github.com/mattn/go-colorable",
"revision": "ed8eb9e318d7a84ce5915b495b7d35e0cfe7b5a8",
"revisionTime": "2016-07-31T23:54:17Z"
"revision": "6c903ff4aa50920ca86087a280590b36b3152b9c",
"revisionTime": "2016-09-30T08:41:57Z"
},
{
"checksumSHA1": "xZuhljnmBysJPta/lMyYmJdujCg=",
@@ -727,10 +727,10 @@
"revisionTime": "2016-08-15T18:46:15Z"
},
{
"checksumSHA1": "y2HsVMt3eYGqywv5ljijnywJMb4=",
"checksumSHA1": "EDAtec3XSbTjw6gWG+NNScows9M=",
"path": "github.com/mitchellh/copystructure",
"revision": "6871c41ca9148d368715dedcda473f396f205df5",
"revisionTime": "2016-08-25T20:45:07Z"
"revision": "ad4c8fe111e90a651ae529a0eb45a12385e2a8eb",
"revisionTime": "2016-09-28T02:51:53Z"
},
{
"checksumSHA1": "AXacfEchaUqT5RGmPmMXsOWRhv8=",
@@ -745,10 +745,10 @@
"revisionTime": "2016-08-08T18:12:53Z"
},
{
"checksumSHA1": "mrqMlK6gqe//WsJSrJ1HgkPM0lM=",
"checksumSHA1": "kXh6sdGViiRK0REpIWydJvpsyY0=",
"path": "github.com/mitchellh/reflectwalk",
"revision": "eecf4c70c626c7cfbb95c90195bc34d386c74ac6",
"revisionTime": "2015-05-27T15:31:53Z"
"revision": "0c9480f65513be815a88d6076a3d8d95d4274236",
"revisionTime": "2016-09-28T02:49:03Z"
},
{
"checksumSHA1": "ZeYZz/zLkTZM3pYWn4uCNqnbtQE=",
@@ -775,10 +775,10 @@
"revisionTime": "2016-08-24T21:06:00Z"
},
{
"checksumSHA1": "ExnVEVNT8APpFTm26cUb5T09yR4=",
"checksumSHA1": "6U1/66VaDVjh/hiz+UPnASgxGV8=",
"path": "github.com/ryanuber/columnize",
"revision": "9b3edd62028f107d7cabb19353292afd29311a4e",
"revisionTime": "2016-07-12T16:32:29Z"
"revision": "6f43af5ecd2928c6fef2b4f35ef6f36f96690390",
"revisionTime": "2016-09-15T03:41:46Z"
},
{
"checksumSHA1": "egQy+ytQKjfBN1oRKQJ/pxIvjYc=",
@@ -787,112 +787,118 @@
"revisionTime": "2016-09-02T21:22:55Z"
},
{
"checksumSHA1": "8Lm8nsMCFz4+gr9EvQLqK8+w+Ks=",
"checksumSHA1": "Qm7DuiE3Cn0+CelfV9tggSPNG0k=",
"path": "github.com/sethgrid/pester",
"revision": "8053687f99650573b28fb75cddf3f295082704d7",
"revisionTime": "2016-04-29T17:20:22Z"
"revision": "2a102734c18c43c74fd0664e06cd414cf9602b93",
"revisionTime": "2016-09-16T18:34:45Z"
},
{
"checksumSHA1": "hS2Ni/NOeuMVV3sBPT4rRdh9cUA=",
"checksumSHA1": "jfIUoeCY4uLz1zCgnCxndi5/UNE=",
"path": "github.com/ugorji/go/codec",
"revision": "98ef79d6c615fa258e892ed0b11c6e013712693e",
"revisionTime": "2016-09-11T04:19:19Z"
"revision": "faddd6128c66c4708f45fdc007f575f75e592a3c",
"revisionTime": "2016-09-28T01:52:44Z"
},
{
"checksumSHA1": "vE43s37+4CJ2CDU6TlOUOYE0K9c=",
"path": "golang.org/x/crypto/bcrypt",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "JsJdKXhz87gWenMwBeejTOeNE7k=",
"path": "golang.org/x/crypto/blowfish",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "h+pFYiRHBogczS8/F1NoN3Ata44=",
"path": "golang.org/x/crypto/curve25519",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "wGb//LjBPNxYHqk+dcLo7BjPXK8=",
"path": "golang.org/x/crypto/ed25519",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "LXFcVx8I587SnWmKycSDEq9yvK8=",
"path": "golang.org/x/crypto/ed25519/internal/edwards25519",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "4D8hxMIaSDEW5pCQk22Xj4DcDh4=",
"path": "golang.org/x/crypto/hkdf",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "MCeXr2RNeiG1XG6V+er1OR0qyeo=",
"path": "golang.org/x/crypto/md4",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "pXOcpeiBjX3zbVKeg0pvYnEmtqU=",
"checksumSHA1": "ueYA012ftzqjyWYYdlt3H3pkixo=",
"path": "golang.org/x/crypto/ssh",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "dA/dc+Var3VnLrksziLa0Zli+YI=",
"checksumSHA1": "SJ3Ma3Ozavxpbh1usZWBCnzMKIc=",
"path": "golang.org/x/crypto/ssh/agent",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "y3a1tOZVwKCqG2yJZvAYycnelyM=",
"path": "golang.org/x/crypto/ssh/terminal",
"revision": "e311231e83195f401421a286060d65643f9c9d40",
"revisionTime": "2016-09-12T10:18:32Z"
"revision": "a20de3fa94e069ec699987416679230d72e030a3",
"revisionTime": "2016-09-23T08:39:13Z"
},
{
"checksumSHA1": "9jjO5GjLa0XF/nfWihF02RoH4qc=",
"path": "golang.org/x/net/context",
"revision": "cfe3c2a7525b50c3d707256e371c90938cfef98a",
"revisionTime": "2016-09-03T02:20:35Z"
"revision": "a333c534c871727fb95745870e8b98a69447f2ce",
"revisionTime": "2016-09-29T23:53:44Z"
},
{
"checksumSHA1": "UL3f1aJMhKAkxTl5kZnkrwyqP+M=",
"checksumSHA1": "LDedV+Ow3M0FDYUxA5ccEbZdryU=",
"path": "golang.org/x/net/http2",
"revision": "cfe3c2a7525b50c3d707256e371c90938cfef98a",
"revisionTime": "2016-09-03T02:20:35Z"
"revision": "a333c534c871727fb95745870e8b98a69447f2ce",
"revisionTime": "2016-09-29T23:53:44Z"
},
{
"checksumSHA1": "EYNaHp7XdLWRydUCE0amEkKAtgk=",
"checksumSHA1": "HzuGD7AwgC0p1az1WAQnEFnEk98=",
"path": "golang.org/x/net/http2/hpack",
"revision": "cfe3c2a7525b50c3d707256e371c90938cfef98a",
"revisionTime": "2016-09-03T02:20:35Z"
"revision": "a333c534c871727fb95745870e8b98a69447f2ce",
"revisionTime": "2016-09-29T23:53:44Z"
},
{
"checksumSHA1": "GIGmSrYACByf5JDIP9ByBZksY80=",
"path": "golang.org/x/net/idna",
"revision": "a333c534c871727fb95745870e8b98a69447f2ce",
"revisionTime": "2016-09-29T23:53:44Z"
},
{
"checksumSHA1": "/k7k6eJDkxXx6K9Zpo/OwNm58XM=",
"path": "golang.org/x/net/internal/timeseries",
"revision": "cfe3c2a7525b50c3d707256e371c90938cfef98a",
"revisionTime": "2016-09-03T02:20:35Z"
"revision": "a333c534c871727fb95745870e8b98a69447f2ce",
"revisionTime": "2016-09-29T23:53:44Z"
},
{
"checksumSHA1": "yhndhWXMs/VSEDLks4dNyFMQStA=",
"checksumSHA1": "3xyuaSNmClqG4YWC7g0isQIbUTc=",
"path": "golang.org/x/net/lex/httplex",
"revision": "cfe3c2a7525b50c3d707256e371c90938cfef98a",
"revisionTime": "2016-09-03T02:20:35Z"
"revision": "a333c534c871727fb95745870e8b98a69447f2ce",
"revisionTime": "2016-09-29T23:53:44Z"
},
{
"checksumSHA1": "WpST9lFOHvWrjDVy0GJNqHe+R3E=",
"path": "golang.org/x/net/trace",
"revision": "cfe3c2a7525b50c3d707256e371c90938cfef98a",
"revisionTime": "2016-09-03T02:20:35Z"
"revision": "a333c534c871727fb95745870e8b98a69447f2ce",
"revisionTime": "2016-09-29T23:53:44Z"
},
{
"checksumSHA1": "XH7CgbL5Z8COUc+MKrYqS3FFosY=",
@@ -907,106 +913,106 @@
"revisionTime": "2016-08-26T23:14:08Z"
},
{
"checksumSHA1": "8fD/im5Kwvy3JgmxulDTambmE8w=",
"checksumSHA1": "vu7njn8O4vhFtmgGWntwjA2NAbk=",
"path": "golang.org/x/sys/unix",
"revision": "30de6d19a3bd89a5f38ae4028e23aaa5582648af",
"revisionTime": "2016-09-07T05:59:14Z"
"revision": "8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9",
"revisionTime": "2016-09-14T20:33:16Z"
},
{
"checksumSHA1": "4lEP/dEWOMb4r2Aehu0D9iBDgIU=",
"path": "google.golang.org/appengine/internal",
"revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05",
"revisionTime": "2016-08-19T23:33:10Z"
"revision": "150dc57a1b433e64154302bdc40b6bb8aefa313a",
"revisionTime": "2016-09-29T07:07:04Z"
},
{
"checksumSHA1": "TsNO8P0xUlLNyh3Ic/tzSp/fDWM=",
"path": "google.golang.org/appengine/internal/base",
"revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05",
"revisionTime": "2016-08-19T23:33:10Z"
"revision": "150dc57a1b433e64154302bdc40b6bb8aefa313a",
"revisionTime": "2016-09-29T07:07:04Z"
},
{
"checksumSHA1": "5QsV5oLGSfKZqTCVXP6NRz5T4Tw=",
"path": "google.golang.org/appengine/internal/datastore",
"revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05",
"revisionTime": "2016-08-19T23:33:10Z"
"revision": "150dc57a1b433e64154302bdc40b6bb8aefa313a",
"revisionTime": "2016-09-29T07:07:04Z"
},
{
"checksumSHA1": "Gep2T9zmVYV8qZfK2gu3zrmG6QE=",
"path": "google.golang.org/appengine/internal/log",
"revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05",
"revisionTime": "2016-08-19T23:33:10Z"
"revision": "150dc57a1b433e64154302bdc40b6bb8aefa313a",
"revisionTime": "2016-09-29T07:07:04Z"
},
{
"checksumSHA1": "a1XY7rz3BieOVqVI2Et6rKiwQCk=",
"path": "google.golang.org/appengine/internal/remote_api",
"revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05",
"revisionTime": "2016-08-19T23:33:10Z"
"revision": "150dc57a1b433e64154302bdc40b6bb8aefa313a",
"revisionTime": "2016-09-29T07:07:04Z"
},
{
"checksumSHA1": "QtAbHtHmDzcf6vOV9eqlCpKgjiw=",
"path": "google.golang.org/appengine/internal/urlfetch",
"revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05",
"revisionTime": "2016-08-19T23:33:10Z"
"revision": "150dc57a1b433e64154302bdc40b6bb8aefa313a",
"revisionTime": "2016-09-29T07:07:04Z"
},
{
"checksumSHA1": "akOV9pYnCbcPA8wJUutSQVibdyg=",
"path": "google.golang.org/appengine/urlfetch",
"revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05",
"revisionTime": "2016-08-19T23:33:10Z"
"revision": "150dc57a1b433e64154302bdc40b6bb8aefa313a",
"revisionTime": "2016-09-29T07:07:04Z"
},
{
"checksumSHA1": "6C+HF81y7JjZBaSviKZQEa7DVwg=",
"checksumSHA1": "N0GmUbip6LljIQkixSZnQ7a76Fs=",
"path": "google.golang.org/grpc",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "08icuA15HRkdYCt6H+Cs90RPQsY=",
"path": "google.golang.org/grpc/codes",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "UZPB/MvlrzbmSc4ThyVSku28laM=",
"checksumSHA1": "Vd1MU+Ojs7GeS6jE52vlxtXvIrI=",
"path": "google.golang.org/grpc/credentials",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "3Lt5hNAG8qJAYSsNghR5uA1zQns=",
"path": "google.golang.org/grpc/grpclog",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "T3Q0p8kzvXFnRkMaK/G8mCv6mc0=",
"path": "google.golang.org/grpc/internal",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "rxtneb9jDjKPHNZhC5obfG++6bI=",
"checksumSHA1": "P64GkSdsTZ8Nxop5HYqZJ6e+iHs=",
"path": "google.golang.org/grpc/metadata",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "4GSUFhOQ0kdFlBH4D5OTeKy78z0=",
"path": "google.golang.org/grpc/naming",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "3RRoLeH6X2//7tVClOVzxW2bY+E=",
"path": "google.golang.org/grpc/peer",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "R+bHFrHoQTCqh7Cj1ZfRjDHg+mk=",
"checksumSHA1": "dzbx9oVtSfVgNE3lTl+r5xOXxcw=",
"path": "google.golang.org/grpc/transport",
"revision": "28707e14b1d2b2f5da81474dea2790d71e526987",
"revisionTime": "2016-09-09T17:41:34Z"
"revision": "c2983be903f6966c83c6ea86ba74df0b7cc882cd",
"revisionTime": "2016-09-29T21:48:06Z"
},
{
"checksumSHA1": "wSu8owMAP7GixsYoSZ4CmKUVhnU=",