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
932553a0
Commit
932553a0
authored
Jun 04, 2019
by
Jordan Liggitt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Set expected in-memory version when decoding unstructured objects from etcd
parent
88f8c785
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
84 additions
and
9 deletions
+84
-9
etcd.go
...iextensions-apiserver/pkg/registry/customresource/etcd.go
+9
-2
conversion_test.go
...-apiserver/test/integration/conversion/conversion_test.go
+30
-5
unstructured.go
...pimachinery/pkg/apis/meta/v1/unstructured/unstructured.go
+10
-0
unstructured_list.go
...hinery/pkg/apis/meta/v1/unstructured/unstructured_list.go
+10
-0
interfaces.go
staging/src/k8s.io/apimachinery/pkg/runtime/interfaces.go
+3
-0
types.go
staging/src/k8s.io/apimachinery/pkg/runtime/testing/types.go
+8
-0
BUILD
staging/src/k8s.io/apiserver/pkg/storage/etcd3/BUILD
+1
-0
store.go
staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go
+7
-1
store_test.go
staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_test.go
+6
-1
No files found.
staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go
View file @
932553a0
...
@@ -177,12 +177,19 @@ type StatusREST struct {
...
@@ -177,12 +177,19 @@ type StatusREST struct {
var
_
=
rest
.
Patcher
(
&
StatusREST
{})
var
_
=
rest
.
Patcher
(
&
StatusREST
{})
func
(
r
*
StatusREST
)
New
()
runtime
.
Object
{
func
(
r
*
StatusREST
)
New
()
runtime
.
Object
{
return
&
unstructured
.
Unstructured
{}
return
r
.
store
.
New
()
}
}
// Get retrieves the object from the storage. It is required to support Patch.
// Get retrieves the object from the storage. It is required to support Patch.
func
(
r
*
StatusREST
)
Get
(
ctx
context
.
Context
,
name
string
,
options
*
metav1
.
GetOptions
)
(
runtime
.
Object
,
error
)
{
func
(
r
*
StatusREST
)
Get
(
ctx
context
.
Context
,
name
string
,
options
*
metav1
.
GetOptions
)
(
runtime
.
Object
,
error
)
{
return
r
.
store
.
Get
(
ctx
,
name
,
options
)
o
,
err
:=
r
.
store
.
Get
(
ctx
,
name
,
options
)
if
err
!=
nil
{
return
nil
,
err
}
if
u
,
ok
:=
o
.
(
*
unstructured
.
Unstructured
);
ok
{
shallowCopyObjectMeta
(
u
)
}
return
o
,
nil
}
}
// Update alters the status subset of an object.
// Update alters the status subset of an object.
...
...
staging/src/k8s.io/apiextensions-apiserver/test/integration/conversion/conversion_test.go
View file @
932553a0
...
@@ -58,15 +58,18 @@ func checks(checkers ...Checker) []Checker {
...
@@ -58,15 +58,18 @@ func checks(checkers ...Checker) []Checker {
return
checkers
return
checkers
}
}
func
TestWebhookConverter
(
t
*
testing
.
T
)
{
func
TestWebhookConverterWithWatchCache
(
t
*
testing
.
T
)
{
testWebhookConverter
(
t
,
false
)
testWebhookConverter
(
t
,
false
,
true
)
}
func
TestWebhookConverterWithoutWatchCache
(
t
*
testing
.
T
)
{
testWebhookConverter
(
t
,
false
,
false
)
}
}
func
TestWebhookConverterWithDefaulting
(
t
*
testing
.
T
)
{
func
TestWebhookConverterWithDefaulting
(
t
*
testing
.
T
)
{
testWebhookConverter
(
t
,
true
)
testWebhookConverter
(
t
,
true
,
true
)
}
}
func
testWebhookConverter
(
t
*
testing
.
T
,
defaulting
bool
)
{
func
testWebhookConverter
(
t
*
testing
.
T
,
defaulting
,
watchCache
bool
)
{
tests
:=
[]
struct
{
tests
:=
[]
struct
{
group
string
group
string
handler
http
.
Handler
handler
http
.
Handler
...
@@ -115,7 +118,7 @@ func testWebhookConverter(t *testing.T, defaulting bool) {
...
@@ -115,7 +118,7 @@ func testWebhookConverter(t *testing.T, defaulting bool) {
defer
featuregatetesting
.
SetFeatureGateDuringTest
(
t
,
utilfeature
.
DefaultFeatureGate
,
apiextensionsfeatures
.
CustomResourceDefaulting
,
true
)()
defer
featuregatetesting
.
SetFeatureGateDuringTest
(
t
,
utilfeature
.
DefaultFeatureGate
,
apiextensionsfeatures
.
CustomResourceDefaulting
,
true
)()
}
}
tearDown
,
config
,
options
,
err
:=
fixtures
.
StartDefaultServer
(
t
)
tearDown
,
config
,
options
,
err
:=
fixtures
.
StartDefaultServer
(
t
,
fmt
.
Sprintf
(
"--watch-cache=%v"
,
watchCache
)
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
...
@@ -320,6 +323,28 @@ func validateNonTrivialConverted(t *testing.T, ctc *conversionTestContext) {
...
@@ -320,6 +323,28 @@ func validateNonTrivialConverted(t *testing.T, ctc *conversionTestContext) {
}
}
verifyMultiVersionObject
(
t
,
getVersion
.
Name
,
obj
)
verifyMultiVersionObject
(
t
,
getVersion
.
Name
,
obj
)
}
}
// send a non-trivial patch to the main resource to verify the oldObject is in the right version
if
_
,
err
:=
client
.
Patch
(
name
,
types
.
MergePatchType
,
[]
byte
(
`{"metadata":{"annotations":{"main":"true"}}}`
),
metav1
.
PatchOptions
{});
err
!=
nil
{
t
.
Fatal
(
err
)
}
// verify that the right, pruned version is in storage
obj
,
err
=
ctc
.
etcdObjectReader
.
GetStoredCustomResource
(
ns
,
name
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
verifyMultiVersionObject
(
t
,
"v1beta1"
,
obj
)
// send a non-trivial patch to the status subresource to verify the oldObject is in the right version
if
_
,
err
:=
client
.
Patch
(
name
,
types
.
MergePatchType
,
[]
byte
(
`{"metadata":{"annotations":{"status":"true"}}}`
),
metav1
.
PatchOptions
{},
"status"
);
err
!=
nil
{
t
.
Fatal
(
err
)
}
// verify that the right, pruned version is in storage
obj
,
err
=
ctc
.
etcdObjectReader
.
GetStoredCustomResource
(
ns
,
name
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
verifyMultiVersionObject
(
t
,
"v1beta1"
,
obj
)
})
})
}
}
}
}
...
...
staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go
View file @
932553a0
...
@@ -127,6 +127,16 @@ func (u *Unstructured) UnmarshalJSON(b []byte) error {
...
@@ -127,6 +127,16 @@ func (u *Unstructured) UnmarshalJSON(b []byte) error {
return
err
return
err
}
}
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
// This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
func
(
in
*
Unstructured
)
NewEmptyInstance
()
runtime
.
Unstructured
{
out
:=
new
(
Unstructured
)
if
in
!=
nil
{
out
.
GetObjectKind
()
.
SetGroupVersionKind
(
in
.
GetObjectKind
()
.
GroupVersionKind
())
}
return
out
}
func
(
in
*
Unstructured
)
DeepCopy
()
*
Unstructured
{
func
(
in
*
Unstructured
)
DeepCopy
()
*
Unstructured
{
if
in
==
nil
{
if
in
==
nil
{
return
nil
return
nil
...
...
staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go
View file @
932553a0
...
@@ -52,6 +52,16 @@ func (u *UnstructuredList) EachListItem(fn func(runtime.Object) error) error {
...
@@ -52,6 +52,16 @@ func (u *UnstructuredList) EachListItem(fn func(runtime.Object) error) error {
return
nil
return
nil
}
}
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
// This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
func
(
u
*
UnstructuredList
)
NewEmptyInstance
()
runtime
.
Unstructured
{
out
:=
new
(
UnstructuredList
)
if
u
!=
nil
{
out
.
SetGroupVersionKind
(
u
.
GroupVersionKind
())
}
return
out
}
// UnstructuredContent returns a map contain an overlay of the Items field onto
// UnstructuredContent returns a map contain an overlay of the Items field onto
// the Object field. Items always overwrites overlay.
// the Object field. Items always overwrites overlay.
func
(
u
*
UnstructuredList
)
UnstructuredContent
()
map
[
string
]
interface
{}
{
func
(
u
*
UnstructuredList
)
UnstructuredContent
()
map
[
string
]
interface
{}
{
...
...
staging/src/k8s.io/apimachinery/pkg/runtime/interfaces.go
View file @
932553a0
...
@@ -260,6 +260,9 @@ type Object interface {
...
@@ -260,6 +260,9 @@ type Object interface {
// to JSON allowed.
// to JSON allowed.
type
Unstructured
interface
{
type
Unstructured
interface
{
Object
Object
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
// This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
NewEmptyInstance
()
Unstructured
// UnstructuredContent returns a non-nil map with this object's contents. Values may be
// UnstructuredContent returns a non-nil map with this object's contents. Values may be
// []interface{}, map[string]interface{}, or any primitive type. Contents are typically serialized to
// []interface{}, map[string]interface{}, or any primitive type. Contents are typically serialized to
// and from JSON. SetUnstructuredContent should be used to mutate the contents.
// and from JSON. SetUnstructuredContent should be used to mutate the contents.
...
...
staging/src/k8s.io/apimachinery/pkg/runtime/testing/types.go
View file @
932553a0
...
@@ -261,6 +261,14 @@ func (obj *Unstructured) EachListItem(fn func(runtime.Object) error) error {
...
@@ -261,6 +261,14 @@ func (obj *Unstructured) EachListItem(fn func(runtime.Object) error) error {
return
nil
return
nil
}
}
func
(
obj
*
Unstructured
)
NewEmptyInstance
()
runtime
.
Unstructured
{
out
:=
new
(
Unstructured
)
if
obj
!=
nil
{
out
.
SetGroupVersionKind
(
obj
.
GroupVersionKind
())
}
return
out
}
func
(
obj
*
Unstructured
)
UnstructuredContent
()
map
[
string
]
interface
{}
{
func
(
obj
*
Unstructured
)
UnstructuredContent
()
map
[
string
]
interface
{}
{
if
obj
.
Object
==
nil
{
if
obj
.
Object
==
nil
{
return
make
(
map
[
string
]
interface
{})
return
make
(
map
[
string
]
interface
{})
...
...
staging/src/k8s.io/apiserver/pkg/storage/etcd3/BUILD
View file @
932553a0
...
@@ -20,6 +20,7 @@ go_test(
...
@@ -20,6 +20,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
...
...
staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go
View file @
932553a0
...
@@ -685,9 +685,15 @@ func (s *store) watch(ctx context.Context, key string, rv string, pred storage.S
...
@@ -685,9 +685,15 @@ func (s *store) watch(ctx context.Context, key string, rv string, pred storage.S
func
(
s
*
store
)
getState
(
getResp
*
clientv3
.
GetResponse
,
key
string
,
v
reflect
.
Value
,
ignoreNotFound
bool
)
(
*
objState
,
error
)
{
func
(
s
*
store
)
getState
(
getResp
*
clientv3
.
GetResponse
,
key
string
,
v
reflect
.
Value
,
ignoreNotFound
bool
)
(
*
objState
,
error
)
{
state
:=
&
objState
{
state
:=
&
objState
{
obj
:
reflect
.
New
(
v
.
Type
())
.
Interface
()
.
(
runtime
.
Object
),
meta
:
&
storage
.
ResponseMeta
{},
meta
:
&
storage
.
ResponseMeta
{},
}
}
if
u
,
ok
:=
v
.
Addr
()
.
Interface
()
.
(
runtime
.
Unstructured
);
ok
{
state
.
obj
=
u
.
NewEmptyInstance
()
}
else
{
state
.
obj
=
reflect
.
New
(
v
.
Type
())
.
Interface
()
.
(
runtime
.
Object
)
}
if
len
(
getResp
.
Kvs
)
==
0
{
if
len
(
getResp
.
Kvs
)
==
0
{
if
!
ignoreNotFound
{
if
!
ignoreNotFound
{
return
nil
,
storage
.
NewKeyNotFoundError
(
key
,
0
)
return
nil
,
storage
.
NewKeyNotFoundError
(
key
,
0
)
...
...
staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_test.go
View file @
932553a0
...
@@ -35,6 +35,7 @@ import (
...
@@ -35,6 +35,7 @@ import (
apitesting
"k8s.io/apimachinery/pkg/api/apitesting"
apitesting
"k8s.io/apimachinery/pkg/api/apitesting"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
...
@@ -1349,7 +1350,11 @@ func testSetup(t *testing.T) (context.Context, *store, *integration.ClusterV3) {
...
@@ -1349,7 +1350,11 @@ func testSetup(t *testing.T) (context.Context, *store, *integration.ClusterV3) {
func
testPropogateStore
(
ctx
context
.
Context
,
t
*
testing
.
T
,
store
*
store
,
obj
*
example
.
Pod
)
(
string
,
*
example
.
Pod
)
{
func
testPropogateStore
(
ctx
context
.
Context
,
t
*
testing
.
T
,
store
*
store
,
obj
*
example
.
Pod
)
(
string
,
*
example
.
Pod
)
{
// Setup store with a key and grab the output for returning.
// Setup store with a key and grab the output for returning.
key
:=
"/testkey"
key
:=
"/testkey"
err
:=
store
.
conditionalDelete
(
ctx
,
key
,
&
example
.
Pod
{},
reflect
.
ValueOf
(
example
.
Pod
{}),
nil
,
storage
.
ValidateAllObjectFunc
)
v
,
err
:=
conversion
.
EnforcePtr
(
obj
)
if
err
!=
nil
{
panic
(
"unable to convert output object to pointer"
)
}
err
=
store
.
conditionalDelete
(
ctx
,
key
,
&
example
.
Pod
{},
v
,
nil
,
storage
.
ValidateAllObjectFunc
)
if
err
!=
nil
&&
!
storage
.
IsNotFound
(
err
)
{
if
err
!=
nil
&&
!
storage
.
IsNotFound
(
err
)
{
t
.
Fatalf
(
"Cleanup failed: %v"
,
err
)
t
.
Fatalf
(
"Cleanup failed: %v"
,
err
)
}
}
...
...
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