Skip to content

Commit 7078e7d

Browse files
author
Daniel Hiltgen
committed
Bump to latest libkv/libnetwork + dependencies
The latest libkv uses a different etcd library. Unfortunately that library uses some funky import paths, so I've added a new cleanup routine for our vendor scripts to be able to normalize the imports to be consistent with how imports work in this tree. Signed-off-by: Daniel Hiltgen <[email protected]>
1 parent 4ea3ff7 commit 7078e7d

76 files changed

Lines changed: 44458 additions & 1969 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

hack/.vendor-helpers.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,13 @@ clean() {
128128

129129
echo done
130130
}
131+
132+
# Fix up hard-coded imports that refer to Godeps paths so they'll work with our vendoring
133+
fix_rewritten_imports () {
134+
local pkg="$1"
135+
local remove="${pkg}/Godeps/_workspace/src/"
136+
local target="vendor/src/$pkg"
137+
138+
echo "$pkg: fixing rewritten imports"
139+
find "$target" -name \*.go -exec sed -i -e "s|\"${remove}|\"|g" {} \;
140+
}

hack/vendor.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,20 @@ clone git github.com/tchap/go-patricia v2.1.0
2020
clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://github.com/golang/net.git
2121

2222
#get libnetwork packages
23-
clone git github.com/docker/libnetwork 0521fe53fc3e7d4e7c2e463800f36662c9169f20
23+
clone git github.com/docker/libnetwork dd1c5f0ffe7697f75a82bd8e4bbd6f225ec5e383
2424
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
2525
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
2626
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
2727
clone git github.com/hashicorp/serf 7151adcef72687bf95f451a2e0ba15cb19412bf2
28-
clone git github.com/docker/libkv 958cd316db2bc916466bdcc632a3188d62ce6e87
28+
clone git github.com/docker/libkv 749af6c5b3fb755bec1738cc5e0d3a6f1574d730
2929
clone git github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
3030
clone git github.com/vishvananda/netlink 4b5dce31de6d42af5bb9811c6d265472199e0fec
3131
clone git github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060
3232
clone git github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374
3333
clone git github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d
34-
clone git github.com/coreos/go-etcd v2.0.0
34+
clone git github.com/coreos/etcd v2.2.0
35+
fix_rewritten_imports github.com/coreos/etcd
36+
clone git github.com/ugorji/go 5abd4e96a45c386928ed2ca2a7ef63e2533e18ec
3537
clone git github.com/hashicorp/consul v0.5.2
3638
clone git github.com/boltdb/bolt v1.0
3739

File renamed without changes.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# etcd/client
2+
3+
etcd/client is the Go client library for etcd.
4+
5+
[![GoDoc](https://godoc.org/github.com/coreos/etcd/client?status.png)](https://godoc.org/github.com/coreos/etcd/client)
6+
7+
## Install
8+
9+
```bash
10+
go get github.com/coreos/etcd/client
11+
```
12+
13+
## Usage
14+
15+
```go
16+
package main
17+
18+
import (
19+
"log"
20+
"time"
21+
22+
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
23+
"github.com/coreos/etcd/client"
24+
)
25+
26+
func main() {
27+
cfg := client.Config{
28+
Endpoints: []string{"http://127.0.0.1:2379"},
29+
Transport: client.DefaultTransport,
30+
// set timeout per request to fail fast when the target endpoint is unavailable
31+
HeaderTimeoutPerRequest: time.Second,
32+
}
33+
c, err := client.New(cfg)
34+
if err != nil {
35+
log.Fatal(err)
36+
}
37+
kapi := client.NewKeysAPI(c)
38+
resp, err := kapi.Set(context.Background(), "foo", "bar", nil)
39+
if err != nil {
40+
log.Fatal(err)
41+
}
42+
}
43+
```
44+
45+
## Error Handling
46+
47+
etcd client might return three types of errors.
48+
49+
- context error
50+
51+
Each API call has its first parameter as `context`. A context can be canceled or have an attached deadline. If the context is canceled or reaches its deadline, the responding context error will be returned no matter what internal errors the API call has already encountered.
52+
53+
- cluster error
54+
55+
Each API call tries to send request to the cluster endpoints one by one until it successfully gets a response. If a requests to an endpoint fails, due to exceeding per request timeout or connection issues, the error will be added into a list of errors. If all possible endpoints fail, a cluster error that includes all encountered errors will be returned.
56+
57+
- response error
58+
59+
If the response gets from the cluster is invalid, a plain string error will be returned. For example, it might be a invalid JSON error.
60+
61+
Here is the example code to handle client errors:
62+
63+
```go
64+
cfg := client.Config{Endpoints: []string{"http://etcd1:2379,http://etcd2:2379,http://etcd3:2379"}}
65+
c, err := client.New(cfg)
66+
if err != nil {
67+
log.Fatal(err)
68+
}
69+
70+
kapi := client.NewKeysAPI(c)
71+
resp, err := kapi.Set(ctx, "test", "bar", nil)
72+
if err != nil {
73+
if err == context.Canceled {
74+
// ctx is canceled by another routine
75+
} else if err == context.DeadlineExceeded {
76+
// ctx is attached with a deadline and it exceeded
77+
} else if cerr, ok := err.(*client.ClusterError); ok {
78+
// process (cerr.Errors)
79+
} else {
80+
// bad cluster endpoints, which are not etcd servers
81+
}
82+
}
83+
```
84+
85+
86+
## Caveat
87+
88+
1. etcd/client prefers to use the same endpoint as long as the endpoint continues to work well. This saves socket resources, and improves efficiency for both client and server side. This preference doesn't remove consistency from the data consumed by the client because data replicated to each etcd member has already passed through the consensus process.
89+
90+
2. etcd/client does round-robin rotation on other available endpoints if the preferred endpoint isn't functioning properly. For example, if the member that etcd/client connects to is hard killed, etcd/client will fail on the first attempt with the killed member, and succeed on the second attempt with another member. If it fails to talk to all available endpoints, it will return all errors happened.
91+
92+
3. Default etcd/client cannot handle the case that the remote server is SIGSTOPed now. TCP keepalive mechanism doesn't help in this scenario because operating system may still send TCP keep-alive packets. Over time we'd like to improve this functionality, but solving this issue isn't high priority because a real-life case in which a server is stopped, but the connection is kept alive, hasn't been brought to our attention.
93+
94+
4. etcd/client cannot detect whether the member in use is healthy when doing read requests. If the member is isolated from the cluster, etcd/client may retrieve outdated data. As a workaround, users could monitor experimental /health endpoint for member healthy information. We are improving it at [#3265](https://github.com/coreos/etcd/issues/3265).
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
// Copyright 2015 CoreOS, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package client
16+
17+
import (
18+
"bytes"
19+
"encoding/json"
20+
"net/http"
21+
"net/url"
22+
23+
"golang.org/x/net/context"
24+
)
25+
26+
type Role struct {
27+
Role string `json:"role"`
28+
Permissions Permissions `json:"permissions"`
29+
Grant *Permissions `json:"grant,omitempty"`
30+
Revoke *Permissions `json:"revoke,omitempty"`
31+
}
32+
33+
type Permissions struct {
34+
KV rwPermission `json:"kv"`
35+
}
36+
37+
type rwPermission struct {
38+
Read []string `json:"read"`
39+
Write []string `json:"write"`
40+
}
41+
42+
type PermissionType int
43+
44+
const (
45+
ReadPermission PermissionType = iota
46+
WritePermission
47+
ReadWritePermission
48+
)
49+
50+
// NewAuthRoleAPI constructs a new AuthRoleAPI that uses HTTP to
51+
// interact with etcd's role creation and modification features.
52+
func NewAuthRoleAPI(c Client) AuthRoleAPI {
53+
return &httpAuthRoleAPI{
54+
client: c,
55+
}
56+
}
57+
58+
type AuthRoleAPI interface {
59+
// Add a role.
60+
AddRole(ctx context.Context, role string) error
61+
62+
// Remove a role.
63+
RemoveRole(ctx context.Context, role string) error
64+
65+
// Get role details.
66+
GetRole(ctx context.Context, role string) (*Role, error)
67+
68+
// Grant a role some permission prefixes for the KV store.
69+
GrantRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
70+
71+
// Revoke some some permission prefixes for a role on the KV store.
72+
RevokeRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
73+
74+
// List roles.
75+
ListRoles(ctx context.Context) ([]string, error)
76+
}
77+
78+
type httpAuthRoleAPI struct {
79+
client httpClient
80+
}
81+
82+
type authRoleAPIAction struct {
83+
verb string
84+
name string
85+
role *Role
86+
}
87+
88+
type authRoleAPIList struct{}
89+
90+
func (list *authRoleAPIList) HTTPRequest(ep url.URL) *http.Request {
91+
u := v2AuthURL(ep, "roles", "")
92+
req, _ := http.NewRequest("GET", u.String(), nil)
93+
req.Header.Set("Content-Type", "application/json")
94+
return req
95+
}
96+
97+
func (l *authRoleAPIAction) HTTPRequest(ep url.URL) *http.Request {
98+
u := v2AuthURL(ep, "roles", l.name)
99+
if l.role == nil {
100+
req, _ := http.NewRequest(l.verb, u.String(), nil)
101+
return req
102+
}
103+
b, err := json.Marshal(l.role)
104+
if err != nil {
105+
panic(err)
106+
}
107+
body := bytes.NewReader(b)
108+
req, _ := http.NewRequest(l.verb, u.String(), body)
109+
req.Header.Set("Content-Type", "application/json")
110+
return req
111+
}
112+
113+
func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, error) {
114+
resp, body, err := r.client.Do(ctx, &authRoleAPIList{})
115+
if err != nil {
116+
return nil, err
117+
}
118+
if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
119+
return nil, err
120+
}
121+
var userList struct {
122+
Roles []string `json:"roles"`
123+
}
124+
err = json.Unmarshal(body, &userList)
125+
if err != nil {
126+
return nil, err
127+
}
128+
return userList.Roles, nil
129+
}
130+
131+
func (r *httpAuthRoleAPI) AddRole(ctx context.Context, rolename string) error {
132+
role := &Role{
133+
Role: rolename,
134+
}
135+
return r.addRemoveRole(ctx, &authRoleAPIAction{
136+
verb: "PUT",
137+
name: rolename,
138+
role: role,
139+
})
140+
}
141+
142+
func (r *httpAuthRoleAPI) RemoveRole(ctx context.Context, rolename string) error {
143+
return r.addRemoveRole(ctx, &authRoleAPIAction{
144+
verb: "DELETE",
145+
name: rolename,
146+
})
147+
}
148+
149+
func (r *httpAuthRoleAPI) addRemoveRole(ctx context.Context, req *authRoleAPIAction) error {
150+
resp, body, err := r.client.Do(ctx, req)
151+
if err != nil {
152+
return err
153+
}
154+
if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
155+
var sec authError
156+
err := json.Unmarshal(body, &sec)
157+
if err != nil {
158+
return err
159+
}
160+
return sec
161+
}
162+
return nil
163+
}
164+
165+
func (r *httpAuthRoleAPI) GetRole(ctx context.Context, rolename string) (*Role, error) {
166+
return r.modRole(ctx, &authRoleAPIAction{
167+
verb: "GET",
168+
name: rolename,
169+
})
170+
}
171+
172+
func buildRWPermission(prefixes []string, permType PermissionType) rwPermission {
173+
var out rwPermission
174+
switch permType {
175+
case ReadPermission:
176+
out.Read = prefixes
177+
case WritePermission:
178+
out.Write = prefixes
179+
case ReadWritePermission:
180+
out.Read = prefixes
181+
out.Write = prefixes
182+
}
183+
return out
184+
}
185+
186+
func (r *httpAuthRoleAPI) GrantRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
187+
rwp := buildRWPermission(prefixes, permType)
188+
role := &Role{
189+
Role: rolename,
190+
Grant: &Permissions{
191+
KV: rwp,
192+
},
193+
}
194+
return r.modRole(ctx, &authRoleAPIAction{
195+
verb: "PUT",
196+
name: rolename,
197+
role: role,
198+
})
199+
}
200+
201+
func (r *httpAuthRoleAPI) RevokeRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
202+
rwp := buildRWPermission(prefixes, permType)
203+
role := &Role{
204+
Role: rolename,
205+
Revoke: &Permissions{
206+
KV: rwp,
207+
},
208+
}
209+
return r.modRole(ctx, &authRoleAPIAction{
210+
verb: "PUT",
211+
name: rolename,
212+
role: role,
213+
})
214+
}
215+
216+
func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAPIAction) (*Role, error) {
217+
resp, body, err := r.client.Do(ctx, req)
218+
if err != nil {
219+
return nil, err
220+
}
221+
if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
222+
var sec authError
223+
err := json.Unmarshal(body, &sec)
224+
if err != nil {
225+
return nil, err
226+
}
227+
return nil, sec
228+
}
229+
var role Role
230+
err = json.Unmarshal(body, &role)
231+
if err != nil {
232+
return nil, err
233+
}
234+
return &role, nil
235+
}

0 commit comments

Comments
 (0)