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
f046d6c8
Commit
f046d6c8
authored
Mar 07, 2016
by
k8s-merge-robot
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #22420 from AdoHe/kubectl_swagger_cache
Auto commit by PR queue bot
parents
bfde580c
893e36c6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
105 additions
and
12 deletions
+105
-12
schema.go
pkg/api/validation/schema.go
+9
-1
factory.go
pkg/kubectl/cmd/util/factory.go
+37
-10
factory_test.go
pkg/kubectl/cmd/util/factory_test.go
+59
-1
No files found.
pkg/api/validation/schema.go
View file @
f046d6c8
...
@@ -44,6 +44,14 @@ func NewInvalidTypeError(expected reflect.Kind, observed reflect.Kind, fieldName
...
@@ -44,6 +44,14 @@ func NewInvalidTypeError(expected reflect.Kind, observed reflect.Kind, fieldName
return
&
InvalidTypeError
{
expected
,
observed
,
fieldName
}
return
&
InvalidTypeError
{
expected
,
observed
,
fieldName
}
}
}
// TypeNotFoundError is returned when specified type
// can not found in schema
type
TypeNotFoundError
string
func
(
tnfe
TypeNotFoundError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"couldn't find type: %s"
,
string
(
tnfe
))
}
// Schema is an interface that knows how to validate an API object serialized to a byte array.
// Schema is an interface that knows how to validate an API object serialized to a byte array.
type
Schema
interface
{
type
Schema
interface
{
ValidateBytes
(
data
[]
byte
)
error
ValidateBytes
(
data
[]
byte
)
error
...
@@ -164,7 +172,7 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName stri
...
@@ -164,7 +172,7 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName stri
models
:=
s
.
api
.
Models
models
:=
s
.
api
.
Models
model
,
ok
:=
models
.
At
(
typeName
)
model
,
ok
:=
models
.
At
(
typeName
)
if
!
ok
{
if
!
ok
{
return
append
(
allErrs
,
fmt
.
Errorf
(
"couldn't find type: %s"
,
typeName
))
return
append
(
allErrs
,
TypeNotFoundError
(
typeName
))
}
}
properties
:=
model
.
Properties
properties
:=
model
.
Properties
if
len
(
properties
.
List
)
==
0
{
if
len
(
properties
.
List
)
==
0
{
...
...
pkg/kubectl/cmd/util/factory.go
View file @
f046d6c8
...
@@ -729,6 +729,7 @@ func writeSchemaFile(schemaData []byte, cacheDir, cacheFile, prefix, groupVersio
...
@@ -729,6 +729,7 @@ func writeSchemaFile(schemaData []byte, cacheDir, cacheFile, prefix, groupVersio
func
getSchemaAndValidate
(
c
schemaClient
,
data
[]
byte
,
prefix
,
groupVersion
,
cacheDir
string
)
(
err
error
)
{
func
getSchemaAndValidate
(
c
schemaClient
,
data
[]
byte
,
prefix
,
groupVersion
,
cacheDir
string
)
(
err
error
)
{
var
schemaData
[]
byte
var
schemaData
[]
byte
var
firstSeen
bool
fullDir
,
err
:=
substituteUserHome
(
cacheDir
)
fullDir
,
err
:=
substituteUserHome
(
cacheDir
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -741,24 +742,50 @@ func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cac
...
@@ -741,24 +742,50 @@ func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cac
}
}
}
}
if
schemaData
==
nil
{
if
schemaData
==
nil
{
schemaData
,
err
=
c
.
Get
()
.
firstSeen
=
true
AbsPath
(
"/swaggerapi"
,
prefix
,
groupVersion
)
.
schemaData
,
err
=
downloadSchemaAndStore
(
c
,
cacheDir
,
fullDir
,
cacheFile
,
prefix
,
groupVersion
)
Do
()
.
Raw
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
len
(
cacheDir
)
!=
0
{
if
err
:=
writeSchemaFile
(
schemaData
,
fullDir
,
cacheFile
,
prefix
,
groupVersion
);
err
!=
nil
{
return
err
}
}
}
}
schema
,
err
:=
validation
.
NewSwaggerSchemaFromBytes
(
schemaData
)
schema
,
err
:=
validation
.
NewSwaggerSchemaFromBytes
(
schemaData
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
return
schema
.
ValidateBytes
(
data
)
err
=
schema
.
ValidateBytes
(
data
)
if
_
,
ok
:=
err
.
(
validation
.
TypeNotFoundError
);
ok
&&
!
firstSeen
{
// As a temporay hack, kubectl would re-get the schema if validation
// fails for type not found reason.
// TODO: runtime-config settings needs to make into the file's name
schemaData
,
err
=
downloadSchemaAndStore
(
c
,
cacheDir
,
fullDir
,
cacheFile
,
prefix
,
groupVersion
)
if
err
!=
nil
{
return
err
}
schema
,
err
:=
validation
.
NewSwaggerSchemaFromBytes
(
schemaData
)
if
err
!=
nil
{
return
err
}
return
schema
.
ValidateBytes
(
data
)
}
return
err
}
// Download swagger schema from apiserver and store it to file.
func
downloadSchemaAndStore
(
c
schemaClient
,
cacheDir
,
fullDir
,
cacheFile
,
prefix
,
groupVersion
string
)
(
schemaData
[]
byte
,
err
error
)
{
schemaData
,
err
=
c
.
Get
()
.
AbsPath
(
"/swaggerapi"
,
prefix
,
groupVersion
)
.
Do
()
.
Raw
()
if
err
!=
nil
{
return
}
if
len
(
cacheDir
)
!=
0
{
if
err
=
writeSchemaFile
(
schemaData
,
fullDir
,
cacheFile
,
prefix
,
groupVersion
);
err
!=
nil
{
return
}
}
return
}
}
func
(
c
*
clientSwaggerSchema
)
ValidateBytes
(
data
[]
byte
)
error
{
func
(
c
*
clientSwaggerSchema
)
ValidateBytes
(
data
[]
byte
)
error
{
...
...
pkg/kubectl/cmd/util/factory_test.go
View file @
f046d6c8
...
@@ -32,6 +32,7 @@ import (
...
@@ -32,6 +32,7 @@ import (
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
clientcmdapi
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
clientcmdapi
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
"k8s.io/kubernetes/pkg/client/unversioned/fake"
"k8s.io/kubernetes/pkg/client/unversioned/fake"
...
@@ -215,6 +216,63 @@ func loadSchemaForTest() (validation.Schema, error) {
...
@@ -215,6 +216,63 @@ func loadSchemaForTest() (validation.Schema, error) {
return
validation
.
NewSwaggerSchemaFromBytes
(
data
)
return
validation
.
NewSwaggerSchemaFromBytes
(
data
)
}
}
func
TestRefetchSchemaWhenValidationFails
(
t
*
testing
.
T
)
{
schema
,
err
:=
loadSchemaForTest
()
if
err
!=
nil
{
t
.
Errorf
(
"Error loading schema: %v"
,
err
)
t
.
FailNow
()
}
output
,
err
:=
json
.
Marshal
(
schema
)
if
err
!=
nil
{
t
.
Errorf
(
"Error serializing schema: %v"
,
err
)
t
.
FailNow
()
}
requests
:=
map
[
string
]
int
{}
c
:=
&
fake
.
RESTClient
{
Codec
:
testapi
.
Default
.
Codec
(),
Client
:
fake
.
CreateHTTPClient
(
func
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
switch
p
,
m
:=
req
.
URL
.
Path
,
req
.
Method
;
{
case
strings
.
HasPrefix
(
p
,
"/swaggerapi"
)
&&
m
==
"GET"
:
requests
[
p
]
=
requests
[
p
]
+
1
return
&
http
.
Response
{
StatusCode
:
200
,
Body
:
ioutil
.
NopCloser
(
bytes
.
NewBuffer
(
output
))},
nil
default
:
t
.
Fatalf
(
"unexpected request: %#v
\n
%#v"
,
req
.
URL
,
req
)
return
nil
,
nil
}
}),
}
dir
:=
os
.
TempDir
()
+
"/schemaCache"
os
.
RemoveAll
(
dir
)
fullDir
,
err
:=
substituteUserHome
(
dir
)
if
err
!=
nil
{
t
.
Errorf
(
"Error getting fullDir: %v"
,
err
)
t
.
FailNow
()
}
cacheFile
:=
path
.
Join
(
fullDir
,
"foo"
,
"bar"
,
schemaFileName
)
err
=
writeSchemaFile
(
output
,
fullDir
,
cacheFile
,
"foo"
,
"bar"
)
if
err
!=
nil
{
t
.
Errorf
(
"Error building old cache schema: %v"
,
err
)
t
.
FailNow
()
}
obj
:=
&
extensions
.
Deployment
{}
data
,
err
:=
runtime
.
Encode
(
testapi
.
Extensions
.
Codec
(),
obj
)
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
t
.
FailNow
()
}
// Re-get request, should use HTTP and write
if
getSchemaAndValidate
(
c
,
data
,
"foo"
,
"bar"
,
dir
);
err
!=
nil
{
t
.
Errorf
(
"unexpected error validating: %v"
,
err
)
}
if
requests
[
"/swaggerapi/foo/bar"
]
!=
1
{
t
.
Errorf
(
"expected 1 schema request, saw: %d"
,
requests
[
"/swaggerapi/foo/bar"
])
}
}
func
TestValidateCachesSchema
(
t
*
testing
.
T
)
{
func
TestValidateCachesSchema
(
t
*
testing
.
T
)
{
schema
,
err
:=
loadSchemaForTest
()
schema
,
err
:=
loadSchemaForTest
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -266,7 +324,7 @@ func TestValidateCachesSchema(t *testing.T) {
...
@@ -266,7 +324,7 @@ func TestValidateCachesSchema(t *testing.T) {
if
getSchemaAndValidate
(
c
,
data
,
"foo"
,
"bar"
,
dir
);
err
!=
nil
{
if
getSchemaAndValidate
(
c
,
data
,
"foo"
,
"bar"
,
dir
);
err
!=
nil
{
t
.
Errorf
(
"unexpected error validating: %v"
,
err
)
t
.
Errorf
(
"unexpected error validating: %v"
,
err
)
}
}
if
requests
[
"/swaggerapi/foo/bar"
]
!=
1
{
if
requests
[
"/swaggerapi/foo/bar"
]
!=
2
{
t
.
Errorf
(
"expected 1 schema request, saw: %d"
,
requests
[
"/swaggerapi/foo/bar"
])
t
.
Errorf
(
"expected 1 schema request, saw: %d"
,
requests
[
"/swaggerapi/foo/bar"
])
}
}
...
...
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