From d9f97198bd53475d9f69cde16600edbe9c7e76f7 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 16 Nov 2016 14:08:09 -0500 Subject: [PATCH 01/19] =?UTF-8?q?Set=20number=20of=20pester=20retries=20to?= =?UTF-8?q?=20zero=20by=20default=20and=20make=20seal=20command=E2=80=A6?= =?UTF-8?q?=20(#2093)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Set number of pester retries to zero by default and make seal command return 403 if unauthorized instead of 500 * Fix build * Use 403 instead and update test * Change another 500 to 403 --- api/client.go | 4 +--- http/sys_seal.go | 9 +++++++-- http/sys_seal_test.go | 6 +++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/api/client.go b/api/client.go index 4aee40c0a7252..c6c78ada9e29b 100644 --- a/api/client.go +++ b/api/client.go @@ -48,7 +48,7 @@ type Config struct { redirectSetup sync.Once // MaxRetries controls the maximum number of times to retry when a 5xx error - // occurs. Set to 0 or less to disable retrying. + // occurs. Set to 0 or less to disable retrying. Defaults to 0. MaxRetries int } @@ -99,8 +99,6 @@ func DefaultConfig() *Config { config.Address = v } - config.MaxRetries = pester.DefaultClient.MaxRetries - return config } diff --git a/http/sys_seal.go b/http/sys_seal.go index 2e02f7308ad16..841dc11071828 100644 --- a/http/sys_seal.go +++ b/http/sys_seal.go @@ -30,8 +30,13 @@ func handleSysSeal(core *vault.Core) http.Handler { // Seal with the token above if err := core.SealWithRequest(req); err != nil { - respondError(w, http.StatusInternalServerError, err) - return + if errwrap.Contains(err, logical.ErrPermissionDenied.Error()) { + respondError(w, http.StatusForbidden, err) + return + } else { + respondError(w, http.StatusInternalServerError, err) + return + } } respondOk(w, nil) diff --git a/http/sys_seal_test.go b/http/sys_seal_test.go index cc12be41d1d01..83fd3198b5b13 100644 --- a/http/sys_seal_test.go +++ b/http/sys_seal_test.go @@ -285,7 +285,7 @@ func TestSysSeal_Permissions(t *testing.T) { // We expect this to fail since it needs update and sudo httpResp := testHttpPut(t, "child", addr+"/v1/sys/seal", nil) - testResponseStatus(t, httpResp, 500) + testResponseStatus(t, httpResp, 403) // Now modify to add update capability req = &logical.Request{ @@ -306,7 +306,7 @@ func TestSysSeal_Permissions(t *testing.T) { // We expect this to fail since it needs sudo httpResp = testHttpPut(t, "child", addr+"/v1/sys/seal", nil) - testResponseStatus(t, httpResp, 500) + testResponseStatus(t, httpResp, 403) // Now modify to just sudo capability req = &logical.Request{ @@ -327,7 +327,7 @@ func TestSysSeal_Permissions(t *testing.T) { // We expect this to fail since it needs update httpResp = testHttpPut(t, "child", addr+"/v1/sys/seal", nil) - testResponseStatus(t, httpResp, 500) + testResponseStatus(t, httpResp, 403) // Now modify to add all needed capabilities req = &logical.Request{ From 0f53aa8fc71e6bfba8ca9bb21ccfed7f23b360b8 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 16 Nov 2016 17:08:16 -0500 Subject: [PATCH 02/19] Document bug causing certain LDAP settings to be forgotten on upgrade to 0.6.1+. Fixes #2104 --- website/source/docs/install/upgrade-to-0.6.1.html.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/source/docs/install/upgrade-to-0.6.1.html.md b/website/source/docs/install/upgrade-to-0.6.1.html.md index f69adec7e6327..23330994731e6 100644 --- a/website/source/docs/install/upgrade-to-0.6.1.html.md +++ b/website/source/docs/install/upgrade-to-0.6.1.html.md @@ -64,6 +64,14 @@ it is *very important* that you set this option **before** upgrading your Vault instances. Without doing so, each Vault instance will believe that it is standalone and there could be consistency issues. +## LDAP Auth Backend Forgets Bind Password and Insecure TLS Settings + +Due to a bug, these two settings are forgotten if they have been configured in +the LDAP backend prior to 0.6.1. If you are using these settings with LDAP, +please be sure to re-submit your LDAP configuration to Vault after the upgrade, +so ensure that you have a valid token to do so before upgrading if you are +relying on LDAP authentication for permissions to modify the backend itself. + ## LDAP Auth Backend Does Not Search `memberOf` The LDAP backend went from a model where all permutations of storing and From 7c21a9a3e71f71327ff3ea38be54e026de10592f Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 16 Nov 2016 18:22:54 -0500 Subject: [PATCH 03/19] Bump deps --- .../Azure/azure-sdk-for-go/storage/blob.go | 310 ++++++++++++- .../Azure/azure-sdk-for-go/storage/client.go | 2 +- .../Azure/azure-sdk-for-go/storage/queue.go | 38 ++ vendor/github.com/Jeffail/gabs/gabs.go | 296 +++--------- vendor/github.com/armon/go-metrics/README.md | 51 ++- .../github.com/aws/aws-sdk-go/aws/config.go | 17 + .../ec2rolecreds/ec2_role_provider.go | 2 +- .../aws/aws-sdk-go/aws/ec2metadata/api.go | 4 +- .../aws/aws-sdk-go/aws/signer/v4/v4.go | 6 +- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../aws-sdk-go/private/protocol/rest/build.go | 9 +- vendor/github.com/go-sql-driver/mysql/AUTHORS | 1 + .../github.com/go-sql-driver/mysql/README.md | 20 +- .../github.com/go-sql-driver/mysql/packets.go | 66 +-- .../go-sql-driver/mysql/statement.go | 5 +- vendor/github.com/gocql/gocql/AUTHORS | 1 + .../gocql/gocql/address_translators.go | 26 ++ vendor/github.com/gocql/gocql/cluster.go | 21 + vendor/github.com/gocql/gocql/conn.go | 4 +- vendor/github.com/gocql/gocql/control.go | 4 +- vendor/github.com/gocql/gocql/events.go | 1 - vendor/github.com/gocql/gocql/integration.sh | 2 +- vendor/github.com/gocql/gocql/token.go | 11 +- .../golang/protobuf/proto/extensions.go | 1 + .../golang/protobuf/proto/text_parser.go | 6 +- .../go-github/github/activity_events.go | 4 + .../google/go-github/github/authorizations.go | 9 - .../google/go-github/github/event_types.go | 33 ++ .../google/go-github/github/github.go | 6 +- .../google/go-github/github/licenses.go | 31 +- .../google/go-github/github/messages.go | 2 + .../google/go-github/github/projects.go | 417 +++++++++++++++++ .../google/go-github/github/pulls.go | 11 +- .../google/go-github/github/repos.go | 20 +- .../google/go-github/github/repos_pages.go | 27 +- .../google/go-github/github/repos_projects.go | 417 +---------------- .../github.com/hashicorp/consul/api/agent.go | 1 + vendor/github.com/hashicorp/consul/api/kv.go | 4 +- .../hashicorp/consul/api/prepared_query.go | 11 +- .../hashicorp/go-multierror/format.go | 6 +- .../hashicorp/hcl/hcl/strconv/quote.go | 12 +- vendor/github.com/lib/pq/conn.go | 11 + .../mattn/go-colorable/colorable_others.go | 3 + .../mattn/go-colorable/colorable_windows.go | 4 + .../mattn/go-colorable/noncolorable.go | 3 + vendor/golang.org/x/net/context/context.go | 102 +++++ vendor/golang.org/x/net/context/go18.go | 22 - vendor/golang.org/x/net/context/pre_go18.go | 109 ----- vendor/golang.org/x/net/http2/go18.go | 4 + vendor/golang.org/x/net/http2/not_go18.go | 4 + vendor/golang.org/x/net/http2/server.go | 112 +++-- vendor/golang.org/x/net/http2/transport.go | 19 +- vendor/golang.org/x/net/http2/writesched.go | 17 +- .../x/net/http2/writesched_priority.go | 10 +- vendor/golang.org/x/net/trace/trace.go | 2 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 3 +- .../x/sys/unix/zsyscall_linux_386.go | 15 +- .../x/sys/unix/zsyscall_linux_amd64.go | 15 +- .../x/sys/unix/zsyscall_linux_arm.go | 15 +- .../x/sys/unix/zsyscall_linux_arm64.go | 15 +- .../x/sys/unix/zsyscall_linux_mips64.go | 15 +- .../x/sys/unix/zsyscall_linux_mips64le.go | 15 +- .../x/sys/unix/zsyscall_linux_ppc64.go | 15 +- .../x/sys/unix/zsyscall_linux_ppc64le.go | 15 +- .../x/sys/unix/zsyscall_linux_s390x.go | 15 +- .../x/sys/unix/zsyscall_linux_sparc64.go | 15 +- .../appengine/internal/api.go | 3 + vendor/google.golang.org/grpc/README.md | 25 + vendor/google.golang.org/grpc/call.go | 59 ++- vendor/google.golang.org/grpc/clientconn.go | 13 + vendor/google.golang.org/grpc/rpc_util.go | 36 +- vendor/google.golang.org/grpc/server.go | 153 +++++-- vendor/google.golang.org/grpc/stats/stats.go | 219 +++++++++ vendor/google.golang.org/grpc/stream.go | 93 +++- vendor/google.golang.org/grpc/tap/tap.go | 54 +++ .../grpc/transport/handler_server.go | 2 +- .../grpc/transport/http2_client.go | 65 ++- .../grpc/transport/http2_server.go | 61 ++- .../grpc/transport/transport.go | 27 +- vendor/vendor.json | 428 +++++++++--------- 80 files changed, 2461 insertions(+), 1269 deletions(-) create mode 100644 vendor/github.com/gocql/gocql/address_translators.go create mode 100644 vendor/github.com/google/go-github/github/projects.go delete mode 100644 vendor/golang.org/x/net/context/go18.go delete mode 100644 vendor/golang.org/x/net/context/pre_go18.go create mode 100644 vendor/google.golang.org/grpc/stats/stats.go create mode 100644 vendor/google.golang.org/grpc/tap/tap.go diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go index 317620363d092..39cd508840fc1 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "io/ioutil" "net/http" "net/url" "strconv" @@ -301,6 +302,65 @@ const ( ContainerAccessTypeContainer ContainerAccessType = "container" ) +// ContainerAccessOptions are used when setting ACLs of containers (after creation) +type ContainerAccessOptions struct { + ContainerAccess ContainerAccessType + Timeout int + LeaseID string +} + +// AccessPolicyDetails are used for SETTING policies +type AccessPolicyDetails struct { + ID string + StartTime time.Time + ExpiryTime time.Time + CanRead bool + CanWrite bool + CanDelete bool +} + +// ContainerPermissions is used when setting permissions and Access Policies for containers. +type ContainerPermissions struct { + AccessOptions ContainerAccessOptions + AccessPolicy AccessPolicyDetails +} + +// AccessPolicyDetailsXML has specifics about an access policy +// annotated with XML details. +type AccessPolicyDetailsXML struct { + StartTime time.Time `xml:"Start"` + ExpiryTime time.Time `xml:"Expiry"` + Permission string `xml:"Permission"` +} + +// SignedIdentifier is a wrapper for a specific policy +type SignedIdentifier struct { + ID string `xml:"Id"` + AccessPolicy AccessPolicyDetailsXML `xml:"AccessPolicy"` +} + +// SignedIdentifiers part of the response from GetPermissions call. +type SignedIdentifiers struct { + SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` +} + +// AccessPolicy is the response type from the GetPermissions call. +type AccessPolicy struct { + SignedIdentifiersList SignedIdentifiers `xml:"SignedIdentifiers"` +} + +// ContainerAccessResponse is returned for the GetContainerPermissions function. +// This contains both the permission and access policy for the container. +type ContainerAccessResponse struct { + ContainerAccess ContainerAccessType + AccessPolicy SignedIdentifiers +} + +// ContainerAccessHeader references header used when setting/getting container ACL +const ( + ContainerAccessHeader string = "x-ms-blob-public-access" +) + // Maximum sizes (per REST API) for various concepts const ( MaxBlobBlockSize = 4 * 1024 * 1024 @@ -416,7 +476,7 @@ func (b BlobStorageClient) createContainer(name string, access ContainerAccessTy headers := b.client.getStandardHeaders() if access != "" { - headers["x-ms-blob-public-access"] = string(access) + headers[ContainerAccessHeader] = string(access) } return b.client.exec(verb, uri, headers, nil) } @@ -438,6 +498,101 @@ func (b BlobStorageClient) ContainerExists(name string) (bool, error) { return false, err } +// SetContainerPermissions sets up container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179391.aspx +func (b BlobStorageClient) SetContainerPermissions(container string, containerPermissions ContainerPermissions) (err error) { + params := url.Values{ + "restype": {"container"}, + "comp": {"acl"}, + } + + if containerPermissions.AccessOptions.Timeout > 0 { + params.Add("timeout", strconv.Itoa(containerPermissions.AccessOptions.Timeout)) + } + + uri := b.client.getEndpoint(blobServiceName, pathForContainer(container), params) + headers := b.client.getStandardHeaders() + if containerPermissions.AccessOptions.ContainerAccess != "" { + headers[ContainerAccessHeader] = string(containerPermissions.AccessOptions.ContainerAccess) + } + + if containerPermissions.AccessOptions.LeaseID != "" { + headers[leaseID] = containerPermissions.AccessOptions.LeaseID + } + + // generate the XML for the SharedAccessSignature if required. + accessPolicyXML, err := generateAccessPolicy(containerPermissions.AccessPolicy) + if err != nil { + return err + } + + var resp *storageResponse + if accessPolicyXML != "" { + headers["Content-Length"] = strconv.Itoa(len(accessPolicyXML)) + resp, err = b.client.exec("PUT", uri, headers, strings.NewReader(accessPolicyXML)) + } else { + resp, err = b.client.exec("PUT", uri, headers, nil) + } + + if err != nil { + return err + } + + if resp != nil { + defer func() { + err = resp.body.Close() + }() + + if resp.statusCode != http.StatusOK { + return errors.New("Unable to set permissions") + } + } + return nil +} + +// GetContainerPermissions gets the container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179469.aspx +// If timeout is 0 then it will not be passed to Azure +// leaseID will only be passed to Azure if populated +// Returns permissionResponse which is combined permissions and AccessPolicy +func (b BlobStorageClient) GetContainerPermissions(container string, timeout int, leaseID string) (permissionResponse *ContainerAccessResponse, err error) { + params := url.Values{"restype": {"container"}, + "comp": {"acl"}} + + if timeout > 0 { + params.Add("timeout", strconv.Itoa(timeout)) + } + + uri := b.client.getEndpoint(blobServiceName, pathForContainer(container), params) + headers := b.client.getStandardHeaders() + + if leaseID != "" { + headers[leaseID] = leaseID + } + + resp, err := b.client.exec("GET", uri, headers, nil) + if err != nil { + return nil, err + } + + // containerAccess. Blob, Container, empty + containerAccess := resp.headers.Get(http.CanonicalHeaderKey(ContainerAccessHeader)) + + defer func() { + err = resp.body.Close() + }() + + var out AccessPolicy + err = xmlUnmarshal(resp.body, &out.SignedIdentifiersList) + if err != nil { + return nil, err + } + + permissionResponse = &ContainerAccessResponse{} + permissionResponse.AccessPolicy = out.SignedIdentifiersList + permissionResponse.ContainerAccess = ContainerAccessType(containerAccess) + + return permissionResponse, nil +} + // DeleteContainer deletes the container with given name on the storage // account. If the container does not exist returns error. // @@ -614,8 +769,6 @@ func (b BlobStorageClient) AcquireLease(container string, name string, leaseTime return returnedLeaseID, nil } - // what should we return in case of HTTP 201 but no lease ID? - // or it just cant happen? (brave words) return "", errors.New("LeaseID not returned") } @@ -1106,15 +1259,20 @@ func (b BlobStorageClient) AppendBlock(container, name string, chunk []byte, ext // // See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx func (b BlobStorageClient) CopyBlob(container, name, sourceBlob string) error { - copyID, err := b.startBlobCopy(container, name, sourceBlob) + copyID, err := b.StartBlobCopy(container, name, sourceBlob) if err != nil { return err } - return b.waitForBlobCopy(container, name, copyID) + return b.WaitForBlobCopy(container, name, copyID) } -func (b BlobStorageClient) startBlobCopy(container, name, sourceBlob string) (string, error) { +// StartBlobCopy starts a blob copy operation. +// sourceBlob parameter must be a canonical URL to the blob (can be +// obtained using GetBlobURL method.) +// +// See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx +func (b BlobStorageClient) StartBlobCopy(container, name, sourceBlob string) (string, error) { uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) headers := b.client.getStandardHeaders() @@ -1137,7 +1295,39 @@ func (b BlobStorageClient) startBlobCopy(container, name, sourceBlob string) (st return copyID, nil } -func (b BlobStorageClient) waitForBlobCopy(container, name, copyID string) error { +// AbortBlobCopy aborts a BlobCopy which has already been triggered by the StartBlobCopy function. +// copyID is generated from StartBlobCopy function. +// currentLeaseID is required IF the destination blob has an active lease on it. +// As defined in https://msdn.microsoft.com/en-us/library/azure/jj159098.aspx +func (b BlobStorageClient) AbortBlobCopy(container, name, copyID, currentLeaseID string, timeout int) error { + params := url.Values{"comp": {"copy"}, "copyid": {copyID}} + if timeout > 0 { + params.Add("timeout", strconv.Itoa(timeout)) + } + + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + headers["x-ms-copy-action"] = "abort" + + if currentLeaseID != "" { + headers[leaseID] = currentLeaseID + } + + resp, err := b.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + + return nil +} + +// WaitForBlobCopy loops until a BlobCopy operation is completed (or fails with error) +func (b BlobStorageClient) WaitForBlobCopy(container, name, copyID string) error { for { props, err := b.GetBlobProperties(container, name) if err != nil { @@ -1181,10 +1371,12 @@ func (b BlobStorageClient) DeleteBlob(container, name string, extraHeaders map[s // See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx func (b BlobStorageClient) DeleteBlobIfExists(container, name string, extraHeaders map[string]string) (bool, error) { resp, err := b.deleteBlob(container, name, extraHeaders) - if resp != nil && (resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound) { - return resp.statusCode == http.StatusAccepted, nil + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusAccepted, nil + } } - defer resp.body.Close() return false, err } @@ -1210,17 +1402,18 @@ func pathForBlob(container, name string) string { return fmt.Sprintf("/%s/%s", container, name) } -// GetBlobSASURI creates an URL to the specified blob which contains the Shared -// Access Signature with specified permissions and expiration time. +// GetBlobSASURIWithSignedIPAndProtocol creates an URL to the specified blob which contains the Shared +// Access Signature with specified permissions and expiration time. Also includes signedIPRange and allowed procotols. +// If old API version is used but no signedIP is passed (ie empty string) then this should still work. +// We only populate the signedIP when it non-empty. // // See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx -func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Time, permissions string) (string, error) { +func (b BlobStorageClient) GetBlobSASURIWithSignedIPAndProtocol(container, name string, expiry time.Time, permissions string, signedIPRange string, HTTPSOnly bool) (string, error) { var ( signedPermissions = permissions blobURL = b.GetBlobURL(container, name) ) canonicalizedResource, err := b.client.buildCanonicalizedResource(blobURL) - if err != nil { return "", err } @@ -1232,7 +1425,6 @@ func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Tim // We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component). canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1) - canonicalizedResource, err = url.QueryUnescape(canonicalizedResource) if err != nil { return "", err @@ -1241,7 +1433,11 @@ func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Tim signedExpiry := expiry.UTC().Format(time.RFC3339) signedResource := "b" - stringToSign, err := blobSASStringToSign(b.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions) + protocols := "https,http" + if HTTPSOnly { + protocols = "https" + } + stringToSign, err := blobSASStringToSign(b.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions, signedIPRange, protocols) if err != nil { return "", err } @@ -1255,6 +1451,13 @@ func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Tim "sig": {sig}, } + if b.client.apiVersion >= "2015-04-05" { + sasParams.Add("spr", protocols) + if signedIPRange != "" { + sasParams.Add("sip", signedIPRange) + } + } + sasURL, err := url.Parse(blobURL) if err != nil { return "", err @@ -1263,16 +1466,89 @@ func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Tim return sasURL.String(), nil } -func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string) (string, error) { +// GetBlobSASURI creates an URL to the specified blob which contains the Shared +// Access Signature with specified permissions and expiration time. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx +func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Time, permissions string) (string, error) { + url, err := b.GetBlobSASURIWithSignedIPAndProtocol(container, name, expiry, permissions, "", false) + return url, err +} + +func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string, signedIP string, protocols string) (string, error) { var signedStart, signedIdentifier, rscc, rscd, rsce, rscl, rsct string if signedVersion >= "2015-02-21" { canonicalizedResource = "/blob" + canonicalizedResource } + // https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx#Anchor_12 + if signedVersion >= "2015-04-05" { + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedIP, protocols, signedVersion, rscc, rscd, rsce, rscl, rsct), nil + } + // reference: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx if signedVersion >= "2013-08-15" { return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedVersion, rscc, rscd, rsce, rscl, rsct), nil } + return "", errors.New("storage: not implemented SAS for versions earlier than 2013-08-15") } + +func generatePermissions(accessPolicy AccessPolicyDetails) (permissions string) { + // generate the permissions string (rwd). + // still want the end user API to have bool flags. + permissions = "" + + if accessPolicy.CanRead { + permissions += "r" + } + + if accessPolicy.CanWrite { + permissions += "w" + } + + if accessPolicy.CanDelete { + permissions += "d" + } + + return permissions +} + +// convertAccessPolicyToXMLStructs converts between AccessPolicyDetails which is a struct better for API usage to the +// AccessPolicy struct which will get converted to XML. +func convertAccessPolicyToXMLStructs(accessPolicy AccessPolicyDetails) SignedIdentifiers { + return SignedIdentifiers{ + SignedIdentifiers: []SignedIdentifier{ + { + ID: accessPolicy.ID, + AccessPolicy: AccessPolicyDetailsXML{ + StartTime: accessPolicy.StartTime.UTC().Round(time.Second), + ExpiryTime: accessPolicy.ExpiryTime.UTC().Round(time.Second), + Permission: generatePermissions(accessPolicy), + }, + }, + }, + } +} + +// generateAccessPolicy generates the XML access policy used as the payload for SetContainerPermissions. +func generateAccessPolicy(accessPolicy AccessPolicyDetails) (accessPolicyXML string, err error) { + + if accessPolicy.ID != "" { + signedIdentifiers := convertAccessPolicyToXMLStructs(accessPolicy) + body, _, err := xmlMarshal(signedIdentifiers) + if err != nil { + return "", err + } + + xmlByteArray, err := ioutil.ReadAll(body) + if err != nil { + return "", err + } + accessPolicyXML = string(xmlByteArray) + return accessPolicyXML, nil + } + + return "", nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go index 2816e03ec6c95..a41a586979b91 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go @@ -305,7 +305,7 @@ func (c Client) buildCanonicalizedResourceTable(uri string) (string, error) { cr := "/" + c.getCanonicalizedAccountName() if len(u.Path) > 0 { - cr += u.Path + cr += u.EscapedPath() } return cr, nil diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go index 3ecf4aca0d216..0cd3578442ea7 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go @@ -82,6 +82,24 @@ func (p PeekMessagesParameters) getParameters() url.Values { return out } +// UpdateMessageParameters is the set of options can be specified for Update Messsage +// operation. A zero struct does not use any preferences for the request. +type UpdateMessageParameters struct { + PopReceipt string + VisibilityTimeout int +} + +func (p UpdateMessageParameters) getParameters() url.Values { + out := url.Values{} + if p.PopReceipt != "" { + out.Set("popreceipt", p.PopReceipt) + } + if p.VisibilityTimeout != 0 { + out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) + } + return out +} + // GetMessagesResponse represents a response returned from Get Messages // operation. type GetMessagesResponse struct { @@ -304,3 +322,23 @@ func (c QueueServiceClient) DeleteMessage(queue, messageID, popReceipt string) e defer resp.body.Close() return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) } + +// UpdateMessage operation deletes the specified message. +// +// See https://msdn.microsoft.com/en-us/library/azure/hh452234.aspx +func (c QueueServiceClient) UpdateMessage(queue string, messageID string, message string, params UpdateMessageParameters) error { + uri := c.client.getEndpoint(queueServiceName, pathForMessage(queue, messageID), params.getParameters()) + req := putMessageRequest{MessageText: message} + body, nn, err := xmlMarshal(req) + if err != nil { + return err + } + headers := c.client.getStandardHeaders() + headers["Content-Length"] = fmt.Sprintf("%d", nn) + resp, err := c.client.exec("PUT", uri, headers, body) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} diff --git a/vendor/github.com/Jeffail/gabs/gabs.go b/vendor/github.com/Jeffail/gabs/gabs.go index 5ab24ce28dfdb..3fcec06ec22cd 100644 --- a/vendor/github.com/Jeffail/gabs/gabs.go +++ b/vendor/github.com/Jeffail/gabs/gabs.go @@ -31,8 +31,7 @@ import ( "strings" ) -/*--------------------------------------------------------------------------------------------------- - */ +//-------------------------------------------------------------------------------------------------- var ( // ErrOutOfBounds - Index out of bounds. @@ -63,40 +62,30 @@ var ( ErrInvalidBuffer = errors.New("input buffer contained invalid JSON") ) -/*--------------------------------------------------------------------------------------------------- - */ +//-------------------------------------------------------------------------------------------------- -/* -Container - an internal structure that holds a reference to the core interface map of the parsed -json. Use this container to move context. -*/ +// Container - an internal structure that holds a reference to the core interface map of the parsed +// json. Use this container to move context. type Container struct { object interface{} } -/* -Data - Return the contained data as an interface{}. -*/ +// Data - Return the contained data as an interface{}. func (g *Container) Data() interface{} { return g.object } -/*--------------------------------------------------------------------------------------------------- - */ +//-------------------------------------------------------------------------------------------------- -/* -Path - Search for a value using dot notation. -*/ +// Path - Search for a value using dot notation. func (g *Container) Path(path string) *Container { return g.Search(strings.Split(path, ".")...) } -/* -Search - Attempt to find and return an object within the JSON structure by specifying the hierarchy -of field names to locate the target. If the search encounters an array and has not reached the end -target then it will iterate each object of the array for the target and return all of the results in -a JSON array. -*/ +// Search - Attempt to find and return an object within the JSON structure by specifying the +// hierarchy of field names to locate the target. If the search encounters an array and has not +// reached the end target then it will iterate each object of the array for the target and return +// all of the results in a JSON array. func (g *Container) Search(hierarchy ...string) *Container { var object interface{} @@ -124,31 +113,22 @@ func (g *Container) Search(hierarchy ...string) *Container { return &Container{object} } -/* -S - Shorthand method, does the same thing as Search. -*/ +// S - Shorthand method, does the same thing as Search. func (g *Container) S(hierarchy ...string) *Container { return g.Search(hierarchy...) } -/* -Exists - Checks whether a path exists. -*/ +// Exists - Checks whether a path exists. func (g *Container) Exists(hierarchy ...string) bool { return g.Search(hierarchy...).Data() != nil } -/* -ExistsP - Checks whether a dot notation path exists. -*/ +// ExistsP - Checks whether a dot notation path exists. func (g *Container) ExistsP(path string) bool { return g.Exists(strings.Split(path, ".")...) } -/* -Index - Attempt to find and return an object with a JSON array by specifying the index of the -target. -*/ +// Index - Attempt to find and return an object within a JSON array by index. func (g *Container) Index(index int) *Container { if array, ok := g.Data().([]interface{}); ok { if index >= len(array) { @@ -159,11 +139,9 @@ func (g *Container) Index(index int) *Container { return &Container{nil} } -/* -Children - Return a slice of all the children of the array. This also works for objects, however, -the children returned for an object will NOT be in order and you lose the names of the returned -objects this way. -*/ +// Children - Return a slice of all the children of the array. This also works for objects, however, +// the children returned for an object will NOT be in order and you lose the names of the returned +// objects this way. func (g *Container) Children() ([]*Container, error) { if array, ok := g.Data().([]interface{}); ok { children := make([]*Container, len(array)) @@ -182,9 +160,7 @@ func (g *Container) Children() ([]*Container, error) { return nil, ErrNotObjOrArray } -/* -ChildrenMap - Return a map of all the children of an object. -*/ +// ChildrenMap - Return a map of all the children of an object. func (g *Container) ChildrenMap() (map[string]*Container, error) { if mmap, ok := g.Data().(map[string]interface{}); ok { children := map[string]*Container{} @@ -196,14 +172,11 @@ func (g *Container) ChildrenMap() (map[string]*Container, error) { return nil, ErrNotObj } -/*--------------------------------------------------------------------------------------------------- - */ +//-------------------------------------------------------------------------------------------------- -/* -Set - Set the value of a field at a JSON path, any parts of the path that do not exist will be -constructed, and if a collision occurs with a non object type whilst iterating the path an error is -returned. -*/ +// Set - Set the value of a field at a JSON path, any parts of the path that do not exist will be +// constructed, and if a collision occurs with a non object type whilst iterating the path an error +// is returned. func (g *Container) Set(value interface{}, path ...string) (*Container, error) { if len(path) == 0 { g.object = value @@ -229,16 +202,12 @@ func (g *Container) Set(value interface{}, path ...string) (*Container, error) { return &Container{object}, nil } -/* -SetP - Does the same as Set, but using a dot notation JSON path. -*/ +// SetP - Does the same as Set, but using a dot notation JSON path. func (g *Container) SetP(value interface{}, path string) (*Container, error) { return g.Set(value, strings.Split(path, ".")...) } -/* -SetIndex - Set a value of an array element based on the index. -*/ +// SetIndex - Set a value of an array element based on the index. func (g *Container) SetIndex(value interface{}, index int) (*Container, error) { if array, ok := g.Data().([]interface{}); ok { if index >= len(array) { @@ -250,80 +219,60 @@ func (g *Container) SetIndex(value interface{}, index int) (*Container, error) { return &Container{nil}, ErrNotArray } -/* -Object - Create a new JSON object at a path. Returns an error if the path contains a collision with -a non object type. -*/ +// Object - Create a new JSON object at a path. Returns an error if the path contains a collision +// with a non object type. func (g *Container) Object(path ...string) (*Container, error) { return g.Set(map[string]interface{}{}, path...) } -/* -ObjectP - Does the same as Object, but using a dot notation JSON path. -*/ +// ObjectP - Does the same as Object, but using a dot notation JSON path. func (g *Container) ObjectP(path string) (*Container, error) { return g.Object(strings.Split(path, ".")...) } -/* -ObjectI - Create a new JSON object at an array index. Returns an error if the object is not an array -or the index is out of bounds. -*/ +// ObjectI - Create a new JSON object at an array index. Returns an error if the object is not an +// array or the index is out of bounds. func (g *Container) ObjectI(index int) (*Container, error) { return g.SetIndex(map[string]interface{}{}, index) } -/* -Array - Create a new JSON array at a path. Returns an error if the path contains a collision with -a non object type. -*/ +// Array - Create a new JSON array at a path. Returns an error if the path contains a collision with +// a non object type. func (g *Container) Array(path ...string) (*Container, error) { return g.Set([]interface{}{}, path...) } -/* -ArrayP - Does the same as Array, but using a dot notation JSON path. -*/ +// ArrayP - Does the same as Array, but using a dot notation JSON path. func (g *Container) ArrayP(path string) (*Container, error) { return g.Array(strings.Split(path, ".")...) } -/* -ArrayI - Create a new JSON array at an array index. Returns an error if the object is not an array -or the index is out of bounds. -*/ +// ArrayI - Create a new JSON array at an array index. Returns an error if the object is not an +// array or the index is out of bounds. func (g *Container) ArrayI(index int) (*Container, error) { return g.SetIndex([]interface{}{}, index) } -/* -ArrayOfSize - Create a new JSON array of a particular size at a path. Returns an error if the path -contains a collision with a non object type. -*/ +// ArrayOfSize - Create a new JSON array of a particular size at a path. Returns an error if the +// path contains a collision with a non object type. func (g *Container) ArrayOfSize(size int, path ...string) (*Container, error) { a := make([]interface{}, size) return g.Set(a, path...) } -/* -ArrayOfSizeP - Does the same as ArrayOfSize, but using a dot notation JSON path. -*/ +// ArrayOfSizeP - Does the same as ArrayOfSize, but using a dot notation JSON path. func (g *Container) ArrayOfSizeP(size int, path string) (*Container, error) { return g.ArrayOfSize(size, strings.Split(path, ".")...) } -/* -ArrayOfSizeI - Create a new JSON array of a particular size at an array index. Returns an error if -the object is not an array or the index is out of bounds. -*/ +// ArrayOfSizeI - Create a new JSON array of a particular size at an array index. Returns an error +// if the object is not an array or the index is out of bounds. func (g *Container) ArrayOfSizeI(size, index int) (*Container, error) { a := make([]interface{}, size) return g.SetIndex(a, index) } -/* -Delete - Delete an element at a JSON path, an error is returned if the element does not exist. -*/ +// Delete - Delete an element at a JSON path, an error is returned if the element does not exist. func (g *Container) Delete(path ...string) error { var object interface{} @@ -346,24 +295,19 @@ func (g *Container) Delete(path ...string) error { return nil } -/* -DeleteP - Does the same as Delete, but using a dot notation JSON path. -*/ +// DeleteP - Does the same as Delete, but using a dot notation JSON path. func (g *Container) DeleteP(path string) error { return g.Delete(strings.Split(path, ".")...) } -/*--------------------------------------------------------------------------------------------------- - */ +//-------------------------------------------------------------------------------------------------- /* Array modification/search - Keeping these options simple right now, no need for anything more complicated since you can just cast to []interface{}, modify and then reassign with Set. */ -/* -ArrayAppend - Append a value onto a JSON array. -*/ +// ArrayAppend - Append a value onto a JSON array. func (g *Container) ArrayAppend(value interface{}, path ...string) error { array, ok := g.Search(path...).Data().([]interface{}) if !ok { @@ -374,16 +318,12 @@ func (g *Container) ArrayAppend(value interface{}, path ...string) error { return err } -/* -ArrayAppendP - Append a value onto a JSON array using a dot notation JSON path. -*/ +// ArrayAppendP - Append a value onto a JSON array using a dot notation JSON path. func (g *Container) ArrayAppendP(value interface{}, path string) error { return g.ArrayAppend(value, strings.Split(path, ".")...) } -/* -ArrayRemove - Remove an element from a JSON array. -*/ +// ArrayRemove - Remove an element from a JSON array. func (g *Container) ArrayRemove(index int, path ...string) error { if index < 0 { return ErrOutOfBounds @@ -401,16 +341,12 @@ func (g *Container) ArrayRemove(index int, path ...string) error { return err } -/* -ArrayRemoveP - Remove an element from a JSON array using a dot notation JSON path. -*/ +// ArrayRemoveP - Remove an element from a JSON array using a dot notation JSON path. func (g *Container) ArrayRemoveP(index int, path string) error { return g.ArrayRemove(index, strings.Split(path, ".")...) } -/* -ArrayElement - Access an element from a JSON array. -*/ +// ArrayElement - Access an element from a JSON array. func (g *Container) ArrayElement(index int, path ...string) (*Container, error) { if index < 0 { return &Container{nil}, ErrOutOfBounds @@ -425,16 +361,12 @@ func (g *Container) ArrayElement(index int, path ...string) (*Container, error) return &Container{nil}, ErrOutOfBounds } -/* -ArrayElementP - Access an element from a JSON array using a dot notation JSON path. -*/ +// ArrayElementP - Access an element from a JSON array using a dot notation JSON path. func (g *Container) ArrayElementP(index int, path string) (*Container, error) { return g.ArrayElement(index, strings.Split(path, ".")...) } -/* -ArrayCount - Count the number of elements in a JSON array. -*/ +// ArrayCount - Count the number of elements in a JSON array. func (g *Container) ArrayCount(path ...string) (int, error) { if array, ok := g.Search(path...).Data().([]interface{}); ok { return len(array), nil @@ -442,19 +374,14 @@ func (g *Container) ArrayCount(path ...string) (int, error) { return 0, ErrNotArray } -/* -ArrayCountP - Count the number of elements in a JSON array using a dot notation JSON path. -*/ +// ArrayCountP - Count the number of elements in a JSON array using a dot notation JSON path. func (g *Container) ArrayCountP(path string) (int, error) { return g.ArrayCount(strings.Split(path, ".")...) } -/*--------------------------------------------------------------------------------------------------- - */ +//-------------------------------------------------------------------------------------------------- -/* -Bytes - Converts the contained object back to a JSON []byte blob. -*/ +// Bytes - Converts the contained object back to a JSON []byte blob. func (g *Container) Bytes() []byte { if g.object != nil { if bytes, err := json.Marshal(g.object); err == nil { @@ -464,9 +391,7 @@ func (g *Container) Bytes() []byte { return []byte("{}") } -/* -BytesIndent - Converts the contained object back to a JSON []byte blob formatted with prefix and indent. -*/ +// BytesIndent - Converts the contained object to a JSON []byte blob formatted with prefix, indent. func (g *Container) BytesIndent(prefix string, indent string) []byte { if g.object != nil { if bytes, err := json.MarshalIndent(g.object, prefix, indent); err == nil { @@ -476,37 +401,27 @@ func (g *Container) BytesIndent(prefix string, indent string) []byte { return []byte("{}") } -/* -String - Converts the contained object back to a JSON formatted string. -*/ +// String - Converts the contained object to a JSON formatted string. func (g *Container) String() string { return string(g.Bytes()) } -/* -StringIndent - Converts the contained object back to a JSON formatted string with prefix and indent. -*/ +// StringIndent - Converts the contained object back to a JSON formatted string with prefix, indent. func (g *Container) StringIndent(prefix string, indent string) string { return string(g.BytesIndent(prefix, indent)) } -/* -New - Create a new gabs JSON object. -*/ +// New - Create a new gabs JSON object. func New() *Container { return &Container{map[string]interface{}{}} } -/* -Consume - Gobble up an already converted JSON object, or a fresh map[string]interface{} object. -*/ +// Consume - Gobble up an already converted JSON object, or a fresh map[string]interface{} object. func Consume(root interface{}) (*Container, error) { return &Container{root}, nil } -/* -ParseJSON - Convert a string into a representation of the parsed JSON. -*/ +// ParseJSON - Convert a string into a representation of the parsed JSON. func ParseJSON(sample []byte) (*Container, error) { var gabs Container @@ -517,9 +432,7 @@ func ParseJSON(sample []byte) (*Container, error) { return &gabs, nil } -/* -ParseJSONDecoder - Convert a json.Decoder into a representation of the parsed JSON. -*/ +// ParseJSONDecoder - Convert a json.Decoder into a representation of the parsed JSON. func ParseJSONDecoder(decoder *json.Decoder) (*Container, error) { var gabs Container @@ -530,9 +443,7 @@ func ParseJSONDecoder(decoder *json.Decoder) (*Container, error) { return &gabs, nil } -/* -ParseJSONFile - Read a file and convert into a representation of the parsed JSON. -*/ +// ParseJSONFile - Read a file and convert into a representation of the parsed JSON. func ParseJSONFile(path string) (*Container, error) { if len(path) > 0 { cBytes, err := ioutil.ReadFile(path) @@ -550,9 +461,7 @@ func ParseJSONFile(path string) (*Container, error) { return nil, ErrInvalidPath } -/* -ParseJSONBuffer - Read the contents of a buffer into a representation of the parsed JSON. -*/ +// ParseJSONBuffer - Read the contents of a buffer into a representation of the parsed JSON. func ParseJSONBuffer(buffer io.Reader) (*Container, error) { var gabs Container jsonDecoder := json.NewDecoder(buffer) @@ -563,83 +472,4 @@ func ParseJSONBuffer(buffer io.Reader) (*Container, error) { return &gabs, nil } -/*--------------------------------------------------------------------------------------------------- - */ - -// DEPRECATED METHODS - -/* -Push - DEPRECATED: Push a value onto a JSON array. -*/ -func (g *Container) Push(target string, value interface{}) error { - if mmap, ok := g.Data().(map[string]interface{}); ok { - arrayTarget := mmap[target] - if array, ok := arrayTarget.([]interface{}); ok { - mmap[target] = append(array, value) - } else { - return ErrNotArray - } - } else { - return ErrNotObj - } - return nil -} - -/* -RemoveElement - DEPRECATED: Remove a value from a JSON array. -*/ -func (g *Container) RemoveElement(target string, index int) error { - if index < 0 { - return ErrOutOfBounds - } - if mmap, ok := g.Data().(map[string]interface{}); ok { - arrayTarget := mmap[target] - if array, ok := arrayTarget.([]interface{}); ok { - if index < len(array) { - mmap[target] = append(array[:index], array[index+1:]...) - } else { - return ErrOutOfBounds - } - } else { - return ErrNotArray - } - } else { - return ErrNotObj - } - return nil -} - -/* -GetElement - DEPRECATED: Get the desired element from a JSON array -*/ -func (g *Container) GetElement(target string, index int) *Container { - if index < 0 { - return &Container{nil} - } - if mmap, ok := g.Data().(map[string]interface{}); ok { - arrayTarget := mmap[target] - if array, ok := arrayTarget.([]interface{}); ok { - if index < len(array) { - return &Container{array[index]} - } - } - } - return &Container{nil} -} - -/* -CountElements - DEPRECATED: Count the elements of a JSON array, returns -1 if the target is not an -array -*/ -func (g *Container) CountElements(target string) int { - if mmap, ok := g.Data().(map[string]interface{}); ok { - arrayTarget := mmap[target] - if array, ok := arrayTarget.([]interface{}); ok { - return len(array) - } - } - return -1 -} - -/*--------------------------------------------------------------------------------------------------- - */ +//-------------------------------------------------------------------------------------------------- diff --git a/vendor/github.com/armon/go-metrics/README.md b/vendor/github.com/armon/go-metrics/README.md index 7b6f23e29f839..b564bf10d6566 100644 --- a/vendor/github.com/armon/go-metrics/README.md +++ b/vendor/github.com/armon/go-metrics/README.md @@ -28,39 +28,42 @@ Examples Here is an example of using the package: - func SlowMethod() { - // Profiling the runtime of a method - defer metrics.MeasureSince([]string{"SlowMethod"}, time.Now()) - } +```go +func SlowMethod() { + // Profiling the runtime of a method + defer metrics.MeasureSince([]string{"SlowMethod"}, time.Now()) +} - // Configure a statsite sink as the global metrics sink - sink, _ := metrics.NewStatsiteSink("statsite:8125") - metrics.NewGlobal(metrics.DefaultConfig("service-name"), sink) - - // Emit a Key/Value pair - metrics.EmitKey([]string{"questions", "meaning of life"}, 42) +// Configure a statsite sink as the global metrics sink +sink, _ := metrics.NewStatsiteSink("statsite:8125") +metrics.NewGlobal(metrics.DefaultConfig("service-name"), sink) +// Emit a Key/Value pair +metrics.EmitKey([]string{"questions", "meaning of life"}, 42) +``` Here is an example of setting up an signal handler: - // Setup the inmem sink and signal handler - inm := metrics.NewInmemSink(10*time.Second, time.Minute) - sig := metrics.DefaultInmemSignal(inm) - metrics.NewGlobal(metrics.DefaultConfig("service-name"), inm) +```go +// Setup the inmem sink and signal handler +inm := metrics.NewInmemSink(10*time.Second, time.Minute) +sig := metrics.DefaultInmemSignal(inm) +metrics.NewGlobal(metrics.DefaultConfig("service-name"), inm) - // Run some code - inm.SetGauge([]string{"foo"}, 42) - inm.EmitKey([]string{"bar"}, 30) +// Run some code +inm.SetGauge([]string{"foo"}, 42) +inm.EmitKey([]string{"bar"}, 30) - inm.IncrCounter([]string{"baz"}, 42) - inm.IncrCounter([]string{"baz"}, 1) - inm.IncrCounter([]string{"baz"}, 80) +inm.IncrCounter([]string{"baz"}, 42) +inm.IncrCounter([]string{"baz"}, 1) +inm.IncrCounter([]string{"baz"}, 80) - inm.AddSample([]string{"method", "wow"}, 42) - inm.AddSample([]string{"method", "wow"}, 100) - inm.AddSample([]string{"method", "wow"}, 22) +inm.AddSample([]string{"method", "wow"}, 42) +inm.AddSample([]string{"method", "wow"}, 100) +inm.AddSample([]string{"method", "wow"}, 22) - .... +.... +``` When a signal comes in, output like the following will be dumped to stderr: diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go index 34c2bab3380bf..bf23d1e452a45 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go @@ -182,6 +182,19 @@ type Config struct { // the delay of a request see the aws/client.DefaultRetryer and // aws/request.Retryer. SleepDelay func(time.Duration) + + // DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests. + // Will default to false. This would only be used for empty directory names in s3 requests. + // + // Example: + // sess, err := session.NewSession(&aws.Config{DisableRestProtocolURICleaning: aws.Bool(true)) + // + // svc := s3.New(sess) + // out, err := svc.GetObject(&s3.GetObjectInput { + // Bucket: aws.String("bucketname"), + // Key: aws.String("//foo//bar//moo"), + // }) + DisableRestProtocolURICleaning *bool } // NewConfig returns a new Config pointer that can be chained with builder @@ -403,6 +416,10 @@ func mergeInConfig(dst *Config, other *Config) { if other.SleepDelay != nil { dst.SleepDelay = other.SleepDelay } + + if other.DisableRestProtocolURICleaning != nil { + dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning + } } // Copy will return a shallow copy of the Config object. If any additional diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go index aa9d689a01154..c39749524ecac 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go @@ -111,7 +111,7 @@ func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) { }, nil } -// A ec2RoleCredRespBody provides the shape for unmarshalling credential +// A ec2RoleCredRespBody provides the shape for unmarshaling credential // request responses. type ec2RoleCredRespBody struct { // Success State diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go index e5755d11b0b34..984407a580f47 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go @@ -133,7 +133,7 @@ func (c *EC2Metadata) Available() bool { return true } -// An EC2IAMInfo provides the shape for unmarshalling +// An EC2IAMInfo provides the shape for unmarshaling // an IAM info from the metadata API type EC2IAMInfo struct { Code string @@ -142,7 +142,7 @@ type EC2IAMInfo struct { InstanceProfileID string } -// An EC2InstanceIdentityDocument provides the shape for unmarshalling +// An EC2InstanceIdentityDocument provides the shape for unmarshaling // an instance identity document type EC2InstanceIdentityDocument struct { DevpayProductCodes []string `json:"devpayProductCodes"` diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go index 986530b401937..08be9ff25670f 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go @@ -567,7 +567,11 @@ func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) { } func (ctx *signingCtx) buildCanonicalString() { - ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1) + query := ctx.Query + for key := range query { + sort.Strings(query[key]) + } + ctx.Request.URL.RawQuery = strings.Replace(query.Encode(), "+", "%20", -1) uri := getURIPath(ctx.Request.URL) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index 1c26603055b34..d12d9906eb223 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.5.0" +const SDKVersion = "1.5.6" diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go index 5f412516dc6ab..f5e8607537277 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/request" ) @@ -92,7 +93,7 @@ func buildLocationElements(r *request.Request, v reflect.Value) { } r.HTTPRequest.URL.RawQuery = query.Encode() - updatePath(r.HTTPRequest.URL, r.HTTPRequest.URL.Path) + updatePath(r.HTTPRequest.URL, r.HTTPRequest.URL.Path, aws.BoolValue(r.Config.DisableRestProtocolURICleaning)) } func buildBody(r *request.Request, v reflect.Value) { @@ -193,13 +194,15 @@ func buildQueryString(query url.Values, v reflect.Value, name string) error { return nil } -func updatePath(url *url.URL, urlPath string) { +func updatePath(url *url.URL, urlPath string, disableRestProtocolURICleaning bool) { scheme, query := url.Scheme, url.RawQuery hasSlash := strings.HasSuffix(urlPath, "/") // clean up path - urlPath = path.Clean(urlPath) + if !disableRestProtocolURICleaning { + urlPath = path.Clean(urlPath) + } if hasSlash && !strings.HasSuffix(urlPath, "/") { urlPath += "/" } diff --git a/vendor/github.com/go-sql-driver/mysql/AUTHORS b/vendor/github.com/go-sql-driver/mysql/AUTHORS index 148ea93aa76d7..692c186fde590 100644 --- a/vendor/github.com/go-sql-driver/mysql/AUTHORS +++ b/vendor/github.com/go-sql-driver/mysql/AUTHORS @@ -38,6 +38,7 @@ Lucas Liu Luke Scott Michael Woolnough Nicola Peduzzi +Olivier Mengué Paul Bonser Runrioter Wung Soroush Pour diff --git a/vendor/github.com/go-sql-driver/mysql/README.md b/vendor/github.com/go-sql-driver/mysql/README.md index 3dcc235441b70..25dcdc8f2250f 100644 --- a/vendor/github.com/go-sql-driver/mysql/README.md +++ b/vendor/github.com/go-sql-driver/mysql/README.md @@ -315,13 +315,21 @@ I/O write timeout. The value must be a decimal number with an unit suffix ( *"ms ##### System Variables -All other parameters are interpreted as system variables: - * `autocommit`: `"SET autocommit="` - * [`time_zone`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `"SET time_zone="` - * [`tx_isolation`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `"SET tx_isolation="` - * `param`: `"SET ="` +Any other parameters are interpreted as system variables: + * `=`: `SET =` + * `=`: `SET =` + * `=%27%27`: `SET =''` + +Rules: +* The values for string variables must be quoted with ' +* The values must also be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed! + (which implies values of string variables must be wrapped with `%27`) + +Examples: + * `autocommit=1`: `SET autocommit=1` + * [`time_zone=%27Europe%2FParis%27`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `SET time_zone='Europe/Paris'` + * [`tx_isolation=%27REPEATABLE-READ%27`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `SET tx_isolation='REPEATABLE-READ'` -*The values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!* #### Examples ``` diff --git a/vendor/github.com/go-sql-driver/mysql/packets.go b/vendor/github.com/go-sql-driver/mysql/packets.go index 9160beb090e8a..481f1ddea4c23 100644 --- a/vendor/github.com/go-sql-driver/mysql/packets.go +++ b/vendor/github.com/go-sql-driver/mysql/packets.go @@ -25,9 +25,9 @@ import ( // Read packet to buffer 'data' func (mc *mysqlConn) readPacket() ([]byte, error) { - var payload []byte + var prevData []byte for { - // Read packet header + // read packet header data, err := mc.buf.readNext(4) if err != nil { errLog.Print(err) @@ -35,16 +35,10 @@ func (mc *mysqlConn) readPacket() ([]byte, error) { return nil, driver.ErrBadConn } - // Packet Length [24 bit] + // packet length [24 bit] pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16) - if pktLen < 1 { - errLog.Print(ErrMalformPkt) - mc.Close() - return nil, driver.ErrBadConn - } - - // Check Packet Sync [8 bit] + // check packet sync [8 bit] if data[3] != mc.sequence { if data[3] > mc.sequence { return nil, ErrPktSyncMul @@ -53,7 +47,20 @@ func (mc *mysqlConn) readPacket() ([]byte, error) { } mc.sequence++ - // Read packet body [pktLen bytes] + // packets with length 0 terminate a previous packet which is a + // multiple of (2^24)−1 bytes long + if pktLen == 0 { + // there was no previous packet + if prevData == nil { + errLog.Print(ErrMalformPkt) + mc.Close() + return nil, driver.ErrBadConn + } + + return prevData, nil + } + + // read packet body [pktLen bytes] data, err = mc.buf.readNext(pktLen) if err != nil { errLog.Print(err) @@ -61,18 +68,17 @@ func (mc *mysqlConn) readPacket() ([]byte, error) { return nil, driver.ErrBadConn } - isLastPacket := (pktLen < maxPacketSize) + // return data if this was the last packet + if pktLen < maxPacketSize { + // zero allocations for non-split packets + if prevData == nil { + return data, nil + } - // Zero allocations for non-splitting packets - if isLastPacket && payload == nil { - return data, nil + return append(prevData, data...), nil } - payload = append(payload, data...) - - if isLastPacket { - return payload, nil - } + prevData = append(prevData, data...) } } @@ -700,11 +706,15 @@ func (rows *textRows) readRow(dest []driver.Value) error { if data[0] == iEOF && len(data) == 5 { // server_status [2 bytes] rows.mc.status = readStatus(data[3:]) - if err := rows.mc.discardResults(); err != nil { - return err + err = rows.mc.discardResults() + if err == nil { + err = io.EOF + } else { + // connection unusable + rows.mc.Close() } rows.mc = nil - return io.EOF + return err } if data[0] == iERR { rows.mc = nil @@ -1105,11 +1115,15 @@ func (rows *binaryRows) readRow(dest []driver.Value) error { // EOF Packet if data[0] == iEOF && len(data) == 5 { rows.mc.status = readStatus(data[3:]) - if err := rows.mc.discardResults(); err != nil { - return err + err = rows.mc.discardResults() + if err == nil { + err = io.EOF + } else { + // connection unusable + rows.mc.Close() } rows.mc = nil - return io.EOF + return err } rows.mc = nil diff --git a/vendor/github.com/go-sql-driver/mysql/statement.go b/vendor/github.com/go-sql-driver/mysql/statement.go index ead9a6bf4711f..7f9b045857430 100644 --- a/vendor/github.com/go-sql-driver/mysql/statement.go +++ b/vendor/github.com/go-sql-driver/mysql/statement.go @@ -24,7 +24,10 @@ type mysqlStmt struct { func (stmt *mysqlStmt) Close() error { if stmt.mc == nil || stmt.mc.netConn == nil { - errLog.Print(ErrInvalidConn) + // driver.Stmt.Close can be called more than once, thus this function + // has to be idempotent. + // See also Issue #450 and golang/go#16019. + //errLog.Print(ErrInvalidConn) return driver.ErrBadConn } diff --git a/vendor/github.com/gocql/gocql/AUTHORS b/vendor/github.com/gocql/gocql/AUTHORS index 36d2285702d0b..e030be78cf5c7 100644 --- a/vendor/github.com/gocql/gocql/AUTHORS +++ b/vendor/github.com/gocql/gocql/AUTHORS @@ -82,3 +82,4 @@ Robert Nix Nathan Youngman Charles Law ; Nathan Davies +Bo Blanton diff --git a/vendor/github.com/gocql/gocql/address_translators.go b/vendor/github.com/gocql/gocql/address_translators.go new file mode 100644 index 0000000000000..6638bcaa83e2a --- /dev/null +++ b/vendor/github.com/gocql/gocql/address_translators.go @@ -0,0 +1,26 @@ +package gocql + +import "net" + +// AddressTranslator provides a way to translate node addresses (and ports) that are +// discovered or received as a node event. This can be useful in an ec2 environment, +// for instance, to translate public IPs to private IPs. +type AddressTranslator interface { + // Translate will translate the provided address and/or port to another + // address and/or port. If no translation is possible, Translate will return the + // address and port provided to it. + Translate(addr net.IP, port int) (net.IP, int) +} + +type AddressTranslatorFunc func(addr net.IP, port int) (net.IP, int) + +func (fn AddressTranslatorFunc) Translate(addr net.IP, port int) (net.IP, int) { + return fn(addr, port) +} + +// IdentityTranslator will do nothing but return what it was provided. It is essentially a no-op. +func IdentityTranslator() AddressTranslator { + return AddressTranslatorFunc(func(addr net.IP, port int) (net.IP, int) { + return addr, port + }) +} diff --git a/vendor/github.com/gocql/gocql/cluster.go b/vendor/github.com/gocql/gocql/cluster.go index f1637c8455584..cff9466291a82 100644 --- a/vendor/github.com/gocql/gocql/cluster.go +++ b/vendor/github.com/gocql/gocql/cluster.go @@ -6,6 +6,8 @@ package gocql import ( "errors" + "log" + "net" "time" ) @@ -75,6 +77,10 @@ type ClusterConfig struct { // via Discovery HostFilter HostFilter + // AddressTranslator will translate addresses found on peer discovery and/or + // node change events. + AddressTranslator AddressTranslator + // If IgnorePeerAddr is true and the address in system.peers does not match // the supplied host by either initial hosts or discovered via events then the // host will be replaced with the supplied address. @@ -146,6 +152,21 @@ func (cfg *ClusterConfig) CreateSession() (*Session, error) { return NewSession(*cfg) } +// translateAddressPort is a helper method that will use the given AddressTranslator +// if defined, to translate the given address and port into a possibly new address +// and port, If no AddressTranslator or if an error occurs, the given address and +// port will be returned. +func (cfg *ClusterConfig) translateAddressPort(addr net.IP, port int) (net.IP, int) { + if cfg.AddressTranslator == nil || len(addr) == 0 { + return addr, port + } + newAddr, newPort := cfg.AddressTranslator.Translate(addr, port) + if gocqlDebug { + log.Printf("gocql: translating address '%v:%d' to '%v:%d'", addr, port, newAddr, newPort) + } + return newAddr, newPort +} + var ( ErrNoHosts = errors.New("no hosts provided") ErrNoConnectionsStarted = errors.New("no connections were made when creating the session") diff --git a/vendor/github.com/gocql/gocql/conn.go b/vendor/github.com/gocql/gocql/conn.go index 4bd719924c902..a1a7cdd107100 100644 --- a/vendor/github.com/gocql/gocql/conn.go +++ b/vendor/github.com/gocql/gocql/conn.go @@ -172,7 +172,9 @@ func Connect(host *HostInfo, cfg *ConnConfig, errorHandler ConnErrorHandler, ses } // TODO(zariel): handle ipv6 zone - addr := (&net.TCPAddr{IP: host.Peer(), Port: host.Port()}).String() + translatedPeer, translatedPort := session.cfg.translateAddressPort(host.Peer(), host.Port()) + addr := (&net.TCPAddr{IP: translatedPeer, Port: translatedPort}).String() + //addr := (&net.TCPAddr{IP: host.Peer(), Port: host.Port()}).String() if cfg.tlsConfig != nil { // the TLS config is safe to be reused by connections but it must not diff --git a/vendor/github.com/gocql/gocql/control.go b/vendor/github.com/gocql/gocql/control.go index fd4eb43f6b7b6..22137daf2601c 100644 --- a/vendor/github.com/gocql/gocql/control.go +++ b/vendor/github.com/gocql/gocql/control.go @@ -318,8 +318,8 @@ func (c *controlConn) reconnect(refreshring bool) { } } - // TODO: should have our own roundrobbin for hosts so that we can try each - // in succession and guantee that we get a different host each time. + // TODO: should have our own round-robin for hosts so that we can try each + // in succession and guarantee that we get a different host each time. if newConn == nil { host := c.session.ring.rrHost() if host == nil { diff --git a/vendor/github.com/gocql/gocql/events.go b/vendor/github.com/gocql/gocql/events.go index 4a7ab23709eff..b067dc441c996 100644 --- a/vendor/github.com/gocql/gocql/events.go +++ b/vendor/github.com/gocql/gocql/events.go @@ -205,7 +205,6 @@ func (s *Session) handleNewNode(ip net.IP, port int, waitForBinary bool) { s.pool.addHost(hostInfo) s.policy.AddHost(hostInfo) hostInfo.setState(NodeUp) - if s.control != nil && !s.cfg.IgnorePeerAddr { s.hostSource.refreshRing() } diff --git a/vendor/github.com/gocql/gocql/integration.sh b/vendor/github.com/gocql/gocql/integration.sh index e97625d6e9dbb..a6692d2151052 100755 --- a/vendor/github.com/gocql/gocql/integration.sh +++ b/vendor/github.com/gocql/gocql/integration.sh @@ -64,7 +64,7 @@ function run_tests() { local args="-gocql.timeout=60s -runssl -proto=$proto -rf=3 -clusterSize=$clusterSize -autowait=2000ms -compressor=snappy -gocql.cversion=$version -cluster=$(ccm liveset) ./..." - go test -v -tags unit + go test -v -tags unit if [ "$auth" = true ] then diff --git a/vendor/github.com/gocql/gocql/token.go b/vendor/github.com/gocql/gocql/token.go index 75ae34244fe55..1113b9276a833 100644 --- a/vendor/github.com/gocql/gocql/token.go +++ b/vendor/github.com/gocql/gocql/token.go @@ -204,14 +204,21 @@ func (t *tokenRing) GetHostForToken(token token) *HostInfo { return nil } + l := len(t.tokens) + // no host tokens, no available hosts + if l == 0 { + return nil + } + // find the primary replica ringIndex := sort.Search( - len(t.tokens), + l, func(i int) bool { return !t.tokens[i].Less(token) }, ) - if ringIndex == len(t.tokens) { + + if ringIndex == l { // wrap around to the first in the ring ringIndex = 0 } diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go index 6b9b363746607..eaad21831263e 100644 --- a/vendor/github.com/golang/protobuf/proto/extensions.go +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -154,6 +154,7 @@ type ExtensionDesc struct { Field int32 // field number Name string // fully-qualified name of extension, for text formatting Tag string // protobuf tag style + Filename string // name of the file in which the extension is defined } func (ed *ExtensionDesc) repeated() bool { diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go index 4fd0531293a26..61f83c1e10fa1 100644 --- a/vendor/github.com/golang/protobuf/proto/text_parser.go +++ b/vendor/github.com/golang/protobuf/proto/text_parser.go @@ -592,7 +592,11 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { props = oop.Prop nv := reflect.New(oop.Type.Elem()) dst = nv.Elem().Field(0) - sv.Field(oop.Field).Set(nv) + field := sv.Field(oop.Field) + if !field.IsNil() { + return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) + } + field.Set(nv) } if !dst.IsValid() { return p.errorf("unknown field name %q in %v", name, st) diff --git a/vendor/github.com/google/go-github/github/activity_events.go b/vendor/github.com/google/go-github/github/activity_events.go index 6bf38b4e2cec8..0fd850e762fad 100644 --- a/vendor/github.com/google/go-github/github/activity_events.go +++ b/vendor/github.com/google/go-github/github/activity_events.go @@ -55,10 +55,14 @@ func (e *Event) Payload() (payload interface{}) { payload = &IssueCommentEvent{} case "IssuesEvent": payload = &IssuesEvent{} + case "LabelEvent": + payload = &LabelEvent{} case "MemberEvent": payload = &MemberEvent{} case "MembershipEvent": payload = &MembershipEvent{} + case "MilestoneEvent": + payload = &MilestoneEvent{} case "PageBuildEvent": payload = &PageBuildEvent{} case "PublicEvent": diff --git a/vendor/github.com/google/go-github/github/authorizations.go b/vendor/github.com/google/go-github/github/authorizations.go index 35ce9a97b887d..d5a5e631d41da 100644 --- a/vendor/github.com/google/go-github/github/authorizations.go +++ b/vendor/github.com/google/go-github/github/authorizations.go @@ -346,9 +346,6 @@ func (s *AuthorizationsService) ListGrants() ([]*Grant, *Response, error) { return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeOAuthGrantAuthorizationsPreview) - grants := []*Grant{} resp, err := s.client.Do(req, &grants) if err != nil { @@ -368,9 +365,6 @@ func (s *AuthorizationsService) GetGrant(id int) (*Grant, *Response, error) { return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeOAuthGrantAuthorizationsPreview) - grant := new(Grant) resp, err := s.client.Do(req, grant) if err != nil { @@ -392,9 +386,6 @@ func (s *AuthorizationsService) DeleteGrant(id int) (*Response, error) { return nil, err } - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeOAuthGrantAuthorizationsPreview) - return s.client.Do(req, nil) } diff --git a/vendor/github.com/google/go-github/github/event_types.go b/vendor/github.com/google/go-github/github/event_types.go index 16f89b04bdc92..3abe1efc2de36 100644 --- a/vendor/github.com/google/go-github/github/event_types.go +++ b/vendor/github.com/google/go-github/github/event_types.go @@ -209,6 +209,22 @@ type IssuesEvent struct { Sender *User `json:"sender,omitempty"` } +// LabelEvent is triggered when a repository's label is created, edited, or deleted. +// The Webhook event name is "label" +// +// GitHub docs: https://developer.github.com/v3/activity/events/types/#labelevent +type LabelEvent struct { + // Action is the action that was performed. Possible values are: + // "created", "edited", "deleted" + Action *string `json:"action,omitempty"` + Label *Label `json:"label,omitempty"` + + // The following fields are only populated by Webhook events. + Changes *EditChange `json:"changes,omitempty"` + Repo *Repository `json:"repository,omitempty"` + Org *Organization `json:"organization,omitempty"` +} + // MemberEvent is triggered when a user is added as a collaborator to a repository. // The Webhook event name is "member". // @@ -243,6 +259,23 @@ type MembershipEvent struct { Sender *User `json:"sender,omitempty"` } +// MilestoneEvent is triggered when a milestone is created, closed, opened, edited, or deleted. +// The Webhook event name is "milestone". +// +// Github docs: https://developer.github.com/v3/activity/events/types/#milestoneevent +type MilestoneEvent struct { + // Action is the action that was performed. Possible values are: + // "created", "closed", "opened", "edited", "deleted" + Action *string `json:"action,omitempty"` + Milestone *Milestone `json:"milestone,omitempty"` + + // The following fields are only populated by Webhook events. + Changes *EditChange `json:"changes,omitempty"` + Repo *Repository `json:"repository,omitempty"` + Sender *User `json:"sender,omitempty"` + Org *Organization `json:"organization,omitempty"` +} + // PageBuildEvent represents an attempted build of a GitHub Pages site, whether // successful or not. // The Webhook event name is "page_build". diff --git a/vendor/github.com/google/go-github/github/github.go b/vendor/github.com/google/go-github/github/github.go index 465574b9f2e05..258f9e2156bb7 100644 --- a/vendor/github.com/google/go-github/github/github.go +++ b/vendor/github.com/google/go-github/github/github.go @@ -68,6 +68,7 @@ const ( mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview" // https://developer.github.com/changes/2016-04-01-squash-api-preview/ + // https://developer.github.com/changes/2016-09-26-pull-request-merge-api-update/ mediaTypeSquashPreview = "application/vnd.github.polaris-preview+json" // https://developer.github.com/changes/2016-04-04-git-signing-api-preview/ @@ -79,9 +80,6 @@ const ( // https://developer.github.com/changes/2016-06-14-repository-invitations/ mediaTypeRepositoryInvitationsPreview = "application/vnd.github.swamp-thing-preview+json" - // https://developer.github.com/changes/2016-04-21-oauth-authorizations-grants-api-preview/ - mediaTypeOAuthGrantAuthorizationsPreview = "application/vnd.github.damage-preview+json" - // https://developer.github.com/changes/2016-07-06-github-pages-preiew-api/ mediaTypePagesPreview = "application/vnd.github.mister-fantastic-preview+json" @@ -126,6 +124,7 @@ type Client struct { Integrations *IntegrationsService Issues *IssuesService Organizations *OrganizationsService + Projects *ProjectsService PullRequests *PullRequestsService Repositories *RepositoriesService Search *SearchService @@ -199,6 +198,7 @@ func NewClient(httpClient *http.Client) *Client { c.Licenses = (*LicensesService)(&c.common) c.Migrations = (*MigrationService)(&c.common) c.Organizations = (*OrganizationsService)(&c.common) + c.Projects = (*ProjectsService)(&c.common) c.PullRequests = (*PullRequestsService)(&c.common) c.Reactions = (*ReactionsService)(&c.common) c.Repositories = (*RepositoriesService)(&c.common) diff --git a/vendor/github.com/google/go-github/github/licenses.go b/vendor/github.com/google/go-github/github/licenses.go index 35cd234191e80..0b5e8b38294f1 100644 --- a/vendor/github.com/google/go-github/github/licenses.go +++ b/vendor/github.com/google/go-github/github/licenses.go @@ -10,23 +10,44 @@ import "fmt" // LicensesService handles communication with the license related // methods of the GitHub API. // -// GitHub API docs: http://developer.github.com/v3/pulls/ +// GitHub API docs: https://developer.github.com/v3/licenses/ type LicensesService service +// RepositoryLicense represents the license for a repository. +type RepositoryLicense struct { + Name *string `json:"name,omitempty"` + Path *string `json:"path,omitempty"` + + SHA *string `json:"sha,omitempty"` + Size *int `json:"size,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + GitURL *string `json:"git_url,omitempty"` + DownloadURL *string `json:"download_url,omitempty"` + Type *string `json:"type,omitempty"` + Content *string `json:"content,omitempty"` + Encoding *string `json:"encoding,omitempty"` + License *License `json:"license,omitempty"` +} + +func (l RepositoryLicense) String() string { + return Stringify(l) +} + // License represents an open source license. type License struct { Key *string `json:"key,omitempty"` Name *string `json:"name,omitempty"` URL *string `json:"url,omitempty"` + SPDXID *string `json:"spdx_id,omitempty"` HTMLURL *string `json:"html_url,omitempty"` Featured *bool `json:"featured,omitempty"` Description *string `json:"description,omitempty"` - Category *string `json:"category,omitempty"` Implementation *string `json:"implementation,omitempty"` - Required *[]string `json:"required,omitempty"` - Permitted *[]string `json:"permitted,omitempty"` - Forbidden *[]string `json:"forbidden,omitempty"` + Permissions *[]string `json:"permissions,omitempty"` + Conditions *[]string `json:"conditions,omitempty"` + Limitations *[]string `json:"limitations,omitempty"` Body *string `json:"body,omitempty"` } diff --git a/vendor/github.com/google/go-github/github/messages.go b/vendor/github.com/google/go-github/github/messages.go index eedb190e4c39d..810e9fd6fd4ec 100644 --- a/vendor/github.com/google/go-github/github/messages.go +++ b/vendor/github.com/google/go-github/github/messages.go @@ -49,8 +49,10 @@ var ( "integration_installation_repositories": "IntegrationInstallationRepositoriesEvent", "issue_comment": "IssueCommentEvent", "issues": "IssuesEvent", + "label": "LabelEvent", "member": "MemberEvent", "membership": "MembershipEvent", + "milestone": "MilestoneEvent", "page_build": "PageBuildEvent", "public": "PublicEvent", "pull_request_review_comment": "PullRequestReviewCommentEvent", diff --git a/vendor/github.com/google/go-github/github/projects.go b/vendor/github.com/google/go-github/github/projects.go new file mode 100644 index 0000000000000..b1c3c754a59b4 --- /dev/null +++ b/vendor/github.com/google/go-github/github/projects.go @@ -0,0 +1,417 @@ +// Copyright 2016 The go-github 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 github + +import "fmt" + +// ProjectsService provides access to the projects functions in the +// GitHub API. +// +// GitHub API docs: https://developer.github.com/v3/projects/ +type ProjectsService service + +// Project represents a GitHub Project. +type Project struct { + ID *int `json:"id,omitempty"` + URL *string `json:"url,omitempty"` + OwnerURL *string `json:"owner_url,omitempty"` + Name *string `json:"name,omitempty"` + Body *string `json:"body,omitempty"` + Number *int `json:"number,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + + // The User object that generated the project. + Creator *User `json:"creator,omitempty"` +} + +func (p Project) String() string { + return Stringify(p) +} + +// GetProject gets a GitHub Project for a repo. +// +// GitHub API docs: https://developer.github.com/v3/projects/#get-a-project +func (s *ProjectsService) GetProject(id int) (*Project, *Response, error) { + u := fmt.Sprintf("/projects/%v", id) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + project := &Project{} + resp, err := s.client.Do(req, project) + if err != nil { + return nil, resp, err + } + + return project, resp, err +} + +// ProjectOptions specifies the parameters to the +// RepositoriesService.CreateProject and +// ProjectsService.UpdateProject methods. +type ProjectOptions struct { + // The name of the project. (Required for creation; optional for update.) + Name string `json:"name,omitempty"` + // The body of the project. (Optional.) + Body string `json:"body,omitempty"` +} + +// UpdateProject updates a repository project. +// +// GitHub API docs: https://developer.github.com/v3/projects/#update-a-project +func (s *ProjectsService) UpdateProject(id int, opt *ProjectOptions) (*Project, *Response, error) { + u := fmt.Sprintf("/projects/%v", id) + req, err := s.client.NewRequest("PATCH", u, opt) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + project := &Project{} + resp, err := s.client.Do(req, project) + if err != nil { + return nil, resp, err + } + + return project, resp, err +} + +// DeleteProject deletes a GitHub Project from a repository. +// +// GitHub API docs: https://developer.github.com/v3/projects/#delete-a-project +func (s *ProjectsService) DeleteProject(id int) (*Response, error) { + u := fmt.Sprintf("/projects/%v", id) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} + +// ProjectColumn represents a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/ +type ProjectColumn struct { + ID *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + ProjectURL *string `json:"project_url,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` +} + +// ListProjectColumns lists the columns of a GitHub Project for a repo. +// +// GitHub API docs: https://developer.github.com/v3/projects/columns/#list-project-columns +func (s *ProjectsService) ListProjectColumns(projectId int, opt *ListOptions) ([]*ProjectColumn, *Response, error) { + u := fmt.Sprintf("/projects/%v/columns", projectId) + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + columns := []*ProjectColumn{} + resp, err := s.client.Do(req, &columns) + if err != nil { + return nil, resp, err + } + + return columns, resp, err +} + +// GetProjectColumn gets a column of a GitHub Project for a repo. +// +// GitHub API docs: https://developer.github.com/v3/projects/columns/#get-a-project-column +func (s *ProjectsService) GetProjectColumn(id int) (*ProjectColumn, *Response, error) { + u := fmt.Sprintf("/projects/columns/%v", id) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + column := &ProjectColumn{} + resp, err := s.client.Do(req, column) + if err != nil { + return nil, resp, err + } + + return column, resp, err +} + +// ProjectColumnOptions specifies the parameters to the +// ProjectsService.CreateProjectColumn and +// ProjectsService.UpdateProjectColumn methods. +type ProjectColumnOptions struct { + // The name of the project column. (Required for creation and update.) + Name string `json:"name"` +} + +// CreateProjectColumn creates a column for the specified (by number) project. +// +// GitHub API docs: https://developer.github.com/v3/projects/columns/#create-a-project-column +func (s *ProjectsService) CreateProjectColumn(projectId int, opt *ProjectColumnOptions) (*ProjectColumn, *Response, error) { + u := fmt.Sprintf("/projects/%v/columns", projectId) + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + column := &ProjectColumn{} + resp, err := s.client.Do(req, column) + if err != nil { + return nil, resp, err + } + + return column, resp, err +} + +// UpdateProjectColumn updates a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/columns/#update-a-project-column +func (s *ProjectsService) UpdateProjectColumn(columnID int, opt *ProjectColumnOptions) (*ProjectColumn, *Response, error) { + u := fmt.Sprintf("/projects/columns/%v", columnID) + req, err := s.client.NewRequest("PATCH", u, opt) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + column := &ProjectColumn{} + resp, err := s.client.Do(req, column) + if err != nil { + return nil, resp, err + } + + return column, resp, err +} + +// DeleteProjectColumn deletes a column from a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/columns/#delete-a-project-column +func (s *ProjectsService) DeleteProjectColumn(columnID int) (*Response, error) { + u := fmt.Sprintf("/projects/columns/%v", columnID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} + +// ProjectColumnMoveOptions specifies the parameters to the +// ProjectsService.MoveProjectColumn method. +type ProjectColumnMoveOptions struct { + // Position can be one of "first", "last", or "after:", where + // is the ID of a column in the same project. (Required.) + Position string `json:"position"` +} + +// MoveProjectColumn moves a column within a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/columns/#move-a-project-column +func (s *ProjectsService) MoveProjectColumn(columnID int, opt *ProjectColumnMoveOptions) (*Response, error) { + u := fmt.Sprintf("/projects/columns/%v/moves", columnID) + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} + +// ProjectCard represents a card in a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/ +type ProjectCard struct { + ColumnURL *string `json:"column_url,omitempty"` + ContentURL *string `json:"content_url,omitempty"` + ID *int `json:"id,omitempty"` + Note *string `json:"note,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` +} + +// ListProjectCards lists the cards in a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/cards/#list-project-cards +func (s *ProjectsService) ListProjectCards(columnID int, opt *ListOptions) ([]*ProjectCard, *Response, error) { + u := fmt.Sprintf("/projects/columns/%v/cards", columnID) + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + cards := []*ProjectCard{} + resp, err := s.client.Do(req, &cards) + if err != nil { + return nil, resp, err + } + + return cards, resp, err +} + +// GetProjectCard gets a card in a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/cards/#get-a-project-card +func (s *ProjectsService) GetProjectCard(columnID int) (*ProjectCard, *Response, error) { + u := fmt.Sprintf("/projects/columns/cards/%v", columnID) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + card := &ProjectCard{} + resp, err := s.client.Do(req, card) + if err != nil { + return nil, resp, err + } + + return card, resp, err +} + +// ProjectCardOptions specifies the parameters to the +// ProjectsService.CreateProjectCard and +// ProjectsService.UpdateProjectCard methods. +type ProjectCardOptions struct { + // The note of the card. Note and ContentID are mutually exclusive. + Note string `json:"note,omitempty"` + // The ID (not Number) of the Issue or Pull Request to associate with this card. + // Note and ContentID are mutually exclusive. + ContentID int `json:"content_id,omitempty"` + // The type of content to associate with this card. Possible values are: "Issue", "PullRequest". + ContentType string `json:"content_type,omitempty"` +} + +// CreateProjectCard creates a card in the specified column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/cards/#create-a-project-card +func (s *ProjectsService) CreateProjectCard(columnID int, opt *ProjectCardOptions) (*ProjectCard, *Response, error) { + u := fmt.Sprintf("/projects/columns/%v/cards", columnID) + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + card := &ProjectCard{} + resp, err := s.client.Do(req, card) + if err != nil { + return nil, resp, err + } + + return card, resp, err +} + +// UpdateProjectCard updates a card of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/cards/#update-a-project-card +func (s *ProjectsService) UpdateProjectCard(cardID int, opt *ProjectCardOptions) (*ProjectCard, *Response, error) { + u := fmt.Sprintf("/projects/columns/cards/%v", cardID) + req, err := s.client.NewRequest("PATCH", u, opt) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + card := &ProjectCard{} + resp, err := s.client.Do(req, card) + if err != nil { + return nil, resp, err + } + + return card, resp, err +} + +// DeleteProjectCard deletes a card from a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/cards/#delete-a-project-card +func (s *ProjectsService) DeleteProjectCard(cardID int) (*Response, error) { + u := fmt.Sprintf("/projects/columns/cards/%v", cardID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} + +// ProjectCardMoveOptions specifies the parameters to the +// ProjectsService.MoveProjectCard method. +type ProjectCardMoveOptions struct { + // Position can be one of "top", "bottom", or "after:", where + // is the ID of a card in the same project. + Position string `json:"position"` + // ColumnID is the ID of a column in the same project. Note that ColumnID + // is required when using Position "after:" when that card is in + // another column; otherwise it is optional. + ColumnID int `json:"column_id,omitempty"` +} + +// MoveProjectCard moves a card within a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/projects/cards/#move-a-project-card +func (s *ProjectsService) MoveProjectCard(cardID int, opt *ProjectCardMoveOptions) (*Response, error) { + u := fmt.Sprintf("/projects/columns/cards/%v/moves", cardID) + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/google/go-github/github/pulls.go b/vendor/github.com/google/go-github/github/pulls.go index 3c883658db4da..85e04f8c07ec2 100644 --- a/vendor/github.com/google/go-github/github/pulls.go +++ b/vendor/github.com/google/go-github/github/pulls.go @@ -253,12 +253,16 @@ type PullRequestMergeResult struct { // PullRequestOptions lets you define how a pull request will be merged. type PullRequestOptions struct { - Squash bool + CommitTitle string + + // The merge method to use. Possible values include: "merge", "squash", and "rebase" with the default being merge. + MergeMethod string } type pullRequestMergeRequest struct { CommitMessage *string `json:"commit_message"` - Squash *bool `json:"squash,omitempty"` + CommitTitle *string `json:"commit_title,omitempty"` + MergeMethod *string `json:"merge_method,omitempty"` } // Merge a pull request (Merge Button™). @@ -269,7 +273,8 @@ func (s *PullRequestsService) Merge(owner string, repo string, number int, commi pullRequestBody := &pullRequestMergeRequest{CommitMessage: &commitMessage} if options != nil { - pullRequestBody.Squash = &options.Squash + pullRequestBody.CommitTitle = &options.CommitTitle + pullRequestBody.MergeMethod = &options.MergeMethod } req, err := s.client.NewRequest("PUT", u, pullRequestBody) diff --git a/vendor/github.com/google/go-github/github/repos.go b/vendor/github.com/google/go-github/github/repos.go index 98e4ac5ac11ef..ff846735bd894 100644 --- a/vendor/github.com/google/go-github/github/repos.go +++ b/vendor/github.com/google/go-github/github/repos.go @@ -5,7 +5,10 @@ package github -import "fmt" +import ( + "fmt" + "strings" +) // RepositoriesService handles communication with the repository related // methods of the GitHub API. @@ -46,6 +49,9 @@ type Repository struct { Source *Repository `json:"source,omitempty"` Organization *Organization `json:"organization,omitempty"` Permissions *map[string]bool `json:"permissions,omitempty"` + AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` + AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` + AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` // Only provided when using RepositoriesService.Get while in preview License *License `json:"license,omitempty"` @@ -286,7 +292,8 @@ func (s *RepositoriesService) Get(owner, repo string) (*Repository, *Response, e // TODO: remove custom Accept header when the license support fully launches // https://developer.github.com/v3/licenses/#get-a-repositorys-license - req.Header.Set("Accept", mediaTypeLicensesPreview) + acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeSquashPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) repository := new(Repository) resp, err := s.client.Do(req, repository) @@ -330,6 +337,9 @@ func (s *RepositoriesService) Edit(owner, repo string, repository *Repository) ( return nil, nil, err } + // TODO: Remove this preview header after API is fully vetted. + req.Header.Add("Accept", mediaTypeSquashPreview) + r := new(Repository) resp, err := s.client.Do(req, r) if err != nil { @@ -585,18 +595,18 @@ func (s *RepositoriesService) EditBranch(owner, repo, branchName string, branch // License gets the contents of a repository's license if one is detected. // // GitHub API docs: https://developer.github.com/v3/licenses/#get-the-contents-of-a-repositorys-license -func (s *RepositoriesService) License(owner, repo string) (*License, *Response, error) { +func (s *RepositoriesService) License(owner, repo string) (*RepositoryLicense, *Response, error) { u := fmt.Sprintf("repos/%v/%v/license", owner, repo) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err } - r := &Repository{} + r := &RepositoryLicense{} resp, err := s.client.Do(req, r) if err != nil { return nil, resp, err } - return r.License, resp, err + return r, resp, err } diff --git a/vendor/github.com/google/go-github/github/repos_pages.go b/vendor/github.com/google/go-github/github/repos_pages.go index ccd24f3777848..5194f27bf4d98 100644 --- a/vendor/github.com/google/go-github/github/repos_pages.go +++ b/vendor/github.com/google/go-github/github/repos_pages.go @@ -36,7 +36,7 @@ type PagesBuild struct { // GetPagesInfo fetches information about a GitHub Pages site. // // GitHub API docs: https://developer.github.com/v3/repos/pages/#get-information-about-a-pages-site -func (s *RepositoriesService) GetPagesInfo(owner string, repo string) (*Pages, *Response, error) { +func (s *RepositoriesService) GetPagesInfo(owner, repo string) (*Pages, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -58,7 +58,7 @@ func (s *RepositoriesService) GetPagesInfo(owner string, repo string) (*Pages, * // ListPagesBuilds lists the builds for a GitHub Pages site. // // GitHub API docs: https://developer.github.com/v3/repos/pages/#list-pages-builds -func (s *RepositoriesService) ListPagesBuilds(owner string, repo string) ([]*PagesBuild, *Response, error) { +func (s *RepositoriesService) ListPagesBuilds(owner, repo string) ([]*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -77,7 +77,7 @@ func (s *RepositoriesService) ListPagesBuilds(owner string, repo string) ([]*Pag // GetLatestPagesBuild fetches the latest build information for a GitHub pages site. // // GitHub API docs: https://developer.github.com/v3/repos/pages/#list-latest-pages-build -func (s *RepositoriesService) GetLatestPagesBuild(owner string, repo string) (*PagesBuild, *Response, error) { +func (s *RepositoriesService) GetLatestPagesBuild(owner, repo string) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds/latest", owner, repo) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -93,10 +93,29 @@ func (s *RepositoriesService) GetLatestPagesBuild(owner string, repo string) (*P return build, resp, err } +// GetPageBuild fetches the specific build information for a GitHub pages site. +// +// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-a-specific-pages-build +func (s *RepositoriesService) GetPageBuild(owner, repo string, id int) (*PagesBuild, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/pages/builds/%v", owner, repo, id) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + build := new(PagesBuild) + resp, err := s.client.Do(req, build) + if err != nil { + return nil, resp, err + } + + return build, resp, err +} + // RequestPageBuild requests a build of a GitHub Pages site without needing to push new commit. // // GitHub API docs: https://developer.github.com/v3/repos/pages/#request-a-page-build -func (s *RepositoriesService) RequestPageBuild(owner string, repo string) (*PagesBuild, *Response, error) { +func (s *RepositoriesService) RequestPageBuild(owner, repo string) (*PagesBuild, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo) req, err := s.client.NewRequest("POST", u, nil) if err != nil { diff --git a/vendor/github.com/google/go-github/github/repos_projects.go b/vendor/github.com/google/go-github/github/repos_projects.go index e37e2202395c2..137f89d141c24 100644 --- a/vendor/github.com/google/go-github/github/repos_projects.go +++ b/vendor/github.com/google/go-github/github/repos_projects.go @@ -5,34 +5,11 @@ package github -import ( - "fmt" -) - -// Project represents a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/ -type Project struct { - ID *int `json:"id,omitempty"` - URL *string `json:"url,omitempty"` - OwnerURL *string `json:"owner_url,omitempty"` - Name *string `json:"name,omitempty"` - Body *string `json:"body,omitempty"` - Number *int `json:"number,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - UpdatedAt *Timestamp `json:"updated_at,omitempty"` - - // The User object that generated the project. - Creator *User `json:"creator,omitempty"` -} - -func (p Project) String() string { - return Stringify(p) -} +import "fmt" // ListProjects lists the projects for a repo. // -// GitHub API docs: https://developer.github.com/v3/repos/projects/#list-projects +// GitHub API docs: https://developer.github.com/v3/projects/#list-repository-projects func (s *RepositoriesService) ListProjects(owner, repo string, opt *ListOptions) ([]*Project, *Response, error) { u := fmt.Sprintf("repos/%v/%v/projects", owner, repo) u, err := addOptions(u, opt) @@ -57,44 +34,12 @@ func (s *RepositoriesService) ListProjects(owner, repo string, opt *ListOptions) return projects, resp, err } -// GetProject gets a GitHub Project for a repo. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#get-a-project -func (s *RepositoriesService) GetProject(owner, repo string, number int) (*Project, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/%v", owner, repo, number) - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - project := &Project{} - resp, err := s.client.Do(req, project) - if err != nil { - return nil, resp, err - } - - return project, resp, err -} - -// ProjectOptions specifies the parameters to the -// RepositoriesService.CreateProject and -// RepositoriesService.UpdateProject methods. -type ProjectOptions struct { - // The name of the project. (Required for creation; optional for update.) - Name string `json:"name,omitempty"` - // The body of the project. (Optional.) - Body string `json:"body,omitempty"` -} - // CreateProject creates a GitHub Project for the specified repository. // -// GitHub API docs: https://developer.github.com/v3/repos/projects/#create-a-project -func (s *RepositoriesService) CreateProject(owner, repo string, projectOptions *ProjectOptions) (*Project, *Response, error) { +// GitHub API docs: https://developer.github.com/v3/projects/#create-a-repository-project +func (s *RepositoriesService) CreateProject(owner, repo string, opt *ProjectOptions) (*Project, *Response, error) { u := fmt.Sprintf("repos/%v/%v/projects", owner, repo) - req, err := s.client.NewRequest("POST", u, projectOptions) + req, err := s.client.NewRequest("POST", u, opt) if err != nil { return nil, nil, err } @@ -110,355 +55,3 @@ func (s *RepositoriesService) CreateProject(owner, repo string, projectOptions * return project, resp, err } - -// UpdateProject updates a repository project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#update-a-project -func (s *RepositoriesService) UpdateProject(owner, repo string, number int, projectOptions *ProjectOptions) (*Project, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/%v", owner, repo, number) - req, err := s.client.NewRequest("PATCH", u, projectOptions) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - project := &Project{} - resp, err := s.client.Do(req, project) - if err != nil { - return nil, resp, err - } - - return project, resp, err -} - -// DeleteProject deletes a GitHub Project from a repository. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#delete-a-project -func (s *RepositoriesService) DeleteProject(owner, repo string, number int) (*Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/%v", owner, repo, number) - req, err := s.client.NewRequest("DELETE", u, nil) - if err != nil { - return nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - return s.client.Do(req, nil) -} - -// ProjectColumn represents a column of a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/ -type ProjectColumn struct { - ID *int `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - ProjectURL *string `json:"project_url,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - UpdatedAt *Timestamp `json:"updated_at,omitempty"` -} - -// ListProjectColumns lists the columns of a GitHub Project for a repo. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#list-columns -func (s *RepositoriesService) ListProjectColumns(owner, repo string, number int, opt *ListOptions) ([]*ProjectColumn, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/%v/columns", owner, repo, number) - u, err := addOptions(u, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - columns := []*ProjectColumn{} - resp, err := s.client.Do(req, &columns) - if err != nil { - return nil, resp, err - } - - return columns, resp, err -} - -// GetProjectColumn gets a column of a GitHub Project for a repo. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#get-a-column -func (s *RepositoriesService) GetProjectColumn(owner, repo string, columnID int) (*ProjectColumn, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/%v", owner, repo, columnID) - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - column := &ProjectColumn{} - resp, err := s.client.Do(req, column) - if err != nil { - return nil, resp, err - } - - return column, resp, err -} - -// ProjectColumnOptions specifies the parameters to the -// RepositoriesService.CreateProjectColumn and -// RepositoriesService.UpdateProjectColumn methods. -type ProjectColumnOptions struct { - // The name of the project column. (Required for creation and update.) - Name string `json:"name"` -} - -// CreateProjectColumn creates a column for the specified (by number) project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#create-a-column -func (s *RepositoriesService) CreateProjectColumn(owner, repo string, number int, columnOptions *ProjectColumnOptions) (*ProjectColumn, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/%v/columns", owner, repo, number) - req, err := s.client.NewRequest("POST", u, columnOptions) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - column := &ProjectColumn{} - resp, err := s.client.Do(req, column) - if err != nil { - return nil, resp, err - } - - return column, resp, err -} - -// UpdateProjectColumn updates a column of a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#update-a-column -func (s *RepositoriesService) UpdateProjectColumn(owner, repo string, columnID int, columnOptions *ProjectColumnOptions) (*ProjectColumn, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/%v", owner, repo, columnID) - req, err := s.client.NewRequest("PATCH", u, columnOptions) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - column := &ProjectColumn{} - resp, err := s.client.Do(req, column) - if err != nil { - return nil, resp, err - } - - return column, resp, err -} - -// DeleteProjectColumn deletes a column from a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#delete-a-column -func (s *RepositoriesService) DeleteProjectColumn(owner, repo string, columnID int) (*Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/%v", owner, repo, columnID) - req, err := s.client.NewRequest("DELETE", u, nil) - if err != nil { - return nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - return s.client.Do(req, nil) -} - -// ProjectColumnMoveOptions specifies the parameters to the -// RepositoriesService.MoveProjectColumn method. -type ProjectColumnMoveOptions struct { - // Position can be one of "first", "last", or "after:", where - // is the ID of a column in the same project. (Required.) - Position string `json:"position"` -} - -// MoveProjectColumn moves a column within a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#move-a-column -func (s *RepositoriesService) MoveProjectColumn(owner, repo string, columnID int, moveOptions *ProjectColumnMoveOptions) (*Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/%v/moves", owner, repo, columnID) - req, err := s.client.NewRequest("POST", u, moveOptions) - if err != nil { - return nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - return s.client.Do(req, nil) -} - -// ProjectCard represents a card in a column of a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/ -type ProjectCard struct { - ColumnURL *string `json:"column_url,omitempty"` - ContentURL *string `json:"content_url,omitempty"` - ID *int `json:"id,omitempty"` - Note *string `json:"note,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - UpdatedAt *Timestamp `json:"updated_at,omitempty"` -} - -// ListProjectCards lists the cards in a column of a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#list-projects-cards -func (s *RepositoriesService) ListProjectCards(owner, repo string, columnID int, opt *ListOptions) ([]*ProjectCard, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/%v/cards", owner, repo, columnID) - u, err := addOptions(u, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - cards := []*ProjectCard{} - resp, err := s.client.Do(req, &cards) - if err != nil { - return nil, resp, err - } - - return cards, resp, err -} - -// GetProjectCard gets a card in a column of a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#get-a-project-card -func (s *RepositoriesService) GetProjectCard(owner, repo string, columnID int) (*ProjectCard, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/cards/%v", owner, repo, columnID) - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - card := &ProjectCard{} - resp, err := s.client.Do(req, card) - if err != nil { - return nil, resp, err - } - - return card, resp, err -} - -// ProjectCardOptions specifies the parameters to the -// RepositoriesService.CreateProjectCard and -// RepositoriesService.UpdateProjectCard methods. -type ProjectCardOptions struct { - // The note of the card. Note and ContentID are mutually exclusive. - Note string `json:"note,omitempty"` - // The ID (not Number) of the Issue or Pull Request to associate with this card. - // Note and ContentID are mutually exclusive. - ContentID int `json:"content_id,omitempty"` - // The type of content to associate with this card. Possible values are: "Issue", "PullRequest". - ContentType string `json:"content_type,omitempty"` -} - -// CreateProjectCard creates a card in the specified column of a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#create-a-project-card -func (s *RepositoriesService) CreateProjectCard(owner, repo string, columnID int, cardOptions *ProjectCardOptions) (*ProjectCard, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/%v/cards", owner, repo, columnID) - req, err := s.client.NewRequest("POST", u, cardOptions) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - card := &ProjectCard{} - resp, err := s.client.Do(req, card) - if err != nil { - return nil, resp, err - } - - return card, resp, err -} - -// UpdateProjectCard updates a card of a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#update-a-project-card -func (s *RepositoriesService) UpdateProjectCard(owner, repo string, cardID int, cardOptions *ProjectCardOptions) (*ProjectCard, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/cards/%v", owner, repo, cardID) - req, err := s.client.NewRequest("PATCH", u, cardOptions) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - card := &ProjectCard{} - resp, err := s.client.Do(req, card) - if err != nil { - return nil, resp, err - } - - return card, resp, err -} - -// DeleteProjectCard deletes a card from a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#delete-a-project-card -func (s *RepositoriesService) DeleteProjectCard(owner, repo string, cardID int) (*Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/cards/%v", owner, repo, cardID) - req, err := s.client.NewRequest("DELETE", u, nil) - if err != nil { - return nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - return s.client.Do(req, nil) -} - -// ProjectCardMoveOptions specifies the parameters to the -// RepositoriesService.MoveProjectCard method. -type ProjectCardMoveOptions struct { - // Position can be one of "top", "bottom", or "after:", where - // is the ID of a card in the same project. - Position string `json:"position"` - // ColumnID is the ID of a column in the same project. Note that ColumnID - // is required when using Position "after:" when that card is in - // another column; otherwise it is optional. - ColumnID int `json:"column_id,omitempty"` -} - -// MoveProjectCard moves a card within a GitHub Project. -// -// GitHub API docs: https://developer.github.com/v3/repos/projects/#move-a-project-card -func (s *RepositoriesService) MoveProjectCard(owner, repo string, cardID int, moveOptions *ProjectCardMoveOptions) (*Response, error) { - u := fmt.Sprintf("repos/%v/%v/projects/columns/cards/%v/moves", owner, repo, cardID) - req, err := s.client.NewRequest("POST", u, moveOptions) - if err != nil { - return nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeProjectsPreview) - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/hashicorp/consul/api/agent.go b/vendor/github.com/hashicorp/consul/api/agent.go index 87a6c10016ce4..41d8bc0b1f668 100644 --- a/vendor/github.com/hashicorp/consul/api/agent.go +++ b/vendor/github.com/hashicorp/consul/api/agent.go @@ -73,6 +73,7 @@ type AgentServiceCheck struct { HTTP string `json:",omitempty"` TCP string `json:",omitempty"` Status string `json:",omitempty"` + TLSSkipVerify string `json:",omitempty"` // In Consul 0.7 and later, checks that are associated with a service // may also contain this optional DeregisterCriticalServiceAfter field, diff --git a/vendor/github.com/hashicorp/consul/api/kv.go b/vendor/github.com/hashicorp/consul/api/kv.go index 5262243a1715d..867592490e9a3 100644 --- a/vendor/github.com/hashicorp/consul/api/kv.go +++ b/vendor/github.com/hashicorp/consul/api/kv.go @@ -156,7 +156,7 @@ func (k *KV) Keys(prefix, separator string, q *QueryOptions) ([]string, *QueryMe } func (k *KV) getInternal(key string, params map[string]string, q *QueryOptions) (*http.Response, *QueryMeta, error) { - r := k.c.newRequest("GET", "/v1/kv/"+key) + r := k.c.newRequest("GET", "/v1/kv/"+strings.TrimPrefix(key, "/")) r.setQueryOptions(q) for param, val := range params { r.params.Set(param, val) @@ -277,7 +277,7 @@ func (k *KV) DeleteTree(prefix string, w *WriteOptions) (*WriteMeta, error) { } func (k *KV) deleteInternal(key string, params map[string]string, q *WriteOptions) (bool, *WriteMeta, error) { - r := k.c.newRequest("DELETE", "/v1/kv/"+key) + r := k.c.newRequest("DELETE", "/v1/kv/"+strings.TrimPrefix(key, "/")) r.setWriteOptions(q) for param, val := range params { r.params.Set(param, val) diff --git a/vendor/github.com/hashicorp/consul/api/prepared_query.go b/vendor/github.com/hashicorp/consul/api/prepared_query.go index 63e741e050d5e..876e2e3b55e91 100644 --- a/vendor/github.com/hashicorp/consul/api/prepared_query.go +++ b/vendor/github.com/hashicorp/consul/api/prepared_query.go @@ -167,19 +167,18 @@ func (c *PreparedQuery) Get(queryID string, q *QueryOptions) ([]*PreparedQueryDe } // Delete is used to delete a specific prepared query. -func (c *PreparedQuery) Delete(queryID string, q *QueryOptions) (*QueryMeta, error) { +func (c *PreparedQuery) Delete(queryID string, q *WriteOptions) (*WriteMeta, error) { r := c.c.newRequest("DELETE", "/v1/query/"+queryID) - r.setQueryOptions(q) + r.setWriteOptions(q) rtt, resp, err := requireOK(c.c.doRequest(r)) if err != nil { return nil, err } defer resp.Body.Close() - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - return qm, nil + wm := &WriteMeta{} + wm.RequestTime = rtt + return wm, nil } // Execute is used to execute a specific prepared query. You can execute using diff --git a/vendor/github.com/hashicorp/go-multierror/format.go b/vendor/github.com/hashicorp/go-multierror/format.go index bb65a12e743af..6c7a3cc91de77 100644 --- a/vendor/github.com/hashicorp/go-multierror/format.go +++ b/vendor/github.com/hashicorp/go-multierror/format.go @@ -12,12 +12,16 @@ type ErrorFormatFunc func([]error) string // ListFormatFunc is a basic formatter that outputs the number of errors // that occurred along with a bullet point list of the errors. func ListFormatFunc(es []error) string { + if len(es) == 1 { + return fmt.Sprintf("1 error occurred:\n\n* %s", es[0]) + } + points := make([]string, len(es)) for i, err := range es { points[i] = fmt.Sprintf("* %s", err) } return fmt.Sprintf( - "%d error(s) occurred:\n\n%s", + "%d errors occurred:\n\n%s", len(es), strings.Join(points, "\n")) } diff --git a/vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go b/vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go index 956c8991c3432..d5787693f3ba8 100644 --- a/vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go +++ b/vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go @@ -46,7 +46,7 @@ func Unquote(s string) (t string, err error) { for len(s) > 0 { // If we're starting a '${}' then let it through un-unquoted. // Specifically: we don't unquote any characters within the `${}` - // section, except for escaped backslashes, which we handle specifically. + // section. if s[0] == '$' && len(s) > 1 && s[1] == '{' { buf = append(buf, '$', '{') s = s[2:] @@ -61,16 +61,6 @@ func Unquote(s string) (t string, err error) { s = s[size:] - // We special case escaped backslashes in interpolations, converting - // them to their unescaped equivalents. - if r == '\\' { - q, _ := utf8.DecodeRuneInString(s) - switch q { - case '\\': - continue - } - } - n := utf8.EncodeRune(runeTmp[:], r) buf = append(buf, runeTmp[:n]...) diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go index d21e0e161be3e..ca88dc8c6718c 100644 --- a/vendor/github.com/lib/pq/conn.go +++ b/vendor/github.com/lib/pq/conn.go @@ -1507,12 +1507,23 @@ func (rs *rows) Next(dest []driver.Value) (err error) { dest[i] = decode(&conn.parameterStatus, rs.rb.next(l), rs.colTyps[i], rs.colFmts[i]) } return + case 'T': + rs.colNames, rs.colFmts, rs.colTyps = parsePortalRowDescribe(&rs.rb) + return io.EOF default: errorf("unexpected message after execute: %q", t) } } } +func (rs *rows) HasNextResultSet() bool { + return !rs.done +} + +func (rs *rows) NextResultSet() error { + return nil +} + // QuoteIdentifier quotes an "identifier" (e.g. a table or a column name) to be // used as part of an SQL statement. For example: // diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go index 52d6653b34bb7..a7fe19a8ca0fe 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_others.go +++ b/vendor/github.com/mattn/go-colorable/colorable_others.go @@ -7,6 +7,7 @@ import ( "os" ) +// NewColorable return new instance of Writer which handle escape sequence. func NewColorable(file *os.File) io.Writer { if file == nil { panic("nil passed instead of *os.File to NewColorable()") @@ -15,10 +16,12 @@ func NewColorable(file *os.File) io.Writer { return file } +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. func NewColorableStdout() io.Writer { return os.Stdout } +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. func NewColorableStderr() io.Writer { return os.Stderr } diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go index 448277f563567..628ad904e5914 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go @@ -75,6 +75,7 @@ type Writer struct { oldpos coord } +// NewColorable return new instance of Writer which handle escape sequence from File. func NewColorable(file *os.File) io.Writer { if file == nil { panic("nil passed instead of *os.File to NewColorable()") @@ -90,10 +91,12 @@ func NewColorable(file *os.File) io.Writer { } } +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. func NewColorableStdout() io.Writer { return NewColorable(os.Stdout) } +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. func NewColorableStderr() io.Writer { return NewColorable(os.Stderr) } @@ -357,6 +360,7 @@ var color256 = map[int]int{ 255: 0xeeeeee, } +// Write write data on console func (w *Writer) Write(data []byte) (n int, err error) { var csbi consoleScreenBufferInfo procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go index b60801dcd5536..ca588c78ac778 100644 --- a/vendor/github.com/mattn/go-colorable/noncolorable.go +++ b/vendor/github.com/mattn/go-colorable/noncolorable.go @@ -5,15 +5,18 @@ import ( "io" ) +// NonColorable hold writer but remove escape sequence. type NonColorable struct { out io.Writer lastbuf bytes.Buffer } +// NewNonColorable return new instance of Writer which remove escape sequence from Writer. func NewNonColorable(w io.Writer) io.Writer { return &NonColorable{out: w} } +// Write write data on console func (w *NonColorable) Write(data []byte) (n int, err error) { er := bytes.NewReader(data) var bw [1]byte diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go index d1ed420ce07e4..134654cf7e2bf 100644 --- a/vendor/golang.org/x/net/context/context.go +++ b/vendor/golang.org/x/net/context/context.go @@ -36,6 +36,103 @@ // Contexts. package context // import "golang.org/x/net/context" +import "time" + +// A Context carries a deadline, a cancelation signal, and other values across +// API boundaries. +// +// Context's methods may be called by multiple goroutines simultaneously. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + // + // WithCancel arranges for Done to be closed when cancel is called; + // WithDeadline arranges for Done to be closed when the deadline + // expires; WithTimeout arranges for Done to be closed when the timeout + // elapses. + // + // Done is provided for use in select statements: + // + // // Stream generates values with DoSomething and sends them to out + // // until DoSomething returns an error or ctx.Done is closed. + // func Stream(ctx context.Context, out chan<- Value) error { + // for { + // v, err := DoSomething(ctx) + // if err != nil { + // return err + // } + // select { + // case <-ctx.Done(): + // return ctx.Err() + // case out <- v: + // } + // } + // } + // + // See http://blog.golang.org/pipelines for more examples of how to use + // a Done channel for cancelation. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + // + // A key identifies a specific value in a Context. Functions that wish + // to store values in Context typically allocate a key in a global + // variable then use that key as the argument to context.WithValue and + // Context.Value. A key can be any type that supports equality; + // packages should define keys as an unexported type to avoid + // collisions. + // + // Packages that define a Context key should provide type-safe accessors + // for the values stores using that key: + // + // // Package user defines a User type that's stored in Contexts. + // package user + // + // import "golang.org/x/net/context" + // + // // User is the type of value stored in the Contexts. + // type User struct {...} + // + // // key is an unexported type for keys defined in this package. + // // This prevents collisions with keys defined in other packages. + // type key int + // + // // userKey is the key for user.User values in Contexts. It is + // // unexported; clients use user.NewContext and user.FromContext + // // instead of using this key directly. + // var userKey key = 0 + // + // // NewContext returns a new Context that carries value u. + // func NewContext(ctx context.Context, u *User) context.Context { + // return context.WithValue(ctx, userKey, u) + // } + // + // // FromContext returns the User value stored in ctx, if any. + // func FromContext(ctx context.Context) (*User, bool) { + // u, ok := ctx.Value(userKey).(*User) + // return u, ok + // } + Value(key interface{}) interface{} +} + // Background returns a non-nil, empty Context. It is never canceled, has no // values, and has no deadline. It is typically used by the main function, // initialization, and tests, and as the top-level Context for incoming @@ -52,3 +149,8 @@ func Background() Context { func TODO() Context { return todo } + +// A CancelFunc tells an operation to abandon its work. +// A CancelFunc does not wait for the work to stop. +// After the first call, subsequent calls to a CancelFunc do nothing. +type CancelFunc func() diff --git a/vendor/golang.org/x/net/context/go18.go b/vendor/golang.org/x/net/context/go18.go deleted file mode 100644 index 35360c50dbeaf..0000000000000 --- a/vendor/golang.org/x/net/context/go18.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2016 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. - -// +build go1.8 - -package context - -import ( - "context" // standard library's context, as of Go 1.7 -) - -// A Context carries a deadline, a cancelation signal, and other values across -// API boundaries. -// -// Context's methods may be called by multiple goroutines simultaneously. -type Context => context.Context - -// A CancelFunc tells an operation to abandon its work. -// A CancelFunc does not wait for the work to stop. -// After the first call, subsequent calls to a CancelFunc do nothing. -type CancelFunc => context.CancelFunc diff --git a/vendor/golang.org/x/net/context/pre_go18.go b/vendor/golang.org/x/net/context/pre_go18.go deleted file mode 100644 index 41bd8ba666b91..0000000000000 --- a/vendor/golang.org/x/net/context/pre_go18.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2016 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. - -// +build !go1.8 - -package context - -import "time" - -// A CancelFunc tells an operation to abandon its work. -// A CancelFunc does not wait for the work to stop. -// After the first call, subsequent calls to a CancelFunc do nothing. -type CancelFunc func() - -// A Context carries a deadline, a cancelation signal, and other values across -// API boundaries. -// -// Context's methods may be called by multiple goroutines simultaneously. -type Context interface { - // Deadline returns the time when work done on behalf of this context - // should be canceled. Deadline returns ok==false when no deadline is - // set. Successive calls to Deadline return the same results. - Deadline() (deadline time.Time, ok bool) - - // Done returns a channel that's closed when work done on behalf of this - // context should be canceled. Done may return nil if this context can - // never be canceled. Successive calls to Done return the same value. - // - // WithCancel arranges for Done to be closed when cancel is called; - // WithDeadline arranges for Done to be closed when the deadline - // expires; WithTimeout arranges for Done to be closed when the timeout - // elapses. - // - // Done is provided for use in select statements: - // - // // Stream generates values with DoSomething and sends them to out - // // until DoSomething returns an error or ctx.Done is closed. - // func Stream(ctx context.Context, out chan<- Value) error { - // for { - // v, err := DoSomething(ctx) - // if err != nil { - // return err - // } - // select { - // case <-ctx.Done(): - // return ctx.Err() - // case out <- v: - // } - // } - // } - // - // See http://blog.golang.org/pipelines for more examples of how to use - // a Done channel for cancelation. - Done() <-chan struct{} - - // Err returns a non-nil error value after Done is closed. Err returns - // Canceled if the context was canceled or DeadlineExceeded if the - // context's deadline passed. No other values for Err are defined. - // After Done is closed, successive calls to Err return the same value. - Err() error - - // Value returns the value associated with this context for key, or nil - // if no value is associated with key. Successive calls to Value with - // the same key returns the same result. - // - // Use context values only for request-scoped data that transits - // processes and API boundaries, not for passing optional parameters to - // functions. - // - // A key identifies a specific value in a Context. Functions that wish - // to store values in Context typically allocate a key in a global - // variable then use that key as the argument to context.WithValue and - // Context.Value. A key can be any type that supports equality; - // packages should define keys as an unexported type to avoid - // collisions. - // - // Packages that define a Context key should provide type-safe accessors - // for the values stores using that key: - // - // // Package user defines a User type that's stored in Contexts. - // package user - // - // import "golang.org/x/net/context" - // - // // User is the type of value stored in the Contexts. - // type User struct {...} - // - // // key is an unexported type for keys defined in this package. - // // This prevents collisions with keys defined in other packages. - // type key int - // - // // userKey is the key for user.User values in Contexts. It is - // // unexported; clients use user.NewContext and user.FromContext - // // instead of using this key directly. - // var userKey key = 0 - // - // // NewContext returns a new Context that carries value u. - // func NewContext(ctx context.Context, u *User) context.Context { - // return context.WithValue(ctx, userKey, u) - // } - // - // // FromContext returns the User value stored in ctx, if any. - // func FromContext(ctx context.Context) (*User, bool) { - // u, ok := ctx.Value(userKey).(*User) - // return u, ok - // } - Value(key interface{}) interface{} -} diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go index e0002036ff83a..8c0dd25084493 100644 --- a/vendor/golang.org/x/net/http2/go18.go +++ b/vendor/golang.org/x/net/http2/go18.go @@ -35,3 +35,7 @@ func configureServer18(h1 *http.Server, h2 *Server) error { } return nil } + +func shouldLogPanic(panicValue interface{}) bool { + return panicValue != nil && panicValue != http.ErrAbortHandler +} diff --git a/vendor/golang.org/x/net/http2/not_go18.go b/vendor/golang.org/x/net/http2/not_go18.go index c1fa5910fed4d..2e600dc3546dd 100644 --- a/vendor/golang.org/x/net/http2/not_go18.go +++ b/vendor/golang.org/x/net/http2/not_go18.go @@ -12,3 +12,7 @@ func configureServer18(h1 *http.Server, h2 *Server) error { // No IdleTimeout to sync prior to Go 1.8. return nil } + +func shouldLogPanic(panicValue interface{}) bool { + return panicValue != nil +} diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index cd394d10e2c6e..0b6b4b08dc54f 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -188,9 +188,6 @@ func ConfigureServer(s *http.Server, conf *Server) error { if !haveNPN { s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS) } - // h2-14 is temporary (as of 2015-03-05) while we wait for all browsers - // to switch to "h2". - s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2-14") if s.TLSNextProto == nil { s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} @@ -205,7 +202,6 @@ func ConfigureServer(s *http.Server, conf *Server) error { }) } s.TLSNextProto[NextProtoTLS] = protoHandler - s.TLSNextProto["h2-14"] = protoHandler // temporary; see above. return nil } @@ -390,8 +386,8 @@ type serverConn struct { advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client curClientStreams uint32 // number of open streams initiated by the client curPushedStreams uint32 // number of open streams initiated by server push - maxStreamID uint32 // max ever seen from client - maxPushPromiseID uint32 // ID of the last push promise, or 0 if there have been no pushes + maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests + maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes streams map[uint32]*stream initialWindowSize int32 maxFrameSize int32 @@ -481,8 +477,14 @@ func (sc *serverConn) state(streamID uint32) (streamState, *stream) { // a client sends a HEADERS frame on stream 7 without ever sending a // frame on stream 5, then stream 5 transitions to the "closed" // state when the first frame for stream 7 is sent or received." - if streamID <= sc.maxStreamID { - return stateClosed, nil + if streamID%2 == 1 { + if streamID <= sc.maxClientStreamID { + return stateClosed, nil + } + } else { + if streamID <= sc.maxPushPromiseID { + return stateClosed, nil + } } return stateIdle, nil } @@ -740,7 +742,7 @@ func (sc *serverConn) serve() { return case <-gracefulShutdownCh: gracefulShutdownCh = nil - sc.goAwayIn(ErrCodeNo, 0) + sc.startGracefulShutdown() case <-sc.shutdownTimerCh: sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) return @@ -1015,7 +1017,7 @@ func (sc *serverConn) scheduleFrameWrite() { sc.needToSendGoAway = false sc.startFrameWrite(FrameWriteRequest{ write: &writeGoAway{ - maxStreamID: sc.maxStreamID, + maxStreamID: sc.maxClientStreamID, code: sc.goAwayCode, }, }) @@ -1042,6 +1044,13 @@ func (sc *serverConn) scheduleFrameWrite() { sc.inFrameScheduleLoop = false } +// startGracefulShutdown sends a GOAWAY with ErrCodeNo to tell the +// client we're gracefully shutting down. The connection isn't closed +// until all current streams are done. +func (sc *serverConn) startGracefulShutdown() { + sc.goAwayIn(ErrCodeNo, 0) +} + func (sc *serverConn) goAway(code ErrCode) { sc.serveG.check() var forceCloseIn time.Duration @@ -1164,6 +1173,8 @@ func (sc *serverConn) processFrame(f Frame) error { return sc.processResetStream(f) case *PriorityFrame: return sc.processPriority(f) + case *GoAwayFrame: + return sc.processGoAway(f) case *PushPromiseFrame: // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. @@ -1189,7 +1200,7 @@ func (sc *serverConn) processPing(f *PingFrame) error { // PROTOCOL_ERROR." return ConnectionError(ErrCodeProtocol) } - if sc.inGoAway { + if sc.inGoAway && sc.goAwayCode != ErrCodeNo { return nil } sc.writeFrame(FrameWriteRequest{write: writePingAck{f}}) @@ -1198,9 +1209,6 @@ func (sc *serverConn) processPing(f *PingFrame) error { func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error { sc.serveG.check() - if sc.inGoAway { - return nil - } switch { case f.StreamID != 0: // stream-level flow control state, st := sc.state(f.StreamID) @@ -1233,9 +1241,6 @@ func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error { func (sc *serverConn) processResetStream(f *RSTStreamFrame) error { sc.serveG.check() - if sc.inGoAway { - return nil - } state, st := sc.state(f.StreamID) if state == stateIdle { @@ -1265,12 +1270,15 @@ func (sc *serverConn) closeStream(st *stream, err error) { } else { sc.curClientStreams-- } - if sc.curClientStreams+sc.curPushedStreams == 0 { - sc.setConnState(http.StateIdle) - } delete(sc.streams, st.id) - if len(sc.streams) == 0 && sc.srv.IdleTimeout != 0 { - sc.idleTimer.Reset(sc.srv.IdleTimeout) + if len(sc.streams) == 0 { + sc.setConnState(http.StateIdle) + if sc.srv.IdleTimeout != 0 { + sc.idleTimer.Reset(sc.srv.IdleTimeout) + } + if h1ServerKeepAlivesDisabled(sc.hs) { + sc.startGracefulShutdown() + } } if p := st.body; p != nil { // Return any buffered unread bytes worth of conn-level flow control. @@ -1295,9 +1303,6 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error { } return nil } - if sc.inGoAway { - return nil - } if err := f.ForeachSetting(sc.processSetting); err != nil { return err } @@ -1369,7 +1374,7 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { func (sc *serverConn) processData(f *DataFrame) error { sc.serveG.check() - if sc.inGoAway { + if sc.inGoAway && sc.goAwayCode != ErrCodeNo { return nil } data := f.Data() @@ -1448,6 +1453,20 @@ func (sc *serverConn) processData(f *DataFrame) error { return nil } +func (sc *serverConn) processGoAway(f *GoAwayFrame) error { + sc.serveG.check() + if f.ErrCode != ErrCodeNo { + sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f) + } else { + sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f) + } + sc.startGracefulShutdown() + // http://tools.ietf.org/html/rfc7540#section-6.8 + // We should not create any new streams, which means we should disable push. + sc.pushEnabled = false + return nil +} + // isPushed reports whether the stream is server-initiated. func (st *stream) isPushed() bool { return st.id%2 == 0 @@ -1508,10 +1527,10 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // endpoint has opened or reserved. [...] An endpoint that // receives an unexpected stream identifier MUST respond with // a connection error (Section 5.4.1) of type PROTOCOL_ERROR. - if id <= sc.maxStreamID { + if id <= sc.maxClientStreamID { return ConnectionError(ErrCodeProtocol) } - sc.maxStreamID = id + sc.maxClientStreamID = id if sc.idleTimer != nil { sc.idleTimer.Stop() @@ -1847,15 +1866,17 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler rw.rws.stream.cancelCtx() if didPanic { e := recover() - // Same as net/http: - const size = 64 << 10 - buf := make([]byte, size) - buf = buf[:runtime.Stack(buf, false)] sc.writeFrameFromHandler(FrameWriteRequest{ write: handlerPanicRST{rw.rws.stream.id}, stream: rw.rws.stream, }) - sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf) + // Same as net/http: + if shouldLogPanic(e) { + const size = 64 << 10 + buf := make([]byte, size) + buf = buf[:runtime.Stack(buf, false)] + sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf) + } return } rw.handlerDone() @@ -2267,8 +2288,9 @@ func (w *responseWriter) CloseNotify() <-chan bool { if ch == nil { ch = make(chan bool, 1) rws.closeNotifierCh = ch + cw := rws.stream.cw go func() { - rws.stream.cw.Wait() // wait for close + cw.Wait() // wait for close ch <- true }() } @@ -2421,7 +2443,7 @@ func (w *responseWriter) push(target string, opts pushOptions) error { } for k := range opts.Header { if strings.HasPrefix(k, ":") { - return fmt.Errorf("promised request headers cannot include psuedo header %q", k) + return fmt.Errorf("promised request headers cannot include pseudo header %q", k) } // These headers are meaningful only if the request has a body, // but PUSH_PROMISE requests cannot have a body. @@ -2514,6 +2536,12 @@ func (sc *serverConn) startPush(msg startPushRequest) { // http://tools.ietf.org/html/rfc7540#section-5.1.1. // Streams initiated by the server MUST use even-numbered identifiers. + // A server that is unable to establish a new stream identifier can send a GOAWAY + // frame so that the client is forced to open a new connection for new streams. + if sc.maxPushPromiseID+2 >= 1<<31 { + sc.startGracefulShutdown() + return 0, ErrPushLimitReached + } sc.maxPushPromiseID += 2 promisedID := sc.maxPushPromiseID @@ -2660,3 +2688,17 @@ func h1ServerShutdownChan(hs *http.Server) <-chan struct{} { // optional test hook for h1ServerShutdownChan. var testh1ServerShutdownChan func(hs *http.Server) <-chan struct{} + +// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives +// disabled. See comments on h1ServerShutdownChan above for why +// the code is written this way. +func h1ServerKeepAlivesDisabled(hs *http.Server) bool { + var x interface{} = hs + type I interface { + doKeepAlives() bool + } + if hs, ok := x.(I); ok { + return !hs.doKeepAlives() + } + return false +} diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 129c8e02b8bfd..8f5f84412c697 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -199,6 +199,7 @@ type clientStream struct { bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read readErr error // sticky read error; owned by transportResponseBody.Read stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu + didReset bool // whether we sent a RST_STREAM to the server; guarded by cc.mu peerReset chan struct{} // closed on peer reset resetErr error // populated before peerReset is closed @@ -226,15 +227,26 @@ func (cs *clientStream) awaitRequestCancel(req *http.Request) { } select { case <-req.Cancel: + cs.cancelStream() cs.bufPipe.CloseWithError(errRequestCanceled) - cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) case <-ctx.Done(): + cs.cancelStream() cs.bufPipe.CloseWithError(ctx.Err()) - cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) case <-cs.done: } } +func (cs *clientStream) cancelStream() { + cs.cc.mu.Lock() + didReset := cs.didReset + cs.didReset = true + cs.cc.mu.Unlock() + + if !didReset { + cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) + } +} + // checkResetOrDone reports any error sent in a RST_STREAM frame by the // server, or errStreamClosed if the stream is complete. func (cs *clientStream) checkResetOrDone() error { @@ -1666,9 +1678,10 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { cc.bw.Flush() cc.wmu.Unlock() } + didReset := cs.didReset cc.mu.Unlock() - if len(data) > 0 { + if len(data) > 0 && !didReset { if _, err := cs.bufPipe.Write(data); err != nil { rl.endStreamError(cs, err) return err diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go index 9f3e1b3207fff..caa77c7cb363d 100644 --- a/vendor/golang.org/x/net/http2/writesched.go +++ b/vendor/golang.org/x/net/http2/writesched.go @@ -25,7 +25,9 @@ type WriteScheduler interface { // https://tools.ietf.org/html/rfc7540#section-5.1 AdjustStream(streamID uint32, priority PriorityParam) - // Push queues a frame in the scheduler. + // Push queues a frame in the scheduler. In most cases, this will not be + // called with wr.StreamID()!=0 unless that stream is currently open. The one + // exception is RST_STREAM frames, which may be sent on idle or closed streams. Push(wr FrameWriteRequest) // Pop dequeues the next frame to write. Returns false if no frames can @@ -62,6 +64,13 @@ type FrameWriteRequest struct { // 0 is used for non-stream frames such as PING and SETTINGS. func (wr FrameWriteRequest) StreamID() uint32 { if wr.stream == nil { + if se, ok := wr.write.(StreamError); ok { + // (*serverConn).resetStream doesn't set + // stream because it doesn't necessarily have + // one. So special case this type of write + // message. + return se.StreamID + } return 0 } return wr.stream.id @@ -142,17 +151,13 @@ func (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteReque // String is for debugging only. func (wr FrameWriteRequest) String() string { - var streamID uint32 - if wr.stream != nil { - streamID = wr.stream.id - } var des string if s, ok := wr.write.(fmt.Stringer); ok { des = s.String() } else { des = fmt.Sprintf("%T", wr.write) } - return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", streamID, wr.done != nil, des) + return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des) } // writeQueue is used by implementations of WriteScheduler. diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go index 40108b066458d..01132721bddda 100644 --- a/vendor/golang.org/x/net/http2/writesched_priority.go +++ b/vendor/golang.org/x/net/http2/writesched_priority.go @@ -388,7 +388,15 @@ func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { } else { n = ws.nodes[id] if n == nil { - panic("add on non-open stream") + // id is an idle or closed stream. wr should not be a HEADERS or + // DATA frame. However, wr can be a RST_STREAM. In this case, we + // push wr onto the root, rather than creating a new priorityNode, + // since RST_STREAM is tiny and the stream's priority is unknown + // anyway. See issue #17919. + if wr.DataSize() > 0 { + panic("add DATA on non-open stream") + } + n = &ws.root } } n.q.push(wr) diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go index 1826586214cf6..ecd766eb7fdc8 100644 --- a/vendor/golang.org/x/net/trace/trace.go +++ b/vendor/golang.org/x/net/trace/trace.go @@ -752,7 +752,7 @@ func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) { and very unlikely to be the fault of this code. The most likely scenario is that some code elsewhere is using - a requestz.Trace after its Finish method is called. + a trace.Trace after its Finish method is called. You can temporarily set the DebugUseAfterFinish var to help discover where that is; do not leave that var set, since it makes this package much less efficient. diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index cfac4a4409418..74eae9b67ccb4 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -899,6 +899,7 @@ func Getpgrp() (pid int) { //sysnb Getppid() (ppid int) //sys Getpriority(which int, who int) (prio int, err error) //sysnb Getrusage(who int, rusage *Rusage) (err error) +//sysnb Getsid(pid int) (sid int, err error) //sysnb Gettid() (tid int) //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) @@ -911,7 +912,7 @@ func Getpgrp() (pid int) { //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT -//sysnb prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) = SYS_PRLIMIT64 +//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) //sys read(fd int, p []byte) (n int, err error) //sys Removexattr(path string, attr string) (err error) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go index 80f6a1b0ad8bc..fa92387b1a55e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go index 078c8f05af870..b34d5c26f01b9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go index 76e5f7c0bbc9c..2e5cb39845ec1 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go index 72b79470a25fc..0d584cc0de69e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go index ba55509ea0e82..bf6f3603ba1c5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go index 2b1cc8473b640..8c86bd70b31e3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go index 25f39db9df0f5..f5d488b4a5420 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go index 70702b516668a..5183711ec87f2 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go index 94b93d3d02cda..4c7ed08cc400d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go index 774b10ed8ff3a..beb83e4fdc649 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go @@ -572,6 +572,17 @@ func Getrusage(who int, rusage *Rusage) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettid() (tid int) { r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) tid = int(r0) @@ -762,8 +773,8 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0) +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go index 09562c462b6ad..aba0f831b5f9e 100644 --- a/vendor/google.golang.org/appengine/internal/api.go +++ b/vendor/google.golang.org/appengine/internal/api.go @@ -576,6 +576,9 @@ var logLevelName = map[int64]string{ } func logf(c *context, level int64, format string, args ...interface{}) { + if c == nil { + panic("not an App Engine context") + } s := fmt.Sprintf(format, args...) s = strings.TrimRight(s, "\n") // Remove any trailing newline characters. c.addLogLine(&logpb.UserAppLogLine{ diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md index 110a8cf425312..39120c2031c82 100644 --- a/vendor/google.golang.org/grpc/README.md +++ b/vendor/google.golang.org/grpc/README.md @@ -18,6 +18,22 @@ Prerequisites This requires Go 1.5 or later. +A note on the version used: significant performance improvements in benchmarks +of grpc-go have been seen by upgrading the go version from 1.5 to the latest +1.7.1. + +From https://golang.org/doc/install, one way to install the latest version of go is: +``` +$ GO_VERSION=1.7.1 +$ OS=linux +$ ARCH=amd64 +$ curl -O https://storage.googleapis.com/golang/go${GO_VERSION}.${OS}-${ARCH}.tar.gz +$ sudo tar -C /usr/local -xzf go$GO_VERSION.$OS-$ARCH.tar.gz +$ # Put go on the PATH, keep the usual installation dir +$ sudo ln -s /usr/local/go/bin/go /usr/bin/go +$ rm go$GO_VERSION.$OS-$ARCH.tar.gz +``` + Constraints ----------- The grpc package should only depend on standard Go packages and a small number of exceptions. If your contribution introduces new dependencies which are NOT in the [list](http://godoc.org/google.golang.org/grpc?imports), you need a discussion with gRPC-Go authors and consultants. @@ -30,3 +46,12 @@ Status ------ GA +FAQ +--- + +#### Compiling error, undefined: grpc.SupportPackageIsVersion + +Please update proto package, gRPC package and rebuild the proto files: + - `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}` + - `go get -u google.golang.org/grpc` + - `protoc --go_out=plugins=grpc:. *.proto` diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index 772c817edd3d0..5d9214d153409 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -42,6 +42,7 @@ import ( "golang.org/x/net/context" "golang.org/x/net/trace" "google.golang.org/grpc/codes" + "google.golang.org/grpc/stats" "google.golang.org/grpc/transport" ) @@ -49,7 +50,8 @@ import ( // On error, it returns the error and indicates whether the call should be retried. // // TODO(zhaoq): Check whether the received message sequence is valid. -func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) (err error) { +// TODO ctx is used for stats collection and processing. It is the context passed from the application. +func recvResponse(ctx context.Context, dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) (err error) { // Try to acquire header metadata from the server if there is any. defer func() { if err != nil { @@ -63,14 +65,25 @@ func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, s return } p := &parser{r: stream} + var inPayload *stats.InPayload + if stats.On() { + inPayload = &stats.InPayload{ + Client: true, + } + } for { - if err = recv(p, dopts.codec, stream, dopts.dc, reply, math.MaxInt32); err != nil { + if err = recv(p, dopts.codec, stream, dopts.dc, reply, math.MaxInt32, inPayload); err != nil { if err == io.EOF { break } return } } + if inPayload != nil && err == io.EOF && stream.StatusCode() == codes.OK { + // TODO in the current implementation, inTrailer may be handled before inPayload in some cases. + // Fix the order if necessary. + stats.Handle(ctx, inPayload) + } c.trailerMD = stream.Trailer() return nil } @@ -89,15 +102,27 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd } } }() - var cbuf *bytes.Buffer + var ( + cbuf *bytes.Buffer + outPayload *stats.OutPayload + ) if compressor != nil { cbuf = new(bytes.Buffer) } - outBuf, err := encode(codec, args, compressor, cbuf) + if stats.On() { + outPayload = &stats.OutPayload{ + Client: true, + } + } + outBuf, err := encode(codec, args, compressor, cbuf, outPayload) if err != nil { return nil, Errorf(codes.Internal, "grpc: %v", err) } err = t.Write(stream, outBuf, opts) + if err == nil && outPayload != nil { + outPayload.SentTime = time.Now() + stats.Handle(ctx, outPayload) + } // t.NewStream(...) could lead to an early rejection of the RPC (e.g., the service/method // does not exist.) so that t.Write could get io.EOF from wait(...). Leave the following // recvResponse to get the final status. @@ -118,7 +143,7 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli return invoke(ctx, method, args, reply, cc, opts...) } -func invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) { +func invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (e error) { c := defaultCallInfo for _, o := range opts { if err := o.before(&c); err != nil { @@ -140,12 +165,30 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli c.traceInfo.tr.LazyLog(&c.traceInfo.firstLine, false) // TODO(dsymonds): Arrange for c.traceInfo.firstLine.remoteAddr to be set. defer func() { - if err != nil { - c.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + if e != nil { + c.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{e}}, true) c.traceInfo.tr.SetError() } }() } + if stats.On() { + begin := &stats.Begin{ + Client: true, + BeginTime: time.Now(), + FailFast: c.failFast, + } + stats.Handle(ctx, begin) + } + defer func() { + if stats.On() { + end := &stats.End{ + Client: true, + EndTime: time.Now(), + Error: e, + } + stats.Handle(ctx, end) + } + }() topts := &transport.Options{ Last: true, Delay: false, @@ -205,7 +248,7 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli } return toRPCErr(err) } - err = recvResponse(cc.dopts, t, &c, stream, reply) + err = recvResponse(ctx, cc.dopts, t, &c, stream, reply) if err != nil { if put != nil { put() diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index 61674729a77ba..f6dab4b772131 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -199,6 +199,8 @@ func WithTimeout(d time.Duration) DialOption { } // WithDialer returns a DialOption that specifies a function to use for dialing network addresses. +// If FailOnNonTempDialError() is set to true, and an error is returned by f, gRPC checks the error's +// Temporary() method to decide if it should try to reconnect to the network address. func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { return func(o *dialOptions) { o.copts.Dialer = func(ctx context.Context, addr string) (net.Conn, error) { @@ -210,6 +212,17 @@ func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { } } +// FailOnNonTempDialError returns a DialOption that specified if gRPC fails on non-temporary dial errors. +// If f is true, and dialer returns a non-temporary error, gRPC will fail the connection to the network +// address and won't try to reconnect. +// The default value of FailOnNonTempDialError is false. +// This is an EXPERIMENTAL API. +func FailOnNonTempDialError(f bool) DialOption { + return func(o *dialOptions) { + o.copts.FailOnNonTempDialError = f + } +} + // WithUserAgent returns a DialOption that specifies a user agent string for all the RPCs. func WithUserAgent(s string) DialOption { return func(o *dialOptions) { diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 6b60095d564ae..66d08b5aa2be0 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -42,11 +42,13 @@ import ( "io/ioutil" "math" "os" + "time" "github.com/golang/protobuf/proto" "golang.org/x/net/context" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/stats" "google.golang.org/grpc/transport" ) @@ -255,9 +257,11 @@ func (p *parser) recvMsg(maxMsgSize int) (pf payloadFormat, msg []byte, err erro // encode serializes msg and prepends the message header. If msg is nil, it // generates the message header of 0 message length. -func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer) ([]byte, error) { - var b []byte - var length uint +func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer, outPayload *stats.OutPayload) ([]byte, error) { + var ( + b []byte + length uint + ) if msg != nil { var err error // TODO(zhaoq): optimize to reduce memory alloc and copying. @@ -265,6 +269,12 @@ func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer) ([]byte if err != nil { return nil, err } + if outPayload != nil { + outPayload.Payload = msg + // TODO truncate large payload. + outPayload.Data = b + outPayload.Length = len(b) + } if cp != nil { if err := cp.Do(cbuf, b); err != nil { return nil, err @@ -295,6 +305,10 @@ func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer) ([]byte // Copy encoded msg to buf copy(buf[5:], b) + if outPayload != nil { + outPayload.WireLength = len(buf) + } + return buf, nil } @@ -311,11 +325,14 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) er return nil } -func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}, maxMsgSize int) error { +func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}, maxMsgSize int, inPayload *stats.InPayload) error { pf, d, err := p.recvMsg(maxMsgSize) if err != nil { return err } + if inPayload != nil { + inPayload.WireLength = len(d) + } if err := checkRecvPayload(pf, s.RecvCompress(), dc); err != nil { return err } @@ -333,6 +350,13 @@ func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{ if err := c.Unmarshal(d, m); err != nil { return Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err) } + if inPayload != nil { + inPayload.RecvTime = time.Now() + inPayload.Payload = m + // TODO truncate large payload. + inPayload.Data = d + inPayload.Length = len(d) + } return nil } @@ -448,10 +472,10 @@ func convertCode(err error) codes.Code { return codes.Unknown } -// SupportPackageIsVersion3 is referenced from generated protocol buffer files +// SupportPackageIsVersion4 is referenced from generated protocol buffer files // to assert that that code is compatible with this version of the grpc package. // // This constant may be renamed in the future if a change in the generated code // requires a synchronised update of grpc-go and protoc-gen-go. This constant // should not be referenced from any other code. -const SupportPackageIsVersion3 = true +const SupportPackageIsVersion4 = true diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index e0bb187ef9758..3af001ac94e58 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -54,6 +54,8 @@ import ( "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/tap" "google.golang.org/grpc/transport" ) @@ -110,6 +112,7 @@ type options struct { maxMsgSize int unaryInt UnaryServerInterceptor streamInt StreamServerInterceptor + inTapHandle tap.ServerInHandle maxConcurrentStreams uint32 useHandlerImpl bool // use http.Handler-based server } @@ -186,6 +189,17 @@ func StreamInterceptor(i StreamServerInterceptor) ServerOption { } } +// InTapHandle returns a ServerOption that sets the tap handle for all the server +// transport to be created. Only one can be installed. +func InTapHandle(h tap.ServerInHandle) ServerOption { + return func(o *options) { + if o.inTapHandle != nil { + panic("The tap handle has been set.") + } + o.inTapHandle = h + } +} + // NewServer creates a gRPC server which has no service registered and has not // started to accept requests yet. func NewServer(opt ...ServerOption) *Server { @@ -412,17 +426,22 @@ func (s *Server) handleRawConn(rawConn net.Conn) { if s.opts.useHandlerImpl { s.serveUsingHandler(conn) } else { - s.serveNewHTTP2Transport(conn, authInfo) + s.serveHTTP2Transport(conn, authInfo) } } -// serveNewHTTP2Transport sets up a new http/2 transport (using the +// serveHTTP2Transport sets up a http/2 transport (using the // gRPC http2 server transport in transport/http2_server.go) and // serves streams on it. // This is run in its own goroutine (it does network I/O in // transport.NewServerTransport). -func (s *Server) serveNewHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) { - st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo) +func (s *Server) serveHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) { + config := &transport.ServerConfig{ + MaxStreams: s.opts.maxConcurrentStreams, + AuthInfo: authInfo, + InTapHandle: s.opts.inTapHandle, + } + st, err := transport.NewServerTransport("http2", c, config) if err != nil { s.mu.Lock() s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err) @@ -448,6 +467,12 @@ func (s *Server) serveStreams(st transport.ServerTransport) { defer wg.Done() s.handleStream(st, stream, s.traceInfo(st, stream)) }() + }, func(ctx context.Context, method string) context.Context { + if !EnableTracing { + return ctx + } + tr := trace.New("grpc.Recv."+methodFamily(method), method) + return trace.NewContext(ctx, tr) }) wg.Wait() } @@ -497,15 +522,17 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // traceInfo returns a traceInfo and associates it with stream, if tracing is enabled. // If tracing is not enabled, it returns nil. func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) { - if !EnableTracing { + tr, ok := trace.FromContext(stream.Context()) + if !ok { return nil } + trInfo = &traceInfo{ - tr: trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()), + tr: tr, } trInfo.firstLine.client = false trInfo.firstLine.remoteAddr = st.RemoteAddr() - stream.TraceContext(trInfo.tr) + if dl, ok := stream.Context().Deadline(); ok { trInfo.firstLine.deadline = dl.Sub(time.Now()) } @@ -532,11 +559,17 @@ func (s *Server) removeConn(c io.Closer) { } func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options) error { - var cbuf *bytes.Buffer + var ( + cbuf *bytes.Buffer + outPayload *stats.OutPayload + ) if cp != nil { cbuf = new(bytes.Buffer) } - p, err := encode(s.opts.codec, msg, cp, cbuf) + if stats.On() { + outPayload = &stats.OutPayload{} + } + p, err := encode(s.opts.codec, msg, cp, cbuf, outPayload) if err != nil { // This typically indicates a fatal issue (e.g., memory // corruption or hardware faults) the application program @@ -547,10 +580,32 @@ func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Str // the optimal option. grpclog.Fatalf("grpc: Server failed to encode response %v", err) } - return t.Write(stream, p, opts) + err = t.Write(stream, p, opts) + if err == nil && outPayload != nil { + outPayload.SentTime = time.Now() + stats.Handle(stream.Context(), outPayload) + } + return err } func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc, trInfo *traceInfo) (err error) { + if stats.On() { + begin := &stats.Begin{ + BeginTime: time.Now(), + } + stats.Handle(stream.Context(), begin) + } + defer func() { + if stats.On() { + end := &stats.End{ + EndTime: time.Now(), + } + if err != nil && err != io.EOF { + end.Error = toRPCErr(err) + } + stats.Handle(stream.Context(), end) + } + }() if trInfo != nil { defer trInfo.tr.Finish() trInfo.firstLine.client = false @@ -579,14 +634,14 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if err != nil { switch err := err.(type) { case *rpcError: - if err := t.WriteStatus(stream, err.code, err.desc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + if e := t.WriteStatus(stream, err.code, err.desc); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) } case transport.ConnectionError: // Nothing to do here. case transport.StreamError: - if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + if e := t.WriteStatus(stream, err.Code, err.Desc); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) } default: panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", err, err)) @@ -597,20 +652,29 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil { switch err := err.(type) { case *rpcError: - if err := t.WriteStatus(stream, err.code, err.desc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + if e := t.WriteStatus(stream, err.code, err.desc); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) } + return err default: - if err := t.WriteStatus(stream, codes.Internal, err.Error()); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + if e := t.WriteStatus(stream, codes.Internal, err.Error()); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) } - + // TODO checkRecvPayload always return RPC error. Add a return here if necessary. + } + } + var inPayload *stats.InPayload + if stats.On() { + inPayload = &stats.InPayload{ + RecvTime: time.Now(), } - return err } statusCode := codes.OK statusDesc := "" df := func(v interface{}) error { + if inPayload != nil { + inPayload.WireLength = len(req) + } if pf == compressionMade { var err error req, err = s.opts.dc.Do(bytes.NewReader(req)) @@ -618,7 +682,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if err := t.WriteStatus(stream, codes.Internal, err.Error()); err != nil { grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) } - return err + return Errorf(codes.Internal, err.Error()) } } if len(req) > s.opts.maxMsgSize { @@ -630,6 +694,12 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if err := s.opts.codec.Unmarshal(req, v); err != nil { return err } + if inPayload != nil { + inPayload.Payload = v + inPayload.Data = req + inPayload.Length = len(req) + stats.Handle(stream.Context(), inPayload) + } if trInfo != nil { trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true) } @@ -650,9 +720,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } if err := t.WriteStatus(stream, statusCode, statusDesc); err != nil { grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) - return err } - return nil + return Errorf(statusCode, statusDesc) } if trInfo != nil { trInfo.tr.LazyLog(stringer("OK"), false) @@ -677,11 +746,32 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if trInfo != nil { trInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true) } - return t.WriteStatus(stream, statusCode, statusDesc) + errWrite := t.WriteStatus(stream, statusCode, statusDesc) + if statusCode != codes.OK { + return Errorf(statusCode, statusDesc) + } + return errWrite } } func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc, trInfo *traceInfo) (err error) { + if stats.On() { + begin := &stats.Begin{ + BeginTime: time.Now(), + } + stats.Handle(stream.Context(), begin) + } + defer func() { + if stats.On() { + end := &stats.End{ + EndTime: time.Now(), + } + if err != nil && err != io.EOF { + end.Error = toRPCErr(err) + } + stats.Handle(stream.Context(), end) + } + }() if s.opts.cp != nil { stream.SetSendCompress(s.opts.cp.Type()) } @@ -744,7 +834,11 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp } ss.mu.Unlock() } - return t.WriteStatus(ss.s, ss.statusCode, ss.statusDesc) + errWrite := t.WriteStatus(ss.s, ss.statusCode, ss.statusDesc) + if ss.statusCode != codes.OK { + return Errorf(ss.statusCode, ss.statusDesc) + } + return errWrite } @@ -759,7 +853,8 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []interface{}{sm}}, true) trInfo.tr.SetError() } - if err := t.WriteStatus(stream, codes.InvalidArgument, fmt.Sprintf("malformed method name: %q", stream.Method())); err != nil { + errDesc := fmt.Sprintf("malformed method name: %q", stream.Method()) + if err := t.WriteStatus(stream, codes.InvalidArgument, errDesc); err != nil { if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) trInfo.tr.SetError() @@ -779,7 +874,8 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str trInfo.tr.LazyLog(&fmtStringer{"Unknown service %v", []interface{}{service}}, true) trInfo.tr.SetError() } - if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown service %v", service)); err != nil { + errDesc := fmt.Sprintf("unknown service %v", service) + if err := t.WriteStatus(stream, codes.Unimplemented, errDesc); err != nil { if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) trInfo.tr.SetError() @@ -804,7 +900,8 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str trInfo.tr.LazyLog(&fmtStringer{"Unknown method %v", []interface{}{method}}, true) trInfo.tr.SetError() } - if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown method %v", method)); err != nil { + errDesc := fmt.Sprintf("unknown method %v", method) + if err := t.WriteStatus(stream, codes.Unimplemented, errDesc); err != nil { if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) trInfo.tr.SetError() diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go new file mode 100644 index 0000000000000..4b030d985ddf2 --- /dev/null +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -0,0 +1,219 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * 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. + * + * 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. + * + */ + +// Package stats is for collecting and reporting various network and RPC stats. +// This package is for monitoring purpose only. All fields are read-only. +// All APIs are experimental. +package stats // import "google.golang.org/grpc/stats" + +import ( + "net" + "sync/atomic" + "time" + + "golang.org/x/net/context" + "google.golang.org/grpc/grpclog" +) + +// RPCStats contains stats information about RPCs. +// All stats types in this package implements this interface. +type RPCStats interface { + // IsClient returns true if this RPCStats is from client side. + IsClient() bool +} + +// Begin contains stats when an RPC begins. +// FailFast are only valid if Client is true. +type Begin struct { + // Client is true if this Begin is from client side. + Client bool + // BeginTime is the time when the RPC begins. + BeginTime time.Time + // FailFast indicates if this RPC is failfast. + FailFast bool +} + +// IsClient indicates if this is from client side. +func (s *Begin) IsClient() bool { return s.Client } + +// InPayload contains the information for an incoming payload. +type InPayload struct { + // Client is true if this InPayload is from client side. + Client bool + // Payload is the payload with original type. + Payload interface{} + // Data is the serialized message payload. + Data []byte + // Length is the length of uncompressed data. + Length int + // WireLength is the length of data on wire (compressed, signed, encrypted). + WireLength int + // RecvTime is the time when the payload is received. + RecvTime time.Time +} + +// IsClient indicates if this is from client side. +func (s *InPayload) IsClient() bool { return s.Client } + +// InHeader contains stats when a header is received. +// FullMethod, addresses and Compression are only valid if Client is false. +type InHeader struct { + // Client is true if this InHeader is from client side. + Client bool + // WireLength is the wire length of header. + WireLength int + + // FullMethod is the full RPC method string, i.e., /package.service/method. + FullMethod string + // RemoteAddr is the remote address of the corresponding connection. + RemoteAddr net.Addr + // LocalAddr is the local address of the corresponding connection. + LocalAddr net.Addr + // Compression is the compression algorithm used for the RPC. + Compression string +} + +// IsClient indicates if this is from client side. +func (s *InHeader) IsClient() bool { return s.Client } + +// InTrailer contains stats when a trailer is received. +type InTrailer struct { + // Client is true if this InTrailer is from client side. + Client bool + // WireLength is the wire length of trailer. + WireLength int +} + +// IsClient indicates if this is from client side. +func (s *InTrailer) IsClient() bool { return s.Client } + +// OutPayload contains the information for an outgoing payload. +type OutPayload struct { + // Client is true if this OutPayload is from client side. + Client bool + // Payload is the payload with original type. + Payload interface{} + // Data is the serialized message payload. + Data []byte + // Length is the length of uncompressed data. + Length int + // WireLength is the length of data on wire (compressed, signed, encrypted). + WireLength int + // SentTime is the time when the payload is sent. + SentTime time.Time +} + +// IsClient indicates if this is from client side. +func (s *OutPayload) IsClient() bool { return s.Client } + +// OutHeader contains stats when a header is sent. +// FullMethod, addresses and Compression are only valid if Client is true. +type OutHeader struct { + // Client is true if this OutHeader is from client side. + Client bool + // WireLength is the wire length of header. + WireLength int + + // FullMethod is the full RPC method string, i.e., /package.service/method. + FullMethod string + // RemoteAddr is the remote address of the corresponding connection. + RemoteAddr net.Addr + // LocalAddr is the local address of the corresponding connection. + LocalAddr net.Addr + // Compression is the compression algorithm used for the RPC. + Compression string +} + +// IsClient indicates if this is from client side. +func (s *OutHeader) IsClient() bool { return s.Client } + +// OutTrailer contains stats when a trailer is sent. +type OutTrailer struct { + // Client is true if this OutTrailer is from client side. + Client bool + // WireLength is the wire length of trailer. + WireLength int +} + +// IsClient indicates if this is from client side. +func (s *OutTrailer) IsClient() bool { return s.Client } + +// End contains stats when an RPC ends. +type End struct { + // Client is true if this End is from client side. + Client bool + // EndTime is the time when the RPC ends. + EndTime time.Time + // Error is the error just happened. Its type is gRPC error. + Error error +} + +// IsClient indicates if this is from client side. +func (s *End) IsClient() bool { return s.Client } + +var ( + on = new(int32) + handler func(context.Context, RPCStats) +) + +// On indicates whether stats is started. +func On() bool { + return atomic.CompareAndSwapInt32(on, 1, 1) +} + +// Handle processes the stats using the call back function registered by user. +func Handle(ctx context.Context, s RPCStats) { + handler(ctx, s) +} + +// RegisterHandler registers the user handler function. +// If another handler was registered before, this new handler will overwrite the old one. +// This handler function will be called to process the stats. +func RegisterHandler(f func(context.Context, RPCStats)) { + handler = f +} + +// Start starts the stats collection and reporting if there is a registered stats handle. +func Start() { + if handler == nil { + grpclog.Println("handler is nil when starting stats. Stats is not started") + return + } + atomic.StoreInt32(on, 1) +} + +// Stop stops the stats collection and processing. +// Stop does not unregister handler. +func Stop() { + atomic.StoreInt32(on, 0) +} diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 46810544f19f7..95c8acf8d1990 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -45,6 +45,7 @@ import ( "golang.org/x/net/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/stats" "google.golang.org/grpc/transport" ) @@ -97,7 +98,7 @@ type ClientStream interface { // NewClientStream creates a new Stream for the client side. This is called // by generated code. -func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) { +func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { if cc.dopts.streamInt != nil { return cc.dopts.streamInt(ctx, desc, cc, method, newClientStream, opts...) } @@ -143,6 +144,24 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth } }() } + if stats.On() { + begin := &stats.Begin{ + Client: true, + BeginTime: time.Now(), + FailFast: c.failFast, + } + stats.Handle(ctx, begin) + } + defer func() { + if err != nil && stats.On() { + // Only handle end stats if err != nil. + end := &stats.End{ + Client: true, + Error: err, + } + stats.Handle(ctx, end) + } + }() gopts := BalancerGetOptions{ BlockingWait: !c.failFast, } @@ -194,6 +213,8 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth tracing: EnableTracing, trInfo: trInfo, + + statsCtx: ctx, } if cc.dopts.cp != nil { cs.cbuf = new(bytes.Buffer) @@ -246,6 +267,11 @@ type clientStream struct { // trInfo.tr is set when the clientStream is created (if EnableTracing is true), // and is set to nil when the clientStream's finish method is called. trInfo traceInfo + + // statsCtx keeps the user context for stats handling. + // All stats collection should use the statsCtx (instead of the stream context) + // so that all the generated stats for a particular RPC can be associated in the processing phase. + statsCtx context.Context } func (cs *clientStream) Context() context.Context { @@ -274,6 +300,8 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { } cs.mu.Unlock() } + // TODO Investigate how to signal the stats handling party. + // generate error stats if err != nil && err != io.EOF? defer func() { if err != nil { cs.finish(err) @@ -296,7 +324,13 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { } err = toRPCErr(err) }() - out, err := encode(cs.codec, m, cs.cp, cs.cbuf) + var outPayload *stats.OutPayload + if stats.On() { + outPayload = &stats.OutPayload{ + Client: true, + } + } + out, err := encode(cs.codec, m, cs.cp, cs.cbuf, outPayload) defer func() { if cs.cbuf != nil { cs.cbuf.Reset() @@ -305,11 +339,37 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { if err != nil { return Errorf(codes.Internal, "grpc: %v", err) } - return cs.t.Write(cs.s, out, &transport.Options{Last: false}) + err = cs.t.Write(cs.s, out, &transport.Options{Last: false}) + if err == nil && outPayload != nil { + outPayload.SentTime = time.Now() + stats.Handle(cs.statsCtx, outPayload) + } + return err } func (cs *clientStream) RecvMsg(m interface{}) (err error) { - err = recv(cs.p, cs.codec, cs.s, cs.dc, m, math.MaxInt32) + defer func() { + if err != nil && stats.On() { + // Only generate End if err != nil. + // If err == nil, it's not the last RecvMsg. + // The last RecvMsg gets either an RPC error or io.EOF. + end := &stats.End{ + Client: true, + EndTime: time.Now(), + } + if err != io.EOF { + end.Error = toRPCErr(err) + } + stats.Handle(cs.statsCtx, end) + } + }() + var inPayload *stats.InPayload + if stats.On() { + inPayload = &stats.InPayload{ + Client: true, + } + } + err = recv(cs.p, cs.codec, cs.s, cs.dc, m, math.MaxInt32, inPayload) defer func() { // err != nil indicates the termination of the stream. if err != nil { @@ -324,11 +384,15 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { } cs.mu.Unlock() } + if inPayload != nil { + stats.Handle(cs.statsCtx, inPayload) + } if !cs.desc.ClientStreams || cs.desc.ServerStreams { return } // Special handling for client streaming rpc. - err = recv(cs.p, cs.codec, cs.s, cs.dc, m, math.MaxInt32) + // This recv expects EOF or errors, so we don't collect inPayload. + err = recv(cs.p, cs.codec, cs.s, cs.dc, m, math.MaxInt32, nil) cs.closeTransportStream(err) if err == nil { return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) @@ -482,7 +546,11 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { ss.mu.Unlock() } }() - out, err := encode(ss.codec, m, ss.cp, ss.cbuf) + var outPayload *stats.OutPayload + if stats.On() { + outPayload = &stats.OutPayload{} + } + out, err := encode(ss.codec, m, ss.cp, ss.cbuf, outPayload) defer func() { if ss.cbuf != nil { ss.cbuf.Reset() @@ -495,6 +563,10 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { if err := ss.t.Write(ss.s, out, &transport.Options{Last: false}); err != nil { return toRPCErr(err) } + if outPayload != nil { + outPayload.SentTime = time.Now() + stats.Handle(ss.s.Context(), outPayload) + } return nil } @@ -513,7 +585,11 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { ss.mu.Unlock() } }() - if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize); err != nil { + var inPayload *stats.InPayload + if stats.On() { + inPayload = &stats.InPayload{} + } + if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize, inPayload); err != nil { if err == io.EOF { return err } @@ -522,5 +598,8 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { } return toRPCErr(err) } + if inPayload != nil { + stats.Handle(ss.s.Context(), inPayload) + } return nil } diff --git a/vendor/google.golang.org/grpc/tap/tap.go b/vendor/google.golang.org/grpc/tap/tap.go new file mode 100644 index 0000000000000..0f3664767423a --- /dev/null +++ b/vendor/google.golang.org/grpc/tap/tap.go @@ -0,0 +1,54 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * 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. + * + * 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. + * + */ + +// Package tap defines the function handles which are executed on the transport +// layer of gRPC-Go and related information. Everything here is EXPERIMENTAL. +package tap + +import ( + "golang.org/x/net/context" +) + +// Info defines the relevant information needed by the handles. +type Info struct { + // FullMethodName is the string of grpc method (in the format of + // /package.service/method). + FullMethodName string + // TODO: More to be added. +} + +// ServerInHandle defines the function which runs when a new stream is created +// on the server side. Note that it is executed in the per-connection I/O goroutine(s) instead +// of per-RPC goroutine. Therefore, users should NOT have any blocking/time-consuming +// work in this handle. Otherwise all the RPCs would slow down. +type ServerInHandle func(ctx context.Context, info *Info) (context.Context, error) diff --git a/vendor/google.golang.org/grpc/transport/handler_server.go b/vendor/google.golang.org/grpc/transport/handler_server.go index 114e34906a142..10b6dc0b19d73 100644 --- a/vendor/google.golang.org/grpc/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/transport/handler_server.go @@ -268,7 +268,7 @@ func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error { }) } -func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) { +func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), traceCtx func(context.Context, string) context.Context) { // With this transport type there will be exactly 1 stream: this HTTP request. var ctx context.Context diff --git a/vendor/google.golang.org/grpc/transport/http2_client.go b/vendor/google.golang.org/grpc/transport/http2_client.go index 2b0f68016af53..cbd9f32602632 100644 --- a/vendor/google.golang.org/grpc/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/transport/http2_client.go @@ -51,16 +51,19 @@ import ( "google.golang.org/grpc/grpclog" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" + "google.golang.org/grpc/stats" ) // http2Client implements the ClientTransport interface with HTTP2. type http2Client struct { - target string // server name/addr - userAgent string - md interface{} - conn net.Conn // underlying communication channel - authInfo credentials.AuthInfo // auth info about the connection - nextID uint32 // the next stream ID to be used + target string // server name/addr + userAgent string + md interface{} + conn net.Conn // underlying communication channel + remoteAddr net.Addr + localAddr net.Addr + authInfo credentials.AuthInfo // auth info about the connection + nextID uint32 // the next stream ID to be used // writableChan synchronizes write access to the transport. // A writer acquires the write lock by sending a value on writableChan @@ -150,6 +153,9 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) ( scheme := "http" conn, err := dial(ctx, opts.Dialer, addr.Addr) if err != nil { + if opts.FailOnNonTempDialError { + return nil, connectionErrorf(isTemporary(err), err, "transport: %v", err) + } return nil, connectionErrorf(true, err, "transport: %v", err) } // Any further errors will close the underlying connection @@ -175,11 +181,13 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) ( } var buf bytes.Buffer t := &http2Client{ - target: addr.Addr, - userAgent: ua, - md: addr.Metadata, - conn: conn, - authInfo: authInfo, + target: addr.Addr, + userAgent: ua, + md: addr.Metadata, + conn: conn, + remoteAddr: conn.RemoteAddr(), + localAddr: conn.LocalAddr(), + authInfo: authInfo, // The client initiated stream id is odd starting from 1. nextID: 1, writableChan: make(chan int, 1), @@ -270,12 +278,13 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { // streams. func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) { pr := &peer.Peer{ - Addr: t.conn.RemoteAddr(), + Addr: t.remoteAddr, } // Attach Auth info if there is any. if t.authInfo != nil { pr.AuthInfo = t.authInfo } + userCtx := ctx ctx = peer.NewContext(ctx, pr) authData := make(map[string]string) for _, c := range t.creds { @@ -347,6 +356,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea return nil, ErrConnClosing } s := t.newStream(ctx, callHdr) + s.clientStatsCtx = userCtx t.activeStreams[s.id] = s // This stream is not counted when applySetings(...) initialize t.streamsQuota. @@ -413,6 +423,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } } first := true + bufLen := t.hBuf.Len() // Sends the headers in a single batch even when they span multiple frames. for !endHeaders { size := t.hBuf.Len() @@ -447,6 +458,17 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea return nil, connectionErrorf(true, err, "transport: %v", err) } } + if stats.On() { + outHeader := &stats.OutHeader{ + Client: true, + WireLength: bufLen, + FullMethod: callHdr.Method, + RemoteAddr: t.remoteAddr, + LocalAddr: t.localAddr, + Compression: callHdr.SendCompress, + } + stats.Handle(s.clientStatsCtx, outHeader) + } t.writableChan <- 0 return s, nil } @@ -874,6 +896,24 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { } endStream := frame.StreamEnded() + var isHeader bool + defer func() { + if stats.On() { + if isHeader { + inHeader := &stats.InHeader{ + Client: true, + WireLength: int(frame.Header().Length), + } + stats.Handle(s.clientStatsCtx, inHeader) + } else { + inTrailer := &stats.InTrailer{ + Client: true, + WireLength: int(frame.Header().Length), + } + stats.Handle(s.clientStatsCtx, inTrailer) + } + } + }() s.mu.Lock() if !endStream { @@ -885,6 +925,7 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { } close(s.headerChan) s.headerDone = true + isHeader = true } if !endStream || s.state == streamDone { s.mu.Unlock() diff --git a/vendor/google.golang.org/grpc/transport/http2_server.go b/vendor/google.golang.org/grpc/transport/http2_server.go index a62fb7c228f14..db9beb90a658c 100644 --- a/vendor/google.golang.org/grpc/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/transport/http2_server.go @@ -50,6 +50,8 @@ import ( "google.golang.org/grpc/grpclog" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/tap" ) // ErrIllegalHeaderWrite indicates that setting header is illegal because of @@ -59,8 +61,11 @@ var ErrIllegalHeaderWrite = errors.New("transport: the stream is done or WriteHe // http2Server implements the ServerTransport interface with HTTP2. type http2Server struct { conn net.Conn + remoteAddr net.Addr + localAddr net.Addr maxStreamID uint32 // max stream ID ever seen authInfo credentials.AuthInfo // auth info about the connection + inTapHandle tap.ServerInHandle // writableChan synchronizes write access to the transport. // A writer acquires the write lock by receiving a value on writableChan // and releases it by sending on writableChan. @@ -91,12 +96,13 @@ type http2Server struct { // newHTTP2Server constructs a ServerTransport based on HTTP2. ConnectionError is // returned if something goes wrong. -func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthInfo) (_ ServerTransport, err error) { +func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) { framer := newFramer(conn) // Send initial settings as connection preface to client. var settings []http2.Setting // TODO(zhaoq): Have a better way to signal "no limit" because 0 is // permitted in the HTTP2 spec. + maxStreams := config.MaxStreams if maxStreams == 0 { maxStreams = math.MaxUint32 } else { @@ -122,11 +128,14 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI var buf bytes.Buffer t := &http2Server{ conn: conn, - authInfo: authInfo, + remoteAddr: conn.RemoteAddr(), + localAddr: conn.LocalAddr(), + authInfo: config.AuthInfo, framer: framer, hBuf: &buf, hEnc: hpack.NewEncoder(&buf), maxStreams: maxStreams, + inTapHandle: config.InTapHandle, controlBuf: newRecvBuffer(), fc: &inFlow{limit: initialConnWindowSize}, sendQuotaPool: newQuotaPool(defaultWindowSize), @@ -142,7 +151,7 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI } // operateHeader takes action on the decoded headers. -func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream)) (close bool) { +func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (close bool) { buf := newRecvBuffer() s := &Stream{ id: frame.Header().StreamID, @@ -173,7 +182,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( s.ctx, s.cancel = context.WithCancel(context.TODO()) } pr := &peer.Peer{ - Addr: t.conn.RemoteAddr(), + Addr: t.remoteAddr, } // Attach Auth info if there is any. if t.authInfo != nil { @@ -195,6 +204,18 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } s.recvCompress = state.encoding s.method = state.method + if t.inTapHandle != nil { + var err error + info := &tap.Info{ + FullMethodName: state.method, + } + s.ctx, err = t.inTapHandle(s.ctx, info) + if err != nil { + // TODO: Log the real error. + t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream}) + return + } + } t.mu.Lock() if t.state != reachable { t.mu.Unlock() @@ -218,13 +239,25 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( s.windowHandler = func(n int) { t.updateWindow(s, uint32(n)) } + s.ctx = traceCtx(s.ctx, s.method) + if stats.On() { + inHeader := &stats.InHeader{ + FullMethod: s.method, + RemoteAddr: t.remoteAddr, + LocalAddr: t.localAddr, + Compression: s.recvCompress, + WireLength: int(frame.Header().Length), + } + stats.Handle(s.ctx, inHeader) + } handle(s) return } // HandleStreams receives incoming streams using the given handler. This is // typically run in a separate goroutine. -func (t *http2Server) HandleStreams(handle func(*Stream)) { +// traceCtx attaches trace to ctx and returns the new context. +func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.Context, string) context.Context) { // Check the validity of client preface. preface := make([]byte, len(clientPreface)) if _, err := io.ReadFull(t.conn, preface); err != nil { @@ -279,7 +312,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) { } switch frame := frame.(type) { case *http2.MetaHeadersFrame: - if t.operateHeaders(frame, handle) { + if t.operateHeaders(frame, handle, traceCtx) { t.Close() break } @@ -492,9 +525,16 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } } + bufLen := t.hBuf.Len() if err := t.writeHeaders(s, t.hBuf, false); err != nil { return err } + if stats.On() { + outHeader := &stats.OutHeader{ + WireLength: bufLen, + } + stats.Handle(s.Context(), outHeader) + } t.writableChan <- 0 return nil } @@ -547,10 +587,17 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } } + bufLen := t.hBuf.Len() if err := t.writeHeaders(s, t.hBuf, true); err != nil { t.Close() return err } + if stats.On() { + outTrailer := &stats.OutTrailer{ + WireLength: bufLen, + } + stats.Handle(s.Context(), outTrailer) + } t.closeStream(s) t.writableChan <- 0 return nil @@ -767,7 +814,7 @@ func (t *http2Server) closeStream(s *Stream) { } func (t *http2Server) RemoteAddr() net.Addr { - return t.conn.RemoteAddr() + return t.remoteAddr } func (t *http2Server) Drain() { diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/transport/transport.go index 413f7493b4483..4726bb2cea6c9 100644 --- a/vendor/google.golang.org/grpc/transport/transport.go +++ b/vendor/google.golang.org/grpc/transport/transport.go @@ -45,10 +45,10 @@ import ( "sync" "golang.org/x/net/context" - "golang.org/x/net/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/tap" ) // recvMsg represents the received msg from the transport. All transport @@ -167,6 +167,11 @@ type Stream struct { id uint32 // nil for client side Stream. st ServerTransport + // clientStatsCtx keeps the user context for stats handling. + // It's only valid on client side. Server side stats context is same as s.ctx. + // All client side stats collection should use the clientStatsCtx (instead of the stream context) + // so that all the generated stats for a particular RPC can be associated in the processing phase. + clientStatsCtx context.Context // ctx is the associated context of the stream. ctx context.Context // cancel is always nil for client side Stream. @@ -266,11 +271,6 @@ func (s *Stream) Context() context.Context { return s.ctx } -// TraceContext recreates the context of s with a trace.Trace. -func (s *Stream) TraceContext(tr trace.Trace) { - s.ctx = trace.NewContext(s.ctx, tr) -} - // Method returns the method for the stream. func (s *Stream) Method() string { return s.method @@ -355,10 +355,17 @@ const ( draining ) +// ServerConfig consists of all the configurations to establish a server transport. +type ServerConfig struct { + MaxStreams uint32 + AuthInfo credentials.AuthInfo + InTapHandle tap.ServerInHandle +} + // NewServerTransport creates a ServerTransport with conn or non-nil error // if it fails. -func NewServerTransport(protocol string, conn net.Conn, maxStreams uint32, authInfo credentials.AuthInfo) (ServerTransport, error) { - return newHTTP2Server(conn, maxStreams, authInfo) +func NewServerTransport(protocol string, conn net.Conn, config *ServerConfig) (ServerTransport, error) { + return newHTTP2Server(conn, config) } // ConnectOptions covers all relevant options for communicating with the server. @@ -367,6 +374,8 @@ type ConnectOptions struct { UserAgent string // Dialer specifies how to dial a network address. Dialer func(context.Context, string) (net.Conn, error) + // FailOnNonTempDialError specifies if gRPC fails on non-temporary dial errors. + FailOnNonTempDialError bool // PerRPCCredentials stores the PerRPCCredentials required to issue RPCs. PerRPCCredentials []credentials.PerRPCCredentials // TransportCredentials stores the Authenticator required to setup a client connection. @@ -466,7 +475,7 @@ type ClientTransport interface { // Write methods for a given Stream will be called serially. type ServerTransport interface { // HandleStreams receives incoming streams using the given handler. - HandleStreams(func(*Stream)) + HandleStreams(func(*Stream), func(context.Context, string) context.Context) // WriteHeader sends the header metadata for the given stream. // WriteHeader may not be called on all streams. diff --git a/vendor/vendor.json b/vendor/vendor.json index 7bbf8daa8cb51..f16e81956dbe4 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -19,16 +19,16 @@ "revision": "" }, { - "checksumSHA1": "M30X+Wqn7AnUr1numUOkQRI7ET0=", + "checksumSHA1": "Xt8qcx6rrE1w8HkRSoxJDlNxswA=", "path": "github.com/Azure/azure-sdk-for-go/storage", - "revision": "bd73d950fa4440dae889bd9917bff7cef539f86e", - "revisionTime": "2016-10-28T18:31:11Z" + "revision": "27ae5c8b5bc5d90ab0540b4c5d0f2632c8db8b57", + "revisionTime": "2016-11-10T23:35:32Z" }, { - "checksumSHA1": "eWlbQbXextN77vRiVuIBV6kSwuE=", + "checksumSHA1": "9BfDgevpBgdiP4B6DT9SvcuVyLs=", "path": "github.com/Jeffail/gabs", - "revision": "855034b6b7a3b7144977efcaefe72d2c64b0d039", - "revisionTime": "2016-08-09T16:55:30Z" + "revision": "2a3aa15961d5fee6047b8151b67ac2f08ba2c48c", + "revisionTime": "2016-11-16T21:39:02Z" }, { "checksumSHA1": "LLVyR2dAgkihu0+HdZF+JK0gMMs=", @@ -43,16 +43,16 @@ "revisionTime": "2015-08-30T18:26:16Z" }, { - "checksumSHA1": "d6798KSc0jDg2MHNxKdgyNfMK7A=", + "checksumSHA1": "6HjBxlrYOUnFZo6jPok9ZfQZ/dM=", "path": "github.com/armon/go-metrics", - "revision": "3df31a1ada83e310c2e24b267c8e8b68836547b4", - "revisionTime": "2016-07-17T04:34:58Z" + "revision": "97c69685293dce4c0a2d0b19535179bbc976e4d2", + "revisionTime": "2016-11-05T01:02:38Z" }, { "checksumSHA1": "OmqT9Y1mAHvlAKeJh0jBHC9SH78=", "path": "github.com/armon/go-metrics/circonus", - "revision": "3df31a1ada83e310c2e24b267c8e8b68836547b4", - "revisionTime": "2016-07-17T04:34:58Z" + "revision": "97c69685293dce4c0a2d0b19535179bbc976e4d2", + "revisionTime": "2016-11-05T01:02:38Z" }, { "checksumSHA1": "gNO0JNpLzYOdInGeq7HqMZUzx9M=", @@ -67,196 +67,196 @@ "revisionTime": "2016-10-01T16:31:30Z" }, { - "checksumSHA1": "QEah7lNQcDSLQinY80RVj5CrF3k=", + "checksumSHA1": "zCEK2WbnAElGz7x27gMGEyNY19A=", "path": "github.com/aws/aws-sdk-go/aws", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "+q4vdl3l1Wom8K1wfIpJ4jlFsbY=", "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "/232RBWA3KnT7U+wciPS2+wmvR0=", "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "c1N3Loy3AS9zD+m5CzpPNAED39U=", "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "zu5C95rmCZff6NYZb62lEaT5ibE=", "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { - "checksumSHA1": "KQiUK/zr3mqnAXD7x/X55/iNme0=", + "checksumSHA1": "u3GOAJLmdvbuNUeUEcZSEAOeL/0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "4Ipx+5xN0gso+cENC2MHMWmQlR4=", "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "DwhFsNluCFEwqzyp3hbJR3q2Wqs=", "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { - "checksumSHA1": "8E0fEBUJY/1lJOyVxzTxMGQGInk=", + "checksumSHA1": "/EXbk/z2TWjWc1Hvb4QYs3Wmhb8=", "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "5Ac22YMTBmrX/CXaEIXzWljr8UY=", "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "eOo6evLMAxQfo7Qkc5/h5euN1Sw=", "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { - "checksumSHA1": "diXvBs1LRC0RJ9WK6sllWKdzC04=", + "checksumSHA1": "9K5Bpjvynki7Req1reyD1W3/uWA=", "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "Esab5F8KswqkTdB4TtjSvZgs56k=", "path": "github.com/aws/aws-sdk-go/private/endpoints", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "wk7EyvDaHwb5qqoOP/4d3cV0708=", "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "1QmQ3FqV37w0Zi44qv8pA1GeR0A=", "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "pNeF0Ey7TfBArH5LBQhKOQXQbLY=", "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "R00RL5jJXRYq1iiK1+PGvMfvXyM=", "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "ZqY5RWavBLWTo6j9xqdyBEaNFRk=", "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "5xzix1R8prUyWxgLnzUQoxTsfik=", "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { - "checksumSHA1": "TW/7U+/8ormL7acf6z2rv2hDD+s=", + "checksumSHA1": "mLxtfPJvWIHdYPRY0f19kFuJ3u4=", "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "ODo+ko8D6unAxZuN1jGzMcN4QCc=", "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "eUEkjyMPAuekKBE4ou+nM9tXEas=", "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", "path": "github.com/aws/aws-sdk-go/private/waiter", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "E5qjR1pDa/V2LEhXP36kZH2w91o=", "path": "github.com/aws/aws-sdk-go/service/dynamodb", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "nNF0ucfWGzZz7PQVe9da0J7Di7w=", "path": "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "6h4tJ9wVtbYb9wG4srtUxyPoAYM=", "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "hQquEMm59E2CwVwfBvKRTVzBj/8=", "path": "github.com/aws/aws-sdk-go/service/iam", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "HtKiIAPKsBg2s1c5ytRkdZ/lqO8=", "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "ouwhxcAsIYQ6oJbMRdLW/Ys/iyg=", "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "967a4b67114c61521c4b514d7c9a2feb869918e9", - "revisionTime": "2016-11-01T23:30:21Z" + "revision": "12ce9fecda7689cae03a715e16c57519a97bddcd", + "revisionTime": "2016-11-16T23:00:31Z" }, { "checksumSHA1": "Isa9x3nvIJ12hvgdvUUBty+yplU=", @@ -291,44 +291,44 @@ { "checksumSHA1": "vcncrPAdKKpLjl5O5lAdrFU6NOc=", "path": "github.com/coreos/etcd/client", - "revision": "7d777a4a6422d87bd9a19f56b9b1ae812e84ed73", - "revisionTime": "2016-11-02T17:34:52Z" + "revision": "377f19b0031f9c0aafe2aec28b6f9019311f52f9", + "revisionTime": "2016-11-16T00:44:50Z" }, { "checksumSHA1": "ga3jt9r+dQBMSXG0gnpNcXp2xYA=", "path": "github.com/coreos/etcd/pkg/fileutil", - "revision": "7d777a4a6422d87bd9a19f56b9b1ae812e84ed73", - "revisionTime": "2016-11-02T17:34:52Z" + "revision": "377f19b0031f9c0aafe2aec28b6f9019311f52f9", + "revisionTime": "2016-11-16T00:44:50Z" }, { "checksumSHA1": "mKIXx1kDwmVmdIpZ3pJtRBuUKso=", "path": "github.com/coreos/etcd/pkg/pathutil", - "revision": "7d777a4a6422d87bd9a19f56b9b1ae812e84ed73", - "revisionTime": "2016-11-02T17:34:52Z" + "revision": "377f19b0031f9c0aafe2aec28b6f9019311f52f9", + "revisionTime": "2016-11-16T00:44:50Z" }, { "checksumSHA1": "rMyIh9PsSvPs6Yd+YgKITQzQJx8=", "path": "github.com/coreos/etcd/pkg/tlsutil", - "revision": "7d777a4a6422d87bd9a19f56b9b1ae812e84ed73", - "revisionTime": "2016-11-02T17:34:52Z" + "revision": "377f19b0031f9c0aafe2aec28b6f9019311f52f9", + "revisionTime": "2016-11-16T00:44:50Z" }, { "checksumSHA1": "985rsigkh9SZlDXm6qK6cBloQg0=", "path": "github.com/coreos/etcd/pkg/transport", - "revision": "7d777a4a6422d87bd9a19f56b9b1ae812e84ed73", - "revisionTime": "2016-11-02T17:34:52Z" + "revision": "377f19b0031f9c0aafe2aec28b6f9019311f52f9", + "revisionTime": "2016-11-16T00:44:50Z" }, { "checksumSHA1": "gx1gJIMU6T0UNQ0bPZ/drQ8cpCI=", "path": "github.com/coreos/etcd/pkg/types", - "revision": "7d777a4a6422d87bd9a19f56b9b1ae812e84ed73", - "revisionTime": "2016-11-02T17:34:52Z" + "revision": "377f19b0031f9c0aafe2aec28b6f9019311f52f9", + "revisionTime": "2016-11-16T00:44:50Z" }, { "checksumSHA1": "d50/+u/LFlXvEV10HiEoXB9OsGg=", "path": "github.com/coreos/go-systemd/journal", - "revision": "64d5cd7cb947834ef93874e82745c42ad6de4d0e", - "revisionTime": "2016-11-02T17:07:22Z" + "revision": "48702e0da86bd25e76cfef347e2adeb434a0d0a6", + "revisionTime": "2016-11-14T12:22:54Z" }, { "checksumSHA1": "wqEybhAfMhCq2uOu4bT737mqu6U=", @@ -391,40 +391,40 @@ "revisionTime": "2016-09-26T17:55:29Z" }, { - "checksumSHA1": "7Di9l3MwdZliLqFKCU9ql2s+Rnw=", + "checksumSHA1": "W7OFi8RC+99JY3lVFkqL8dVhUT0=", "path": "github.com/go-sql-driver/mysql", - "revision": "ce924a41eea897745442daaa1739089b0f3f561d", - "revisionTime": "2016-11-01T11:13:14Z" + "revision": "665b83488b90b902ce0a305ef6652e599771cdf9", + "revisionTime": "2016-11-16T07:07:42Z" }, { - "checksumSHA1": "Ea5tZxe8OjKyrXAaw5FTrpxiBWw=", + "checksumSHA1": "9dGSivFlYCZvic4tBgE0xtWF0x0=", "path": "github.com/gocql/gocql", - "revision": "3a52a1dae458ea8c51f156b4b0e07758cd652b55", - "revisionTime": "2016-11-01T09:30:54Z" + "revision": "47f897f054183a4c891f27b235f11221683982dc", + "revisionTime": "2016-11-07T21:46:42Z" }, { "checksumSHA1": "Z3N6HDGWcvcNu0FloZRq54uO3h4=", "path": "github.com/gocql/gocql/internal/lru", - "revision": "3a52a1dae458ea8c51f156b4b0e07758cd652b55", - "revisionTime": "2016-11-01T09:30:54Z" + "revision": "47f897f054183a4c891f27b235f11221683982dc", + "revisionTime": "2016-11-07T21:46:42Z" }, { "checksumSHA1": "ctK9mwZKnt/8dHxx2Ef6nZTljZs=", "path": "github.com/gocql/gocql/internal/murmur", - "revision": "3a52a1dae458ea8c51f156b4b0e07758cd652b55", - "revisionTime": "2016-11-01T09:30:54Z" + "revision": "47f897f054183a4c891f27b235f11221683982dc", + "revisionTime": "2016-11-07T21:46:42Z" }, { "checksumSHA1": "tZQDfMMTKrYMXqen0zjJWLtOf1A=", "path": "github.com/gocql/gocql/internal/streams", - "revision": "3a52a1dae458ea8c51f156b4b0e07758cd652b55", - "revisionTime": "2016-11-01T09:30:54Z" + "revision": "47f897f054183a4c891f27b235f11221683982dc", + "revisionTime": "2016-11-07T21:46:42Z" }, { - "checksumSHA1": "SVXOQdpDBh0ihdZ5aIflgdA+Rpw=", + "checksumSHA1": "QlFGL6EkbK8an+9M+EupFAKe4uM=", "path": "github.com/golang/protobuf/proto", - "revision": "98fa357170587e470c5f27d3c3ea0947b71eb455", - "revisionTime": "2016-10-12T20:53:35Z" + "revision": "224aaba33b1ac32a92a165f27489409fb8133d08", + "revisionTime": "2016-11-16T19:48:24Z" }, { "checksumSHA1": "W+E/2xXcE1GmJ0Qb784ald0Fn6I=", @@ -433,10 +433,10 @@ "revisionTime": "2016-05-29T05:00:41Z" }, { - "checksumSHA1": "TSS9EqiOoJcVUMNb46zVngVrAO8=", + "checksumSHA1": "5+cRIgrrCwJ/BhOG34jUcNyvDPI=", "path": "github.com/google/go-github/github", - "revision": "f7fcf6f52ff94adf1cc0ded41e7768d2ad729972", - "revisionTime": "2016-10-28T15:10:40Z" + "revision": "d4f1b2d029be1730fd349ca929cc9c0da4a27007", + "revisionTime": "2016-11-14T19:06:42Z" }, { "checksumSHA1": "yyAzHoiVLu+xywYI2BDyRq6sOqE=", @@ -451,16 +451,16 @@ "revisionTime": "2016-01-25T11:53:50Z" }, { - "checksumSHA1": "LclVLJYrBi03PBjsVPpgoMbUDQ8=", + "checksumSHA1": "DHgZ2o3MR8CjlrzkgrjlbyvK/cw=", "path": "github.com/hashicorp/consul/api", - "revision": "fb7c03cbb1b3fa71b0746e2f19c442c63e686382", - "revisionTime": "2016-11-01T13:11:20Z" + "revision": "74cfcd301485b5dd658715f0282c4e5dff232fca", + "revisionTime": "2016-11-16T15:58:24Z" }, { "checksumSHA1": "0DPAA2cTBjrCGgXaxXil0vILcFs=", "path": "github.com/hashicorp/consul/lib", - "revision": "fb7c03cbb1b3fa71b0746e2f19c442c63e686382", - "revisionTime": "2016-11-01T13:11:20Z" + "revision": "74cfcd301485b5dd658715f0282c4e5dff232fca", + "revisionTime": "2016-11-16T15:58:24Z" }, { "checksumSHA1": "cdOCt0Yb+hdErz8NAQqayxPmRsY=", @@ -481,10 +481,10 @@ "revisionTime": "2015-05-18T23:42:57Z" }, { - "checksumSHA1": "KS9lmJV8Z7KHdtSIhbafQLU1hC4=", + "checksumSHA1": "jplwF0kQyDhu2Wqq7cmZu0SHjOI=", "path": "github.com/hashicorp/go-multierror", - "revision": "8c5f0ad9360406a3807ce7de6bc73269a91a6e51", - "revisionTime": "2016-08-11T01:57:21Z" + "revision": "8484912a3b9987857bac52e0c5fec2b95f419628", + "revisionTime": "2016-11-06T17:22:40Z" }, { "checksumSHA1": "ErJHGU6AVPZM9yoY/xV11TwSjQs=", @@ -525,56 +525,56 @@ { "checksumSHA1": "8OPDk+bKyRGJoKcS4QNw9F7dpE8=", "path": "github.com/hashicorp/hcl", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { "checksumSHA1": "XQmjDva9JCGGkIecOgwtBEMCJhU=", "path": "github.com/hashicorp/hcl/hcl/ast", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { "checksumSHA1": "croNloscHsjX87X+4/cKOURf1EY=", "path": "github.com/hashicorp/hcl/hcl/parser", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { "checksumSHA1": "lgR7PSAZ0RtvAc9OCtCnNsF/x8g=", "path": "github.com/hashicorp/hcl/hcl/scanner", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { - "checksumSHA1": "JlZmnzqdmFFyb1+2afLyR3BOE/8=", + "checksumSHA1": "/e0ULfQnGeUKiM1+iMnQhImo62k=", "path": "github.com/hashicorp/hcl/hcl/strconv", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { "checksumSHA1": "c6yprzj06ASwCo18TtbbNNBHljA=", "path": "github.com/hashicorp/hcl/hcl/token", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { "checksumSHA1": "138aCV5n8n7tkGYMsMVQQnnLq+0=", "path": "github.com/hashicorp/hcl/json/parser", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { "checksumSHA1": "YdvFsNOMSWMLnY6fcliWQa0O5Fw=", "path": "github.com/hashicorp/hcl/json/scanner", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { "checksumSHA1": "fNlXQCQEnb+B3k5UDL/r15xtSJY=", "path": "github.com/hashicorp/hcl/json/token", - "revision": "6e968a3fcdcbab092f5307fd0d85479d5af1e4dc", - "revisionTime": "2016-11-01T18:00:25Z" + "revision": "c3e054bfd4dcf77b9965ed2b79b22afa2f41d4eb", + "revisionTime": "2016-11-12T23:52:43Z" }, { "checksumSHA1": "qnlqWJYV81ENr61SZk9c65R1mDo=", @@ -597,8 +597,8 @@ { "checksumSHA1": "E3Xcanc9ouQwL+CZGOUyA/+giLg=", "path": "github.com/hashicorp/serf/coordinate", - "revision": "e0680ca729b018b791af1add413faebe3e1c147e", - "revisionTime": "2016-10-31T21:31:47Z" + "revision": "f679d7594a349263f6118db40d87122d3a474e7d", + "revisionTime": "2016-11-09T18:57:27Z" }, { "checksumSHA1": "ZhK6IO2XN81Y+3RAjTcVm1Ic7oU=", @@ -673,22 +673,22 @@ "revisionTime": "2016-10-04T15:35:44Z" }, { - "checksumSHA1": "T6yD9DYjn6yO+Kz70bO+sDj20oE=", + "checksumSHA1": "avqi4lkviHdrNJ92cXCwrw9x870=", "path": "github.com/lib/pq", - "revision": "a37edb86214894fa6c6c3401a4c4976b02176dd3", - "revisionTime": "2016-11-02T07:48:14Z" + "revision": "d8eeeb8bae8896dd8e1b7e514ab0d396c4f12a1b", + "revisionTime": "2016-11-03T02:43:54Z" }, { "checksumSHA1": "xppHi82MLqVx1eyQmbhTesAEjx8=", "path": "github.com/lib/pq/oid", - "revision": "a37edb86214894fa6c6c3401a4c4976b02176dd3", - "revisionTime": "2016-11-02T07:48:14Z" + "revision": "d8eeeb8bae8896dd8e1b7e514ab0d396c4f12a1b", + "revisionTime": "2016-11-03T02:43:54Z" }, { - "checksumSHA1": "WFbWfoslftbEoKx6ZNVTMcU0EzA=", + "checksumSHA1": "I4njd26dG5hxFT2nawuByM4pxzY=", "path": "github.com/mattn/go-colorable", - "revision": "6e26b354bd2b0fc420cb632b0d878abccdc6544c", - "revisionTime": "2016-11-02T08:09:25Z" + "revision": "d228849504861217f796da67fae4f6e347643f15", + "revisionTime": "2016-11-03T16:00:40Z" }, { "checksumSHA1": "xZuhljnmBysJPta/lMyYmJdujCg=", @@ -853,160 +853,172 @@ "revisionTime": "2016-10-31T15:37:30Z" }, { - "checksumSHA1": "4hQNaJUg67lF/QcO0NKzUeqlaew=", + "checksumSHA1": "9jjO5GjLa0XF/nfWihF02RoH4qc=", "path": "golang.org/x/net/context", - "revision": "4bb47a1098b37d69980d96237e2ae4ff56bb5a95", - "revisionTime": "2016-10-31T16:36:42Z" + "revision": "4971afdc2f162e82d185353533d3cf16188a9f4e", + "revisionTime": "2016-11-15T21:05:04Z" }, { - "checksumSHA1": "r+7Ol7uTCa/i5W8pNej9M8xZxWg=", + "checksumSHA1": "pLsZUQhI8jm3W9R/4JO9D/L1cUA=", "path": "golang.org/x/net/http2", - "revision": "4bb47a1098b37d69980d96237e2ae4ff56bb5a95", - "revisionTime": "2016-10-31T16:36:42Z" + "revision": "4971afdc2f162e82d185353533d3cf16188a9f4e", + "revisionTime": "2016-11-15T21:05:04Z" }, { "checksumSHA1": "HzuGD7AwgC0p1az1WAQnEFnEk98=", "path": "golang.org/x/net/http2/hpack", - "revision": "4bb47a1098b37d69980d96237e2ae4ff56bb5a95", - "revisionTime": "2016-10-31T16:36:42Z" + "revision": "4971afdc2f162e82d185353533d3cf16188a9f4e", + "revisionTime": "2016-11-15T21:05:04Z" }, { "checksumSHA1": "GIGmSrYACByf5JDIP9ByBZksY80=", "path": "golang.org/x/net/idna", - "revision": "4bb47a1098b37d69980d96237e2ae4ff56bb5a95", - "revisionTime": "2016-10-31T16:36:42Z" + "revision": "4971afdc2f162e82d185353533d3cf16188a9f4e", + "revisionTime": "2016-11-15T21:05:04Z" }, { "checksumSHA1": "/k7k6eJDkxXx6K9Zpo/OwNm58XM=", "path": "golang.org/x/net/internal/timeseries", - "revision": "4bb47a1098b37d69980d96237e2ae4ff56bb5a95", - "revisionTime": "2016-10-31T16:36:42Z" + "revision": "4971afdc2f162e82d185353533d3cf16188a9f4e", + "revisionTime": "2016-11-15T21:05:04Z" }, { "checksumSHA1": "3xyuaSNmClqG4YWC7g0isQIbUTc=", "path": "golang.org/x/net/lex/httplex", - "revision": "4bb47a1098b37d69980d96237e2ae4ff56bb5a95", - "revisionTime": "2016-10-31T16:36:42Z" + "revision": "4971afdc2f162e82d185353533d3cf16188a9f4e", + "revisionTime": "2016-11-15T21:05:04Z" }, { - "checksumSHA1": "4MMbG0LI3ghvWooRn36RmDrFIB0=", + "checksumSHA1": "P9qTIn8a6L6Q9wd1IJBCuhno1Q8=", "path": "golang.org/x/net/trace", - "revision": "4bb47a1098b37d69980d96237e2ae4ff56bb5a95", - "revisionTime": "2016-10-31T16:36:42Z" + "revision": "4971afdc2f162e82d185353533d3cf16188a9f4e", + "revisionTime": "2016-11-15T21:05:04Z" }, { "checksumSHA1": "XH7CgbL5Z8COUc+MKrYqS3FFosY=", "path": "golang.org/x/oauth2", - "revision": "25b4fb1468cb89700c7c060cb99f30581a61f5e3", - "revisionTime": "2016-10-25T17:59:40Z" + "revision": "d5040cddfc0da40b408c9a1da4728662435176a9", + "revisionTime": "2016-11-03T22:50:36Z" }, { "checksumSHA1": "D3v/aqfB9swlaZcSksCoF+lbOqo=", "path": "golang.org/x/oauth2/internal", - "revision": "25b4fb1468cb89700c7c060cb99f30581a61f5e3", - "revisionTime": "2016-10-25T17:59:40Z" + "revision": "d5040cddfc0da40b408c9a1da4728662435176a9", + "revisionTime": "2016-11-03T22:50:36Z" }, { - "checksumSHA1": "aVgPDgwY3/t4J/JOw9H3FVMHqh0=", + "checksumSHA1": "KqecwXo3OO+p4N+E9RhlHvl9I+w=", "path": "golang.org/x/sys/unix", - "revision": "c200b10b5d5e122be351b67af224adc6128af5bf", - "revisionTime": "2016-10-22T18:22:21Z" + "revision": "b699b7032584f0953262cb2788a0ca19bb494703", + "revisionTime": "2016-11-10T11:58:56Z" }, { - "checksumSHA1": "vIZ71Qe81RHec1vNHpKG+CSx/es=", + "checksumSHA1": "gYHoPrPncGO926bN0jr1rzDxBQU=", "path": "google.golang.org/appengine/internal", - "revision": "46239ca616842c00f41b8cbc6bbf2bd6ffbfcdad", - "revisionTime": "2016-10-25T16:43:32Z" + "revision": "ca59ef35f409df61fa4a5f8290ff289b37eccfb8", + "revisionTime": "2016-11-15T22:01:06Z" }, { "checksumSHA1": "TsNO8P0xUlLNyh3Ic/tzSp/fDWM=", "path": "google.golang.org/appengine/internal/base", - "revision": "46239ca616842c00f41b8cbc6bbf2bd6ffbfcdad", - "revisionTime": "2016-10-25T16:43:32Z" + "revision": "ca59ef35f409df61fa4a5f8290ff289b37eccfb8", + "revisionTime": "2016-11-15T22:01:06Z" }, { "checksumSHA1": "5QsV5oLGSfKZqTCVXP6NRz5T4Tw=", "path": "google.golang.org/appengine/internal/datastore", - "revision": "46239ca616842c00f41b8cbc6bbf2bd6ffbfcdad", - "revisionTime": "2016-10-25T16:43:32Z" + "revision": "ca59ef35f409df61fa4a5f8290ff289b37eccfb8", + "revisionTime": "2016-11-15T22:01:06Z" }, { "checksumSHA1": "Gep2T9zmVYV8qZfK2gu3zrmG6QE=", "path": "google.golang.org/appengine/internal/log", - "revision": "46239ca616842c00f41b8cbc6bbf2bd6ffbfcdad", - "revisionTime": "2016-10-25T16:43:32Z" + "revision": "ca59ef35f409df61fa4a5f8290ff289b37eccfb8", + "revisionTime": "2016-11-15T22:01:06Z" }, { "checksumSHA1": "a1XY7rz3BieOVqVI2Et6rKiwQCk=", "path": "google.golang.org/appengine/internal/remote_api", - "revision": "46239ca616842c00f41b8cbc6bbf2bd6ffbfcdad", - "revisionTime": "2016-10-25T16:43:32Z" + "revision": "ca59ef35f409df61fa4a5f8290ff289b37eccfb8", + "revisionTime": "2016-11-15T22:01:06Z" }, { "checksumSHA1": "QtAbHtHmDzcf6vOV9eqlCpKgjiw=", "path": "google.golang.org/appengine/internal/urlfetch", - "revision": "46239ca616842c00f41b8cbc6bbf2bd6ffbfcdad", - "revisionTime": "2016-10-25T16:43:32Z" + "revision": "ca59ef35f409df61fa4a5f8290ff289b37eccfb8", + "revisionTime": "2016-11-15T22:01:06Z" }, { "checksumSHA1": "akOV9pYnCbcPA8wJUutSQVibdyg=", "path": "google.golang.org/appengine/urlfetch", - "revision": "46239ca616842c00f41b8cbc6bbf2bd6ffbfcdad", - "revisionTime": "2016-10-25T16:43:32Z" + "revision": "ca59ef35f409df61fa4a5f8290ff289b37eccfb8", + "revisionTime": "2016-11-15T22:01:06Z" }, { - "checksumSHA1": "r2jmzn/o6RN6PT9FRRtBeAfgNEk=", + "checksumSHA1": "xyB2Py2ViSKX8Td+oe2hxG6f0Ak=", "path": "google.golang.org/grpc", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { "checksumSHA1": "08icuA15HRkdYCt6H+Cs90RPQsY=", "path": "google.golang.org/grpc/codes", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { "checksumSHA1": "Vd1MU+Ojs7GeS6jE52vlxtXvIrI=", "path": "google.golang.org/grpc/credentials", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { "checksumSHA1": "3Lt5hNAG8qJAYSsNghR5uA1zQns=", "path": "google.golang.org/grpc/grpclog", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { "checksumSHA1": "T3Q0p8kzvXFnRkMaK/G8mCv6mc0=", "path": "google.golang.org/grpc/internal", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { "checksumSHA1": "P64GkSdsTZ8Nxop5HYqZJ6e+iHs=", "path": "google.golang.org/grpc/metadata", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { "checksumSHA1": "4GSUFhOQ0kdFlBH4D5OTeKy78z0=", "path": "google.golang.org/grpc/naming", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { "checksumSHA1": "3RRoLeH6X2//7tVClOVzxW2bY+E=", "path": "google.golang.org/grpc/peer", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { - "checksumSHA1": "HQJrtiTtr5eiRsXQLut2R1Q9kuY=", + "checksumSHA1": "FCgy+WB249Vt1XEG5pe4Z7plTLs=", + "path": "google.golang.org/grpc/stats", + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" + }, + { + "checksumSHA1": "N0TftT6/CyWqp6VRi2DqDx60+Fo=", + "path": "google.golang.org/grpc/tap", + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" + }, + { + "checksumSHA1": "uVGwQAu6ncFK7qd3BpzbMEJDUP4=", "path": "google.golang.org/grpc/transport", - "revision": "f8b3c6010888dd5f12b97390791d75ff43453836", - "revisionTime": "2016-11-02T18:01:57Z" + "revision": "941cc894cea3c87a12943fd12b594964541b6d28", + "revisionTime": "2016-11-15T20:54:09Z" }, { "checksumSHA1": "wSu8owMAP7GixsYoSZ4CmKUVhnU=", From 2b374afbf24942e1b2765c12fa2066b9ec426fe7 Mon Sep 17 00:00:00 2001 From: Kevin Goess Date: Thu, 17 Nov 2016 06:59:27 -0800 Subject: [PATCH 04/19] check for failure on that mysql query (#2105) --- physical/mysql.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/physical/mysql.go b/physical/mysql.go index b86ac92493f75..ce1351465ccd1 100644 --- a/physical/mysql.go +++ b/physical/mysql.go @@ -173,6 +173,9 @@ func (m *MySQLBackend) List(prefix string) ([]string, error) { // Add the % wildcard to the prefix to do the prefix search likePrefix := prefix + "%" rows, err := m.statements["list"].Query(likePrefix) + if err != nil { + return nil, fmt.Errorf("failed to execute statement: %v", err) + } var keys []string for rows.Next() { From 81661199b966a92977764227b40985e3ef53e512 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 17 Nov 2016 10:00:33 -0500 Subject: [PATCH 05/19] changelog++ --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37300d4a8e418..91f8fd12d8330 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ BUG FIXES: the command returns [GH-2016] * core: Fix bug where a failure to come up as active node (e.g. if an audit backend failed) could lead to deadlock [GH-2083] + * physical/mysql: Fix potential crash during setup due to a query failure + [GH-2105] ## 0.6.2 (October 5, 2016) From 7579c50ac960e2beb40809b1b31d1753856035e2 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 17 Nov 2016 10:06:26 -0500 Subject: [PATCH 06/19] Bump proto files after update --- helper/forwarding/types.pb.go | 105 +++++++++++++++++++++++++ vault/request_forwarding_service.pb.go | 4 +- 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/helper/forwarding/types.pb.go b/helper/forwarding/types.pb.go index 8b7e54c85296f..705f7ac6dfa43 100644 --- a/helper/forwarding/types.pb.go +++ b/helper/forwarding/types.pb.go @@ -49,6 +49,13 @@ func (m *Request) String() string { return proto.CompactTextString(m) func (*Request) ProtoMessage() {} func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (m *Request) GetMethod() string { + if m != nil { + return m.Method + } + return "" +} + func (m *Request) GetUrl() *URL { if m != nil { return m.Url @@ -63,6 +70,34 @@ func (m *Request) GetHeaderEntries() map[string]*HeaderEntry { return nil } +func (m *Request) GetBody() []byte { + if m != nil { + return m.Body + } + return nil +} + +func (m *Request) GetHost() string { + if m != nil { + return m.Host + } + return "" +} + +func (m *Request) GetRemoteAddr() string { + if m != nil { + return m.RemoteAddr + } + return "" +} + +func (m *Request) GetPeerCertificates() [][]byte { + if m != nil { + return m.PeerCertificates + } + return nil +} + type URL struct { Scheme string `protobuf:"bytes,1,opt,name=scheme" json:"scheme,omitempty"` Opaque string `protobuf:"bytes,2,opt,name=opaque" json:"opaque,omitempty"` @@ -83,6 +118,55 @@ func (m *URL) String() string { return proto.CompactTextString(m) } func (*URL) ProtoMessage() {} func (*URL) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } +func (m *URL) GetScheme() string { + if m != nil { + return m.Scheme + } + return "" +} + +func (m *URL) GetOpaque() string { + if m != nil { + return m.Opaque + } + return "" +} + +func (m *URL) GetHost() string { + if m != nil { + return m.Host + } + return "" +} + +func (m *URL) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *URL) GetRawPath() string { + if m != nil { + return m.RawPath + } + return "" +} + +func (m *URL) GetRawQuery() string { + if m != nil { + return m.RawQuery + } + return "" +} + +func (m *URL) GetFragment() string { + if m != nil { + return m.Fragment + } + return "" +} + type HeaderEntry struct { Values []string `protobuf:"bytes,1,rep,name=values" json:"values,omitempty"` } @@ -92,6 +176,13 @@ func (m *HeaderEntry) String() string { return proto.CompactTextStrin func (*HeaderEntry) ProtoMessage() {} func (*HeaderEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } +func (m *HeaderEntry) GetValues() []string { + if m != nil { + return m.Values + } + return nil +} + type Response struct { // Not used right now but reserving in case it turns out that streaming // makes things more economical on the gRPC side @@ -108,6 +199,20 @@ func (m *Response) String() string { return proto.CompactTextString(m func (*Response) ProtoMessage() {} func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } +func (m *Response) GetStatusCode() uint32 { + if m != nil { + return m.StatusCode + } + return 0 +} + +func (m *Response) GetBody() []byte { + if m != nil { + return m.Body + } + return nil +} + func (m *Response) GetHeaderEntries() map[string]*HeaderEntry { if m != nil { return m.HeaderEntries diff --git a/vault/request_forwarding_service.pb.go b/vault/request_forwarding_service.pb.go index 2a14345eca689..3980f9345b7bf 100644 --- a/vault/request_forwarding_service.pb.go +++ b/vault/request_forwarding_service.pb.go @@ -39,7 +39,7 @@ var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion3 +const _ = grpc.SupportPackageIsVersion4 // Client API for RequestForwarding service @@ -102,7 +102,7 @@ var _RequestForwarding_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptor0, + Metadata: "request_forwarding_service.proto", } func init() { proto.RegisterFile("request_forwarding_service.proto", fileDescriptor0) } From d5c05842d6ca79b024bd1291e3952b9606be1bba Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 17 Nov 2016 12:57:36 -0500 Subject: [PATCH 07/19] Don't exclude 0 from the set of valid polynomials in Shamir. This leads to a potential (although extremely trivial) amount of information leakage. --- shamir/shamir.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/shamir/shamir.go b/shamir/shamir.go index 02a543f2be83e..96d48361acedd 100644 --- a/shamir/shamir.go +++ b/shamir/shamir.go @@ -29,13 +29,11 @@ func makePolynomial(intercept, degree uint8) (polynomial, error) { // Ensure the intercept is set p.coefficients[0] = intercept - // Assign random co-efficients to the polynomial, ensuring - // the highest order co-efficient is non-zero - for p.coefficients[degree] == 0 { - if _, err := rand.Read(p.coefficients[1:]); err != nil { - return p, err - } + // Assign random co-efficients to the polynomial + if _, err := rand.Read(p.coefficients[1:]); err != nil { + return p, err } + return p, nil } From 8a14a12efda0ed3b597f0e7c1ee7b26912131108 Mon Sep 17 00:00:00 2001 From: Benjamin Farley Date: Thu, 17 Nov 2016 18:36:00 +0000 Subject: [PATCH 08/19] Update libraries doc for Haskell community library (#2101) --- website/source/docs/http/libraries.html.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/source/docs/http/libraries.html.md b/website/source/docs/http/libraries.html.md index fdba465eaf263..546db85ea61e0 100644 --- a/website/source/docs/http/libraries.html.md +++ b/website/source/docs/http/libraries.html.md @@ -47,6 +47,11 @@ These libraries are provided by the community. * [vaultex](https://hex.pm/packages/vaultex) +### Haskell + +* [vault-tool](https://hackage.haskell.org/package/vault-tool) + * `cabal install vault-tool` + ### Java * [Spring Vault](https://github.com/spring-projects/spring-vault) From f0c59deeb789d559660caaa26fed0e2d8d35792e Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Thu, 17 Nov 2016 12:06:43 -0800 Subject: [PATCH 09/19] http: limit maximum request size --- http/handler.go | 10 +++++++++- http/logical.go | 5 +++++ http/logical_test.go | 13 +++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/http/handler.go b/http/handler.go index 775fce99701a9..c013a323710cf 100644 --- a/http/handler.go +++ b/http/handler.go @@ -26,6 +26,11 @@ const ( // NoRequestForwardingHeaderName is the name of the header telling Vault // not to use request forwarding NoRequestForwardingHeaderName = "X-Vault-No-Request-Forwarding" + + // MaxRequestSize is the maximum accepted request size. This is to prevent + // a denial of service attack where no Content-Length is provided and the server + // is fed ever more data until it exhausts memory. + MaxRequestSize = 8 * 1024 * 1024 ) // Handler returns an http.Handler for the API. This can be used on @@ -109,7 +114,10 @@ func stripPrefix(prefix, path string) (string, bool) { } func parseRequest(r *http.Request, out interface{}) error { - err := jsonutil.DecodeJSONFromReader(r.Body, out) + // Limit the maximum number of bytes to MaxRequestSize to protect + // against an indefinite amount of data being read. + limit := &io.LimitedReader{R: r.Body, N: MaxRequestSize} + err := jsonutil.DecodeJSONFromReader(limit, out) if err != nil && err != io.EOF { return fmt.Errorf("Failed to parse JSON input: %s", err) } diff --git a/http/logical.go b/http/logical.go index edf1eabf9bca0..6e644789781f5 100644 --- a/http/logical.go +++ b/http/logical.go @@ -26,6 +26,11 @@ func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Reques return nil, http.StatusNotFound, nil } + // Verify the content length does not exceed the maximum size + if r.ContentLength >= MaxRequestSize { + return nil, http.StatusRequestEntityTooLarge, nil + } + // Determine the operation var op logical.Operation switch r.Method { diff --git a/http/logical_test.go b/http/logical_test.go index 161261686d2fa..8149a5c4f9e06 100644 --- a/http/logical_test.go +++ b/http/logical_test.go @@ -231,3 +231,16 @@ func TestLogical_RawHTTP(t *testing.T) { t.Fatalf("Bad: %s", body.Bytes()) } } + +func TestLogical_RequestSizeLimit(t *testing.T) { + core, _, token := vault.TestCoreUnsealed(t) + ln, addr := TestServer(t, core) + defer ln.Close() + TestServerAuth(t, addr, token) + + // Write a very large object, should fail + resp := testHttpPut(t, token, addr+"/v1/secret/foo", map[string]interface{}{ + "data": make([]byte, MaxRequestSize), + }) + testResponseStatus(t, resp, 413) +} From a786ac4120fd5b3abe37d5d4903932fc67355868 Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Thu, 17 Nov 2016 12:15:37 -0800 Subject: [PATCH 10/19] http: increase request limit from 8MB to 32MB --- http/handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/handler.go b/http/handler.go index c013a323710cf..f927a4351396f 100644 --- a/http/handler.go +++ b/http/handler.go @@ -30,7 +30,7 @@ const ( // MaxRequestSize is the maximum accepted request size. This is to prevent // a denial of service attack where no Content-Length is provided and the server // is fed ever more data until it exhausts memory. - MaxRequestSize = 8 * 1024 * 1024 + MaxRequestSize = 32 * 1024 * 1024 ) // Handler returns an http.Handler for the API. This can be used on From 5a467432bf76271965f4facf5f4c0a61ce25218d Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Thu, 17 Nov 2016 12:17:31 -0800 Subject: [PATCH 11/19] Updating changelog --- CHANGELOG.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91f8fd12d8330..df812718b604a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## Next (Unreleased) +DEPRECATIONS/CHANGES: + + * http: impose a maximum request size of 32MB to prevent a denial of service + with arbitrarily large requests. [GH-2108] + IMPROVEMENTS: * auth/github: Policies can now be assigned to users as well as to teams @@ -172,11 +177,11 @@ DEPRECATIONS/CHANGES: * Status codes for sealed/uninitialized Vaults have changed to `503`/`501` respectively. See the [version-specific upgrade guide](https://www.vaultproject.io/docs/install/upgrade-to-0.6.1.html) for - more details. + more details. * Root tokens (tokens with the `root` policy) can no longer be created except by another root token or the `generate-root` endpoint. * Issued certificates from the `pki` backend against new roles created or - modified after upgrading will contain a set of default key usages. + modified after upgrading will contain a set of default key usages. * The `dynamodb` physical data store no longer supports HA by default. It has some non-ideal behavior around failover that was causing confusion. See the [documentation](https://www.vaultproject.io/docs/config/index.html#ha_enabled) @@ -246,7 +251,7 @@ IMPROVEMENTS: the request portion of the response. [GH-1650] * auth/aws-ec2: Added a new constraint `bound_account_id` to the role [GH-1523] - * auth/aws-ec2: Added a new constraint `bound_iam_role_arn` to the role + * auth/aws-ec2: Added a new constraint `bound_iam_role_arn` to the role [GH-1522] * auth/aws-ec2: Added `ttl` field for the role [GH-1703] * auth/ldap, secret/cassandra, physical/consul: Clients with `tls.Config` @@ -290,7 +295,7 @@ IMPROVEMENTS: configuration [GH-1581] * secret/mssql,mysql,postgresql: Reading of connection settings is supported in all the sql backends [GH-1515] - * secret/mysql: Added optional maximum idle connections value to MySQL + * secret/mysql: Added optional maximum idle connections value to MySQL connection configuration [GH-1635] * secret/mysql: Use a combination of the role name and token display name in generated user names and allow the length to be controlled [GH-1604] @@ -633,7 +638,7 @@ BUG FIXES: during renewals [GH-1176] ## 0.5.1 (February 25th, 2016) - + DEPRECATIONS/CHANGES: * RSA keys less than 2048 bits are no longer supported in the PKI backend. @@ -663,7 +668,7 @@ IMPROVEMENTS: * api/health: Add the server's time in UTC to health responses [GH-1117] * command/rekey and command/generate-root: These now return the status at attempt initialization time, rather than requiring a separate fetch for the - nonce [GH-1054] + nonce [GH-1054] * credential/cert: Don't require root/sudo tokens for the `certs/` and `crls/` paths; use normal ACL behavior instead [GH-468] * credential/github: The validity of the token used for login will be checked @@ -793,7 +798,7 @@ FEATURES: documentation](https://vaultproject.io/docs/config/index.html) for details. [GH-945] * **STS Support in AWS Secret Backend**: You can now use the AWS secret - backend to fetch STS tokens rather than IAM users. [GH-927] + backend to fetch STS tokens rather than IAM users. [GH-927] * **Speedups in the transit backend**: The `transit` backend has gained a cache, and now loads only the working set of keys (e.g. from the `min_decryption_version` to the current key version) into its working set. From 6165c3e20f9b40fd8034e3ef5019d790053a5603 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 22 Nov 2016 12:19:22 -0500 Subject: [PATCH 12/19] Update docs to fix #2102 --- website/source/docs/secrets/pki/index.html.md | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/website/source/docs/secrets/pki/index.html.md b/website/source/docs/secrets/pki/index.html.md index 6cb0436c149e5..b54155e986142 100644 --- a/website/source/docs/secrets/pki/index.html.md +++ b/website/source/docs/secrets/pki/index.html.md @@ -996,8 +996,9 @@ subpath for interactive help output. optional Format for returned data. Can be `pem`, `der`, or `pem_bundle`; defaults to `pem`. If `der`, the output is base64 encoded. If - `pem_bundle`, the `certificate` field will contain the private key, - certificate, and issuing CA, concatenated. + `pem_bundle`, the `certificate` field will contain the private key and + certificate, concatenated; if the issuing CA is not a Vault-derived + self-signed root, this will be included as well.
  • exclude_cn_from_sans @@ -1393,8 +1394,9 @@ subpath for interactive help output. optional Format for returned data. Can be `pem`, `der`, or `pem_bundle`; defaults to `pem`. If `der`, the output is base64 encoded. If - `pem_bundle`, the `certificate` field will contain the private key (if exported), - certificate, and issuing CA, concatenated. + `pem_bundle`, the `certificate` field will contain the private key (if + exported) and certificate, concatenated; if the issuing CA is not a + Vault-derived self-signed root, this will be included as well.
  • key_type @@ -1503,8 +1505,9 @@ subpath for interactive help output. optional Format for returned data. Can be `pem`, `der`, or `pem_bundle`; defaults to `pem`. If `der`, the output is base64 encoded. If - `pem_bundle`, the `certificate` field will contain the certificate and - issuing CA, concatenated. + `pem_bundle`, the `certificate` field will contain the certificate and, + if the issuing CA is not a Vault-derived self-signed root, it will be + concatenated with the certificate.
  • max_path_length @@ -1616,8 +1619,9 @@ subpath for interactive help output. optional Format for returned data. Can be `pem`, `der`, or `pem_bundle`; defaults to `pem`. If `der`, the output is base64 encoded. If - `pem_bundle`, the `certificate` field will contain the certificate and - issuing CA, concatenated. + `pem_bundle`, the `certificate` field will contain the certificate and, + if the issuing CA is not a Vault-derived self-signed root, it will be + concatenated with the certificate.
  • exclude_cn_from_sans @@ -1691,8 +1695,9 @@ subpath for interactive help output. optional Format for returned data. Can be `pem`, `der`, or `pem_bundle`; defaults to `pem`. If `der`, the output is base64 encoded. If - `pem_bundle`, the `certificate` field will contain the certificate and - issuing CA, concatenated. + `pem_bundle`, the `certificate` field will contain the certificate and, + if the issuing CA is not a Vault-derived self-signed root, it will be + concatenated with the certificate.
  • From 9571df6bc6c8f43ed26788720bdb26effb3f9726 Mon Sep 17 00:00:00 2001 From: Kyle McCullough Date: Tue, 22 Nov 2016 11:30:23 -0600 Subject: [PATCH 13/19] cli: fix bug with 'vault read -field=...' when the field value contains a printf formatting verb (#2109) --- command/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/util.go b/command/util.go index 990416d9f4ea7..0ec3916a706f1 100644 --- a/command/util.go +++ b/command/util.go @@ -79,7 +79,7 @@ func PrintRawField(ui cli.Ui, secret *api.Secret, field string) int { // directly print the message. If mitchellh/cli exposes method // to print without CR, this check needs to be removed. if reflect.TypeOf(ui).String() == "*cli.BasicUi" { - fmt.Fprintf(os.Stdout, fmt.Sprintf("%v", val)) + fmt.Fprintf(os.Stdout, "%v", val) } else { ui.Output(fmt.Sprintf("%v", val)) } From 7c3ef33a941fd6124f1fa06f69b4968baa18ff00 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 22 Nov 2016 12:31:19 -0500 Subject: [PATCH 14/19] changelog++ --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index df812718b604a..16645a2b8bfbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ BUG FIXES: * api/unwrap, command/unwrap: Fix error when no client token exists [GH-2077] * command/ssh: Use temporary file for identity and ensure its deletion before the command returns [GH-2016] + * cli: Fix error printing values with `-field` if the values contained + formatting directives [GH-2109] * core: Fix bug where a failure to come up as active node (e.g. if an audit backend failed) could lead to deadlock [GH-2083] * physical/mysql: Fix potential crash during setup due to a query failure From fba6068e97afbfffc262d32184d8e5b9ef9a9b85 Mon Sep 17 00:00:00 2001 From: Em Smith Date: Tue, 22 Nov 2016 18:44:17 +0100 Subject: [PATCH 15/19] Change command examples for First Secrets #2116 (#2117) These were discovered to be out of date as per https://github.com/hashicorp/vault/issues/2116 --- .../getting-started/first-secret.html.md | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/website/source/intro/getting-started/first-secret.html.md b/website/source/intro/getting-started/first-secret.html.md index c3206f285095c..1fd86aaddfff8 100644 --- a/website/source/intro/getting-started/first-secret.html.md +++ b/website/source/intro/getting-started/first-secret.html.md @@ -62,10 +62,11 @@ As you might expect, secrets can be read with `vault read`: ``` $ vault read secret/hello -Key Value -lease_duration 2764800 -excited yes -value world +Key Value +--- ----- +refresh_interval 768h0m0s +excited yes +value world ``` As you can see, the values we wrote are given back to us. Vault read @@ -79,13 +80,15 @@ a tool like `jq`, you can output the data in JSON format: ``` $ vault read -format=json secret/hello { - "lease_id": "", - "lease_duration": 0, - "renewable": false, - "data": { - "excited": "yes", - "value": "world" - } + "request_id": "68315073-6658-e3ff-2da7-67939fb91bbd", + "lease_id": "", + "lease_duration": 2764800, + "renewable": false, + "data": { + "excited": "yes", + "value": "world" + }, + "warnings": null } ``` From 24d2f39a7fd9f637fe745a107a2580eb891f0fb1 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 22 Nov 2016 12:56:36 -0500 Subject: [PATCH 16/19] Don't say mlock is supported on OSX when it isn't. (#2120) Fixes #2119 --- command/server.go | 2 +- helper/mlock/mlock_unavail.go | 2 +- helper/mlock/mlock_unix.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/command/server.go b/command/server.go index 4a16b1c23100b..881f371eadf94 100644 --- a/command/server.go +++ b/command/server.go @@ -350,7 +350,7 @@ func (c *ServerCommand) Run(args []string) int { info["log level"] = logLevel info["mlock"] = fmt.Sprintf( "supported: %v, enabled: %v", - mlock.Supported(), !config.DisableMlock) + mlock.Supported(), !config.DisableMlock && mlock.Supported()) infoKeys = append(infoKeys, "log level", "mlock", "backend") if config.HABackend != nil { diff --git a/helper/mlock/mlock_unavail.go b/helper/mlock/mlock_unavail.go index 2ae4b352c3559..8084963f72ab7 100644 --- a/helper/mlock/mlock_unavail.go +++ b/helper/mlock/mlock_unavail.go @@ -1,4 +1,4 @@ -// +build android nacl netbsd plan9 windows +// +build android darwin nacl netbsd plan9 windows package mlock diff --git a/helper/mlock/mlock_unix.go b/helper/mlock/mlock_unix.go index f7847a5bd8f51..af0a69d48a36c 100644 --- a/helper/mlock/mlock_unix.go +++ b/helper/mlock/mlock_unix.go @@ -1,4 +1,4 @@ -// +build darwin dragonfly freebsd linux openbsd solaris +// +build dragonfly freebsd linux openbsd solaris package mlock From 5056fb9cd84bf6fb71dc4d570569b04c25b8039f Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 22 Nov 2016 12:57:11 -0500 Subject: [PATCH 17/19] changelog++ --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16645a2b8bfbb..d1d4695239b14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ BUG FIXES: the command returns [GH-2016] * cli: Fix error printing values with `-field` if the values contained formatting directives [GH-2109] + * command/server: Don't say mlock is supported on OSX when it isn't. [GH-2120] * core: Fix bug where a failure to come up as active node (e.g. if an audit backend failed) could lead to deadlock [GH-2083] * physical/mysql: Fix potential crash during setup due to a query failure From 9d2f60a0830e8c72e849b4e66ceff8f7527b5243 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 22 Nov 2016 16:04:50 -0500 Subject: [PATCH 18/19] Change current version number --- version/version_base.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version_base.go b/version/version_base.go index 062d92af9bfcc..a55536eff4320 100644 --- a/version/version_base.go +++ b/version/version_base.go @@ -4,10 +4,10 @@ package version func init() { // The main version number that is being run at the moment. - Version = "0.6.2" + Version = "0.6.3" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. - VersionPrerelease = "" + VersionPrerelease = "dev" } From 2a84f795f778d58ee1d1ddc013c2ad518173ac8b Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 22 Nov 2016 16:43:05 -0500 Subject: [PATCH 19/19] Add version sha to server startup output --- command/server.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/command/server.go b/command/server.go index 881f371eadf94..b8efe14d51c22 100644 --- a/command/server.go +++ b/command/server.go @@ -464,8 +464,10 @@ func (c *ServerCommand) Run(args []string) int { defer c.cleanupGuard.Do(listenerCloseFunc) - infoKeys = append(infoKeys, "version") - info["version"] = version.GetVersion().FullVersionNumber() + infoKeys = append(infoKeys, "version", "version_sha") + verInfo := version.GetVersion() + info["version"] = verInfo.FullVersionNumber() + info["version_sha"] = strings.Trim(verInfo.Revision, "'") // Server configuration output padding := 24