Skip to content
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

Merged
merged 6 commits into from
Mar 23, 2017
Merged

namespace proxy #7549

merged 6 commits into from
Mar 23, 2017

Conversation

heyitsanthony
Copy link
Contributor

No description provided.

clientv3/op.go Outdated
@@ -69,6 +69,15 @@ type Op struct {
leaseID LeaseID
}

// accesors / mutators

func (op Op) KeyBytes() []byte { return op.key }
Copy link
Contributor

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.

@@ -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 }
Copy link
Contributor

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use context instead?

Copy link
Contributor Author

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

Copy link
Contributor

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just context?

Copy link
Contributor Author

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)

Copy link
Contributor

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use context?

Copy link
Contributor Author

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)

Copy link
Contributor

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) {
Copy link
Contributor

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use context?


func (w *watcherPrefix) Watch(ctx context.Context, key string, opts ...clientv3.OpOption) clientv3.WatchChan {
// add prefix
op := clientv3.OpGet("abc", opts...)
Copy link
Contributor

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.

@xiang90
Copy link
Contributor

xiang90 commented Mar 21, 2017

Looks good in general.

// Next, override the client interfaces:
//
// unprefixedKV := cli.KV
// cli.KV = namespace.NewKV(cli.KV, "my-prefix/")
Copy link
Contributor

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.

Copy link
Contributor Author

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...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

@xiang90
Copy link
Contributor

xiang90 commented Mar 21, 2017

@heyitsanthony

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.

/cc @wojtek-t @timothysc @heyitsanthony @smarterclayton

pfxEnd = []byte{0}
}
} else if len(end) >= 1 {
pfxKey = make([]byte, len(pfx)+len(key))
Copy link
Contributor

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?

Copy link
Contributor Author

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

```bash
$ etcd grpc-proxy start --endpoints=localhost:2379 \
--listen-addr=127.0.0.1:23790 \
--namespace-prefix=my-prefix/
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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...


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`:
Copy link
Contributor

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
Copy link
Contributor

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.

@xiang90
Copy link
Contributor

xiang90 commented Mar 21, 2017

LGTM

@@ -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)
Copy link
Member

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.

@heyitsanthony heyitsanthony force-pushed the namespace-proxy branch 6 times, most recently from 3b7a41d to c3e3508 Compare March 22, 2017 19:17
@fanminshi
Copy link
Member

lgtm

@heyitsanthony heyitsanthony merged commit 049ca87 into etcd-io:master Mar 23, 2017
@heyitsanthony heyitsanthony deleted the namespace-proxy branch March 23, 2017 06:26
@gyuho gyuho changed the title namespace proxy *: namespace proxy Apr 25, 2017
@gyuho gyuho changed the title *: namespace proxy namespace proxy Apr 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants