mirror of
https://github.com/genuinetools/reg.git
synced 2024-06-28 10:24:17 -04:00
add v3 api
Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
This commit is contained in:
parent
fc4797acd4
commit
67bc3ef6c3
115
Gopkg.lock
generated
115
Gopkg.lock
generated
|
@ -34,6 +34,16 @@
|
|||
packages = ["pathdriver"]
|
||||
revision = "d3c23511c1bf5851696cba83143d9cbcd666869b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/coreos/clair"
|
||||
packages = [
|
||||
"api/v3/clairpb",
|
||||
"database",
|
||||
"ext/versionfmt"
|
||||
]
|
||||
revision = "e907e4d263a743f7d4923c177e5db37f656a53b4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/docker/cli"
|
||||
|
@ -42,7 +52,7 @@
|
|||
"cli/config/credentials",
|
||||
"opts"
|
||||
]
|
||||
revision = "90f8ce8a5db263842af7bef3726f6c4d6937d85e"
|
||||
revision = "4cb3c70f36baeade76879694a587358be2a74854"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -103,13 +113,13 @@
|
|||
"registry",
|
||||
"registry/resumable"
|
||||
]
|
||||
revision = "fd2f2a919e392b96de74795ae9af2dc5e510bc4c"
|
||||
revision = "d812dee47e26ad4db1d53102f0c16af01f70cf2c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/docker/docker-ce"
|
||||
packages = ["components/cli/cli/config"]
|
||||
revision = "370137f15d67e96f4d4435fc868fb2deec6f1f89"
|
||||
revision = "ecac08f83bacbf4b72d6a55e0de3e7969919d0a5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/docker/docker-credential-helpers"
|
||||
|
@ -157,7 +167,17 @@
|
|||
|
||||
[[projects]]
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
packages = [
|
||||
"jsonpb",
|
||||
"proto",
|
||||
"protoc-gen-go/descriptor",
|
||||
"ptypes",
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/empty",
|
||||
"ptypes/struct",
|
||||
"ptypes/timestamp"
|
||||
]
|
||||
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
version = "v1.1.0"
|
||||
|
||||
|
@ -184,6 +204,16 @@
|
|||
revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf"
|
||||
version = "v1.6.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/grpc-ecosystem/grpc-gateway"
|
||||
packages = [
|
||||
"runtime",
|
||||
"runtime/internal",
|
||||
"utilities"
|
||||
]
|
||||
revision = "92583770e3f01b09a0d3e9bdf64321d8bebd48f2"
|
||||
version = "v1.4.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
|
@ -236,7 +266,7 @@
|
|||
"prometheus",
|
||||
"prometheus/promhttp"
|
||||
]
|
||||
revision = "208fa994be3bd65c0de04f506db92852b581bc4a"
|
||||
revision = "faf4ec335fe01ae5a6a0eaa34a5a9333bfbd1a30"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -281,7 +311,7 @@
|
|||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
revision = "b47b1587369238182299fe4dad77d05b8b461e06"
|
||||
revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -289,8 +319,14 @@
|
|||
packages = [
|
||||
"context",
|
||||
"context/ctxhttp",
|
||||
"http/httpguts",
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"internal/socks",
|
||||
"proxy"
|
||||
"internal/timeseries",
|
||||
"proxy",
|
||||
"trace"
|
||||
]
|
||||
revision = "1e491301e022f8f977054da4c2d852decd59571f"
|
||||
|
||||
|
@ -301,11 +337,72 @@
|
|||
"unix",
|
||||
"windows"
|
||||
]
|
||||
revision = "538ab54ba952cc4c7c705fa213fbf7993c97c175"
|
||||
revision = "bff228c7b664c5fce602223a05fb708fd8654986"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
"collate/build",
|
||||
"internal/colltab",
|
||||
"internal/gen",
|
||||
"internal/tag",
|
||||
"internal/triegen",
|
||||
"internal/ucd",
|
||||
"language",
|
||||
"secure/bidirule",
|
||||
"transform",
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable"
|
||||
]
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = [
|
||||
"googleapis/api/annotations",
|
||||
"googleapis/rpc/status"
|
||||
]
|
||||
revision = "32ee49c4dd805befd833990acba36cb75042378c"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
"balancer",
|
||||
"balancer/base",
|
||||
"balancer/roundrobin",
|
||||
"channelz",
|
||||
"codes",
|
||||
"connectivity",
|
||||
"credentials",
|
||||
"encoding",
|
||||
"encoding/proto",
|
||||
"grpclb/grpc_lb_v1/messages",
|
||||
"grpclog",
|
||||
"internal",
|
||||
"keepalive",
|
||||
"metadata",
|
||||
"naming",
|
||||
"peer",
|
||||
"resolver",
|
||||
"resolver/dns",
|
||||
"resolver/passthrough",
|
||||
"stats",
|
||||
"status",
|
||||
"tap",
|
||||
"transport"
|
||||
]
|
||||
revision = "7a6a684ca69eb4cae85ad0a484f2e531598c047b"
|
||||
version = "v1.12.2"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "5cdf10e821ede3dcf4207f6e2b0e5abe31ac803e81704a82c798b0199c057882"
|
||||
inputs-digest = "7c1fd839f687a4f2c428d59dc6ec6387743b88aeec7d16d7818b881879f07b81"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
|
79
clair/ancestry.go
Normal file
79
clair/ancestry.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package clair
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/coreos/clair/api/v3/clairpb"
|
||||
)
|
||||
|
||||
// GetAncestry displays an ancestry and optionally all of its features and vulnerabilities.
|
||||
func (c *Clair) GetAncestry(name string, features, vulnerabilities bool) (*clairpb.Ancestry, error) {
|
||||
url := c.url("/v3/ancestry")
|
||||
c.Logf("clair.ancestry.get url=%s name=%s", url, name)
|
||||
|
||||
b, err := json.Marshal(clairpb.GetAncestryRequest{AncestryName: name, WithVulnerabilities: vulnerabilities, WithFeatures: features})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.Logf("clair.ancestry.get req.Body=%s", string(b))
|
||||
|
||||
req, err := http.NewRequest("GET", url, bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
c.Logf("clair.ancestry.get resp.Status=%s", resp.Status)
|
||||
|
||||
var aResp clairpb.GetAncestryResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&aResp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if aResp.GetStatus() != nil {
|
||||
c.Logf("clair.ancestry.get ClairStatus=%#v", *aResp.GetStatus())
|
||||
}
|
||||
|
||||
return aResp.GetAncestry(), nil
|
||||
}
|
||||
|
||||
// PostAncestry performs the analysis of all layers from the provided path.
|
||||
func (c *Clair) PostAncestry(name string, layers []*clairpb.PostAncestryRequest_PostLayer) error {
|
||||
url := c.url("/v3/ancestry")
|
||||
c.Logf("clair.ancestry.post url=%s name=%s", url, name)
|
||||
|
||||
b, err := json.Marshal(clairpb.PostAncestryRequest{AncestryName: name, Layers: layers})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Logf("clair.ancestry.post req.Body=%s", string(b))
|
||||
|
||||
resp, err := c.Client.Post(url, "application/json", bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
c.Logf("clair.ancestry.post resp.Status=%s", resp.Status)
|
||||
|
||||
var aResp clairpb.PostAncestryResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&aResp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if aResp.GetStatus() != nil {
|
||||
c.Logf("clair.ancestry.post ClairStatus=%#v", *aResp.GetStatus())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -34,14 +34,15 @@ func (c *Clair) PostLayer(layer *Layer) (*Layer, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
c.Logf("clair.clair req.Body=%s", string(b))
|
||||
c.Logf("clair.layers.post req.Body=%s", string(b))
|
||||
|
||||
resp, err := c.Client.Post(url, "application/json", bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
c.Logf("clair.clair resp.Status=%s", resp.Status)
|
||||
|
||||
c.Logf("clair.layers.post resp.Status=%s", resp.Status)
|
||||
|
||||
var respLayer layerEnvelope
|
||||
if err := json.NewDecoder(resp.Body).Decode(&respLayer); err != nil {
|
||||
|
|
7
vendor/github.com/coreos/clair/.dockerignore
generated
vendored
Normal file
7
vendor/github.com/coreos/clair/.dockerignore
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
.*
|
||||
*.md
|
||||
DCO
|
||||
LICENSE
|
||||
NOTICE
|
||||
docs
|
||||
cloudconfig
|
38
vendor/github.com/coreos/clair/.travis.yml
generated
vendored
Normal file
38
vendor/github.com/coreos/clair/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- "1.10"
|
||||
|
||||
sudo: required
|
||||
|
||||
install:
|
||||
- curl https://glide.sh/get | sh
|
||||
|
||||
script:
|
||||
- go test $(glide novendor | grep -v contrib)
|
||||
|
||||
dist: trusty
|
||||
|
||||
services:
|
||||
- postgresql
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- addons:
|
||||
apt:
|
||||
packages:
|
||||
- rpm
|
||||
postgresql: 9.4
|
||||
- addons:
|
||||
apt:
|
||||
packages:
|
||||
- rpm
|
||||
postgresql: 9.5
|
||||
- addons:
|
||||
apt:
|
||||
packages:
|
||||
- rpm
|
||||
postgresql: 9.6
|
36
vendor/github.com/coreos/clair/DCO
generated
vendored
Executable file
36
vendor/github.com/coreos/clair/DCO
generated
vendored
Executable file
|
@ -0,0 +1,36 @@
|
|||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
29
vendor/github.com/coreos/clair/Dockerfile
generated
vendored
Normal file
29
vendor/github.com/coreos/clair/Dockerfile
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Copyright 2017 clair authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM golang:1.10-alpine
|
||||
|
||||
VOLUME /config
|
||||
EXPOSE 6060 6061
|
||||
|
||||
ADD . /go/src/github.com/coreos/clair/
|
||||
WORKDIR /go/src/github.com/coreos/clair/
|
||||
|
||||
RUN apk add --no-cache git bzr rpm xz dumb-init && \
|
||||
go install -v github.com/coreos/clair/cmd/clair && \
|
||||
mv /go/bin/clair /clair && \
|
||||
rm -rf /go /usr/local/go
|
||||
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/clair"]
|
||||
|
202
vendor/github.com/coreos/clair/LICENSE
generated
vendored
Executable file
202
vendor/github.com/coreos/clair/LICENSE
generated
vendored
Executable file
|
@ -0,0 +1,202 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
5
vendor/github.com/coreos/clair/NOTICE
generated
vendored
Executable file
5
vendor/github.com/coreos/clair/NOTICE
generated
vendored
Executable file
|
@ -0,0 +1,5 @@
|
|||
CoreOS Project
|
||||
Copyright 2015 CoreOS, Inc
|
||||
|
||||
This product includes software developed at CoreOS, Inc.
|
||||
(http://www.coreos.com/).
|
58
vendor/github.com/coreos/clair/README.md
generated
vendored
Normal file
58
vendor/github.com/coreos/clair/README.md
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
# Clair
|
||||
|
||||
[![Build Status](https://api.travis-ci.org/coreos/clair.svg?branch=master "Build Status")](https://travis-ci.org/coreos/clair)
|
||||
[![Docker Repository on Quay](https://quay.io/repository/coreos/clair/status "Docker Repository on Quay")](https://quay.io/repository/coreos/clair)
|
||||
[![Go Report Card](https://goreportcard.com/badge/coreos/clair "Go Report Card")](https://goreportcard.com/report/coreos/clair)
|
||||
[![GoDoc](https://godoc.org/github.com/coreos/clair?status.svg "GoDoc")](https://godoc.org/github.com/coreos/clair)
|
||||
[![IRC Channel](https://img.shields.io/badge/freenode-%23clair-blue.svg "IRC Channel")](http://webchat.freenode.net/?channels=clair)
|
||||
|
||||
**Note**: The `master` branch may be in an *unstable or even broken state* during development.
|
||||
Please use [releases] instead of the `master` branch in order to get stable binaries.
|
||||
|
||||
![Clair Logo](https://cloud.githubusercontent.com/assets/343539/21630811/c5081e5c-d202-11e6-92eb-919d5999c77a.png)
|
||||
|
||||
Clair is an open source project for the [static analysis] of vulnerabilities in application containers (currently including [appc] and [docker]).
|
||||
|
||||
1. In regular intervals, Clair ingests vulnerability metadata from a configured set of sources and stores it in the database.
|
||||
2. Clients use the Clair API to index their container images; this creates a list of _features_ present in the image and stores them in the database.
|
||||
3. Clients use the Clair API to query the database for vulnerabilities of a particular image; correlating vulnerabilities and features is done for each request, avoiding the need to rescan images.
|
||||
4. When updates to vulnerability metadata occur, a notification can be sent to alert systems that a change has occured.
|
||||
|
||||
Our goal is to enable a more transparent view of the security of container-based infrastructure.
|
||||
Thus, the project was named `Clair` after the French term which translates to *clear*, *bright*, *transparent*.
|
||||
|
||||
[appc]: https://github.com/appc/spec
|
||||
[docker]: https://github.com/docker/docker/blob/master/image/spec/v1.2.md
|
||||
[releases]: https://github.com/coreos/clair/releases
|
||||
[static analysis]: https://en.wikipedia.org/wiki/Static_program_analysis
|
||||
|
||||
## Getting Started
|
||||
|
||||
* Learn [the terminology] and about the [drivers and data sources] that power Clair
|
||||
* Watch [presentations] on the high-level goals and design of Clair
|
||||
* Follow instructions to get Clair [up and running]
|
||||
* Explore [the API] on SwaggerHub
|
||||
* Discover third party [integrations] that help integrate Clair with your infrastructure
|
||||
* Read the rest of the documentation on the [CoreOS website] or in the [Documentation directory]
|
||||
|
||||
[the terminology]: /Documentation/terminology.md
|
||||
[drivers and data sources]: /Documentation/drivers-and-data-sources.md
|
||||
[presentations]: /Documentation/presentations.md
|
||||
[up and running]: /Documentation/running-clair.md
|
||||
[the API]: https://app.swaggerhub.com/apis/coreos/clair/3.0
|
||||
[integrations]: /Documentation/integrations.md
|
||||
[CoreOS website]: https://coreos.com/clair/docs/latest/
|
||||
[Documentation directory]: /Documentation
|
||||
|
||||
## Contact
|
||||
|
||||
- IRC: #[clair](irc://irc.freenode.org:6667/#clair) on freenode.org
|
||||
- Bugs: [issues](https://github.com/coreos/clair/issues)
|
||||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING](.github/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
## License
|
||||
|
||||
Clair is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
|
15
vendor/github.com/coreos/clair/ROADMAP.md
generated
vendored
Normal file
15
vendor/github.com/coreos/clair/ROADMAP.md
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Clair Roadmap
|
||||
|
||||
This document defines a high level roadmap for Clair development.
|
||||
|
||||
The dates below should not be considered authoritative, but rather indicative of the projected timeline of the project.
|
||||
The [milestones defined in GitHub](https://github.com/coreos/clair/milestones) represent the most up-to-date and issue-for-issue plans.
|
||||
|
||||
The roadmap below outlines new features that will be added to Clair, and while subject to change, define what future stable will look like.
|
||||
|
||||
- Support multiple namespaces per image
|
||||
- This enables language-level package managers (e.g. npm, pip)
|
||||
- Improve coverage and readability of documentation
|
||||
- Decouple the project from Postgres
|
||||
- gRPC API supporting direct uploads of images
|
||||
- Support operating Clair without internet access
|
127
vendor/github.com/coreos/clair/api/api.go
generated
vendored
Normal file
127
vendor/github.com/coreos/clair/api/api.go
generated
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tylerb/graceful"
|
||||
|
||||
"github.com/coreos/clair/api/v3"
|
||||
"github.com/coreos/clair/database"
|
||||
"github.com/coreos/clair/pkg/stopper"
|
||||
)
|
||||
|
||||
const timeoutResponse = `{"Error":{"Message":"Clair failed to respond within the configured timeout window.","Type":"Timeout"}}`
|
||||
|
||||
// Config is the configuration for the API service.
|
||||
type Config struct {
|
||||
Addr string
|
||||
HealthAddr string
|
||||
Timeout time.Duration
|
||||
CertFile, KeyFile, CAFile string
|
||||
}
|
||||
|
||||
func Run(cfg *Config, store database.Datastore) {
|
||||
tlsConfig, err := tlsClientConfig(cfg.CAFile)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("could not initialize client cert authentication")
|
||||
}
|
||||
if tlsConfig != nil {
|
||||
log.Info("main API configured with client certificate authentication")
|
||||
}
|
||||
v3.Run(cfg.Addr, tlsConfig, cfg.CertFile, cfg.KeyFile, store)
|
||||
}
|
||||
|
||||
func RunHealth(cfg *Config, store database.Datastore, st *stopper.Stopper) {
|
||||
defer st.End()
|
||||
|
||||
// Do not run the API service if there is no config.
|
||||
if cfg == nil {
|
||||
log.Info("health API service is disabled.")
|
||||
return
|
||||
}
|
||||
log.WithField("addr", cfg.HealthAddr).Info("starting health API")
|
||||
|
||||
srv := &graceful.Server{
|
||||
Timeout: 10 * time.Second, // Interrupt health checks when stopping
|
||||
NoSignalHandling: true, // We want to use our own Stopper
|
||||
Server: &http.Server{
|
||||
Addr: cfg.HealthAddr,
|
||||
Handler: http.TimeoutHandler(newHealthHandler(store), cfg.Timeout, timeoutResponse),
|
||||
},
|
||||
}
|
||||
|
||||
listenAndServeWithStopper(srv, st, "", "")
|
||||
|
||||
log.Info("health API stopped")
|
||||
}
|
||||
|
||||
// listenAndServeWithStopper wraps graceful.Server's
|
||||
// ListenAndServe/ListenAndServeTLS and adds the ability to interrupt them with
|
||||
// the provided stopper.Stopper.
|
||||
func listenAndServeWithStopper(srv *graceful.Server, st *stopper.Stopper, certFile, keyFile string) {
|
||||
go func() {
|
||||
<-st.Chan()
|
||||
srv.Stop(0)
|
||||
}()
|
||||
|
||||
var err error
|
||||
if certFile != "" && keyFile != "" {
|
||||
log.Info("API: TLS Enabled")
|
||||
err = srv.ListenAndServeTLS(certFile, keyFile)
|
||||
} else {
|
||||
err = srv.ListenAndServe()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if opErr, ok := err.(*net.OpError); !ok || (ok && opErr.Op != "accept") {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tlsClientConfig initializes a *tls.Config using the given CA. The resulting
|
||||
// *tls.Config is meant to be used to configure an HTTP server to do client
|
||||
// certificate authentication.
|
||||
//
|
||||
// If no CA is given, a nil *tls.Config is returned; no client certificate will
|
||||
// be required and verified. In other words, authentication will be disabled.
|
||||
func tlsClientConfig(caPath string) (*tls.Config, error) {
|
||||
if caPath == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
caCert, err := ioutil.ReadFile(caPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
caCertPool := x509.NewCertPool()
|
||||
caCertPool.AppendCertsFromPEM(caCert)
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
ClientCAs: caCertPool,
|
||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||
}
|
||||
|
||||
return tlsConfig, nil
|
||||
}
|
47
vendor/github.com/coreos/clair/api/router.go
generated
vendored
Normal file
47
vendor/github.com/coreos/clair/api/router.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
|
||||
"github.com/coreos/clair/database"
|
||||
)
|
||||
|
||||
// router is an HTTP router that forwards requests to the appropriate sub-router
|
||||
// depending on the API version specified in the request URI.
|
||||
type router map[string]*httprouter.Router
|
||||
|
||||
func newHealthHandler(store database.Datastore) http.Handler {
|
||||
router := httprouter.New()
|
||||
router.GET("/health", healthHandler(store))
|
||||
return router
|
||||
}
|
||||
|
||||
func healthHandler(store database.Datastore) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
header := w.Header()
|
||||
header.Set("Server", "clair")
|
||||
|
||||
status := http.StatusInternalServerError
|
||||
if store.Ping() {
|
||||
status = http.StatusOK
|
||||
}
|
||||
|
||||
w.WriteHeader(status)
|
||||
}
|
||||
}
|
7
vendor/github.com/coreos/clair/api/v3/clairpb/Dockerfile
generated
vendored
Normal file
7
vendor/github.com/coreos/clair/api/v3/clairpb/Dockerfile
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
FROM golang:alpine
|
||||
|
||||
RUN apk add --update --no-cache git bash protobuf-dev
|
||||
|
||||
RUN go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
|
||||
RUN go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
|
||||
RUN go get -u github.com/golang/protobuf/protoc-gen-go
|
917
vendor/github.com/coreos/clair/api/v3/clairpb/clair.pb.go
generated
vendored
Normal file
917
vendor/github.com/coreos/clair/api/v3/clairpb/clair.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,917 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: api/v3/clairpb/clair.proto
|
||||
|
||||
/*
|
||||
Package clairpb is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
api/v3/clairpb/clair.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Vulnerability
|
||||
ClairStatus
|
||||
Feature
|
||||
Ancestry
|
||||
Layer
|
||||
Notification
|
||||
IndexedAncestryName
|
||||
PagedVulnerableAncestries
|
||||
PostAncestryRequest
|
||||
PostAncestryResponse
|
||||
GetAncestryRequest
|
||||
GetAncestryResponse
|
||||
GetNotificationRequest
|
||||
GetNotificationResponse
|
||||
MarkNotificationAsReadRequest
|
||||
*/
|
||||
package clairpb
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import _ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
import google_protobuf1 "github.com/golang/protobuf/ptypes/empty"
|
||||
import google_protobuf2 "github.com/golang/protobuf/ptypes/timestamp"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type Vulnerability struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
NamespaceName string `protobuf:"bytes,2,opt,name=namespace_name,json=namespaceName" json:"namespace_name,omitempty"`
|
||||
Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"`
|
||||
Link string `protobuf:"bytes,4,opt,name=link" json:"link,omitempty"`
|
||||
Severity string `protobuf:"bytes,5,opt,name=severity" json:"severity,omitempty"`
|
||||
Metadata string `protobuf:"bytes,6,opt,name=metadata" json:"metadata,omitempty"`
|
||||
// fixed_by exists when vulnerability is under feature.
|
||||
FixedBy string `protobuf:"bytes,7,opt,name=fixed_by,json=fixedBy" json:"fixed_by,omitempty"`
|
||||
// affected_versions exists when vulnerability is under notification.
|
||||
AffectedVersions []*Feature `protobuf:"bytes,8,rep,name=affected_versions,json=affectedVersions" json:"affected_versions,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Vulnerability) Reset() { *m = Vulnerability{} }
|
||||
func (m *Vulnerability) String() string { return proto.CompactTextString(m) }
|
||||
func (*Vulnerability) ProtoMessage() {}
|
||||
func (*Vulnerability) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
func (m *Vulnerability) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Vulnerability) GetNamespaceName() string {
|
||||
if m != nil {
|
||||
return m.NamespaceName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Vulnerability) GetDescription() string {
|
||||
if m != nil {
|
||||
return m.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Vulnerability) GetLink() string {
|
||||
if m != nil {
|
||||
return m.Link
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Vulnerability) GetSeverity() string {
|
||||
if m != nil {
|
||||
return m.Severity
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Vulnerability) GetMetadata() string {
|
||||
if m != nil {
|
||||
return m.Metadata
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Vulnerability) GetFixedBy() string {
|
||||
if m != nil {
|
||||
return m.FixedBy
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Vulnerability) GetAffectedVersions() []*Feature {
|
||||
if m != nil {
|
||||
return m.AffectedVersions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClairStatus struct {
|
||||
// listers and detectors are processors implemented in this Clair and used to
|
||||
// scan ancestries
|
||||
Listers []string `protobuf:"bytes,1,rep,name=listers" json:"listers,omitempty"`
|
||||
Detectors []string `protobuf:"bytes,2,rep,name=detectors" json:"detectors,omitempty"`
|
||||
LastUpdateTime *google_protobuf2.Timestamp `protobuf:"bytes,3,opt,name=last_update_time,json=lastUpdateTime" json:"last_update_time,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ClairStatus) Reset() { *m = ClairStatus{} }
|
||||
func (m *ClairStatus) String() string { return proto.CompactTextString(m) }
|
||||
func (*ClairStatus) ProtoMessage() {}
|
||||
func (*ClairStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
func (m *ClairStatus) GetListers() []string {
|
||||
if m != nil {
|
||||
return m.Listers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ClairStatus) GetDetectors() []string {
|
||||
if m != nil {
|
||||
return m.Detectors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ClairStatus) GetLastUpdateTime() *google_protobuf2.Timestamp {
|
||||
if m != nil {
|
||||
return m.LastUpdateTime
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Feature struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
NamespaceName string `protobuf:"bytes,2,opt,name=namespace_name,json=namespaceName" json:"namespace_name,omitempty"`
|
||||
Version string `protobuf:"bytes,3,opt,name=version" json:"version,omitempty"`
|
||||
// version_format is the format used by installer package manager to store
|
||||
// package versions.
|
||||
VersionFormat string `protobuf:"bytes,4,opt,name=version_format,json=versionFormat" json:"version_format,omitempty"`
|
||||
Vulnerabilities []*Vulnerability `protobuf:"bytes,5,rep,name=vulnerabilities" json:"vulnerabilities,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Feature) Reset() { *m = Feature{} }
|
||||
func (m *Feature) String() string { return proto.CompactTextString(m) }
|
||||
func (*Feature) ProtoMessage() {}
|
||||
func (*Feature) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
||||
|
||||
func (m *Feature) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Feature) GetNamespaceName() string {
|
||||
if m != nil {
|
||||
return m.NamespaceName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Feature) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Feature) GetVersionFormat() string {
|
||||
if m != nil {
|
||||
return m.VersionFormat
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Feature) GetVulnerabilities() []*Vulnerability {
|
||||
if m != nil {
|
||||
return m.Vulnerabilities
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Ancestry struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
Features []*Feature `protobuf:"bytes,2,rep,name=features" json:"features,omitempty"`
|
||||
Layers []*Layer `protobuf:"bytes,3,rep,name=layers" json:"layers,omitempty"`
|
||||
// scanned_listers and scanned_detectors are used to scan this ancestry, it
|
||||
// may be different from listers and detectors in ClairStatus since the
|
||||
// ancestry could be scanned by previous version of Clair.
|
||||
ScannedListers []string `protobuf:"bytes,4,rep,name=scanned_listers,json=scannedListers" json:"scanned_listers,omitempty"`
|
||||
ScannedDetectors []string `protobuf:"bytes,5,rep,name=scanned_detectors,json=scannedDetectors" json:"scanned_detectors,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Ancestry) Reset() { *m = Ancestry{} }
|
||||
func (m *Ancestry) String() string { return proto.CompactTextString(m) }
|
||||
func (*Ancestry) ProtoMessage() {}
|
||||
func (*Ancestry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
|
||||
func (m *Ancestry) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Ancestry) GetFeatures() []*Feature {
|
||||
if m != nil {
|
||||
return m.Features
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Ancestry) GetLayers() []*Layer {
|
||||
if m != nil {
|
||||
return m.Layers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Ancestry) GetScannedListers() []string {
|
||||
if m != nil {
|
||||
return m.ScannedListers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Ancestry) GetScannedDetectors() []string {
|
||||
if m != nil {
|
||||
return m.ScannedDetectors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Layer struct {
|
||||
Hash string `protobuf:"bytes,1,opt,name=hash" json:"hash,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Layer) Reset() { *m = Layer{} }
|
||||
func (m *Layer) String() string { return proto.CompactTextString(m) }
|
||||
func (*Layer) ProtoMessage() {}
|
||||
func (*Layer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
|
||||
|
||||
func (m *Layer) GetHash() string {
|
||||
if m != nil {
|
||||
return m.Hash
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
Created string `protobuf:"bytes,2,opt,name=created" json:"created,omitempty"`
|
||||
Notified string `protobuf:"bytes,3,opt,name=notified" json:"notified,omitempty"`
|
||||
Deleted string `protobuf:"bytes,4,opt,name=deleted" json:"deleted,omitempty"`
|
||||
Old *PagedVulnerableAncestries `protobuf:"bytes,5,opt,name=old" json:"old,omitempty"`
|
||||
New *PagedVulnerableAncestries `protobuf:"bytes,6,opt,name=new" json:"new,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Notification) Reset() { *m = Notification{} }
|
||||
func (m *Notification) String() string { return proto.CompactTextString(m) }
|
||||
func (*Notification) ProtoMessage() {}
|
||||
func (*Notification) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
|
||||
|
||||
func (m *Notification) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Notification) GetCreated() string {
|
||||
if m != nil {
|
||||
return m.Created
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Notification) GetNotified() string {
|
||||
if m != nil {
|
||||
return m.Notified
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Notification) GetDeleted() string {
|
||||
if m != nil {
|
||||
return m.Deleted
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Notification) GetOld() *PagedVulnerableAncestries {
|
||||
if m != nil {
|
||||
return m.Old
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Notification) GetNew() *PagedVulnerableAncestries {
|
||||
if m != nil {
|
||||
return m.New
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type IndexedAncestryName struct {
|
||||
// index is unique to name in all streams simultaneously streamed, increasing
|
||||
// and larger than all indexes in previous page in same stream.
|
||||
Index int32 `protobuf:"varint,1,opt,name=index" json:"index,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (m *IndexedAncestryName) Reset() { *m = IndexedAncestryName{} }
|
||||
func (m *IndexedAncestryName) String() string { return proto.CompactTextString(m) }
|
||||
func (*IndexedAncestryName) ProtoMessage() {}
|
||||
func (*IndexedAncestryName) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
|
||||
|
||||
func (m *IndexedAncestryName) GetIndex() int32 {
|
||||
if m != nil {
|
||||
return m.Index
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *IndexedAncestryName) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PagedVulnerableAncestries struct {
|
||||
CurrentPage string `protobuf:"bytes,1,opt,name=current_page,json=currentPage" json:"current_page,omitempty"`
|
||||
// if next_page is empty, it signals the end of all pages.
|
||||
NextPage string `protobuf:"bytes,2,opt,name=next_page,json=nextPage" json:"next_page,omitempty"`
|
||||
Limit int32 `protobuf:"varint,3,opt,name=limit" json:"limit,omitempty"`
|
||||
Vulnerability *Vulnerability `protobuf:"bytes,4,opt,name=vulnerability" json:"vulnerability,omitempty"`
|
||||
Ancestries []*IndexedAncestryName `protobuf:"bytes,5,rep,name=ancestries" json:"ancestries,omitempty"`
|
||||
}
|
||||
|
||||
func (m *PagedVulnerableAncestries) Reset() { *m = PagedVulnerableAncestries{} }
|
||||
func (m *PagedVulnerableAncestries) String() string { return proto.CompactTextString(m) }
|
||||
func (*PagedVulnerableAncestries) ProtoMessage() {}
|
||||
func (*PagedVulnerableAncestries) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||
|
||||
func (m *PagedVulnerableAncestries) GetCurrentPage() string {
|
||||
if m != nil {
|
||||
return m.CurrentPage
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *PagedVulnerableAncestries) GetNextPage() string {
|
||||
if m != nil {
|
||||
return m.NextPage
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *PagedVulnerableAncestries) GetLimit() int32 {
|
||||
if m != nil {
|
||||
return m.Limit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *PagedVulnerableAncestries) GetVulnerability() *Vulnerability {
|
||||
if m != nil {
|
||||
return m.Vulnerability
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PagedVulnerableAncestries) GetAncestries() []*IndexedAncestryName {
|
||||
if m != nil {
|
||||
return m.Ancestries
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PostAncestryRequest struct {
|
||||
AncestryName string `protobuf:"bytes,1,opt,name=ancestry_name,json=ancestryName" json:"ancestry_name,omitempty"`
|
||||
Format string `protobuf:"bytes,2,opt,name=format" json:"format,omitempty"`
|
||||
Layers []*PostAncestryRequest_PostLayer `protobuf:"bytes,3,rep,name=layers" json:"layers,omitempty"`
|
||||
}
|
||||
|
||||
func (m *PostAncestryRequest) Reset() { *m = PostAncestryRequest{} }
|
||||
func (m *PostAncestryRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*PostAncestryRequest) ProtoMessage() {}
|
||||
func (*PostAncestryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
|
||||
|
||||
func (m *PostAncestryRequest) GetAncestryName() string {
|
||||
if m != nil {
|
||||
return m.AncestryName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *PostAncestryRequest) GetFormat() string {
|
||||
if m != nil {
|
||||
return m.Format
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *PostAncestryRequest) GetLayers() []*PostAncestryRequest_PostLayer {
|
||||
if m != nil {
|
||||
return m.Layers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PostAncestryRequest_PostLayer struct {
|
||||
Hash string `protobuf:"bytes,1,opt,name=hash" json:"hash,omitempty"`
|
||||
Path string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"`
|
||||
Headers map[string]string `protobuf:"bytes,3,rep,name=headers" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
}
|
||||
|
||||
func (m *PostAncestryRequest_PostLayer) Reset() { *m = PostAncestryRequest_PostLayer{} }
|
||||
func (m *PostAncestryRequest_PostLayer) String() string { return proto.CompactTextString(m) }
|
||||
func (*PostAncestryRequest_PostLayer) ProtoMessage() {}
|
||||
func (*PostAncestryRequest_PostLayer) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{8, 0}
|
||||
}
|
||||
|
||||
func (m *PostAncestryRequest_PostLayer) GetHash() string {
|
||||
if m != nil {
|
||||
return m.Hash
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *PostAncestryRequest_PostLayer) GetPath() string {
|
||||
if m != nil {
|
||||
return m.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *PostAncestryRequest_PostLayer) GetHeaders() map[string]string {
|
||||
if m != nil {
|
||||
return m.Headers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PostAncestryResponse struct {
|
||||
Status *ClairStatus `protobuf:"bytes,1,opt,name=status" json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (m *PostAncestryResponse) Reset() { *m = PostAncestryResponse{} }
|
||||
func (m *PostAncestryResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*PostAncestryResponse) ProtoMessage() {}
|
||||
func (*PostAncestryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
|
||||
|
||||
func (m *PostAncestryResponse) GetStatus() *ClairStatus {
|
||||
if m != nil {
|
||||
return m.Status
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetAncestryRequest struct {
|
||||
AncestryName string `protobuf:"bytes,1,opt,name=ancestry_name,json=ancestryName" json:"ancestry_name,omitempty"`
|
||||
WithVulnerabilities bool `protobuf:"varint,2,opt,name=with_vulnerabilities,json=withVulnerabilities" json:"with_vulnerabilities,omitempty"`
|
||||
WithFeatures bool `protobuf:"varint,3,opt,name=with_features,json=withFeatures" json:"with_features,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetAncestryRequest) Reset() { *m = GetAncestryRequest{} }
|
||||
func (m *GetAncestryRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetAncestryRequest) ProtoMessage() {}
|
||||
func (*GetAncestryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
|
||||
|
||||
func (m *GetAncestryRequest) GetAncestryName() string {
|
||||
if m != nil {
|
||||
return m.AncestryName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *GetAncestryRequest) GetWithVulnerabilities() bool {
|
||||
if m != nil {
|
||||
return m.WithVulnerabilities
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *GetAncestryRequest) GetWithFeatures() bool {
|
||||
if m != nil {
|
||||
return m.WithFeatures
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type GetAncestryResponse struct {
|
||||
Ancestry *Ancestry `protobuf:"bytes,1,opt,name=ancestry" json:"ancestry,omitempty"`
|
||||
Status *ClairStatus `protobuf:"bytes,2,opt,name=status" json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetAncestryResponse) Reset() { *m = GetAncestryResponse{} }
|
||||
func (m *GetAncestryResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetAncestryResponse) ProtoMessage() {}
|
||||
func (*GetAncestryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
|
||||
|
||||
func (m *GetAncestryResponse) GetAncestry() *Ancestry {
|
||||
if m != nil {
|
||||
return m.Ancestry
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetAncestryResponse) GetStatus() *ClairStatus {
|
||||
if m != nil {
|
||||
return m.Status
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetNotificationRequest struct {
|
||||
// if the vulnerability_page is empty, it implies the first page.
|
||||
OldVulnerabilityPage string `protobuf:"bytes,1,opt,name=old_vulnerability_page,json=oldVulnerabilityPage" json:"old_vulnerability_page,omitempty"`
|
||||
NewVulnerabilityPage string `protobuf:"bytes,2,opt,name=new_vulnerability_page,json=newVulnerabilityPage" json:"new_vulnerability_page,omitempty"`
|
||||
Limit int32 `protobuf:"varint,3,opt,name=limit" json:"limit,omitempty"`
|
||||
Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetNotificationRequest) Reset() { *m = GetNotificationRequest{} }
|
||||
func (m *GetNotificationRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetNotificationRequest) ProtoMessage() {}
|
||||
func (*GetNotificationRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
|
||||
|
||||
func (m *GetNotificationRequest) GetOldVulnerabilityPage() string {
|
||||
if m != nil {
|
||||
return m.OldVulnerabilityPage
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *GetNotificationRequest) GetNewVulnerabilityPage() string {
|
||||
if m != nil {
|
||||
return m.NewVulnerabilityPage
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *GetNotificationRequest) GetLimit() int32 {
|
||||
if m != nil {
|
||||
return m.Limit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *GetNotificationRequest) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetNotificationResponse struct {
|
||||
Notification *Notification `protobuf:"bytes,1,opt,name=notification" json:"notification,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetNotificationResponse) Reset() { *m = GetNotificationResponse{} }
|
||||
func (m *GetNotificationResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetNotificationResponse) ProtoMessage() {}
|
||||
func (*GetNotificationResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
|
||||
|
||||
func (m *GetNotificationResponse) GetNotification() *Notification {
|
||||
if m != nil {
|
||||
return m.Notification
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MarkNotificationAsReadRequest struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MarkNotificationAsReadRequest) Reset() { *m = MarkNotificationAsReadRequest{} }
|
||||
func (m *MarkNotificationAsReadRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*MarkNotificationAsReadRequest) ProtoMessage() {}
|
||||
func (*MarkNotificationAsReadRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
|
||||
|
||||
func (m *MarkNotificationAsReadRequest) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Vulnerability)(nil), "clairpb.Vulnerability")
|
||||
proto.RegisterType((*ClairStatus)(nil), "clairpb.ClairStatus")
|
||||
proto.RegisterType((*Feature)(nil), "clairpb.Feature")
|
||||
proto.RegisterType((*Ancestry)(nil), "clairpb.Ancestry")
|
||||
proto.RegisterType((*Layer)(nil), "clairpb.Layer")
|
||||
proto.RegisterType((*Notification)(nil), "clairpb.Notification")
|
||||
proto.RegisterType((*IndexedAncestryName)(nil), "clairpb.IndexedAncestryName")
|
||||
proto.RegisterType((*PagedVulnerableAncestries)(nil), "clairpb.PagedVulnerableAncestries")
|
||||
proto.RegisterType((*PostAncestryRequest)(nil), "clairpb.PostAncestryRequest")
|
||||
proto.RegisterType((*PostAncestryRequest_PostLayer)(nil), "clairpb.PostAncestryRequest.PostLayer")
|
||||
proto.RegisterType((*PostAncestryResponse)(nil), "clairpb.PostAncestryResponse")
|
||||
proto.RegisterType((*GetAncestryRequest)(nil), "clairpb.GetAncestryRequest")
|
||||
proto.RegisterType((*GetAncestryResponse)(nil), "clairpb.GetAncestryResponse")
|
||||
proto.RegisterType((*GetNotificationRequest)(nil), "clairpb.GetNotificationRequest")
|
||||
proto.RegisterType((*GetNotificationResponse)(nil), "clairpb.GetNotificationResponse")
|
||||
proto.RegisterType((*MarkNotificationAsReadRequest)(nil), "clairpb.MarkNotificationAsReadRequest")
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
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.SupportPackageIsVersion4
|
||||
|
||||
// Client API for AncestryService service
|
||||
|
||||
type AncestryServiceClient interface {
|
||||
PostAncestry(ctx context.Context, in *PostAncestryRequest, opts ...grpc.CallOption) (*PostAncestryResponse, error)
|
||||
GetAncestry(ctx context.Context, in *GetAncestryRequest, opts ...grpc.CallOption) (*GetAncestryResponse, error)
|
||||
}
|
||||
|
||||
type ancestryServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewAncestryServiceClient(cc *grpc.ClientConn) AncestryServiceClient {
|
||||
return &ancestryServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *ancestryServiceClient) PostAncestry(ctx context.Context, in *PostAncestryRequest, opts ...grpc.CallOption) (*PostAncestryResponse, error) {
|
||||
out := new(PostAncestryResponse)
|
||||
err := grpc.Invoke(ctx, "/clairpb.AncestryService/PostAncestry", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *ancestryServiceClient) GetAncestry(ctx context.Context, in *GetAncestryRequest, opts ...grpc.CallOption) (*GetAncestryResponse, error) {
|
||||
out := new(GetAncestryResponse)
|
||||
err := grpc.Invoke(ctx, "/clairpb.AncestryService/GetAncestry", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for AncestryService service
|
||||
|
||||
type AncestryServiceServer interface {
|
||||
PostAncestry(context.Context, *PostAncestryRequest) (*PostAncestryResponse, error)
|
||||
GetAncestry(context.Context, *GetAncestryRequest) (*GetAncestryResponse, error)
|
||||
}
|
||||
|
||||
func RegisterAncestryServiceServer(s *grpc.Server, srv AncestryServiceServer) {
|
||||
s.RegisterService(&_AncestryService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _AncestryService_PostAncestry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(PostAncestryRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AncestryServiceServer).PostAncestry(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/clairpb.AncestryService/PostAncestry",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AncestryServiceServer).PostAncestry(ctx, req.(*PostAncestryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AncestryService_GetAncestry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetAncestryRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AncestryServiceServer).GetAncestry(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/clairpb.AncestryService/GetAncestry",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AncestryServiceServer).GetAncestry(ctx, req.(*GetAncestryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _AncestryService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "clairpb.AncestryService",
|
||||
HandlerType: (*AncestryServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "PostAncestry",
|
||||
Handler: _AncestryService_PostAncestry_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetAncestry",
|
||||
Handler: _AncestryService_GetAncestry_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api/v3/clairpb/clair.proto",
|
||||
}
|
||||
|
||||
// Client API for NotificationService service
|
||||
|
||||
type NotificationServiceClient interface {
|
||||
GetNotification(ctx context.Context, in *GetNotificationRequest, opts ...grpc.CallOption) (*GetNotificationResponse, error)
|
||||
MarkNotificationAsRead(ctx context.Context, in *MarkNotificationAsReadRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error)
|
||||
}
|
||||
|
||||
type notificationServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewNotificationServiceClient(cc *grpc.ClientConn) NotificationServiceClient {
|
||||
return ¬ificationServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *notificationServiceClient) GetNotification(ctx context.Context, in *GetNotificationRequest, opts ...grpc.CallOption) (*GetNotificationResponse, error) {
|
||||
out := new(GetNotificationResponse)
|
||||
err := grpc.Invoke(ctx, "/clairpb.NotificationService/GetNotification", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *notificationServiceClient) MarkNotificationAsRead(ctx context.Context, in *MarkNotificationAsReadRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error) {
|
||||
out := new(google_protobuf1.Empty)
|
||||
err := grpc.Invoke(ctx, "/clairpb.NotificationService/MarkNotificationAsRead", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for NotificationService service
|
||||
|
||||
type NotificationServiceServer interface {
|
||||
GetNotification(context.Context, *GetNotificationRequest) (*GetNotificationResponse, error)
|
||||
MarkNotificationAsRead(context.Context, *MarkNotificationAsReadRequest) (*google_protobuf1.Empty, error)
|
||||
}
|
||||
|
||||
func RegisterNotificationServiceServer(s *grpc.Server, srv NotificationServiceServer) {
|
||||
s.RegisterService(&_NotificationService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _NotificationService_GetNotification_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetNotificationRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(NotificationServiceServer).GetNotification(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/clairpb.NotificationService/GetNotification",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NotificationServiceServer).GetNotification(ctx, req.(*GetNotificationRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _NotificationService_MarkNotificationAsRead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MarkNotificationAsReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(NotificationServiceServer).MarkNotificationAsRead(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/clairpb.NotificationService/MarkNotificationAsRead",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NotificationServiceServer).MarkNotificationAsRead(ctx, req.(*MarkNotificationAsReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _NotificationService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "clairpb.NotificationService",
|
||||
HandlerType: (*NotificationServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetNotification",
|
||||
Handler: _NotificationService_GetNotification_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "MarkNotificationAsRead",
|
||||
Handler: _NotificationService_MarkNotificationAsRead_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api/v3/clairpb/clair.proto",
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("api/v3/clairpb/clair.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 1162 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4d, 0x6f, 0xdb, 0x46,
|
||||
0x13, 0x06, 0x25, 0xcb, 0x92, 0x46, 0xf2, 0xd7, 0x5a, 0x51, 0x68, 0xd9, 0x46, 0x1c, 0xbe, 0x78,
|
||||
0xd3, 0x20, 0x6d, 0x25, 0x54, 0xf6, 0xa1, 0x35, 0xd2, 0x8f, 0xa4, 0x4e, 0xd2, 0x02, 0x49, 0x10,
|
||||
0x30, 0xa9, 0x0f, 0xbd, 0x08, 0x6b, 0x72, 0x64, 0x13, 0xa6, 0x48, 0x96, 0xbb, 0x92, 0x2c, 0x04,
|
||||
0xbd, 0xb4, 0xc7, 0x9e, 0xda, 0xfe, 0x8f, 0xfe, 0x84, 0x5e, 0x0b, 0xf4, 0x9a, 0x7b, 0x81, 0x02,
|
||||
0xbd, 0xf6, 0x3f, 0x14, 0xbb, 0xdc, 0xa5, 0x48, 0x8b, 0x0e, 0x8c, 0xf6, 0x24, 0xce, 0xcc, 0x33,
|
||||
0xbb, 0x33, 0xcf, 0x33, 0x3b, 0x10, 0x74, 0x68, 0xe4, 0xf5, 0x26, 0xfb, 0x3d, 0xc7, 0xa7, 0x5e,
|
||||
0x1c, 0x9d, 0x24, 0xbf, 0xdd, 0x28, 0x0e, 0x79, 0x48, 0xaa, 0xca, 0xd9, 0xd9, 0x39, 0x0d, 0xc3,
|
||||
0x53, 0x1f, 0x7b, 0x02, 0x4b, 0x83, 0x20, 0xe4, 0x94, 0x7b, 0x61, 0xc0, 0x12, 0x58, 0x67, 0x5b,
|
||||
0x45, 0xa5, 0x75, 0x32, 0x1e, 0xf6, 0x70, 0x14, 0xf1, 0x99, 0x0a, 0xde, 0xba, 0x1c, 0xe4, 0xde,
|
||||
0x08, 0x19, 0xa7, 0xa3, 0x28, 0x01, 0x58, 0x3f, 0x95, 0x60, 0xe5, 0x78, 0xec, 0x07, 0x18, 0xd3,
|
||||
0x13, 0xcf, 0xf7, 0xf8, 0x8c, 0x10, 0x58, 0x0a, 0xe8, 0x08, 0x4d, 0x63, 0xcf, 0xb8, 0x5b, 0xb7,
|
||||
0xe5, 0x37, 0xf9, 0x3f, 0xac, 0x8a, 0x5f, 0x16, 0x51, 0x07, 0x07, 0x32, 0x5a, 0x92, 0xd1, 0x95,
|
||||
0xd4, 0xfb, 0x5c, 0xc0, 0xf6, 0xa0, 0xe1, 0x22, 0x73, 0x62, 0x2f, 0x12, 0x05, 0x9a, 0x65, 0x89,
|
||||
0xc9, 0xba, 0xc4, 0xe1, 0xbe, 0x17, 0x9c, 0x9b, 0x4b, 0xc9, 0xe1, 0xe2, 0x9b, 0x74, 0xa0, 0xc6,
|
||||
0x70, 0x82, 0xb1, 0xc7, 0x67, 0x66, 0x45, 0xfa, 0x53, 0x5b, 0xc4, 0x46, 0xc8, 0xa9, 0x4b, 0x39,
|
||||
0x35, 0x97, 0x93, 0x98, 0xb6, 0xc9, 0x16, 0xd4, 0x86, 0xde, 0x05, 0xba, 0x83, 0x93, 0x99, 0x59,
|
||||
0x95, 0xb1, 0xaa, 0xb4, 0x1f, 0xce, 0xc8, 0xc7, 0xb0, 0x41, 0x87, 0x43, 0x74, 0x38, 0xba, 0x83,
|
||||
0x09, 0xc6, 0x4c, 0xd0, 0x65, 0xd6, 0xf6, 0xca, 0x77, 0x1b, 0xfd, 0xf5, 0xae, 0xa2, 0xb5, 0xfb,
|
||||
0x18, 0x29, 0x1f, 0xc7, 0x68, 0xaf, 0x6b, 0xe8, 0xb1, 0x42, 0x5a, 0x3f, 0x18, 0xd0, 0xf8, 0x5c,
|
||||
0xa0, 0x5e, 0x72, 0xca, 0xc7, 0x8c, 0x98, 0x50, 0xf5, 0x3d, 0xc6, 0x31, 0x66, 0xa6, 0xb1, 0x57,
|
||||
0x16, 0x17, 0x29, 0x93, 0xec, 0x40, 0xdd, 0x45, 0x8e, 0x0e, 0x0f, 0x63, 0x66, 0x96, 0x64, 0x6c,
|
||||
0xee, 0x20, 0x47, 0xb0, 0xee, 0x53, 0xc6, 0x07, 0xe3, 0xc8, 0xa5, 0x1c, 0x07, 0x82, 0x7b, 0x49,
|
||||
0x4a, 0xa3, 0xdf, 0xe9, 0x26, 0xc2, 0x74, 0xb5, 0x30, 0xdd, 0x57, 0x5a, 0x18, 0x7b, 0x55, 0xe4,
|
||||
0x7c, 0x25, 0x53, 0x84, 0xd3, 0xfa, 0xcd, 0x80, 0xaa, 0xaa, 0xf5, 0xbf, 0x88, 0x63, 0x42, 0x55,
|
||||
0x51, 0xa1, 0x84, 0xd1, 0xa6, 0x38, 0x40, 0x7d, 0x0e, 0x86, 0x61, 0x3c, 0xa2, 0x5c, 0xc9, 0xb3,
|
||||
0xa2, 0xbc, 0x8f, 0xa5, 0x93, 0x7c, 0x06, 0x6b, 0x93, 0xcc, 0xa4, 0x78, 0xc8, 0xcc, 0x8a, 0xa4,
|
||||
0xb4, 0x9d, 0x52, 0x9a, 0x9b, 0x24, 0xfb, 0x32, 0xdc, 0xfa, 0xdd, 0x80, 0xda, 0x83, 0xc0, 0x41,
|
||||
0xc6, 0xe3, 0xe2, 0x39, 0x7b, 0x0f, 0x6a, 0xc3, 0xa4, 0xd3, 0x84, 0xcd, 0x22, 0xb9, 0x52, 0x04,
|
||||
0xb9, 0x03, 0xcb, 0x3e, 0x9d, 0x09, 0x55, 0xca, 0x12, 0xbb, 0x9a, 0x62, 0x9f, 0x0a, 0xb7, 0xad,
|
||||
0xa2, 0xe4, 0x1d, 0x58, 0x63, 0x0e, 0x0d, 0x02, 0x74, 0x07, 0x5a, 0xc6, 0x25, 0x29, 0xd5, 0xaa,
|
||||
0x72, 0x3f, 0x55, 0x6a, 0xbe, 0x0b, 0x1b, 0x1a, 0x38, 0x57, 0xb5, 0x22, 0xa1, 0xeb, 0x2a, 0x70,
|
||||
0xa4, 0xfd, 0xd6, 0x36, 0x54, 0xe4, 0x35, 0xa2, 0x91, 0x33, 0xca, 0xce, 0x74, 0x23, 0xe2, 0xdb,
|
||||
0xfa, 0xc3, 0x80, 0xe6, 0xf3, 0x90, 0x7b, 0x43, 0xcf, 0xa1, 0x7a, 0xf0, 0x17, 0xba, 0x35, 0xa1,
|
||||
0xea, 0xc4, 0x48, 0x39, 0xba, 0x4a, 0x31, 0x6d, 0x8a, 0xb1, 0x0f, 0x64, 0x36, 0xba, 0x4a, 0xac,
|
||||
0xd4, 0x16, 0x59, 0x2e, 0xfa, 0x28, 0xb2, 0x12, 0x99, 0xb4, 0x49, 0x0e, 0xa0, 0x1c, 0xfa, 0xae,
|
||||
0x7c, 0x43, 0x8d, 0xbe, 0x95, 0x92, 0xf1, 0x82, 0x9e, 0xa2, 0xab, 0x95, 0xf1, 0x51, 0x09, 0xe0,
|
||||
0x21, 0xb3, 0x05, 0x5c, 0x64, 0x05, 0x38, 0x95, 0xaf, 0xeb, 0x9a, 0x59, 0x01, 0x4e, 0xad, 0x4f,
|
||||
0x61, 0xf3, 0xcb, 0xc0, 0xc5, 0x0b, 0x74, 0xb5, 0xa0, 0x72, 0xc8, 0x5a, 0x50, 0xf1, 0x84, 0x5b,
|
||||
0xf6, 0x59, 0xb1, 0x13, 0x23, 0x6d, 0xbe, 0x34, 0x6f, 0xde, 0xfa, 0xdb, 0x80, 0xad, 0x2b, 0xef,
|
||||
0x20, 0xb7, 0xa1, 0xe9, 0x8c, 0xe3, 0x18, 0x03, 0x3e, 0x88, 0xe8, 0xa9, 0xa6, 0xad, 0xa1, 0x7c,
|
||||
0x22, 0x8f, 0x6c, 0x43, 0x3d, 0xc0, 0x0b, 0x15, 0x2f, 0x29, 0x92, 0xf0, 0x22, 0x09, 0xb6, 0xa0,
|
||||
0xe2, 0x7b, 0x23, 0x8f, 0x4b, 0xf6, 0x2a, 0x76, 0x62, 0x90, 0xfb, 0xb0, 0x92, 0x1d, 0xc9, 0x99,
|
||||
0x24, 0xf0, 0xea, 0xf9, 0xcd, 0x83, 0xc9, 0x7d, 0x00, 0x9a, 0x56, 0xa8, 0x46, 0x7f, 0x27, 0x4d,
|
||||
0x2d, 0x60, 0xc3, 0xce, 0xe0, 0xad, 0x37, 0x25, 0xd8, 0x7c, 0x11, 0x32, 0xae, 0x01, 0x36, 0x7e,
|
||||
0x33, 0x46, 0xc6, 0xc9, 0xff, 0x60, 0x45, 0xa1, 0x66, 0x83, 0xcc, 0x84, 0x34, 0x69, 0x96, 0xd6,
|
||||
0x36, 0x2c, 0xab, 0x97, 0x99, 0x34, 0xaa, 0x2c, 0xf2, 0xc9, 0xa5, 0x17, 0x70, 0x67, 0x2e, 0xdf,
|
||||
0xe2, 0x55, 0xd2, 0x97, 0x7b, 0x19, 0x9d, 0x5f, 0x0d, 0xa8, 0xa7, 0xde, 0xa2, 0x41, 0x16, 0xbe,
|
||||
0x88, 0xf2, 0x33, 0x2d, 0x9d, 0xf8, 0x26, 0xcf, 0xa0, 0x7a, 0x86, 0xd4, 0x9d, 0x5f, 0xbb, 0x7f,
|
||||
0xbd, 0x6b, 0xbb, 0x5f, 0x24, 0x59, 0x8f, 0x02, 0x11, 0xd5, 0x67, 0x74, 0x0e, 0xa1, 0x99, 0x0d,
|
||||
0x90, 0x75, 0x28, 0x9f, 0xe3, 0x4c, 0x55, 0x21, 0x3e, 0x85, 0x9a, 0x13, 0xea, 0x8f, 0xb5, 0xcc,
|
||||
0x89, 0x71, 0x58, 0xfa, 0xd0, 0xb0, 0x8e, 0xa0, 0x95, 0xbf, 0x92, 0x45, 0x61, 0xc0, 0xc4, 0x22,
|
||||
0x59, 0x66, 0x72, 0x77, 0xcb, 0x63, 0x1a, 0xfd, 0x56, 0x5a, 0x61, 0x66, 0xaf, 0xdb, 0x0a, 0x63,
|
||||
0xfd, 0x68, 0x00, 0x79, 0x82, 0xff, 0x4e, 0x9a, 0x0f, 0xa0, 0x35, 0xf5, 0xf8, 0xd9, 0xe0, 0xf2,
|
||||
0x6a, 0x14, 0xa5, 0xd6, 0xec, 0x4d, 0x11, 0x3b, 0xce, 0x87, 0xc4, 0xb9, 0x32, 0x25, 0x5d, 0x75,
|
||||
0x65, 0x89, 0x6d, 0x0a, 0xa7, 0xda, 0x72, 0xcc, 0x8a, 0x61, 0x33, 0x57, 0x92, 0x6a, 0xec, 0x7d,
|
||||
0xa8, 0xe9, 0xeb, 0x55, 0x6b, 0x1b, 0x69, 0x6b, 0x29, 0x38, 0x85, 0x64, 0x78, 0x28, 0x5d, 0x83,
|
||||
0x87, 0x5f, 0x0c, 0x68, 0x3f, 0x41, 0x9e, 0x5d, 0x5c, 0x9a, 0x8b, 0x03, 0x68, 0x87, 0xbe, 0x9b,
|
||||
0xeb, 0x72, 0x96, 0x7d, 0x9a, 0xad, 0xd0, 0x77, 0x73, 0xaf, 0x47, 0x3e, 0xc3, 0x03, 0x68, 0x07,
|
||||
0x38, 0x2d, 0xca, 0x4a, 0x94, 0x6c, 0x05, 0x38, 0x5d, 0xcc, 0x2a, 0x7e, 0xbc, 0x7a, 0x89, 0x2c,
|
||||
0x65, 0x96, 0xc8, 0x2b, 0xb8, 0xb9, 0x50, 0xaf, 0x22, 0xea, 0x23, 0x68, 0x06, 0x19, 0xbf, 0x22,
|
||||
0xeb, 0x46, 0xda, 0x7f, 0x2e, 0x29, 0x07, 0xb5, 0xf6, 0x61, 0xf7, 0x19, 0x8d, 0xcf, 0xb3, 0x88,
|
||||
0x07, 0xcc, 0x46, 0xea, 0x6a, 0x32, 0x0a, 0x96, 0x79, 0xff, 0x4f, 0x03, 0xd6, 0xb4, 0x00, 0x2f,
|
||||
0x31, 0x9e, 0x78, 0x0e, 0x12, 0x0a, 0xcd, 0xec, 0x74, 0x92, 0x9d, 0xb7, 0xbd, 0x93, 0xce, 0xee,
|
||||
0x15, 0xd1, 0xa4, 0x21, 0xab, 0xf5, 0xdd, 0x9b, 0xbf, 0x7e, 0x2e, 0xad, 0x5a, 0xf5, 0x9e, 0x56,
|
||||
0xf7, 0xd0, 0xb8, 0x47, 0xce, 0xa1, 0x91, 0x19, 0x13, 0xb2, 0x9d, 0x9e, 0xb1, 0x38, 0xcf, 0x9d,
|
||||
0x9d, 0xe2, 0xa0, 0x3a, 0xff, 0xb6, 0x3c, 0x7f, 0x9b, 0x6c, 0xa5, 0xe7, 0xf7, 0x5e, 0xe7, 0xc6,
|
||||
0xff, 0xdb, 0xfe, 0xf7, 0x25, 0xd8, 0xcc, 0xb2, 0xa2, 0xfb, 0x64, 0xb0, 0x76, 0x49, 0x06, 0x72,
|
||||
0x2b, 0x7b, 0x57, 0xc1, 0x40, 0x75, 0xf6, 0xae, 0x06, 0xa8, 0x82, 0x76, 0x65, 0x41, 0x37, 0xc9,
|
||||
0x8d, 0x5e, 0x56, 0x1d, 0xd6, 0x7b, 0x2d, 0x8b, 0x21, 0x53, 0x68, 0x17, 0xab, 0x44, 0xe6, 0x5b,
|
||||
0xf0, 0xad, 0x32, 0x76, 0xda, 0x0b, 0x7f, 0xc2, 0x1e, 0x89, 0xbf, 0xce, 0xfa, 0xe2, 0x7b, 0xc5,
|
||||
0x17, 0x3f, 0xac, 0x7f, 0xad, 0xff, 0x99, 0x9f, 0x2c, 0xcb, 0xcc, 0xfd, 0x7f, 0x02, 0x00, 0x00,
|
||||
0xff, 0xff, 0x51, 0xb7, 0x75, 0x58, 0xc7, 0x0b, 0x00, 0x00,
|
||||
}
|
363
vendor/github.com/coreos/clair/api/v3/clairpb/clair.pb.gw.go
generated
vendored
Normal file
363
vendor/github.com/coreos/clair/api/v3/clairpb/clair.pb.gw.go
generated
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: api/v3/clairpb/clair.proto
|
||||
|
||||
/*
|
||||
Package clairpb is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package clairpb
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
|
||||
func request_AncestryService_PostAncestry_0(ctx context.Context, marshaler runtime.Marshaler, client AncestryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq PostAncestryRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if req.ContentLength > 0 {
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
msg, err := client.PostAncestry(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_AncestryService_GetAncestry_0 = &utilities.DoubleArray{Encoding: map[string]int{"ancestry_name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
)
|
||||
|
||||
func request_AncestryService_GetAncestry_0(ctx context.Context, marshaler runtime.Marshaler, client AncestryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetAncestryRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["ancestry_name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "ancestry_name")
|
||||
}
|
||||
|
||||
protoReq.AncestryName, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "ancestry_name", err)
|
||||
}
|
||||
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_AncestryService_GetAncestry_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetAncestry(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_NotificationService_GetNotification_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
)
|
||||
|
||||
func request_NotificationService_GetNotification_0(ctx context.Context, marshaler runtime.Marshaler, client NotificationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetNotificationRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
|
||||
protoReq.Name, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_NotificationService_GetNotification_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetNotification(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_NotificationService_MarkNotificationAsRead_0(ctx context.Context, marshaler runtime.Marshaler, client NotificationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq MarkNotificationAsReadRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
|
||||
protoReq.Name, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
msg, err := client.MarkNotificationAsRead(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterAncestryServiceHandlerFromEndpoint is same as RegisterAncestryServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterAncestryServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterAncestryServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterAncestryServiceHandler registers the http handlers for service AncestryService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterAncestryServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterAncestryServiceHandlerClient(ctx, mux, NewAncestryServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterAncestryServiceHandler registers the http handlers for service AncestryService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over the given implementation of "AncestryServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AncestryServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "AncestryServiceClient" to call the correct interceptors.
|
||||
func RegisterAncestryServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AncestryServiceClient) error {
|
||||
|
||||
mux.Handle("POST", pattern_AncestryService_PostAncestry_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_AncestryService_PostAncestry_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AncestryService_PostAncestry_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_AncestryService_GetAncestry_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_AncestryService_GetAncestry_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AncestryService_GetAncestry_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_AncestryService_PostAncestry_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"ancestry"}, ""))
|
||||
|
||||
pattern_AncestryService_GetAncestry_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"ancestry", "ancestry_name"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_AncestryService_PostAncestry_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_AncestryService_GetAncestry_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
// RegisterNotificationServiceHandlerFromEndpoint is same as RegisterNotificationServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterNotificationServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterNotificationServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterNotificationServiceHandler registers the http handlers for service NotificationService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterNotificationServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterNotificationServiceHandlerClient(ctx, mux, NewNotificationServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterNotificationServiceHandler registers the http handlers for service NotificationService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over the given implementation of "NotificationServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "NotificationServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "NotificationServiceClient" to call the correct interceptors.
|
||||
func RegisterNotificationServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client NotificationServiceClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_NotificationService_GetNotification_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_NotificationService_GetNotification_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_NotificationService_GetNotification_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_NotificationService_MarkNotificationAsRead_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_NotificationService_MarkNotificationAsRead_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_NotificationService_MarkNotificationAsRead_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_NotificationService_GetNotification_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"notifications", "name"}, ""))
|
||||
|
||||
pattern_NotificationService_MarkNotificationAsRead_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"notifications", "name"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_NotificationService_GetNotification_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_NotificationService_MarkNotificationAsRead_0 = runtime.ForwardResponseMessage
|
||||
)
|
165
vendor/github.com/coreos/clair/api/v3/clairpb/clair.proto
generated
vendored
Normal file
165
vendor/github.com/coreos/clair/api/v3/clairpb/clair.proto
generated
vendored
Normal file
|
@ -0,0 +1,165 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto3";
|
||||
option go_package = "clairpb";
|
||||
|
||||
package clairpb;
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
message Vulnerability {
|
||||
string name = 1;
|
||||
string namespace_name = 2;
|
||||
string description = 3;
|
||||
string link = 4;
|
||||
string severity = 5;
|
||||
string metadata = 6;
|
||||
// fixed_by exists when vulnerability is under feature.
|
||||
string fixed_by = 7;
|
||||
// affected_versions exists when vulnerability is under notification.
|
||||
repeated Feature affected_versions = 8;
|
||||
}
|
||||
|
||||
message ClairStatus {
|
||||
// listers and detectors are processors implemented in this Clair and used to
|
||||
// scan ancestries
|
||||
repeated string listers = 1;
|
||||
repeated string detectors = 2;
|
||||
google.protobuf.Timestamp last_update_time = 3;
|
||||
}
|
||||
|
||||
message Feature{
|
||||
string name = 1;
|
||||
string namespace_name = 2;
|
||||
string version = 3;
|
||||
|
||||
// version_format is the format used by installer package manager to store
|
||||
// package versions.
|
||||
string version_format = 4;
|
||||
repeated Vulnerability vulnerabilities = 5;
|
||||
}
|
||||
|
||||
message Ancestry {
|
||||
string name = 1;
|
||||
repeated Feature features = 2;
|
||||
repeated Layer layers = 3;
|
||||
|
||||
// scanned_listers and scanned_detectors are used to scan this ancestry, it
|
||||
// may be different from listers and detectors in ClairStatus since the
|
||||
// ancestry could be scanned by previous version of Clair.
|
||||
repeated string scanned_listers = 4;
|
||||
repeated string scanned_detectors = 5;
|
||||
}
|
||||
|
||||
message Layer {
|
||||
string hash = 1;
|
||||
}
|
||||
|
||||
message Notification {
|
||||
string name = 1;
|
||||
string created = 2;
|
||||
string notified = 3;
|
||||
string deleted = 4;
|
||||
PagedVulnerableAncestries old = 5;
|
||||
PagedVulnerableAncestries new = 6;
|
||||
}
|
||||
|
||||
message IndexedAncestryName {
|
||||
// index is unique to name in all streams simultaneously streamed, increasing
|
||||
// and larger than all indexes in previous page in same stream.
|
||||
int32 index = 1;
|
||||
string name = 2;
|
||||
}
|
||||
|
||||
message PagedVulnerableAncestries {
|
||||
string current_page = 1;
|
||||
// if next_page is empty, it signals the end of all pages.
|
||||
string next_page = 2;
|
||||
int32 limit = 3;
|
||||
Vulnerability vulnerability = 4;
|
||||
repeated IndexedAncestryName ancestries = 5;
|
||||
}
|
||||
|
||||
message PostAncestryRequest {
|
||||
message PostLayer {
|
||||
string hash = 1;
|
||||
string path = 2;
|
||||
map<string, string> headers = 3;
|
||||
}
|
||||
string ancestry_name = 1;
|
||||
string format = 2;
|
||||
repeated PostLayer layers = 3;
|
||||
}
|
||||
|
||||
message PostAncestryResponse {
|
||||
ClairStatus status = 1;
|
||||
}
|
||||
|
||||
message GetAncestryRequest {
|
||||
string ancestry_name = 1;
|
||||
bool with_vulnerabilities = 2;
|
||||
bool with_features = 3;
|
||||
}
|
||||
|
||||
message GetAncestryResponse {
|
||||
Ancestry ancestry = 1;
|
||||
ClairStatus status = 2;
|
||||
}
|
||||
|
||||
message GetNotificationRequest {
|
||||
// if the vulnerability_page is empty, it implies the first page.
|
||||
string old_vulnerability_page = 1;
|
||||
string new_vulnerability_page = 2;
|
||||
int32 limit = 3;
|
||||
string name = 4;
|
||||
}
|
||||
|
||||
message GetNotificationResponse {
|
||||
Notification notification = 1;
|
||||
}
|
||||
|
||||
message MarkNotificationAsReadRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
service AncestryService{
|
||||
rpc PostAncestry(PostAncestryRequest) returns (PostAncestryResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/ancestry"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc GetAncestry(GetAncestryRequest) returns (GetAncestryResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/ancestry/{ancestry_name}"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
service NotificationService{
|
||||
rpc GetNotification(GetNotificationRequest) returns (GetNotificationResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/notifications/{name}"
|
||||
};
|
||||
}
|
||||
|
||||
rpc MarkNotificationAsRead(MarkNotificationAsReadRequest) returns (google.protobuf.Empty) {
|
||||
option (google.api.http) = {
|
||||
delete: "/notifications/{name}"
|
||||
};
|
||||
}
|
||||
}
|
399
vendor/github.com/coreos/clair/api/v3/clairpb/clair.swagger.json
generated
vendored
Normal file
399
vendor/github.com/coreos/clair/api/v3/clairpb/clair.swagger.json
generated
vendored
Normal file
|
@ -0,0 +1,399 @@
|
|||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "api/v3/clairpb/clair.proto",
|
||||
"version": "version not set"
|
||||
},
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/ancestry": {
|
||||
"post": {
|
||||
"operationId": "PostAncestry",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairpbPostAncestryResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairpbPostAncestryRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AncestryService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/ancestry/{ancestry_name}": {
|
||||
"get": {
|
||||
"operationId": "GetAncestry",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairpbGetAncestryResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "ancestry_name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "with_vulnerabilities",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "with_features",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AncestryService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/notifications/{name}": {
|
||||
"get": {
|
||||
"operationId": "GetNotification",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairpbGetNotificationResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "old_vulnerability_page",
|
||||
"description": "if the vulnerability_page is empty, it implies the first page.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "new_vulnerability_page",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"NotificationService"
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "MarkNotificationAsRead",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/protobufEmpty"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"NotificationService"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"PostAncestryRequestPostLayer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"hash": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"headers": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbAncestry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"features": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairpbFeature"
|
||||
}
|
||||
},
|
||||
"layers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairpbLayer"
|
||||
}
|
||||
},
|
||||
"scanned_listers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "scanned_listers and scanned_detectors are used to scan this ancestry, it\nmay be different from listers and detectors in ClairStatus since the\nancestry could be scanned by previous version of Clair."
|
||||
},
|
||||
"scanned_detectors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbClairStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"listers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "listers and detectors are processors implemented in this Clair and used to\nscan ancestries"
|
||||
},
|
||||
"detectors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"last_update_time": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbFeature": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespace_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"version_format": {
|
||||
"type": "string",
|
||||
"description": "version_format is the format used by installer package manager to store\npackage versions."
|
||||
},
|
||||
"vulnerabilities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairpbVulnerability"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbGetAncestryResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ancestry": {
|
||||
"$ref": "#/definitions/clairpbAncestry"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/clairpbClairStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbGetNotificationResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"notification": {
|
||||
"$ref": "#/definitions/clairpbNotification"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbIndexedAncestryName": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"index": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "index is unique to name in all streams simultaneously streamed, increasing\nand larger than all indexes in previous page in same stream."
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbLayer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"hash": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbNotification": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"created": {
|
||||
"type": "string"
|
||||
},
|
||||
"notified": {
|
||||
"type": "string"
|
||||
},
|
||||
"deleted": {
|
||||
"type": "string"
|
||||
},
|
||||
"old": {
|
||||
"$ref": "#/definitions/clairpbPagedVulnerableAncestries"
|
||||
},
|
||||
"new": {
|
||||
"$ref": "#/definitions/clairpbPagedVulnerableAncestries"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbPagedVulnerableAncestries": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"current_page": {
|
||||
"type": "string"
|
||||
},
|
||||
"next_page": {
|
||||
"type": "string",
|
||||
"description": "if next_page is empty, it signals the end of all pages."
|
||||
},
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"vulnerability": {
|
||||
"$ref": "#/definitions/clairpbVulnerability"
|
||||
},
|
||||
"ancestries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairpbIndexedAncestryName"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbPostAncestryRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ancestry_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"format": {
|
||||
"type": "string"
|
||||
},
|
||||
"layers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PostAncestryRequestPostLayer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbPostAncestryResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"$ref": "#/definitions/clairpbClairStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairpbVulnerability": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespace_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"link": {
|
||||
"type": "string"
|
||||
},
|
||||
"severity": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "string"
|
||||
},
|
||||
"fixed_by": {
|
||||
"type": "string",
|
||||
"description": "fixed_by exists when vulnerability is under feature."
|
||||
},
|
||||
"affected_versions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairpbFeature"
|
||||
},
|
||||
"description": "affected_versions exists when vulnerability is under notification."
|
||||
}
|
||||
}
|
||||
},
|
||||
"protobufEmpty": {
|
||||
"type": "object",
|
||||
"description": "service Foo {\n rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);\n }\n\nThe JSON representation for `Empty` is empty JSON object `{}`.",
|
||||
"title": "A generic empty message that you can re-use to avoid defining duplicated\nempty messages in your APIs. A typical example is to use it as the request\nor the response type of an API method. For instance:"
|
||||
}
|
||||
}
|
||||
}
|
155
vendor/github.com/coreos/clair/api/v3/clairpb/convert.go
generated
vendored
Normal file
155
vendor/github.com/coreos/clair/api/v3/clairpb/convert.go
generated
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package clairpb
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/clair/database"
|
||||
"github.com/coreos/clair/ext/versionfmt"
|
||||
)
|
||||
|
||||
// PagedVulnerableAncestriesFromDatabaseModel converts database
|
||||
// PagedVulnerableAncestries to api PagedVulnerableAncestries and assigns
|
||||
// indexes to ancestries.
|
||||
func PagedVulnerableAncestriesFromDatabaseModel(dbVuln *database.PagedVulnerableAncestries) (*PagedVulnerableAncestries, error) {
|
||||
if dbVuln == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
vuln, err := VulnerabilityFromDatabaseModel(dbVuln.Vulnerability)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
next := ""
|
||||
if !dbVuln.End {
|
||||
next = string(dbVuln.Next)
|
||||
}
|
||||
|
||||
vulnAncestry := PagedVulnerableAncestries{
|
||||
Vulnerability: vuln,
|
||||
CurrentPage: string(dbVuln.Current),
|
||||
NextPage: next,
|
||||
Limit: int32(dbVuln.Limit),
|
||||
}
|
||||
|
||||
for index, ancestryName := range dbVuln.Affected {
|
||||
indexedAncestry := IndexedAncestryName{
|
||||
Name: ancestryName,
|
||||
Index: int32(index),
|
||||
}
|
||||
vulnAncestry.Ancestries = append(vulnAncestry.Ancestries, &indexedAncestry)
|
||||
}
|
||||
|
||||
return &vulnAncestry, nil
|
||||
}
|
||||
|
||||
// NotificationFromDatabaseModel converts database notification, old and new
|
||||
// vulnerabilities' paged vulnerable ancestries to be api notification.
|
||||
func NotificationFromDatabaseModel(dbNotification database.VulnerabilityNotificationWithVulnerable) (*Notification, error) {
|
||||
var (
|
||||
noti Notification
|
||||
err error
|
||||
)
|
||||
|
||||
noti.Name = dbNotification.Name
|
||||
if !dbNotification.Created.IsZero() {
|
||||
noti.Created = fmt.Sprintf("%d", dbNotification.Created.Unix())
|
||||
}
|
||||
|
||||
if !dbNotification.Notified.IsZero() {
|
||||
noti.Notified = fmt.Sprintf("%d", dbNotification.Notified.Unix())
|
||||
}
|
||||
|
||||
if !dbNotification.Deleted.IsZero() {
|
||||
noti.Deleted = fmt.Sprintf("%d", dbNotification.Deleted.Unix())
|
||||
}
|
||||
|
||||
noti.Old, err = PagedVulnerableAncestriesFromDatabaseModel(dbNotification.Old)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
noti.New, err = PagedVulnerableAncestriesFromDatabaseModel(dbNotification.New)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ¬i, nil
|
||||
}
|
||||
|
||||
func VulnerabilityFromDatabaseModel(dbVuln database.Vulnerability) (*Vulnerability, error) {
|
||||
metaString := ""
|
||||
if dbVuln.Metadata != nil {
|
||||
metadataByte, err := json.Marshal(dbVuln.Metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metaString = string(metadataByte)
|
||||
}
|
||||
|
||||
return &Vulnerability{
|
||||
Name: dbVuln.Name,
|
||||
NamespaceName: dbVuln.Namespace.Name,
|
||||
Description: dbVuln.Description,
|
||||
Link: dbVuln.Link,
|
||||
Severity: string(dbVuln.Severity),
|
||||
Metadata: metaString,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func VulnerabilityWithFixedInFromDatabaseModel(dbVuln database.VulnerabilityWithFixedIn) (*Vulnerability, error) {
|
||||
vuln, err := VulnerabilityFromDatabaseModel(dbVuln.Vulnerability)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vuln.FixedBy = dbVuln.FixedInVersion
|
||||
return vuln, nil
|
||||
}
|
||||
|
||||
// AncestryFromDatabaseModel converts database ancestry to api ancestry.
|
||||
func AncestryFromDatabaseModel(dbAncestry database.Ancestry) *Ancestry {
|
||||
ancestry := &Ancestry{
|
||||
Name: dbAncestry.Name,
|
||||
}
|
||||
for _, layer := range dbAncestry.Layers {
|
||||
ancestry.Layers = append(ancestry.Layers, LayerFromDatabaseModel(layer))
|
||||
}
|
||||
return ancestry
|
||||
}
|
||||
|
||||
// LayerFromDatabaseModel converts database layer to api layer.
|
||||
func LayerFromDatabaseModel(dbLayer database.Layer) *Layer {
|
||||
layer := Layer{Hash: dbLayer.Hash}
|
||||
return &layer
|
||||
}
|
||||
|
||||
// NamespacedFeatureFromDatabaseModel converts database namespacedFeature to api Feature.
|
||||
func NamespacedFeatureFromDatabaseModel(feature database.NamespacedFeature) *Feature {
|
||||
version := feature.Feature.Version
|
||||
if version == versionfmt.MaxVersion {
|
||||
version = "None"
|
||||
}
|
||||
|
||||
return &Feature{
|
||||
Name: feature.Feature.Name,
|
||||
NamespaceName: feature.Namespace.Name,
|
||||
VersionFormat: feature.Namespace.VersionFormat,
|
||||
Version: version,
|
||||
}
|
||||
}
|
28
vendor/github.com/coreos/clair/api/v3/clairpb/generate-protobuf.sh
generated
vendored
Executable file
28
vendor/github.com/coreos/clair/api/v3/clairpb/generate-protobuf.sh
generated
vendored
Executable file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2018 clair authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
DOCKER_REPO_ROOT="$GOPATH/src/github.com/coreos/clair"
|
||||
IMAGE=${IMAGE:-"quay.io/coreos/clair-gen-proto"}
|
||||
|
||||
docker run --rm -it \
|
||||
-v "$DOCKER_REPO_ROOT":"$DOCKER_REPO_ROOT" \
|
||||
-w "$DOCKER_REPO_ROOT" \
|
||||
"$IMAGE" \
|
||||
"./api/v3/clairpb/run_in_docker.sh"
|
39
vendor/github.com/coreos/clair/api/v3/clairpb/run_in_docker.sh
generated
vendored
Executable file
39
vendor/github.com/coreos/clair/api/v3/clairpb/run_in_docker.sh
generated
vendored
Executable file
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2018 clair authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
protoc -I/usr/include -I. \
|
||||
-I"${GOPATH}/src" \
|
||||
-I"${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis" \
|
||||
--go_out=plugins=grpc:. \
|
||||
./api/v3/clairpb/clair.proto
|
||||
|
||||
protoc -I/usr/include -I. \
|
||||
-I"${GOPATH}/src" \
|
||||
-I"${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis" \
|
||||
--grpc-gateway_out=logtostderr=true:. \
|
||||
./api/v3/clairpb/clair.proto
|
||||
|
||||
protoc -I/usr/include -I. \
|
||||
-I"${GOPATH}/src" \
|
||||
-I"${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis" \
|
||||
--swagger_out=logtostderr=true:. \
|
||||
./api/v3/clairpb/clair.proto
|
||||
|
||||
go generate .
|
253
vendor/github.com/coreos/clair/api/v3/rpc.go
generated
vendored
Normal file
253
vendor/github.com/coreos/clair/api/v3/rpc.go
generated
vendored
Normal file
|
@ -0,0 +1,253 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
google_protobuf1 "github.com/golang/protobuf/ptypes/empty"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/coreos/clair"
|
||||
pb "github.com/coreos/clair/api/v3/clairpb"
|
||||
"github.com/coreos/clair/database"
|
||||
"github.com/coreos/clair/pkg/commonerr"
|
||||
)
|
||||
|
||||
// NotificationServer implements NotificationService interface for serving RPC.
|
||||
type NotificationServer struct {
|
||||
Store database.Datastore
|
||||
}
|
||||
|
||||
// AncestryServer implements AncestryService interface for serving RPC.
|
||||
type AncestryServer struct {
|
||||
Store database.Datastore
|
||||
}
|
||||
|
||||
// PostAncestry implements posting an ancestry via the Clair gRPC service.
|
||||
func (s *AncestryServer) PostAncestry(ctx context.Context, req *pb.PostAncestryRequest) (*pb.PostAncestryResponse, error) {
|
||||
ancestryName := req.GetAncestryName()
|
||||
if ancestryName == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "ancestry name should not be empty")
|
||||
}
|
||||
|
||||
layers := req.GetLayers()
|
||||
if len(layers) == 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "ancestry should have at least one layer")
|
||||
}
|
||||
|
||||
ancestryFormat := req.GetFormat()
|
||||
if ancestryFormat == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "ancestry format should not be empty")
|
||||
}
|
||||
|
||||
ancestryLayers := []clair.LayerRequest{}
|
||||
for _, layer := range layers {
|
||||
if layer == nil {
|
||||
err := status.Error(codes.InvalidArgument, "ancestry layer is invalid")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if layer.GetHash() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "ancestry layer hash should not be empty")
|
||||
}
|
||||
|
||||
if layer.GetPath() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "ancestry layer path should not be empty")
|
||||
}
|
||||
|
||||
ancestryLayers = append(ancestryLayers, clair.LayerRequest{
|
||||
Hash: layer.Hash,
|
||||
Headers: layer.Headers,
|
||||
Path: layer.Path,
|
||||
})
|
||||
}
|
||||
|
||||
err := clair.ProcessAncestry(s.Store, ancestryFormat, ancestryName, ancestryLayers)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "ancestry is failed to be processed: "+err.Error())
|
||||
}
|
||||
|
||||
clairStatus, err := s.getClairStatus()
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &pb.PostAncestryResponse{Status: clairStatus}, nil
|
||||
}
|
||||
|
||||
func (s *AncestryServer) getClairStatus() (*pb.ClairStatus, error) {
|
||||
status := &pb.ClairStatus{
|
||||
Listers: clair.Processors.Listers,
|
||||
Detectors: clair.Processors.Detectors,
|
||||
}
|
||||
|
||||
t, firstUpdate, err := clair.GetLastUpdateTime(s.Store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if firstUpdate {
|
||||
return status, nil
|
||||
}
|
||||
|
||||
status.LastUpdateTime, err = ptypes.TimestampProto(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// GetAncestry implements retrieving an ancestry via the Clair gRPC service.
|
||||
func (s *AncestryServer) GetAncestry(ctx context.Context, req *pb.GetAncestryRequest) (*pb.GetAncestryResponse, error) {
|
||||
if req.GetAncestryName() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "ancestry name should not be empty")
|
||||
}
|
||||
|
||||
tx, err := s.Store.Begin()
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
ancestry, _, ok, err := tx.FindAncestry(req.GetAncestryName())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
} else if !ok {
|
||||
return nil, status.Error(codes.NotFound, fmt.Sprintf("requested ancestry '%s' is not found", req.GetAncestryName()))
|
||||
}
|
||||
|
||||
pbAncestry := pb.AncestryFromDatabaseModel(ancestry)
|
||||
if req.GetWithFeatures() || req.GetWithVulnerabilities() {
|
||||
ancestryWFeature, ok, err := tx.FindAncestryFeatures(ancestry.Name)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return nil, status.Error(codes.NotFound, fmt.Sprintf("requested ancestry '%s' is not found", req.GetAncestryName()))
|
||||
}
|
||||
pbAncestry.ScannedDetectors = ancestryWFeature.ProcessedBy.Detectors
|
||||
pbAncestry.ScannedListers = ancestryWFeature.ProcessedBy.Listers
|
||||
|
||||
if req.GetWithVulnerabilities() {
|
||||
featureVulnerabilities, err := tx.FindAffectedNamespacedFeatures(ancestryWFeature.Features)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
for _, fv := range featureVulnerabilities {
|
||||
// Ensure that every feature can be found.
|
||||
if !fv.Valid {
|
||||
return nil, status.Error(codes.Internal, "ancestry feature is not found")
|
||||
}
|
||||
|
||||
pbFeature := pb.NamespacedFeatureFromDatabaseModel(fv.NamespacedFeature)
|
||||
for _, v := range fv.AffectedBy {
|
||||
pbVuln, err := pb.VulnerabilityWithFixedInFromDatabaseModel(v)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
pbFeature.Vulnerabilities = append(pbFeature.Vulnerabilities, pbVuln)
|
||||
}
|
||||
|
||||
pbAncestry.Features = append(pbAncestry.Features, pbFeature)
|
||||
}
|
||||
} else {
|
||||
for _, f := range ancestryWFeature.Features {
|
||||
pbAncestry.Features = append(pbAncestry.Features, pb.NamespacedFeatureFromDatabaseModel(f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clairStatus, err := s.getClairStatus()
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &pb.GetAncestryResponse{
|
||||
Status: clairStatus,
|
||||
Ancestry: pbAncestry,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetNotification implements retrieving a notification via the Clair gRPC
|
||||
// service.
|
||||
func (s *NotificationServer) GetNotification(ctx context.Context, req *pb.GetNotificationRequest) (*pb.GetNotificationResponse, error) {
|
||||
if req.GetName() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "notification name should not be empty")
|
||||
}
|
||||
|
||||
if req.GetLimit() <= 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "notification page limit should not be empty or less than 1")
|
||||
}
|
||||
|
||||
tx, err := s.Store.Begin()
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
dbNotification, ok, err := tx.FindVulnerabilityNotification(
|
||||
req.GetName(),
|
||||
int(req.GetLimit()),
|
||||
database.PageNumber(req.GetOldVulnerabilityPage()),
|
||||
database.PageNumber(req.GetNewVulnerabilityPage()),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return nil, status.Error(codes.NotFound, fmt.Sprintf("requested notification '%s' is not found", req.GetName()))
|
||||
}
|
||||
|
||||
notification, err := pb.NotificationFromDatabaseModel(dbNotification)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &pb.GetNotificationResponse{Notification: notification}, nil
|
||||
}
|
||||
|
||||
// MarkNotificationAsRead implements deleting a notification via the Clair gRPC
|
||||
// service.
|
||||
func (s *NotificationServer) MarkNotificationAsRead(ctx context.Context, req *pb.MarkNotificationAsReadRequest) (*google_protobuf1.Empty, error) {
|
||||
if req.GetName() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "notification name should not be empty")
|
||||
}
|
||||
|
||||
tx, err := s.Store.Begin()
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
err = tx.DeleteNotification(req.GetName())
|
||||
if err == commonerr.ErrNotFound {
|
||||
return nil, status.Error(codes.NotFound, "requested notification \""+req.GetName()+"\" is not found")
|
||||
} else if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &google_protobuf1.Empty{}, nil
|
||||
}
|
222
vendor/github.com/coreos/clair/api/v3/server.go
generated
vendored
Normal file
222
vendor/github.com/coreos/clair/api/v3/server.go
generated
vendored
Normal file
|
@ -0,0 +1,222 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/cmux"
|
||||
"github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
pb "github.com/coreos/clair/api/v3/clairpb"
|
||||
"github.com/coreos/clair/database"
|
||||
)
|
||||
|
||||
// handleShutdown handles the server shut down error.
|
||||
func handleShutdown(err error) {
|
||||
if err != nil {
|
||||
if opErr, ok := err.(*net.OpError); !ok || (ok && opErr.Op != "accept") {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
promResponseDurationMilliseconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Name: "clair_v3_api_response_duration_milliseconds",
|
||||
Help: "The duration of time it takes to receive and write a response to an V2 API request",
|
||||
Buckets: prometheus.ExponentialBuckets(9.375, 2, 10),
|
||||
}, []string{"route", "code"})
|
||||
)
|
||||
|
||||
func init() {
|
||||
prometheus.MustRegister(promResponseDurationMilliseconds)
|
||||
}
|
||||
|
||||
func newGrpcServer(store database.Datastore, tlsConfig *tls.Config) *grpc.Server {
|
||||
grpcOpts := []grpc.ServerOption{
|
||||
grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
|
||||
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
|
||||
}
|
||||
|
||||
if tlsConfig != nil {
|
||||
grpcOpts = append(grpcOpts, grpc.Creds(credentials.NewTLS(tlsConfig)))
|
||||
}
|
||||
|
||||
grpcServer := grpc.NewServer(grpcOpts...)
|
||||
pb.RegisterAncestryServiceServer(grpcServer, &AncestryServer{Store: store})
|
||||
pb.RegisterNotificationServiceServer(grpcServer, &NotificationServer{Store: store})
|
||||
return grpcServer
|
||||
}
|
||||
|
||||
type httpStatusWritter struct {
|
||||
http.ResponseWriter
|
||||
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
func (w *httpStatusWritter) WriteHeader(code int) {
|
||||
w.StatusCode = code
|
||||
w.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
|
||||
// logHandler adds request logging to an http handler.
|
||||
func logHandler(handler http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
start := time.Now()
|
||||
lrw := &httpStatusWritter{ResponseWriter: w, StatusCode: http.StatusOK}
|
||||
|
||||
handler.ServeHTTP(lrw, r)
|
||||
|
||||
statusStr := strconv.Itoa(lrw.StatusCode)
|
||||
if lrw.StatusCode == 0 {
|
||||
statusStr = "???"
|
||||
}
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"remote addr": r.RemoteAddr,
|
||||
"method": r.Method,
|
||||
"request uri": r.RequestURI,
|
||||
"status": statusStr,
|
||||
"elapsed time (ms)": float64(time.Since(start).Nanoseconds()) * 1e-6,
|
||||
}).Info("Handled HTTP request")
|
||||
})
|
||||
}
|
||||
|
||||
func newGrpcGatewayServer(ctx context.Context, listenerAddr string, tlsConfig *tls.Config) http.Handler {
|
||||
var (
|
||||
gwTLSConfig *tls.Config
|
||||
gwOpts []grpc.DialOption
|
||||
)
|
||||
|
||||
if tlsConfig != nil {
|
||||
gwTLSConfig = tlsConfig.Clone()
|
||||
gwTLSConfig.InsecureSkipVerify = true
|
||||
gwOpts = append(gwOpts, grpc.WithTransportCredentials(credentials.NewTLS(gwTLSConfig)))
|
||||
} else {
|
||||
gwOpts = append(gwOpts, grpc.WithInsecure())
|
||||
}
|
||||
|
||||
// changes json serializer to include empty fields with default values
|
||||
jsonOpt := runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{EmitDefaults: true})
|
||||
gwmux := runtime.NewServeMux(jsonOpt)
|
||||
|
||||
conn, err := grpc.DialContext(ctx, listenerAddr, gwOpts...)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("could not initialize grpc gateway connection")
|
||||
}
|
||||
|
||||
err = pb.RegisterAncestryServiceHandler(ctx, gwmux, conn)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("could not initialize ancestry grpc gateway")
|
||||
}
|
||||
|
||||
err = pb.RegisterNotificationServiceHandler(ctx, gwmux, conn)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("could not initialize notification grpc gateway")
|
||||
}
|
||||
|
||||
return logHandler(gwmux)
|
||||
}
|
||||
|
||||
func servePrometheus(mux *http.ServeMux) {
|
||||
mux.Handle("/metrics", prometheus.Handler())
|
||||
}
|
||||
|
||||
// Run initializes grpc and grpc gateway api services on the same address
|
||||
func Run(Addr string, tlsConfig *tls.Config, CertFile, KeyFile string, store database.Datastore) {
|
||||
l, err := net.Listen("tcp", Addr)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatalf("could not listen to address" + Addr)
|
||||
}
|
||||
log.WithField("addr", l.Addr().String()).Info("starting grpc server")
|
||||
|
||||
var (
|
||||
apiHandler http.Handler
|
||||
apiListener net.Listener
|
||||
srv *http.Server
|
||||
ctx = context.Background()
|
||||
httpMux = http.NewServeMux()
|
||||
tcpMux = cmux.New(l)
|
||||
)
|
||||
|
||||
if tlsConfig != nil {
|
||||
cert, err := tls.LoadX509KeyPair(CertFile, KeyFile)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Failed to load certificate files")
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
tlsConfig.NextProtos = []string{"h2"}
|
||||
|
||||
apiListener = tls.NewListener(tcpMux.Match(cmux.Any()), tlsConfig)
|
||||
go func() { handleShutdown(tcpMux.Serve()) }()
|
||||
|
||||
grpcServer := newGrpcServer(store, tlsConfig)
|
||||
gwmux := newGrpcGatewayServer(ctx, apiListener.Addr().String(), tlsConfig)
|
||||
|
||||
httpMux.Handle("/", gwmux)
|
||||
servePrometheus(httpMux)
|
||||
apiHandler = grpcHandlerFunc(grpcServer, httpMux)
|
||||
|
||||
log.Info("grpc server is configured with client certificate authentication")
|
||||
} else {
|
||||
grpcL := tcpMux.Match(cmux.HTTP2HeaderField("content-type", "application/grpc"))
|
||||
apiListener = tcpMux.Match(cmux.Any())
|
||||
go func() { handleShutdown(tcpMux.Serve()) }()
|
||||
|
||||
grpcServer := newGrpcServer(store, nil)
|
||||
go func() { handleShutdown(grpcServer.Serve(grpcL)) }()
|
||||
|
||||
gwmux := newGrpcGatewayServer(ctx, apiListener.Addr().String(), nil)
|
||||
|
||||
httpMux.Handle("/", gwmux)
|
||||
servePrometheus(httpMux)
|
||||
apiHandler = httpMux
|
||||
|
||||
log.Warn("grpc server is configured without client certificate authentication")
|
||||
}
|
||||
|
||||
srv = &http.Server{
|
||||
Handler: apiHandler,
|
||||
TLSConfig: tlsConfig,
|
||||
}
|
||||
|
||||
// blocking call
|
||||
handleShutdown(srv.Serve(apiListener))
|
||||
log.Info("Grpc API stopped")
|
||||
}
|
||||
|
||||
// grpcHandlerFunc returns an http.Handler that delegates to grpcServer on incoming gRPC
|
||||
// connections or otherHandler otherwise. Copied from cockroachdb.
|
||||
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
|
||||
grpcServer.ServeHTTP(w, r)
|
||||
} else {
|
||||
otherHandler.ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
}
|
132
vendor/github.com/coreos/clair/bill-of-materials.json
generated
vendored
Normal file
132
vendor/github.com/coreos/clair/bill-of-materials.json
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
[
|
||||
{
|
||||
"project": "github.com/beorn7/perks/quantile",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT License",
|
||||
"confidence": 0.9891304347826086
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/coreos/clair",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache License 2.0",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/coreos/pkg/timeutil",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache License 2.0",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/golang/protobuf/proto",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "BSD 3-clause \"New\" or \"Revised\" License",
|
||||
"confidence": 0.92
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/matttproud/golang_protobuf_extensions/pbutil",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache License 2.0",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/pborman/uuid",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "BSD 3-clause \"New\" or \"Revised\" License",
|
||||
"confidence": 0.9663865546218487
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/prometheus/client_golang/prometheus",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache License 2.0",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/prometheus/client_model/go",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache License 2.0",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/prometheus/common",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache License 2.0",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/prometheus/procfs",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache License 2.0",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/sirupsen/logrus",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT License",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/stretchr/testify/assert",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT License",
|
||||
"confidence": 0.9430051813471503
|
||||
},
|
||||
{
|
||||
"type": "MIT License",
|
||||
"confidence": 0.9430051813471503
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "ISC License",
|
||||
"confidence": 0.9850746268656716
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "BSD 3-clause \"New\" or \"Revised\" License",
|
||||
"confidence": 0.9830508474576272
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
61
vendor/github.com/coreos/clair/code-of-conduct.md
generated
vendored
Normal file
61
vendor/github.com/coreos/clair/code-of-conduct.md
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
## CoreOS Community Code of Conduct
|
||||
|
||||
### Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of
|
||||
fostering an open and welcoming community, we pledge to respect all people who
|
||||
contribute through reporting issues, posting feature requests, updating
|
||||
documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free
|
||||
experience for everyone, regardless of level of experience, gender, gender
|
||||
identity and expression, sexual orientation, disability, personal appearance,
|
||||
body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as physical or electronic addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct. By adopting this Code of Conduct,
|
||||
project maintainers commit themselves to fairly and consistently applying these
|
||||
principles to every aspect of managing this project. Project maintainers who do
|
||||
not follow or enforce the Code of Conduct may be permanently removed from the
|
||||
project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting a project maintainer, Brandon Philips
|
||||
<brandon.philips@coreos.com>, and/or Rithu John <rithu.john@coreos.com>.
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant
|
||||
(http://contributor-covenant.org), version 1.2.0, available at
|
||||
http://contributor-covenant.org/version/1/2/0/
|
||||
|
||||
### CoreOS Events Code of Conduct
|
||||
|
||||
CoreOS events are working conferences intended for professional networking and
|
||||
collaboration in the CoreOS community. Attendees are expected to behave
|
||||
according to professional standards and in accordance with their employer’s
|
||||
policies on appropriate workplace behavior.
|
||||
|
||||
While at CoreOS events or related social networking opportunities, attendees
|
||||
should not engage in discriminatory or offensive speech or actions including
|
||||
but not limited to gender, sexuality, race, age, disability, or religion.
|
||||
Speakers should be especially aware of these concerns.
|
||||
|
||||
CoreOS does not condone any statements by speakers contrary to these standards.
|
||||
CoreOS reserves the right to deny entrance and/or eject from an event (without
|
||||
refund) any individual found to be engaging in discriminatory or offensive
|
||||
speech or actions.
|
||||
|
||||
Please bring any concerns to the immediate attention of designated on-site
|
||||
staff, Brandon Philips <brandon.philips@coreos.com>, and/or Rithu John <rithu.john@coreos.com>.
|
99
vendor/github.com/coreos/clair/config.yaml.sample
generated
vendored
Normal file
99
vendor/github.com/coreos/clair/config.yaml.sample
generated
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
# Copyright 2015 clair authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The values specified here are the default values that Clair uses if no configuration file is specified or if the keys are not defined.
|
||||
clair:
|
||||
database:
|
||||
# Database driver
|
||||
type: pgsql
|
||||
options:
|
||||
# PostgreSQL Connection string
|
||||
# https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
||||
source: host=localhost port=5432 user=postgres sslmode=disable statement_timeout=60000
|
||||
|
||||
# Number of elements kept in the cache
|
||||
# Values unlikely to change (e.g. namespaces) are cached in order to save prevent needless roundtrips to the database.
|
||||
cachesize: 16384
|
||||
|
||||
# 32-bit URL-safe base64 key used to encrypt pagination tokens
|
||||
# If one is not provided, it will be generated.
|
||||
# Multiple clair instances in the same cluster need the same value.
|
||||
paginationkey:
|
||||
|
||||
api:
|
||||
# v3 grpc/RESTful API server address
|
||||
addr: "0.0.0.0:6060"
|
||||
|
||||
# Health server address
|
||||
# This is an unencrypted endpoint useful for load balancers to check to healthiness of the clair server.
|
||||
healthaddr: "0.0.0.0:6061"
|
||||
|
||||
# Deadline before an API request will respond with a 503
|
||||
timeout: 900s
|
||||
|
||||
# Optional PKI configuration
|
||||
# If you want to easily generate client certificates and CAs, try the following projects:
|
||||
# https://github.com/coreos/etcd-ca
|
||||
# https://github.com/cloudflare/cfssl
|
||||
servername:
|
||||
cafile:
|
||||
keyfile:
|
||||
certfile:
|
||||
|
||||
worker:
|
||||
namespace_detectors:
|
||||
- os-release
|
||||
- lsb-release
|
||||
- apt-sources
|
||||
- alpine-release
|
||||
- redhat-release
|
||||
|
||||
feature_listers:
|
||||
- apk
|
||||
- dpkg
|
||||
- rpm
|
||||
|
||||
updater:
|
||||
# Frequency the database will be updated with vulnerabilities from the default data sources
|
||||
# The value 0 disables the updater entirely.
|
||||
interval: 2h
|
||||
enabledupdaters:
|
||||
- debian
|
||||
- ubuntu
|
||||
- rhel
|
||||
- oracle
|
||||
- alpine
|
||||
|
||||
notifier:
|
||||
# Number of attempts before the notification is marked as failed to be sent
|
||||
attempts: 3
|
||||
|
||||
# Duration before a failed notification is retried
|
||||
renotifyinterval: 2h
|
||||
|
||||
http:
|
||||
# Optional endpoint that will receive notifications via POST requests
|
||||
endpoint:
|
||||
|
||||
# Optional PKI configuration
|
||||
# If you want to easily generate client certificates and CAs, try the following projects:
|
||||
# https://github.com/cloudflare/cfssl
|
||||
# https://github.com/coreos/etcd-ca
|
||||
servername:
|
||||
cafile:
|
||||
keyfile:
|
||||
certfile:
|
||||
|
||||
# Optional HTTP Proxy: must be a valid URL (including the scheme).
|
||||
proxy:
|
224
vendor/github.com/coreos/clair/database/database.go
generated
vendored
Normal file
224
vendor/github.com/coreos/clair/database/database.go
generated
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package database defines the Clair's models and a common interface for
|
||||
// database implementations.
|
||||
package database
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrBackendException is an error that occurs when the database backend
|
||||
// does not work properly (ie. unreachable).
|
||||
ErrBackendException = errors.New("database: an error occurred when querying the backend")
|
||||
|
||||
// ErrInconsistent is an error that occurs when a database consistency check
|
||||
// fails (i.e. when an entity which is supposed to be unique is detected
|
||||
// twice)
|
||||
ErrInconsistent = errors.New("database: inconsistent database")
|
||||
)
|
||||
|
||||
// RegistrableComponentConfig is a configuration block that can be used to
|
||||
// determine which registrable component should be initialized and pass custom
|
||||
// configuration to it.
|
||||
type RegistrableComponentConfig struct {
|
||||
Type string
|
||||
Options map[string]interface{}
|
||||
}
|
||||
|
||||
var drivers = make(map[string]Driver)
|
||||
|
||||
// Driver is a function that opens a Datastore specified by its database driver
|
||||
// type and specific configuration.
|
||||
type Driver func(RegistrableComponentConfig) (Datastore, error)
|
||||
|
||||
// Register makes a Constructor available by the provided name.
|
||||
//
|
||||
// If this function is called twice with the same name or if the Constructor is
|
||||
// nil, it panics.
|
||||
func Register(name string, driver Driver) {
|
||||
if driver == nil {
|
||||
panic("database: could not register nil Driver")
|
||||
}
|
||||
if _, dup := drivers[name]; dup {
|
||||
panic("database: could not register duplicate Driver: " + name)
|
||||
}
|
||||
drivers[name] = driver
|
||||
}
|
||||
|
||||
// Open opens a Datastore specified by a configuration.
|
||||
func Open(cfg RegistrableComponentConfig) (Datastore, error) {
|
||||
driver, ok := drivers[cfg.Type]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("database: unknown Driver %q (forgotten configuration or import?)", cfg.Type)
|
||||
}
|
||||
return driver(cfg)
|
||||
}
|
||||
|
||||
// Session contains the required operations on a persistent data store for a
|
||||
// Clair deployment.
|
||||
//
|
||||
// Session is started by Datastore.Begin and terminated with Commit or Rollback.
|
||||
// Besides Commit and Rollback, other functions cannot be called after the
|
||||
// session is terminated.
|
||||
// Any function is not guaranteed to be called successfully if there's a session
|
||||
// failure.
|
||||
type Session interface {
|
||||
// Commit commits changes to datastore.
|
||||
//
|
||||
// Commit call after Rollback does no-op.
|
||||
Commit() error
|
||||
|
||||
// Rollback drops changes to datastore.
|
||||
//
|
||||
// Rollback call after Commit does no-op.
|
||||
Rollback() error
|
||||
|
||||
// UpsertAncestry inserts or replaces an ancestry and its namespaced
|
||||
// features and processors used to scan the ancestry.
|
||||
UpsertAncestry(ancestry Ancestry, features []NamespacedFeature, processedBy Processors) error
|
||||
|
||||
// FindAncestry retrieves an ancestry with processors used to scan the
|
||||
// ancestry. If the ancestry is not found, return false.
|
||||
//
|
||||
// The ancestry's processors are returned to short cut processing ancestry
|
||||
// if it has been processed by all processors in the current Clair instance.
|
||||
FindAncestry(name string) (ancestry Ancestry, processedBy Processors, found bool, err error)
|
||||
|
||||
// FindAncestryFeatures retrieves an ancestry with all detected namespaced
|
||||
// features. If the ancestry is not found, return false.
|
||||
FindAncestryFeatures(name string) (ancestry AncestryWithFeatures, found bool, err error)
|
||||
|
||||
// PersistFeatures inserts a set of features if not in the database.
|
||||
PersistFeatures(features []Feature) error
|
||||
|
||||
// PersistNamespacedFeatures inserts a set of namespaced features if not in
|
||||
// the database.
|
||||
PersistNamespacedFeatures([]NamespacedFeature) error
|
||||
|
||||
// CacheAffectedNamespacedFeatures relates the namespaced features with the
|
||||
// vulnerabilities affecting these features.
|
||||
//
|
||||
// NOTE(Sida): it's not necessary for every database implementation and so
|
||||
// this function may have a better home.
|
||||
CacheAffectedNamespacedFeatures([]NamespacedFeature) error
|
||||
|
||||
// FindAffectedNamespacedFeatures retrieves a set of namespaced features
|
||||
// with affecting vulnerabilities.
|
||||
FindAffectedNamespacedFeatures(features []NamespacedFeature) ([]NullableAffectedNamespacedFeature, error)
|
||||
|
||||
// PersistNamespaces inserts a set of namespaces if not in the database.
|
||||
PersistNamespaces([]Namespace) error
|
||||
|
||||
// PersistLayer inserts a layer if not in the datastore.
|
||||
PersistLayer(Layer) error
|
||||
|
||||
// PersistLayerContent persists a layer's content in the database. The given
|
||||
// namespaces and features can be partial content of this layer.
|
||||
//
|
||||
// The layer, namespaces and features are expected to be already existing
|
||||
// in the database.
|
||||
PersistLayerContent(hash string, namespaces []Namespace, features []Feature, processedBy Processors) error
|
||||
|
||||
// FindLayer retrieves a layer and the processors scanned the layer.
|
||||
FindLayer(hash string) (layer Layer, processedBy Processors, found bool, err error)
|
||||
|
||||
// FindLayerWithContent returns a layer with all detected features and
|
||||
// namespaces.
|
||||
FindLayerWithContent(hash string) (layer LayerWithContent, found bool, err error)
|
||||
|
||||
// InsertVulnerabilities inserts a set of UNIQUE vulnerabilities with
|
||||
// affected features into database, assuming that all vulnerabilities
|
||||
// provided are NOT in database and all vulnerabilities' namespaces are
|
||||
// already in the database.
|
||||
InsertVulnerabilities([]VulnerabilityWithAffected) error
|
||||
|
||||
// FindVulnerability retrieves a set of Vulnerabilities with affected
|
||||
// features.
|
||||
FindVulnerabilities([]VulnerabilityID) ([]NullableVulnerability, error)
|
||||
|
||||
// DeleteVulnerability removes a set of Vulnerabilities assuming that the
|
||||
// requested vulnerabilities are in the database.
|
||||
DeleteVulnerabilities([]VulnerabilityID) error
|
||||
|
||||
// InsertVulnerabilityNotifications inserts a set of unique vulnerability
|
||||
// notifications into datastore, assuming that they are not in the database.
|
||||
InsertVulnerabilityNotifications([]VulnerabilityNotification) error
|
||||
|
||||
// FindNewNotification retrieves a notification, which has never been
|
||||
// notified or notified before a certain time.
|
||||
FindNewNotification(notifiedBefore time.Time) (hook NotificationHook, found bool, err error)
|
||||
|
||||
// FindVulnerabilityNotification retrieves a vulnerability notification with
|
||||
// affected ancestries affected by old or new vulnerability.
|
||||
//
|
||||
// Because the number of affected ancestries maybe large, they are paginated
|
||||
// and their pages are specified by the given encrypted PageNumbers, which,
|
||||
// if empty, are always considered first page.
|
||||
//
|
||||
// Session interface implementation should have encrypt and decrypt
|
||||
// functions for PageNumber.
|
||||
FindVulnerabilityNotification(name string, limit int,
|
||||
oldVulnerabilityPage PageNumber,
|
||||
newVulnerabilityPage PageNumber) (
|
||||
noti VulnerabilityNotificationWithVulnerable,
|
||||
found bool, err error)
|
||||
|
||||
// MarkNotificationNotified marks a Notification as notified now, assuming
|
||||
// the requested notification is in the database.
|
||||
MarkNotificationNotified(name string) error
|
||||
|
||||
// DeleteNotification removes a Notification in the database.
|
||||
DeleteNotification(name string) error
|
||||
|
||||
// UpdateKeyValue stores or updates a simple key/value pair.
|
||||
UpdateKeyValue(key, value string) error
|
||||
|
||||
// FindKeyValue retrieves a value from the given key.
|
||||
FindKeyValue(key string) (value string, found bool, err error)
|
||||
|
||||
// Lock creates or renew a Lock in the database with the given name, owner
|
||||
// and duration.
|
||||
//
|
||||
// After the specified duration, the Lock expires by itself if it hasn't been
|
||||
// unlocked, and thus, let other users create a Lock with the same name.
|
||||
// However, the owner can renew its Lock by setting renew to true.
|
||||
// Lock should not block, it should instead returns whether the Lock has been
|
||||
// successfully acquired/renewed. If it's the case, the expiration time of
|
||||
// that Lock is returned as well.
|
||||
Lock(name string, owner string, duration time.Duration, renew bool) (success bool, expiration time.Time, err error)
|
||||
|
||||
// Unlock releases an existing Lock.
|
||||
Unlock(name, owner string) error
|
||||
|
||||
// FindLock returns the owner of a Lock specified by the name, and its
|
||||
// expiration time if it exists.
|
||||
FindLock(name string) (owner string, expiration time.Time, found bool, err error)
|
||||
}
|
||||
|
||||
// Datastore represents a persistent data store
|
||||
type Datastore interface {
|
||||
// Begin starts a session to change.
|
||||
Begin() (Session, error)
|
||||
|
||||
// Ping returns the health status of the database.
|
||||
Ping() bool
|
||||
|
||||
// Close closes the database and frees any allocated resource.
|
||||
Close()
|
||||
}
|
270
vendor/github.com/coreos/clair/database/mock.go
generated
vendored
Normal file
270
vendor/github.com/coreos/clair/database/mock.go
generated
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
// Copyright 2015 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package database
|
||||
|
||||
import "time"
|
||||
|
||||
// MockSession implements Session and enables overriding each available method.
|
||||
// The default behavior of each method is to simply panic.
|
||||
type MockSession struct {
|
||||
FctCommit func() error
|
||||
FctRollback func() error
|
||||
FctUpsertAncestry func(Ancestry, []NamespacedFeature, Processors) error
|
||||
FctFindAncestry func(name string) (Ancestry, Processors, bool, error)
|
||||
FctFindAncestryFeatures func(name string) (AncestryWithFeatures, bool, error)
|
||||
FctFindAffectedNamespacedFeatures func(features []NamespacedFeature) ([]NullableAffectedNamespacedFeature, error)
|
||||
FctPersistNamespaces func([]Namespace) error
|
||||
FctPersistFeatures func([]Feature) error
|
||||
FctPersistNamespacedFeatures func([]NamespacedFeature) error
|
||||
FctCacheAffectedNamespacedFeatures func([]NamespacedFeature) error
|
||||
FctPersistLayer func(Layer) error
|
||||
FctPersistLayerContent func(hash string, namespaces []Namespace, features []Feature, processedBy Processors) error
|
||||
FctFindLayer func(name string) (Layer, Processors, bool, error)
|
||||
FctFindLayerWithContent func(name string) (LayerWithContent, bool, error)
|
||||
FctInsertVulnerabilities func([]VulnerabilityWithAffected) error
|
||||
FctFindVulnerabilities func([]VulnerabilityID) ([]NullableVulnerability, error)
|
||||
FctDeleteVulnerabilities func([]VulnerabilityID) error
|
||||
FctInsertVulnerabilityNotifications func([]VulnerabilityNotification) error
|
||||
FctFindNewNotification func(lastNotified time.Time) (NotificationHook, bool, error)
|
||||
FctFindVulnerabilityNotification func(name string, limit int, oldPage PageNumber, newPage PageNumber) (
|
||||
vuln VulnerabilityNotificationWithVulnerable, ok bool, err error)
|
||||
FctMarkNotificationNotified func(name string) error
|
||||
FctDeleteNotification func(name string) error
|
||||
FctUpdateKeyValue func(key, value string) error
|
||||
FctFindKeyValue func(key string) (string, bool, error)
|
||||
FctLock func(name string, owner string, duration time.Duration, renew bool) (bool, time.Time, error)
|
||||
FctUnlock func(name, owner string) error
|
||||
FctFindLock func(name string) (string, time.Time, bool, error)
|
||||
}
|
||||
|
||||
func (ms *MockSession) Commit() error {
|
||||
if ms.FctCommit != nil {
|
||||
return ms.FctCommit()
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) Rollback() error {
|
||||
if ms.FctRollback != nil {
|
||||
return ms.FctRollback()
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) UpsertAncestry(ancestry Ancestry, features []NamespacedFeature, processedBy Processors) error {
|
||||
if ms.FctUpsertAncestry != nil {
|
||||
return ms.FctUpsertAncestry(ancestry, features, processedBy)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindAncestry(name string) (Ancestry, Processors, bool, error) {
|
||||
if ms.FctFindAncestry != nil {
|
||||
return ms.FctFindAncestry(name)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindAncestryFeatures(name string) (AncestryWithFeatures, bool, error) {
|
||||
if ms.FctFindAncestryFeatures != nil {
|
||||
return ms.FctFindAncestryFeatures(name)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindAffectedNamespacedFeatures(features []NamespacedFeature) ([]NullableAffectedNamespacedFeature, error) {
|
||||
if ms.FctFindAffectedNamespacedFeatures != nil {
|
||||
return ms.FctFindAffectedNamespacedFeatures(features)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) PersistNamespaces(namespaces []Namespace) error {
|
||||
if ms.FctPersistNamespaces != nil {
|
||||
return ms.FctPersistNamespaces(namespaces)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) PersistFeatures(features []Feature) error {
|
||||
if ms.FctPersistFeatures != nil {
|
||||
return ms.FctPersistFeatures(features)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) PersistNamespacedFeatures(namespacedFeatures []NamespacedFeature) error {
|
||||
if ms.FctPersistNamespacedFeatures != nil {
|
||||
return ms.FctPersistNamespacedFeatures(namespacedFeatures)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) CacheAffectedNamespacedFeatures(namespacedFeatures []NamespacedFeature) error {
|
||||
if ms.FctCacheAffectedNamespacedFeatures != nil {
|
||||
return ms.FctCacheAffectedNamespacedFeatures(namespacedFeatures)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) PersistLayer(layer Layer) error {
|
||||
if ms.FctPersistLayer != nil {
|
||||
return ms.FctPersistLayer(layer)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) PersistLayerContent(hash string, namespaces []Namespace, features []Feature, processedBy Processors) error {
|
||||
if ms.FctPersistLayerContent != nil {
|
||||
return ms.FctPersistLayerContent(hash, namespaces, features, processedBy)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindLayer(name string) (Layer, Processors, bool, error) {
|
||||
if ms.FctFindLayer != nil {
|
||||
return ms.FctFindLayer(name)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindLayerWithContent(name string) (LayerWithContent, bool, error) {
|
||||
if ms.FctFindLayerWithContent != nil {
|
||||
return ms.FctFindLayerWithContent(name)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) InsertVulnerabilities(vulnerabilities []VulnerabilityWithAffected) error {
|
||||
if ms.FctInsertVulnerabilities != nil {
|
||||
return ms.FctInsertVulnerabilities(vulnerabilities)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindVulnerabilities(vulnerabilityIDs []VulnerabilityID) ([]NullableVulnerability, error) {
|
||||
if ms.FctFindVulnerabilities != nil {
|
||||
return ms.FctFindVulnerabilities(vulnerabilityIDs)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) DeleteVulnerabilities(VulnerabilityIDs []VulnerabilityID) error {
|
||||
if ms.FctDeleteVulnerabilities != nil {
|
||||
return ms.FctDeleteVulnerabilities(VulnerabilityIDs)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) InsertVulnerabilityNotifications(vulnerabilityNotifications []VulnerabilityNotification) error {
|
||||
if ms.FctInsertVulnerabilityNotifications != nil {
|
||||
return ms.FctInsertVulnerabilityNotifications(vulnerabilityNotifications)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindNewNotification(lastNotified time.Time) (NotificationHook, bool, error) {
|
||||
if ms.FctFindNewNotification != nil {
|
||||
return ms.FctFindNewNotification(lastNotified)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindVulnerabilityNotification(name string, limit int, oldPage PageNumber, newPage PageNumber) (
|
||||
VulnerabilityNotificationWithVulnerable, bool, error) {
|
||||
if ms.FctFindVulnerabilityNotification != nil {
|
||||
return ms.FctFindVulnerabilityNotification(name, limit, oldPage, newPage)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) MarkNotificationNotified(name string) error {
|
||||
if ms.FctMarkNotificationNotified != nil {
|
||||
return ms.FctMarkNotificationNotified(name)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) DeleteNotification(name string) error {
|
||||
if ms.FctDeleteNotification != nil {
|
||||
return ms.FctDeleteNotification(name)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) UpdateKeyValue(key, value string) error {
|
||||
if ms.FctUpdateKeyValue != nil {
|
||||
return ms.FctUpdateKeyValue(key, value)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindKeyValue(key string) (string, bool, error) {
|
||||
if ms.FctFindKeyValue != nil {
|
||||
return ms.FctFindKeyValue(key)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) Lock(name string, owner string, duration time.Duration, renew bool) (bool, time.Time, error) {
|
||||
if ms.FctLock != nil {
|
||||
return ms.FctLock(name, owner, duration, renew)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) Unlock(name, owner string) error {
|
||||
if ms.FctUnlock != nil {
|
||||
return ms.FctUnlock(name, owner)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) FindLock(name string) (string, time.Time, bool, error) {
|
||||
if ms.FctFindLock != nil {
|
||||
return ms.FctFindLock(name)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
// MockDatastore implements Datastore and enables overriding each available method.
|
||||
// The default behavior of each method is to simply panic.
|
||||
type MockDatastore struct {
|
||||
FctBegin func() (Session, error)
|
||||
FctPing func() bool
|
||||
FctClose func()
|
||||
}
|
||||
|
||||
func (mds *MockDatastore) Begin() (Session, error) {
|
||||
if mds.FctBegin != nil {
|
||||
return mds.FctBegin()
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (mds *MockDatastore) Ping() bool {
|
||||
if mds.FctPing != nil {
|
||||
return mds.FctPing()
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (mds *MockDatastore) Close() {
|
||||
if mds.FctClose != nil {
|
||||
mds.FctClose()
|
||||
return
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
235
vendor/github.com/coreos/clair/database/models.go
generated
vendored
Normal file
235
vendor/github.com/coreos/clair/database/models.go
generated
vendored
Normal file
|
@ -0,0 +1,235 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Processors are extentions to scan layer's content.
|
||||
type Processors struct {
|
||||
Listers []string
|
||||
Detectors []string
|
||||
}
|
||||
|
||||
// Ancestry is a manifest that keeps all layers in an image in order.
|
||||
type Ancestry struct {
|
||||
Name string
|
||||
// Layers should be ordered and i_th layer is the parent of i+1_th layer in
|
||||
// the slice.
|
||||
Layers []Layer
|
||||
}
|
||||
|
||||
// AncestryWithFeatures is an ancestry with namespaced features detected in the
|
||||
// ancestry, which is processed by `ProcessedBy`.
|
||||
type AncestryWithFeatures struct {
|
||||
Ancestry
|
||||
|
||||
ProcessedBy Processors
|
||||
Features []NamespacedFeature
|
||||
}
|
||||
|
||||
// Layer corresponds to a layer in an image processed by `ProcessedBy`.
|
||||
type Layer struct {
|
||||
// Hash is content hash of the layer.
|
||||
Hash string
|
||||
}
|
||||
|
||||
// LayerWithContent is a layer with its detected namespaces and features by
|
||||
// ProcessedBy.
|
||||
type LayerWithContent struct {
|
||||
Layer
|
||||
|
||||
ProcessedBy Processors
|
||||
Namespaces []Namespace
|
||||
Features []Feature
|
||||
}
|
||||
|
||||
// Namespace is the contextual information around features.
|
||||
//
|
||||
// e.g. Debian:7, NodeJS.
|
||||
type Namespace struct {
|
||||
Name string
|
||||
VersionFormat string
|
||||
}
|
||||
|
||||
// Feature represents a package detected in a layer but the namespace is not
|
||||
// determined.
|
||||
//
|
||||
// e.g. Name: OpenSSL, Version: 1.0, VersionFormat: dpkg.
|
||||
// dpkg is the version format of the installer package manager, which in this
|
||||
// case could be dpkg or apk.
|
||||
type Feature struct {
|
||||
Name string
|
||||
Version string
|
||||
VersionFormat string
|
||||
}
|
||||
|
||||
// NamespacedFeature is a feature with determined namespace and can be affected
|
||||
// by vulnerabilities.
|
||||
//
|
||||
// e.g. OpenSSL 1.0 dpkg Debian:7.
|
||||
type NamespacedFeature struct {
|
||||
Feature
|
||||
|
||||
Namespace Namespace
|
||||
}
|
||||
|
||||
// AffectedNamespacedFeature is a namespaced feature affected by the
|
||||
// vulnerabilities with fixed-in versions for this feature.
|
||||
type AffectedNamespacedFeature struct {
|
||||
NamespacedFeature
|
||||
|
||||
AffectedBy []VulnerabilityWithFixedIn
|
||||
}
|
||||
|
||||
// VulnerabilityWithFixedIn is used for AffectedNamespacedFeature to retrieve
|
||||
// the affecting vulnerabilities and the fixed-in versions for the feature.
|
||||
type VulnerabilityWithFixedIn struct {
|
||||
Vulnerability
|
||||
|
||||
FixedInVersion string
|
||||
}
|
||||
|
||||
// AffectedFeature is used to determine whether a namespaced feature is affected
|
||||
// by a Vulnerability. Namespace and Feature Name is unique. Affected Feature is
|
||||
// bound to vulnerability.
|
||||
type AffectedFeature struct {
|
||||
Namespace Namespace
|
||||
FeatureName string
|
||||
// FixedInVersion is known next feature version that's not affected by the
|
||||
// vulnerability. Empty FixedInVersion means the unaffected version is
|
||||
// unknown.
|
||||
FixedInVersion string
|
||||
// AffectedVersion contains the version range to determine whether or not a
|
||||
// feature is affected.
|
||||
AffectedVersion string
|
||||
}
|
||||
|
||||
// VulnerabilityID is an identifier for every vulnerability. Every vulnerability
|
||||
// has unique namespace and name.
|
||||
type VulnerabilityID struct {
|
||||
Name string
|
||||
Namespace string
|
||||
}
|
||||
|
||||
// Vulnerability represents CVE or similar vulnerability reports.
|
||||
type Vulnerability struct {
|
||||
Name string
|
||||
Namespace Namespace
|
||||
|
||||
Description string
|
||||
Link string
|
||||
Severity Severity
|
||||
|
||||
Metadata MetadataMap
|
||||
}
|
||||
|
||||
// VulnerabilityWithAffected is an vulnerability with all known affected
|
||||
// features.
|
||||
type VulnerabilityWithAffected struct {
|
||||
Vulnerability
|
||||
|
||||
Affected []AffectedFeature
|
||||
}
|
||||
|
||||
// PagedVulnerableAncestries is a vulnerability with a page of affected
|
||||
// ancestries each with a special index attached for streaming purpose. The
|
||||
// current page number and next page number are for navigate.
|
||||
type PagedVulnerableAncestries struct {
|
||||
Vulnerability
|
||||
|
||||
// Affected is a map of special indexes to Ancestries, which the pair
|
||||
// should be unique in a stream. Every indexes in the map should be larger
|
||||
// than previous page.
|
||||
Affected map[int]string
|
||||
|
||||
Limit int
|
||||
Current PageNumber
|
||||
Next PageNumber
|
||||
|
||||
// End signals the end of the pages.
|
||||
End bool
|
||||
}
|
||||
|
||||
// NotificationHook is a message sent to another service to inform of a change
|
||||
// to a Vulnerability or the Ancestries affected by a Vulnerability. It contains
|
||||
// the name of a notification that should be read and marked as read via the
|
||||
// API.
|
||||
type NotificationHook struct {
|
||||
Name string
|
||||
|
||||
Created time.Time
|
||||
Notified time.Time
|
||||
Deleted time.Time
|
||||
}
|
||||
|
||||
// VulnerabilityNotification is a notification for vulnerability changes.
|
||||
type VulnerabilityNotification struct {
|
||||
NotificationHook
|
||||
|
||||
Old *Vulnerability
|
||||
New *Vulnerability
|
||||
}
|
||||
|
||||
// VulnerabilityNotificationWithVulnerable is a notification for vulnerability
|
||||
// changes with vulnerable ancestries.
|
||||
type VulnerabilityNotificationWithVulnerable struct {
|
||||
NotificationHook
|
||||
|
||||
Old *PagedVulnerableAncestries
|
||||
New *PagedVulnerableAncestries
|
||||
}
|
||||
|
||||
// PageNumber is used to do pagination.
|
||||
type PageNumber string
|
||||
|
||||
type MetadataMap map[string]interface{}
|
||||
|
||||
// NullableAffectedNamespacedFeature is an affectednamespacedfeature with
|
||||
// whether it's found in datastore.
|
||||
type NullableAffectedNamespacedFeature struct {
|
||||
AffectedNamespacedFeature
|
||||
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// NullableVulnerability is a vulnerability with whether the vulnerability is
|
||||
// found in datastore.
|
||||
type NullableVulnerability struct {
|
||||
VulnerabilityWithAffected
|
||||
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (mm *MetadataMap) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// github.com/lib/pq decodes TEXT/VARCHAR fields into strings.
|
||||
val, ok := value.(string)
|
||||
if !ok {
|
||||
panic("got type other than []byte from database")
|
||||
}
|
||||
return json.Unmarshal([]byte(val), mm)
|
||||
}
|
||||
|
||||
func (mm *MetadataMap) Value() (driver.Value, error) {
|
||||
json, err := json.Marshal(*mm)
|
||||
return string(json), err
|
||||
}
|
49
vendor/github.com/coreos/clair/database/namespace_mapping.go
generated
vendored
Normal file
49
vendor/github.com/coreos/clair/database/namespace_mapping.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2015 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package database
|
||||
|
||||
// DebianReleasesMapping translates Debian code names and class names to version numbers
|
||||
var DebianReleasesMapping = map[string]string{
|
||||
// Code names
|
||||
"squeeze": "6",
|
||||
"wheezy": "7",
|
||||
"jessie": "8",
|
||||
"stretch": "9",
|
||||
"buster": "10",
|
||||
"sid": "unstable",
|
||||
|
||||
// Class names
|
||||
"oldoldstable": "7",
|
||||
"oldstable": "8",
|
||||
"stable": "9",
|
||||
"testing": "10",
|
||||
"unstable": "unstable",
|
||||
}
|
||||
|
||||
// UbuntuReleasesMapping translates Ubuntu code names to version numbers
|
||||
var UbuntuReleasesMapping = map[string]string{
|
||||
"precise": "12.04",
|
||||
"quantal": "12.10",
|
||||
"raring": "13.04",
|
||||
"trusty": "14.04",
|
||||
"utopic": "14.10",
|
||||
"vivid": "15.04",
|
||||
"wily": "15.10",
|
||||
"xenial": "16.04",
|
||||
"yakkety": "16.10",
|
||||
"zesty": "17.04",
|
||||
"artful": "17.10",
|
||||
"bionic": "18.04",
|
||||
}
|
144
vendor/github.com/coreos/clair/database/severity.go
generated
vendored
Normal file
144
vendor/github.com/coreos/clair/database/severity.go
generated
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ErrFailedToParseSeverity is the error returned when a severity could not
|
||||
// be parsed from a string.
|
||||
var ErrFailedToParseSeverity = errors.New("failed to parse Severity from input")
|
||||
|
||||
// Severity defines a standard scale for measuring the severity of a
|
||||
// vulnerability.
|
||||
type Severity string
|
||||
|
||||
const (
|
||||
// UnknownSeverity is either a security problem that has not been assigned to
|
||||
// a priority yet or a priority that our system did not recognize.
|
||||
UnknownSeverity Severity = "Unknown"
|
||||
|
||||
// NegligibleSeverity is technically a security problem, but is only
|
||||
// theoretical in nature, requires a very special situation, has almost no
|
||||
// install base, or does no real damage. These tend not to get backport from
|
||||
// upstream, and will likely not be included in security updates unless
|
||||
// there is an easy fix and some other issue causes an update.
|
||||
NegligibleSeverity Severity = "Negligible"
|
||||
|
||||
// LowSeverity is a security problem, but is hard to exploit due to
|
||||
// environment, requires a user-assisted attack, a small install base, or
|
||||
// does very little damage. These tend to be included in security updates
|
||||
// only when higher priority issues require an update, or if many low
|
||||
// priority issues have built up.
|
||||
LowSeverity Severity = "Low"
|
||||
|
||||
// MediumSeverity is a real security problem, and is exploitable for many
|
||||
// people. Includes network daemon denial of service attacks, cross-site
|
||||
// scripting, and gaining user privileges. Updates should be made soon for
|
||||
// this priority of issue.
|
||||
MediumSeverity Severity = "Medium"
|
||||
|
||||
// HighSeverity is a real problem, exploitable for many people in a default
|
||||
// installation. Includes serious remote denial of services, local root
|
||||
// privilege escalations, or data loss.
|
||||
HighSeverity Severity = "High"
|
||||
|
||||
// CriticalSeverity is a world-burning problem, exploitable for nearly all
|
||||
// people in a default installation of Linux. Includes remote root privilege
|
||||
// escalations, or massive data loss.
|
||||
CriticalSeverity Severity = "Critical"
|
||||
|
||||
// Defcon1Severity is a Critical problem which has been manually highlighted
|
||||
// by the team. It requires an immediate attention.
|
||||
Defcon1Severity Severity = "Defcon1"
|
||||
)
|
||||
|
||||
// Severities lists all known severities, ordered from lowest to highest.
|
||||
var Severities = []Severity{
|
||||
UnknownSeverity,
|
||||
NegligibleSeverity,
|
||||
LowSeverity,
|
||||
MediumSeverity,
|
||||
HighSeverity,
|
||||
CriticalSeverity,
|
||||
Defcon1Severity,
|
||||
}
|
||||
|
||||
// NewSeverity attempts to parse a string into a standard Severity value.
|
||||
func NewSeverity(s string) (Severity, error) {
|
||||
for _, ss := range Severities {
|
||||
if strings.EqualFold(s, string(ss)) {
|
||||
return ss, nil
|
||||
}
|
||||
}
|
||||
|
||||
return UnknownSeverity, ErrFailedToParseSeverity
|
||||
}
|
||||
|
||||
// Compare determines the equality of two severities.
|
||||
//
|
||||
// If the severities are equal, returns 0.
|
||||
// If the receiver is less, returns -1.
|
||||
// If the receiver is greater, returns 1.
|
||||
func (s Severity) Compare(s2 Severity) int {
|
||||
var i1, i2 int
|
||||
|
||||
for i1 = 0; i1 < len(Severities); i1 = i1 + 1 {
|
||||
if s == Severities[i1] {
|
||||
break
|
||||
}
|
||||
}
|
||||
for i2 = 0; i2 < len(Severities); i2 = i2 + 1 {
|
||||
if s2 == Severities[i2] {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return i1 - i2
|
||||
}
|
||||
|
||||
// Scan implements the database/sql.Scanner interface.
|
||||
func (s *Severity) Scan(value interface{}) error {
|
||||
val, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New("could not scan a Severity from a non-string input")
|
||||
}
|
||||
|
||||
var err error
|
||||
*s, err = NewSeverity(string(val))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the database/sql/driver.Valuer interface.
|
||||
func (s Severity) Value() (driver.Value, error) {
|
||||
return string(s), nil
|
||||
}
|
||||
|
||||
// Valid checks if the severity is valid or not.
|
||||
func (s Severity) Valid() bool {
|
||||
for _, v := range Severities {
|
||||
if s == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
35
vendor/github.com/coreos/clair/database/severity_test.go
generated
vendored
Normal file
35
vendor/github.com/coreos/clair/database/severity_test.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCompareSeverity(t *testing.T) {
|
||||
assert.Equal(t, MediumSeverity.Compare(MediumSeverity), 0, "Severity comparison failed")
|
||||
assert.True(t, MediumSeverity.Compare(HighSeverity) < 0, "Severity comparison failed")
|
||||
assert.True(t, CriticalSeverity.Compare(LowSeverity) > 0, "Severity comparison failed")
|
||||
}
|
||||
|
||||
func TestParseSeverity(t *testing.T) {
|
||||
_, err := NewSeverity("Test")
|
||||
assert.Equal(t, ErrFailedToParseSeverity, err)
|
||||
|
||||
_, err = NewSeverity("Unknown")
|
||||
assert.Nil(t, err)
|
||||
}
|
151
vendor/github.com/coreos/clair/ext/versionfmt/driver.go
generated
vendored
Normal file
151
vendor/github.com/coreos/clair/ext/versionfmt/driver.go
generated
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
// Copyright 2016 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package versionfmt exposes functions to dynamically register formats used to
|
||||
// parse Feature Versions.
|
||||
package versionfmt
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
// MinVersion is a special package version which is always sorted first.
|
||||
MinVersion = "#MINV#"
|
||||
|
||||
// MaxVersion is a special package version which is always sorted last.
|
||||
MaxVersion = "#MAXV#"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnknownVersionFormat is returned when a function does not have enough
|
||||
// context to determine the format of a version.
|
||||
ErrUnknownVersionFormat = errors.New("unknown version format")
|
||||
|
||||
// ErrInvalidVersion is returned when a function needs to validate a version,
|
||||
// but should return an error in the case where the version is invalid.
|
||||
ErrInvalidVersion = errors.New("invalid version")
|
||||
|
||||
parsersM sync.Mutex
|
||||
parsers = make(map[string]Parser)
|
||||
)
|
||||
|
||||
// Parser represents any format that can compare two version strings.
|
||||
type Parser interface {
|
||||
// Valid attempts to parse a version string and returns its success.
|
||||
Valid(string) bool
|
||||
|
||||
// Compare parses two different version strings.
|
||||
// Returns 0 when equal, -1 when a < b, 1 when b < a.
|
||||
Compare(a, b string) (int, error)
|
||||
|
||||
// InRange computes if a is in range of b
|
||||
//
|
||||
// NOTE(Sida): For legacy version formats, rangeB is a version and
|
||||
// always use if versionA < rangeB as threshold.
|
||||
InRange(versionA, rangeB string) (bool, error)
|
||||
|
||||
// GetFixedIn computes a fixed in version for a certain version range.
|
||||
//
|
||||
// NOTE(Sida): For legacy version formats, rangeA is a version and
|
||||
// be returned directly becuase it was considered fixed in version.
|
||||
GetFixedIn(rangeA string) (string, error)
|
||||
}
|
||||
|
||||
// RegisterParser provides a way to dynamically register an implementation of a
|
||||
// Parser.
|
||||
//
|
||||
// If RegisterParser is called twice with the same name, the name is blank, or
|
||||
// if the provided Parser is nil, this function panics.
|
||||
func RegisterParser(name string, p Parser) {
|
||||
if name == "" {
|
||||
panic("versionfmt: could not register a Parser with an empty name")
|
||||
}
|
||||
|
||||
if p == nil {
|
||||
panic("versionfmt: could not register a nil Parser")
|
||||
}
|
||||
|
||||
parsersM.Lock()
|
||||
defer parsersM.Unlock()
|
||||
|
||||
if _, dup := parsers[name]; dup {
|
||||
panic("versionfmt: RegisterParser called twice for " + name)
|
||||
}
|
||||
|
||||
parsers[name] = p
|
||||
}
|
||||
|
||||
// GetParser returns the registered Parser with a provided name.
|
||||
func GetParser(name string) (p Parser, exists bool) {
|
||||
parsersM.Lock()
|
||||
defer parsersM.Unlock()
|
||||
|
||||
p, exists = parsers[name]
|
||||
return
|
||||
}
|
||||
|
||||
// Valid is a helper function that will return an error if the version fails to
|
||||
// validate with a given format.
|
||||
func Valid(format, version string) error {
|
||||
versionParser, exists := GetParser(format)
|
||||
if !exists {
|
||||
return ErrUnknownVersionFormat
|
||||
}
|
||||
|
||||
if !versionParser.Valid(version) {
|
||||
return ErrInvalidVersion
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compare is a helper function that will compare two versions with a given
|
||||
// format and return an error if there are any failures.
|
||||
func Compare(format, versionA, versionB string) (int, error) {
|
||||
versionParser, exists := GetParser(format)
|
||||
if !exists {
|
||||
return 0, ErrUnknownVersionFormat
|
||||
}
|
||||
|
||||
return versionParser.Compare(versionA, versionB)
|
||||
}
|
||||
|
||||
// InRange is a helper function that checks if `versionA` is in `rangeB`
|
||||
func InRange(format, version, versionRange string) (bool, error) {
|
||||
versionParser, exists := GetParser(format)
|
||||
if !exists {
|
||||
return false, ErrUnknownVersionFormat
|
||||
}
|
||||
|
||||
in, err := versionParser.InRange(version, versionRange)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"Format": format, "Version": version, "Range": versionRange}).Error(err)
|
||||
}
|
||||
return in, err
|
||||
}
|
||||
|
||||
// GetFixedIn is a helper function that computes the next fixed in version given
|
||||
// a affected version range `rangeA`.
|
||||
func GetFixedIn(format, rangeA string) (string, error) {
|
||||
versionParser, exists := GetParser(format)
|
||||
if !exists {
|
||||
return "", ErrUnknownVersionFormat
|
||||
}
|
||||
|
||||
return versionParser.GetFixedIn(rangeA)
|
||||
}
|
133
vendor/github.com/coreos/clair/glide.lock
generated
vendored
Normal file
133
vendor/github.com/coreos/clair/glide.lock
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
hash: b5b9ebebad30becd361736196a015af23b1d9a616a375c7fc13823121fd17226
|
||||
updated: 2017-06-05T16:11:29.019891941-04:00
|
||||
imports:
|
||||
- name: github.com/beorn7/perks
|
||||
version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
|
||||
subpackages:
|
||||
- quantile
|
||||
- name: github.com/cockroachdb/cmux
|
||||
version: 30d10be492927e2dcae0089c374c455d42414fcb
|
||||
- name: github.com/coreos/pkg
|
||||
version: 3ac0863d7acf3bc44daf49afef8919af12f704ef
|
||||
subpackages:
|
||||
- timeutil
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/fernet/fernet-go
|
||||
version: 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
|
||||
- name: github.com/golang/protobuf
|
||||
version: 5a0f697c9ed9d68fef0116532c6e05cfeae00e55
|
||||
subpackages:
|
||||
- jsonpb
|
||||
- proto
|
||||
- protoc-gen-go/descriptor
|
||||
- ptypes/any
|
||||
- ptypes/empty
|
||||
- ptypes/struct
|
||||
- name: github.com/grpc-ecosystem/go-grpc-prometheus
|
||||
version: 2500245aa6110c562d17020fb31a2c133d737799
|
||||
- name: github.com/grpc-ecosystem/grpc-gateway
|
||||
version: 2a40dd79571b760642c30f62ada35c65ac2b779c
|
||||
subpackages:
|
||||
- runtime
|
||||
- runtime/internal
|
||||
- utilities
|
||||
- name: github.com/guregu/null
|
||||
version: 41961cea0328defc5f95c1c473f89ebf0d1813f6
|
||||
subpackages:
|
||||
- zero
|
||||
- name: github.com/hashicorp/golang-lru
|
||||
version: 0a025b7e63adc15a622f29b0b2c4c3848243bbf6
|
||||
subpackages:
|
||||
- simplelru
|
||||
- name: github.com/julienschmidt/httprouter
|
||||
version: 8c199fb6259ffc1af525cc3ad52ee60ba8359669
|
||||
- name: github.com/lib/pq
|
||||
version: 8837942c3e09574accbc5f150e2c5e057189cace
|
||||
subpackages:
|
||||
- oid
|
||||
- name: github.com/matttproud/golang_protobuf_extensions
|
||||
version: c12348ce28de40eed0136aa2b644d0ee0650e56c
|
||||
subpackages:
|
||||
- pbutil
|
||||
- name: github.com/pborman/uuid
|
||||
version: a97ce2ca70fa5a848076093f05e639a89ca34d06
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
- difflib
|
||||
- name: github.com/prometheus/client_golang
|
||||
version: c5b7fccd204277076155f10851dad72b76a49317
|
||||
subpackages:
|
||||
- prometheus
|
||||
- name: github.com/prometheus/client_model
|
||||
version: 6f3806018612930941127f2a7c6c453ba2c527d2
|
||||
subpackages:
|
||||
- go
|
||||
- name: github.com/prometheus/common
|
||||
version: 13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207
|
||||
subpackages:
|
||||
- expfmt
|
||||
- internal/bitbucket.org/ww/goautoneg
|
||||
- model
|
||||
- name: github.com/prometheus/procfs
|
||||
version: 65c1f6f8f0fc1e2185eb9863a3bc751496404259
|
||||
subpackages:
|
||||
- xfs
|
||||
- name: github.com/remind101/migrate
|
||||
version: d22d647232c20dbea6d2aa1dda7f2737cccce614
|
||||
- name: github.com/sirupsen/logrus
|
||||
version: ba1b36c82c5e05c4f912a88eab0dcd91a171688f
|
||||
- name: github.com/stretchr/testify
|
||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||
subpackages:
|
||||
- assert
|
||||
- name: github.com/tylerb/graceful
|
||||
version: 4654dfbb6ad53cb5e27f37d99b02e16c1872fbbb
|
||||
- name: golang.org/x/net
|
||||
version: 59a0b19b5533c7977ddeb86b017bf507ed407b12
|
||||
subpackages:
|
||||
- context
|
||||
- http2
|
||||
- http2/hpack
|
||||
- idna
|
||||
- internal/timeseries
|
||||
- lex/httplex
|
||||
- trace
|
||||
- name: golang.org/x/sys
|
||||
version: b90f89a1e7a9c1f6b918820b3daa7f08488c8594
|
||||
subpackages:
|
||||
- unix
|
||||
- name: golang.org/x/text
|
||||
version: ccbd3f7822129ff389f8ca4858a9b9d4d910531c
|
||||
subpackages:
|
||||
- secure/bidirule
|
||||
- transform
|
||||
- unicode/bidi
|
||||
- unicode/norm
|
||||
- name: google.golang.org/genproto
|
||||
version: aa2eb687b4d3e17154372564ad8d6bf11c3cf21f
|
||||
subpackages:
|
||||
- googleapis/api/annotations
|
||||
- googleapis/rpc/status
|
||||
- name: google.golang.org/grpc
|
||||
version: 8de2dff78c3b968a51c99ec526d934f686537437
|
||||
subpackages:
|
||||
- codes
|
||||
- credentials
|
||||
- grpclb/grpc_lb_v1
|
||||
- grpclog
|
||||
- internal
|
||||
- keepalive
|
||||
- metadata
|
||||
- naming
|
||||
- peer
|
||||
- stats
|
||||
- status
|
||||
- tap
|
||||
- transport
|
||||
- name: gopkg.in/yaml.v2
|
||||
version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b
|
||||
testImports: []
|
32
vendor/github.com/coreos/clair/glide.yaml
generated
vendored
Normal file
32
vendor/github.com/coreos/clair/glide.yaml
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
package: github.com/coreos/clair
|
||||
import:
|
||||
- package: github.com/coreos/pkg
|
||||
version: ^3.0.0
|
||||
subpackages:
|
||||
- timeutil
|
||||
- package: github.com/fernet/fernet-go
|
||||
- package: github.com/guregu/null
|
||||
version: ^3.1.0
|
||||
subpackages:
|
||||
- zero
|
||||
- package: github.com/hashicorp/golang-lru
|
||||
- package: github.com/julienschmidt/httprouter
|
||||
version: ^1.1.0
|
||||
- package: github.com/lib/pq
|
||||
- package: github.com/pborman/uuid
|
||||
version: ^1.0.0
|
||||
- package: github.com/prometheus/client_golang
|
||||
version: ^0.8.0
|
||||
subpackages:
|
||||
- prometheus
|
||||
- package: github.com/remind101/migrate
|
||||
- package: github.com/sirupsen/logrus
|
||||
version: ^0.11.5
|
||||
- package: github.com/stretchr/testify
|
||||
version: ^1.1.4
|
||||
subpackages:
|
||||
- assert
|
||||
- package: github.com/tylerb/graceful
|
||||
version: ^1.2.15
|
||||
- package: gopkg.in/yaml.v2
|
||||
- package: github.com/cockroachdb/cmux
|
251
vendor/github.com/coreos/clair/notifier.go
generated
vendored
Normal file
251
vendor/github.com/coreos/clair/notifier.go
generated
vendored
Normal file
|
@ -0,0 +1,251 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package clair
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/coreos/pkg/timeutil"
|
||||
"github.com/pborman/uuid"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/coreos/clair/database"
|
||||
"github.com/coreos/clair/ext/notification"
|
||||
"github.com/coreos/clair/pkg/stopper"
|
||||
)
|
||||
|
||||
const (
|
||||
notifierCheckInterval = 5 * time.Minute
|
||||
notifierMaxBackOff = 15 * time.Minute
|
||||
notifierLockRefreshDuration = time.Minute * 2
|
||||
notifierLockDuration = time.Minute*8 + notifierLockRefreshDuration
|
||||
|
||||
logSenderName = "sender name"
|
||||
logNotiName = "notification name"
|
||||
)
|
||||
|
||||
var (
|
||||
promNotifierLatencyMilliseconds = prometheus.NewHistogram(prometheus.HistogramOpts{
|
||||
Name: "clair_notifier_latency_milliseconds",
|
||||
Help: "Time it takes to send a notification after it's been created.",
|
||||
})
|
||||
|
||||
promNotifierBackendErrorsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "clair_notifier_backend_errors_total",
|
||||
Help: "Number of errors that notifier backends generated.",
|
||||
}, []string{"backend"})
|
||||
)
|
||||
|
||||
func init() {
|
||||
prometheus.MustRegister(promNotifierLatencyMilliseconds)
|
||||
prometheus.MustRegister(promNotifierBackendErrorsTotal)
|
||||
}
|
||||
|
||||
// RunNotifier begins a process that checks for new notifications that should
|
||||
// be sent out to third parties.
|
||||
func RunNotifier(config *notification.Config, datastore database.Datastore, stopper *stopper.Stopper) {
|
||||
defer stopper.End()
|
||||
|
||||
// Configure registered notifiers.
|
||||
for senderName, sender := range notification.Senders() {
|
||||
if configured, err := sender.Configure(config); configured {
|
||||
log.WithField(logSenderName, senderName).Info("sender configured")
|
||||
} else {
|
||||
notification.UnregisterSender(senderName)
|
||||
if err != nil {
|
||||
log.WithError(err).WithField(logSenderName, senderName).Error("could not configure notifier")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do not run the updater if there is no notifier enabled.
|
||||
if len(notification.Senders()) == 0 {
|
||||
log.Info("notifier service is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
whoAmI := uuid.New()
|
||||
log.WithField("lock identifier", whoAmI).Info("notifier service started")
|
||||
|
||||
for running := true; running; {
|
||||
// Find task.
|
||||
notification := findTask(datastore, config.RenotifyInterval, whoAmI, stopper)
|
||||
if notification == nil {
|
||||
// Interrupted while finding a task, Clair is stopping.
|
||||
break
|
||||
}
|
||||
|
||||
// Handle task.
|
||||
done := make(chan bool, 1)
|
||||
go func() {
|
||||
success, interrupted := handleTask(*notification, stopper, config.Attempts)
|
||||
if success {
|
||||
err := markNotificationNotified(datastore, notification.Name)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to mark notification notified")
|
||||
}
|
||||
promNotifierLatencyMilliseconds.Observe(float64(time.Since(notification.Created).Nanoseconds()) / float64(time.Millisecond))
|
||||
}
|
||||
if interrupted {
|
||||
running = false
|
||||
}
|
||||
unlock(datastore, notification.Name, whoAmI)
|
||||
done <- true
|
||||
}()
|
||||
|
||||
// Refresh task lock until done.
|
||||
outer:
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
break outer
|
||||
case <-time.After(notifierLockRefreshDuration):
|
||||
lock(datastore, notification.Name, whoAmI, notifierLockDuration, true)
|
||||
case <-stopper.Chan():
|
||||
running = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("notifier service stopped")
|
||||
}
|
||||
|
||||
func findTask(datastore database.Datastore, renotifyInterval time.Duration, whoAmI string, stopper *stopper.Stopper) *database.NotificationHook {
|
||||
for {
|
||||
notification, ok, err := findNewNotification(datastore, renotifyInterval)
|
||||
if err != nil || !ok {
|
||||
if !ok {
|
||||
log.WithError(err).Warning("could not get notification to send")
|
||||
}
|
||||
|
||||
// Wait.
|
||||
if !stopper.Sleep(notifierCheckInterval) {
|
||||
return nil
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// Lock the notification.
|
||||
if hasLock, _ := lock(datastore, notification.Name, whoAmI, notifierLockDuration, false); hasLock {
|
||||
log.WithField(logNotiName, notification.Name).Info("found and locked a notification")
|
||||
return ¬ification
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleTask(n database.NotificationHook, st *stopper.Stopper, maxAttempts int) (bool, bool) {
|
||||
// Send notification.
|
||||
for senderName, sender := range notification.Senders() {
|
||||
var attempts int
|
||||
var backOff time.Duration
|
||||
for {
|
||||
// Max attempts exceeded.
|
||||
if attempts >= maxAttempts {
|
||||
log.WithFields(log.Fields{logNotiName: n.Name, logSenderName: senderName, "max attempts": maxAttempts}).Info("giving up on sending notification : max attempts exceeded")
|
||||
return false, false
|
||||
}
|
||||
|
||||
// Backoff.
|
||||
if backOff > 0 {
|
||||
log.WithFields(log.Fields{"duration": backOff, logNotiName: n.Name, logSenderName: senderName, "attempts": attempts + 1, "max attempts": maxAttempts}).Info("waiting before retrying to send notification")
|
||||
if !st.Sleep(backOff) {
|
||||
return false, true
|
||||
}
|
||||
}
|
||||
|
||||
// Send using the current notifier.
|
||||
if err := sender.Send(n.Name); err != nil {
|
||||
// Send failed; increase attempts/backoff and retry.
|
||||
promNotifierBackendErrorsTotal.WithLabelValues(senderName).Inc()
|
||||
log.WithError(err).WithFields(log.Fields{logSenderName: senderName, logNotiName: n.Name}).Error("could not send notification via notifier")
|
||||
backOff = timeutil.ExpBackoff(backOff, notifierMaxBackOff)
|
||||
attempts++
|
||||
continue
|
||||
}
|
||||
|
||||
// Send has been successful. Go to the next notifier.
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
log.WithField(logNotiName, n.Name).Info("successfully sent notification")
|
||||
return true, false
|
||||
}
|
||||
|
||||
func findNewNotification(datastore database.Datastore, renotifyInterval time.Duration) (database.NotificationHook, bool, error) {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return database.NotificationHook{}, false, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return tx.FindNewNotification(time.Now().Add(-renotifyInterval))
|
||||
}
|
||||
|
||||
func markNotificationNotified(datastore database.Datastore, name string) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("an error happens when beginning database transaction")
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.MarkNotificationNotified(name); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// unlock removes a lock with provided name, owner. Internally, it handles
|
||||
// database transaction and catches error.
|
||||
func unlock(datastore database.Datastore, name, owner string) {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.Unlock(name, owner); err != nil {
|
||||
return
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func lock(datastore database.Datastore, name string, owner string, duration time.Duration, renew bool) (bool, time.Time) {
|
||||
// any error will cause the function to catch the error and return false.
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return false, time.Time{}
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
|
||||
locked, t, err := tx.Lock(name, owner, duration, renew)
|
||||
if err != nil {
|
||||
return false, time.Time{}
|
||||
}
|
||||
|
||||
if locked {
|
||||
if err := tx.Commit(); err != nil {
|
||||
return false, time.Time{}
|
||||
}
|
||||
}
|
||||
|
||||
return locked, t
|
||||
}
|
698
vendor/github.com/coreos/clair/updater.go
generated
vendored
Normal file
698
vendor/github.com/coreos/clair/updater.go
generated
vendored
Normal file
|
@ -0,0 +1,698 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package clair
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pborman/uuid"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/coreos/clair/database"
|
||||
"github.com/coreos/clair/ext/vulnmdsrc"
|
||||
"github.com/coreos/clair/ext/vulnsrc"
|
||||
"github.com/coreos/clair/pkg/stopper"
|
||||
)
|
||||
|
||||
const (
|
||||
updaterLastFlagName = "updater/last"
|
||||
updaterLockName = "updater"
|
||||
updaterLockDuration = updaterLockRefreshDuration + time.Minute*2
|
||||
updaterLockRefreshDuration = time.Minute * 8
|
||||
updaterSleepBetweenLoopsDuration = time.Minute
|
||||
)
|
||||
|
||||
var (
|
||||
promUpdaterErrorsTotal = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Name: "clair_updater_errors_total",
|
||||
Help: "Numbers of errors that the updater generated.",
|
||||
})
|
||||
|
||||
promUpdaterDurationSeconds = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "clair_updater_duration_seconds",
|
||||
Help: "Time it takes to update the vulnerability database.",
|
||||
})
|
||||
|
||||
promUpdaterNotesTotal = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "clair_updater_notes_total",
|
||||
Help: "Number of notes that the vulnerability fetchers generated.",
|
||||
})
|
||||
|
||||
// EnabledUpdaters contains all updaters to be used for update.
|
||||
EnabledUpdaters []string
|
||||
)
|
||||
|
||||
func init() {
|
||||
prometheus.MustRegister(promUpdaterErrorsTotal)
|
||||
prometheus.MustRegister(promUpdaterDurationSeconds)
|
||||
prometheus.MustRegister(promUpdaterNotesTotal)
|
||||
}
|
||||
|
||||
// UpdaterConfig is the configuration for the Updater service.
|
||||
type UpdaterConfig struct {
|
||||
EnabledUpdaters []string
|
||||
Interval time.Duration
|
||||
}
|
||||
|
||||
type vulnerabilityChange struct {
|
||||
old *database.VulnerabilityWithAffected
|
||||
new *database.VulnerabilityWithAffected
|
||||
}
|
||||
|
||||
// RunUpdater begins a process that updates the vulnerability database at
|
||||
// regular intervals.
|
||||
func RunUpdater(config *UpdaterConfig, datastore database.Datastore, st *stopper.Stopper) {
|
||||
defer st.End()
|
||||
|
||||
// Do not run the updater if there is no config or if the interval is 0.
|
||||
if config == nil || config.Interval == 0 || len(config.EnabledUpdaters) == 0 {
|
||||
log.Info("updater service is disabled.")
|
||||
return
|
||||
}
|
||||
|
||||
whoAmI := uuid.New()
|
||||
log.WithField("lock identifier", whoAmI).Info("updater service started")
|
||||
|
||||
for {
|
||||
var stop bool
|
||||
|
||||
// Determine if this is the first update and define the next update time.
|
||||
// The next update time is (last update time + interval) or now if this is the first update.
|
||||
nextUpdate := time.Now().UTC()
|
||||
lastUpdate, firstUpdate, err := GetLastUpdateTime(datastore)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("an error occurred while getting the last update time")
|
||||
nextUpdate = nextUpdate.Add(config.Interval)
|
||||
} else if !firstUpdate {
|
||||
nextUpdate = lastUpdate.Add(config.Interval)
|
||||
}
|
||||
|
||||
// If the next update timer is in the past, then try to update.
|
||||
if nextUpdate.Before(time.Now().UTC()) {
|
||||
// Attempt to get a lock on the the update.
|
||||
log.Debug("attempting to obtain update lock")
|
||||
hasLock, hasLockUntil := lock(datastore, updaterLockName, whoAmI, updaterLockDuration, false)
|
||||
if hasLock {
|
||||
// Launch update in a new go routine.
|
||||
doneC := make(chan bool, 1)
|
||||
go func() {
|
||||
update(datastore, firstUpdate)
|
||||
doneC <- true
|
||||
}()
|
||||
|
||||
for done := false; !done && !stop; {
|
||||
select {
|
||||
case <-doneC:
|
||||
done = true
|
||||
case <-time.After(updaterLockRefreshDuration):
|
||||
// Refresh the lock until the update is done.
|
||||
lock(datastore, updaterLockName, whoAmI, updaterLockDuration, true)
|
||||
case <-st.Chan():
|
||||
stop = true
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock the updater.
|
||||
unlock(datastore, updaterLockName, whoAmI)
|
||||
|
||||
if stop {
|
||||
break
|
||||
}
|
||||
|
||||
// Sleep for a short duration to prevent pinning the CPU on a
|
||||
// consistent failure.
|
||||
if stopped := sleepUpdater(time.Now().Add(updaterSleepBetweenLoopsDuration), st); stopped {
|
||||
break
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
lockOwner, lockExpiration, ok, err := findLock(datastore, updaterLockName)
|
||||
if !ok || err != nil {
|
||||
log.Debug("update lock is already taken")
|
||||
nextUpdate = hasLockUntil
|
||||
} else {
|
||||
log.WithFields(log.Fields{"lock owner": lockOwner, "lock expiration": lockExpiration}).Debug("update lock is already taken")
|
||||
nextUpdate = lockExpiration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if stopped := sleepUpdater(nextUpdate, st); stopped {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Clean resources.
|
||||
for _, appenders := range vulnmdsrc.Appenders() {
|
||||
appenders.Clean()
|
||||
}
|
||||
for _, updaters := range vulnsrc.Updaters() {
|
||||
updaters.Clean()
|
||||
}
|
||||
|
||||
log.Info("updater service stopped")
|
||||
}
|
||||
|
||||
// sleepUpdater sleeps the updater for an approximate duration, but remains
|
||||
// able to be cancelled by a stopper.
|
||||
func sleepUpdater(approxWakeup time.Time, st *stopper.Stopper) (stopped bool) {
|
||||
waitUntil := approxWakeup.Add(time.Duration(rand.ExpFloat64()/0.5) * time.Second)
|
||||
log.WithField("scheduled time", waitUntil).Debug("updater sleeping")
|
||||
if !waitUntil.Before(time.Now().UTC()) {
|
||||
if !st.Sleep(waitUntil.Sub(time.Now())) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// update fetches all the vulnerabilities from the registered fetchers, updates
|
||||
// vulnerabilities, and updater flags, and logs notes from updaters.
|
||||
func update(datastore database.Datastore, firstUpdate bool) {
|
||||
defer setUpdaterDuration(time.Now())
|
||||
|
||||
log.Info("updating vulnerabilities")
|
||||
|
||||
// Fetch updates.
|
||||
success, vulnerabilities, flags, notes := fetch(datastore)
|
||||
|
||||
// do vulnerability namespacing again to merge potentially duplicated
|
||||
// vulnerabilities from each updater.
|
||||
vulnerabilities = doVulnerabilitiesNamespacing(vulnerabilities)
|
||||
|
||||
// deduplicate fetched namespaces and store them into database.
|
||||
nsMap := map[database.Namespace]struct{}{}
|
||||
for _, vuln := range vulnerabilities {
|
||||
nsMap[vuln.Namespace] = struct{}{}
|
||||
}
|
||||
|
||||
namespaces := make([]database.Namespace, 0, len(nsMap))
|
||||
for ns := range nsMap {
|
||||
namespaces = append(namespaces, ns)
|
||||
}
|
||||
|
||||
if err := persistNamespaces(datastore, namespaces); err != nil {
|
||||
log.WithError(err).Error("Unable to insert namespaces")
|
||||
return
|
||||
}
|
||||
|
||||
changes, err := updateVulnerabilities(datastore, vulnerabilities)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
promUpdaterErrorsTotal.Inc()
|
||||
}
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Unable to update vulnerabilities")
|
||||
return
|
||||
}
|
||||
|
||||
if !firstUpdate {
|
||||
err = createVulnerabilityNotifications(datastore, changes)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Unable to create notifications")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = updateUpdaterFlags(datastore, flags)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Unable to update updater flags")
|
||||
return
|
||||
}
|
||||
|
||||
for _, note := range notes {
|
||||
log.WithField("note", note).Warning("fetcher note")
|
||||
}
|
||||
promUpdaterNotesTotal.Set(float64(len(notes)))
|
||||
|
||||
if success {
|
||||
err = setLastUpdateTime(datastore)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Unable to set last update time")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("update finished")
|
||||
}
|
||||
|
||||
func setUpdaterDuration(start time.Time) {
|
||||
promUpdaterDurationSeconds.Set(time.Since(start).Seconds())
|
||||
}
|
||||
|
||||
// fetch get data from the registered fetchers, in parallel.
|
||||
func fetch(datastore database.Datastore) (bool, []database.VulnerabilityWithAffected, map[string]string, []string) {
|
||||
var vulnerabilities []database.VulnerabilityWithAffected
|
||||
var notes []string
|
||||
status := true
|
||||
flags := make(map[string]string)
|
||||
|
||||
// Fetch updates in parallel.
|
||||
log.Info("fetching vulnerability updates")
|
||||
var responseC = make(chan *vulnsrc.UpdateResponse, 0)
|
||||
numUpdaters := 0
|
||||
for n, u := range vulnsrc.Updaters() {
|
||||
if !updaterEnabled(n) {
|
||||
continue
|
||||
}
|
||||
numUpdaters++
|
||||
go func(name string, u vulnsrc.Updater) {
|
||||
response, err := u.Update(datastore)
|
||||
if err != nil {
|
||||
promUpdaterErrorsTotal.Inc()
|
||||
log.WithError(err).WithField("updater name", name).Error("an error occurred when fetching update")
|
||||
status = false
|
||||
responseC <- nil
|
||||
return
|
||||
}
|
||||
|
||||
responseC <- &response
|
||||
log.WithField("updater name", name).Info("finished fetching")
|
||||
}(n, u)
|
||||
}
|
||||
|
||||
// Collect results of updates.
|
||||
for i := 0; i < numUpdaters; i++ {
|
||||
resp := <-responseC
|
||||
if resp != nil {
|
||||
vulnerabilities = append(vulnerabilities, doVulnerabilitiesNamespacing(resp.Vulnerabilities)...)
|
||||
notes = append(notes, resp.Notes...)
|
||||
if resp.FlagName != "" && resp.FlagValue != "" {
|
||||
flags[resp.FlagName] = resp.FlagValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(responseC)
|
||||
return status, addMetadata(datastore, vulnerabilities), flags, notes
|
||||
}
|
||||
|
||||
// Add metadata to the specified vulnerabilities using the registered
|
||||
// MetadataFetchers, in parallel.
|
||||
func addMetadata(datastore database.Datastore, vulnerabilities []database.VulnerabilityWithAffected) []database.VulnerabilityWithAffected {
|
||||
if len(vulnmdsrc.Appenders()) == 0 || len(vulnerabilities) == 0 {
|
||||
return vulnerabilities
|
||||
}
|
||||
|
||||
log.Info("adding metadata to vulnerabilities")
|
||||
|
||||
// Add a mutex to each vulnerability to ensure that only one appender at a
|
||||
// time can modify the vulnerability's Metadata map.
|
||||
lockableVulnerabilities := make([]*lockableVulnerability, 0, len(vulnerabilities))
|
||||
for i := 0; i < len(vulnerabilities); i++ {
|
||||
lockableVulnerabilities = append(lockableVulnerabilities, &lockableVulnerability{
|
||||
VulnerabilityWithAffected: &vulnerabilities[i],
|
||||
})
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(vulnmdsrc.Appenders()))
|
||||
|
||||
for n, a := range vulnmdsrc.Appenders() {
|
||||
go func(name string, appender vulnmdsrc.Appender) {
|
||||
defer wg.Done()
|
||||
|
||||
// Build up a metadata cache.
|
||||
if err := appender.BuildCache(datastore); err != nil {
|
||||
promUpdaterErrorsTotal.Inc()
|
||||
log.WithError(err).WithField("appender name", name).Error("an error occurred when loading metadata fetcher")
|
||||
return
|
||||
}
|
||||
|
||||
// Append vulnerability metadata to each vulnerability.
|
||||
for _, vulnerability := range lockableVulnerabilities {
|
||||
appender.Append(vulnerability.Name, vulnerability.appendFunc)
|
||||
}
|
||||
|
||||
// Purge the metadata cache.
|
||||
appender.PurgeCache()
|
||||
}(n, a)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return vulnerabilities
|
||||
}
|
||||
|
||||
// GetLastUpdateTime retrieves the latest successful time of update and whether
|
||||
// or not it's the first update.
|
||||
func GetLastUpdateTime(datastore database.Datastore) (time.Time, bool, error) {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return time.Time{}, false, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
lastUpdateTSS, ok, err := tx.FindKeyValue(updaterLastFlagName)
|
||||
if err != nil {
|
||||
return time.Time{}, false, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
// This is the first update.
|
||||
return time.Time{}, true, nil
|
||||
}
|
||||
|
||||
lastUpdateTS, err := strconv.ParseInt(lastUpdateTSS, 10, 64)
|
||||
if err != nil {
|
||||
return time.Time{}, false, err
|
||||
}
|
||||
|
||||
return time.Unix(lastUpdateTS, 0).UTC(), false, nil
|
||||
}
|
||||
|
||||
type lockableVulnerability struct {
|
||||
*database.VulnerabilityWithAffected
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (lv *lockableVulnerability) appendFunc(metadataKey string, metadata interface{}, severity database.Severity) {
|
||||
lv.Lock()
|
||||
defer lv.Unlock()
|
||||
|
||||
// If necessary, initialize the metadata map for the vulnerability.
|
||||
if lv.Metadata == nil {
|
||||
lv.Metadata = make(map[string]interface{})
|
||||
}
|
||||
|
||||
// Append the metadata.
|
||||
lv.Metadata[metadataKey] = metadata
|
||||
|
||||
// If necessary, provide a severity for the vulnerability.
|
||||
if lv.Severity == database.UnknownSeverity {
|
||||
lv.Severity = severity
|
||||
}
|
||||
}
|
||||
|
||||
// doVulnerabilitiesNamespacing takes Vulnerabilities that don't have a
|
||||
// Namespace and split them into multiple vulnerabilities that have a Namespace
|
||||
// and only contains the Affected Features corresponding to their
|
||||
// Namespace.
|
||||
//
|
||||
// It helps simplifying the fetchers that share the same metadata about a
|
||||
// Vulnerability regardless of their actual namespace (ie. same vulnerability
|
||||
// information for every version of a distro).
|
||||
//
|
||||
// It also validates the vulnerabilities fetched from updaters. If any
|
||||
// vulnerability is mal-formated, the updater process will continue but will log
|
||||
// warning.
|
||||
func doVulnerabilitiesNamespacing(vulnerabilities []database.VulnerabilityWithAffected) []database.VulnerabilityWithAffected {
|
||||
vulnerabilitiesMap := make(map[string]*database.VulnerabilityWithAffected)
|
||||
|
||||
for _, v := range vulnerabilities {
|
||||
namespacedFeatures := v.Affected
|
||||
v.Affected = []database.AffectedFeature{}
|
||||
|
||||
for _, fv := range namespacedFeatures {
|
||||
// validate vulnerabilities, throw out the invalid vulnerabilities
|
||||
if fv.AffectedVersion == "" || fv.FeatureName == "" || fv.Namespace.Name == "" || fv.Namespace.VersionFormat == "" {
|
||||
log.WithFields(log.Fields{
|
||||
"Name": fv.FeatureName,
|
||||
"Affected Version": fv.AffectedVersion,
|
||||
"Namespace": fv.Namespace.Name + ":" + fv.Namespace.VersionFormat,
|
||||
}).Warn("Mal-formated affected feature (skipped)")
|
||||
continue
|
||||
}
|
||||
index := fv.Namespace.Name + ":" + v.Name
|
||||
|
||||
if vulnerability, ok := vulnerabilitiesMap[index]; !ok {
|
||||
newVulnerability := v
|
||||
newVulnerability.Namespace = fv.Namespace
|
||||
newVulnerability.Affected = []database.AffectedFeature{fv}
|
||||
|
||||
vulnerabilitiesMap[index] = &newVulnerability
|
||||
} else {
|
||||
vulnerability.Affected = append(vulnerability.Affected, fv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert map into a slice.
|
||||
var response []database.VulnerabilityWithAffected
|
||||
for _, v := range vulnerabilitiesMap {
|
||||
// throw out invalid vulnerabilities.
|
||||
if v.Name == "" || !v.Severity.Valid() || v.Namespace.Name == "" || v.Namespace.VersionFormat == "" {
|
||||
log.WithFields(log.Fields{
|
||||
"Name": v.Name,
|
||||
"Severity": v.Severity,
|
||||
"Namespace": v.Namespace.Name + ":" + v.Namespace.VersionFormat,
|
||||
}).Warning("Vulnerability is mal-formatted")
|
||||
continue
|
||||
}
|
||||
response = append(response, *v)
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
func findLock(datastore database.Datastore, updaterLockName string) (string, time.Time, bool, error) {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
log.WithError(err).Error()
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return tx.FindLock(updaterLockName)
|
||||
}
|
||||
|
||||
// updateUpdaterFlags updates the flags specified by updaters, every transaction
|
||||
// is independent of each other.
|
||||
func updateUpdaterFlags(datastore database.Datastore, flags map[string]string) error {
|
||||
for key, value := range flags {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
err = tx.UpdateKeyValue(key, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setLastUpdateTime records the last successful date time in database.
|
||||
func setLastUpdateTime(datastore database.Datastore) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
err = tx.UpdateKeyValue(updaterLastFlagName, strconv.FormatInt(time.Now().UTC().Unix(), 10))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// isVulnerabilityChange compares two vulnerabilities by their severity and
|
||||
// affected features, and return true if they are different.
|
||||
func isVulnerabilityChanged(a *database.VulnerabilityWithAffected, b *database.VulnerabilityWithAffected) bool {
|
||||
if a == b {
|
||||
return false
|
||||
} else if a != nil && b != nil && a.Severity == b.Severity && len(a.Affected) == len(b.Affected) {
|
||||
checked := map[string]bool{}
|
||||
for _, affected := range a.Affected {
|
||||
checked[affected.Namespace.Name+":"+affected.FeatureName] = false
|
||||
}
|
||||
|
||||
for _, affected := range b.Affected {
|
||||
key := affected.Namespace.Name + ":" + affected.FeatureName
|
||||
if visited, ok := checked[key]; !ok || visited {
|
||||
return true
|
||||
}
|
||||
checked[key] = true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// findVulnerabilityChanges finds vulnerability changes from old
|
||||
// vulnerabilities to new vulnerabilities.
|
||||
// old and new vulnerabilities should be unique.
|
||||
func findVulnerabilityChanges(old []database.VulnerabilityWithAffected, new []database.VulnerabilityWithAffected) ([]vulnerabilityChange, error) {
|
||||
changes := map[database.VulnerabilityID]vulnerabilityChange{}
|
||||
for i, vuln := range old {
|
||||
key := database.VulnerabilityID{
|
||||
Name: vuln.Name,
|
||||
Namespace: vuln.Namespace.Name,
|
||||
}
|
||||
|
||||
if _, ok := changes[key]; ok {
|
||||
return nil, fmt.Errorf("duplicated old vulnerability")
|
||||
}
|
||||
changes[key] = vulnerabilityChange{old: &old[i]}
|
||||
}
|
||||
|
||||
for i, vuln := range new {
|
||||
key := database.VulnerabilityID{
|
||||
Name: vuln.Name,
|
||||
Namespace: vuln.Namespace.Name,
|
||||
}
|
||||
|
||||
if change, ok := changes[key]; ok {
|
||||
if isVulnerabilityChanged(change.old, &vuln) {
|
||||
change.new = &new[i]
|
||||
changes[key] = change
|
||||
} else {
|
||||
delete(changes, key)
|
||||
}
|
||||
} else {
|
||||
changes[key] = vulnerabilityChange{new: &new[i]}
|
||||
}
|
||||
}
|
||||
|
||||
vulnChange := make([]vulnerabilityChange, 0, len(changes))
|
||||
for _, change := range changes {
|
||||
vulnChange = append(vulnChange, change)
|
||||
}
|
||||
return vulnChange, nil
|
||||
}
|
||||
|
||||
// createVulnerabilityNotifications makes notifications out of vulnerability
|
||||
// changes and insert them into database.
|
||||
func createVulnerabilityNotifications(datastore database.Datastore, changes []vulnerabilityChange) error {
|
||||
log.WithField("count", len(changes)).Debug("creating vulnerability notifications")
|
||||
if len(changes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
notifications := make([]database.VulnerabilityNotification, 0, len(changes))
|
||||
for _, change := range changes {
|
||||
var oldVuln, newVuln *database.Vulnerability
|
||||
if change.old != nil {
|
||||
oldVuln = &change.old.Vulnerability
|
||||
}
|
||||
|
||||
if change.new != nil {
|
||||
newVuln = &change.new.Vulnerability
|
||||
}
|
||||
|
||||
notifications = append(notifications, database.VulnerabilityNotification{
|
||||
NotificationHook: database.NotificationHook{
|
||||
Name: uuid.New(),
|
||||
Created: time.Now(),
|
||||
},
|
||||
Old: oldVuln,
|
||||
New: newVuln,
|
||||
})
|
||||
}
|
||||
|
||||
if err := tx.InsertVulnerabilityNotifications(notifications); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// updateVulnerabilities upserts unique vulnerabilities into the database and
|
||||
// computes vulnerability changes.
|
||||
func updateVulnerabilities(datastore database.Datastore, vulnerabilities []database.VulnerabilityWithAffected) ([]vulnerabilityChange, error) {
|
||||
log.WithField("count", len(vulnerabilities)).Debug("updating vulnerabilities")
|
||||
if len(vulnerabilities) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ids := make([]database.VulnerabilityID, 0, len(vulnerabilities))
|
||||
for _, vuln := range vulnerabilities {
|
||||
ids = append(ids, database.VulnerabilityID{
|
||||
Name: vuln.Name,
|
||||
Namespace: vuln.Namespace.Name,
|
||||
})
|
||||
}
|
||||
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
oldVulnNullable, err := tx.FindVulnerabilities(ids)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oldVuln := []database.VulnerabilityWithAffected{}
|
||||
for _, vuln := range oldVulnNullable {
|
||||
if vuln.Valid {
|
||||
oldVuln = append(oldVuln, vuln.VulnerabilityWithAffected)
|
||||
}
|
||||
}
|
||||
|
||||
changes, err := findVulnerabilityChanges(oldVuln, vulnerabilities)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
toRemove := []database.VulnerabilityID{}
|
||||
toAdd := []database.VulnerabilityWithAffected{}
|
||||
for _, change := range changes {
|
||||
if change.old != nil {
|
||||
toRemove = append(toRemove, database.VulnerabilityID{
|
||||
Name: change.old.Name,
|
||||
Namespace: change.old.Namespace.Name,
|
||||
})
|
||||
}
|
||||
|
||||
if change.new != nil {
|
||||
toAdd = append(toAdd, *change.new)
|
||||
}
|
||||
}
|
||||
|
||||
log.WithField("count", len(toRemove)).Debug("marking vulnerabilities as outdated")
|
||||
if err := tx.DeleteVulnerabilities(toRemove); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.WithField("count", len(toAdd)).Debug("inserting new vulnerabilities")
|
||||
if err := tx.InsertVulnerabilities(toAdd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
func updaterEnabled(updaterName string) bool {
|
||||
for _, u := range EnabledUpdaters {
|
||||
if u == updaterName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
324
vendor/github.com/coreos/clair/updater_test.go
generated
vendored
Normal file
324
vendor/github.com/coreos/clair/updater_test.go
generated
vendored
Normal file
|
@ -0,0 +1,324 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package clair
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/coreos/clair/database"
|
||||
)
|
||||
|
||||
type mockUpdaterDatastore struct {
|
||||
database.MockDatastore
|
||||
|
||||
namespaces map[string]database.Namespace
|
||||
vulnerabilities map[database.VulnerabilityID]database.VulnerabilityWithAffected
|
||||
vulnNotification map[string]database.VulnerabilityNotification
|
||||
keyValues map[string]string
|
||||
}
|
||||
|
||||
type mockUpdaterSession struct {
|
||||
database.MockSession
|
||||
|
||||
store *mockUpdaterDatastore
|
||||
copy mockUpdaterDatastore
|
||||
terminated bool
|
||||
}
|
||||
|
||||
func copyUpdaterDatastore(md *mockUpdaterDatastore) mockUpdaterDatastore {
|
||||
namespaces := map[string]database.Namespace{}
|
||||
for k, n := range md.namespaces {
|
||||
namespaces[k] = n
|
||||
}
|
||||
|
||||
vulnerabilities := map[database.VulnerabilityID]database.VulnerabilityWithAffected{}
|
||||
for key, v := range md.vulnerabilities {
|
||||
newV := v
|
||||
affected := []database.AffectedFeature{}
|
||||
for _, f := range v.Affected {
|
||||
affected = append(affected, f)
|
||||
}
|
||||
newV.Affected = affected
|
||||
vulnerabilities[key] = newV
|
||||
}
|
||||
|
||||
vulnNoti := map[string]database.VulnerabilityNotification{}
|
||||
for key, v := range md.vulnNotification {
|
||||
vulnNoti[key] = v
|
||||
}
|
||||
|
||||
kv := map[string]string{}
|
||||
for key, value := range md.keyValues {
|
||||
kv[key] = value
|
||||
}
|
||||
|
||||
return mockUpdaterDatastore{
|
||||
namespaces: namespaces,
|
||||
vulnerabilities: vulnerabilities,
|
||||
vulnNotification: vulnNoti,
|
||||
keyValues: kv,
|
||||
}
|
||||
}
|
||||
|
||||
func newmockUpdaterDatastore() *mockUpdaterDatastore {
|
||||
errSessionDone := errors.New("Session Done")
|
||||
md := &mockUpdaterDatastore{
|
||||
namespaces: make(map[string]database.Namespace),
|
||||
vulnerabilities: make(map[database.VulnerabilityID]database.VulnerabilityWithAffected),
|
||||
vulnNotification: make(map[string]database.VulnerabilityNotification),
|
||||
keyValues: make(map[string]string),
|
||||
}
|
||||
|
||||
md.FctBegin = func() (database.Session, error) {
|
||||
session := &mockUpdaterSession{
|
||||
store: md,
|
||||
copy: copyUpdaterDatastore(md),
|
||||
terminated: false,
|
||||
}
|
||||
|
||||
session.FctCommit = func() error {
|
||||
if session.terminated {
|
||||
return errSessionDone
|
||||
}
|
||||
session.store.namespaces = session.copy.namespaces
|
||||
session.store.vulnerabilities = session.copy.vulnerabilities
|
||||
session.store.vulnNotification = session.copy.vulnNotification
|
||||
session.store.keyValues = session.copy.keyValues
|
||||
session.terminated = true
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctRollback = func() error {
|
||||
if session.terminated {
|
||||
return errSessionDone
|
||||
}
|
||||
session.terminated = true
|
||||
session.copy = mockUpdaterDatastore{}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctPersistNamespaces = func(ns []database.Namespace) error {
|
||||
if session.terminated {
|
||||
return errSessionDone
|
||||
}
|
||||
for _, n := range ns {
|
||||
_, ok := session.copy.namespaces[n.Name]
|
||||
if !ok {
|
||||
session.copy.namespaces[n.Name] = n
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctFindVulnerabilities = func(ids []database.VulnerabilityID) ([]database.NullableVulnerability, error) {
|
||||
r := []database.NullableVulnerability{}
|
||||
for _, id := range ids {
|
||||
vuln, ok := session.copy.vulnerabilities[id]
|
||||
r = append(r, database.NullableVulnerability{
|
||||
VulnerabilityWithAffected: vuln,
|
||||
Valid: ok,
|
||||
})
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
session.FctDeleteVulnerabilities = func(ids []database.VulnerabilityID) error {
|
||||
for _, id := range ids {
|
||||
delete(session.copy.vulnerabilities, id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctInsertVulnerabilities = func(vulnerabilities []database.VulnerabilityWithAffected) error {
|
||||
for _, vuln := range vulnerabilities {
|
||||
id := database.VulnerabilityID{
|
||||
Name: vuln.Name,
|
||||
Namespace: vuln.Namespace.Name,
|
||||
}
|
||||
if _, ok := session.copy.vulnerabilities[id]; ok {
|
||||
return errors.New("Vulnerability already exists")
|
||||
}
|
||||
session.copy.vulnerabilities[id] = vuln
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctUpdateKeyValue = func(key, value string) error {
|
||||
session.copy.keyValues[key] = value
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctFindKeyValue = func(key string) (string, bool, error) {
|
||||
s, b := session.copy.keyValues[key]
|
||||
return s, b, nil
|
||||
}
|
||||
|
||||
session.FctInsertVulnerabilityNotifications = func(notifications []database.VulnerabilityNotification) error {
|
||||
for _, noti := range notifications {
|
||||
session.copy.vulnNotification[noti.Name] = noti
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return session, nil
|
||||
}
|
||||
return md
|
||||
}
|
||||
|
||||
func TestDoVulnerabilitiesNamespacing(t *testing.T) {
|
||||
fv1 := database.AffectedFeature{
|
||||
Namespace: database.Namespace{Name: "Namespace1"},
|
||||
FeatureName: "Feature1",
|
||||
FixedInVersion: "0.1",
|
||||
AffectedVersion: "0.1",
|
||||
}
|
||||
|
||||
fv2 := database.AffectedFeature{
|
||||
Namespace: database.Namespace{Name: "Namespace2"},
|
||||
FeatureName: "Feature1",
|
||||
FixedInVersion: "0.2",
|
||||
AffectedVersion: "0.2",
|
||||
}
|
||||
|
||||
fv3 := database.AffectedFeature{
|
||||
|
||||
Namespace: database.Namespace{Name: "Namespace2"},
|
||||
FeatureName: "Feature2",
|
||||
FixedInVersion: "0.3",
|
||||
AffectedVersion: "0.3",
|
||||
}
|
||||
|
||||
vulnerability := database.VulnerabilityWithAffected{
|
||||
Vulnerability: database.Vulnerability{
|
||||
Name: "DoVulnerabilityNamespacing",
|
||||
},
|
||||
Affected: []database.AffectedFeature{fv1, fv2, fv3},
|
||||
}
|
||||
|
||||
vulnerabilities := doVulnerabilitiesNamespacing([]database.VulnerabilityWithAffected{vulnerability})
|
||||
for _, vulnerability := range vulnerabilities {
|
||||
switch vulnerability.Namespace.Name {
|
||||
case fv1.Namespace.Name:
|
||||
assert.Len(t, vulnerability.Affected, 1)
|
||||
assert.Contains(t, vulnerability.Affected, fv1)
|
||||
case fv2.Namespace.Name:
|
||||
assert.Len(t, vulnerability.Affected, 2)
|
||||
assert.Contains(t, vulnerability.Affected, fv2)
|
||||
assert.Contains(t, vulnerability.Affected, fv3)
|
||||
default:
|
||||
t.Errorf("Should not have a Vulnerability with '%s' as its Namespace.", vulnerability.Namespace.Name)
|
||||
fmt.Printf("%#v\n", vulnerability)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreatVulnerabilityNotification(t *testing.T) {
|
||||
vf1 := "VersionFormat1"
|
||||
ns1 := database.Namespace{
|
||||
Name: "namespace 1",
|
||||
VersionFormat: vf1,
|
||||
}
|
||||
af1 := database.AffectedFeature{
|
||||
Namespace: ns1,
|
||||
FeatureName: "feature 1",
|
||||
}
|
||||
|
||||
v1 := database.VulnerabilityWithAffected{
|
||||
Vulnerability: database.Vulnerability{
|
||||
Name: "vulnerability 1",
|
||||
Namespace: ns1,
|
||||
Severity: database.UnknownSeverity,
|
||||
},
|
||||
}
|
||||
|
||||
// severity change
|
||||
v2 := database.VulnerabilityWithAffected{
|
||||
Vulnerability: database.Vulnerability{
|
||||
Name: "vulnerability 1",
|
||||
Namespace: ns1,
|
||||
Severity: database.LowSeverity,
|
||||
},
|
||||
}
|
||||
|
||||
// affected versions change
|
||||
v3 := database.VulnerabilityWithAffected{
|
||||
Vulnerability: database.Vulnerability{
|
||||
Name: "vulnerability 1",
|
||||
Namespace: ns1,
|
||||
Severity: database.UnknownSeverity,
|
||||
},
|
||||
Affected: []database.AffectedFeature{af1},
|
||||
}
|
||||
|
||||
datastore := newmockUpdaterDatastore()
|
||||
change, err := updateVulnerabilities(datastore, []database.VulnerabilityWithAffected{})
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, change, 0)
|
||||
|
||||
change, err = updateVulnerabilities(datastore, []database.VulnerabilityWithAffected{v1})
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, change, 1)
|
||||
assert.Nil(t, change[0].old)
|
||||
assertVulnerability(t, *change[0].new, v1)
|
||||
|
||||
change, err = updateVulnerabilities(datastore, []database.VulnerabilityWithAffected{v1})
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, change, 0)
|
||||
|
||||
change, err = updateVulnerabilities(datastore, []database.VulnerabilityWithAffected{v2})
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, change, 1)
|
||||
assertVulnerability(t, *change[0].new, v2)
|
||||
assertVulnerability(t, *change[0].old, v1)
|
||||
|
||||
change, err = updateVulnerabilities(datastore, []database.VulnerabilityWithAffected{v3})
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, change, 1)
|
||||
assertVulnerability(t, *change[0].new, v3)
|
||||
assertVulnerability(t, *change[0].old, v2)
|
||||
|
||||
err = createVulnerabilityNotifications(datastore, change)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, datastore.vulnNotification, 1)
|
||||
for _, noti := range datastore.vulnNotification {
|
||||
assert.Equal(t, *noti.New, v3.Vulnerability)
|
||||
assert.Equal(t, *noti.Old, v2.Vulnerability)
|
||||
}
|
||||
}
|
||||
|
||||
func assertVulnerability(t *testing.T, expected database.VulnerabilityWithAffected, actual database.VulnerabilityWithAffected) bool {
|
||||
expectedAF := expected.Affected
|
||||
actualAF := actual.Affected
|
||||
expected.Affected, actual.Affected = nil, nil
|
||||
|
||||
assert.Equal(t, expected, actual)
|
||||
assert.Len(t, actualAF, len(expectedAF))
|
||||
|
||||
mapAF := map[database.AffectedFeature]bool{}
|
||||
for _, af := range expectedAF {
|
||||
mapAF[af] = false
|
||||
}
|
||||
|
||||
for _, af := range actualAF {
|
||||
if visited, ok := mapAF[af]; !ok || visited {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
568
vendor/github.com/coreos/clair/worker.go
generated
vendored
Normal file
568
vendor/github.com/coreos/clair/worker.go
generated
vendored
Normal file
|
@ -0,0 +1,568 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package clair
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/coreos/clair/database"
|
||||
"github.com/coreos/clair/ext/featurefmt"
|
||||
"github.com/coreos/clair/ext/featurens"
|
||||
"github.com/coreos/clair/ext/imagefmt"
|
||||
"github.com/coreos/clair/pkg/commonerr"
|
||||
"github.com/coreos/clair/pkg/strutil"
|
||||
)
|
||||
|
||||
const (
|
||||
logLayerName = "layer"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnsupported is the error that should be raised when an OS or package
|
||||
// manager is not supported.
|
||||
ErrUnsupported = commonerr.NewBadRequestError("worker: OS and/or package manager are not supported")
|
||||
|
||||
// ErrParentUnknown is the error that should be raised when a parent layer
|
||||
// has yet to be processed for the current layer.
|
||||
ErrParentUnknown = commonerr.NewBadRequestError("worker: parent layer is unknown, it must be processed first")
|
||||
|
||||
urlParametersRegexp = regexp.MustCompile(`(\?|\&)([^=]+)\=([^ &]+)`)
|
||||
|
||||
// Processors contain the names of namespace detectors and feature listers
|
||||
// enabled in this instance of Clair.
|
||||
//
|
||||
// Processors are initialized during booting and configured in the
|
||||
// configuration file.
|
||||
Processors database.Processors
|
||||
)
|
||||
|
||||
type WorkerConfig struct {
|
||||
EnabledDetectors []string `yaml:"namespace_detectors"`
|
||||
EnabledListers []string `yaml:"feature_listers"`
|
||||
}
|
||||
|
||||
// LayerRequest represents all information necessary to download and process a
|
||||
// layer.
|
||||
type LayerRequest struct {
|
||||
Hash string
|
||||
Path string
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// partialLayer stores layer's content detected by `processedBy` processors.
|
||||
type partialLayer struct {
|
||||
hash string
|
||||
processedBy database.Processors
|
||||
namespaces []database.Namespace
|
||||
features []database.Feature
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
// processRequest stores parameters used for processing layers.
|
||||
type processRequest struct {
|
||||
request LayerRequest
|
||||
// notProcessedBy represents a set of processors used to process the
|
||||
// request.
|
||||
notProcessedBy database.Processors
|
||||
}
|
||||
|
||||
// cleanURL removes all parameters from an URL.
|
||||
func cleanURL(str string) string {
|
||||
return urlParametersRegexp.ReplaceAllString(str, "")
|
||||
}
|
||||
|
||||
// processLayers in parallel processes a set of requests for unique set of layers
|
||||
// and returns sets of unique namespaces, features and layers to be inserted
|
||||
// into the database.
|
||||
func processRequests(imageFormat string, toDetect []processRequest) ([]database.Namespace, []database.Feature, map[string]partialLayer, error) {
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(len(toDetect))
|
||||
results := make([]partialLayer, len(toDetect))
|
||||
for i := range toDetect {
|
||||
go func(req *processRequest, res *partialLayer) {
|
||||
res.hash = req.request.Hash
|
||||
res.processedBy = req.notProcessedBy
|
||||
res.namespaces, res.features, res.err = detectContent(imageFormat, req.request.Hash, req.request.Path, req.request.Headers, req.notProcessedBy)
|
||||
wg.Done()
|
||||
}(&toDetect[i], &results[i])
|
||||
}
|
||||
wg.Wait()
|
||||
distinctNS := map[database.Namespace]struct{}{}
|
||||
distinctF := map[database.Feature]struct{}{}
|
||||
|
||||
errs := []error{}
|
||||
for _, r := range results {
|
||||
errs = append(errs, r.err)
|
||||
}
|
||||
|
||||
if err := commonerr.CombineErrors(errs...); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
updates := map[string]partialLayer{}
|
||||
for _, r := range results {
|
||||
for _, ns := range r.namespaces {
|
||||
distinctNS[ns] = struct{}{}
|
||||
}
|
||||
|
||||
for _, f := range r.features {
|
||||
distinctF[f] = struct{}{}
|
||||
}
|
||||
|
||||
if _, ok := updates[r.hash]; !ok {
|
||||
updates[r.hash] = r
|
||||
} else {
|
||||
return nil, nil, nil, errors.New("Duplicated updates is not allowed")
|
||||
}
|
||||
}
|
||||
|
||||
namespaces := make([]database.Namespace, 0, len(distinctNS))
|
||||
features := make([]database.Feature, 0, len(distinctF))
|
||||
|
||||
for ns := range distinctNS {
|
||||
namespaces = append(namespaces, ns)
|
||||
}
|
||||
|
||||
for f := range distinctF {
|
||||
features = append(features, f)
|
||||
}
|
||||
return namespaces, features, updates, nil
|
||||
}
|
||||
|
||||
func getLayer(datastore database.Datastore, req LayerRequest) (layer database.LayerWithContent, preq *processRequest, err error) {
|
||||
var ok bool
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
layer, ok, err = tx.FindLayerWithContent(req.Hash)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !ok {
|
||||
l := database.Layer{Hash: req.Hash}
|
||||
err = tx.PersistLayer(l)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
layer = database.LayerWithContent{Layer: l}
|
||||
preq = &processRequest{
|
||||
request: req,
|
||||
notProcessedBy: Processors,
|
||||
}
|
||||
} else {
|
||||
notProcessed := getNotProcessedBy(layer.ProcessedBy)
|
||||
if !(len(notProcessed.Detectors) == 0 && len(notProcessed.Listers) == 0 && ok) {
|
||||
preq = &processRequest{
|
||||
request: req,
|
||||
notProcessedBy: notProcessed,
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// processLayers processes a set of post layer requests, stores layers and
|
||||
// returns an ordered list of processed layers with detected features and
|
||||
// namespaces.
|
||||
func processLayers(datastore database.Datastore, imageFormat string, requests []LayerRequest) ([]database.LayerWithContent, error) {
|
||||
toDetect := []processRequest{}
|
||||
layers := map[string]database.LayerWithContent{}
|
||||
for _, req := range requests {
|
||||
if _, ok := layers[req.Hash]; ok {
|
||||
continue
|
||||
}
|
||||
layer, preq, err := getLayer(datastore, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
layers[req.Hash] = layer
|
||||
if preq != nil {
|
||||
toDetect = append(toDetect, *preq)
|
||||
}
|
||||
}
|
||||
|
||||
namespaces, features, partialRes, err := processRequests(imageFormat, toDetect)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Store partial results.
|
||||
if err := persistNamespaces(datastore, namespaces); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := persistFeatures(datastore, features); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, res := range partialRes {
|
||||
if err := persistPartialLayer(datastore, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(Sida): The full layers are computed using partially
|
||||
// processed layers in current database session. If any other instances of
|
||||
// Clair are changing some layers in this set of layers, it might generate
|
||||
// different results especially when the other Clair is with different
|
||||
// processors.
|
||||
completeLayers := []database.LayerWithContent{}
|
||||
for _, req := range requests {
|
||||
if partialLayer, ok := partialRes[req.Hash]; ok {
|
||||
completeLayers = append(completeLayers, combineLayers(layers[req.Hash], partialLayer))
|
||||
} else {
|
||||
completeLayers = append(completeLayers, layers[req.Hash])
|
||||
}
|
||||
}
|
||||
|
||||
return completeLayers, nil
|
||||
}
|
||||
|
||||
func persistPartialLayer(datastore database.Datastore, layer partialLayer) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.PersistLayerContent(layer.hash, layer.namespaces, layer.features, layer.processedBy); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func persistFeatures(datastore database.Datastore, features []database.Feature) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.PersistFeatures(features); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func persistNamespaces(datastore database.Datastore, namespaces []database.Namespace) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.PersistNamespaces(namespaces); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// combineLayers merges `layer` and `partial` without duplicated content.
|
||||
func combineLayers(layer database.LayerWithContent, partial partialLayer) database.LayerWithContent {
|
||||
mapF := map[database.Feature]struct{}{}
|
||||
mapNS := map[database.Namespace]struct{}{}
|
||||
for _, f := range layer.Features {
|
||||
mapF[f] = struct{}{}
|
||||
}
|
||||
for _, ns := range layer.Namespaces {
|
||||
mapNS[ns] = struct{}{}
|
||||
}
|
||||
for _, f := range partial.features {
|
||||
mapF[f] = struct{}{}
|
||||
}
|
||||
for _, ns := range partial.namespaces {
|
||||
mapNS[ns] = struct{}{}
|
||||
}
|
||||
features := make([]database.Feature, 0, len(mapF))
|
||||
namespaces := make([]database.Namespace, 0, len(mapNS))
|
||||
for f := range mapF {
|
||||
features = append(features, f)
|
||||
}
|
||||
for ns := range mapNS {
|
||||
namespaces = append(namespaces, ns)
|
||||
}
|
||||
|
||||
layer.ProcessedBy.Detectors = append(layer.ProcessedBy.Detectors, strutil.CompareStringLists(partial.processedBy.Detectors, layer.ProcessedBy.Detectors)...)
|
||||
layer.ProcessedBy.Listers = append(layer.ProcessedBy.Listers, strutil.CompareStringLists(partial.processedBy.Listers, layer.ProcessedBy.Listers)...)
|
||||
return database.LayerWithContent{
|
||||
Layer: database.Layer{
|
||||
Hash: layer.Hash,
|
||||
},
|
||||
ProcessedBy: layer.ProcessedBy,
|
||||
Features: features,
|
||||
Namespaces: namespaces,
|
||||
}
|
||||
}
|
||||
|
||||
func isAncestryProcessed(datastore database.Datastore, name string) (bool, error) {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
_, processed, ok, err := tx.FindAncestry(name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
notProcessed := getNotProcessedBy(processed)
|
||||
return len(notProcessed.Detectors) == 0 && len(notProcessed.Listers) == 0, nil
|
||||
}
|
||||
|
||||
// ProcessAncestry downloads and scans an ancestry if it's not scanned by all
|
||||
// enabled processors in this instance of Clair.
|
||||
func ProcessAncestry(datastore database.Datastore, imageFormat, name string, layerRequest []LayerRequest) error {
|
||||
var err error
|
||||
if name == "" {
|
||||
return commonerr.NewBadRequestError("could not process a layer which does not have a name")
|
||||
}
|
||||
|
||||
if imageFormat == "" {
|
||||
return commonerr.NewBadRequestError("could not process a layer which does not have a format")
|
||||
}
|
||||
|
||||
if ok, err := isAncestryProcessed(datastore, name); ok && err == nil {
|
||||
log.WithField("ancestry", name).Debug("Ancestry is processed")
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
layers, err := processLayers(datastore, imageFormat, layerRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !validateProcessors(layers) {
|
||||
// This error might be triggered because of multiple workers are
|
||||
// processing the same instance with different processors.
|
||||
return errors.New("ancestry layers are scanned with different listers and detectors")
|
||||
}
|
||||
|
||||
return processAncestry(datastore, name, layers)
|
||||
}
|
||||
|
||||
func processAncestry(datastore database.Datastore, name string, layers []database.LayerWithContent) error {
|
||||
ancestryFeatures, err := computeAncestryFeatures(layers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ancestryLayers := make([]database.Layer, 0, len(layers))
|
||||
for _, layer := range layers {
|
||||
ancestryLayers = append(ancestryLayers, layer.Layer)
|
||||
}
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"ancestry": name,
|
||||
"number of features": len(ancestryFeatures),
|
||||
"processed by": Processors,
|
||||
"number of layers": len(ancestryLayers),
|
||||
}).Debug("compute ancestry features")
|
||||
|
||||
if err := persistNamespacedFeatures(datastore, ancestryFeatures); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.UpsertAncestry(database.Ancestry{Name: name, Layers: ancestryLayers}, ancestryFeatures, Processors)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func persistNamespacedFeatures(datastore database.Datastore, features []database.NamespacedFeature) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.PersistNamespacedFeatures(features); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx, err = datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.CacheAffectedNamespacedFeatures(features); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// validateProcessors checks if the layers processed by same set of processors.
|
||||
func validateProcessors(layers []database.LayerWithContent) bool {
|
||||
if len(layers) == 0 {
|
||||
return true
|
||||
}
|
||||
detectors := layers[0].ProcessedBy.Detectors
|
||||
listers := layers[0].ProcessedBy.Listers
|
||||
|
||||
for _, l := range layers[1:] {
|
||||
if len(strutil.CompareStringLists(detectors, l.ProcessedBy.Detectors)) != 0 ||
|
||||
len(strutil.CompareStringLists(listers, l.ProcessedBy.Listers)) != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// computeAncestryFeatures computes the features in an ancestry based on all
|
||||
// layers.
|
||||
func computeAncestryFeatures(ancestryLayers []database.LayerWithContent) ([]database.NamespacedFeature, error) {
|
||||
// version format -> namespace
|
||||
namespaces := map[string]database.Namespace{}
|
||||
// version format -> feature ID -> feature
|
||||
features := map[string]map[string]database.NamespacedFeature{}
|
||||
for _, layer := range ancestryLayers {
|
||||
// At start of the loop, namespaces and features always contain the
|
||||
// previous layer's result.
|
||||
for _, ns := range layer.Namespaces {
|
||||
namespaces[ns.VersionFormat] = ns
|
||||
}
|
||||
|
||||
// version format -> feature ID -> feature
|
||||
currentFeatures := map[string]map[string]database.NamespacedFeature{}
|
||||
for _, f := range layer.Features {
|
||||
if ns, ok := namespaces[f.VersionFormat]; ok {
|
||||
var currentMap map[string]database.NamespacedFeature
|
||||
if currentMap, ok = currentFeatures[f.VersionFormat]; !ok {
|
||||
currentFeatures[f.VersionFormat] = make(map[string]database.NamespacedFeature)
|
||||
currentMap = currentFeatures[f.VersionFormat]
|
||||
}
|
||||
|
||||
inherited := false
|
||||
if mapF, ok := features[f.VersionFormat]; ok {
|
||||
if parentFeature, ok := mapF[f.Name+":"+f.Version]; ok {
|
||||
currentMap[f.Name+":"+f.Version] = parentFeature
|
||||
inherited = true
|
||||
}
|
||||
}
|
||||
|
||||
if !inherited {
|
||||
currentMap[f.Name+":"+f.Version] = database.NamespacedFeature{
|
||||
Feature: f,
|
||||
Namespace: ns,
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return nil, errors.New("No corresponding version format")
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(Sida): we update the feature map in some version format
|
||||
// only if there's at least one feature with that version format. This
|
||||
// approach won't differentiate feature file removed vs all detectable
|
||||
// features removed from that file vs feature file not changed.
|
||||
//
|
||||
// One way to differentiate (feature file removed or not changed) vs
|
||||
// all detectable features removed is to pass in the file status.
|
||||
for vf, mapF := range currentFeatures {
|
||||
features[vf] = mapF
|
||||
}
|
||||
}
|
||||
|
||||
ancestryFeatures := []database.NamespacedFeature{}
|
||||
for _, featureMap := range features {
|
||||
for _, feature := range featureMap {
|
||||
ancestryFeatures = append(ancestryFeatures, feature)
|
||||
}
|
||||
}
|
||||
return ancestryFeatures, nil
|
||||
}
|
||||
|
||||
// getNotProcessedBy returns a processors, which contains the detectors and
|
||||
// listers not in `processedBy` but implemented in the current clair instance.
|
||||
func getNotProcessedBy(processedBy database.Processors) database.Processors {
|
||||
notProcessedLister := strutil.CompareStringLists(Processors.Listers, processedBy.Listers)
|
||||
notProcessedDetector := strutil.CompareStringLists(Processors.Detectors, processedBy.Detectors)
|
||||
return database.Processors{
|
||||
Listers: notProcessedLister,
|
||||
Detectors: notProcessedDetector,
|
||||
}
|
||||
}
|
||||
|
||||
// detectContent downloads a layer and detects all features and namespaces.
|
||||
func detectContent(imageFormat, name, path string, headers map[string]string, toProcess database.Processors) (namespaces []database.Namespace, featureVersions []database.Feature, err error) {
|
||||
log.WithFields(log.Fields{"Hash": name}).Debug("Process Layer")
|
||||
totalRequiredFiles := append(featurefmt.RequiredFilenames(toProcess.Listers), featurens.RequiredFilenames(toProcess.Detectors)...)
|
||||
files, err := imagefmt.Extract(imageFormat, path, headers, totalRequiredFiles)
|
||||
if err != nil {
|
||||
log.WithError(err).WithFields(log.Fields{
|
||||
logLayerName: name,
|
||||
"path": cleanURL(path),
|
||||
}).Error("failed to extract data from path")
|
||||
return
|
||||
}
|
||||
|
||||
namespaces, err = featurens.Detect(files, toProcess.Detectors)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(featureVersions) > 0 {
|
||||
log.WithFields(log.Fields{logLayerName: name, "count": len(namespaces)}).Debug("detected layer namespaces")
|
||||
}
|
||||
|
||||
featureVersions, err = featurefmt.ListFeatures(files, toProcess.Listers)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(featureVersions) > 0 {
|
||||
log.WithFields(log.Fields{logLayerName: name, "count": len(featureVersions)}).Debug("detected layer features")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
640
vendor/github.com/coreos/clair/worker_test.go
generated
vendored
Normal file
640
vendor/github.com/coreos/clair/worker_test.go
generated
vendored
Normal file
|
@ -0,0 +1,640 @@
|
|||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package clair
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/coreos/clair/database"
|
||||
"github.com/coreos/clair/ext/featurefmt"
|
||||
"github.com/coreos/clair/ext/featurens"
|
||||
"github.com/coreos/clair/ext/versionfmt/dpkg"
|
||||
"github.com/coreos/clair/pkg/strutil"
|
||||
|
||||
// Register the required detectors.
|
||||
_ "github.com/coreos/clair/ext/featurefmt/dpkg"
|
||||
_ "github.com/coreos/clair/ext/featurefmt/rpm"
|
||||
_ "github.com/coreos/clair/ext/featurens/aptsources"
|
||||
_ "github.com/coreos/clair/ext/featurens/osrelease"
|
||||
_ "github.com/coreos/clair/ext/imagefmt/docker"
|
||||
)
|
||||
|
||||
type mockDatastore struct {
|
||||
database.MockDatastore
|
||||
|
||||
layers map[string]database.LayerWithContent
|
||||
ancestry map[string]database.AncestryWithFeatures
|
||||
namespaces map[string]database.Namespace
|
||||
features map[string]database.Feature
|
||||
namespacedFeatures map[string]database.NamespacedFeature
|
||||
}
|
||||
|
||||
type mockSession struct {
|
||||
database.MockSession
|
||||
|
||||
store *mockDatastore
|
||||
copy mockDatastore
|
||||
terminated bool
|
||||
}
|
||||
|
||||
func copyDatastore(md *mockDatastore) mockDatastore {
|
||||
layers := map[string]database.LayerWithContent{}
|
||||
for k, l := range md.layers {
|
||||
features := append([]database.Feature(nil), l.Features...)
|
||||
namespaces := append([]database.Namespace(nil), l.Namespaces...)
|
||||
listers := append([]string(nil), l.ProcessedBy.Listers...)
|
||||
detectors := append([]string(nil), l.ProcessedBy.Detectors...)
|
||||
layers[k] = database.LayerWithContent{
|
||||
Layer: database.Layer{
|
||||
Hash: l.Hash,
|
||||
},
|
||||
ProcessedBy: database.Processors{
|
||||
Listers: listers,
|
||||
Detectors: detectors,
|
||||
},
|
||||
Features: features,
|
||||
Namespaces: namespaces,
|
||||
}
|
||||
}
|
||||
|
||||
ancestry := map[string]database.AncestryWithFeatures{}
|
||||
for k, a := range md.ancestry {
|
||||
nf := append([]database.NamespacedFeature(nil), a.Features...)
|
||||
l := append([]database.Layer(nil), a.Layers...)
|
||||
listers := append([]string(nil), a.ProcessedBy.Listers...)
|
||||
detectors := append([]string(nil), a.ProcessedBy.Detectors...)
|
||||
ancestry[k] = database.AncestryWithFeatures{
|
||||
Ancestry: database.Ancestry{
|
||||
Name: a.Name,
|
||||
Layers: l,
|
||||
},
|
||||
ProcessedBy: database.Processors{
|
||||
Detectors: detectors,
|
||||
Listers: listers,
|
||||
},
|
||||
Features: nf,
|
||||
}
|
||||
}
|
||||
|
||||
namespaces := map[string]database.Namespace{}
|
||||
for k, n := range md.namespaces {
|
||||
namespaces[k] = n
|
||||
}
|
||||
|
||||
features := map[string]database.Feature{}
|
||||
for k, f := range md.features {
|
||||
features[k] = f
|
||||
}
|
||||
|
||||
namespacedFeatures := map[string]database.NamespacedFeature{}
|
||||
for k, f := range md.namespacedFeatures {
|
||||
namespacedFeatures[k] = f
|
||||
}
|
||||
return mockDatastore{
|
||||
layers: layers,
|
||||
ancestry: ancestry,
|
||||
namespaces: namespaces,
|
||||
namespacedFeatures: namespacedFeatures,
|
||||
features: features,
|
||||
}
|
||||
}
|
||||
|
||||
func newMockDatastore() *mockDatastore {
|
||||
errSessionDone := errors.New("Session Done")
|
||||
md := &mockDatastore{
|
||||
layers: make(map[string]database.LayerWithContent),
|
||||
ancestry: make(map[string]database.AncestryWithFeatures),
|
||||
namespaces: make(map[string]database.Namespace),
|
||||
features: make(map[string]database.Feature),
|
||||
namespacedFeatures: make(map[string]database.NamespacedFeature),
|
||||
}
|
||||
|
||||
md.FctBegin = func() (database.Session, error) {
|
||||
session := &mockSession{
|
||||
store: md,
|
||||
copy: copyDatastore(md),
|
||||
terminated: false,
|
||||
}
|
||||
|
||||
session.FctCommit = func() error {
|
||||
if session.terminated {
|
||||
return nil
|
||||
}
|
||||
session.store.layers = session.copy.layers
|
||||
session.store.ancestry = session.copy.ancestry
|
||||
session.store.namespaces = session.copy.namespaces
|
||||
session.store.features = session.copy.features
|
||||
session.store.namespacedFeatures = session.copy.namespacedFeatures
|
||||
session.terminated = true
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctRollback = func() error {
|
||||
if session.terminated {
|
||||
return nil
|
||||
}
|
||||
session.terminated = true
|
||||
session.copy = mockDatastore{}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctFindAncestry = func(name string) (database.Ancestry, database.Processors, bool, error) {
|
||||
processors := database.Processors{}
|
||||
if session.terminated {
|
||||
return database.Ancestry{}, processors, false, errSessionDone
|
||||
}
|
||||
ancestry, ok := session.copy.ancestry[name]
|
||||
return ancestry.Ancestry, ancestry.ProcessedBy, ok, nil
|
||||
}
|
||||
|
||||
session.FctFindLayer = func(name string) (database.Layer, database.Processors, bool, error) {
|
||||
processors := database.Processors{}
|
||||
if session.terminated {
|
||||
return database.Layer{}, processors, false, errSessionDone
|
||||
}
|
||||
layer, ok := session.copy.layers[name]
|
||||
return layer.Layer, layer.ProcessedBy, ok, nil
|
||||
}
|
||||
|
||||
session.FctFindLayerWithContent = func(name string) (database.LayerWithContent, bool, error) {
|
||||
if session.terminated {
|
||||
return database.LayerWithContent{}, false, errSessionDone
|
||||
}
|
||||
layer, ok := session.copy.layers[name]
|
||||
return layer, ok, nil
|
||||
}
|
||||
|
||||
session.FctPersistLayer = func(layer database.Layer) error {
|
||||
if session.terminated {
|
||||
return errSessionDone
|
||||
}
|
||||
if _, ok := session.copy.layers[layer.Hash]; !ok {
|
||||
session.copy.layers[layer.Hash] = database.LayerWithContent{Layer: layer}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctPersistNamespaces = func(ns []database.Namespace) error {
|
||||
if session.terminated {
|
||||
return errSessionDone
|
||||
}
|
||||
for _, n := range ns {
|
||||
_, ok := session.copy.namespaces[n.Name]
|
||||
if !ok {
|
||||
session.copy.namespaces[n.Name] = n
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctPersistFeatures = func(fs []database.Feature) error {
|
||||
if session.terminated {
|
||||
return errSessionDone
|
||||
}
|
||||
for _, f := range fs {
|
||||
key := FeatureKey(&f)
|
||||
_, ok := session.copy.features[key]
|
||||
if !ok {
|
||||
session.copy.features[key] = f
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctPersistLayerContent = func(hash string, namespaces []database.Namespace, features []database.Feature, processedBy database.Processors) error {
|
||||
if session.terminated {
|
||||
return errSessionDone
|
||||
}
|
||||
|
||||
// update the layer
|
||||
layer, ok := session.copy.layers[hash]
|
||||
if !ok {
|
||||
return errors.New("layer not found")
|
||||
}
|
||||
|
||||
layerFeatures := map[string]database.Feature{}
|
||||
layerNamespaces := map[string]database.Namespace{}
|
||||
for _, f := range layer.Features {
|
||||
layerFeatures[FeatureKey(&f)] = f
|
||||
}
|
||||
for _, n := range layer.Namespaces {
|
||||
layerNamespaces[n.Name] = n
|
||||
}
|
||||
|
||||
// ensure that all the namespaces, features are in the database
|
||||
for _, ns := range namespaces {
|
||||
if _, ok := session.copy.namespaces[ns.Name]; !ok {
|
||||
return errors.New("Namespaces should be in the database")
|
||||
}
|
||||
if _, ok := layerNamespaces[ns.Name]; !ok {
|
||||
layer.Namespaces = append(layer.Namespaces, ns)
|
||||
layerNamespaces[ns.Name] = ns
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range features {
|
||||
if _, ok := session.copy.features[FeatureKey(&f)]; !ok {
|
||||
return errors.New("Namespaces should be in the database")
|
||||
}
|
||||
if _, ok := layerFeatures[FeatureKey(&f)]; !ok {
|
||||
layer.Features = append(layer.Features, f)
|
||||
layerFeatures[FeatureKey(&f)] = f
|
||||
}
|
||||
}
|
||||
|
||||
layer.ProcessedBy.Detectors = append(layer.ProcessedBy.Detectors, strutil.CompareStringLists(processedBy.Detectors, layer.ProcessedBy.Detectors)...)
|
||||
layer.ProcessedBy.Listers = append(layer.ProcessedBy.Listers, strutil.CompareStringLists(processedBy.Listers, layer.ProcessedBy.Listers)...)
|
||||
|
||||
session.copy.layers[hash] = layer
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctUpsertAncestry = func(ancestry database.Ancestry, features []database.NamespacedFeature, processors database.Processors) error {
|
||||
if session.terminated {
|
||||
return errSessionDone
|
||||
}
|
||||
|
||||
// ensure features are in the database
|
||||
for _, f := range features {
|
||||
if _, ok := session.copy.namespacedFeatures[NamespacedFeatureKey(&f)]; !ok {
|
||||
return errors.New("namepsaced feature not in db")
|
||||
}
|
||||
}
|
||||
|
||||
ancestryWFeature := database.AncestryWithFeatures{
|
||||
Ancestry: ancestry,
|
||||
Features: features,
|
||||
ProcessedBy: processors,
|
||||
}
|
||||
|
||||
session.copy.ancestry[ancestry.Name] = ancestryWFeature
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctPersistNamespacedFeatures = func(namespacedFeatures []database.NamespacedFeature) error {
|
||||
for i, f := range namespacedFeatures {
|
||||
session.copy.namespacedFeatures[NamespacedFeatureKey(&f)] = namespacedFeatures[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
session.FctCacheAffectedNamespacedFeatures = func(namespacedFeatures []database.NamespacedFeature) error {
|
||||
// The function does nothing because we don't care about the vulnerability cache in worker_test.
|
||||
return nil
|
||||
}
|
||||
|
||||
return session, nil
|
||||
}
|
||||
return md
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
Processors = database.Processors{
|
||||
Listers: featurefmt.ListListers(),
|
||||
Detectors: featurens.ListDetectors(),
|
||||
}
|
||||
m.Run()
|
||||
}
|
||||
|
||||
func FeatureKey(f *database.Feature) string {
|
||||
return strings.Join([]string{f.Name, f.VersionFormat, f.Version}, "__")
|
||||
}
|
||||
|
||||
func NamespacedFeatureKey(f *database.NamespacedFeature) string {
|
||||
return strings.Join([]string{f.Name, f.Namespace.Name}, "__")
|
||||
}
|
||||
|
||||
func TestProcessAncestryWithDistUpgrade(t *testing.T) {
|
||||
// Create the list of Features that should not been upgraded from one layer to another.
|
||||
nonUpgradedFeatures := []database.Feature{
|
||||
{Name: "libtext-wrapi18n-perl", Version: "0.06-7"},
|
||||
{Name: "libtext-charwidth-perl", Version: "0.04-7"},
|
||||
{Name: "libtext-iconv-perl", Version: "1.7-5"},
|
||||
{Name: "mawk", Version: "1.3.3-17"},
|
||||
{Name: "insserv", Version: "1.14.0-5"},
|
||||
{Name: "db", Version: "5.1.29-5"},
|
||||
{Name: "ustr", Version: "1.0.4-3"},
|
||||
{Name: "xz-utils", Version: "5.1.1alpha+20120614-2"},
|
||||
}
|
||||
|
||||
nonUpgradedMap := map[database.Feature]struct{}{}
|
||||
for _, f := range nonUpgradedFeatures {
|
||||
f.VersionFormat = "dpkg"
|
||||
nonUpgradedMap[f] = struct{}{}
|
||||
}
|
||||
|
||||
// Process test layers.
|
||||
//
|
||||
// blank.tar: MAINTAINER Quentin MACHU <quentin.machu.fr>
|
||||
// wheezy.tar: FROM debian:wheezy
|
||||
// jessie.tar: RUN sed -i "s/precise/trusty/" /etc/apt/sources.list && apt-get update &&
|
||||
// apt-get -y dist-upgrade
|
||||
_, f, _, _ := runtime.Caller(0)
|
||||
testDataPath := filepath.Join(filepath.Dir(f)) + "/testdata/DistUpgrade/"
|
||||
|
||||
datastore := newMockDatastore()
|
||||
|
||||
layers := []LayerRequest{
|
||||
{Hash: "blank", Path: testDataPath + "blank.tar.gz"},
|
||||
{Hash: "wheezy", Path: testDataPath + "wheezy.tar.gz"},
|
||||
{Hash: "jessie", Path: testDataPath + "jessie.tar.gz"},
|
||||
}
|
||||
|
||||
assert.Nil(t, ProcessAncestry(datastore, "Docker", "Mock", layers))
|
||||
// check the ancestry features
|
||||
assert.Len(t, datastore.ancestry["Mock"].Features, 74)
|
||||
for _, f := range datastore.ancestry["Mock"].Features {
|
||||
if _, ok := nonUpgradedMap[f.Feature]; ok {
|
||||
assert.Equal(t, "debian:7", f.Namespace.Name)
|
||||
} else {
|
||||
assert.Equal(t, "debian:8", f.Namespace.Name)
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(t, []database.Layer{
|
||||
{Hash: "blank"},
|
||||
{Hash: "wheezy"},
|
||||
{Hash: "jessie"},
|
||||
}, datastore.ancestry["Mock"].Layers)
|
||||
}
|
||||
|
||||
func TestProcessLayers(t *testing.T) {
|
||||
_, f, _, _ := runtime.Caller(0)
|
||||
testDataPath := filepath.Join(filepath.Dir(f)) + "/testdata/DistUpgrade/"
|
||||
|
||||
datastore := newMockDatastore()
|
||||
|
||||
layers := []LayerRequest{
|
||||
{Hash: "blank", Path: testDataPath + "blank.tar.gz"},
|
||||
{Hash: "wheezy", Path: testDataPath + "wheezy.tar.gz"},
|
||||
{Hash: "jessie", Path: testDataPath + "jessie.tar.gz"},
|
||||
}
|
||||
|
||||
processedLayers, err := processLayers(datastore, "Docker", layers)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, processedLayers, 3)
|
||||
// ensure resubmit won't break the stuff
|
||||
processedLayers, err = processLayers(datastore, "Docker", layers)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, processedLayers, 3)
|
||||
// Ensure each processed layer is correct
|
||||
assert.Len(t, processedLayers[0].Namespaces, 0)
|
||||
assert.Len(t, processedLayers[1].Namespaces, 1)
|
||||
assert.Len(t, processedLayers[2].Namespaces, 1)
|
||||
assert.Len(t, processedLayers[0].Features, 0)
|
||||
assert.Len(t, processedLayers[1].Features, 52)
|
||||
assert.Len(t, processedLayers[2].Features, 74)
|
||||
|
||||
// Ensure each layer has expected namespaces and features detected
|
||||
if blank, ok := datastore.layers["blank"]; ok {
|
||||
assert.Equal(t, blank.ProcessedBy.Detectors, Processors.Detectors)
|
||||
assert.Equal(t, blank.ProcessedBy.Listers, Processors.Listers)
|
||||
assert.Len(t, blank.Namespaces, 0)
|
||||
assert.Len(t, blank.Features, 0)
|
||||
} else {
|
||||
assert.Fail(t, "blank is not stored")
|
||||
return
|
||||
}
|
||||
|
||||
if wheezy, ok := datastore.layers["wheezy"]; ok {
|
||||
assert.Equal(t, wheezy.ProcessedBy.Detectors, Processors.Detectors)
|
||||
assert.Equal(t, wheezy.ProcessedBy.Listers, Processors.Listers)
|
||||
assert.Equal(t, wheezy.Namespaces, []database.Namespace{{Name: "debian:7", VersionFormat: dpkg.ParserName}})
|
||||
assert.Len(t, wheezy.Features, 52)
|
||||
} else {
|
||||
assert.Fail(t, "wheezy is not stored")
|
||||
return
|
||||
}
|
||||
|
||||
if jessie, ok := datastore.layers["jessie"]; ok {
|
||||
assert.Equal(t, jessie.ProcessedBy.Detectors, Processors.Detectors)
|
||||
assert.Equal(t, jessie.ProcessedBy.Listers, Processors.Listers)
|
||||
assert.Equal(t, jessie.Namespaces, []database.Namespace{{Name: "debian:8", VersionFormat: dpkg.ParserName}})
|
||||
assert.Len(t, jessie.Features, 74)
|
||||
} else {
|
||||
assert.Fail(t, "jessie is not stored")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// TestUpgradeClair checks if a clair is upgraded and certain ancestry's
|
||||
// features should not change. We assume that Clair should only upgrade
|
||||
func TestClairUpgrade(t *testing.T) {
|
||||
_, f, _, _ := runtime.Caller(0)
|
||||
testDataPath := filepath.Join(filepath.Dir(f)) + "/testdata/DistUpgrade/"
|
||||
|
||||
datastore := newMockDatastore()
|
||||
|
||||
// suppose there are two ancestries.
|
||||
layers := []LayerRequest{
|
||||
{Hash: "blank", Path: testDataPath + "blank.tar.gz"},
|
||||
{Hash: "wheezy", Path: testDataPath + "wheezy.tar.gz"},
|
||||
{Hash: "jessie", Path: testDataPath + "jessie.tar.gz"},
|
||||
}
|
||||
|
||||
layers2 := []LayerRequest{
|
||||
{Hash: "blank", Path: testDataPath + "blank.tar.gz"},
|
||||
{Hash: "wheezy", Path: testDataPath + "wheezy.tar.gz"},
|
||||
}
|
||||
|
||||
// Suppose user scan an ancestry with an old instance of Clair.
|
||||
Processors = database.Processors{
|
||||
Detectors: []string{"os-release"},
|
||||
Listers: []string{"rpm"},
|
||||
}
|
||||
|
||||
assert.Nil(t, ProcessAncestry(datastore, "Docker", "Mock", layers))
|
||||
assert.Len(t, datastore.ancestry["Mock"].Features, 0)
|
||||
|
||||
assert.Nil(t, ProcessAncestry(datastore, "Docker", "Mock2", layers2))
|
||||
assert.Len(t, datastore.ancestry["Mock2"].Features, 0)
|
||||
|
||||
// Clair is upgraded to use a new namespace detector. The expected
|
||||
// behavior is that all layers will be rescanned with "apt-sources" and
|
||||
// the ancestry's features are recalculated.
|
||||
Processors = database.Processors{
|
||||
Detectors: []string{"os-release", "apt-sources"},
|
||||
Listers: []string{"rpm"},
|
||||
}
|
||||
|
||||
// Even though Clair processors are upgraded, the ancestry's features should
|
||||
// not be upgraded without posting the ancestry to Clair again.
|
||||
assert.Nil(t, ProcessAncestry(datastore, "Docker", "Mock", layers))
|
||||
assert.Len(t, datastore.ancestry["Mock"].Features, 0)
|
||||
|
||||
// Clair is upgraded to use a new feature lister. The expected behavior is
|
||||
// that all layers will be rescanned with "dpkg" and the ancestry's features
|
||||
// are invalidated and recalculated.
|
||||
Processors = database.Processors{
|
||||
Detectors: []string{"os-release", "apt-sources"},
|
||||
Listers: []string{"rpm", "dpkg"},
|
||||
}
|
||||
|
||||
assert.Nil(t, ProcessAncestry(datastore, "Docker", "Mock", layers))
|
||||
assert.Len(t, datastore.ancestry["Mock"].Features, 74)
|
||||
assert.Nil(t, ProcessAncestry(datastore, "Docker", "Mock2", layers2))
|
||||
assert.Len(t, datastore.ancestry["Mock2"].Features, 52)
|
||||
|
||||
// check the namespaces are correct
|
||||
for _, f := range datastore.ancestry["Mock"].Features {
|
||||
if !assert.NotEqual(t, database.Namespace{}, f.Namespace) {
|
||||
assert.Fail(t, "Every feature should have a namespace attached")
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range datastore.ancestry["Mock2"].Features {
|
||||
if !assert.NotEqual(t, database.Namespace{}, f.Namespace) {
|
||||
assert.Fail(t, "Every feature should have a namespace attached")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestMultipleNamespaces tests computing ancestry features
|
||||
func TestComputeAncestryFeatures(t *testing.T) {
|
||||
vf1 := "format 1"
|
||||
vf2 := "format 2"
|
||||
|
||||
ns1a := database.Namespace{
|
||||
Name: "namespace 1:a",
|
||||
VersionFormat: vf1,
|
||||
}
|
||||
|
||||
ns1b := database.Namespace{
|
||||
Name: "namespace 1:b",
|
||||
VersionFormat: vf1,
|
||||
}
|
||||
|
||||
ns2a := database.Namespace{
|
||||
Name: "namespace 2:a",
|
||||
VersionFormat: vf2,
|
||||
}
|
||||
|
||||
ns2b := database.Namespace{
|
||||
Name: "namespace 2:b",
|
||||
VersionFormat: vf2,
|
||||
}
|
||||
|
||||
f1 := database.Feature{
|
||||
Name: "feature 1",
|
||||
Version: "0.1",
|
||||
VersionFormat: vf1,
|
||||
}
|
||||
|
||||
f2 := database.Feature{
|
||||
Name: "feature 2",
|
||||
Version: "0.2",
|
||||
VersionFormat: vf1,
|
||||
}
|
||||
|
||||
f3 := database.Feature{
|
||||
Name: "feature 1",
|
||||
Version: "0.3",
|
||||
VersionFormat: vf2,
|
||||
}
|
||||
|
||||
f4 := database.Feature{
|
||||
Name: "feature 2",
|
||||
Version: "0.3",
|
||||
VersionFormat: vf2,
|
||||
}
|
||||
|
||||
// Suppose Clair is watching two files for namespaces one containing ns1
|
||||
// changes e.g. os-release and the other one containing ns2 changes e.g.
|
||||
// node.
|
||||
blank := database.LayerWithContent{Layer: database.Layer{Hash: "blank"}}
|
||||
initNS1a := database.LayerWithContent{
|
||||
Layer: database.Layer{Hash: "init ns1a"},
|
||||
Namespaces: []database.Namespace{ns1a},
|
||||
Features: []database.Feature{f1, f2},
|
||||
}
|
||||
|
||||
upgradeNS2b := database.LayerWithContent{
|
||||
Layer: database.Layer{Hash: "upgrade ns2b"},
|
||||
Namespaces: []database.Namespace{ns2b},
|
||||
}
|
||||
|
||||
upgradeNS1b := database.LayerWithContent{
|
||||
Layer: database.Layer{Hash: "upgrade ns1b"},
|
||||
Namespaces: []database.Namespace{ns1b},
|
||||
Features: []database.Feature{f1, f2},
|
||||
}
|
||||
|
||||
initNS2a := database.LayerWithContent{
|
||||
Layer: database.Layer{Hash: "init ns2a"},
|
||||
Namespaces: []database.Namespace{ns2a},
|
||||
Features: []database.Feature{f3, f4},
|
||||
}
|
||||
|
||||
removeF2 := database.LayerWithContent{
|
||||
Layer: database.Layer{Hash: "remove f2"},
|
||||
Features: []database.Feature{f1},
|
||||
}
|
||||
|
||||
// blank -> ns1:a, f1 f2 (init)
|
||||
// -> f1 (feature change)
|
||||
// -> ns2:a, f3, f4 (init ns2a)
|
||||
// -> ns2:b (ns2 upgrade without changing features)
|
||||
// -> blank (empty)
|
||||
// -> ns1:b, f1 f2 (ns1 upgrade and add f2)
|
||||
// -> f1 (remove f2)
|
||||
// -> blank (empty)
|
||||
|
||||
layers := []database.LayerWithContent{
|
||||
blank,
|
||||
initNS1a,
|
||||
removeF2,
|
||||
initNS2a,
|
||||
upgradeNS2b,
|
||||
blank,
|
||||
upgradeNS1b,
|
||||
removeF2,
|
||||
blank,
|
||||
}
|
||||
|
||||
expected := map[database.NamespacedFeature]bool{
|
||||
{
|
||||
Feature: f1,
|
||||
Namespace: ns1a,
|
||||
}: false,
|
||||
{
|
||||
Feature: f3,
|
||||
Namespace: ns2a,
|
||||
}: false,
|
||||
{
|
||||
Feature: f4,
|
||||
Namespace: ns2a,
|
||||
}: false,
|
||||
}
|
||||
|
||||
features, err := computeAncestryFeatures(layers)
|
||||
assert.Nil(t, err)
|
||||
for _, f := range features {
|
||||
if assert.Contains(t, expected, f) {
|
||||
if assert.False(t, expected[f]) {
|
||||
expected[f] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for f, visited := range expected {
|
||||
assert.True(t, visited, "expected feature is missing : "+f.Namespace.Name+":"+f.Name)
|
||||
}
|
||||
}
|
1
vendor/github.com/docker/cli/MAINTAINERS
generated
vendored
1
vendor/github.com/docker/cli/MAINTAINERS
generated
vendored
|
@ -29,6 +29,7 @@
|
|||
"justincormack",
|
||||
"silvin-lubecki",
|
||||
"stevvooe",
|
||||
"thajeztah",
|
||||
"tibor",
|
||||
"tonistiigi",
|
||||
"vdemeester",
|
||||
|
|
4
vendor/github.com/docker/cli/cli/config/config_test.go
generated
vendored
4
vendor/github.com/docker/cli/cli/config/config_test.go
generated
vendored
|
@ -12,9 +12,9 @@ import (
|
|||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/config/credentials"
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"github.com/pkg/errors"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
func setupConfigDir(t *testing.T) (string, func()) {
|
||||
|
|
4
vendor/github.com/docker/cli/cli/config/configfile/file_test.go
generated
vendored
4
vendor/github.com/docker/cli/cli/config/configfile/file_test.go
generated
vendored
|
@ -6,8 +6,8 @@ import (
|
|||
|
||||
"github.com/docker/cli/cli/config/credentials"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
func TestEncodeAuth(t *testing.T) {
|
||||
|
|
4
vendor/github.com/docker/cli/cli/config/credentials/file_store_test.go
generated
vendored
4
vendor/github.com/docker/cli/cli/config/credentials/file_store_test.go
generated
vendored
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
type fakeStore struct {
|
||||
|
|
4
vendor/github.com/docker/cli/cli/config/credentials/native_store_test.go
generated
vendored
4
vendor/github.com/docker/cli/cli/config/credentials/native_store_test.go
generated
vendored
|
@ -11,9 +11,9 @@ import (
|
|||
"github.com/docker/docker-credential-helpers/client"
|
||||
"github.com/docker/docker-credential-helpers/credentials"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"github.com/pkg/errors"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
2
vendor/github.com/docker/cli/cli/required_test.go
generated
vendored
2
vendor/github.com/docker/cli/cli/required_test.go
generated
vendored
|
@ -5,8 +5,8 @@ import (
|
|||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
"github.com/spf13/cobra"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
func TestRequiresNoArgs(t *testing.T) {
|
||||
|
|
4
vendor/github.com/docker/cli/opts/duration_test.go
generated
vendored
4
vendor/github.com/docker/cli/opts/duration_test.go
generated
vendored
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
func TestDurationOptString(t *testing.T) {
|
||||
|
|
4
vendor/github.com/docker/cli/opts/mount_test.go
generated
vendored
4
vendor/github.com/docker/cli/opts/mount_test.go
generated
vendored
|
@ -5,8 +5,8 @@ import (
|
|||
"testing"
|
||||
|
||||
mounttypes "github.com/docker/docker/api/types/mount"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
func TestMountOptString(t *testing.T) {
|
||||
|
|
4
vendor/github.com/docker/cli/opts/network_test.go
generated
vendored
4
vendor/github.com/docker/cli/opts/network_test.go
generated
vendored
|
@ -3,8 +3,8 @@ package opts
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
func TestNetworkOptLegacySyntax(t *testing.T) {
|
||||
|
|
4
vendor/github.com/docker/cli/opts/port_test.go
generated
vendored
4
vendor/github.com/docker/cli/opts/port_test.go
generated
vendored
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
func TestPortOptValidSimpleSyntax(t *testing.T) {
|
||||
|
|
4
vendor/github.com/docker/cli/opts/quotedstring_test.go
generated
vendored
4
vendor/github.com/docker/cli/opts/quotedstring_test.go
generated
vendored
|
@ -3,8 +3,8 @@ package opts
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
func TestQuotedStringSetWithQuotes(t *testing.T) {
|
||||
|
|
4
vendor/github.com/docker/cli/opts/secret_test.go
generated
vendored
4
vendor/github.com/docker/cli/opts/secret_test.go
generated
vendored
|
@ -4,8 +4,8 @@ import (
|
|||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
)
|
||||
|
||||
func TestSecretOptionsSimple(t *testing.T) {
|
||||
|
|
35
vendor/github.com/docker/cli/vendor.conf
generated
vendored
35
vendor/github.com/docker/cli/vendor.conf
generated
vendored
|
@ -6,7 +6,7 @@ github.com/coreos/etcd v3.2.1
|
|||
github.com/cpuguy83/go-md2man v1.0.8
|
||||
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
|
||||
github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5
|
||||
github.com/docker/docker d37f5c6bdf788a6cb82c07fb707e31a240eff5f9
|
||||
github.com/docker/docker 162ba6016def672690ee4a1f3978368853a1e149
|
||||
github.com/docker/docker-credential-helpers 3c90bd29a46b943b2a9842987b58fb91a7c1819b
|
||||
# the docker/go package contains a customized version of canonical/json
|
||||
# and is used by Notary. The package is periodically rebased on current Go versions.
|
||||
|
@ -15,30 +15,31 @@ github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6
|
|||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||
github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
|
||||
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
|
||||
github.com/docker/swarmkit bd69f6e8e301645afd344913fa1ede53a0a111fb
|
||||
github.com/docker/swarmkit edd5641391926a50bc5f7040e20b7efc05003c26
|
||||
github.com/emicklei/go-restful ff4f55a206334ef123e4f79bbf348980da81ca46
|
||||
github.com/emicklei/go-restful-swagger12 dcef7f55730566d41eae5db10e7d6981829720f6
|
||||
github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff
|
||||
github.com/ghodss/yaml 0ca9ea5df5451ffdf184b4428c902747c2c11cd7
|
||||
github.com/gogo/protobuf v0.4
|
||||
github.com/golang/glog 44145f04b68cf362d9c4df2182967c2275eaefed
|
||||
github.com/gogo/protobuf v1.0.0
|
||||
github.com/google/go-cmp v0.2.0
|
||||
github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4
|
||||
github.com/golang/glog 44145f04b68cf362d9c4df2182967c2275eaefed
|
||||
github.com/golang/protobuf v1.1.0
|
||||
github.com/google/btree 316fb6d3f031ae8f4d457c6c5186b9e3ded70435
|
||||
github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c
|
||||
github.com/googleapis/gnostic e4f56557df6250e1945ee6854f181ce4e1c2c646
|
||||
github.com/gorilla/context v1.1
|
||||
github.com/gorilla/mux v1.1
|
||||
github.com/gotestyourself/gotestyourself cf3a5ab914a2efa8bc838d09f5918c1d44d02909
|
||||
gotest.tools v2.1.0
|
||||
github.com/go-openapi/jsonpointer 46af16f9f7b149af66e5d1bd010e3574dc06de98
|
||||
github.com/go-openapi/jsonreference 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272
|
||||
github.com/go-openapi/spec 6aced65f8501fe1217321abf0749d354824ba2ff
|
||||
github.com/go-openapi/swag 1d0bd113de87027671077d3c71eb3ac5d7dbba72
|
||||
github.com/gregjones/httpcache c1f8028e62adb3d518b823a2f8e6a95c38bdd3aa
|
||||
github.com/grpc-ecosystem/grpc-gateway 1a03ca3bad1e1ebadaedd3abb76bc58d4ac8143b
|
||||
github.com/hashicorp/golang-lru 0a025b7e63adc15a622f29b0b2c4c3848243bbf6
|
||||
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
||||
github.com/hashicorp/golang-lru a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
|
||||
github.com/howeyc/gopass 3ca23474a7c7203e0a0a070fd33508f6efdb9b3d
|
||||
github.com/imdario/mergo 9d5f1277e9a8ed20c3684bda8fde67c05628518c # v0.3.4
|
||||
github.com/imdario/mergo v0.3.5
|
||||
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
||||
github.com/juju/ratelimit 5b9ff866471762aa2ab2dced63c9fb6f53921342
|
||||
github.com/json-iterator/go 6240e1e7983a85228f7fd9c3e1b6932d46ec58e2
|
||||
|
@ -48,15 +49,15 @@ github.com/matttproud/golang_protobuf_extensions v1.0.0
|
|||
github.com/Microsoft/go-winio v0.4.6
|
||||
github.com/miekg/pkcs11 5f6e0d0dad6f472df908c8e968a98ef00c9224bb
|
||||
github.com/mitchellh/mapstructure f3009df150dadf309fdee4a54ed65c124afad715
|
||||
github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8
|
||||
github.com/moby/buildkit 43e758232a0ac7d50c6a11413186e16684fc1e4f
|
||||
github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b
|
||||
github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c https://github.com/ijc25/Gotty
|
||||
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc 4fc53a81fb7c994640722ac585fa9ca548971871
|
||||
github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340
|
||||
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
||||
github.com/peterbourgon/diskv 5f041e8faa004a95c88a202771f4cc3e991971e6
|
||||
github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
github.com/prometheus/client_golang 52437c81da6b127a9925d17eb3a382a2e5fd395e
|
||||
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
|
||||
github.com/prometheus/common ebdfc6da46522d58825777cf1f90490a5b1ef1d8
|
||||
|
@ -69,18 +70,18 @@ github.com/sirupsen/logrus v1.0.3
|
|||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.1
|
||||
github.com/theupdateframework/notary v0.6.1
|
||||
github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2
|
||||
github.com/tonistiigi/fsutil dc68c74458923f357474a9178bd198aa3ed11a5f
|
||||
github.com/xeipuuv/gojsonpointer e0fe6f68307607d540ed8eac07a342c33fa1b54a
|
||||
github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45
|
||||
github.com/xeipuuv/gojsonschema 93e72a773fade158921402d6a24c819b48aba29d
|
||||
golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
|
||||
golang.org/x/net 5561cd9b4330353950f399814f427425c0a26fd2
|
||||
golang.org/x/crypto 1a580b3eff7814fc9b40602fd35256c63b50f491
|
||||
golang.org/x/net 0ed95abb35c445290478a5348a7b38bb154135fd
|
||||
golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5
|
||||
golang.org/x/sys 37707fdb30a5b38865cfb95e5aab41707daec7fd
|
||||
golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756
|
||||
golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
|
||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||
google.golang.org/grpc v1.3.0
|
||||
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
|
||||
google.golang.org/grpc v1.12.0
|
||||
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
||||
gopkg.in/yaml.v2 4c78c975fe7c825c6d1466c42be594d1d6f3aba6
|
||||
k8s.io/api kubernetes-1.8.2
|
||||
|
|
1
vendor/github.com/docker/docker-ce/components/cli/MAINTAINERS
generated
vendored
1
vendor/github.com/docker/docker-ce/components/cli/MAINTAINERS
generated
vendored
|
@ -29,6 +29,7 @@
|
|||
"justincormack",
|
||||
"silvin-lubecki",
|
||||
"stevvooe",
|
||||
"thajeztah",
|
||||
"tibor",
|
||||
"tonistiigi",
|
||||
"vdemeester",
|
||||
|
|
32
vendor/github.com/docker/docker-ce/components/cli/vendor.conf
generated
vendored
32
vendor/github.com/docker/docker-ce/components/cli/vendor.conf
generated
vendored
|
@ -6,7 +6,7 @@ github.com/coreos/etcd v3.2.1
|
|||
github.com/cpuguy83/go-md2man v1.0.8
|
||||
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
|
||||
github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5
|
||||
github.com/docker/docker d37f5c6bdf788a6cb82c07fb707e31a240eff5f9
|
||||
github.com/docker/docker 162ba6016def672690ee4a1f3978368853a1e149
|
||||
github.com/docker/docker-credential-helpers 3c90bd29a46b943b2a9842987b58fb91a7c1819b
|
||||
# the docker/go package contains a customized version of canonical/json
|
||||
# and is used by Notary. The package is periodically rebased on current Go versions.
|
||||
|
@ -15,15 +15,15 @@ github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6
|
|||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||
github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
|
||||
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
|
||||
github.com/docker/swarmkit bd69f6e8e301645afd344913fa1ede53a0a111fb
|
||||
github.com/docker/swarmkit edd5641391926a50bc5f7040e20b7efc05003c26
|
||||
github.com/emicklei/go-restful ff4f55a206334ef123e4f79bbf348980da81ca46
|
||||
github.com/emicklei/go-restful-swagger12 dcef7f55730566d41eae5db10e7d6981829720f6
|
||||
github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff
|
||||
github.com/ghodss/yaml 0ca9ea5df5451ffdf184b4428c902747c2c11cd7
|
||||
github.com/gogo/protobuf v0.4
|
||||
github.com/golang/glog 44145f04b68cf362d9c4df2182967c2275eaefed
|
||||
github.com/gogo/protobuf v1.0.0
|
||||
github.com/google/go-cmp v0.2.0
|
||||
github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4
|
||||
github.com/golang/glog 44145f04b68cf362d9c4df2182967c2275eaefed
|
||||
github.com/golang/protobuf v1.1.0
|
||||
github.com/google/btree 316fb6d3f031ae8f4d457c6c5186b9e3ded70435
|
||||
github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c
|
||||
github.com/googleapis/gnostic e4f56557df6250e1945ee6854f181ce4e1c2c646
|
||||
|
@ -36,9 +36,10 @@ github.com/go-openapi/spec 6aced65f8501fe1217321abf0749d354824ba2ff
|
|||
github.com/go-openapi/swag 1d0bd113de87027671077d3c71eb3ac5d7dbba72
|
||||
github.com/gregjones/httpcache c1f8028e62adb3d518b823a2f8e6a95c38bdd3aa
|
||||
github.com/grpc-ecosystem/grpc-gateway 1a03ca3bad1e1ebadaedd3abb76bc58d4ac8143b
|
||||
github.com/hashicorp/golang-lru 0a025b7e63adc15a622f29b0b2c4c3848243bbf6
|
||||
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
||||
github.com/hashicorp/golang-lru a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
|
||||
github.com/howeyc/gopass 3ca23474a7c7203e0a0a070fd33508f6efdb9b3d
|
||||
github.com/imdario/mergo 9d5f1277e9a8ed20c3684bda8fde67c05628518c # v0.3.4
|
||||
github.com/imdario/mergo v0.3.5
|
||||
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
||||
github.com/juju/ratelimit 5b9ff866471762aa2ab2dced63c9fb6f53921342
|
||||
github.com/json-iterator/go 6240e1e7983a85228f7fd9c3e1b6932d46ec58e2
|
||||
|
@ -48,12 +49,13 @@ github.com/matttproud/golang_protobuf_extensions v1.0.0
|
|||
github.com/Microsoft/go-winio v0.4.6
|
||||
github.com/miekg/pkcs11 5f6e0d0dad6f472df908c8e968a98ef00c9224bb
|
||||
github.com/mitchellh/mapstructure f3009df150dadf309fdee4a54ed65c124afad715
|
||||
github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8
|
||||
github.com/moby/buildkit 43e758232a0ac7d50c6a11413186e16684fc1e4f
|
||||
github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b
|
||||
github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c https://github.com/ijc25/Gotty
|
||||
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc 4fc53a81fb7c994640722ac585fa9ca548971871
|
||||
github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340
|
||||
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
||||
github.com/peterbourgon/diskv 5f041e8faa004a95c88a202771f4cc3e991971e6
|
||||
github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
|
@ -69,18 +71,18 @@ github.com/sirupsen/logrus v1.0.3
|
|||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.1
|
||||
github.com/theupdateframework/notary v0.6.1
|
||||
github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2
|
||||
github.com/tonistiigi/fsutil dc68c74458923f357474a9178bd198aa3ed11a5f
|
||||
github.com/xeipuuv/gojsonpointer e0fe6f68307607d540ed8eac07a342c33fa1b54a
|
||||
github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45
|
||||
github.com/xeipuuv/gojsonschema 93e72a773fade158921402d6a24c819b48aba29d
|
||||
golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
|
||||
golang.org/x/net 5561cd9b4330353950f399814f427425c0a26fd2
|
||||
golang.org/x/crypto 1a580b3eff7814fc9b40602fd35256c63b50f491
|
||||
golang.org/x/net 0ed95abb35c445290478a5348a7b38bb154135fd
|
||||
golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5
|
||||
golang.org/x/sys 37707fdb30a5b38865cfb95e5aab41707daec7fd
|
||||
golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756
|
||||
golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
|
||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||
google.golang.org/grpc v1.3.0
|
||||
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
|
||||
google.golang.org/grpc v1.12.0
|
||||
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
||||
gopkg.in/yaml.v2 4c78c975fe7c825c6d1466c42be594d1d6f3aba6
|
||||
k8s.io/api kubernetes-1.8.2
|
||||
|
|
4
vendor/github.com/docker/docker/Dockerfile
generated
vendored
4
vendor/github.com/docker/docker/Dockerfile
generated
vendored
|
@ -24,10 +24,10 @@
|
|||
# the case. Therefore, you don't have to disable it anymore.
|
||||
#
|
||||
|
||||
FROM golang:1.10.2 AS base
|
||||
FROM golang:1.10.3 AS base
|
||||
# FIXME(vdemeester) this is kept for other script depending on it to not fail right away
|
||||
# Remove this once the other scripts uses something else to detect the version
|
||||
ENV GO_VERSION 1.10.2
|
||||
ENV GO_VERSION 1.10.3
|
||||
# allow replacing httpredir or deb mirror
|
||||
ARG APT_MIRROR=deb.debian.org
|
||||
RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
|
||||
|
|
2
vendor/github.com/docker/docker/Dockerfile.e2e
generated
vendored
2
vendor/github.com/docker/docker/Dockerfile.e2e
generated
vendored
|
@ -1,5 +1,5 @@
|
|||
## Step 1: Build tests
|
||||
FROM golang:1.10.2-alpine3.7 as builder
|
||||
FROM golang:1.10.3-alpine3.7 as builder
|
||||
|
||||
RUN apk add --update \
|
||||
bash \
|
||||
|
|
2
vendor/github.com/docker/docker/Dockerfile.simple
generated
vendored
2
vendor/github.com/docker/docker/Dockerfile.simple
generated
vendored
|
@ -42,7 +42,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
# will need updating, to avoid errors. Ping #docker-maintainers on IRC
|
||||
# with a heads-up.
|
||||
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
|
||||
ENV GO_VERSION 1.10.2
|
||||
ENV GO_VERSION 1.10.3
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
||||
|
|
2
vendor/github.com/docker/docker/Dockerfile.windows
generated
vendored
2
vendor/github.com/docker/docker/Dockerfile.windows
generated
vendored
|
@ -161,7 +161,7 @@ SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPref
|
|||
# Environment variable notes:
|
||||
# - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
|
||||
# - FROM_DOCKERFILE is used for detection of building within a container.
|
||||
ENV GO_VERSION=1.10.2 `
|
||||
ENV GO_VERSION=1.10.3 `
|
||||
GIT_VERSION=2.11.1 `
|
||||
GOPATH=C:\go `
|
||||
FROM_DOCKERFILE=1
|
||||
|
|
1
vendor/github.com/docker/docker/MAINTAINERS
generated
vendored
1
vendor/github.com/docker/docker/MAINTAINERS
generated
vendored
|
@ -40,6 +40,7 @@
|
|||
"mlaventure",
|
||||
"runcom",
|
||||
"stevvooe",
|
||||
"thajeztah",
|
||||
"tianon",
|
||||
"tibor",
|
||||
"tonistiigi",
|
||||
|
|
14
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
14
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
|
@ -772,6 +772,16 @@ definitions:
|
|||
- "default"
|
||||
- "process"
|
||||
- "hyperv"
|
||||
MaskedPaths:
|
||||
type: "array"
|
||||
description: "The list of paths to be masked inside the container (this overrides the default set of paths)"
|
||||
items:
|
||||
type: "string"
|
||||
ReadonlyPaths:
|
||||
type: "array"
|
||||
description: "The list of paths to be set as read-only inside the container (this overrides the default set of paths)"
|
||||
items:
|
||||
type: "string"
|
||||
|
||||
ContainerConfig:
|
||||
description: "Configuration for a container that is portable between hosts"
|
||||
|
@ -2711,6 +2721,10 @@ definitions:
|
|||
- "default"
|
||||
- "process"
|
||||
- "hyperv"
|
||||
Init:
|
||||
description: "Run an init inside the container that forwards signals and reaps processes. This field is omitted if empty, and the default (as configured on the daemon) is used."
|
||||
type: "boolean"
|
||||
x-nullable: true
|
||||
NetworkAttachmentSpec:
|
||||
description: |
|
||||
Read-only spec type for non-swarm containers attached to swarm overlay
|
||||
|
|
6
vendor/github.com/docker/docker/api/types/container/host_config.go
generated
vendored
6
vendor/github.com/docker/docker/api/types/container/host_config.go
generated
vendored
|
@ -401,6 +401,12 @@ type HostConfig struct {
|
|||
// Mounts specs used by the container
|
||||
Mounts []mount.Mount `json:",omitempty"`
|
||||
|
||||
// MaskedPaths is the list of paths to be masked inside the container (this overrides the default set of paths)
|
||||
MaskedPaths []string
|
||||
|
||||
// ReadonlyPaths is the list of paths to be set as read-only inside the container (this overrides the default set of paths)
|
||||
ReadonlyPaths []string
|
||||
|
||||
// Run a custom init inside the container, if null, use the daemon's configured settings
|
||||
Init *bool `json:",omitempty"`
|
||||
}
|
||||
|
|
1
vendor/github.com/docker/docker/api/types/swarm/container.go
generated
vendored
1
vendor/github.com/docker/docker/api/types/swarm/container.go
generated
vendored
|
@ -55,6 +55,7 @@ type ContainerSpec struct {
|
|||
User string `json:",omitempty"`
|
||||
Groups []string `json:",omitempty"`
|
||||
Privileges *Privileges `json:",omitempty"`
|
||||
Init *bool `json:",omitempty"`
|
||||
StopSignal string `json:",omitempty"`
|
||||
TTY bool `json:",omitempty"`
|
||||
OpenStdin bool `json:",omitempty"`
|
||||
|
|
2
vendor/github.com/docker/docker/client/client_test.go
generated
vendored
2
vendor/github.com/docker/docker/client/client_test.go
generated
vendored
|
@ -193,7 +193,7 @@ func TestNewEnvClientSetsDefaultVersion(t *testing.T) {
|
|||
// TestNegotiateAPIVersionEmpty asserts that client.Client can
|
||||
// negotiate a compatible APIVersion when omitted
|
||||
func TestNegotiateAPIVersionEmpty(t *testing.T) {
|
||||
defer env.PatchAll(t, map[string]string{"DOCKER_API_VERSION": ""})
|
||||
defer env.PatchAll(t, map[string]string{"DOCKER_API_VERSION": ""})()
|
||||
|
||||
client, err := NewEnvClient()
|
||||
assert.NilError(t, err)
|
||||
|
|
105
vendor/github.com/docker/docker/client/hijack.go
generated
vendored
105
vendor/github.com/docker/docker/client/hijack.go
generated
vendored
|
@ -9,7 +9,6 @@ import (
|
|||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
|
@ -17,21 +16,6 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// tlsClientCon holds tls information and a dialed connection.
|
||||
type tlsClientCon struct {
|
||||
*tls.Conn
|
||||
rawConn net.Conn
|
||||
}
|
||||
|
||||
func (c *tlsClientCon) CloseWrite() error {
|
||||
// Go standard tls.Conn doesn't provide the CloseWrite() method so we do it
|
||||
// on its underlying connection.
|
||||
if conn, ok := c.rawConn.(types.CloseWriter); ok {
|
||||
return conn.CloseWrite()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// postHijacked sends a POST request and hijacks the connection.
|
||||
func (cli *Client) postHijacked(ctx context.Context, path string, query url.Values, body interface{}, headers map[string][]string) (types.HijackedResponse, error) {
|
||||
bodyEncoded, err := encodeData(body)
|
||||
|
@ -54,96 +38,9 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
|
|||
return types.HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn)}, err
|
||||
}
|
||||
|
||||
func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) {
|
||||
return tlsDialWithDialer(new(net.Dialer), network, addr, config)
|
||||
}
|
||||
|
||||
// We need to copy Go's implementation of tls.Dial (pkg/cryptor/tls/tls.go) in
|
||||
// order to return our custom tlsClientCon struct which holds both the tls.Conn
|
||||
// object _and_ its underlying raw connection. The rationale for this is that
|
||||
// we need to be able to close the write end of the connection when attaching,
|
||||
// which tls.Conn does not provide.
|
||||
func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Config) (net.Conn, error) {
|
||||
// We want the Timeout and Deadline values from dialer to cover the
|
||||
// whole process: TCP connection and TLS handshake. This means that we
|
||||
// also need to start our own timers now.
|
||||
timeout := dialer.Timeout
|
||||
|
||||
if !dialer.Deadline.IsZero() {
|
||||
deadlineTimeout := time.Until(dialer.Deadline)
|
||||
if timeout == 0 || deadlineTimeout < timeout {
|
||||
timeout = deadlineTimeout
|
||||
}
|
||||
}
|
||||
|
||||
var errChannel chan error
|
||||
|
||||
if timeout != 0 {
|
||||
errChannel = make(chan error, 2)
|
||||
time.AfterFunc(timeout, func() {
|
||||
errChannel <- errors.New("")
|
||||
})
|
||||
}
|
||||
|
||||
proxyDialer, err := sockets.DialerFromEnvironment(dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawConn, err := proxyDialer.Dial(network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// When we set up a TCP connection for hijack, there could be long periods
|
||||
// of inactivity (a long running command with no output) that in certain
|
||||
// network setups may cause ECONNTIMEOUT, leaving the client in an unknown
|
||||
// state. Setting TCP KeepAlive on the socket connection will prohibit
|
||||
// ECONNTIMEOUT unless the socket connection truly is broken
|
||||
if tcpConn, ok := rawConn.(*net.TCPConn); ok {
|
||||
tcpConn.SetKeepAlive(true)
|
||||
tcpConn.SetKeepAlivePeriod(30 * time.Second)
|
||||
}
|
||||
|
||||
colonPos := strings.LastIndex(addr, ":")
|
||||
if colonPos == -1 {
|
||||
colonPos = len(addr)
|
||||
}
|
||||
hostname := addr[:colonPos]
|
||||
|
||||
// If no ServerName is set, infer the ServerName
|
||||
// from the hostname we're connecting to.
|
||||
if config.ServerName == "" {
|
||||
// Make a copy to avoid polluting argument or default.
|
||||
config = tlsConfigClone(config)
|
||||
config.ServerName = hostname
|
||||
}
|
||||
|
||||
conn := tls.Client(rawConn, config)
|
||||
|
||||
if timeout == 0 {
|
||||
err = conn.Handshake()
|
||||
} else {
|
||||
go func() {
|
||||
errChannel <- conn.Handshake()
|
||||
}()
|
||||
|
||||
err = <-errChannel
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
rawConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This is Docker difference with standard's crypto/tls package: returned a
|
||||
// wrapper which holds both the TLS and raw connections.
|
||||
return &tlsClientCon{conn, rawConn}, nil
|
||||
}
|
||||
|
||||
func dial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
|
||||
if tlsConfig != nil && proto != "unix" && proto != "npipe" {
|
||||
// Notice this isn't Go standard's tls.Dial function
|
||||
return tlsDial(proto, addr, tlsConfig)
|
||||
return tls.Dial(proto, addr, tlsConfig)
|
||||
}
|
||||
if proto == "npipe" {
|
||||
return sockets.DialPipe(addr, 32*time.Second)
|
||||
|
|
103
vendor/github.com/docker/docker/client/hijack_test.go
generated
vendored
Normal file
103
vendor/github.com/docker/docker/client/hijack_test.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func TestTLSCloseWriter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var chErr chan error
|
||||
ts := &httptest.Server{Config: &http.Server{Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
chErr = make(chan error, 1)
|
||||
defer close(chErr)
|
||||
if err := httputils.ParseForm(req); err != nil {
|
||||
chErr <- errors.Wrap(err, "error parsing form")
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
r, rw, err := httputils.HijackConnection(w)
|
||||
if err != nil {
|
||||
chErr <- errors.Wrap(err, "error hijacking connection")
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
fmt.Fprint(rw, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\n")
|
||||
|
||||
buf := make([]byte, 5)
|
||||
_, err = r.Read(buf)
|
||||
if err != nil {
|
||||
chErr <- errors.Wrap(err, "error reading from client")
|
||||
return
|
||||
}
|
||||
_, err = rw.Write(buf)
|
||||
if err != nil {
|
||||
chErr <- errors.Wrap(err, "error writing to client")
|
||||
return
|
||||
}
|
||||
})}}
|
||||
|
||||
var (
|
||||
l net.Listener
|
||||
err error
|
||||
)
|
||||
for i := 1024; i < 10000; i++ {
|
||||
l, err = net.Listen("tcp4", fmt.Sprintf("127.0.0.1:%d", i))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.Assert(t, err)
|
||||
|
||||
ts.Listener = l
|
||||
defer l.Close()
|
||||
|
||||
defer func() {
|
||||
if chErr != nil {
|
||||
assert.Assert(t, <-chErr)
|
||||
}
|
||||
}()
|
||||
|
||||
ts.StartTLS()
|
||||
defer ts.Close()
|
||||
|
||||
serverURL, err := url.Parse(ts.URL)
|
||||
assert.Assert(t, err)
|
||||
|
||||
client, err := NewClient("tcp://"+serverURL.Host, "", ts.Client(), nil)
|
||||
assert.Assert(t, err)
|
||||
|
||||
resp, err := client.postHijacked(context.Background(), "/asdf", url.Values{}, nil, map[string][]string{"Content-Type": {"text/plain"}})
|
||||
assert.Assert(t, err)
|
||||
defer resp.Close()
|
||||
|
||||
if _, ok := resp.Conn.(types.CloseWriter); !ok {
|
||||
t.Fatal("tls conn did not implement the CloseWrite interface")
|
||||
}
|
||||
|
||||
_, err = resp.Conn.Write([]byte("hello"))
|
||||
assert.Assert(t, err)
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Reader)
|
||||
assert.Assert(t, err)
|
||||
assert.Assert(t, string(b) == "hello")
|
||||
assert.Assert(t, resp.CloseWrite())
|
||||
|
||||
// This should error since writes are closed
|
||||
_, err = resp.Conn.Write([]byte("no"))
|
||||
assert.Assert(t, err != nil)
|
||||
}
|
11
vendor/github.com/docker/docker/client/tlsconfig_clone.go
generated
vendored
11
vendor/github.com/docker/docker/client/tlsconfig_clone.go
generated
vendored
|
@ -1,11 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package client // import "github.com/docker/docker/client"
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
// tlsConfigClone returns a clone of tls.Config. This function is provided for
|
||||
// compatibility for go1.7 that doesn't include this method in stdlib.
|
||||
func tlsConfigClone(c *tls.Config) *tls.Config {
|
||||
return c.Clone()
|
||||
}
|
12
vendor/github.com/docker/docker/vendor.conf
generated
vendored
12
vendor/github.com/docker/docker/vendor.conf
generated
vendored
|
@ -13,7 +13,7 @@ github.com/mattn/go-shellwords v1.0.3
|
|||
github.com/sirupsen/logrus v1.0.3
|
||||
github.com/tchap/go-patricia v2.2.6
|
||||
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
|
||||
golang.org/x/net 5561cd9b4330353950f399814f427425c0a26fd2
|
||||
golang.org/x/net 0ed95abb35c445290478a5348a7b38bb154135fd
|
||||
golang.org/x/sys 37707fdb30a5b38865cfb95e5aab41707daec7fd
|
||||
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
|
||||
github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6
|
||||
|
@ -35,7 +35,7 @@ github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
|||
#get libnetwork packages
|
||||
|
||||
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy accordingly
|
||||
github.com/docker/libnetwork eb6b2a57955e5c149d47c3973573216e8f8baa09
|
||||
github.com/docker/libnetwork 19279f0492417475b6bfbd0aa529f73e8f178fb5
|
||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
|
||||
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||
|
@ -58,7 +58,7 @@ github.com/coreos/go-semver v0.2.0
|
|||
github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065
|
||||
github.com/hashicorp/consul v0.5.2
|
||||
github.com/boltdb/bolt fff57c100f4dea1905678da7e90d92429dff2904
|
||||
github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
|
||||
github.com/miekg/dns v1.0.7
|
||||
github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
|
||||
|
||||
# get graph and distribution packages
|
||||
|
@ -112,11 +112,11 @@ github.com/googleapis/gax-go v2.0.0
|
|||
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
|
||||
|
||||
# containerd
|
||||
github.com/containerd/containerd c7083eed5d8633d54c25fe81aa609010a4f2e495
|
||||
github.com/containerd/containerd 63522d9eaa5a0443d225642c4b6f4f5fdedf932b
|
||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||
github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b
|
||||
github.com/containerd/cgroups fe281dd265766145e943a034aa41086474ea6130
|
||||
github.com/containerd/console cb7008ab3d8359b78c5f464cb7cf160107ad5925
|
||||
github.com/containerd/console 9290d21dc56074581f619579c43d970b4514bc08
|
||||
github.com/containerd/go-runc f271fa2021de855d4d918dbef83c5fe19db1bdd
|
||||
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
|
||||
github.com/stevvooe/ttrpc d4528379866b0ce7e9d71f3eb96f0582fc374577
|
||||
|
@ -128,7 +128,7 @@ github.com/gogo/protobuf v1.0.0
|
|||
github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
|
||||
github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
|
||||
github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
|
||||
golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
|
||||
golang.org/x/crypto 1a580b3eff7814fc9b40602fd35256c63b50f491
|
||||
golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
|
||||
github.com/hashicorp/go-memdb cb9a474f84cc5e41b273b20c6927680b2a8776ad
|
||||
github.com/hashicorp/go-immutable-radix 8e8ed81f8f0bf1bdd829593fdd5c29922c1ea990
|
||||
|
|
1241
vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
generated
vendored
Normal file
1241
vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1150
vendor/github.com/golang/protobuf/jsonpb/jsonpb_test.go
generated
vendored
Normal file
1150
vendor/github.com/golang/protobuf/jsonpb/jsonpb_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
2812
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go
generated
vendored
Normal file
2812
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
872
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto
generated
vendored
Normal file
872
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto
generated
vendored
Normal file
|
@ -0,0 +1,872 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// The messages in this file describe the definitions found in .proto files.
|
||||
// A valid .proto file can be translated directly to a FileDescriptorProto
|
||||
// without any other information (e.g. without reading its imports).
|
||||
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package google.protobuf;
|
||||
option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "DescriptorProtos";
|
||||
option csharp_namespace = "Google.Protobuf.Reflection";
|
||||
option objc_class_prefix = "GPB";
|
||||
option cc_enable_arenas = true;
|
||||
|
||||
// descriptor.proto must be optimized for speed because reflection-based
|
||||
// algorithms don't work during bootstrapping.
|
||||
option optimize_for = SPEED;
|
||||
|
||||
// The protocol compiler can output a FileDescriptorSet containing the .proto
|
||||
// files it parses.
|
||||
message FileDescriptorSet {
|
||||
repeated FileDescriptorProto file = 1;
|
||||
}
|
||||
|
||||
// Describes a complete .proto file.
|
||||
message FileDescriptorProto {
|
||||
optional string name = 1; // file name, relative to root of source tree
|
||||
optional string package = 2; // e.g. "foo", "foo.bar", etc.
|
||||
|
||||
// Names of files imported by this file.
|
||||
repeated string dependency = 3;
|
||||
// Indexes of the public imported files in the dependency list above.
|
||||
repeated int32 public_dependency = 10;
|
||||
// Indexes of the weak imported files in the dependency list.
|
||||
// For Google-internal migration only. Do not use.
|
||||
repeated int32 weak_dependency = 11;
|
||||
|
||||
// All top-level definitions in this file.
|
||||
repeated DescriptorProto message_type = 4;
|
||||
repeated EnumDescriptorProto enum_type = 5;
|
||||
repeated ServiceDescriptorProto service = 6;
|
||||
repeated FieldDescriptorProto extension = 7;
|
||||
|
||||
optional FileOptions options = 8;
|
||||
|
||||
// This field contains optional information about the original source code.
|
||||
// You may safely remove this entire field without harming runtime
|
||||
// functionality of the descriptors -- the information is needed only by
|
||||
// development tools.
|
||||
optional SourceCodeInfo source_code_info = 9;
|
||||
|
||||
// The syntax of the proto file.
|
||||
// The supported values are "proto2" and "proto3".
|
||||
optional string syntax = 12;
|
||||
}
|
||||
|
||||
// Describes a message type.
|
||||
message DescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
repeated FieldDescriptorProto field = 2;
|
||||
repeated FieldDescriptorProto extension = 6;
|
||||
|
||||
repeated DescriptorProto nested_type = 3;
|
||||
repeated EnumDescriptorProto enum_type = 4;
|
||||
|
||||
message ExtensionRange {
|
||||
optional int32 start = 1;
|
||||
optional int32 end = 2;
|
||||
|
||||
optional ExtensionRangeOptions options = 3;
|
||||
}
|
||||
repeated ExtensionRange extension_range = 5;
|
||||
|
||||
repeated OneofDescriptorProto oneof_decl = 8;
|
||||
|
||||
optional MessageOptions options = 7;
|
||||
|
||||
// Range of reserved tag numbers. Reserved tag numbers may not be used by
|
||||
// fields or extension ranges in the same message. Reserved ranges may
|
||||
// not overlap.
|
||||
message ReservedRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Exclusive.
|
||||
}
|
||||
repeated ReservedRange reserved_range = 9;
|
||||
// Reserved field names, which may not be used by fields in the same message.
|
||||
// A given name may only be reserved once.
|
||||
repeated string reserved_name = 10;
|
||||
}
|
||||
|
||||
message ExtensionRangeOptions {
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
// Describes a field within a message.
|
||||
message FieldDescriptorProto {
|
||||
enum Type {
|
||||
// 0 is reserved for errors.
|
||||
// Order is weird for historical reasons.
|
||||
TYPE_DOUBLE = 1;
|
||||
TYPE_FLOAT = 2;
|
||||
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
|
||||
// negative values are likely.
|
||||
TYPE_INT64 = 3;
|
||||
TYPE_UINT64 = 4;
|
||||
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
|
||||
// negative values are likely.
|
||||
TYPE_INT32 = 5;
|
||||
TYPE_FIXED64 = 6;
|
||||
TYPE_FIXED32 = 7;
|
||||
TYPE_BOOL = 8;
|
||||
TYPE_STRING = 9;
|
||||
// Tag-delimited aggregate.
|
||||
// Group type is deprecated and not supported in proto3. However, Proto3
|
||||
// implementations should still be able to parse the group wire format and
|
||||
// treat group fields as unknown fields.
|
||||
TYPE_GROUP = 10;
|
||||
TYPE_MESSAGE = 11; // Length-delimited aggregate.
|
||||
|
||||
// New in version 2.
|
||||
TYPE_BYTES = 12;
|
||||
TYPE_UINT32 = 13;
|
||||
TYPE_ENUM = 14;
|
||||
TYPE_SFIXED32 = 15;
|
||||
TYPE_SFIXED64 = 16;
|
||||
TYPE_SINT32 = 17; // Uses ZigZag encoding.
|
||||
TYPE_SINT64 = 18; // Uses ZigZag encoding.
|
||||
};
|
||||
|
||||
enum Label {
|
||||
// 0 is reserved for errors
|
||||
LABEL_OPTIONAL = 1;
|
||||
LABEL_REQUIRED = 2;
|
||||
LABEL_REPEATED = 3;
|
||||
};
|
||||
|
||||
optional string name = 1;
|
||||
optional int32 number = 3;
|
||||
optional Label label = 4;
|
||||
|
||||
// If type_name is set, this need not be set. If both this and type_name
|
||||
// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
|
||||
optional Type type = 5;
|
||||
|
||||
// For message and enum types, this is the name of the type. If the name
|
||||
// starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
|
||||
// rules are used to find the type (i.e. first the nested types within this
|
||||
// message are searched, then within the parent, on up to the root
|
||||
// namespace).
|
||||
optional string type_name = 6;
|
||||
|
||||
// For extensions, this is the name of the type being extended. It is
|
||||
// resolved in the same manner as type_name.
|
||||
optional string extendee = 2;
|
||||
|
||||
// For numeric types, contains the original text representation of the value.
|
||||
// For booleans, "true" or "false".
|
||||
// For strings, contains the default text contents (not escaped in any way).
|
||||
// For bytes, contains the C escaped value. All bytes >= 128 are escaped.
|
||||
// TODO(kenton): Base-64 encode?
|
||||
optional string default_value = 7;
|
||||
|
||||
// If set, gives the index of a oneof in the containing type's oneof_decl
|
||||
// list. This field is a member of that oneof.
|
||||
optional int32 oneof_index = 9;
|
||||
|
||||
// JSON name of this field. The value is set by protocol compiler. If the
|
||||
// user has set a "json_name" option on this field, that option's value
|
||||
// will be used. Otherwise, it's deduced from the field's name by converting
|
||||
// it to camelCase.
|
||||
optional string json_name = 10;
|
||||
|
||||
optional FieldOptions options = 8;
|
||||
}
|
||||
|
||||
// Describes a oneof.
|
||||
message OneofDescriptorProto {
|
||||
optional string name = 1;
|
||||
optional OneofOptions options = 2;
|
||||
}
|
||||
|
||||
// Describes an enum type.
|
||||
message EnumDescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
repeated EnumValueDescriptorProto value = 2;
|
||||
|
||||
optional EnumOptions options = 3;
|
||||
|
||||
// Range of reserved numeric values. Reserved values may not be used by
|
||||
// entries in the same enum. Reserved ranges may not overlap.
|
||||
//
|
||||
// Note that this is distinct from DescriptorProto.ReservedRange in that it
|
||||
// is inclusive such that it can appropriately represent the entire int32
|
||||
// domain.
|
||||
message EnumReservedRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Inclusive.
|
||||
}
|
||||
|
||||
// Range of reserved numeric values. Reserved numeric values may not be used
|
||||
// by enum values in the same enum declaration. Reserved ranges may not
|
||||
// overlap.
|
||||
repeated EnumReservedRange reserved_range = 4;
|
||||
|
||||
// Reserved enum value names, which may not be reused. A given name may only
|
||||
// be reserved once.
|
||||
repeated string reserved_name = 5;
|
||||
}
|
||||
|
||||
// Describes a value within an enum.
|
||||
message EnumValueDescriptorProto {
|
||||
optional string name = 1;
|
||||
optional int32 number = 2;
|
||||
|
||||
optional EnumValueOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a service.
|
||||
message ServiceDescriptorProto {
|
||||
optional string name = 1;
|
||||
repeated MethodDescriptorProto method = 2;
|
||||
|
||||
optional ServiceOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a method of a service.
|
||||
message MethodDescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
// Input and output type names. These are resolved in the same way as
|
||||
// FieldDescriptorProto.type_name, but must refer to a message type.
|
||||
optional string input_type = 2;
|
||||
optional string output_type = 3;
|
||||
|
||||
optional MethodOptions options = 4;
|
||||
|
||||
// Identifies if client streams multiple client messages
|
||||
optional bool client_streaming = 5 [default=false];
|
||||
// Identifies if server streams multiple server messages
|
||||
optional bool server_streaming = 6 [default=false];
|
||||
}
|
||||
|
||||
|
||||
// ===================================================================
|
||||
// Options
|
||||
|
||||
// Each of the definitions above may have "options" attached. These are
|
||||
// just annotations which may cause code to be generated slightly differently
|
||||
// or may contain hints for code that manipulates protocol messages.
|
||||
//
|
||||
// Clients may define custom options as extensions of the *Options messages.
|
||||
// These extensions may not yet be known at parsing time, so the parser cannot
|
||||
// store the values in them. Instead it stores them in a field in the *Options
|
||||
// message called uninterpreted_option. This field must have the same name
|
||||
// across all *Options messages. We then use this field to populate the
|
||||
// extensions when we build a descriptor, at which point all protos have been
|
||||
// parsed and so all extensions are known.
|
||||
//
|
||||
// Extension numbers for custom options may be chosen as follows:
|
||||
// * For options which will only be used within a single application or
|
||||
// organization, or for experimental options, use field numbers 50000
|
||||
// through 99999. It is up to you to ensure that you do not use the
|
||||
// same number for multiple options.
|
||||
// * For options which will be published and used publicly by multiple
|
||||
// independent entities, e-mail protobuf-global-extension-registry@google.com
|
||||
// to reserve extension numbers. Simply provide your project name (e.g.
|
||||
// Objective-C plugin) and your project website (if available) -- there's no
|
||||
// need to explain how you intend to use them. Usually you only need one
|
||||
// extension number. You can declare multiple options with only one extension
|
||||
// number by putting them in a sub-message. See the Custom Options section of
|
||||
// the docs for examples:
|
||||
// https://developers.google.com/protocol-buffers/docs/proto#options
|
||||
// If this turns out to be popular, a web service will be set up
|
||||
// to automatically assign option numbers.
|
||||
|
||||
|
||||
message FileOptions {
|
||||
|
||||
// Sets the Java package where classes generated from this .proto will be
|
||||
// placed. By default, the proto package is used, but this is often
|
||||
// inappropriate because proto packages do not normally start with backwards
|
||||
// domain names.
|
||||
optional string java_package = 1;
|
||||
|
||||
|
||||
// If set, all the classes from the .proto file are wrapped in a single
|
||||
// outer class with the given name. This applies to both Proto1
|
||||
// (equivalent to the old "--one_java_file" option) and Proto2 (where
|
||||
// a .proto always translates to a single class, but you may want to
|
||||
// explicitly choose the class name).
|
||||
optional string java_outer_classname = 8;
|
||||
|
||||
// If set true, then the Java code generator will generate a separate .java
|
||||
// file for each top-level message, enum, and service defined in the .proto
|
||||
// file. Thus, these types will *not* be nested inside the outer class
|
||||
// named by java_outer_classname. However, the outer class will still be
|
||||
// generated to contain the file's getDescriptor() method as well as any
|
||||
// top-level extensions defined in the file.
|
||||
optional bool java_multiple_files = 10 [default=false];
|
||||
|
||||
// This option does nothing.
|
||||
optional bool java_generate_equals_and_hash = 20 [deprecated=true];
|
||||
|
||||
// If set true, then the Java2 code generator will generate code that
|
||||
// throws an exception whenever an attempt is made to assign a non-UTF-8
|
||||
// byte sequence to a string field.
|
||||
// Message reflection will do the same.
|
||||
// However, an extension field still accepts non-UTF-8 byte sequences.
|
||||
// This option has no effect on when used with the lite runtime.
|
||||
optional bool java_string_check_utf8 = 27 [default=false];
|
||||
|
||||
|
||||
// Generated classes can be optimized for speed or code size.
|
||||
enum OptimizeMode {
|
||||
SPEED = 1; // Generate complete code for parsing, serialization,
|
||||
// etc.
|
||||
CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
|
||||
LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
|
||||
}
|
||||
optional OptimizeMode optimize_for = 9 [default=SPEED];
|
||||
|
||||
// Sets the Go package where structs generated from this .proto will be
|
||||
// placed. If omitted, the Go package will be derived from the following:
|
||||
// - The basename of the package import path, if provided.
|
||||
// - Otherwise, the package statement in the .proto file, if present.
|
||||
// - Otherwise, the basename of the .proto file, without extension.
|
||||
optional string go_package = 11;
|
||||
|
||||
|
||||
|
||||
// Should generic services be generated in each language? "Generic" services
|
||||
// are not specific to any particular RPC system. They are generated by the
|
||||
// main code generators in each language (without additional plugins).
|
||||
// Generic services were the only kind of service generation supported by
|
||||
// early versions of google.protobuf.
|
||||
//
|
||||
// Generic services are now considered deprecated in favor of using plugins
|
||||
// that generate code specific to your particular RPC system. Therefore,
|
||||
// these default to false. Old code which depends on generic services should
|
||||
// explicitly set them to true.
|
||||
optional bool cc_generic_services = 16 [default=false];
|
||||
optional bool java_generic_services = 17 [default=false];
|
||||
optional bool py_generic_services = 18 [default=false];
|
||||
optional bool php_generic_services = 42 [default=false];
|
||||
|
||||
// Is this file deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for everything in the file, or it will be completely ignored; in the very
|
||||
// least, this is a formalization for deprecating files.
|
||||
optional bool deprecated = 23 [default=false];
|
||||
|
||||
// Enables the use of arenas for the proto messages in this file. This applies
|
||||
// only to generated classes for C++.
|
||||
optional bool cc_enable_arenas = 31 [default=false];
|
||||
|
||||
|
||||
// Sets the objective c class prefix which is prepended to all objective c
|
||||
// generated classes from this .proto. There is no default.
|
||||
optional string objc_class_prefix = 36;
|
||||
|
||||
// Namespace for generated classes; defaults to the package.
|
||||
optional string csharp_namespace = 37;
|
||||
|
||||
// By default Swift generators will take the proto package and CamelCase it
|
||||
// replacing '.' with underscore and use that to prefix the types/symbols
|
||||
// defined. When this options is provided, they will use this value instead
|
||||
// to prefix the types/symbols defined.
|
||||
optional string swift_prefix = 39;
|
||||
|
||||
// Sets the php class prefix which is prepended to all php generated classes
|
||||
// from this .proto. Default is empty.
|
||||
optional string php_class_prefix = 40;
|
||||
|
||||
// Use this option to change the namespace of php generated classes. Default
|
||||
// is empty. When this option is empty, the package name will be used for
|
||||
// determining the namespace.
|
||||
optional string php_namespace = 41;
|
||||
|
||||
// The parser stores options it doesn't recognize here.
|
||||
// See the documentation for the "Options" section above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message.
|
||||
// See the documentation for the "Options" section above.
|
||||
extensions 1000 to max;
|
||||
|
||||
reserved 38;
|
||||
}
|
||||
|
||||
message MessageOptions {
|
||||
// Set true to use the old proto1 MessageSet wire format for extensions.
|
||||
// This is provided for backwards-compatibility with the MessageSet wire
|
||||
// format. You should not use this for any other reason: It's less
|
||||
// efficient, has fewer features, and is more complicated.
|
||||
//
|
||||
// The message must be defined exactly as follows:
|
||||
// message Foo {
|
||||
// option message_set_wire_format = true;
|
||||
// extensions 4 to max;
|
||||
// }
|
||||
// Note that the message cannot have any defined fields; MessageSets only
|
||||
// have extensions.
|
||||
//
|
||||
// All extensions of your type must be singular messages; e.g. they cannot
|
||||
// be int32s, enums, or repeated messages.
|
||||
//
|
||||
// Because this is an option, the above two restrictions are not enforced by
|
||||
// the protocol compiler.
|
||||
optional bool message_set_wire_format = 1 [default=false];
|
||||
|
||||
// Disables the generation of the standard "descriptor()" accessor, which can
|
||||
// conflict with a field of the same name. This is meant to make migration
|
||||
// from proto1 easier; new code should avoid fields named "descriptor".
|
||||
optional bool no_standard_descriptor_accessor = 2 [default=false];
|
||||
|
||||
// Is this message deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the message, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating messages.
|
||||
optional bool deprecated = 3 [default=false];
|
||||
|
||||
// Whether the message is an automatically generated map entry type for the
|
||||
// maps field.
|
||||
//
|
||||
// For maps fields:
|
||||
// map<KeyType, ValueType> map_field = 1;
|
||||
// The parsed descriptor looks like:
|
||||
// message MapFieldEntry {
|
||||
// option map_entry = true;
|
||||
// optional KeyType key = 1;
|
||||
// optional ValueType value = 2;
|
||||
// }
|
||||
// repeated MapFieldEntry map_field = 1;
|
||||
//
|
||||
// Implementations may choose not to generate the map_entry=true message, but
|
||||
// use a native map in the target language to hold the keys and values.
|
||||
// The reflection APIs in such implementions still need to work as
|
||||
// if the field is a repeated message field.
|
||||
//
|
||||
// NOTE: Do not set the option in .proto files. Always use the maps syntax
|
||||
// instead. The option should only be implicitly set by the proto compiler
|
||||
// parser.
|
||||
optional bool map_entry = 7;
|
||||
|
||||
reserved 8; // javalite_serializable
|
||||
reserved 9; // javanano_as_lite
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message FieldOptions {
|
||||
// The ctype option instructs the C++ code generator to use a different
|
||||
// representation of the field than it normally would. See the specific
|
||||
// options below. This option is not yet implemented in the open source
|
||||
// release -- sorry, we'll try to include it in a future version!
|
||||
optional CType ctype = 1 [default = STRING];
|
||||
enum CType {
|
||||
// Default mode.
|
||||
STRING = 0;
|
||||
|
||||
CORD = 1;
|
||||
|
||||
STRING_PIECE = 2;
|
||||
}
|
||||
// The packed option can be enabled for repeated primitive fields to enable
|
||||
// a more efficient representation on the wire. Rather than repeatedly
|
||||
// writing the tag and type for each element, the entire array is encoded as
|
||||
// a single length-delimited blob. In proto3, only explicit setting it to
|
||||
// false will avoid using packed encoding.
|
||||
optional bool packed = 2;
|
||||
|
||||
// The jstype option determines the JavaScript type used for values of the
|
||||
// field. The option is permitted only for 64 bit integral and fixed types
|
||||
// (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING
|
||||
// is represented as JavaScript string, which avoids loss of precision that
|
||||
// can happen when a large value is converted to a floating point JavaScript.
|
||||
// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
|
||||
// use the JavaScript "number" type. The behavior of the default option
|
||||
// JS_NORMAL is implementation dependent.
|
||||
//
|
||||
// This option is an enum to permit additional types to be added, e.g.
|
||||
// goog.math.Integer.
|
||||
optional JSType jstype = 6 [default = JS_NORMAL];
|
||||
enum JSType {
|
||||
// Use the default type.
|
||||
JS_NORMAL = 0;
|
||||
|
||||
// Use JavaScript strings.
|
||||
JS_STRING = 1;
|
||||
|
||||
// Use JavaScript numbers.
|
||||
JS_NUMBER = 2;
|
||||
}
|
||||
|
||||
// Should this field be parsed lazily? Lazy applies only to message-type
|
||||
// fields. It means that when the outer message is initially parsed, the
|
||||
// inner message's contents will not be parsed but instead stored in encoded
|
||||
// form. The inner message will actually be parsed when it is first accessed.
|
||||
//
|
||||
// This is only a hint. Implementations are free to choose whether to use
|
||||
// eager or lazy parsing regardless of the value of this option. However,
|
||||
// setting this option true suggests that the protocol author believes that
|
||||
// using lazy parsing on this field is worth the additional bookkeeping
|
||||
// overhead typically needed to implement it.
|
||||
//
|
||||
// This option does not affect the public interface of any generated code;
|
||||
// all method signatures remain the same. Furthermore, thread-safety of the
|
||||
// interface is not affected by this option; const methods remain safe to
|
||||
// call from multiple threads concurrently, while non-const methods continue
|
||||
// to require exclusive access.
|
||||
//
|
||||
//
|
||||
// Note that implementations may choose not to check required fields within
|
||||
// a lazy sub-message. That is, calling IsInitialized() on the outer message
|
||||
// may return true even if the inner message has missing required fields.
|
||||
// This is necessary because otherwise the inner message would have to be
|
||||
// parsed in order to perform the check, defeating the purpose of lazy
|
||||
// parsing. An implementation which chooses not to check required fields
|
||||
// must be consistent about it. That is, for any particular sub-message, the
|
||||
// implementation must either *always* check its required fields, or *never*
|
||||
// check its required fields, regardless of whether or not the message has
|
||||
// been parsed.
|
||||
optional bool lazy = 5 [default=false];
|
||||
|
||||
// Is this field deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for accessors, or it will be completely ignored; in the very least, this
|
||||
// is a formalization for deprecating fields.
|
||||
optional bool deprecated = 3 [default=false];
|
||||
|
||||
// For Google-internal migration only. Do not use.
|
||||
optional bool weak = 10 [default=false];
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
|
||||
reserved 4; // removed jtype
|
||||
}
|
||||
|
||||
message OneofOptions {
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message EnumOptions {
|
||||
|
||||
// Set this option to true to allow mapping different tag names to the same
|
||||
// value.
|
||||
optional bool allow_alias = 2;
|
||||
|
||||
// Is this enum deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the enum, or it will be completely ignored; in the very least, this
|
||||
// is a formalization for deprecating enums.
|
||||
optional bool deprecated = 3 [default=false];
|
||||
|
||||
reserved 5; // javanano_as_lite
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message EnumValueOptions {
|
||||
// Is this enum value deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the enum value, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating enum values.
|
||||
optional bool deprecated = 1 [default=false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message ServiceOptions {
|
||||
|
||||
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
|
||||
// framework. We apologize for hoarding these numbers to ourselves, but
|
||||
// we were already using them long before we decided to release Protocol
|
||||
// Buffers.
|
||||
|
||||
// Is this service deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the service, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating services.
|
||||
optional bool deprecated = 33 [default=false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message MethodOptions {
|
||||
|
||||
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
|
||||
// framework. We apologize for hoarding these numbers to ourselves, but
|
||||
// we were already using them long before we decided to release Protocol
|
||||
// Buffers.
|
||||
|
||||
// Is this method deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the method, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating methods.
|
||||
optional bool deprecated = 33 [default=false];
|
||||
|
||||
// Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
|
||||
// or neither? HTTP based RPC implementation may choose GET verb for safe
|
||||
// methods, and PUT verb for idempotent methods instead of the default POST.
|
||||
enum IdempotencyLevel {
|
||||
IDEMPOTENCY_UNKNOWN = 0;
|
||||
NO_SIDE_EFFECTS = 1; // implies idempotent
|
||||
IDEMPOTENT = 2; // idempotent, but may have side effects
|
||||
}
|
||||
optional IdempotencyLevel idempotency_level =
|
||||
34 [default=IDEMPOTENCY_UNKNOWN];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
|
||||
// A message representing a option the parser does not recognize. This only
|
||||
// appears in options protos created by the compiler::Parser class.
|
||||
// DescriptorPool resolves these when building Descriptor objects. Therefore,
|
||||
// options protos in descriptor objects (e.g. returned by Descriptor::options(),
|
||||
// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
|
||||
// in them.
|
||||
message UninterpretedOption {
|
||||
// The name of the uninterpreted option. Each string represents a segment in
|
||||
// a dot-separated name. is_extension is true iff a segment represents an
|
||||
// extension (denoted with parentheses in options specs in .proto files).
|
||||
// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
|
||||
// "foo.(bar.baz).qux".
|
||||
message NamePart {
|
||||
required string name_part = 1;
|
||||
required bool is_extension = 2;
|
||||
}
|
||||
repeated NamePart name = 2;
|
||||
|
||||
// The value of the uninterpreted option, in whatever type the tokenizer
|
||||
// identified it as during parsing. Exactly one of these should be set.
|
||||
optional string identifier_value = 3;
|
||||
optional uint64 positive_int_value = 4;
|
||||
optional int64 negative_int_value = 5;
|
||||
optional double double_value = 6;
|
||||
optional bytes string_value = 7;
|
||||
optional string aggregate_value = 8;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Optional source code info
|
||||
|
||||
// Encapsulates information about the original source file from which a
|
||||
// FileDescriptorProto was generated.
|
||||
message SourceCodeInfo {
|
||||
// A Location identifies a piece of source code in a .proto file which
|
||||
// corresponds to a particular definition. This information is intended
|
||||
// to be useful to IDEs, code indexers, documentation generators, and similar
|
||||
// tools.
|
||||
//
|
||||
// For example, say we have a file like:
|
||||
// message Foo {
|
||||
// optional string foo = 1;
|
||||
// }
|
||||
// Let's look at just the field definition:
|
||||
// optional string foo = 1;
|
||||
// ^ ^^ ^^ ^ ^^^
|
||||
// a bc de f ghi
|
||||
// We have the following locations:
|
||||
// span path represents
|
||||
// [a,i) [ 4, 0, 2, 0 ] The whole field definition.
|
||||
// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
|
||||
// [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
|
||||
// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
|
||||
// [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
|
||||
//
|
||||
// Notes:
|
||||
// - A location may refer to a repeated field itself (i.e. not to any
|
||||
// particular index within it). This is used whenever a set of elements are
|
||||
// logically enclosed in a single code segment. For example, an entire
|
||||
// extend block (possibly containing multiple extension definitions) will
|
||||
// have an outer location whose path refers to the "extensions" repeated
|
||||
// field without an index.
|
||||
// - Multiple locations may have the same path. This happens when a single
|
||||
// logical declaration is spread out across multiple places. The most
|
||||
// obvious example is the "extend" block again -- there may be multiple
|
||||
// extend blocks in the same scope, each of which will have the same path.
|
||||
// - A location's span is not always a subset of its parent's span. For
|
||||
// example, the "extendee" of an extension declaration appears at the
|
||||
// beginning of the "extend" block and is shared by all extensions within
|
||||
// the block.
|
||||
// - Just because a location's span is a subset of some other location's span
|
||||
// does not mean that it is a descendent. For example, a "group" defines
|
||||
// both a type and a field in a single declaration. Thus, the locations
|
||||
// corresponding to the type and field and their components will overlap.
|
||||
// - Code which tries to interpret locations should probably be designed to
|
||||
// ignore those that it doesn't understand, as more types of locations could
|
||||
// be recorded in the future.
|
||||
repeated Location location = 1;
|
||||
message Location {
|
||||
// Identifies which part of the FileDescriptorProto was defined at this
|
||||
// location.
|
||||
//
|
||||
// Each element is a field number or an index. They form a path from
|
||||
// the root FileDescriptorProto to the place where the definition. For
|
||||
// example, this path:
|
||||
// [ 4, 3, 2, 7, 1 ]
|
||||
// refers to:
|
||||
// file.message_type(3) // 4, 3
|
||||
// .field(7) // 2, 7
|
||||
// .name() // 1
|
||||
// This is because FileDescriptorProto.message_type has field number 4:
|
||||
// repeated DescriptorProto message_type = 4;
|
||||
// and DescriptorProto.field has field number 2:
|
||||
// repeated FieldDescriptorProto field = 2;
|
||||
// and FieldDescriptorProto.name has field number 1:
|
||||
// optional string name = 1;
|
||||
//
|
||||
// Thus, the above path gives the location of a field name. If we removed
|
||||
// the last element:
|
||||
// [ 4, 3, 2, 7 ]
|
||||
// this path refers to the whole field declaration (from the beginning
|
||||
// of the label to the terminating semicolon).
|
||||
repeated int32 path = 1 [packed=true];
|
||||
|
||||
// Always has exactly three or four elements: start line, start column,
|
||||
// end line (optional, otherwise assumed same as start line), end column.
|
||||
// These are packed into a single field for efficiency. Note that line
|
||||
// and column numbers are zero-based -- typically you will want to add
|
||||
// 1 to each before displaying to a user.
|
||||
repeated int32 span = 2 [packed=true];
|
||||
|
||||
// If this SourceCodeInfo represents a complete declaration, these are any
|
||||
// comments appearing before and after the declaration which appear to be
|
||||
// attached to the declaration.
|
||||
//
|
||||
// A series of line comments appearing on consecutive lines, with no other
|
||||
// tokens appearing on those lines, will be treated as a single comment.
|
||||
//
|
||||
// leading_detached_comments will keep paragraphs of comments that appear
|
||||
// before (but not connected to) the current element. Each paragraph,
|
||||
// separated by empty lines, will be one comment element in the repeated
|
||||
// field.
|
||||
//
|
||||
// Only the comment content is provided; comment markers (e.g. //) are
|
||||
// stripped out. For block comments, leading whitespace and an asterisk
|
||||
// will be stripped from the beginning of each line other than the first.
|
||||
// Newlines are included in the output.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// optional int32 foo = 1; // Comment attached to foo.
|
||||
// // Comment attached to bar.
|
||||
// optional int32 bar = 2;
|
||||
//
|
||||
// optional string baz = 3;
|
||||
// // Comment attached to baz.
|
||||
// // Another line attached to baz.
|
||||
//
|
||||
// // Comment attached to qux.
|
||||
// //
|
||||
// // Another line attached to qux.
|
||||
// optional double qux = 4;
|
||||
//
|
||||
// // Detached comment for corge. This is not leading or trailing comments
|
||||
// // to qux or corge because there are blank lines separating it from
|
||||
// // both.
|
||||
//
|
||||
// // Detached comment for corge paragraph 2.
|
||||
//
|
||||
// optional string corge = 5;
|
||||
// /* Block comment attached
|
||||
// * to corge. Leading asterisks
|
||||
// * will be removed. */
|
||||
// /* Block comment attached to
|
||||
// * grault. */
|
||||
// optional int32 grault = 6;
|
||||
//
|
||||
// // ignored detached comments.
|
||||
optional string leading_comments = 3;
|
||||
optional string trailing_comments = 4;
|
||||
repeated string leading_detached_comments = 6;
|
||||
}
|
||||
}
|
||||
|
||||
// Describes the relationship between generated code and its original source
|
||||
// file. A GeneratedCodeInfo message is associated with only one generated
|
||||
// source file, but may contain references to different source .proto files.
|
||||
message GeneratedCodeInfo {
|
||||
// An Annotation connects some span of text in generated code to an element
|
||||
// of its generating .proto file.
|
||||
repeated Annotation annotation = 1;
|
||||
message Annotation {
|
||||
// Identifies the element in the original source .proto file. This field
|
||||
// is formatted the same as SourceCodeInfo.Location.path.
|
||||
repeated int32 path = 1 [packed=true];
|
||||
|
||||
// Identifies the filesystem path to the original source .proto.
|
||||
optional string source_file = 2;
|
||||
|
||||
// Identifies the starting offset in bytes in the generated code
|
||||
// that relates to the identified object.
|
||||
optional int32 begin = 3;
|
||||
|
||||
// Identifies the ending offset in bytes in the generated code that
|
||||
// relates to the identified offset. The end offset should be one past
|
||||
// the last relevant byte (so the length of the text = end - begin).
|
||||
optional int32 end = 4;
|
||||
}
|
||||
}
|
51
vendor/github.com/golang/protobuf/protoc-gen-go/doc.go
generated
vendored
Normal file
51
vendor/github.com/golang/protobuf/protoc-gen-go/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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.
|
||||
|
||||
/*
|
||||
A plugin for the Google protocol buffer compiler to generate Go code.
|
||||
Run it by building this program and putting it in your path with the name
|
||||
protoc-gen-go
|
||||
That word 'go' at the end becomes part of the option string set for the
|
||||
protocol compiler, so once the protocol compiler (protoc) is installed
|
||||
you can run
|
||||
protoc --go_out=output_directory input_directory/file.proto
|
||||
to generate Go bindings for the protocol defined by file.proto.
|
||||
With that input, the output will be written to
|
||||
output_directory/file.pb.go
|
||||
|
||||
The generated code is documented in the package comment for
|
||||
the library.
|
||||
|
||||
See the README and documentation for protocol buffers to learn more:
|
||||
https://developers.google.com/protocol-buffers/
|
||||
|
||||
*/
|
||||
package documentation
|
422
vendor/github.com/golang/protobuf/protoc-gen-go/golden_test.go
generated
vendored
Normal file
422
vendor/github.com/golang/protobuf/protoc-gen-go/golden_test.go
generated
vendored
Normal file
|
@ -0,0 +1,422 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Set --regenerate to regenerate the golden files.
|
||||
var regenerate = flag.Bool("regenerate", false, "regenerate golden files")
|
||||
|
||||
// When the environment variable RUN_AS_PROTOC_GEN_GO is set, we skip running
|
||||
// tests and instead act as protoc-gen-go. This allows the test binary to
|
||||
// pass itself to protoc.
|
||||
func init() {
|
||||
if os.Getenv("RUN_AS_PROTOC_GEN_GO") != "" {
|
||||
main()
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGolden(t *testing.T) {
|
||||
workdir, err := ioutil.TempDir("", "proto-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(workdir)
|
||||
|
||||
// Find all the proto files we need to compile. We assume that each directory
|
||||
// contains the files for a single package.
|
||||
supportTypeAliases := hasReleaseTag("go1.9")
|
||||
packages := map[string][]string{}
|
||||
err = filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error {
|
||||
if filepath.Base(path) == "import_public" && !supportTypeAliases {
|
||||
// Public imports require type alias support.
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if !strings.HasSuffix(path, ".proto") {
|
||||
return nil
|
||||
}
|
||||
dir := filepath.Dir(path)
|
||||
packages[dir] = append(packages[dir], path)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Compile each package, using this binary as protoc-gen-go.
|
||||
for _, sources := range packages {
|
||||
args := []string{"-Itestdata", "--go_out=plugins=grpc,paths=source_relative:" + workdir}
|
||||
args = append(args, sources...)
|
||||
protoc(t, args)
|
||||
}
|
||||
|
||||
// Compare each generated file to the golden version.
|
||||
filepath.Walk(workdir, func(genPath string, info os.FileInfo, _ error) error {
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// For each generated file, figure out the path to the corresponding
|
||||
// golden file in the testdata directory.
|
||||
relPath, err := filepath.Rel(workdir, genPath)
|
||||
if err != nil {
|
||||
t.Errorf("filepath.Rel(%q, %q): %v", workdir, genPath, err)
|
||||
return nil
|
||||
}
|
||||
if filepath.SplitList(relPath)[0] == ".." {
|
||||
t.Errorf("generated file %q is not relative to %q", genPath, workdir)
|
||||
}
|
||||
goldenPath := filepath.Join("testdata", relPath)
|
||||
|
||||
got, err := ioutil.ReadFile(genPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return nil
|
||||
}
|
||||
if *regenerate {
|
||||
// If --regenerate set, just rewrite the golden files.
|
||||
err := ioutil.WriteFile(goldenPath, got, 0666)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
want, err := ioutil.ReadFile(goldenPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
want = fdescRE.ReplaceAll(want, nil)
|
||||
got = fdescRE.ReplaceAll(got, nil)
|
||||
if bytes.Equal(got, want) {
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd := exec.Command("diff", "-u", goldenPath, genPath)
|
||||
out, _ := cmd.CombinedOutput()
|
||||
t.Errorf("golden file differs: %v\n%v", relPath, string(out))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var fdescRE = regexp.MustCompile(`(?ms)^var fileDescriptor.*}`)
|
||||
|
||||
// Source files used by TestParameters.
|
||||
const (
|
||||
aProto = `
|
||||
syntax = "proto3";
|
||||
package test.alpha;
|
||||
option go_package = "package/alpha";
|
||||
import "beta/b.proto";
|
||||
message M { test.beta.M field = 1; }`
|
||||
|
||||
bProto = `
|
||||
syntax = "proto3";
|
||||
package test.beta;
|
||||
// no go_package option
|
||||
message M {}`
|
||||
)
|
||||
|
||||
func TestParameters(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
parameters string
|
||||
wantFiles map[string]bool
|
||||
wantImportsA map[string]bool
|
||||
wantPackageA string
|
||||
wantPackageB string
|
||||
}{{
|
||||
parameters: "",
|
||||
wantFiles: map[string]bool{
|
||||
"package/alpha/a.pb.go": true,
|
||||
"beta/b.pb.go": true,
|
||||
},
|
||||
wantPackageA: "alpha",
|
||||
wantPackageB: "test_beta",
|
||||
wantImportsA: map[string]bool{
|
||||
"github.com/golang/protobuf/proto": true,
|
||||
"beta": true,
|
||||
},
|
||||
}, {
|
||||
parameters: "import_prefix=prefix",
|
||||
wantFiles: map[string]bool{
|
||||
"package/alpha/a.pb.go": true,
|
||||
"beta/b.pb.go": true,
|
||||
},
|
||||
wantPackageA: "alpha",
|
||||
wantPackageB: "test_beta",
|
||||
wantImportsA: map[string]bool{
|
||||
// This really doesn't seem like useful behavior.
|
||||
"prefixgithub.com/golang/protobuf/proto": true,
|
||||
"prefixbeta": true,
|
||||
},
|
||||
}, {
|
||||
// import_path only affects the 'package' line.
|
||||
parameters: "import_path=import/path/of/pkg",
|
||||
wantPackageA: "alpha",
|
||||
wantPackageB: "pkg",
|
||||
wantFiles: map[string]bool{
|
||||
"package/alpha/a.pb.go": true,
|
||||
"beta/b.pb.go": true,
|
||||
},
|
||||
}, {
|
||||
parameters: "Mbeta/b.proto=package/gamma",
|
||||
wantFiles: map[string]bool{
|
||||
"package/alpha/a.pb.go": true,
|
||||
"beta/b.pb.go": true,
|
||||
},
|
||||
wantPackageA: "alpha",
|
||||
wantPackageB: "test_beta",
|
||||
wantImportsA: map[string]bool{
|
||||
"github.com/golang/protobuf/proto": true,
|
||||
// Rewritten by the M parameter.
|
||||
"package/gamma": true,
|
||||
},
|
||||
}, {
|
||||
parameters: "import_prefix=prefix,Mbeta/b.proto=package/gamma",
|
||||
wantFiles: map[string]bool{
|
||||
"package/alpha/a.pb.go": true,
|
||||
"beta/b.pb.go": true,
|
||||
},
|
||||
wantPackageA: "alpha",
|
||||
wantPackageB: "test_beta",
|
||||
wantImportsA: map[string]bool{
|
||||
// import_prefix applies after M.
|
||||
"prefixpackage/gamma": true,
|
||||
},
|
||||
}, {
|
||||
parameters: "paths=source_relative",
|
||||
wantFiles: map[string]bool{
|
||||
"alpha/a.pb.go": true,
|
||||
"beta/b.pb.go": true,
|
||||
},
|
||||
wantPackageA: "alpha",
|
||||
wantPackageB: "test_beta",
|
||||
}, {
|
||||
parameters: "paths=source_relative,import_prefix=prefix",
|
||||
wantFiles: map[string]bool{
|
||||
// import_prefix doesn't affect filenames.
|
||||
"alpha/a.pb.go": true,
|
||||
"beta/b.pb.go": true,
|
||||
},
|
||||
wantPackageA: "alpha",
|
||||
wantPackageB: "test_beta",
|
||||
}} {
|
||||
name := test.parameters
|
||||
if name == "" {
|
||||
name = "defaults"
|
||||
}
|
||||
// TODO: Switch to t.Run when we no longer support Go 1.6.
|
||||
t.Logf("TEST: %v", name)
|
||||
workdir, err := ioutil.TempDir("", "proto-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(workdir)
|
||||
|
||||
for _, dir := range []string{"alpha", "beta", "out"} {
|
||||
if err := os.MkdirAll(filepath.Join(workdir, dir), 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(workdir, "alpha", "a.proto"), []byte(aProto), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(workdir, "beta", "b.proto"), []byte(bProto), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
protoc(t, []string{
|
||||
"-I" + workdir,
|
||||
"--go_out=" + test.parameters + ":" + filepath.Join(workdir, "out"),
|
||||
filepath.Join(workdir, "alpha", "a.proto"),
|
||||
})
|
||||
protoc(t, []string{
|
||||
"-I" + workdir,
|
||||
"--go_out=" + test.parameters + ":" + filepath.Join(workdir, "out"),
|
||||
filepath.Join(workdir, "beta", "b.proto"),
|
||||
})
|
||||
|
||||
contents := make(map[string]string)
|
||||
gotFiles := make(map[string]bool)
|
||||
outdir := filepath.Join(workdir, "out")
|
||||
filepath.Walk(outdir, func(p string, info os.FileInfo, _ error) error {
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
base := filepath.Base(p)
|
||||
if base == "a.pb.go" || base == "b.pb.go" {
|
||||
b, err := ioutil.ReadFile(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
contents[base] = string(b)
|
||||
}
|
||||
relPath, _ := filepath.Rel(outdir, p)
|
||||
gotFiles[relPath] = true
|
||||
return nil
|
||||
})
|
||||
for got := range gotFiles {
|
||||
if runtime.GOOS == "windows" {
|
||||
got = filepath.ToSlash(got)
|
||||
}
|
||||
if !test.wantFiles[got] {
|
||||
t.Errorf("unexpected output file: %v", got)
|
||||
}
|
||||
}
|
||||
for want := range test.wantFiles {
|
||||
if runtime.GOOS == "windows" {
|
||||
want = filepath.FromSlash(want)
|
||||
}
|
||||
if !gotFiles[want] {
|
||||
t.Errorf("missing output file: %v", want)
|
||||
}
|
||||
}
|
||||
gotPackageA, gotImports, err := parseFile(contents["a.pb.go"])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gotPackageB, _, err := parseFile(contents["b.pb.go"])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, want := gotPackageA, test.wantPackageA; want != got {
|
||||
t.Errorf("output file a.pb.go is package %q, want %q", got, want)
|
||||
}
|
||||
if got, want := gotPackageB, test.wantPackageB; want != got {
|
||||
t.Errorf("output file b.pb.go is package %q, want %q", got, want)
|
||||
}
|
||||
missingImport := false
|
||||
WantImport:
|
||||
for want := range test.wantImportsA {
|
||||
for _, imp := range gotImports {
|
||||
if `"`+want+`"` == imp {
|
||||
continue WantImport
|
||||
}
|
||||
}
|
||||
t.Errorf("output file a.pb.go does not contain expected import %q", want)
|
||||
missingImport = true
|
||||
}
|
||||
if missingImport {
|
||||
t.Error("got imports:")
|
||||
for _, imp := range gotImports {
|
||||
t.Errorf(" %v", imp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPackageComment(t *testing.T) {
|
||||
workdir, err := ioutil.TempDir("", "proto-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(workdir)
|
||||
|
||||
var packageRE = regexp.MustCompile(`(?m)^package .*`)
|
||||
|
||||
for i, test := range []struct {
|
||||
goPackageOption string
|
||||
wantPackage string
|
||||
}{{
|
||||
goPackageOption: ``,
|
||||
wantPackage: `package proto_package`,
|
||||
}, {
|
||||
goPackageOption: `option go_package = "go_package";`,
|
||||
wantPackage: `package go_package`,
|
||||
}, {
|
||||
goPackageOption: `option go_package = "import/path/of/go_package";`,
|
||||
wantPackage: `package go_package // import "import/path/of/go_package"`,
|
||||
}, {
|
||||
goPackageOption: `option go_package = "import/path/of/something;go_package";`,
|
||||
wantPackage: `package go_package // import "import/path/of/something"`,
|
||||
}, {
|
||||
goPackageOption: `option go_package = "import_path;go_package";`,
|
||||
wantPackage: `package go_package // import "import_path"`,
|
||||
}} {
|
||||
srcName := filepath.Join(workdir, fmt.Sprintf("%d.proto", i))
|
||||
tgtName := filepath.Join(workdir, fmt.Sprintf("%d.pb.go", i))
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
fmt.Fprintln(buf, `syntax = "proto3";`)
|
||||
fmt.Fprintln(buf, `package proto_package;`)
|
||||
fmt.Fprintln(buf, test.goPackageOption)
|
||||
if err := ioutil.WriteFile(srcName, buf.Bytes(), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
protoc(t, []string{"-I" + workdir, "--go_out=paths=source_relative:" + workdir, srcName})
|
||||
|
||||
out, err := ioutil.ReadFile(tgtName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pkg := packageRE.Find(out)
|
||||
if pkg == nil {
|
||||
t.Errorf("generated .pb.go contains no package line\n\nsource:\n%v\n\noutput:\n%v", buf.String(), string(out))
|
||||
continue
|
||||
}
|
||||
|
||||
if got, want := string(pkg), test.wantPackage; got != want {
|
||||
t.Errorf("unexpected package statement with go_package = %q\n got: %v\nwant: %v", test.goPackageOption, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parseFile returns a file's package name and a list of all packages it imports.
|
||||
func parseFile(source string) (packageName string, imports []string, err error) {
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "<source>", source, parser.ImportsOnly)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
for _, imp := range f.Imports {
|
||||
imports = append(imports, imp.Path.Value)
|
||||
}
|
||||
return f.Name.Name, imports, nil
|
||||
}
|
||||
|
||||
func protoc(t *testing.T, args []string) {
|
||||
cmd := exec.Command("protoc", "--plugin=protoc-gen-go="+os.Args[0])
|
||||
cmd.Args = append(cmd.Args, args...)
|
||||
// We set the RUN_AS_PROTOC_GEN_GO environment variable to indicate that
|
||||
// the subprocess should act as a proto compiler rather than a test.
|
||||
cmd.Env = append(os.Environ(), "RUN_AS_PROTOC_GEN_GO=1")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if len(out) > 0 || err != nil {
|
||||
t.Log("RUNNING: ", strings.Join(cmd.Args, " "))
|
||||
}
|
||||
if len(out) > 0 {
|
||||
t.Log(string(out))
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("protoc: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func hasReleaseTag(want string) bool {
|
||||
for _, tag := range build.Default.ReleaseTags {
|
||||
if tag == want {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
34
vendor/github.com/golang/protobuf/protoc-gen-go/link_grpc.go
generated
vendored
Normal file
34
vendor/github.com/golang/protobuf/protoc-gen-go/link_grpc.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 main
|
||||
|
||||
import _ "github.com/golang/protobuf/protoc-gen-go/grpc"
|
98
vendor/github.com/golang/protobuf/protoc-gen-go/main.go
generated
vendored
Normal file
98
vendor/github.com/golang/protobuf/protoc-gen-go/main.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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.
|
||||
|
||||
// protoc-gen-go is a plugin for the Google protocol buffer compiler to generate
|
||||
// Go code. Run it by building this program and putting it in your path with
|
||||
// the name
|
||||
// protoc-gen-go
|
||||
// That word 'go' at the end becomes part of the option string set for the
|
||||
// protocol compiler, so once the protocol compiler (protoc) is installed
|
||||
// you can run
|
||||
// protoc --go_out=output_directory input_directory/file.proto
|
||||
// to generate Go bindings for the protocol defined by file.proto.
|
||||
// With that input, the output will be written to
|
||||
// output_directory/file.pb.go
|
||||
//
|
||||
// The generated code is documented in the package comment for
|
||||
// the library.
|
||||
//
|
||||
// See the README and documentation for protocol buffers to learn more:
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/protoc-gen-go/generator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Begin by allocating a generator. The request and response structures are stored there
|
||||
// so we can do error handling easily - the response structure contains the field to
|
||||
// report failure.
|
||||
g := generator.New()
|
||||
|
||||
data, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
g.Error(err, "reading input")
|
||||
}
|
||||
|
||||
if err := proto.Unmarshal(data, g.Request); err != nil {
|
||||
g.Error(err, "parsing input proto")
|
||||
}
|
||||
|
||||
if len(g.Request.FileToGenerate) == 0 {
|
||||
g.Fail("no files to generate")
|
||||
}
|
||||
|
||||
g.CommandLineParameters(g.Request.GetParameter())
|
||||
|
||||
// Create a wrapped version of the Descriptors and EnumDescriptors that
|
||||
// point to the file that defines them.
|
||||
g.WrapTypes()
|
||||
|
||||
g.SetPackageNames()
|
||||
g.BuildTypeNameMap()
|
||||
|
||||
g.GenerateAllFiles()
|
||||
|
||||
// Send back the results.
|
||||
data, err = proto.Marshal(g.Response)
|
||||
if err != nil {
|
||||
g.Error(err, "failed to marshal output proto")
|
||||
}
|
||||
_, err = os.Stdout.Write(data)
|
||||
if err != nil {
|
||||
g.Error(err, "failed to write output proto")
|
||||
}
|
||||
}
|
139
vendor/github.com/golang/protobuf/ptypes/any.go
generated
vendored
Normal file
139
vendor/github.com/golang/protobuf/ptypes/any.go
generated
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 ptypes
|
||||
|
||||
// This file implements functions to marshal proto.Message to/from
|
||||
// google.protobuf.Any message.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
)
|
||||
|
||||
const googleApis = "type.googleapis.com/"
|
||||
|
||||
// AnyMessageName returns the name of the message contained in a google.protobuf.Any message.
|
||||
//
|
||||
// Note that regular type assertions should be done using the Is
|
||||
// function. AnyMessageName is provided for less common use cases like filtering a
|
||||
// sequence of Any messages based on a set of allowed message type names.
|
||||
func AnyMessageName(any *any.Any) (string, error) {
|
||||
if any == nil {
|
||||
return "", fmt.Errorf("message is nil")
|
||||
}
|
||||
slash := strings.LastIndex(any.TypeUrl, "/")
|
||||
if slash < 0 {
|
||||
return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
|
||||
}
|
||||
return any.TypeUrl[slash+1:], nil
|
||||
}
|
||||
|
||||
// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any.
|
||||
func MarshalAny(pb proto.Message) (*any.Any, error) {
|
||||
value, err := proto.Marshal(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil
|
||||
}
|
||||
|
||||
// DynamicAny is a value that can be passed to UnmarshalAny to automatically
|
||||
// allocate a proto.Message for the type specified in a google.protobuf.Any
|
||||
// message. The allocated message is stored in the embedded proto.Message.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var x ptypes.DynamicAny
|
||||
// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
|
||||
// fmt.Printf("unmarshaled message: %v", x.Message)
|
||||
type DynamicAny struct {
|
||||
proto.Message
|
||||
}
|
||||
|
||||
// Empty returns a new proto.Message of the type specified in a
|
||||
// google.protobuf.Any message. It returns an error if corresponding message
|
||||
// type isn't linked in.
|
||||
func Empty(any *any.Any) (proto.Message, error) {
|
||||
aname, err := AnyMessageName(any)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t := proto.MessageType(aname)
|
||||
if t == nil {
|
||||
return nil, fmt.Errorf("any: message type %q isn't linked in", aname)
|
||||
}
|
||||
return reflect.New(t.Elem()).Interface().(proto.Message), nil
|
||||
}
|
||||
|
||||
// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any
|
||||
// message and places the decoded result in pb. It returns an error if type of
|
||||
// contents of Any message does not match type of pb message.
|
||||
//
|
||||
// pb can be a proto.Message, or a *DynamicAny.
|
||||
func UnmarshalAny(any *any.Any, pb proto.Message) error {
|
||||
if d, ok := pb.(*DynamicAny); ok {
|
||||
if d.Message == nil {
|
||||
var err error
|
||||
d.Message, err = Empty(any)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return UnmarshalAny(any, d.Message)
|
||||
}
|
||||
|
||||
aname, err := AnyMessageName(any)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mname := proto.MessageName(pb)
|
||||
if aname != mname {
|
||||
return fmt.Errorf("mismatched message type: got %q want %q", aname, mname)
|
||||
}
|
||||
return proto.Unmarshal(any.Value, pb)
|
||||
}
|
||||
|
||||
// Is returns true if any value contains a given message type.
|
||||
func Is(any *any.Any, pb proto.Message) bool {
|
||||
aname, err := AnyMessageName(any)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return aname == proto.MessageName(pb)
|
||||
}
|
191
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
generated
vendored
Normal file
191
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: google/protobuf/any.proto
|
||||
|
||||
package any // import "github.com/golang/protobuf/ptypes/any"
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// `Any` contains an arbitrary serialized protocol buffer message along with a
|
||||
// URL that describes the type of the serialized message.
|
||||
//
|
||||
// Protobuf library provides support to pack/unpack Any values in the form
|
||||
// of utility functions or additional generated methods of the Any type.
|
||||
//
|
||||
// Example 1: Pack and unpack a message in C++.
|
||||
//
|
||||
// Foo foo = ...;
|
||||
// Any any;
|
||||
// any.PackFrom(foo);
|
||||
// ...
|
||||
// if (any.UnpackTo(&foo)) {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// Example 2: Pack and unpack a message in Java.
|
||||
//
|
||||
// Foo foo = ...;
|
||||
// Any any = Any.pack(foo);
|
||||
// ...
|
||||
// if (any.is(Foo.class)) {
|
||||
// foo = any.unpack(Foo.class);
|
||||
// }
|
||||
//
|
||||
// Example 3: Pack and unpack a message in Python.
|
||||
//
|
||||
// foo = Foo(...)
|
||||
// any = Any()
|
||||
// any.Pack(foo)
|
||||
// ...
|
||||
// if any.Is(Foo.DESCRIPTOR):
|
||||
// any.Unpack(foo)
|
||||
// ...
|
||||
//
|
||||
// Example 4: Pack and unpack a message in Go
|
||||
//
|
||||
// foo := &pb.Foo{...}
|
||||
// any, err := ptypes.MarshalAny(foo)
|
||||
// ...
|
||||
// foo := &pb.Foo{}
|
||||
// if err := ptypes.UnmarshalAny(any, foo); err != nil {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// The pack methods provided by protobuf library will by default use
|
||||
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
|
||||
// methods only use the fully qualified type name after the last '/'
|
||||
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
|
||||
// name "y.z".
|
||||
//
|
||||
//
|
||||
// JSON
|
||||
// ====
|
||||
// The JSON representation of an `Any` value uses the regular
|
||||
// representation of the deserialized, embedded message, with an
|
||||
// additional field `@type` which contains the type URL. Example:
|
||||
//
|
||||
// package google.profile;
|
||||
// message Person {
|
||||
// string first_name = 1;
|
||||
// string last_name = 2;
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// "@type": "type.googleapis.com/google.profile.Person",
|
||||
// "firstName": <string>,
|
||||
// "lastName": <string>
|
||||
// }
|
||||
//
|
||||
// If the embedded message type is well-known and has a custom JSON
|
||||
// representation, that representation will be embedded adding a field
|
||||
// `value` which holds the custom JSON in addition to the `@type`
|
||||
// field. Example (for message [google.protobuf.Duration][]):
|
||||
//
|
||||
// {
|
||||
// "@type": "type.googleapis.com/google.protobuf.Duration",
|
||||
// "value": "1.212s"
|
||||
// }
|
||||
//
|
||||
type Any struct {
|
||||
// A URL/resource name whose content describes the type of the
|
||||
// serialized protocol buffer message.
|
||||
//
|
||||
// For URLs which use the scheme `http`, `https`, or no scheme, the
|
||||
// following restrictions and interpretations apply:
|
||||
//
|
||||
// * If no scheme is provided, `https` is assumed.
|
||||
// * The last segment of the URL's path must represent the fully
|
||||
// qualified name of the type (as in `path/google.protobuf.Duration`).
|
||||
// The name should be in a canonical form (e.g., leading "." is
|
||||
// not accepted).
|
||||
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
|
||||
// value in binary format, or produce an error.
|
||||
// * Applications are allowed to cache lookup results based on the
|
||||
// URL, or have them precompiled into a binary to avoid any
|
||||
// lookup. Therefore, binary compatibility needs to be preserved
|
||||
// on changes to types. (Use versioned type names to manage
|
||||
// breaking changes.)
|
||||
//
|
||||
// Schemes other than `http`, `https` (or the empty scheme) might be
|
||||
// used with implementation specific semantics.
|
||||
//
|
||||
TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"`
|
||||
// Must be a valid serialized protocol buffer of the above specified type.
|
||||
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Any) Reset() { *m = Any{} }
|
||||
func (m *Any) String() string { return proto.CompactTextString(m) }
|
||||
func (*Any) ProtoMessage() {}
|
||||
func (*Any) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_any_744b9ca530f228db, []int{0}
|
||||
}
|
||||
func (*Any) XXX_WellKnownType() string { return "Any" }
|
||||
func (m *Any) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Any.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Any.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Any) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Any.Merge(dst, src)
|
||||
}
|
||||
func (m *Any) XXX_Size() int {
|
||||
return xxx_messageInfo_Any.Size(m)
|
||||
}
|
||||
func (m *Any) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Any.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Any proto.InternalMessageInfo
|
||||
|
||||
func (m *Any) GetTypeUrl() string {
|
||||
if m != nil {
|
||||
return m.TypeUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Any) GetValue() []byte {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Any)(nil), "google.protobuf.Any")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_any_744b9ca530f228db) }
|
||||
|
||||
var fileDescriptor_any_744b9ca530f228db = []byte{
|
||||
// 185 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f,
|
||||
0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4,
|
||||
0x03, 0x73, 0x84, 0xf8, 0x21, 0x52, 0x7a, 0x30, 0x29, 0x25, 0x33, 0x2e, 0x66, 0xc7, 0xbc, 0x4a,
|
||||
0x21, 0x49, 0x2e, 0x8e, 0x92, 0xca, 0x82, 0xd4, 0xf8, 0xd2, 0xa2, 0x1c, 0x09, 0x46, 0x05, 0x46,
|
||||
0x0d, 0xce, 0x20, 0x76, 0x10, 0x3f, 0xb4, 0x28, 0x47, 0x48, 0x84, 0x8b, 0xb5, 0x2c, 0x31, 0xa7,
|
||||
0x34, 0x55, 0x82, 0x49, 0x81, 0x51, 0x83, 0x27, 0x08, 0xc2, 0x71, 0xca, 0xe7, 0x12, 0x4e, 0xce,
|
||||
0xcf, 0xd5, 0x43, 0x33, 0xce, 0x89, 0xc3, 0x31, 0xaf, 0x32, 0x00, 0xc4, 0x09, 0x60, 0x8c, 0x52,
|
||||
0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc,
|
||||
0x4b, 0x47, 0xb8, 0xa8, 0x00, 0x64, 0x7a, 0x31, 0xc8, 0x61, 0x8b, 0x98, 0x98, 0xdd, 0x03, 0x9c,
|
||||
0x56, 0x31, 0xc9, 0xb9, 0x43, 0x8c, 0x0a, 0x80, 0x2a, 0xd1, 0x0b, 0x4f, 0xcd, 0xc9, 0xf1, 0xce,
|
||||
0xcb, 0x2f, 0xcf, 0x0b, 0x01, 0x29, 0x4d, 0x62, 0x03, 0xeb, 0x35, 0x06, 0x04, 0x00, 0x00, 0xff,
|
||||
0xff, 0x13, 0xf8, 0xe8, 0x42, 0xdd, 0x00, 0x00, 0x00,
|
||||
}
|
149
vendor/github.com/golang/protobuf/ptypes/any/any.proto
generated
vendored
Normal file
149
vendor/github.com/golang/protobuf/ptypes/any/any.proto
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
|
||||
option go_package = "github.com/golang/protobuf/ptypes/any";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "AnyProto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
// `Any` contains an arbitrary serialized protocol buffer message along with a
|
||||
// URL that describes the type of the serialized message.
|
||||
//
|
||||
// Protobuf library provides support to pack/unpack Any values in the form
|
||||
// of utility functions or additional generated methods of the Any type.
|
||||
//
|
||||
// Example 1: Pack and unpack a message in C++.
|
||||
//
|
||||
// Foo foo = ...;
|
||||
// Any any;
|
||||
// any.PackFrom(foo);
|
||||
// ...
|
||||
// if (any.UnpackTo(&foo)) {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// Example 2: Pack and unpack a message in Java.
|
||||
//
|
||||
// Foo foo = ...;
|
||||
// Any any = Any.pack(foo);
|
||||
// ...
|
||||
// if (any.is(Foo.class)) {
|
||||
// foo = any.unpack(Foo.class);
|
||||
// }
|
||||
//
|
||||
// Example 3: Pack and unpack a message in Python.
|
||||
//
|
||||
// foo = Foo(...)
|
||||
// any = Any()
|
||||
// any.Pack(foo)
|
||||
// ...
|
||||
// if any.Is(Foo.DESCRIPTOR):
|
||||
// any.Unpack(foo)
|
||||
// ...
|
||||
//
|
||||
// Example 4: Pack and unpack a message in Go
|
||||
//
|
||||
// foo := &pb.Foo{...}
|
||||
// any, err := ptypes.MarshalAny(foo)
|
||||
// ...
|
||||
// foo := &pb.Foo{}
|
||||
// if err := ptypes.UnmarshalAny(any, foo); err != nil {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// The pack methods provided by protobuf library will by default use
|
||||
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
|
||||
// methods only use the fully qualified type name after the last '/'
|
||||
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
|
||||
// name "y.z".
|
||||
//
|
||||
//
|
||||
// JSON
|
||||
// ====
|
||||
// The JSON representation of an `Any` value uses the regular
|
||||
// representation of the deserialized, embedded message, with an
|
||||
// additional field `@type` which contains the type URL. Example:
|
||||
//
|
||||
// package google.profile;
|
||||
// message Person {
|
||||
// string first_name = 1;
|
||||
// string last_name = 2;
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// "@type": "type.googleapis.com/google.profile.Person",
|
||||
// "firstName": <string>,
|
||||
// "lastName": <string>
|
||||
// }
|
||||
//
|
||||
// If the embedded message type is well-known and has a custom JSON
|
||||
// representation, that representation will be embedded adding a field
|
||||
// `value` which holds the custom JSON in addition to the `@type`
|
||||
// field. Example (for message [google.protobuf.Duration][]):
|
||||
//
|
||||
// {
|
||||
// "@type": "type.googleapis.com/google.protobuf.Duration",
|
||||
// "value": "1.212s"
|
||||
// }
|
||||
//
|
||||
message Any {
|
||||
// A URL/resource name whose content describes the type of the
|
||||
// serialized protocol buffer message.
|
||||
//
|
||||
// For URLs which use the scheme `http`, `https`, or no scheme, the
|
||||
// following restrictions and interpretations apply:
|
||||
//
|
||||
// * If no scheme is provided, `https` is assumed.
|
||||
// * The last segment of the URL's path must represent the fully
|
||||
// qualified name of the type (as in `path/google.protobuf.Duration`).
|
||||
// The name should be in a canonical form (e.g., leading "." is
|
||||
// not accepted).
|
||||
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
|
||||
// value in binary format, or produce an error.
|
||||
// * Applications are allowed to cache lookup results based on the
|
||||
// URL, or have them precompiled into a binary to avoid any
|
||||
// lookup. Therefore, binary compatibility needs to be preserved
|
||||
// on changes to types. (Use versioned type names to manage
|
||||
// breaking changes.)
|
||||
//
|
||||
// Schemes other than `http`, `https` (or the empty scheme) might be
|
||||
// used with implementation specific semantics.
|
||||
//
|
||||
string type_url = 1;
|
||||
|
||||
// Must be a valid serialized protocol buffer of the above specified type.
|
||||
bytes value = 2;
|
||||
}
|
113
vendor/github.com/golang/protobuf/ptypes/any_test.go
generated
vendored
Normal file
113
vendor/github.com/golang/protobuf/ptypes/any_test.go
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 ptypes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
pb "github.com/golang/protobuf/protoc-gen-go/descriptor"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
)
|
||||
|
||||
func TestMarshalUnmarshal(t *testing.T) {
|
||||
orig := &any.Any{Value: []byte("test")}
|
||||
|
||||
packed, err := MarshalAny(orig)
|
||||
if err != nil {
|
||||
t.Errorf("MarshalAny(%+v): got: _, %v exp: _, nil", orig, err)
|
||||
}
|
||||
|
||||
unpacked := &any.Any{}
|
||||
err = UnmarshalAny(packed, unpacked)
|
||||
if err != nil || !proto.Equal(unpacked, orig) {
|
||||
t.Errorf("got: %v, %+v; want nil, %+v", err, unpacked, orig)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIs(t *testing.T) {
|
||||
a, err := MarshalAny(&pb.FileDescriptorProto{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if Is(a, &pb.DescriptorProto{}) {
|
||||
t.Error("FileDescriptorProto is not a DescriptorProto, but Is says it is")
|
||||
}
|
||||
if !Is(a, &pb.FileDescriptorProto{}) {
|
||||
t.Error("FileDescriptorProto is indeed a FileDescriptorProto, but Is says it is not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDifferentUrlPrefixes(t *testing.T) {
|
||||
m := &pb.FileDescriptorProto{}
|
||||
a := &any.Any{TypeUrl: "foo/bar/" + proto.MessageName(m)}
|
||||
if !Is(a, m) {
|
||||
t.Errorf("message with type url %q didn't satisfy Is for type %q", a.TypeUrl, proto.MessageName(m))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalDynamic(t *testing.T) {
|
||||
want := &pb.FileDescriptorProto{Name: proto.String("foo")}
|
||||
a, err := MarshalAny(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var got DynamicAny
|
||||
if err := UnmarshalAny(a, &got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !proto.Equal(got.Message, want) {
|
||||
t.Errorf("invalid result from UnmarshalAny, got %q want %q", got.Message, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
want := &pb.FileDescriptorProto{}
|
||||
a, err := MarshalAny(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := Empty(a)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !proto.Equal(got, want) {
|
||||
t.Errorf("unequal empty message, got %q, want %q", got, want)
|
||||
}
|
||||
|
||||
// that's a valid type_url for a message which shouldn't be linked into this
|
||||
// test binary. We want an error.
|
||||
a.TypeUrl = "type.googleapis.com/google.protobuf.FieldMask"
|
||||
if _, err := Empty(a); err == nil {
|
||||
t.Errorf("got no error for an attempt to create a message of type %q, which shouldn't be linked in", a.TypeUrl)
|
||||
}
|
||||
}
|
35
vendor/github.com/golang/protobuf/ptypes/doc.go
generated
vendored
Normal file
35
vendor/github.com/golang/protobuf/ptypes/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 ptypes contains code for interacting with well-known types.
|
||||
*/
|
||||
package ptypes
|
102
vendor/github.com/golang/protobuf/ptypes/duration.go
generated
vendored
Normal file
102
vendor/github.com/golang/protobuf/ptypes/duration.go
generated
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 ptypes
|
||||
|
||||
// This file implements conversions between google.protobuf.Duration
|
||||
// and time.Duration.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
durpb "github.com/golang/protobuf/ptypes/duration"
|
||||
)
|
||||
|
||||
const (
|
||||
// Range of a durpb.Duration in seconds, as specified in
|
||||
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
|
||||
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
|
||||
minSeconds = -maxSeconds
|
||||
)
|
||||
|
||||
// validateDuration determines whether the durpb.Duration is valid according to the
|
||||
// definition in google/protobuf/duration.proto. A valid durpb.Duration
|
||||
// may still be too large to fit into a time.Duration (the range of durpb.Duration
|
||||
// is about 10,000 years, and the range of time.Duration is about 290).
|
||||
func validateDuration(d *durpb.Duration) error {
|
||||
if d == nil {
|
||||
return errors.New("duration: nil Duration")
|
||||
}
|
||||
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
|
||||
return fmt.Errorf("duration: %v: seconds out of range", d)
|
||||
}
|
||||
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
|
||||
return fmt.Errorf("duration: %v: nanos out of range", d)
|
||||
}
|
||||
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
|
||||
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
|
||||
return fmt.Errorf("duration: %v: seconds and nanos have different signs", d)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Duration converts a durpb.Duration to a time.Duration. Duration
|
||||
// returns an error if the durpb.Duration is invalid or is too large to be
|
||||
// represented in a time.Duration.
|
||||
func Duration(p *durpb.Duration) (time.Duration, error) {
|
||||
if err := validateDuration(p); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
d := time.Duration(p.Seconds) * time.Second
|
||||
if int64(d/time.Second) != p.Seconds {
|
||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
|
||||
}
|
||||
if p.Nanos != 0 {
|
||||
d += time.Duration(p.Nanos)
|
||||
if (d < 0) != (p.Nanos < 0) {
|
||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
|
||||
}
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// DurationProto converts a time.Duration to a durpb.Duration.
|
||||
func DurationProto(d time.Duration) *durpb.Duration {
|
||||
nanos := d.Nanoseconds()
|
||||
secs := nanos / 1e9
|
||||
nanos -= secs * 1e9
|
||||
return &durpb.Duration{
|
||||
Seconds: secs,
|
||||
Nanos: int32(nanos),
|
||||
}
|
||||
}
|
159
vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go
generated
vendored
Normal file
159
vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: google/protobuf/duration.proto
|
||||
|
||||
package duration // import "github.com/golang/protobuf/ptypes/duration"
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// A Duration represents a signed, fixed-length span of time represented
|
||||
// as a count of seconds and fractions of seconds at nanosecond
|
||||
// resolution. It is independent of any calendar and concepts like "day"
|
||||
// or "month". It is related to Timestamp in that the difference between
|
||||
// two Timestamp values is a Duration and it can be added or subtracted
|
||||
// from a Timestamp. Range is approximately +-10,000 years.
|
||||
//
|
||||
// # Examples
|
||||
//
|
||||
// Example 1: Compute Duration from two Timestamps in pseudo code.
|
||||
//
|
||||
// Timestamp start = ...;
|
||||
// Timestamp end = ...;
|
||||
// Duration duration = ...;
|
||||
//
|
||||
// duration.seconds = end.seconds - start.seconds;
|
||||
// duration.nanos = end.nanos - start.nanos;
|
||||
//
|
||||
// if (duration.seconds < 0 && duration.nanos > 0) {
|
||||
// duration.seconds += 1;
|
||||
// duration.nanos -= 1000000000;
|
||||
// } else if (durations.seconds > 0 && duration.nanos < 0) {
|
||||
// duration.seconds -= 1;
|
||||
// duration.nanos += 1000000000;
|
||||
// }
|
||||
//
|
||||
// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
|
||||
//
|
||||
// Timestamp start = ...;
|
||||
// Duration duration = ...;
|
||||
// Timestamp end = ...;
|
||||
//
|
||||
// end.seconds = start.seconds + duration.seconds;
|
||||
// end.nanos = start.nanos + duration.nanos;
|
||||
//
|
||||
// if (end.nanos < 0) {
|
||||
// end.seconds -= 1;
|
||||
// end.nanos += 1000000000;
|
||||
// } else if (end.nanos >= 1000000000) {
|
||||
// end.seconds += 1;
|
||||
// end.nanos -= 1000000000;
|
||||
// }
|
||||
//
|
||||
// Example 3: Compute Duration from datetime.timedelta in Python.
|
||||
//
|
||||
// td = datetime.timedelta(days=3, minutes=10)
|
||||
// duration = Duration()
|
||||
// duration.FromTimedelta(td)
|
||||
//
|
||||
// # JSON Mapping
|
||||
//
|
||||
// In JSON format, the Duration type is encoded as a string rather than an
|
||||
// object, where the string ends in the suffix "s" (indicating seconds) and
|
||||
// is preceded by the number of seconds, with nanoseconds expressed as
|
||||
// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
|
||||
// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
|
||||
// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
|
||||
// microsecond should be expressed in JSON format as "3.000001s".
|
||||
//
|
||||
//
|
||||
type Duration struct {
|
||||
// Signed seconds of the span of time. Must be from -315,576,000,000
|
||||
// to +315,576,000,000 inclusive. Note: these bounds are computed from:
|
||||
// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
|
||||
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
|
||||
// Signed fractions of a second at nanosecond resolution of the span
|
||||
// of time. Durations less than one second are represented with a 0
|
||||
// `seconds` field and a positive or negative `nanos` field. For durations
|
||||
// of one second or more, a non-zero value for the `nanos` field must be
|
||||
// of the same sign as the `seconds` field. Must be from -999,999,999
|
||||
// to +999,999,999 inclusive.
|
||||
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Duration) Reset() { *m = Duration{} }
|
||||
func (m *Duration) String() string { return proto.CompactTextString(m) }
|
||||
func (*Duration) ProtoMessage() {}
|
||||
func (*Duration) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_duration_e7d612259e3f0613, []int{0}
|
||||
}
|
||||
func (*Duration) XXX_WellKnownType() string { return "Duration" }
|
||||
func (m *Duration) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Duration.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Duration.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Duration) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Duration.Merge(dst, src)
|
||||
}
|
||||
func (m *Duration) XXX_Size() int {
|
||||
return xxx_messageInfo_Duration.Size(m)
|
||||
}
|
||||
func (m *Duration) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Duration.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Duration proto.InternalMessageInfo
|
||||
|
||||
func (m *Duration) GetSeconds() int64 {
|
||||
if m != nil {
|
||||
return m.Seconds
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Duration) GetNanos() int32 {
|
||||
if m != nil {
|
||||
return m.Nanos
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_duration_e7d612259e3f0613)
|
||||
}
|
||||
|
||||
var fileDescriptor_duration_e7d612259e3f0613 = []byte{
|
||||
// 190 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f,
|
||||
0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a,
|
||||
0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x03, 0x8b, 0x08, 0xf1, 0x43, 0xe4, 0xf5, 0x60, 0xf2, 0x4a, 0x56,
|
||||
0x5c, 0x1c, 0x2e, 0x50, 0x25, 0x42, 0x12, 0x5c, 0xec, 0xc5, 0xa9, 0xc9, 0xf9, 0x79, 0x29, 0xc5,
|
||||
0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x30, 0xae, 0x90, 0x08, 0x17, 0x6b, 0x5e, 0x62, 0x5e,
|
||||
0x7e, 0xb1, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x84, 0xe3, 0x54, 0xc3, 0x25, 0x9c, 0x9c,
|
||||
0x9f, 0xab, 0x87, 0x66, 0xa4, 0x13, 0x2f, 0xcc, 0xc0, 0x00, 0x90, 0x48, 0x00, 0x63, 0x94, 0x56,
|
||||
0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e,
|
||||
0x3a, 0xc2, 0x7d, 0x05, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x70, 0x67, 0xfe, 0x60, 0x64, 0x5c, 0xc4,
|
||||
0xc4, 0xec, 0x1e, 0xe0, 0xb4, 0x8a, 0x49, 0xce, 0x1d, 0x62, 0x6e, 0x00, 0x54, 0xa9, 0x5e, 0x78,
|
||||
0x6a, 0x4e, 0x8e, 0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0x48, 0x4b, 0x12, 0x1b, 0xd8, 0x0c, 0x63,
|
||||
0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x84, 0x30, 0xff, 0xf3, 0x00, 0x00, 0x00,
|
||||
}
|
117
vendor/github.com/golang/protobuf/ptypes/duration/duration.proto
generated
vendored
Normal file
117
vendor/github.com/golang/protobuf/ptypes/duration/duration.proto
generated
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
|
||||
option cc_enable_arenas = true;
|
||||
option go_package = "github.com/golang/protobuf/ptypes/duration";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "DurationProto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
// A Duration represents a signed, fixed-length span of time represented
|
||||
// as a count of seconds and fractions of seconds at nanosecond
|
||||
// resolution. It is independent of any calendar and concepts like "day"
|
||||
// or "month". It is related to Timestamp in that the difference between
|
||||
// two Timestamp values is a Duration and it can be added or subtracted
|
||||
// from a Timestamp. Range is approximately +-10,000 years.
|
||||
//
|
||||
// # Examples
|
||||
//
|
||||
// Example 1: Compute Duration from two Timestamps in pseudo code.
|
||||
//
|
||||
// Timestamp start = ...;
|
||||
// Timestamp end = ...;
|
||||
// Duration duration = ...;
|
||||
//
|
||||
// duration.seconds = end.seconds - start.seconds;
|
||||
// duration.nanos = end.nanos - start.nanos;
|
||||
//
|
||||
// if (duration.seconds < 0 && duration.nanos > 0) {
|
||||
// duration.seconds += 1;
|
||||
// duration.nanos -= 1000000000;
|
||||
// } else if (durations.seconds > 0 && duration.nanos < 0) {
|
||||
// duration.seconds -= 1;
|
||||
// duration.nanos += 1000000000;
|
||||
// }
|
||||
//
|
||||
// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
|
||||
//
|
||||
// Timestamp start = ...;
|
||||
// Duration duration = ...;
|
||||
// Timestamp end = ...;
|
||||
//
|
||||
// end.seconds = start.seconds + duration.seconds;
|
||||
// end.nanos = start.nanos + duration.nanos;
|
||||
//
|
||||
// if (end.nanos < 0) {
|
||||
// end.seconds -= 1;
|
||||
// end.nanos += 1000000000;
|
||||
// } else if (end.nanos >= 1000000000) {
|
||||
// end.seconds += 1;
|
||||
// end.nanos -= 1000000000;
|
||||
// }
|
||||
//
|
||||
// Example 3: Compute Duration from datetime.timedelta in Python.
|
||||
//
|
||||
// td = datetime.timedelta(days=3, minutes=10)
|
||||
// duration = Duration()
|
||||
// duration.FromTimedelta(td)
|
||||
//
|
||||
// # JSON Mapping
|
||||
//
|
||||
// In JSON format, the Duration type is encoded as a string rather than an
|
||||
// object, where the string ends in the suffix "s" (indicating seconds) and
|
||||
// is preceded by the number of seconds, with nanoseconds expressed as
|
||||
// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
|
||||
// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
|
||||
// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
|
||||
// microsecond should be expressed in JSON format as "3.000001s".
|
||||
//
|
||||
//
|
||||
message Duration {
|
||||
|
||||
// Signed seconds of the span of time. Must be from -315,576,000,000
|
||||
// to +315,576,000,000 inclusive. Note: these bounds are computed from:
|
||||
// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
|
||||
int64 seconds = 1;
|
||||
|
||||
// Signed fractions of a second at nanosecond resolution of the span
|
||||
// of time. Durations less than one second are represented with a 0
|
||||
// `seconds` field and a positive or negative `nanos` field. For durations
|
||||
// of one second or more, a non-zero value for the `nanos` field must be
|
||||
// of the same sign as the `seconds` field. Must be from -999,999,999
|
||||
// to +999,999,999 inclusive.
|
||||
int32 nanos = 2;
|
||||
}
|
121
vendor/github.com/golang/protobuf/ptypes/duration_test.go
generated
vendored
Normal file
121
vendor/github.com/golang/protobuf/ptypes/duration_test.go
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 ptypes
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
durpb "github.com/golang/protobuf/ptypes/duration"
|
||||
)
|
||||
|
||||
const (
|
||||
minGoSeconds = math.MinInt64 / int64(1e9)
|
||||
maxGoSeconds = math.MaxInt64 / int64(1e9)
|
||||
)
|
||||
|
||||
var durationTests = []struct {
|
||||
proto *durpb.Duration
|
||||
isValid bool
|
||||
inRange bool
|
||||
dur time.Duration
|
||||
}{
|
||||
// The zero duration.
|
||||
{&durpb.Duration{Seconds: 0, Nanos: 0}, true, true, 0},
|
||||
// Some ordinary non-zero durations.
|
||||
{&durpb.Duration{Seconds: 100, Nanos: 0}, true, true, 100 * time.Second},
|
||||
{&durpb.Duration{Seconds: -100, Nanos: 0}, true, true, -100 * time.Second},
|
||||
{&durpb.Duration{Seconds: 100, Nanos: 987}, true, true, 100*time.Second + 987},
|
||||
{&durpb.Duration{Seconds: -100, Nanos: -987}, true, true, -(100*time.Second + 987)},
|
||||
// The largest duration representable in Go.
|
||||
{&durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, true, math.MaxInt64},
|
||||
// The smallest duration representable in Go.
|
||||
{&durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, true, true, math.MinInt64},
|
||||
{nil, false, false, 0},
|
||||
{&durpb.Duration{Seconds: -100, Nanos: 987}, false, false, 0},
|
||||
{&durpb.Duration{Seconds: 100, Nanos: -987}, false, false, 0},
|
||||
{&durpb.Duration{Seconds: math.MinInt64, Nanos: 0}, false, false, 0},
|
||||
{&durpb.Duration{Seconds: math.MaxInt64, Nanos: 0}, false, false, 0},
|
||||
// The largest valid duration.
|
||||
{&durpb.Duration{Seconds: maxSeconds, Nanos: 1e9 - 1}, true, false, 0},
|
||||
// The smallest valid duration.
|
||||
{&durpb.Duration{Seconds: minSeconds, Nanos: -(1e9 - 1)}, true, false, 0},
|
||||
// The smallest invalid duration above the valid range.
|
||||
{&durpb.Duration{Seconds: maxSeconds + 1, Nanos: 0}, false, false, 0},
|
||||
// The largest invalid duration below the valid range.
|
||||
{&durpb.Duration{Seconds: minSeconds - 1, Nanos: -(1e9 - 1)}, false, false, 0},
|
||||
// One nanosecond past the largest duration representable in Go.
|
||||
{&durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64-1e9*maxGoSeconds) + 1}, true, false, 0},
|
||||
// One nanosecond past the smallest duration representable in Go.
|
||||
{&durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64-1e9*minGoSeconds) - 1}, true, false, 0},
|
||||
// One second past the largest duration representable in Go.
|
||||
{&durpb.Duration{Seconds: maxGoSeconds + 1, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, false, 0},
|
||||
// One second past the smallest duration representable in Go.
|
||||
{&durpb.Duration{Seconds: minGoSeconds - 1, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, true, false, 0},
|
||||
}
|
||||
|
||||
func TestValidateDuration(t *testing.T) {
|
||||
for _, test := range durationTests {
|
||||
err := validateDuration(test.proto)
|
||||
gotValid := (err == nil)
|
||||
if gotValid != test.isValid {
|
||||
t.Errorf("validateDuration(%v) = %t, want %t", test.proto, gotValid, test.isValid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDuration(t *testing.T) {
|
||||
for _, test := range durationTests {
|
||||
got, err := Duration(test.proto)
|
||||
gotOK := (err == nil)
|
||||
wantOK := test.isValid && test.inRange
|
||||
if gotOK != wantOK {
|
||||
t.Errorf("Duration(%v) ok = %t, want %t", test.proto, gotOK, wantOK)
|
||||
}
|
||||
if err == nil && got != test.dur {
|
||||
t.Errorf("Duration(%v) = %v, want %v", test.proto, got, test.dur)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationProto(t *testing.T) {
|
||||
for _, test := range durationTests {
|
||||
if test.isValid && test.inRange {
|
||||
got := DurationProto(test.dur)
|
||||
if !proto.Equal(got, test.proto) {
|
||||
t.Errorf("DurationProto(%v) = %v, want %v", test.dur, got, test.proto)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
79
vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
generated
vendored
Normal file
79
vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: google/protobuf/empty.proto
|
||||
|
||||
package empty // import "github.com/golang/protobuf/ptypes/empty"
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// A generic empty message that you can re-use to avoid defining duplicated
|
||||
// empty messages in your APIs. A typical example is to use it as the request
|
||||
// or the response type of an API method. For instance:
|
||||
//
|
||||
// service Foo {
|
||||
// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
|
||||
// }
|
||||
//
|
||||
// The JSON representation for `Empty` is empty JSON object `{}`.
|
||||
type Empty struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Empty) Reset() { *m = Empty{} }
|
||||
func (m *Empty) String() string { return proto.CompactTextString(m) }
|
||||
func (*Empty) ProtoMessage() {}
|
||||
func (*Empty) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_empty_39e6d6db0632e5b2, []int{0}
|
||||
}
|
||||
func (*Empty) XXX_WellKnownType() string { return "Empty" }
|
||||
func (m *Empty) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Empty.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Empty) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Empty.Merge(dst, src)
|
||||
}
|
||||
func (m *Empty) XXX_Size() int {
|
||||
return xxx_messageInfo_Empty.Size(m)
|
||||
}
|
||||
func (m *Empty) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Empty.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Empty proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Empty)(nil), "google.protobuf.Empty")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("google/protobuf/empty.proto", fileDescriptor_empty_39e6d6db0632e5b2) }
|
||||
|
||||
var fileDescriptor_empty_39e6d6db0632e5b2 = []byte{
|
||||
// 148 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0xcf, 0xcf, 0x4f,
|
||||
0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcd, 0x2d, 0x28,
|
||||
0xa9, 0xd4, 0x03, 0x73, 0x85, 0xf8, 0x21, 0x92, 0x7a, 0x30, 0x49, 0x25, 0x76, 0x2e, 0x56, 0x57,
|
||||
0x90, 0xbc, 0x53, 0x19, 0x97, 0x70, 0x72, 0x7e, 0xae, 0x1e, 0x9a, 0xbc, 0x13, 0x17, 0x58, 0x36,
|
||||
0x00, 0xc4, 0x0d, 0x60, 0x8c, 0x52, 0x4f, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf,
|
||||
0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0x47, 0x58, 0x53, 0x50, 0x52, 0x59, 0x90, 0x5a, 0x0c,
|
||||
0xb1, 0xed, 0x07, 0x23, 0xe3, 0x22, 0x26, 0x66, 0xf7, 0x00, 0xa7, 0x55, 0x4c, 0x72, 0xee, 0x10,
|
||||
0x13, 0x03, 0xa0, 0xea, 0xf4, 0xc2, 0x53, 0x73, 0x72, 0xbc, 0xf3, 0xf2, 0xcb, 0xf3, 0x42, 0x40,
|
||||
0xea, 0x93, 0xd8, 0xc0, 0x06, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x64, 0xd4, 0xb3, 0xa6,
|
||||
0xb7, 0x00, 0x00, 0x00,
|
||||
}
|
52
vendor/github.com/golang/protobuf/ptypes/empty/empty.proto
generated
vendored
Normal file
52
vendor/github.com/golang/protobuf/ptypes/empty/empty.proto
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
|
||||
option go_package = "github.com/golang/protobuf/ptypes/empty";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "EmptyProto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
option cc_enable_arenas = true;
|
||||
|
||||
// A generic empty message that you can re-use to avoid defining duplicated
|
||||
// empty messages in your APIs. A typical example is to use it as the request
|
||||
// or the response type of an API method. For instance:
|
||||
//
|
||||
// service Foo {
|
||||
// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
|
||||
// }
|
||||
//
|
||||
// The JSON representation for `Empty` is empty JSON object `{}`.
|
||||
message Empty {}
|
440
vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go
generated
vendored
Normal file
440
vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,440 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: google/protobuf/struct.proto
|
||||
|
||||
package structpb // import "github.com/golang/protobuf/ptypes/struct"
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// `NullValue` is a singleton enumeration to represent the null value for the
|
||||
// `Value` type union.
|
||||
//
|
||||
// The JSON representation for `NullValue` is JSON `null`.
|
||||
type NullValue int32
|
||||
|
||||
const (
|
||||
// Null value.
|
||||
NullValue_NULL_VALUE NullValue = 0
|
||||
)
|
||||
|
||||
var NullValue_name = map[int32]string{
|
||||
0: "NULL_VALUE",
|
||||
}
|
||||
var NullValue_value = map[string]int32{
|
||||
"NULL_VALUE": 0,
|
||||
}
|
||||
|
||||
func (x NullValue) String() string {
|
||||
return proto.EnumName(NullValue_name, int32(x))
|
||||
}
|
||||
func (NullValue) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_struct_3a5a94e0c7801b27, []int{0}
|
||||
}
|
||||
func (NullValue) XXX_WellKnownType() string { return "NullValue" }
|
||||
|
||||
// `Struct` represents a structured data value, consisting of fields
|
||||
// which map to dynamically typed values. In some languages, `Struct`
|
||||
// might be supported by a native representation. For example, in
|
||||
// scripting languages like JS a struct is represented as an
|
||||
// object. The details of that representation are described together
|
||||
// with the proto support for the language.
|
||||
//
|
||||
// The JSON representation for `Struct` is JSON object.
|
||||
type Struct struct {
|
||||
// Unordered map of dynamically typed values.
|
||||
Fields map[string]*Value `protobuf:"bytes,1,rep,name=fields" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Struct) Reset() { *m = Struct{} }
|
||||
func (m *Struct) String() string { return proto.CompactTextString(m) }
|
||||
func (*Struct) ProtoMessage() {}
|
||||
func (*Struct) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_struct_3a5a94e0c7801b27, []int{0}
|
||||
}
|
||||
func (*Struct) XXX_WellKnownType() string { return "Struct" }
|
||||
func (m *Struct) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Struct.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Struct) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Struct.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Struct) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Struct.Merge(dst, src)
|
||||
}
|
||||
func (m *Struct) XXX_Size() int {
|
||||
return xxx_messageInfo_Struct.Size(m)
|
||||
}
|
||||
func (m *Struct) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Struct.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Struct proto.InternalMessageInfo
|
||||
|
||||
func (m *Struct) GetFields() map[string]*Value {
|
||||
if m != nil {
|
||||
return m.Fields
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// `Value` represents a dynamically typed value which can be either
|
||||
// null, a number, a string, a boolean, a recursive struct value, or a
|
||||
// list of values. A producer of value is expected to set one of that
|
||||
// variants, absence of any variant indicates an error.
|
||||
//
|
||||
// The JSON representation for `Value` is JSON value.
|
||||
type Value struct {
|
||||
// The kind of value.
|
||||
//
|
||||
// Types that are valid to be assigned to Kind:
|
||||
// *Value_NullValue
|
||||
// *Value_NumberValue
|
||||
// *Value_StringValue
|
||||
// *Value_BoolValue
|
||||
// *Value_StructValue
|
||||
// *Value_ListValue
|
||||
Kind isValue_Kind `protobuf_oneof:"kind"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Value) Reset() { *m = Value{} }
|
||||
func (m *Value) String() string { return proto.CompactTextString(m) }
|
||||
func (*Value) ProtoMessage() {}
|
||||
func (*Value) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_struct_3a5a94e0c7801b27, []int{1}
|
||||
}
|
||||
func (*Value) XXX_WellKnownType() string { return "Value" }
|
||||
func (m *Value) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Value.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Value.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Value) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Value.Merge(dst, src)
|
||||
}
|
||||
func (m *Value) XXX_Size() int {
|
||||
return xxx_messageInfo_Value.Size(m)
|
||||
}
|
||||
func (m *Value) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Value.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Value proto.InternalMessageInfo
|
||||
|
||||
type isValue_Kind interface {
|
||||
isValue_Kind()
|
||||
}
|
||||
|
||||
type Value_NullValue struct {
|
||||
NullValue NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,enum=google.protobuf.NullValue,oneof"`
|
||||
}
|
||||
type Value_NumberValue struct {
|
||||
NumberValue float64 `protobuf:"fixed64,2,opt,name=number_value,json=numberValue,oneof"`
|
||||
}
|
||||
type Value_StringValue struct {
|
||||
StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,oneof"`
|
||||
}
|
||||
type Value_BoolValue struct {
|
||||
BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,oneof"`
|
||||
}
|
||||
type Value_StructValue struct {
|
||||
StructValue *Struct `protobuf:"bytes,5,opt,name=struct_value,json=structValue,oneof"`
|
||||
}
|
||||
type Value_ListValue struct {
|
||||
ListValue *ListValue `protobuf:"bytes,6,opt,name=list_value,json=listValue,oneof"`
|
||||
}
|
||||
|
||||
func (*Value_NullValue) isValue_Kind() {}
|
||||
func (*Value_NumberValue) isValue_Kind() {}
|
||||
func (*Value_StringValue) isValue_Kind() {}
|
||||
func (*Value_BoolValue) isValue_Kind() {}
|
||||
func (*Value_StructValue) isValue_Kind() {}
|
||||
func (*Value_ListValue) isValue_Kind() {}
|
||||
|
||||
func (m *Value) GetKind() isValue_Kind {
|
||||
if m != nil {
|
||||
return m.Kind
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Value) GetNullValue() NullValue {
|
||||
if x, ok := m.GetKind().(*Value_NullValue); ok {
|
||||
return x.NullValue
|
||||
}
|
||||
return NullValue_NULL_VALUE
|
||||
}
|
||||
|
||||
func (m *Value) GetNumberValue() float64 {
|
||||
if x, ok := m.GetKind().(*Value_NumberValue); ok {
|
||||
return x.NumberValue
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Value) GetStringValue() string {
|
||||
if x, ok := m.GetKind().(*Value_StringValue); ok {
|
||||
return x.StringValue
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Value) GetBoolValue() bool {
|
||||
if x, ok := m.GetKind().(*Value_BoolValue); ok {
|
||||
return x.BoolValue
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Value) GetStructValue() *Struct {
|
||||
if x, ok := m.GetKind().(*Value_StructValue); ok {
|
||||
return x.StructValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Value) GetListValue() *ListValue {
|
||||
if x, ok := m.GetKind().(*Value_ListValue); ok {
|
||||
return x.ListValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// XXX_OneofFuncs is for the internal use of the proto package.
|
||||
func (*Value) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
|
||||
return _Value_OneofMarshaler, _Value_OneofUnmarshaler, _Value_OneofSizer, []interface{}{
|
||||
(*Value_NullValue)(nil),
|
||||
(*Value_NumberValue)(nil),
|
||||
(*Value_StringValue)(nil),
|
||||
(*Value_BoolValue)(nil),
|
||||
(*Value_StructValue)(nil),
|
||||
(*Value_ListValue)(nil),
|
||||
}
|
||||
}
|
||||
|
||||
func _Value_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
|
||||
m := msg.(*Value)
|
||||
// kind
|
||||
switch x := m.Kind.(type) {
|
||||
case *Value_NullValue:
|
||||
b.EncodeVarint(1<<3 | proto.WireVarint)
|
||||
b.EncodeVarint(uint64(x.NullValue))
|
||||
case *Value_NumberValue:
|
||||
b.EncodeVarint(2<<3 | proto.WireFixed64)
|
||||
b.EncodeFixed64(math.Float64bits(x.NumberValue))
|
||||
case *Value_StringValue:
|
||||
b.EncodeVarint(3<<3 | proto.WireBytes)
|
||||
b.EncodeStringBytes(x.StringValue)
|
||||
case *Value_BoolValue:
|
||||
t := uint64(0)
|
||||
if x.BoolValue {
|
||||
t = 1
|
||||
}
|
||||
b.EncodeVarint(4<<3 | proto.WireVarint)
|
||||
b.EncodeVarint(t)
|
||||
case *Value_StructValue:
|
||||
b.EncodeVarint(5<<3 | proto.WireBytes)
|
||||
if err := b.EncodeMessage(x.StructValue); err != nil {
|
||||
return err
|
||||
}
|
||||
case *Value_ListValue:
|
||||
b.EncodeVarint(6<<3 | proto.WireBytes)
|
||||
if err := b.EncodeMessage(x.ListValue); err != nil {
|
||||
return err
|
||||
}
|
||||
case nil:
|
||||
default:
|
||||
return fmt.Errorf("Value.Kind has unexpected type %T", x)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func _Value_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
|
||||
m := msg.(*Value)
|
||||
switch tag {
|
||||
case 1: // kind.null_value
|
||||
if wire != proto.WireVarint {
|
||||
return true, proto.ErrInternalBadWireType
|
||||
}
|
||||
x, err := b.DecodeVarint()
|
||||
m.Kind = &Value_NullValue{NullValue(x)}
|
||||
return true, err
|
||||
case 2: // kind.number_value
|
||||
if wire != proto.WireFixed64 {
|
||||
return true, proto.ErrInternalBadWireType
|
||||
}
|
||||
x, err := b.DecodeFixed64()
|
||||
m.Kind = &Value_NumberValue{math.Float64frombits(x)}
|
||||
return true, err
|
||||
case 3: // kind.string_value
|
||||
if wire != proto.WireBytes {
|
||||
return true, proto.ErrInternalBadWireType
|
||||
}
|
||||
x, err := b.DecodeStringBytes()
|
||||
m.Kind = &Value_StringValue{x}
|
||||
return true, err
|
||||
case 4: // kind.bool_value
|
||||
if wire != proto.WireVarint {
|
||||
return true, proto.ErrInternalBadWireType
|
||||
}
|
||||
x, err := b.DecodeVarint()
|
||||
m.Kind = &Value_BoolValue{x != 0}
|
||||
return true, err
|
||||
case 5: // kind.struct_value
|
||||
if wire != proto.WireBytes {
|
||||
return true, proto.ErrInternalBadWireType
|
||||
}
|
||||
msg := new(Struct)
|
||||
err := b.DecodeMessage(msg)
|
||||
m.Kind = &Value_StructValue{msg}
|
||||
return true, err
|
||||
case 6: // kind.list_value
|
||||
if wire != proto.WireBytes {
|
||||
return true, proto.ErrInternalBadWireType
|
||||
}
|
||||
msg := new(ListValue)
|
||||
err := b.DecodeMessage(msg)
|
||||
m.Kind = &Value_ListValue{msg}
|
||||
return true, err
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func _Value_OneofSizer(msg proto.Message) (n int) {
|
||||
m := msg.(*Value)
|
||||
// kind
|
||||
switch x := m.Kind.(type) {
|
||||
case *Value_NullValue:
|
||||
n += 1 // tag and wire
|
||||
n += proto.SizeVarint(uint64(x.NullValue))
|
||||
case *Value_NumberValue:
|
||||
n += 1 // tag and wire
|
||||
n += 8
|
||||
case *Value_StringValue:
|
||||
n += 1 // tag and wire
|
||||
n += proto.SizeVarint(uint64(len(x.StringValue)))
|
||||
n += len(x.StringValue)
|
||||
case *Value_BoolValue:
|
||||
n += 1 // tag and wire
|
||||
n += 1
|
||||
case *Value_StructValue:
|
||||
s := proto.Size(x.StructValue)
|
||||
n += 1 // tag and wire
|
||||
n += proto.SizeVarint(uint64(s))
|
||||
n += s
|
||||
case *Value_ListValue:
|
||||
s := proto.Size(x.ListValue)
|
||||
n += 1 // tag and wire
|
||||
n += proto.SizeVarint(uint64(s))
|
||||
n += s
|
||||
case nil:
|
||||
default:
|
||||
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// `ListValue` is a wrapper around a repeated field of values.
|
||||
//
|
||||
// The JSON representation for `ListValue` is JSON array.
|
||||
type ListValue struct {
|
||||
// Repeated field of dynamically typed values.
|
||||
Values []*Value `protobuf:"bytes,1,rep,name=values" json:"values,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListValue) Reset() { *m = ListValue{} }
|
||||
func (m *ListValue) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListValue) ProtoMessage() {}
|
||||
func (*ListValue) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_struct_3a5a94e0c7801b27, []int{2}
|
||||
}
|
||||
func (*ListValue) XXX_WellKnownType() string { return "ListValue" }
|
||||
func (m *ListValue) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListValue.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListValue.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *ListValue) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListValue.Merge(dst, src)
|
||||
}
|
||||
func (m *ListValue) XXX_Size() int {
|
||||
return xxx_messageInfo_ListValue.Size(m)
|
||||
}
|
||||
func (m *ListValue) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListValue.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListValue proto.InternalMessageInfo
|
||||
|
||||
func (m *ListValue) GetValues() []*Value {
|
||||
if m != nil {
|
||||
return m.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Struct)(nil), "google.protobuf.Struct")
|
||||
proto.RegisterMapType((map[string]*Value)(nil), "google.protobuf.Struct.FieldsEntry")
|
||||
proto.RegisterType((*Value)(nil), "google.protobuf.Value")
|
||||
proto.RegisterType((*ListValue)(nil), "google.protobuf.ListValue")
|
||||
proto.RegisterEnum("google.protobuf.NullValue", NullValue_name, NullValue_value)
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("google/protobuf/struct.proto", fileDescriptor_struct_3a5a94e0c7801b27)
|
||||
}
|
||||
|
||||
var fileDescriptor_struct_3a5a94e0c7801b27 = []byte{
|
||||
// 417 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x41, 0x8b, 0xd3, 0x40,
|
||||
0x14, 0xc7, 0x3b, 0xc9, 0x36, 0x98, 0x17, 0x59, 0x97, 0x11, 0xb4, 0xac, 0xa2, 0xa1, 0x7b, 0x09,
|
||||
0x22, 0x29, 0xd6, 0x8b, 0x18, 0x2f, 0x06, 0xd6, 0x5d, 0x30, 0x2c, 0x31, 0xba, 0x15, 0xbc, 0x94,
|
||||
0x26, 0x4d, 0x63, 0xe8, 0x74, 0x26, 0x24, 0x33, 0x4a, 0x8f, 0x7e, 0x0b, 0xcf, 0x1e, 0x3d, 0xfa,
|
||||
0xe9, 0x3c, 0xca, 0xcc, 0x24, 0xa9, 0xb4, 0xf4, 0x94, 0xbc, 0xf7, 0x7e, 0xef, 0x3f, 0xef, 0xff,
|
||||
0x66, 0xe0, 0x71, 0xc1, 0x58, 0x41, 0xf2, 0x49, 0x55, 0x33, 0xce, 0x52, 0xb1, 0x9a, 0x34, 0xbc,
|
||||
0x16, 0x19, 0xf7, 0x55, 0x8c, 0xef, 0xe9, 0xaa, 0xdf, 0x55, 0xc7, 0x3f, 0x11, 0x58, 0x1f, 0x15,
|
||||
0x81, 0x03, 0xb0, 0x56, 0x65, 0x4e, 0x96, 0xcd, 0x08, 0xb9, 0xa6, 0xe7, 0x4c, 0x2f, 0xfc, 0x3d,
|
||||
0xd8, 0xd7, 0xa0, 0xff, 0x4e, 0x51, 0x97, 0x94, 0xd7, 0xdb, 0xa4, 0x6d, 0x39, 0xff, 0x00, 0xce,
|
||||
0x7f, 0x69, 0x7c, 0x06, 0xe6, 0x3a, 0xdf, 0x8e, 0x90, 0x8b, 0x3c, 0x3b, 0x91, 0xbf, 0xf8, 0x39,
|
||||
0x0c, 0xbf, 0x2d, 0x88, 0xc8, 0x47, 0x86, 0x8b, 0x3c, 0x67, 0xfa, 0xe0, 0x40, 0x7c, 0x26, 0xab,
|
||||
0x89, 0x86, 0x5e, 0x1b, 0xaf, 0xd0, 0xf8, 0x8f, 0x01, 0x43, 0x95, 0xc4, 0x01, 0x00, 0x15, 0x84,
|
||||
0xcc, 0xb5, 0x80, 0x14, 0x3d, 0x9d, 0x9e, 0x1f, 0x08, 0xdc, 0x08, 0x42, 0x14, 0x7f, 0x3d, 0x48,
|
||||
0x6c, 0xda, 0x05, 0xf8, 0x02, 0xee, 0x52, 0xb1, 0x49, 0xf3, 0x7a, 0xbe, 0x3b, 0x1f, 0x5d, 0x0f,
|
||||
0x12, 0x47, 0x67, 0x7b, 0xa8, 0xe1, 0x75, 0x49, 0x8b, 0x16, 0x32, 0xe5, 0xe0, 0x12, 0xd2, 0x59,
|
||||
0x0d, 0x3d, 0x05, 0x48, 0x19, 0xeb, 0xc6, 0x38, 0x71, 0x91, 0x77, 0x47, 0x1e, 0x25, 0x73, 0x1a,
|
||||
0x78, 0xa3, 0x54, 0x44, 0xc6, 0x5b, 0x64, 0xa8, 0xac, 0x3e, 0x3c, 0xb2, 0xc7, 0x56, 0x5e, 0x64,
|
||||
0xbc, 0x77, 0x49, 0xca, 0xa6, 0xeb, 0xb5, 0x54, 0xef, 0xa1, 0xcb, 0xa8, 0x6c, 0x78, 0xef, 0x92,
|
||||
0x74, 0x41, 0x68, 0xc1, 0xc9, 0xba, 0xa4, 0xcb, 0x71, 0x00, 0x76, 0x4f, 0x60, 0x1f, 0x2c, 0x25,
|
||||
0xd6, 0xdd, 0xe8, 0xb1, 0xa5, 0xb7, 0xd4, 0xb3, 0x47, 0x60, 0xf7, 0x4b, 0xc4, 0xa7, 0x00, 0x37,
|
||||
0xb7, 0x51, 0x34, 0x9f, 0xbd, 0x8d, 0x6e, 0x2f, 0xcf, 0x06, 0xe1, 0x0f, 0x04, 0xf7, 0x33, 0xb6,
|
||||
0xd9, 0x97, 0x08, 0x1d, 0xed, 0x26, 0x96, 0x71, 0x8c, 0xbe, 0xbc, 0x28, 0x4a, 0xfe, 0x55, 0xa4,
|
||||
0x7e, 0xc6, 0x36, 0x93, 0x82, 0x91, 0x05, 0x2d, 0x76, 0x4f, 0xb1, 0xe2, 0xdb, 0x2a, 0x6f, 0xda,
|
||||
0x17, 0x19, 0xe8, 0x4f, 0x95, 0xfe, 0x45, 0xe8, 0x97, 0x61, 0x5e, 0xc5, 0xe1, 0x6f, 0xe3, 0xc9,
|
||||
0x95, 0x16, 0x8f, 0xbb, 0xf9, 0x3e, 0xe7, 0x84, 0xbc, 0xa7, 0xec, 0x3b, 0xfd, 0x24, 0x3b, 0x53,
|
||||
0x4b, 0x49, 0xbd, 0xfc, 0x17, 0x00, 0x00, 0xff, 0xff, 0xe8, 0x1b, 0x59, 0xf8, 0xe5, 0x02, 0x00,
|
||||
0x00,
|
||||
}
|
96
vendor/github.com/golang/protobuf/ptypes/struct/struct.proto
generated
vendored
Normal file
96
vendor/github.com/golang/protobuf/ptypes/struct/struct.proto
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
|
||||
option cc_enable_arenas = true;
|
||||
option go_package = "github.com/golang/protobuf/ptypes/struct;structpb";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "StructProto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
|
||||
// `Struct` represents a structured data value, consisting of fields
|
||||
// which map to dynamically typed values. In some languages, `Struct`
|
||||
// might be supported by a native representation. For example, in
|
||||
// scripting languages like JS a struct is represented as an
|
||||
// object. The details of that representation are described together
|
||||
// with the proto support for the language.
|
||||
//
|
||||
// The JSON representation for `Struct` is JSON object.
|
||||
message Struct {
|
||||
// Unordered map of dynamically typed values.
|
||||
map<string, Value> fields = 1;
|
||||
}
|
||||
|
||||
// `Value` represents a dynamically typed value which can be either
|
||||
// null, a number, a string, a boolean, a recursive struct value, or a
|
||||
// list of values. A producer of value is expected to set one of that
|
||||
// variants, absence of any variant indicates an error.
|
||||
//
|
||||
// The JSON representation for `Value` is JSON value.
|
||||
message Value {
|
||||
// The kind of value.
|
||||
oneof kind {
|
||||
// Represents a null value.
|
||||
NullValue null_value = 1;
|
||||
// Represents a double value.
|
||||
double number_value = 2;
|
||||
// Represents a string value.
|
||||
string string_value = 3;
|
||||
// Represents a boolean value.
|
||||
bool bool_value = 4;
|
||||
// Represents a structured value.
|
||||
Struct struct_value = 5;
|
||||
// Represents a repeated `Value`.
|
||||
ListValue list_value = 6;
|
||||
}
|
||||
}
|
||||
|
||||
// `NullValue` is a singleton enumeration to represent the null value for the
|
||||
// `Value` type union.
|
||||
//
|
||||
// The JSON representation for `NullValue` is JSON `null`.
|
||||
enum NullValue {
|
||||
// Null value.
|
||||
NULL_VALUE = 0;
|
||||
}
|
||||
|
||||
// `ListValue` is a wrapper around a repeated field of values.
|
||||
//
|
||||
// The JSON representation for `ListValue` is JSON array.
|
||||
message ListValue {
|
||||
// Repeated field of dynamically typed values.
|
||||
repeated Value values = 1;
|
||||
}
|
134
vendor/github.com/golang/protobuf/ptypes/timestamp.go
generated
vendored
Normal file
134
vendor/github.com/golang/protobuf/ptypes/timestamp.go
generated
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 ptypes
|
||||
|
||||
// This file implements operations on google.protobuf.Timestamp.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
tspb "github.com/golang/protobuf/ptypes/timestamp"
|
||||
)
|
||||
|
||||
const (
|
||||
// Seconds field of the earliest valid Timestamp.
|
||||
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
minValidSeconds = -62135596800
|
||||
// Seconds field just after the latest valid Timestamp.
|
||||
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
maxValidSeconds = 253402300800
|
||||
)
|
||||
|
||||
// validateTimestamp determines whether a Timestamp is valid.
|
||||
// A valid timestamp represents a time in the range
|
||||
// [0001-01-01, 10000-01-01) and has a Nanos field
|
||||
// in the range [0, 1e9).
|
||||
//
|
||||
// If the Timestamp is valid, validateTimestamp returns nil.
|
||||
// Otherwise, it returns an error that describes
|
||||
// the problem.
|
||||
//
|
||||
// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
|
||||
func validateTimestamp(ts *tspb.Timestamp) error {
|
||||
if ts == nil {
|
||||
return errors.New("timestamp: nil Timestamp")
|
||||
}
|
||||
if ts.Seconds < minValidSeconds {
|
||||
return fmt.Errorf("timestamp: %v before 0001-01-01", ts)
|
||||
}
|
||||
if ts.Seconds >= maxValidSeconds {
|
||||
return fmt.Errorf("timestamp: %v after 10000-01-01", ts)
|
||||
}
|
||||
if ts.Nanos < 0 || ts.Nanos >= 1e9 {
|
||||
return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Timestamp converts a google.protobuf.Timestamp proto to a time.Time.
|
||||
// It returns an error if the argument is invalid.
|
||||
//
|
||||
// Unlike most Go functions, if Timestamp returns an error, the first return value
|
||||
// is not the zero time.Time. Instead, it is the value obtained from the
|
||||
// time.Unix function when passed the contents of the Timestamp, in the UTC
|
||||
// locale. This may or may not be a meaningful time; many invalid Timestamps
|
||||
// do map to valid time.Times.
|
||||
//
|
||||
// A nil Timestamp returns an error. The first return value in that case is
|
||||
// undefined.
|
||||
func Timestamp(ts *tspb.Timestamp) (time.Time, error) {
|
||||
// Don't return the zero value on error, because corresponds to a valid
|
||||
// timestamp. Instead return whatever time.Unix gives us.
|
||||
var t time.Time
|
||||
if ts == nil {
|
||||
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
|
||||
} else {
|
||||
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
|
||||
}
|
||||
return t, validateTimestamp(ts)
|
||||
}
|
||||
|
||||
// TimestampNow returns a google.protobuf.Timestamp for the current time.
|
||||
func TimestampNow() *tspb.Timestamp {
|
||||
ts, err := TimestampProto(time.Now())
|
||||
if err != nil {
|
||||
panic("ptypes: time.Now() out of Timestamp range")
|
||||
}
|
||||
return ts
|
||||
}
|
||||
|
||||
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
|
||||
// It returns an error if the resulting Timestamp is invalid.
|
||||
func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
|
||||
seconds := t.Unix()
|
||||
nanos := int32(t.Sub(time.Unix(seconds, 0)))
|
||||
ts := &tspb.Timestamp{
|
||||
Seconds: seconds,
|
||||
Nanos: nanos,
|
||||
}
|
||||
if err := validateTimestamp(ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
|
||||
// Timestamps, it returns an error message in parentheses.
|
||||
func TimestampString(ts *tspb.Timestamp) string {
|
||||
t, err := Timestamp(ts)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("(%v)", err)
|
||||
}
|
||||
return t.Format(time.RFC3339Nano)
|
||||
}
|
175
vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go
generated
vendored
Normal file
175
vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: google/protobuf/timestamp.proto
|
||||
|
||||
package timestamp // import "github.com/golang/protobuf/ptypes/timestamp"
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// A Timestamp represents a point in time independent of any time zone
|
||||
// or calendar, represented as seconds and fractions of seconds at
|
||||
// nanosecond resolution in UTC Epoch time. It is encoded using the
|
||||
// Proleptic Gregorian Calendar which extends the Gregorian calendar
|
||||
// backwards to year one. It is encoded assuming all minutes are 60
|
||||
// seconds long, i.e. leap seconds are "smeared" so that no leap second
|
||||
// table is needed for interpretation. Range is from
|
||||
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
|
||||
// By restricting to that range, we ensure that we can convert to
|
||||
// and from RFC 3339 date strings.
|
||||
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
|
||||
//
|
||||
// # Examples
|
||||
//
|
||||
// Example 1: Compute Timestamp from POSIX `time()`.
|
||||
//
|
||||
// Timestamp timestamp;
|
||||
// timestamp.set_seconds(time(NULL));
|
||||
// timestamp.set_nanos(0);
|
||||
//
|
||||
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
|
||||
//
|
||||
// struct timeval tv;
|
||||
// gettimeofday(&tv, NULL);
|
||||
//
|
||||
// Timestamp timestamp;
|
||||
// timestamp.set_seconds(tv.tv_sec);
|
||||
// timestamp.set_nanos(tv.tv_usec * 1000);
|
||||
//
|
||||
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
|
||||
//
|
||||
// FILETIME ft;
|
||||
// GetSystemTimeAsFileTime(&ft);
|
||||
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
|
||||
//
|
||||
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
|
||||
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
|
||||
// Timestamp timestamp;
|
||||
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
|
||||
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
|
||||
//
|
||||
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
|
||||
//
|
||||
// long millis = System.currentTimeMillis();
|
||||
//
|
||||
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
|
||||
// .setNanos((int) ((millis % 1000) * 1000000)).build();
|
||||
//
|
||||
//
|
||||
// Example 5: Compute Timestamp from current time in Python.
|
||||
//
|
||||
// timestamp = Timestamp()
|
||||
// timestamp.GetCurrentTime()
|
||||
//
|
||||
// # JSON Mapping
|
||||
//
|
||||
// In JSON format, the Timestamp type is encoded as a string in the
|
||||
// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
|
||||
// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
|
||||
// where {year} is always expressed using four digits while {month}, {day},
|
||||
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
|
||||
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
|
||||
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
|
||||
// is required, though only UTC (as indicated by "Z") is presently supported.
|
||||
//
|
||||
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
|
||||
// 01:30 UTC on January 15, 2017.
|
||||
//
|
||||
// In JavaScript, one can convert a Date object to this format using the
|
||||
// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
|
||||
// method. In Python, a standard `datetime.datetime` object can be converted
|
||||
// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
|
||||
// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
|
||||
// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
|
||||
// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--)
|
||||
// to obtain a formatter capable of generating timestamps in this format.
|
||||
//
|
||||
//
|
||||
type Timestamp struct {
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
|
||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||
// second values with fractions must still have non-negative nanos values
|
||||
// that count forward in time. Must be from 0 to 999,999,999
|
||||
// inclusive.
|
||||
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Timestamp) Reset() { *m = Timestamp{} }
|
||||
func (m *Timestamp) String() string { return proto.CompactTextString(m) }
|
||||
func (*Timestamp) ProtoMessage() {}
|
||||
func (*Timestamp) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_timestamp_b826e8e5fba671a8, []int{0}
|
||||
}
|
||||
func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" }
|
||||
func (m *Timestamp) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Timestamp.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Timestamp) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Timestamp.Merge(dst, src)
|
||||
}
|
||||
func (m *Timestamp) XXX_Size() int {
|
||||
return xxx_messageInfo_Timestamp.Size(m)
|
||||
}
|
||||
func (m *Timestamp) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Timestamp.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Timestamp proto.InternalMessageInfo
|
||||
|
||||
func (m *Timestamp) GetSeconds() int64 {
|
||||
if m != nil {
|
||||
return m.Seconds
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Timestamp) GetNanos() int32 {
|
||||
if m != nil {
|
||||
return m.Nanos
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_timestamp_b826e8e5fba671a8)
|
||||
}
|
||||
|
||||
var fileDescriptor_timestamp_b826e8e5fba671a8 = []byte{
|
||||
// 191 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f,
|
||||
0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d,
|
||||
0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x03, 0x0b, 0x09, 0xf1, 0x43, 0x14, 0xe8, 0xc1, 0x14, 0x28,
|
||||
0x59, 0x73, 0x71, 0x86, 0xc0, 0xd4, 0x08, 0x49, 0x70, 0xb1, 0x17, 0xa7, 0x26, 0xe7, 0xe7, 0xa5,
|
||||
0x14, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x30, 0x07, 0xc1, 0xb8, 0x42, 0x22, 0x5c, 0xac, 0x79, 0x89,
|
||||
0x79, 0xf9, 0xc5, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xac, 0x41, 0x10, 0x8e, 0x53, 0x1d, 0x97, 0x70,
|
||||
0x72, 0x7e, 0xae, 0x1e, 0x9a, 0x99, 0x4e, 0x7c, 0x70, 0x13, 0x03, 0x40, 0x42, 0x01, 0x8c, 0x51,
|
||||
0xda, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xe9, 0xf9, 0x39, 0x89,
|
||||
0x79, 0xe9, 0x08, 0x27, 0x16, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x23, 0x5c, 0xfa, 0x83, 0x91, 0x71,
|
||||
0x11, 0x13, 0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xc9, 0x01, 0x50, 0xb5, 0x7a,
|
||||
0xe1, 0xa9, 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x3d, 0x49, 0x6c, 0x60, 0x43,
|
||||
0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x77, 0x4a, 0x07, 0xf7, 0x00, 0x00, 0x00,
|
||||
}
|
133
vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
generated
vendored
Normal file
133
vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
|
||||
option cc_enable_arenas = true;
|
||||
option go_package = "github.com/golang/protobuf/ptypes/timestamp";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "TimestampProto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
// A Timestamp represents a point in time independent of any time zone
|
||||
// or calendar, represented as seconds and fractions of seconds at
|
||||
// nanosecond resolution in UTC Epoch time. It is encoded using the
|
||||
// Proleptic Gregorian Calendar which extends the Gregorian calendar
|
||||
// backwards to year one. It is encoded assuming all minutes are 60
|
||||
// seconds long, i.e. leap seconds are "smeared" so that no leap second
|
||||
// table is needed for interpretation. Range is from
|
||||
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
|
||||
// By restricting to that range, we ensure that we can convert to
|
||||
// and from RFC 3339 date strings.
|
||||
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
|
||||
//
|
||||
// # Examples
|
||||
//
|
||||
// Example 1: Compute Timestamp from POSIX `time()`.
|
||||
//
|
||||
// Timestamp timestamp;
|
||||
// timestamp.set_seconds(time(NULL));
|
||||
// timestamp.set_nanos(0);
|
||||
//
|
||||
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
|
||||
//
|
||||
// struct timeval tv;
|
||||
// gettimeofday(&tv, NULL);
|
||||
//
|
||||
// Timestamp timestamp;
|
||||
// timestamp.set_seconds(tv.tv_sec);
|
||||
// timestamp.set_nanos(tv.tv_usec * 1000);
|
||||
//
|
||||
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
|
||||
//
|
||||
// FILETIME ft;
|
||||
// GetSystemTimeAsFileTime(&ft);
|
||||
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
|
||||
//
|
||||
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
|
||||
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
|
||||
// Timestamp timestamp;
|
||||
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
|
||||
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
|
||||
//
|
||||
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
|
||||
//
|
||||
// long millis = System.currentTimeMillis();
|
||||
//
|
||||
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
|
||||
// .setNanos((int) ((millis % 1000) * 1000000)).build();
|
||||
//
|
||||
//
|
||||
// Example 5: Compute Timestamp from current time in Python.
|
||||
//
|
||||
// timestamp = Timestamp()
|
||||
// timestamp.GetCurrentTime()
|
||||
//
|
||||
// # JSON Mapping
|
||||
//
|
||||
// In JSON format, the Timestamp type is encoded as a string in the
|
||||
// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
|
||||
// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
|
||||
// where {year} is always expressed using four digits while {month}, {day},
|
||||
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
|
||||
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
|
||||
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
|
||||
// is required, though only UTC (as indicated by "Z") is presently supported.
|
||||
//
|
||||
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
|
||||
// 01:30 UTC on January 15, 2017.
|
||||
//
|
||||
// In JavaScript, one can convert a Date object to this format using the
|
||||
// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
|
||||
// method. In Python, a standard `datetime.datetime` object can be converted
|
||||
// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
|
||||
// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
|
||||
// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
|
||||
// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--)
|
||||
// to obtain a formatter capable of generating timestamps in this format.
|
||||
//
|
||||
//
|
||||
message Timestamp {
|
||||
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
int64 seconds = 1;
|
||||
|
||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||
// second values with fractions must still have non-negative nanos values
|
||||
// that count forward in time. Must be from 0 to 999,999,999
|
||||
// inclusive.
|
||||
int32 nanos = 2;
|
||||
}
|
153
vendor/github.com/golang/protobuf/ptypes/timestamp_test.go
generated
vendored
Normal file
153
vendor/github.com/golang/protobuf/ptypes/timestamp_test.go
generated
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 ptypes
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
tspb "github.com/golang/protobuf/ptypes/timestamp"
|
||||
)
|
||||
|
||||
var tests = []struct {
|
||||
ts *tspb.Timestamp
|
||||
valid bool
|
||||
t time.Time
|
||||
}{
|
||||
// The timestamp representing the Unix epoch date.
|
||||
{&tspb.Timestamp{Seconds: 0, Nanos: 0}, true, utcDate(1970, 1, 1)},
|
||||
// The smallest representable timestamp.
|
||||
{&tspb.Timestamp{Seconds: math.MinInt64, Nanos: math.MinInt32}, false,
|
||||
time.Unix(math.MinInt64, math.MinInt32).UTC()},
|
||||
// The smallest representable timestamp with non-negative nanos.
|
||||
{&tspb.Timestamp{Seconds: math.MinInt64, Nanos: 0}, false, time.Unix(math.MinInt64, 0).UTC()},
|
||||
// The earliest valid timestamp.
|
||||
{&tspb.Timestamp{Seconds: minValidSeconds, Nanos: 0}, true, utcDate(1, 1, 1)},
|
||||
//"0001-01-01T00:00:00Z"},
|
||||
// The largest representable timestamp.
|
||||
{&tspb.Timestamp{Seconds: math.MaxInt64, Nanos: math.MaxInt32}, false,
|
||||
time.Unix(math.MaxInt64, math.MaxInt32).UTC()},
|
||||
// The largest representable timestamp with nanos in range.
|
||||
{&tspb.Timestamp{Seconds: math.MaxInt64, Nanos: 1e9 - 1}, false,
|
||||
time.Unix(math.MaxInt64, 1e9-1).UTC()},
|
||||
// The largest valid timestamp.
|
||||
{&tspb.Timestamp{Seconds: maxValidSeconds - 1, Nanos: 1e9 - 1}, true,
|
||||
time.Date(9999, 12, 31, 23, 59, 59, 1e9-1, time.UTC)},
|
||||
// The smallest invalid timestamp that is larger than the valid range.
|
||||
{&tspb.Timestamp{Seconds: maxValidSeconds, Nanos: 0}, false, time.Unix(maxValidSeconds, 0).UTC()},
|
||||
// A date before the epoch.
|
||||
{&tspb.Timestamp{Seconds: -281836800, Nanos: 0}, true, utcDate(1961, 1, 26)},
|
||||
// A date after the epoch.
|
||||
{&tspb.Timestamp{Seconds: 1296000000, Nanos: 0}, true, utcDate(2011, 1, 26)},
|
||||
// A date after the epoch, in the middle of the day.
|
||||
{&tspb.Timestamp{Seconds: 1296012345, Nanos: 940483}, true,
|
||||
time.Date(2011, 1, 26, 3, 25, 45, 940483, time.UTC)},
|
||||
}
|
||||
|
||||
func TestValidateTimestamp(t *testing.T) {
|
||||
for _, s := range tests {
|
||||
got := validateTimestamp(s.ts)
|
||||
if (got == nil) != s.valid {
|
||||
t.Errorf("validateTimestamp(%v) = %v, want %v", s.ts, got, s.valid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimestamp(t *testing.T) {
|
||||
for _, s := range tests {
|
||||
got, err := Timestamp(s.ts)
|
||||
if (err == nil) != s.valid {
|
||||
t.Errorf("Timestamp(%v) error = %v, but valid = %t", s.ts, err, s.valid)
|
||||
} else if s.valid && got != s.t {
|
||||
t.Errorf("Timestamp(%v) = %v, want %v", s.ts, got, s.t)
|
||||
}
|
||||
}
|
||||
// Special case: a nil Timestamp is an error, but returns the 0 Unix time.
|
||||
got, err := Timestamp(nil)
|
||||
want := time.Unix(0, 0).UTC()
|
||||
if got != want {
|
||||
t.Errorf("Timestamp(nil) = %v, want %v", got, want)
|
||||
}
|
||||
if err == nil {
|
||||
t.Errorf("Timestamp(nil) error = nil, expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimestampProto(t *testing.T) {
|
||||
for _, s := range tests {
|
||||
got, err := TimestampProto(s.t)
|
||||
if (err == nil) != s.valid {
|
||||
t.Errorf("TimestampProto(%v) error = %v, but valid = %t", s.t, err, s.valid)
|
||||
} else if s.valid && !proto.Equal(got, s.ts) {
|
||||
t.Errorf("TimestampProto(%v) = %v, want %v", s.t, got, s.ts)
|
||||
}
|
||||
}
|
||||
// No corresponding special case here: no time.Time results in a nil Timestamp.
|
||||
}
|
||||
|
||||
func TestTimestampString(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
ts *tspb.Timestamp
|
||||
want string
|
||||
}{
|
||||
// Not much testing needed because presumably time.Format is
|
||||
// well-tested.
|
||||
{&tspb.Timestamp{Seconds: 0, Nanos: 0}, "1970-01-01T00:00:00Z"},
|
||||
{&tspb.Timestamp{Seconds: minValidSeconds - 1, Nanos: 0}, "(timestamp: seconds:-62135596801 before 0001-01-01)"},
|
||||
} {
|
||||
got := TimestampString(test.ts)
|
||||
if got != test.want {
|
||||
t.Errorf("TimestampString(%v) = %q, want %q", test.ts, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func utcDate(year, month, day int) time.Time {
|
||||
return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
func TestTimestampNow(t *testing.T) {
|
||||
// Bracket the expected time.
|
||||
before := time.Now()
|
||||
ts := TimestampNow()
|
||||
after := time.Now()
|
||||
|
||||
tm, err := Timestamp(ts)
|
||||
if err != nil {
|
||||
t.Errorf("between %v and %v\nTimestampNow() = %v\nwhich is invalid (%v)", before, after, ts, err)
|
||||
}
|
||||
if tm.Before(before) || tm.After(after) {
|
||||
t.Errorf("between %v and %v\nTimestamp(TimestampNow()) = %v", before, after, tm)
|
||||
}
|
||||
}
|
9
vendor/github.com/grpc-ecosystem/grpc-gateway/.gitignore
generated
vendored
Normal file
9
vendor/github.com/grpc-ecosystem/grpc-gateway/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
_output/
|
||||
.idea
|
||||
|
||||
# Bazel.
|
||||
bazel-bin
|
||||
bazel-genfiles
|
||||
bazel-grpc-gateway
|
||||
bazel-out
|
||||
bazel-testlogs
|
81
vendor/github.com/grpc-ecosystem/grpc-gateway/.travis.yml
generated
vendored
Normal file
81
vendor/github.com/grpc-ecosystem/grpc-gateway/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- master
|
||||
go_import_path: github.com/grpc-ecosystem/grpc-gateway
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/local
|
||||
- ${TRAVIS_BUILD_DIR}/examples/browser/node_modules
|
||||
- $HOME/.cache/_grpc_gateway_bazel
|
||||
before_install:
|
||||
- if [ "${USE_BAZEL}" = true ]; then ./.travis/install-bazel.sh $BAZEL_VERSION; fi
|
||||
- test "${USE_BAZEL}" = true || ./.travis/install-protoc.sh $PROTOC_VERSION
|
||||
- test "${USE_BAZEL}" = true || ./.travis/install-swagger-codegen.sh $SWAGGER_CODEGEN_VERSION
|
||||
- test "${USE_BAZEL}" = true || (nvm install $NODE_VERSION && nvm use $NODE_VERSION && node --version)
|
||||
- test "${USE_BAZEL}" = true || go get github.com/golang/lint/golint
|
||||
- test "${USE_BAZEL}" = true || go get github.com/dghubble/sling
|
||||
- test "${USE_BAZEL}" = true || go get github.com/go-resty/resty
|
||||
install:
|
||||
# Make sure externally referenced packages are go-gettable.
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
go get github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
go get github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
go get github.com/grpc-ecosystem/grpc-gateway/runtime
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
go get github.com/grpc-ecosystem/grpc-gateway/examples/cmd/example-grpc-server
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
go get github.com/grpc-ecosystem/grpc-gateway/examples/cmd/example-gateway-server
|
||||
|
||||
# Just build if USE_BAZEL
|
||||
- if [ "${USE_BAZEL}" = true ]; then ./.travis/bazel-build.sh; fi
|
||||
before_script:
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
(cd examples/browser && npm install)
|
||||
script:
|
||||
# Make sure examples of generated files are up-to-date
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
(make realclean && make examples SWAGGER_CODEGEN="java -jar $HOME/local/swagger-codegen-cli.jar")
|
||||
- if [ -z "${USE_BAZEL}" ] &&
|
||||
(go version | grep -q "${GO_VERSION_TO_DIFF_TEST}") &&
|
||||
[ -z "${GATEWAY_PLUGIN_FLAGS}" ]; then
|
||||
test -z "$(git status --porcelain)" || (git status; git diff; exit 1);
|
||||
fi
|
||||
|
||||
# Unit tests, integration tests and code health checks
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
env GLOG_logtostderr=1 go test -race -v github.com/grpc-ecosystem/grpc-gateway/...
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
make lint
|
||||
- test "${USE_BAZEL}" = true ||
|
||||
sh -c 'cd examples/browser && node ./node_modules/gulp/bin/gulp'
|
||||
|
||||
- if [ "${USE_BAZEL}" = true ]; then ./.travis/bazel-test.sh; fi
|
||||
|
||||
# test coverage
|
||||
- if (go version | grep -q "${GO_VERSION_TO_DIFF_TEST}") &&
|
||||
[ -z "${GATEWAY_PLUGIN_FLAGS}" ]; then
|
||||
env GLOG_logtostderr=1 ./bin/coverage;
|
||||
fi
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
env:
|
||||
global:
|
||||
- "PATH=$PATH:$HOME/local/bin"
|
||||
- GO_VERSION_TO_DIFF_TEST="go version go1\.10\.[0-9]\+ linux/amd64"
|
||||
- BAZEL_VERSION=0.12.0
|
||||
- NODE_VERSION=v6.1
|
||||
- PROTOC_VERSION=3.1.0
|
||||
- SWAGGER_CODEGEN_VERSION=2.2.2
|
||||
matrix:
|
||||
- GATEWAY_PLUGIN_FLAGS=
|
||||
- GATEWAY_PLUGIN_FLAGS=request_context=false
|
||||
matrix:
|
||||
include:
|
||||
- go: master
|
||||
env: USE_BAZEL=true
|
23
vendor/github.com/grpc-ecosystem/grpc-gateway/BUILD
generated
vendored
Normal file
23
vendor/github.com/grpc-ecosystem/grpc-gateway/BUILD
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
load("@bazel_gazelle//:def.bzl", "gazelle")
|
||||
|
||||
# gazelle:exclude third_party
|
||||
|
||||
gazelle(
|
||||
name = "gazelle_diff",
|
||||
mode = "diff",
|
||||
prefix = "github.com/grpc-ecosystem/grpc-gateway",
|
||||
)
|
||||
|
||||
gazelle(
|
||||
name = "gazelle_fix",
|
||||
mode = "fix",
|
||||
prefix = "github.com/grpc-ecosystem/grpc-gateway",
|
||||
)
|
||||
|
||||
package_group(
|
||||
name = "generators",
|
||||
packages = [
|
||||
"//protoc-gen-grpc-gateway/...",
|
||||
"//protoc-gen-swagger/...",
|
||||
],
|
||||
)
|
590
vendor/github.com/grpc-ecosystem/grpc-gateway/CHANGELOG.md
generated
vendored
Normal file
590
vendor/github.com/grpc-ecosystem/grpc-gateway/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,590 @@
|
|||
# Change Log
|
||||
|
||||
## [v1.4.1](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.4.1) (2018-05-23)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.4.0...v1.4.1)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Next release ? [\#605](https://github.com/grpc-ecosystem/grpc-gateway/issues/605)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Translate gRPC FailedPrecondition as HTTP PreconditionFailed [\#657](https://github.com/grpc-ecosystem/grpc-gateway/pull/657) ([slomek](https://github.com/slomek))
|
||||
|
||||
## [v1.4.0](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.4.0) (2018-05-20)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.3.1...v1.4.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- customize the error return [\#405](https://github.com/grpc-ecosystem/grpc-gateway/issues/405)
|
||||
- Support map type in query string [\#316](https://github.com/grpc-ecosystem/grpc-gateway/issues/316)
|
||||
- gRPC gateway Bazel build rules [\#66](https://github.com/grpc-ecosystem/grpc-gateway/issues/66)
|
||||
- Support bytes fields in path parameter [\#5](https://github.com/grpc-ecosystem/grpc-gateway/issues/5)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- the protoc\_gen\_swagger bazel rule generates non working import path. [\#633](https://github.com/grpc-ecosystem/grpc-gateway/issues/633)
|
||||
- code.NotFound should return a 404 instead of a 405 [\#630](https://github.com/grpc-ecosystem/grpc-gateway/issues/630)
|
||||
- field in query path not found [\#629](https://github.com/grpc-ecosystem/grpc-gateway/issues/629)
|
||||
- how to use client pool in the gateway? [\#612](https://github.com/grpc-ecosystem/grpc-gateway/issues/612)
|
||||
- pass http request uri to grpc server [\#587](https://github.com/grpc-ecosystem/grpc-gateway/issues/587)
|
||||
- bidi streams have racy read caused by goroutine that closes over local variable [\#583](https://github.com/grpc-ecosystem/grpc-gateway/issues/583)
|
||||
- Streamed response is not valid json \(or: is this the expected format?\) [\#581](https://github.com/grpc-ecosystem/grpc-gateway/issues/581)
|
||||
- Import "google/api/annotations.proto" was not found or had errors. [\#574](https://github.com/grpc-ecosystem/grpc-gateway/issues/574)
|
||||
- is there has a way to let grpc-gateway server support multiple endpoints [\#573](https://github.com/grpc-ecosystem/grpc-gateway/issues/573)
|
||||
- would it be possible to avoid vendoring "third\_party/googleapis/" [\#572](https://github.com/grpc-ecosystem/grpc-gateway/issues/572)
|
||||
- Path parameters can't have URL encoded values [\#566](https://github.com/grpc-ecosystem/grpc-gateway/issues/566)
|
||||
- Is there anyway to output the access log of grpc gateway [\#556](https://github.com/grpc-ecosystem/grpc-gateway/issues/556)
|
||||
- proto: no slice oenc for \*reflect.rtype = \[\]\*reflect.rtype [\#551](https://github.com/grpc-ecosystem/grpc-gateway/issues/551)
|
||||
- autoreconf not found [\#549](https://github.com/grpc-ecosystem/grpc-gateway/issues/549)
|
||||
- \[feature\]combine expvar into grpc-gateway [\#542](https://github.com/grpc-ecosystem/grpc-gateway/issues/542)
|
||||
- Source code still imports "golang.org/x/net/context" [\#533](https://github.com/grpc-ecosystem/grpc-gateway/issues/533)
|
||||
- Incorrect error message when execute protoc-gen-grpc-gateway to HTTP GET method with BODY [\#531](https://github.com/grpc-ecosystem/grpc-gateway/issues/531)
|
||||
- add support for the google.api.HttpBody proto as a request [\#528](https://github.com/grpc-ecosystem/grpc-gateway/issues/528)
|
||||
- Prefixed model names in generated swagger spec [\#525](https://github.com/grpc-ecosystem/grpc-gateway/issues/525)
|
||||
- Better format for error.message in stream [\#519](https://github.com/grpc-ecosystem/grpc-gateway/issues/519)
|
||||
- Getting this on go get . in the src directory: HelloService.pb.go:20:8 - no Go files in \go\src\google\api [\#518](https://github.com/grpc-ecosystem/grpc-gateway/issues/518)
|
||||
- ci: set up codecov [\#513](https://github.com/grpc-ecosystem/grpc-gateway/issues/513)
|
||||
- protoc-gen-swagger not using description field of info swagger object [\#511](https://github.com/grpc-ecosystem/grpc-gateway/issues/511)
|
||||
- Cut a minor release for https://github.com/grpc-ecosystem/grpc-gateway/issues/495 [\#506](https://github.com/grpc-ecosystem/grpc-gateway/issues/506)
|
||||
- bug: uncapitalized service name causes runtime error unknown function in service.pb.gw.go [\#484](https://github.com/grpc-ecosystem/grpc-gateway/issues/484)
|
||||
- RESOURCE\_EXHAUSTED -\> 503 [\#431](https://github.com/grpc-ecosystem/grpc-gateway/issues/431)
|
||||
- Adding authentication definitions to generated swagger files [\#428](https://github.com/grpc-ecosystem/grpc-gateway/issues/428)
|
||||
- Move to stdlib context over x/net/context [\#326](https://github.com/grpc-ecosystem/grpc-gateway/issues/326)
|
||||
- deprecate 1.6 and embrace \(\*http.Request\).Context by default [\#313](https://github.com/grpc-ecosystem/grpc-gateway/issues/313)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Generate a single swagger definition on demand [\#658](https://github.com/grpc-ecosystem/grpc-gateway/pull/658) ([achew22](https://github.com/achew22))
|
||||
- Regenerate example files [\#656](https://github.com/grpc-ecosystem/grpc-gateway/pull/656) ([achew22](https://github.com/achew22))
|
||||
- Add v1.4.0 changelog [\#655](https://github.com/grpc-ecosystem/grpc-gateway/pull/655) ([achew22](https://github.com/achew22))
|
||||
- Add README.md for examples [\#645](https://github.com/grpc-ecosystem/grpc-gateway/pull/645) ([liukgg](https://github.com/liukgg))
|
||||
- JSONPb marshaler panics if input is nil interface [\#639](https://github.com/grpc-ecosystem/grpc-gateway/pull/639) ([jhump](https://github.com/jhump))
|
||||
- provide access to underlying \*json.Decoder from JSONPb.NewDecoder [\#637](https://github.com/grpc-ecosystem/grpc-gateway/pull/637) ([jhump](https://github.com/jhump))
|
||||
- fix compile errors caused by protobuf finally merging their dev branch to master [\#636](https://github.com/grpc-ecosystem/grpc-gateway/pull/636) ([jhump](https://github.com/jhump))
|
||||
- Generate import mappings. [\#635](https://github.com/grpc-ecosystem/grpc-gateway/pull/635) ([ensonic](https://github.com/ensonic))
|
||||
- Add support for the grpc\_api\_configuration option in the bazel rule. [\#632](https://github.com/grpc-ecosystem/grpc-gateway/pull/632) ([ensonic](https://github.com/ensonic))
|
||||
- Use repo relative labels in protoc-gen-swagger [\#631](https://github.com/grpc-ecosystem/grpc-gateway/pull/631) ([achew22](https://github.com/achew22))
|
||||
- Correct dependencies in Makefile [\#626](https://github.com/grpc-ecosystem/grpc-gateway/pull/626) ([yugui](https://github.com/yugui))
|
||||
- Avoid timing issues in the integration tests [\#624](https://github.com/grpc-ecosystem/grpc-gateway/pull/624) ([yugui](https://github.com/yugui))
|
||||
- Fix typos in gRPC API Configuration usage documentation [\#623](https://github.com/grpc-ecosystem/grpc-gateway/pull/623) ([hacst](https://github.com/hacst))
|
||||
- Skip unnecessary steps in USE\_BAZEL builds on TravisCI [\#622](https://github.com/grpc-ecosystem/grpc-gateway/pull/622) ([yugui](https://github.com/yugui))
|
||||
- Support param for field from Oneof definition. [\#621](https://github.com/grpc-ecosystem/grpc-gateway/pull/621) ([bonafideyan](https://github.com/bonafideyan))
|
||||
- Fixes file integrity errors on TravisCI [\#619](https://github.com/grpc-ecosystem/grpc-gateway/pull/619) ([yugui](https://github.com/yugui))
|
||||
- Reorganize examples [\#618](https://github.com/grpc-ecosystem/grpc-gateway/pull/618) ([yugui](https://github.com/yugui))
|
||||
- Update dependency declarations in the Makefile [\#617](https://github.com/grpc-ecosystem/grpc-gateway/pull/617) ([yugui](https://github.com/yugui))
|
||||
- Support delete method in swagger generator [\#616](https://github.com/grpc-ecosystem/grpc-gateway/pull/616) ([blackdahila](https://github.com/blackdahila))
|
||||
- feat\(bazel\): Add rule for generating .swagger.json files [\#613](https://github.com/grpc-ecosystem/grpc-gateway/pull/613) ([mrmeku](https://github.com/mrmeku))
|
||||
- Support UNIX domain socket in the example servers [\#609](https://github.com/grpc-ecosystem/grpc-gateway/pull/609) ([yugui](https://github.com/yugui))
|
||||
- misspelling [\#601](https://github.com/grpc-ecosystem/grpc-gateway/pull/601) ([chemidy](https://github.com/chemidy))
|
||||
- Pulled out parseReq func into a generic package + tests [\#600](https://github.com/grpc-ecosystem/grpc-gateway/pull/600) ([f0rmiga](https://github.com/f0rmiga))
|
||||
- Added Bazel support [\#599](https://github.com/grpc-ecosystem/grpc-gateway/pull/599) ([f0rmiga](https://github.com/f0rmiga))
|
||||
- Add basic docs section [\#597](https://github.com/grpc-ecosystem/grpc-gateway/pull/597) ([achew22](https://github.com/achew22))
|
||||
- Upgrade to go1.10 and regenerate [\#596](https://github.com/grpc-ecosystem/grpc-gateway/pull/596) ([achew22](https://github.com/achew22))
|
||||
- Support cases where the request is done with transfer-encoding chunked [\#589](https://github.com/grpc-ecosystem/grpc-gateway/pull/589) ([jacksontj](https://github.com/jacksontj))
|
||||
- Support multiple metadata annotators [\#586](https://github.com/grpc-ecosystem/grpc-gateway/pull/586) ([dmacthedestroyer](https://github.com/dmacthedestroyer))
|
||||
- Changed to use more appropriate http status code for ResourceExhausted [\#580](https://github.com/grpc-ecosystem/grpc-gateway/pull/580) ([eleniums](https://github.com/eleniums))
|
||||
- fix racy access of err variable [\#575](https://github.com/grpc-ecosystem/grpc-gateway/pull/575) ([jhump](https://github.com/jhump))
|
||||
- runtime: return 503 not 403 with ResourceExhausted. [\#569](https://github.com/grpc-ecosystem/grpc-gateway/pull/569) ([hexfusion](https://github.com/hexfusion))
|
||||
- \[\]byte in query now uses base64.StdEncoding [\#565](https://github.com/grpc-ecosystem/grpc-gateway/pull/565) ([lucasvo](https://github.com/lucasvo))
|
||||
- Add 3rd party rpc protos in order to have access to status and error [\#563](https://github.com/grpc-ecosystem/grpc-gateway/pull/563) ([rvegas](https://github.com/rvegas))
|
||||
- Add details to stream error response [\#561](https://github.com/grpc-ecosystem/grpc-gateway/pull/561) ([johanbrandhorst](https://github.com/johanbrandhorst))
|
||||
- fix noenc error by fixing Details error field [\#557](https://github.com/grpc-ecosystem/grpc-gateway/pull/557) ([srenatus](https://github.com/srenatus))
|
||||
- error details: add @type key by switching to any.Any [\#553](https://github.com/grpc-ecosystem/grpc-gateway/pull/553) ([srenatus](https://github.com/srenatus))
|
||||
- Add a FAQ [\#550](https://github.com/grpc-ecosystem/grpc-gateway/pull/550) ([achew22](https://github.com/achew22))
|
||||
- Add security fields support to protoc-gen-swagger [\#547](https://github.com/grpc-ecosystem/grpc-gateway/pull/547) ([ivucica](https://github.com/ivucica))
|
||||
- Omit well-known type definitions from swagger output [\#541](https://github.com/grpc-ecosystem/grpc-gateway/pull/541) ([alexleigh](https://github.com/alexleigh))
|
||||
- Use importPath to set package name rather than package path. [\#537](https://github.com/grpc-ecosystem/grpc-gateway/pull/537) ([rwlincoln](https://github.com/rwlincoln))
|
||||
- Support for map type in query string [\#535](https://github.com/grpc-ecosystem/grpc-gateway/pull/535) ([adamstruck](https://github.com/adamstruck))
|
||||
- Fix error message in protoc-gen-grpc-gateway \(for \#531\) [\#532](https://github.com/grpc-ecosystem/grpc-gateway/pull/532) ([budougumi0617](https://github.com/budougumi0617))
|
||||
- runtime: support FieldMask as query param [\#529](https://github.com/grpc-ecosystem/grpc-gateway/pull/529) ([glerchundi](https://github.com/glerchundi))
|
||||
- Fix decoding empty request body [\#527](https://github.com/grpc-ecosystem/grpc-gateway/pull/527) ([syhpoon](https://github.com/syhpoon))
|
||||
- Add description, summary and tags fields in operationObject \(swagger\) [\#526](https://github.com/grpc-ecosystem/grpc-gateway/pull/526) ([devnull-](https://github.com/devnull-))
|
||||
- Converts the first letter of service name to uppercase [\#522](https://github.com/grpc-ecosystem/grpc-gateway/pull/522) ([thurt](https://github.com/thurt))
|
||||
- Add support for basic gRPC API Configuration YAML files [\#521](https://github.com/grpc-ecosystem/grpc-gateway/pull/521) ([hacst](https://github.com/hacst))
|
||||
- Fix travis to only difftest on go 1.9 [\#520](https://github.com/grpc-ecosystem/grpc-gateway/pull/520) ([achew22](https://github.com/achew22))
|
||||
- add error details to error json [\#515](https://github.com/grpc-ecosystem/grpc-gateway/pull/515) ([srenatus](https://github.com/srenatus))
|
||||
- ci: add codecov [\#514](https://github.com/grpc-ecosystem/grpc-gateway/pull/514) ([tmc](https://github.com/tmc))
|
||||
- Generate "Description" and "TermsOfService" fields [\#512](https://github.com/grpc-ecosystem/grpc-gateway/pull/512) ([lukasmalkmus](https://github.com/lukasmalkmus))
|
||||
- Release 1.3.1 [\#509](https://github.com/grpc-ecosystem/grpc-gateway/pull/509) ([tmc](https://github.com/tmc))
|
||||
- Support mapping bytes to \[\]byte [\#489](https://github.com/grpc-ecosystem/grpc-gateway/pull/489) ([loderunner](https://github.com/loderunner))
|
||||
- properly respect file flag for protoc-gen-swagger [\#293](https://github.com/grpc-ecosystem/grpc-gateway/pull/293) ([tmc](https://github.com/tmc))
|
||||
|
||||
## [v1.3.1](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.3.1) (2017-12-23)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.3.0...v1.3.1)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Support import\_path? [\#443](https://github.com/grpc-ecosystem/grpc-gateway/issues/443)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- protoc-gen-swagger missing definition issue [\#504](https://github.com/grpc-ecosystem/grpc-gateway/issues/504)
|
||||
- Are gateway metrics available? [\#498](https://github.com/grpc-ecosystem/grpc-gateway/issues/498)
|
||||
- Backwards incompatible change to chunked encoding [\#495](https://github.com/grpc-ecosystem/grpc-gateway/issues/495)
|
||||
- Map of list [\#493](https://github.com/grpc-ecosystem/grpc-gateway/issues/493)
|
||||
- Repeated nested messages doesn't work in GET requests queries. [\#492](https://github.com/grpc-ecosystem/grpc-gateway/issues/492)
|
||||
- How to run `makefile` for this repo? [\#491](https://github.com/grpc-ecosystem/grpc-gateway/issues/491)
|
||||
- all SubConns are in TransientFailure [\#490](https://github.com/grpc-ecosystem/grpc-gateway/issues/490)
|
||||
- Appengine Standard Environment: "not an Appengine context" [\#487](https://github.com/grpc-ecosystem/grpc-gateway/issues/487)
|
||||
- Enum Path Parameter to Swagger [\#486](https://github.com/grpc-ecosystem/grpc-gateway/issues/486)
|
||||
- Should v1.3 be also tagged as v1.3.0? [\#483](https://github.com/grpc-ecosystem/grpc-gateway/issues/483)
|
||||
- HTTP response is not correct json encoded if the grpc return stream of objects. [\#481](https://github.com/grpc-ecosystem/grpc-gateway/issues/481)
|
||||
- Support JSON-RPCv2 [\#477](https://github.com/grpc-ecosystem/grpc-gateway/issues/477)
|
||||
- Naming convention? [\#475](https://github.com/grpc-ecosystem/grpc-gateway/issues/475)
|
||||
- Request context not being used [\#470](https://github.com/grpc-ecosystem/grpc-gateway/issues/470)
|
||||
- Generate Swagger documentation [\#469](https://github.com/grpc-ecosystem/grpc-gateway/issues/469)
|
||||
- Support Request | make: swagger-codegen: Command not found [\#468](https://github.com/grpc-ecosystem/grpc-gateway/issues/468)
|
||||
- How do you generate a swagger yaml file instead of json? [\#467](https://github.com/grpc-ecosystem/grpc-gateway/issues/467)
|
||||
- Add default support for proto over http [\#465](https://github.com/grpc-ecosystem/grpc-gateway/issues/465)
|
||||
- Allow compiling the gateway code to a different go package [\#463](https://github.com/grpc-ecosystem/grpc-gateway/issues/463)
|
||||
- support google.api.HttpBody [\#457](https://github.com/grpc-ecosystem/grpc-gateway/issues/457)
|
||||
- \[swagger bug\] with google/protobuf/wrappers.proto [\#453](https://github.com/grpc-ecosystem/grpc-gateway/issues/453)
|
||||
- The tensorflow serving support RESTful api:{"error":"json: cannot unmarshal object into Go value of type \[\]json.RawMessage","code":3} [\#444](https://github.com/grpc-ecosystem/grpc-gateway/issues/444)
|
||||
- choose some return fields omit or not omit by configure [\#439](https://github.com/grpc-ecosystem/grpc-gateway/issues/439)
|
||||
- swagger title and version hardcoded [\#437](https://github.com/grpc-ecosystem/grpc-gateway/issues/437)
|
||||
- Change the path though http header [\#424](https://github.com/grpc-ecosystem/grpc-gateway/issues/424)
|
||||
- google/protobuf/descriptor.proto: File not found [\#422](https://github.com/grpc-ecosystem/grpc-gateway/issues/422)
|
||||
- Output file will not compile if the .proto file does not contain a service with parameters in the url path [\#389](https://github.com/grpc-ecosystem/grpc-gateway/issues/389)
|
||||
- Scaling support [\#381](https://github.com/grpc-ecosystem/grpc-gateway/issues/381)
|
||||
- I cannot get the default value from client side [\#380](https://github.com/grpc-ecosystem/grpc-gateway/issues/380)
|
||||
- Problem with Generated annotations.proto file [\#377](https://github.com/grpc-ecosystem/grpc-gateway/issues/377)
|
||||
- Release 1.3.0 [\#357](https://github.com/grpc-ecosystem/grpc-gateway/issues/357)
|
||||
- swagger: Unclear comments' parser behaviour [\#352](https://github.com/grpc-ecosystem/grpc-gateway/issues/352)
|
||||
- Support semicolon syntax in go\_package protobuf option [\#341](https://github.com/grpc-ecosystem/grpc-gateway/issues/341)
|
||||
- Add SOAP proxy [\#339](https://github.com/grpc-ecosystem/grpc-gateway/issues/339)
|
||||
- Support combination of query params and body for POSTs [\#234](https://github.com/grpc-ecosystem/grpc-gateway/issues/234)
|
||||
- Interceptor [\#221](https://github.com/grpc-ecosystem/grpc-gateway/issues/221)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Add support for --Import\_path [\#507](https://github.com/grpc-ecosystem/grpc-gateway/pull/507) ([achew22](https://github.com/achew22))
|
||||
- Fix \#504 Missing Definitions [\#505](https://github.com/grpc-ecosystem/grpc-gateway/pull/505) ([warmans](https://github.com/warmans))
|
||||
- Maintain default delimiter of newline [\#497](https://github.com/grpc-ecosystem/grpc-gateway/pull/497) ([jacksontj](https://github.com/jacksontj))
|
||||
- Fix gen-swagger to support more well known types [\#496](https://github.com/grpc-ecosystem/grpc-gateway/pull/496) ([shouichi](https://github.com/shouichi))
|
||||
- Use golang/protobuf instead of gogo/protobuf [\#494](https://github.com/grpc-ecosystem/grpc-gateway/pull/494) ([shouichi](https://github.com/shouichi))
|
||||
- Fix stream delimiters [\#488](https://github.com/grpc-ecosystem/grpc-gateway/pull/488) ([afking](https://github.com/afking))
|
||||
- ForwardResponseStream status code errors [\#482](https://github.com/grpc-ecosystem/grpc-gateway/pull/482) ([afking](https://github.com/afking))
|
||||
- protoc-gen-grpc-gateway: flip request\_context default to true [\#474](https://github.com/grpc-ecosystem/grpc-gateway/pull/474) ([srenatus](https://github.com/srenatus))
|
||||
- grpc-gateway/generator: respect full package [\#462](https://github.com/grpc-ecosystem/grpc-gateway/pull/462) ([glerchundi](https://github.com/glerchundi))
|
||||
- Add proto marshaller for proto-over-http [\#459](https://github.com/grpc-ecosystem/grpc-gateway/pull/459) ([MatthewDolan](https://github.com/MatthewDolan))
|
||||
|
||||
## [v1.3.0](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.3.0) (2017-11-03)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.3...v1.3.0)
|
||||
|
||||
## [v1.3](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.3) (2017-11-03)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.2.2...v1.3)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Extract basic auth from URL [\#480](https://github.com/grpc-ecosystem/grpc-gateway/issues/480)
|
||||
- Lack of "google/protobuf/descriptor.proto" [\#476](https://github.com/grpc-ecosystem/grpc-gateway/issues/476)
|
||||
- question: how to indicate whether call is through grpc gateway [\#456](https://github.com/grpc-ecosystem/grpc-gateway/issues/456)
|
||||
- How to define this restful api using pb? [\#452](https://github.com/grpc-ecosystem/grpc-gateway/issues/452)
|
||||
- how to output field as an array of json values? [\#449](https://github.com/grpc-ecosystem/grpc-gateway/issues/449)
|
||||
- How do I override maxMsgSize? [\#445](https://github.com/grpc-ecosystem/grpc-gateway/issues/445)
|
||||
- OpenAPI spec is generated with duplicated operation IDs. [\#442](https://github.com/grpc-ecosystem/grpc-gateway/issues/442)
|
||||
- This process seems to generate conflicting code with go-micro [\#440](https://github.com/grpc-ecosystem/grpc-gateway/issues/440)
|
||||
- any way to let int64 marshal to int not string? [\#438](https://github.com/grpc-ecosystem/grpc-gateway/issues/438)
|
||||
- Support streaming [\#435](https://github.com/grpc-ecosystem/grpc-gateway/issues/435)
|
||||
- Update DO NOT EDIT header in generated files [\#433](https://github.com/grpc-ecosystem/grpc-gateway/issues/433)
|
||||
- generate code use context not "golang.org/x/net/context" [\#430](https://github.com/grpc-ecosystem/grpc-gateway/issues/430)
|
||||
- Replace \n with spaces in swagger definitions [\#426](https://github.com/grpc-ecosystem/grpc-gateway/issues/426)
|
||||
- \[question\]Is there any example for http headers process? [\#420](https://github.com/grpc-ecosystem/grpc-gateway/issues/420)
|
||||
- Is there any way to support a multipart form request? [\#410](https://github.com/grpc-ecosystem/grpc-gateway/issues/410)
|
||||
- Not able to pass allow\_delete\_body to protoc-gen-grpc-gateway. [\#402](https://github.com/grpc-ecosystem/grpc-gateway/issues/402)
|
||||
- returned errors should conform to google.rpc.Status [\#399](https://github.com/grpc-ecosystem/grpc-gateway/issues/399)
|
||||
- Is there any way to generate python gateway code? [\#398](https://github.com/grpc-ecosystem/grpc-gateway/issues/398)
|
||||
- how to handle arbitrary \(json\) structs [\#395](https://github.com/grpc-ecosystem/grpc-gateway/issues/395)
|
||||
- \[question\]can give a url with query sting demo? [\#394](https://github.com/grpc-ecosystem/grpc-gateway/issues/394)
|
||||
- \[question\]the swagger url generated is what? [\#393](https://github.com/grpc-ecosystem/grpc-gateway/issues/393)
|
||||
- \[Question\] How do I use semantic versions? [\#392](https://github.com/grpc-ecosystem/grpc-gateway/issues/392)
|
||||
- \[question\]how to run examples? [\#391](https://github.com/grpc-ecosystem/grpc-gateway/issues/391)
|
||||
- Why does gateway use ServerMetadata? [\#388](https://github.com/grpc-ecosystem/grpc-gateway/issues/388)
|
||||
- Can't generate code with last version [\#384](https://github.com/grpc-ecosystem/grpc-gateway/issues/384)
|
||||
- is it ready for production use? [\#382](https://github.com/grpc-ecosystem/grpc-gateway/issues/382)
|
||||
- Support Google Flatbuffers [\#376](https://github.com/grpc-ecosystem/grpc-gateway/issues/376)
|
||||
- calling Enum by string name in requests using gogo/protobuf results in error. [\#372](https://github.com/grpc-ecosystem/grpc-gateway/issues/372)
|
||||
- Definitions containing URLs with trailing slashes won't compile [\#370](https://github.com/grpc-ecosystem/grpc-gateway/issues/370)
|
||||
- Should metadata annotator include the headers from incoming matcher? [\#368](https://github.com/grpc-ecosystem/grpc-gateway/issues/368)
|
||||
- metadata.NewOutgoingContext is undefined [\#364](https://github.com/grpc-ecosystem/grpc-gateway/issues/364)
|
||||
- Why does not gateway forward headers as-is? [\#311](https://github.com/grpc-ecosystem/grpc-gateway/issues/311)
|
||||
- Question: Why passing context to RegisterMyServiceHandler is required? [\#301](https://github.com/grpc-ecosystem/grpc-gateway/issues/301)
|
||||
- Allow whitelisting of particular HTTP headers to map to metadata. [\#253](https://github.com/grpc-ecosystem/grpc-gateway/issues/253)
|
||||
- Swagger definitions don't handle parameters that are not explicitly required in the url [\#159](https://github.com/grpc-ecosystem/grpc-gateway/issues/159)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Fix wrong method names [\#603](https://github.com/grpc-ecosystem/grpc-gateway/pull/603) ([yugui](https://github.com/yugui))
|
||||
- Streaming forward handler fix chunk encoding [\#479](https://github.com/grpc-ecosystem/grpc-gateway/pull/479) ([afking](https://github.com/afking))
|
||||
- Fix logic handling primitive wrapper in URL params [\#478](https://github.com/grpc-ecosystem/grpc-gateway/pull/478) ([tgeng](https://github.com/tgeng))
|
||||
- runtime: use r.Context\(\) [\#473](https://github.com/grpc-ecosystem/grpc-gateway/pull/473) ([srenatus](https://github.com/srenatus))
|
||||
- Optional SourceCodeInfo [\#466](https://github.com/grpc-ecosystem/grpc-gateway/pull/466) ([afking](https://github.com/afking))
|
||||
- Some steps to fix Travis CI [\#461](https://github.com/grpc-ecosystem/grpc-gateway/pull/461) ([AlekSi](https://github.com/AlekSi))
|
||||
- fix 2 typos in Registry.SetPrefix's comment [\#455](https://github.com/grpc-ecosystem/grpc-gateway/pull/455) ([hectorj](https://github.com/hectorj))
|
||||
- Add Handler method to pass in client [\#454](https://github.com/grpc-ecosystem/grpc-gateway/pull/454) ([jacksontj](https://github.com/jacksontj))
|
||||
- Fallback to JSON name when matching URL parameter. [\#450](https://github.com/grpc-ecosystem/grpc-gateway/pull/450) ([tgeng](https://github.com/tgeng))
|
||||
- Update DO NOT EDIT template. [\#434](https://github.com/grpc-ecosystem/grpc-gateway/pull/434) ([AlekSi](https://github.com/AlekSi))
|
||||
- Memoise calls to fullyQualifiedNameToSwaggerName to speed it up for large registries [\#421](https://github.com/grpc-ecosystem/grpc-gateway/pull/421) ([peterebden](https://github.com/peterebden))
|
||||
- Update Swagger Codegen from 2.1.6 to 2.2.2 [\#415](https://github.com/grpc-ecosystem/grpc-gateway/pull/415) ([yugui](https://github.com/yugui))
|
||||
- Return codes.InvalidArgument to rather return HTTP 400 instead of HTTP 500 [\#409](https://github.com/grpc-ecosystem/grpc-gateway/pull/409) ([vaporz](https://github.com/vaporz))
|
||||
- improve {incoming,outgoing}HeaderMatcher logic [\#408](https://github.com/grpc-ecosystem/grpc-gateway/pull/408) ([flisky](https://github.com/flisky))
|
||||
- improve WKT handling in gateway and openapi output [\#404](https://github.com/grpc-ecosystem/grpc-gateway/pull/404) ([tmc](https://github.com/tmc))
|
||||
- Return if runtime.AnnotateContext gave error [\#403](https://github.com/grpc-ecosystem/grpc-gateway/pull/403) ([tamalsaha](https://github.com/tamalsaha))
|
||||
- jsonpb: update tests to reflect new jsonpb behavior [\#401](https://github.com/grpc-ecosystem/grpc-gateway/pull/401) ([tmc](https://github.com/tmc))
|
||||
- Reference import grpc Status to suppress unused errors. [\#387](https://github.com/grpc-ecosystem/grpc-gateway/pull/387) ([tamalsaha](https://github.com/tamalsaha))
|
||||
- ci: regen with current protoc-gen-go [\#385](https://github.com/grpc-ecosystem/grpc-gateway/pull/385) ([tmc](https://github.com/tmc))
|
||||
- Use status package for error and introduce WithProtoErrorHandler option [\#378](https://github.com/grpc-ecosystem/grpc-gateway/pull/378) ([kazegusuri](https://github.com/kazegusuri))
|
||||
- Return response headers from grpc server [\#374](https://github.com/grpc-ecosystem/grpc-gateway/pull/374) ([tamalsaha](https://github.com/tamalsaha))
|
||||
- Skip unreferenced messages in definitions. [\#371](https://github.com/grpc-ecosystem/grpc-gateway/pull/371) ([Lantame](https://github.com/Lantame))
|
||||
- Use canonical header form in default header matcher. [\#369](https://github.com/grpc-ecosystem/grpc-gateway/pull/369) ([tamalsaha](https://github.com/tamalsaha))
|
||||
- support allow\_delete\_body for protoc-gen-grpc-gateway [\#318](https://github.com/grpc-ecosystem/grpc-gateway/pull/318) ([flisky](https://github.com/flisky))
|
||||
- fixes package name override doesn't work [\#277](https://github.com/grpc-ecosystem/grpc-gateway/pull/277) ([favadi](https://github.com/favadi))
|
||||
- add custom options to allow more control of swagger/openapi output [\#145](https://github.com/grpc-ecosystem/grpc-gateway/pull/145) ([ivucica](https://github.com/ivucica))
|
||||
|
||||
## [v1.2.2](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.2.2) (2017-04-17)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.2.1...v1.2.2)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Add changelog for 1.2.2 [\#363](https://github.com/grpc-ecosystem/grpc-gateway/pull/363) ([tmc](https://github.com/tmc))
|
||||
- metadata: fix properly and change to Outgoing [\#361](https://github.com/grpc-ecosystem/grpc-gateway/pull/361) ([tmc](https://github.com/tmc))
|
||||
|
||||
## [v1.2.1](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.2.1) (2017-04-17)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.2.0...v1.2.1)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- reflect upstream grpc metadata api change [\#358](https://github.com/grpc-ecosystem/grpc-gateway/issues/358)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Empty value omitted [\#355](https://github.com/grpc-ecosystem/grpc-gateway/issues/355)
|
||||
- Must generate reverse proxy in same package? [\#353](https://github.com/grpc-ecosystem/grpc-gateway/issues/353)
|
||||
- Release 1.2.0 [\#340](https://github.com/grpc-ecosystem/grpc-gateway/issues/340)
|
||||
- Cut another release [\#278](https://github.com/grpc-ecosystem/grpc-gateway/issues/278)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Add changelog for 1.2.1 [\#360](https://github.com/grpc-ecosystem/grpc-gateway/pull/360) ([tmc](https://github.com/tmc))
|
||||
- bugfix: reflect upstream api change. [\#359](https://github.com/grpc-ecosystem/grpc-gateway/pull/359) ([tmc](https://github.com/tmc))
|
||||
|
||||
## [v1.2.0](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.2.0) (2017-03-31)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.2.0.rc1...v1.2.0)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Problem with \*.proto as "no buildable Go source files" [\#338](https://github.com/grpc-ecosystem/grpc-gateway/issues/338)
|
||||
- Invalid import during code generation [\#337](https://github.com/grpc-ecosystem/grpc-gateway/issues/337)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Add changelog for 1.2.0 [\#342](https://github.com/grpc-ecosystem/grpc-gateway/pull/342) ([tmc](https://github.com/tmc))
|
||||
|
||||
## [v1.2.0.rc1](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.2.0.rc1) (2017-03-24)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.1.0...v1.2.0.rc1)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Support for Any types [\#80](https://github.com/grpc-ecosystem/grpc-gateway/issues/80)
|
||||
- improve\(genswagger:template\):added support for google.protobuf.Timestamp [\#209](https://github.com/grpc-ecosystem/grpc-gateway/pull/209) ([EranAvidor](https://github.com/EranAvidor))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Support for multi-segment elements [\#122](https://github.com/grpc-ecosystem/grpc-gateway/issues/122)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Go get breaks with autogenerated code [\#331](https://github.com/grpc-ecosystem/grpc-gateway/issues/331)
|
||||
- Fresh install no longer generates necessary `google/api/annotations.pb.go` & `google/api/http.pb.go` files. [\#327](https://github.com/grpc-ecosystem/grpc-gateway/issues/327)
|
||||
- Panic with query parameters [\#324](https://github.com/grpc-ecosystem/grpc-gateway/issues/324)
|
||||
- Swagger-UI query parameters for enum types are sent as strings [\#320](https://github.com/grpc-ecosystem/grpc-gateway/issues/320)
|
||||
- hide the object name in the response [\#317](https://github.com/grpc-ecosystem/grpc-gateway/issues/317)
|
||||
- Package imported but not used [\#310](https://github.com/grpc-ecosystem/grpc-gateway/issues/310)
|
||||
- Authorization headers aren't specified in Swagger.json [\#309](https://github.com/grpc-ecosystem/grpc-gateway/issues/309)
|
||||
- Generating swagger version, contact name etc in generated docs [\#303](https://github.com/grpc-ecosystem/grpc-gateway/issues/303)
|
||||
- Feature request: custom content type per service and rpc [\#302](https://github.com/grpc-ecosystem/grpc-gateway/issues/302)
|
||||
- Reference: another RESTful api-gateway [\#299](https://github.com/grpc-ecosystem/grpc-gateway/issues/299)
|
||||
- Integration with other languages is partially broken [\#298](https://github.com/grpc-ecosystem/grpc-gateway/issues/298)
|
||||
- jsonpb convert int64 to integer instead of string [\#296](https://github.com/grpc-ecosystem/grpc-gateway/issues/296)
|
||||
- default enum value is omitted [\#294](https://github.com/grpc-ecosystem/grpc-gateway/issues/294)
|
||||
- Advice: could we simplify the flow as the below [\#292](https://github.com/grpc-ecosystem/grpc-gateway/issues/292)
|
||||
- examples/browser test failure: TypeError: undefined is not a function \(evaluating 'window.location.protocol.startsWith\('chrome-extension'\)'\) [\#287](https://github.com/grpc-ecosystem/grpc-gateway/issues/287)
|
||||
- ./entrypoint.go:25: undefined: api.RegisterYourServiceHandlerFromEndpoint [\#285](https://github.com/grpc-ecosystem/grpc-gateway/issues/285)
|
||||
- Query params not handled in swagger file [\#284](https://github.com/grpc-ecosystem/grpc-gateway/issues/284)
|
||||
- Please help: google/api/annotations.proto: File not found. [\#283](https://github.com/grpc-ecosystem/grpc-gateway/issues/283)
|
||||
- Option to Allow Swagger for DELETEs with a body [\#279](https://github.com/grpc-ecosystem/grpc-gateway/issues/279)
|
||||
- client declared and not used compilation error, after recent upgrade [\#276](https://github.com/grpc-ecosystem/grpc-gateway/issues/276)
|
||||
- feature request / idea: generating JSONRPC2 client proxies from GRPC [\#272](https://github.com/grpc-ecosystem/grpc-gateway/issues/272)
|
||||
- protoc-swagger-generator messes up the comments if there is rpc method that does not have rest [\#263](https://github.com/grpc-ecosystem/grpc-gateway/issues/263)
|
||||
- Swagger Gen: underscores -\> lowerCamelCase field names and refs [\#261](https://github.com/grpc-ecosystem/grpc-gateway/issues/261)
|
||||
- Timestamp as URL param causes bad request error [\#260](https://github.com/grpc-ecosystem/grpc-gateway/issues/260)
|
||||
- "proto: no coders for int" printed whenever a gRPC error is returned over grpc-gateway. [\#259](https://github.com/grpc-ecosystem/grpc-gateway/issues/259)
|
||||
- Compatibility with grpc.SupportPackageIsVersion4 [\#258](https://github.com/grpc-ecosystem/grpc-gateway/issues/258)
|
||||
- How to use circuit breaker in this grpc gateway? [\#257](https://github.com/grpc-ecosystem/grpc-gateway/issues/257)
|
||||
- cannot use example code to generate [\#255](https://github.com/grpc-ecosystem/grpc-gateway/issues/255)
|
||||
- tests fail on go tip due to importing of main packages in test [\#250](https://github.com/grpc-ecosystem/grpc-gateway/issues/250)
|
||||
- Add NGINX support [\#249](https://github.com/grpc-ecosystem/grpc-gateway/issues/249)
|
||||
- Error when reverse proxy to gRPC server \(which is impl with Node.js\) [\#246](https://github.com/grpc-ecosystem/grpc-gateway/issues/246)
|
||||
- Error output titlecase instead of lowercase [\#243](https://github.com/grpc-ecosystem/grpc-gateway/issues/243)
|
||||
- Option field "\(google.api.http\)" is not a field or extension of message "ServiceOptions" [\#241](https://github.com/grpc-ecosystem/grpc-gateway/issues/241)
|
||||
- Implement credentials handler in-box [\#238](https://github.com/grpc-ecosystem/grpc-gateway/issues/238)
|
||||
- Proposal: Support WKT structs for URL params [\#237](https://github.com/grpc-ecosystem/grpc-gateway/issues/237)
|
||||
- Example of /} in path template [\#232](https://github.com/grpc-ecosystem/grpc-gateway/issues/232)
|
||||
- Serving swagger.json from runtime mux? [\#230](https://github.com/grpc-ecosystem/grpc-gateway/issues/230)
|
||||
- ETCDclientv3 build error with the latest changes - github.com/grpc-ecosystem/grpc-gateway/runtime/marshal\_jsonpb.go:114: undefined: jsonpb.Unmarshaler [\#226](https://github.com/grpc-ecosystem/grpc-gateway/issues/226)
|
||||
- Map in GET request [\#223](https://github.com/grpc-ecosystem/grpc-gateway/issues/223)
|
||||
- HTTPS no longer works [\#220](https://github.com/grpc-ecosystem/grpc-gateway/issues/220)
|
||||
- --swagger\_out plugin translates proto type int64 to string in Swagger specification [\#219](https://github.com/grpc-ecosystem/grpc-gateway/issues/219)
|
||||
- Response body as a single field [\#217](https://github.com/grpc-ecosystem/grpc-gateway/issues/217)
|
||||
- documentation of semantics of endpoint declarations [\#212](https://github.com/grpc-ecosystem/grpc-gateway/issues/212)
|
||||
- gen-swagger does not generate PATCH method endpoints [\#211](https://github.com/grpc-ecosystem/grpc-gateway/issues/211)
|
||||
- protoc-gen-grpc-gateway doesn't work correctly with option go\_package [\#207](https://github.com/grpc-ecosystem/grpc-gateway/issues/207)
|
||||
- Browser Side Streaming Best Practices [\#206](https://github.com/grpc-ecosystem/grpc-gateway/issues/206)
|
||||
- Does grpc-gateway support App Engine? [\#204](https://github.com/grpc-ecosystem/grpc-gateway/issues/204)
|
||||
- "use of internal package" error, after moving to grpc-ecosystem [\#203](https://github.com/grpc-ecosystem/grpc-gateway/issues/203)
|
||||
- Move to google.golang.org/genproto instead of shipping annotations.proto. [\#202](https://github.com/grpc-ecosystem/grpc-gateway/issues/202)
|
||||
- Release v1.1.0 [\#196](https://github.com/grpc-ecosystem/grpc-gateway/issues/196)
|
||||
- marshaler runtime.Marshaler does not handle io.EOF when decoding [\#195](https://github.com/grpc-ecosystem/grpc-gateway/issues/195)
|
||||
- protobuf enumerated values now returned as strings instead of numbers. [\#186](https://github.com/grpc-ecosystem/grpc-gateway/issues/186)
|
||||
- support annotating fields as required \(in swagger/oapi generation\)? [\#175](https://github.com/grpc-ecosystem/grpc-gateway/issues/175)
|
||||
- architectural question: Can i codegen the client code for talking to the server ? [\#167](https://github.com/grpc-ecosystem/grpc-gateway/issues/167)
|
||||
- Passing ENUM value as URL parameter throws error [\#166](https://github.com/grpc-ecosystem/grpc-gateway/issues/166)
|
||||
- Support specifying which schemes should be output in swagger.json [\#161](https://github.com/grpc-ecosystem/grpc-gateway/issues/161)
|
||||
- Use headers for routing [\#157](https://github.com/grpc-ecosystem/grpc-gateway/issues/157)
|
||||
- ENUM in swagger.json makes client code failed to parse response from gateway [\#153](https://github.com/grpc-ecosystem/grpc-gateway/issues/153)
|
||||
- Support map types [\#140](https://github.com/grpc-ecosystem/grpc-gateway/issues/140)
|
||||
- generate OpenAPI/swagger documentation at run time? [\#138](https://github.com/grpc-ecosystem/grpc-gateway/issues/138)
|
||||
- After the 1.7 release, update .travis.yaml to check the compiled proto output [\#137](https://github.com/grpc-ecosystem/grpc-gateway/issues/137)
|
||||
- Getting parsed runtime.Pattern from server mux [\#127](https://github.com/grpc-ecosystem/grpc-gateway/issues/127)
|
||||
- REST API without proxying [\#46](https://github.com/grpc-ecosystem/grpc-gateway/issues/46)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Remove an obsolete custom option [\#604](https://github.com/grpc-ecosystem/grpc-gateway/pull/604) ([yugui](https://github.com/yugui))
|
||||
- Support user configurable header forwarding & context metadata [\#336](https://github.com/grpc-ecosystem/grpc-gateway/pull/336) ([tamalsaha](https://github.com/tamalsaha))
|
||||
- Update go\_out parameter to remove comma [\#333](https://github.com/grpc-ecosystem/grpc-gateway/pull/333) ([tmc](https://github.com/tmc))
|
||||
- Update stale path in README [\#332](https://github.com/grpc-ecosystem/grpc-gateway/pull/332) ([tmc](https://github.com/tmc))
|
||||
- improve documentation regarding external dependencies [\#330](https://github.com/grpc-ecosystem/grpc-gateway/pull/330) ([CaptTofu](https://github.com/CaptTofu))
|
||||
- Return an error on invalid nested query parameters. [\#329](https://github.com/grpc-ecosystem/grpc-gateway/pull/329) ([fische](https://github.com/fische))
|
||||
- Update upstream proto files and add google.golang.org/genproto support. [\#325](https://github.com/grpc-ecosystem/grpc-gateway/pull/325) ([tmc](https://github.com/tmc))
|
||||
- Support oneof fields in query params [\#321](https://github.com/grpc-ecosystem/grpc-gateway/pull/321) ([nilium](https://github.com/nilium))
|
||||
- Do not ignore the error coming from http.ListenAndServe in examples [\#319](https://github.com/grpc-ecosystem/grpc-gateway/pull/319) ([campoy](https://github.com/campoy))
|
||||
- Look up enum value maps by their proto name [\#315](https://github.com/grpc-ecosystem/grpc-gateway/pull/315) ([nilium](https://github.com/nilium))
|
||||
- enable parsing enums from query parameters [\#314](https://github.com/grpc-ecosystem/grpc-gateway/pull/314) ([tzneal](https://github.com/tzneal))
|
||||
- Do not add imports from methods with no bindings. [\#312](https://github.com/grpc-ecosystem/grpc-gateway/pull/312) ([fische](https://github.com/fische))
|
||||
- Convert the first letter of method name to upper [\#300](https://github.com/grpc-ecosystem/grpc-gateway/pull/300) ([lipixun](https://github.com/lipixun))
|
||||
- write query parameters to swagger definition [\#297](https://github.com/grpc-ecosystem/grpc-gateway/pull/297) ([t-yuki](https://github.com/t-yuki))
|
||||
- Bump swagger-client to 2.1.28 for examples/browser [\#290](https://github.com/grpc-ecosystem/grpc-gateway/pull/290) ([tmc](https://github.com/tmc))
|
||||
- pin to version before es6ism [\#289](https://github.com/grpc-ecosystem/grpc-gateway/pull/289) ([tmc](https://github.com/tmc))
|
||||
- Prevent lack of http bindings from generating non-building output [\#286](https://github.com/grpc-ecosystem/grpc-gateway/pull/286) ([tmc](https://github.com/tmc))
|
||||
- Added support for Timestamp in URL. [\#281](https://github.com/grpc-ecosystem/grpc-gateway/pull/281) ([johansja](https://github.com/johansja))
|
||||
- add plugin param 'allow\_delete\_body' [\#280](https://github.com/grpc-ecosystem/grpc-gateway/pull/280) ([msample](https://github.com/msample))
|
||||
- Fix ruby gen command [\#275](https://github.com/grpc-ecosystem/grpc-gateway/pull/275) ([bluehallu](https://github.com/bluehallu))
|
||||
- Make grpc-gateway support enum fields in path parameter [\#273](https://github.com/grpc-ecosystem/grpc-gateway/pull/273) ([linuxerwang](https://github.com/linuxerwang))
|
||||
- remove unnecessary make\(\) [\#271](https://github.com/grpc-ecosystem/grpc-gateway/pull/271) ([tmc](https://github.com/tmc))
|
||||
- preserve field order in swagger spec [\#270](https://github.com/grpc-ecosystem/grpc-gateway/pull/270) ([tmc](https://github.com/tmc))
|
||||
- Merge \#228 [\#268](https://github.com/grpc-ecosystem/grpc-gateway/pull/268) ([tmc](https://github.com/tmc))
|
||||
- Handle methods with no bindings more carefully [\#267](https://github.com/grpc-ecosystem/grpc-gateway/pull/267) ([tmc](https://github.com/tmc))
|
||||
- describe default marshaler in README.md [\#266](https://github.com/grpc-ecosystem/grpc-gateway/pull/266) ([tmc](https://github.com/tmc))
|
||||
- Add request\_context flag to utilize \(\*http.Request\).Context\(\) in handlers [\#265](https://github.com/grpc-ecosystem/grpc-gateway/pull/265) ([tmc](https://github.com/tmc))
|
||||
- Regenerate examples [\#264](https://github.com/grpc-ecosystem/grpc-gateway/pull/264) ([tmc](https://github.com/tmc))
|
||||
- Correct runtime.errorBody protobuf field tag [\#256](https://github.com/grpc-ecosystem/grpc-gateway/pull/256) ([tmc](https://github.com/tmc))
|
||||
- Pass permanent HTTP request headers [\#252](https://github.com/grpc-ecosystem/grpc-gateway/pull/252) ([tmc](https://github.com/tmc))
|
||||
- regenerate examples, fix tests for go tip [\#248](https://github.com/grpc-ecosystem/grpc-gateway/pull/248) ([tmc](https://github.com/tmc))
|
||||
- Render the swagger request body properly [\#247](https://github.com/grpc-ecosystem/grpc-gateway/pull/247) ([dprotaso](https://github.com/dprotaso))
|
||||
- Error output should have lowercase attribute names [\#244](https://github.com/grpc-ecosystem/grpc-gateway/pull/244) ([nathanborror](https://github.com/nathanborror))
|
||||
- runtime - export prefix constants [\#236](https://github.com/grpc-ecosystem/grpc-gateway/pull/236) ([philipithomas](https://github.com/philipithomas))
|
||||
- README - Add CoreOS example [\#231](https://github.com/grpc-ecosystem/grpc-gateway/pull/231) ([philipithomas](https://github.com/philipithomas))
|
||||
- Docs - Add section about how HTTP maps to gRPC [\#227](https://github.com/grpc-ecosystem/grpc-gateway/pull/227) ([philipithomas](https://github.com/philipithomas))
|
||||
- readme: added links to additional documentation [\#222](https://github.com/grpc-ecosystem/grpc-gateway/pull/222) ([sdemos](https://github.com/sdemos))
|
||||
- Use a released version of protoc [\#216](https://github.com/grpc-ecosystem/grpc-gateway/pull/216) ([yugui](https://github.com/yugui))
|
||||
- Add contribution guideline [\#210](https://github.com/grpc-ecosystem/grpc-gateway/pull/210) ([yugui](https://github.com/yugui))
|
||||
- Allowing unknown fields to be dropped instead of returning error from… [\#208](https://github.com/grpc-ecosystem/grpc-gateway/pull/208) ([sriniven](https://github.com/sriniven))
|
||||
- Avoid Internal Server Error on zero-length input for bidi streaming [\#200](https://github.com/grpc-ecosystem/grpc-gateway/pull/200) ([yugui](https://github.com/yugui))
|
||||
|
||||
## [v1.1.0](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.1.0) (2016-07-23)
|
||||
[Full Changelog](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/compare/v1.0.0...v1.1.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Support oneof types of fields [\#82](https://github.com/grpc-ecosystem/grpc-gateway/issues/82)
|
||||
- allow use of jsonpb for marshaling [\#79](https://github.com/grpc-ecosystem/grpc-gateway/issues/79)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Generating a gRPC stub using Gateway generates a gRPC internal error [\#198](https://github.com/grpc-ecosystem/grpc-gateway/issues/198)
|
||||
- Build fails with error: use of internal package not allowed [\#197](https://github.com/grpc-ecosystem/grpc-gateway/issues/197)
|
||||
- google/protobuf/descriptor.proto: File not found. [\#194](https://github.com/grpc-ecosystem/grpc-gateway/issues/194)
|
||||
- please tag releases [\#189](https://github.com/grpc-ecosystem/grpc-gateway/issues/189)
|
||||
- Support for path collapsing for embedded structs? [\#187](https://github.com/grpc-ecosystem/grpc-gateway/issues/187)
|
||||
- \[ACTION Required\] Moving to grpc-ecosystem [\#179](https://github.com/grpc-ecosystem/grpc-gateway/issues/179)
|
||||
- Ading grpc-timeout support [\#107](https://github.com/grpc-ecosystem/grpc-gateway/issues/107)
|
||||
- Generation of one swagger file out of multiple protos? [\#99](https://github.com/grpc-ecosystem/grpc-gateway/issues/99)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Rename packages to follow the repository transfer [\#192](https://github.com/grpc-ecosystem/grpc-gateway/pull/192) ([yugui](https://github.com/yugui))
|
||||
- return err early if EOF to prevent logging in normal conditions [\#191](https://github.com/grpc-ecosystem/grpc-gateway/pull/191) ([tmc](https://github.com/tmc))
|
||||
- send Trailer header on error [\#188](https://github.com/grpc-ecosystem/grpc-gateway/pull/188) ([kazegusuri](https://github.com/kazegusuri))
|
||||
- generate swagger output for streaming endpoints with a basic note [\#183](https://github.com/grpc-ecosystem/grpc-gateway/pull/183) ([tmc](https://github.com/tmc))
|
||||
|
||||
## [v1.0.0](https://grpc-ecosystem.github.io/grpc-gateway/grpc-ecosystem/grpc-gateway/tree/v1.0.0) (2016-06-15)
|
||||
**Implemented enhancements:**
|
||||
|
||||
- support protobuf-over-HTTP [\#124](https://github.com/grpc-ecosystem/grpc-gateway/issues/124)
|
||||
- Static mapping from proto field names to golang field names [\#86](https://github.com/grpc-ecosystem/grpc-gateway/issues/86)
|
||||
- Format Errors to JSON [\#25](https://github.com/grpc-ecosystem/grpc-gateway/issues/25)
|
||||
- Emit API definition in Swagger schema format [\#9](https://github.com/grpc-ecosystem/grpc-gateway/issues/9)
|
||||
- Method parameter in query string [\#6](https://github.com/grpc-ecosystem/grpc-gateway/issues/6)
|
||||
- Integrate authentication [\#4](https://github.com/grpc-ecosystem/grpc-gateway/issues/4)
|
||||
- Add swagger support [\#68](https://github.com/grpc-ecosystem/grpc-gateway/pull/68) ([achew22](https://github.com/achew22))
|
||||
- Add runtime.WithForwardResponseOption [\#53](https://github.com/grpc-ecosystem/grpc-gateway/pull/53) ([peter-edge](https://github.com/peter-edge))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- recent annotation change requires req.RemoteAddr to be populated [\#177](https://github.com/grpc-ecosystem/grpc-gateway/issues/177)
|
||||
- Runtime panic with CloseNotify [\#115](https://github.com/grpc-ecosystem/grpc-gateway/issues/115)
|
||||
- Gateway code generation broken when rpc method with a streaming response has an input paramter [\#35](https://github.com/grpc-ecosystem/grpc-gateway/issues/35)
|
||||
- URL usage of nested messages causes nil pointer in proto3 [\#32](https://github.com/grpc-ecosystem/grpc-gateway/issues/32)
|
||||
- Multiple .proto files generates invalid import statements. [\#22](https://github.com/grpc-ecosystem/grpc-gateway/issues/22)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- remote peer address is lost in ctx - always resolves to localhost [\#173](https://github.com/grpc-ecosystem/grpc-gateway/issues/173)
|
||||
- Bidirectional streams don't concurrently Send and Recv [\#169](https://github.com/grpc-ecosystem/grpc-gateway/issues/169)
|
||||
- Error: failed to import google/api/annotations.proto [\#165](https://github.com/grpc-ecosystem/grpc-gateway/issues/165)
|
||||
- Test datarace in controlapi [\#163](https://github.com/grpc-ecosystem/grpc-gateway/issues/163)
|
||||
- not enough arguments in call to runtime.HTTPError [\#162](https://github.com/grpc-ecosystem/grpc-gateway/issues/162)
|
||||
- String-values for Enums in request object are not recognized. [\#150](https://github.com/grpc-ecosystem/grpc-gateway/issues/150)
|
||||
- Handling of import public "file.proto" [\#139](https://github.com/grpc-ecosystem/grpc-gateway/issues/139)
|
||||
- Does grpc-gateway support http middleware? [\#132](https://github.com/grpc-ecosystem/grpc-gateway/issues/132)
|
||||
- push to web clients using WS or SSE ? [\#131](https://github.com/grpc-ecosystem/grpc-gateway/issues/131)
|
||||
- protoc-gen-swagger comment parsing for documentation gen [\#128](https://github.com/grpc-ecosystem/grpc-gateway/issues/128)
|
||||
- generated code has a data race [\#123](https://github.com/grpc-ecosystem/grpc-gateway/issues/123)
|
||||
- panic: net/http: CloseNotify called after ServeHTTP finished [\#121](https://github.com/grpc-ecosystem/grpc-gateway/issues/121)
|
||||
- CloseNotify race with ServeHTTP [\#119](https://github.com/grpc-ecosystem/grpc-gateway/issues/119)
|
||||
- echo service example does not compile [\#117](https://github.com/grpc-ecosystem/grpc-gateway/issues/117)
|
||||
- go vet issues in template\_test.go [\#113](https://github.com/grpc-ecosystem/grpc-gateway/issues/113)
|
||||
- undefined: proto.SizeVarint [\#103](https://github.com/grpc-ecosystem/grpc-gateway/issues/103)
|
||||
- Closing the HTTP connection does not cancel the Context [\#101](https://github.com/grpc-ecosystem/grpc-gateway/issues/101)
|
||||
- Logging [\#92](https://github.com/grpc-ecosystem/grpc-gateway/issues/92)
|
||||
- Missing default values in JSON output? [\#91](https://github.com/grpc-ecosystem/grpc-gateway/issues/91)
|
||||
- Better grpc error strings [\#87](https://github.com/grpc-ecosystem/grpc-gateway/issues/87)
|
||||
- Fields aren't named in the same manner as golang/protobuf [\#84](https://github.com/grpc-ecosystem/grpc-gateway/issues/84)
|
||||
- Header Forwarding from server. [\#73](https://github.com/grpc-ecosystem/grpc-gateway/issues/73)
|
||||
- No pattern specified in google.api.HttpRule [\#70](https://github.com/grpc-ecosystem/grpc-gateway/issues/70)
|
||||
- cannot find package "google/api" [\#67](https://github.com/grpc-ecosystem/grpc-gateway/issues/67)
|
||||
- Generated .pb.go with services no longer works with latest version of grpc-go. [\#62](https://github.com/grpc-ecosystem/grpc-gateway/issues/62)
|
||||
- JavaScript Proxy [\#61](https://github.com/grpc-ecosystem/grpc-gateway/issues/61)
|
||||
- Add HTTP error code, error status to responseStreamChunk Error [\#58](https://github.com/grpc-ecosystem/grpc-gateway/issues/58)
|
||||
- Reverse the code gen idea [\#44](https://github.com/grpc-ecosystem/grpc-gateway/issues/44)
|
||||
- array of maps in json [\#43](https://github.com/grpc-ecosystem/grpc-gateway/issues/43)
|
||||
- Examples break with 1.5 because of import of "main" examples package [\#37](https://github.com/grpc-ecosystem/grpc-gateway/issues/37)
|
||||
- Breaks with 1.5rc1 due to "internal" package name. [\#36](https://github.com/grpc-ecosystem/grpc-gateway/issues/36)
|
||||
- Feature Request: Support for non-nullable nested messages. [\#20](https://github.com/grpc-ecosystem/grpc-gateway/issues/20)
|
||||
- Is PascalFromSnake the right conversion to be doing? [\#19](https://github.com/grpc-ecosystem/grpc-gateway/issues/19)
|
||||
- Infinite loop in generator when package name conflicts [\#17](https://github.com/grpc-ecosystem/grpc-gateway/issues/17)
|
||||
- google.api.http options in multi-line format not supported [\#16](https://github.com/grpc-ecosystem/grpc-gateway/issues/16)
|
||||
- Is there any plan to developing a C++ version? [\#15](https://github.com/grpc-ecosystem/grpc-gateway/issues/15)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Regenerate files with the latest protoc-gen-go [\#185](https://github.com/grpc-ecosystem/grpc-gateway/pull/185) ([yugui](https://github.com/yugui))
|
||||
- Add browser examples [\#184](https://github.com/grpc-ecosystem/grpc-gateway/pull/184) ([yugui](https://github.com/yugui))
|
||||
- Fix golint and go vet errors [\#182](https://github.com/grpc-ecosystem/grpc-gateway/pull/182) ([yugui](https://github.com/yugui))
|
||||
- Add integration with clients generated by swagger-codegen [\#181](https://github.com/grpc-ecosystem/grpc-gateway/pull/181) ([yugui](https://github.com/yugui))
|
||||
- Simplify example services [\#180](https://github.com/grpc-ecosystem/grpc-gateway/pull/180) ([yugui](https://github.com/yugui))
|
||||
- Avoid errors when req.RemoteAddr is empty [\#178](https://github.com/grpc-ecosystem/grpc-gateway/pull/178) ([yugui](https://github.com/yugui))
|
||||
- Feature/headers [\#176](https://github.com/grpc-ecosystem/grpc-gateway/pull/176) ([yugui](https://github.com/yugui))
|
||||
- Include HTTP req.remoteAddr in gRPC ctx [\#174](https://github.com/grpc-ecosystem/grpc-gateway/pull/174) ([mikeatlas](https://github.com/mikeatlas))
|
||||
- Update dependencies [\#171](https://github.com/grpc-ecosystem/grpc-gateway/pull/171) ([yugui](https://github.com/yugui))
|
||||
- Add bidirectional streaming support by running Send\(\) and Recv\(\) concurrently [\#170](https://github.com/grpc-ecosystem/grpc-gateway/pull/170) ([tmc](https://github.com/tmc))
|
||||
- make Authorization header check case-insensitive to comply with RFC 2616 4.2 [\#164](https://github.com/grpc-ecosystem/grpc-gateway/pull/164) ([tmc](https://github.com/tmc))
|
||||
- jsonpb: avoid duplicating upstream's struct [\#158](https://github.com/grpc-ecosystem/grpc-gateway/pull/158) ([tamird](https://github.com/tamird))
|
||||
- Generate Swagger description for service methods using proto comments. [\#156](https://github.com/grpc-ecosystem/grpc-gateway/pull/156) ([t-yuki](https://github.com/t-yuki))
|
||||
- Implement gRPC timeout support for inbound HTTP headers [\#155](https://github.com/grpc-ecosystem/grpc-gateway/pull/155) ([mwitkow](https://github.com/mwitkow))
|
||||
- Add more examples to marshalers [\#154](https://github.com/grpc-ecosystem/grpc-gateway/pull/154) ([yugui](https://github.com/yugui))
|
||||
- custom marshaler: handle `Accept` headers correctly [\#152](https://github.com/grpc-ecosystem/grpc-gateway/pull/152) ([tamird](https://github.com/tamird))
|
||||
- Simplify custom marshaler API [\#151](https://github.com/grpc-ecosystem/grpc-gateway/pull/151) ([yugui](https://github.com/yugui))
|
||||
- Fix camel case path parameter handling in swagger [\#149](https://github.com/grpc-ecosystem/grpc-gateway/pull/149) ([yugui](https://github.com/yugui))
|
||||
- Swagger dot in path template [\#148](https://github.com/grpc-ecosystem/grpc-gateway/pull/148) ([yugui](https://github.com/yugui))
|
||||
- Support map types in swagger generator [\#147](https://github.com/grpc-ecosystem/grpc-gateway/pull/147) ([yugui](https://github.com/yugui))
|
||||
- Cleanup custom marshaler [\#146](https://github.com/grpc-ecosystem/grpc-gateway/pull/146) ([yugui](https://github.com/yugui))
|
||||
- Implement custom Marshaler support, add jsonpb implemention. [\#144](https://github.com/grpc-ecosystem/grpc-gateway/pull/144) ([tmc](https://github.com/tmc))
|
||||
- Allow period in path URL templates when generating Swagger templates. [\#143](https://github.com/grpc-ecosystem/grpc-gateway/pull/143) ([ivucica](https://github.com/ivucica))
|
||||
- Link to LICENSE.txt [\#142](https://github.com/grpc-ecosystem/grpc-gateway/pull/142) ([sunkuet02](https://github.com/sunkuet02))
|
||||
- Support map types in swagger generator [\#141](https://github.com/grpc-ecosystem/grpc-gateway/pull/141) ([t-yuki](https://github.com/t-yuki))
|
||||
- Conditionally stops checking if generated file are up-to-date [\#136](https://github.com/grpc-ecosystem/grpc-gateway/pull/136) ([yugui](https://github.com/yugui))
|
||||
- Generate Swagger description for service methods using proto comments. [\#134](https://github.com/grpc-ecosystem/grpc-gateway/pull/134) ([ivucica](https://github.com/ivucica))
|
||||
- Swagger definitions now have `type` set to `object`. [\#133](https://github.com/grpc-ecosystem/grpc-gateway/pull/133) ([ivucica](https://github.com/ivucica))
|
||||
- go\_package option as go import path [\#129](https://github.com/grpc-ecosystem/grpc-gateway/pull/129) ([kazegusuri](https://github.com/kazegusuri))
|
||||
- Fix govet errors [\#126](https://github.com/grpc-ecosystem/grpc-gateway/pull/126) ([yugui](https://github.com/yugui))
|
||||
- Fix data-race in generated codes [\#125](https://github.com/grpc-ecosystem/grpc-gateway/pull/125) ([yugui](https://github.com/yugui))
|
||||
- Fix \#119 - CloseNotify race with ServeHTTP [\#120](https://github.com/grpc-ecosystem/grpc-gateway/pull/120) ([cuongdo](https://github.com/cuongdo))
|
||||
- Replace glog with grpclog [\#118](https://github.com/grpc-ecosystem/grpc-gateway/pull/118) ([cuongdo](https://github.com/cuongdo))
|
||||
- Fix a goroutine-leak in HTTP keep-alive [\#116](https://github.com/grpc-ecosystem/grpc-gateway/pull/116) ([yugui](https://github.com/yugui))
|
||||
- Fix camel case path parameter handling in swagger [\#114](https://github.com/grpc-ecosystem/grpc-gateway/pull/114) ([t-yuki](https://github.com/t-yuki))
|
||||
- gofmt -s [\#112](https://github.com/grpc-ecosystem/grpc-gateway/pull/112) ([shawnps](https://github.com/shawnps))
|
||||
- fix typo [\#111](https://github.com/grpc-ecosystem/grpc-gateway/pull/111) ([shawnps](https://github.com/shawnps))
|
||||
- fix typo [\#110](https://github.com/grpc-ecosystem/grpc-gateway/pull/110) ([shawnps](https://github.com/shawnps))
|
||||
- fixes missing swagger operation objects [\#109](https://github.com/grpc-ecosystem/grpc-gateway/pull/109) ([t-yuki](https://github.com/t-yuki))
|
||||
- Add parser and swagger support for enum, no gengateway yet [\#108](https://github.com/grpc-ecosystem/grpc-gateway/pull/108) ([t-yuki](https://github.com/t-yuki))
|
||||
- README: add protoc-gen-swagger too [\#105](https://github.com/grpc-ecosystem/grpc-gateway/pull/105) ([philips](https://github.com/philips))
|
||||
- README: Suggest go get -u by default. [\#104](https://github.com/grpc-ecosystem/grpc-gateway/pull/104) ([shurcooL](https://github.com/shurcooL))
|
||||
- Cancel context when HTTP connection is closed [\#102](https://github.com/grpc-ecosystem/grpc-gateway/pull/102) ([floridoo](https://github.com/floridoo))
|
||||
- wait test server up [\#100](https://github.com/grpc-ecosystem/grpc-gateway/pull/100) ([kazegusuri](https://github.com/kazegusuri))
|
||||
- Fix the swagger section of the README.md [\#98](https://github.com/grpc-ecosystem/grpc-gateway/pull/98) ([naibaf0](https://github.com/naibaf0))
|
||||
- Add documentation for using Swagger [\#97](https://github.com/grpc-ecosystem/grpc-gateway/pull/97) ([achew22](https://github.com/achew22))
|
||||
- Better compatibility to field names generated by protoc-gen-go [\#96](https://github.com/grpc-ecosystem/grpc-gateway/pull/96) ([yugui](https://github.com/yugui))
|
||||
- Update protoc from 3.0.0-beta1 to 3.0.0-beta2 [\#95](https://github.com/grpc-ecosystem/grpc-gateway/pull/95) ([yugui](https://github.com/yugui))
|
||||
- Better grpc error strings [\#94](https://github.com/grpc-ecosystem/grpc-gateway/pull/94) ([floridoo](https://github.com/floridoo))
|
||||
- make available header and trailer metadata [\#93](https://github.com/grpc-ecosystem/grpc-gateway/pull/93) ([kazegusuri](https://github.com/kazegusuri))
|
||||
- make grpc.DialOption configurable [\#89](https://github.com/grpc-ecosystem/grpc-gateway/pull/89) ([kazegusuri](https://github.com/kazegusuri))
|
||||
- Add request in error handlers [\#88](https://github.com/grpc-ecosystem/grpc-gateway/pull/88) ([daniellowtw](https://github.com/daniellowtw))
|
||||
- Improve PascalFromSnake behavior [\#85](https://github.com/grpc-ecosystem/grpc-gateway/pull/85) ([tmc](https://github.com/tmc))
|
||||
- Typo grcp -\> grpc [\#81](https://github.com/grpc-ecosystem/grpc-gateway/pull/81) ([daniellowtw](https://github.com/daniellowtw))
|
||||
- Add abstraction of code generator implementation [\#78](https://github.com/grpc-ecosystem/grpc-gateway/pull/78) ([yugui](https://github.com/yugui))
|
||||
- Support multivalue of metadata [\#77](https://github.com/grpc-ecosystem/grpc-gateway/pull/77) ([yugui](https://github.com/yugui))
|
||||
- Fix broken test [\#76](https://github.com/grpc-ecosystem/grpc-gateway/pull/76) ([yugui](https://github.com/yugui))
|
||||
- Added missing instruction line in README [\#75](https://github.com/grpc-ecosystem/grpc-gateway/pull/75) ([betrcode](https://github.com/betrcode))
|
||||
- Fix a complie error in generated go files [\#71](https://github.com/grpc-ecosystem/grpc-gateway/pull/71) ([yugui](https://github.com/yugui))
|
||||
- Update generated .pb.go files in third\_party [\#69](https://github.com/grpc-ecosystem/grpc-gateway/pull/69) ([peter-edge](https://github.com/peter-edge))
|
||||
- Bugfix/handling headers for `Authorization` and `Host` [\#65](https://github.com/grpc-ecosystem/grpc-gateway/pull/65) ([mwitkow](https://github.com/mwitkow))
|
||||
- Fix `error` field always in chunk response [\#64](https://github.com/grpc-ecosystem/grpc-gateway/pull/64) ([mwitkow](https://github.com/mwitkow))
|
||||
- Update .pb.go to latest version. [\#63](https://github.com/grpc-ecosystem/grpc-gateway/pull/63) ([johansja](https://github.com/johansja))
|
||||
- Run more tests in Travis CI [\#60](https://github.com/grpc-ecosystem/grpc-gateway/pull/60) ([yugui](https://github.com/yugui))
|
||||
- Added http error code and error status for responseStreamChunk error [\#59](https://github.com/grpc-ecosystem/grpc-gateway/pull/59) ([kdima](https://github.com/kdima))
|
||||
- Fix parsing of verb and final path component. [\#55](https://github.com/grpc-ecosystem/grpc-gateway/pull/55) ([hbchai](https://github.com/hbchai))
|
||||
- add grpc.WithInsecure\(\) as option for grpc.Dial call in template [\#52](https://github.com/grpc-ecosystem/grpc-gateway/pull/52) ([peter-edge](https://github.com/peter-edge))
|
||||
- update .pb.go files for latest golang proto generation [\#51](https://github.com/grpc-ecosystem/grpc-gateway/pull/51) ([peter-edge](https://github.com/peter-edge))
|
||||
- Fix a build error with the latest protoc-gen-go [\#50](https://github.com/grpc-ecosystem/grpc-gateway/pull/50) ([yugui](https://github.com/yugui))
|
||||
- Configure Travis CI [\#49](https://github.com/grpc-ecosystem/grpc-gateway/pull/49) ([yugui](https://github.com/yugui))
|
||||
- Follow a change of go package name convention in protoc-gen-go [\#48](https://github.com/grpc-ecosystem/grpc-gateway/pull/48) ([yugui](https://github.com/yugui))
|
||||
- Consider tail segments after deep wildcard [\#47](https://github.com/grpc-ecosystem/grpc-gateway/pull/47) ([yugui](https://github.com/yugui))
|
||||
- Fix typo in README [\#45](https://github.com/grpc-ecosystem/grpc-gateway/pull/45) ([jonboulle](https://github.com/jonboulle))
|
||||
- Fix undefined variable error in generated codes [\#42](https://github.com/grpc-ecosystem/grpc-gateway/pull/42) ([yugui](https://github.com/yugui))
|
||||
- Follow changes in protoc-gen-go and grpc-go [\#41](https://github.com/grpc-ecosystem/grpc-gateway/pull/41) ([yugui](https://github.com/yugui))
|
||||
- Fixes \#4 [\#40](https://github.com/grpc-ecosystem/grpc-gateway/pull/40) ([AmandaCameron](https://github.com/AmandaCameron))
|
||||
- fix examples to work with go1.5 [\#39](https://github.com/grpc-ecosystem/grpc-gateway/pull/39) ([tmc](https://github.com/tmc))
|
||||
- rename internal to utilties for 1.5 compatibility [\#38](https://github.com/grpc-ecosystem/grpc-gateway/pull/38) ([tmc](https://github.com/tmc))
|
||||
- Reflection fix of proto3 nested messages. [\#34](https://github.com/grpc-ecosystem/grpc-gateway/pull/34) ([mwitkow](https://github.com/mwitkow))
|
||||
- \[Experimental\] Make the response forwarder function customizable [\#31](https://github.com/grpc-ecosystem/grpc-gateway/pull/31) ([yugui](https://github.com/yugui))
|
||||
- Add f.Flush\(\) to runtime.ForwardResponseStream [\#30](https://github.com/grpc-ecosystem/grpc-gateway/pull/30) ([vvakame](https://github.com/vvakame))
|
||||
- Format error message in JSON [\#29](https://github.com/grpc-ecosystem/grpc-gateway/pull/29) ([yugui](https://github.com/yugui))
|
||||
- Update examples with HTTP header context annotation [\#28](https://github.com/grpc-ecosystem/grpc-gateway/pull/28) ([yugui](https://github.com/yugui))
|
||||
- Report semantic errors in the source to protoc [\#27](https://github.com/grpc-ecosystem/grpc-gateway/pull/27) ([yugui](https://github.com/yugui))
|
||||
- Add support for non-nullable nested messages. [\#21](https://github.com/grpc-ecosystem/grpc-gateway/pull/21) ([shurcooL](https://github.com/shurcooL))
|
||||
- Receive GRPC metadata from HTTP headers. [\#18](https://github.com/grpc-ecosystem/grpc-gateway/pull/18) ([crast](https://github.com/crast))
|
||||
- Implement detailed specs of google.api.http [\#14](https://github.com/grpc-ecosystem/grpc-gateway/pull/14) ([yugui](https://github.com/yugui))
|
||||
- Configure travis CI [\#13](https://github.com/grpc-ecosystem/grpc-gateway/pull/13) ([yugui](https://github.com/yugui))
|
||||
- Replace our own custom option with the one defined by Google [\#12](https://github.com/grpc-ecosystem/grpc-gateway/pull/12) ([yugui](https://github.com/yugui))
|
||||
- Remove useless context setup [\#11](https://github.com/grpc-ecosystem/grpc-gateway/pull/11) ([iamqizhao](https://github.com/iamqizhao))
|
||||
- Fix typo, path, missing semicolon. [\#10](https://github.com/grpc-ecosystem/grpc-gateway/pull/10) ([shurcooL](https://github.com/shurcooL))
|
||||
- Use a globally unique id for the custom option [\#3](https://github.com/grpc-ecosystem/grpc-gateway/pull/3) ([yugui](https://github.com/yugui))
|
||||
- implement ABitOfEverythingService [\#2](https://github.com/grpc-ecosystem/grpc-gateway/pull/2) ([mattn](https://github.com/mattn))
|
||||
- support streaming API calls [\#1](https://github.com/grpc-ecosystem/grpc-gateway/pull/1) ([yugui](https://github.com/yugui))
|
||||
|
||||
|
||||
|
||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
20
vendor/github.com/grpc-ecosystem/grpc-gateway/CONTRIBUTING.md
generated
vendored
Normal file
20
vendor/github.com/grpc-ecosystem/grpc-gateway/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
# How to contribute
|
||||
|
||||
Thank you for your contribution to grpc-gateway.
|
||||
Here's the recommended process of contribution.
|
||||
|
||||
1. `go get github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway`
|
||||
2. `cd $GOPATH/src/github.com/grpc-ecosystem/grpc-gateway`
|
||||
3. hack, hack, hack...
|
||||
4. Make sure that your change follows best practices in Go
|
||||
* [Effective Go](https://golang.org/doc/effective_go.html)
|
||||
* [Go Code Review Comments](https://golang.org/wiki/CodeReviewComments)
|
||||
5. Make sure that `make test` passes. (use swagger-codegen 2.2.2, not newer versions)
|
||||
6. Sign [a Contributor License Agreement](https://cla.developers.google.com/clas)
|
||||
7. Open a pull request in Github
|
||||
|
||||
When you work on a larger contribution, it is also recommended that you get in touch
|
||||
with us through the issue tracker.
|
||||
|
||||
### Code reviews
|
||||
All submissions, including submissions by project members, require review.
|
41
vendor/github.com/grpc-ecosystem/grpc-gateway/ISSUE_TEMPLATE.md
generated
vendored
Normal file
41
vendor/github.com/grpc-ecosystem/grpc-gateway/ISSUE_TEMPLATE.md
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
|
||||
# Please follow the general troubleshooting steps first:
|
||||
|
||||
- [ ] Update your protoc to the [latest version](https://github.com/google/protobuf/releases)
|
||||
- [ ] Update your copy of `grpc-gateway` to the latest version from github. with
|
||||
`git fetch https://github.com/grpc-ecosystem/grpc-gateway master && git reset --hard FETCH_HEAD`
|
||||
- [ ] Delete the `protoc-gen-grpc-gateway` and `protoc-gen-swagger` binary from your `PATH`,
|
||||
and install locally built binaries.
|
||||
|
||||
### Bug reports:
|
||||
|
||||
Fill in the following sections with explanations of what's gone wrong.
|
||||
|
||||
Steps you follow to reproduce the error:
|
||||
|
||||
<!-- Example steps
|
||||
1. I grab my catapult
|
||||
2. I load it with lettuce
|
||||
3. Press the fire button
|
||||
4. It falls over
|
||||
-->
|
||||
|
||||
Your steps here.
|
||||
|
||||
What did you expect to happen instead:
|
||||
|
||||
<!-- Example answer
|
||||
1. It would have rained lettuce from the sky bringing forth a cuddly army of bunnies we could
|
||||
play with
|
||||
-->
|
||||
|
||||
Your answer here.
|
||||
|
||||
What's your theory on why it isn't working:
|
||||
|
||||
<!-- Example answer
|
||||
Evil wizards are hoarding the bunnies and don't want to share. The wizards are casting
|
||||
lettuce protection spells so the cattapult won't work.
|
||||
-->
|
||||
|
||||
Your theory here.
|
27
vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt
generated
vendored
Normal file
27
vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2015, Gengo, 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 Gengo, 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.
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue