-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
namespace proxy #7549
namespace proxy #7549
Conversation
clientv3/op.go
Outdated
@@ -69,6 +69,15 @@ type Op struct { | |||
leaseID LeaseID | |||
} | |||
|
|||
// accesors / mutators | |||
|
|||
func (op Op) KeyBytes() []byte { return op.key } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's document these public funcs.
clientv3/compare.go
Outdated
@@ -82,6 +82,16 @@ func ModRevision(key string) Cmp { | |||
return Cmp{Key: []byte(key), Target: pb.Compare_MOD} | |||
} | |||
|
|||
func (cmp *Cmp) KeyBytes() []byte { return cmp.Key } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let us document these public funcs.
import ( | ||
"sync" | ||
|
||
"golang.org/x/net/context" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use context instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
./watch.go:35: cannot use watcherPrefix literal (type *watcherPrefix) as type clientv3.Watcher in return argument:
*watcherPrefix does not implement clientv3.Watcher (wrong type for Watch method)
have Watch("context".Context, string, ...clientv3.OpOption) clientv3.WatchChan
want Watch("golang.org/x/net/context".Context, string, ...clientv3.OpOption) clientv3.WatchChan
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok...
package namespace | ||
|
||
import ( | ||
"golang.org/x/net/context" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
./kv.go:33: cannot use kvPrefix literal (type *kvPrefix) as type clientv3.KV in return argument:
*kvPrefix does not implement clientv3.KV (wrong type for Delete method)
have Delete("context".Context, string, ...clientv3.OpOption) (*clientv3.DeleteResponse, error)
want Delete("golang.org/x/net/context".Context, string, ...clientv3.OpOption) (*clientv3.DeleteResponse, error)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. got it.
import ( | ||
"bytes" | ||
|
||
"golang.org/x/net/context" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
./lease.go:33: cannot use leasePrefix literal (type *leasePrefix) as type clientv3.Lease in return argument:
*leasePrefix does not implement clientv3.Lease (wrong type for TimeToLive method)
have TimeToLive("context".Context, clientv3.LeaseID, ...clientv3.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error)
want TimeToLive("golang.org/x/net/context".Context, clientv3.LeaseID, ...clientv3.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok got it.
|
||
package namespace | ||
|
||
func prefixInterval(pfx string, key, end []byte) (pfxKey []byte, pfxEnd []byte) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a unit test for this func?
"github.com/coreos/etcd/integration" | ||
"github.com/coreos/etcd/mvcc/mvccpb" | ||
"github.com/coreos/etcd/pkg/testutil" | ||
"golang.org/x/net/context" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use context?
clientv3/namespace/watch.go
Outdated
|
||
func (w *watcherPrefix) Watch(ctx context.Context, key string, opts ...clientv3.OpOption) clientv3.WatchChan { | ||
// add prefix | ||
op := clientv3.OpGet("abc", opts...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the use of this dummy op is not obvious. probably need a line of more specific comment.
Looks good in general. |
// Next, override the client interfaces: | ||
// | ||
// unprefixedKV := cli.KV | ||
// cli.KV = namespace.NewKV(cli.KV, "my-prefix/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my initial thought was to add a WithPrefix option to NewKV function. But I guess a new pkg might be cleaner though. The only problem is discoverability of this new pkg. we probably also needs to add a one line doc somewhere in the root doc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trying to observe separation of concerns with this; a monster client that does everything seems much more difficult to maintain than having composable wrappers-- docs are no big deal by comparison...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree
namespaced proxy is great! It can help to limit the access of an etcd cluster to a prefix without changing any client logic. In the long term, I also want the proxy to support multiple etcd clusters through auto discovery. Say we have etcd-us, etcd-cn, etcd-jp, etcd-kr, etcd-uk. Users can do client.Put("abc", WithCluster("us")) and the gRPC proxy should forward the request to etcd-us (optionally auto fail back to a default cluster one if the requested Cluster does not exist). This might be useful for supporting sharded etcd cluster for different Kubernetes namespace without introducing too much client side changes. For example, Kubernetes API server can still accept only a set of symmetric endpoints (gRPC proxy endpoints). All we need to do is to attach different namespace as cluster option in client. |
clientv3/namespace/util.go
Outdated
pfxEnd = []byte{0} | ||
} | ||
} else if len(end) >= 1 { | ||
pfxKey = make([]byte, len(pfx)+len(key)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aren't these redundant with line 18-19?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was a bug; fixed while writing the unit test
18b347c
to
08aede2
Compare
Documentation/op-guide/grpc_proxy.md
Outdated
```bash | ||
$ etcd grpc-proxy start --endpoints=localhost:2379 \ | ||
--listen-addr=127.0.0.1:23790 \ | ||
--namespace-prefix=my-prefix/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we also test grpc-proxy with namespace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like, -tags cluster_proxy? I don't think it'll exercise any behavior that's not already covered by the clientv3/integration tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although, it probably should because it might miss some update to the protocol and not translate the full response like the grpcproxy proper has done in the past. The patch to test it is relatively unobtrusive, I'll throw it on...
Documentation/op-guide/grpc_proxy.md
Outdated
|
||
Suppose an application expects full control over the entire key space, but the etcd cluster is shared with other applications. To let all appications run without interfering with each other, the proxy can partition the etcd keyspace so clients appear to have access to the complete keyspace. When the proxy is given the flag `--namespace-prefix`, all client requests going into the proxy are translated to have a user-defined prefix on the keys. Accesses to the etcd cluster will be under the prefix and responses from the proxy will strip away the prefix; to the client, it appears as if there is no prefix at all. | ||
|
||
To namespace a proxy, start it with `--namespace-prefix`: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i feel namespace is clear enough. it is shorter than namespace-prefix.
@@ -0,0 +1,43 @@ | |||
// Copyright 2017 The etcd Authors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we also add a link to this godoc in https://github.com/coreos/etcd/tree/master/clientv3#etcdclientv3? I think this should be useful for a lot of users.
LGTM |
08aede2
to
324383e
Compare
integration/cluster_proxy.go
Outdated
@@ -44,9 +46,16 @@ func toGRPC(c *clientv3.Client) grpcAPI { | |||
if v, ok := proxies[c]; ok { | |||
return v.grpc | |||
} | |||
|
|||
// test namespacing proxy | |||
c.KV = namespace.NewKV(c.KV, ns) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is ns
var defined? I don't see it.
3b7a41d
to
c3e3508
Compare
c3e3508
to
978118b
Compare
lgtm |
Hardcode a namespace over the testing grpcproxy.
978118b
to
85f989a
Compare
No description provided.