Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
a73990a3
Unverified
Commit
a73990a3
authored
Feb 22, 2017
by
Clayton Coleman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update etcd3 storage to leverage storage/value interfaces
Adds context argument which must be set for AES GCM authenticated data to be passed.
parent
f418468c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
52 additions
and
43 deletions
+52
-43
store.go
staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go
+33
-34
store_test.go
staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_test.go
+9
-2
watcher.go
staging/src/k8s.io/apiserver/pkg/storage/etcd3/watcher.go
+5
-4
etcd3.go
....io/apiserver/pkg/storage/storagebackend/factory/etcd3.go
+3
-2
cacher_test.go
...ing/src/k8s.io/apiserver/pkg/storage/tests/cacher_test.go
+2
-1
No files found.
staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go
View file @
a73990a3
...
@@ -36,27 +36,25 @@ import (
...
@@ -36,27 +36,25 @@ import (
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage/etcd"
"k8s.io/apiserver/pkg/storage/etcd"
"k8s.io/apiserver/pkg/storage/value"
utiltrace
"k8s.io/apiserver/pkg/util/trace"
utiltrace
"k8s.io/apiserver/pkg/util/trace"
)
)
// ValueTransformer allows a string value to be transformed before being read from or written to the underlying store. The methods
// authenticatedDataString satisfies the value.Context interface. It uses the key to
// must be able to undo the transformation caused by the other.
// authenticate the stored data. This does not defend against reuse of previously
type
ValueTransformer
interface
{
// encrypted values under the same key, but will prevent an attacker from using an
// TransformFromStorage may transform the provided data from its underlying storage representation or return an error.
// encrypted value from a different key. A stronger authenticated data segment would
// Stale is true if the object on disk is stale and a write to etcd should be issued, even if the contents of the object
// include the etcd3 Version field (which is incremented on each write to a key and
// have not changed.
// reset when the key is deleted), but an attacker with write access to etcd can
TransformFromStorage
([]
byte
)
(
data
[]
byte
,
stale
bool
,
err
error
)
// force deletion and recreation of keys to weaken that angle.
// TransformToStorage may transform the provided data into the appropriate form in storage or return an error.
type
authenticatedDataString
string
TransformToStorage
([]
byte
)
(
data
[]
byte
,
err
error
)
// AuthenticatedData implements the value.Context interface.
func
(
d
authenticatedDataString
)
AuthenticatedData
()
[]
byte
{
return
[]
byte
(
string
(
d
))
}
}
type
identityTransformer
struct
{}
var
_
value
.
Context
=
authenticatedDataString
(
""
)
func
(
identityTransformer
)
TransformFromStorage
(
b
[]
byte
)
([]
byte
,
bool
,
error
)
{
return
b
,
false
,
nil
}
func
(
identityTransformer
)
TransformToStorage
(
b
[]
byte
)
([]
byte
,
error
)
{
return
b
,
nil
}
// IdentityTransformer performs no transformation on the provided values.
var
IdentityTransformer
ValueTransformer
=
identityTransformer
{}
type
store
struct
{
type
store
struct
{
client
*
clientv3
.
Client
client
*
clientv3
.
Client
...
@@ -65,7 +63,7 @@ type store struct {
...
@@ -65,7 +63,7 @@ type store struct {
getOps
[]
clientv3
.
OpOption
getOps
[]
clientv3
.
OpOption
codec
runtime
.
Codec
codec
runtime
.
Codec
versioner
storage
.
Versioner
versioner
storage
.
Versioner
transformer
Value
Transformer
transformer
value
.
Transformer
pathPrefix
string
pathPrefix
string
watcher
*
watcher
watcher
*
watcher
}
}
...
@@ -84,17 +82,17 @@ type objState struct {
...
@@ -84,17 +82,17 @@ type objState struct {
}
}
// New returns an etcd3 implementation of storage.Interface.
// New returns an etcd3 implementation of storage.Interface.
func
New
(
c
*
clientv3
.
Client
,
codec
runtime
.
Codec
,
prefix
string
,
transformer
Value
Transformer
)
storage
.
Interface
{
func
New
(
c
*
clientv3
.
Client
,
codec
runtime
.
Codec
,
prefix
string
,
transformer
value
.
Transformer
)
storage
.
Interface
{
return
newStore
(
c
,
true
,
codec
,
prefix
,
transformer
)
return
newStore
(
c
,
true
,
codec
,
prefix
,
transformer
)
}
}
// NewWithNoQuorumRead returns etcd3 implementation of storage.Interface
// NewWithNoQuorumRead returns etcd3 implementation of storage.Interface
// where Get operations don't require quorum read.
// where Get operations don't require quorum read.
func
NewWithNoQuorumRead
(
c
*
clientv3
.
Client
,
codec
runtime
.
Codec
,
prefix
string
,
transformer
Value
Transformer
)
storage
.
Interface
{
func
NewWithNoQuorumRead
(
c
*
clientv3
.
Client
,
codec
runtime
.
Codec
,
prefix
string
,
transformer
value
.
Transformer
)
storage
.
Interface
{
return
newStore
(
c
,
false
,
codec
,
prefix
,
transformer
)
return
newStore
(
c
,
false
,
codec
,
prefix
,
transformer
)
}
}
func
newStore
(
c
*
clientv3
.
Client
,
quorumRead
bool
,
codec
runtime
.
Codec
,
prefix
string
,
transformer
Value
Transformer
)
*
store
{
func
newStore
(
c
*
clientv3
.
Client
,
quorumRead
bool
,
codec
runtime
.
Codec
,
prefix
string
,
transformer
value
.
Transformer
)
*
store
{
versioner
:=
etcd
.
APIObjectVersioner
{}
versioner
:=
etcd
.
APIObjectVersioner
{}
result
:=
&
store
{
result
:=
&
store
{
client
:
c
,
client
:
c
,
...
@@ -136,7 +134,7 @@ func (s *store) Get(ctx context.Context, key string, resourceVersion string, out
...
@@ -136,7 +134,7 @@ func (s *store) Get(ctx context.Context, key string, resourceVersion string, out
}
}
kv
:=
getResp
.
Kvs
[
0
]
kv
:=
getResp
.
Kvs
[
0
]
data
,
_
,
err
:=
s
.
transformer
.
TransformFromStorage
(
kv
.
Value
)
data
,
_
,
err
:=
s
.
transformer
.
TransformFromStorage
(
kv
.
Value
,
authenticatedDataString
(
key
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
storage
.
NewInternalError
(
err
.
Error
())
return
storage
.
NewInternalError
(
err
.
Error
())
}
}
...
@@ -160,7 +158,7 @@ func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object,
...
@@ -160,7 +158,7 @@ func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object,
return
err
return
err
}
}
newData
,
err
:=
s
.
transformer
.
TransformToStorage
(
data
)
newData
,
err
:=
s
.
transformer
.
TransformToStorage
(
data
,
authenticatedDataString
(
key
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
storage
.
NewInternalError
(
err
.
Error
())
return
storage
.
NewInternalError
(
err
.
Error
())
}
}
...
@@ -185,16 +183,16 @@ func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object,
...
@@ -185,16 +183,16 @@ func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object,
}
}
// Delete implements storage.Interface.Delete.
// Delete implements storage.Interface.Delete.
func
(
s
*
store
)
Delete
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
,
precondtions
*
storage
.
Preconditions
)
error
{
func
(
s
*
store
)
Delete
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
,
precond
i
tions
*
storage
.
Preconditions
)
error
{
v
,
err
:=
conversion
.
EnforcePtr
(
out
)
v
,
err
:=
conversion
.
EnforcePtr
(
out
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
"unable to convert output object to pointer"
)
panic
(
"unable to convert output object to pointer"
)
}
}
key
=
path
.
Join
(
s
.
pathPrefix
,
key
)
key
=
path
.
Join
(
s
.
pathPrefix
,
key
)
if
precondtions
==
nil
{
if
precond
i
tions
==
nil
{
return
s
.
unconditionalDelete
(
ctx
,
key
,
out
)
return
s
.
unconditionalDelete
(
ctx
,
key
,
out
)
}
}
return
s
.
conditionalDelete
(
ctx
,
key
,
out
,
v
,
precondtions
)
return
s
.
conditionalDelete
(
ctx
,
key
,
out
,
v
,
precond
i
tions
)
}
}
func
(
s
*
store
)
unconditionalDelete
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
)
error
{
func
(
s
*
store
)
unconditionalDelete
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
)
error
{
...
@@ -213,14 +211,14 @@ func (s *store) unconditionalDelete(ctx context.Context, key string, out runtime
...
@@ -213,14 +211,14 @@ func (s *store) unconditionalDelete(ctx context.Context, key string, out runtime
}
}
kv
:=
getResp
.
Kvs
[
0
]
kv
:=
getResp
.
Kvs
[
0
]
data
,
_
,
err
:=
s
.
transformer
.
TransformFromStorage
(
kv
.
Value
)
data
,
_
,
err
:=
s
.
transformer
.
TransformFromStorage
(
kv
.
Value
,
authenticatedDataString
(
key
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
storage
.
NewInternalError
(
err
.
Error
())
return
storage
.
NewInternalError
(
err
.
Error
())
}
}
return
decode
(
s
.
codec
,
s
.
versioner
,
data
,
out
,
kv
.
ModRevision
)
return
decode
(
s
.
codec
,
s
.
versioner
,
data
,
out
,
kv
.
ModRevision
)
}
}
func
(
s
*
store
)
conditionalDelete
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
,
v
reflect
.
Value
,
precondtions
*
storage
.
Preconditions
)
error
{
func
(
s
*
store
)
conditionalDelete
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
,
v
reflect
.
Value
,
precond
i
tions
*
storage
.
Preconditions
)
error
{
getResp
,
err
:=
s
.
client
.
KV
.
Get
(
ctx
,
key
)
getResp
,
err
:=
s
.
client
.
KV
.
Get
(
ctx
,
key
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -230,7 +228,7 @@ func (s *store) conditionalDelete(ctx context.Context, key string, out runtime.O
...
@@ -230,7 +228,7 @@ func (s *store) conditionalDelete(ctx context.Context, key string, out runtime.O
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
checkPreconditions
(
key
,
precondtions
,
origState
.
obj
);
err
!=
nil
{
if
err
:=
checkPreconditions
(
key
,
precond
i
tions
,
origState
.
obj
);
err
!=
nil
{
return
err
return
err
}
}
txnResp
,
err
:=
s
.
client
.
KV
.
Txn
(
ctx
)
.
If
(
txnResp
,
err
:=
s
.
client
.
KV
.
Txn
(
ctx
)
.
If
(
...
@@ -255,7 +253,7 @@ func (s *store) conditionalDelete(ctx context.Context, key string, out runtime.O
...
@@ -255,7 +253,7 @@ func (s *store) conditionalDelete(ctx context.Context, key string, out runtime.O
// GuaranteedUpdate implements storage.Interface.GuaranteedUpdate.
// GuaranteedUpdate implements storage.Interface.GuaranteedUpdate.
func
(
s
*
store
)
GuaranteedUpdate
(
func
(
s
*
store
)
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
,
ignoreNotFound
bool
,
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
,
ignoreNotFound
bool
,
precondtions
*
storage
.
Preconditions
,
tryUpdate
storage
.
UpdateFunc
,
suggestion
...
runtime
.
Object
)
error
{
precond
i
tions
*
storage
.
Preconditions
,
tryUpdate
storage
.
UpdateFunc
,
suggestion
...
runtime
.
Object
)
error
{
trace
:=
utiltrace
.
New
(
fmt
.
Sprintf
(
"GuaranteedUpdate etcd3: %s"
,
reflect
.
TypeOf
(
out
)
.
String
()))
trace
:=
utiltrace
.
New
(
fmt
.
Sprintf
(
"GuaranteedUpdate etcd3: %s"
,
reflect
.
TypeOf
(
out
)
.
String
()))
defer
trace
.
LogIfLong
(
500
*
time
.
Millisecond
)
defer
trace
.
LogIfLong
(
500
*
time
.
Millisecond
)
...
@@ -283,8 +281,9 @@ func (s *store) GuaranteedUpdate(
...
@@ -283,8 +281,9 @@ func (s *store) GuaranteedUpdate(
}
}
trace
.
Step
(
"initial value restored"
)
trace
.
Step
(
"initial value restored"
)
transformContext
:=
authenticatedDataString
(
key
)
for
{
for
{
if
err
:=
checkPreconditions
(
key
,
precondtions
,
origState
.
obj
);
err
!=
nil
{
if
err
:=
checkPreconditions
(
key
,
precond
i
tions
,
origState
.
obj
);
err
!=
nil
{
return
err
return
err
}
}
...
@@ -301,7 +300,7 @@ func (s *store) GuaranteedUpdate(
...
@@ -301,7 +300,7 @@ func (s *store) GuaranteedUpdate(
return
decode
(
s
.
codec
,
s
.
versioner
,
origState
.
data
,
out
,
origState
.
rev
)
return
decode
(
s
.
codec
,
s
.
versioner
,
origState
.
data
,
out
,
origState
.
rev
)
}
}
newData
,
err
:=
s
.
transformer
.
TransformToStorage
(
data
)
newData
,
err
:=
s
.
transformer
.
TransformToStorage
(
data
,
transformContext
)
if
err
!=
nil
{
if
err
!=
nil
{
return
storage
.
NewInternalError
(
err
.
Error
())
return
storage
.
NewInternalError
(
err
.
Error
())
}
}
...
@@ -354,7 +353,7 @@ func (s *store) GetToList(ctx context.Context, key string, resourceVersion strin
...
@@ -354,7 +353,7 @@ func (s *store) GetToList(ctx context.Context, key string, resourceVersion strin
if
len
(
getResp
.
Kvs
)
==
0
{
if
len
(
getResp
.
Kvs
)
==
0
{
return
nil
return
nil
}
}
data
,
_
,
err
:=
s
.
transformer
.
TransformFromStorage
(
getResp
.
Kvs
[
0
]
.
Value
)
data
,
_
,
err
:=
s
.
transformer
.
TransformFromStorage
(
getResp
.
Kvs
[
0
]
.
Value
,
authenticatedDataString
(
key
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
storage
.
NewInternalError
(
err
.
Error
())
return
storage
.
NewInternalError
(
err
.
Error
())
}
}
...
@@ -389,7 +388,7 @@ func (s *store) List(ctx context.Context, key, resourceVersion string, pred stor
...
@@ -389,7 +388,7 @@ func (s *store) List(ctx context.Context, key, resourceVersion string, pred stor
elems
:=
make
([]
*
elemForDecode
,
0
,
len
(
getResp
.
Kvs
))
elems
:=
make
([]
*
elemForDecode
,
0
,
len
(
getResp
.
Kvs
))
for
_
,
kv
:=
range
getResp
.
Kvs
{
for
_
,
kv
:=
range
getResp
.
Kvs
{
data
,
_
,
err
:=
s
.
transformer
.
TransformFromStorage
(
kv
.
Value
)
data
,
_
,
err
:=
s
.
transformer
.
TransformFromStorage
(
kv
.
Value
,
authenticatedDataString
(
key
)
)
if
err
!=
nil
{
if
err
!=
nil
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"unable to transform key %q: %v"
,
key
,
err
))
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"unable to transform key %q: %v"
,
key
,
err
))
continue
continue
...
@@ -439,7 +438,7 @@ func (s *store) getState(getResp *clientv3.GetResponse, key string, v reflect.Va
...
@@ -439,7 +438,7 @@ func (s *store) getState(getResp *clientv3.GetResponse, key string, v reflect.Va
return
nil
,
err
return
nil
,
err
}
}
}
else
{
}
else
{
data
,
stale
,
err
:=
s
.
transformer
.
TransformFromStorage
(
getResp
.
Kvs
[
0
]
.
Value
)
data
,
stale
,
err
:=
s
.
transformer
.
TransformFromStorage
(
getResp
.
Kvs
[
0
]
.
Value
,
authenticatedDataString
(
key
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
storage
.
NewInternalError
(
err
.
Error
())
return
nil
,
storage
.
NewInternalError
(
err
.
Error
())
}
}
...
...
staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_test.go
View file @
a73990a3
...
@@ -35,6 +35,7 @@ import (
...
@@ -35,6 +35,7 @@ import (
examplev1
"k8s.io/apiserver/pkg/apis/example/v1"
examplev1
"k8s.io/apiserver/pkg/apis/example/v1"
"k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage"
storagetests
"k8s.io/apiserver/pkg/storage/tests"
storagetests
"k8s.io/apiserver/pkg/storage/tests"
"k8s.io/apiserver/pkg/storage/value"
"github.com/coreos/etcd/integration"
"github.com/coreos/etcd/integration"
"golang.org/x/net/context"
"golang.org/x/net/context"
...
@@ -56,13 +57,19 @@ type prefixTransformer struct {
...
@@ -56,13 +57,19 @@ type prefixTransformer struct {
err
error
err
error
}
}
func
(
p
prefixTransformer
)
TransformFromStorage
(
b
[]
byte
)
([]
byte
,
bool
,
error
)
{
func
(
p
prefixTransformer
)
TransformFromStorage
(
b
[]
byte
,
ctx
value
.
Context
)
([]
byte
,
bool
,
error
)
{
if
ctx
==
nil
{
panic
(
"no context provided"
)
}
if
!
bytes
.
HasPrefix
(
b
,
p
.
prefix
)
{
if
!
bytes
.
HasPrefix
(
b
,
p
.
prefix
)
{
return
nil
,
false
,
fmt
.
Errorf
(
"value does not have expected prefix: %s"
,
string
(
b
))
return
nil
,
false
,
fmt
.
Errorf
(
"value does not have expected prefix: %s"
,
string
(
b
))
}
}
return
bytes
.
TrimPrefix
(
b
,
p
.
prefix
),
p
.
stale
,
p
.
err
return
bytes
.
TrimPrefix
(
b
,
p
.
prefix
),
p
.
stale
,
p
.
err
}
}
func
(
p
prefixTransformer
)
TransformToStorage
(
b
[]
byte
)
([]
byte
,
error
)
{
func
(
p
prefixTransformer
)
TransformToStorage
(
b
[]
byte
,
ctx
value
.
Context
)
([]
byte
,
error
)
{
if
ctx
==
nil
{
panic
(
"no context provided"
)
}
if
len
(
b
)
>
0
{
if
len
(
b
)
>
0
{
return
append
(
append
([]
byte
{},
p
.
prefix
...
),
b
...
),
p
.
err
return
append
(
append
([]
byte
{},
p
.
prefix
...
),
b
...
),
p
.
err
}
}
...
...
staging/src/k8s.io/apiserver/pkg/storage/etcd3/watcher.go
View file @
a73990a3
...
@@ -26,6 +26,7 @@ import (
...
@@ -26,6 +26,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage/value"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/clientv3"
etcdrpc
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
etcdrpc
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
...
@@ -43,7 +44,7 @@ type watcher struct {
...
@@ -43,7 +44,7 @@ type watcher struct {
client
*
clientv3
.
Client
client
*
clientv3
.
Client
codec
runtime
.
Codec
codec
runtime
.
Codec
versioner
storage
.
Versioner
versioner
storage
.
Versioner
transformer
Value
Transformer
transformer
value
.
Transformer
}
}
// watchChan implements watch.Interface.
// watchChan implements watch.Interface.
...
@@ -60,7 +61,7 @@ type watchChan struct {
...
@@ -60,7 +61,7 @@ type watchChan struct {
errChan
chan
error
errChan
chan
error
}
}
func
newWatcher
(
client
*
clientv3
.
Client
,
codec
runtime
.
Codec
,
versioner
storage
.
Versioner
,
transformer
Value
Transformer
)
*
watcher
{
func
newWatcher
(
client
*
clientv3
.
Client
,
codec
runtime
.
Codec
,
versioner
storage
.
Versioner
,
transformer
value
.
Transformer
)
*
watcher
{
return
&
watcher
{
return
&
watcher
{
client
:
client
,
client
:
client
,
codec
:
codec
,
codec
:
codec
,
...
@@ -343,7 +344,7 @@ func (wc *watchChan) sendEvent(e *event) {
...
@@ -343,7 +344,7 @@ func (wc *watchChan) sendEvent(e *event) {
func
(
wc
*
watchChan
)
prepareObjs
(
e
*
event
)
(
curObj
runtime
.
Object
,
oldObj
runtime
.
Object
,
err
error
)
{
func
(
wc
*
watchChan
)
prepareObjs
(
e
*
event
)
(
curObj
runtime
.
Object
,
oldObj
runtime
.
Object
,
err
error
)
{
if
!
e
.
isDeleted
{
if
!
e
.
isDeleted
{
data
,
_
,
err
:=
wc
.
watcher
.
transformer
.
TransformFromStorage
(
e
.
value
)
data
,
_
,
err
:=
wc
.
watcher
.
transformer
.
TransformFromStorage
(
e
.
value
,
authenticatedDataString
(
e
.
key
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
...
@@ -358,7 +359,7 @@ func (wc *watchChan) prepareObjs(e *event) (curObj runtime.Object, oldObj runtim
...
@@ -358,7 +359,7 @@ func (wc *watchChan) prepareObjs(e *event) (curObj runtime.Object, oldObj runtim
// we need the object only to compute whether it was filtered out
// we need the object only to compute whether it was filtered out
// before).
// before).
if
len
(
e
.
prevValue
)
>
0
&&
(
e
.
isDeleted
||
!
wc
.
acceptAll
())
{
if
len
(
e
.
prevValue
)
>
0
&&
(
e
.
isDeleted
||
!
wc
.
acceptAll
())
{
data
,
_
,
err
:=
wc
.
watcher
.
transformer
.
TransformFromStorage
(
e
.
prevValue
)
data
,
_
,
err
:=
wc
.
watcher
.
transformer
.
TransformFromStorage
(
e
.
prevValue
,
authenticatedDataString
(
e
.
key
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
...
...
staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go
View file @
a73990a3
...
@@ -20,6 +20,7 @@ import (
...
@@ -20,6 +20,7 @@ import (
"k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage/etcd3"
"k8s.io/apiserver/pkg/storage/etcd3"
"k8s.io/apiserver/pkg/storage/storagebackend"
"k8s.io/apiserver/pkg/storage/storagebackend"
"k8s.io/apiserver/pkg/storage/value"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/pkg/transport"
"github.com/coreos/etcd/pkg/transport"
...
@@ -56,7 +57,7 @@ func newETCD3Storage(c storagebackend.Config) (storage.Interface, DestroyFunc, e
...
@@ -56,7 +57,7 @@ func newETCD3Storage(c storagebackend.Config) (storage.Interface, DestroyFunc, e
client
.
Close
()
client
.
Close
()
}
}
if
c
.
Quorum
{
if
c
.
Quorum
{
return
etcd3
.
New
(
client
,
c
.
Codec
,
c
.
Prefix
,
etcd3
.
IdentityTransformer
),
destroyFunc
,
nil
return
etcd3
.
New
(
client
,
c
.
Codec
,
c
.
Prefix
,
value
.
IdentityTransformer
),
destroyFunc
,
nil
}
}
return
etcd3
.
NewWithNoQuorumRead
(
client
,
c
.
Codec
,
c
.
Prefix
,
etcd3
.
IdentityTransformer
),
destroyFunc
,
nil
return
etcd3
.
NewWithNoQuorumRead
(
client
,
c
.
Codec
,
c
.
Prefix
,
value
.
IdentityTransformer
),
destroyFunc
,
nil
}
}
staging/src/k8s.io/apiserver/pkg/storage/tests/cacher_test.go
View file @
a73990a3
...
@@ -42,6 +42,7 @@ import (
...
@@ -42,6 +42,7 @@ import (
"k8s.io/apiserver/pkg/storage/etcd/etcdtest"
"k8s.io/apiserver/pkg/storage/etcd/etcdtest"
etcdtesting
"k8s.io/apiserver/pkg/storage/etcd/testing"
etcdtesting
"k8s.io/apiserver/pkg/storage/etcd/testing"
"k8s.io/apiserver/pkg/storage/etcd3"
"k8s.io/apiserver/pkg/storage/etcd3"
"k8s.io/apiserver/pkg/storage/value"
"golang.org/x/net/context"
"golang.org/x/net/context"
...
@@ -92,7 +93,7 @@ func AddObjectMetaFieldsSet(source fields.Set, objectMeta *metav1.ObjectMeta, ha
...
@@ -92,7 +93,7 @@ func AddObjectMetaFieldsSet(source fields.Set, objectMeta *metav1.ObjectMeta, ha
func
newEtcdTestStorage
(
t
*
testing
.
T
,
prefix
string
)
(
*
etcdtesting
.
EtcdTestServer
,
storage
.
Interface
)
{
func
newEtcdTestStorage
(
t
*
testing
.
T
,
prefix
string
)
(
*
etcdtesting
.
EtcdTestServer
,
storage
.
Interface
)
{
server
,
_
:=
etcdtesting
.
NewUnsecuredEtcd3TestClientServer
(
t
,
scheme
)
server
,
_
:=
etcdtesting
.
NewUnsecuredEtcd3TestClientServer
(
t
,
scheme
)
storage
:=
etcd3
.
New
(
server
.
V3Client
,
apitesting
.
TestCodec
(
codecs
,
examplev1
.
SchemeGroupVersion
),
prefix
,
etcd3
.
IdentityTransformer
)
storage
:=
etcd3
.
New
(
server
.
V3Client
,
apitesting
.
TestCodec
(
codecs
,
examplev1
.
SchemeGroupVersion
),
prefix
,
value
.
IdentityTransformer
)
return
server
,
storage
return
server
,
storage
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment