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
6918a4d3
Commit
6918a4d3
authored
Mar 16, 2015
by
Clayton Coleman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace automatic YAML decoding with opt-in YAML decoding
Base codecs no longer automically handle YAML. Instead, clients must convert to JSON first via yaml.ToJSON and runtime.YAMLDecoder.
parent
71abc99d
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
49 additions
and
40 deletions
+49
-40
examples_test.go
examples/examples_test.go
+16
-2
schema.go
pkg/api/validation/schema.go
+10
-6
latest.go
pkg/client/clientcmd/api/latest/latest.go
+2
-1
decode.go
pkg/conversion/decode.go
+8
-21
meta.go
pkg/conversion/meta.go
+5
-8
mapper.go
pkg/kubectl/resource/mapper.go
+6
-0
resource_printer_test.go
pkg/kubectl/resource_printer_test.go
+2
-2
No files found.
examples/examples_test.go
View file @
6918a4d3
...
@@ -29,6 +29,7 @@ import (
...
@@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/yaml"
"github.com/golang/glog"
"github.com/golang/glog"
)
)
...
@@ -88,6 +89,15 @@ func walkJSONFiles(inDir string, fn func(name, path string, data []byte)) error
...
@@ -88,6 +89,15 @@ func walkJSONFiles(inDir string, fn func(name, path string, data []byte)) error
return
err
return
err
}
}
name
:=
strings
.
TrimSuffix
(
file
,
ext
)
name
:=
strings
.
TrimSuffix
(
file
,
ext
)
if
ext
==
".yaml"
{
out
,
err
:=
yaml
.
ToJSON
(
data
)
if
err
!=
nil
{
return
err
}
data
=
out
}
fn
(
name
,
path
,
data
)
fn
(
name
,
path
,
data
)
}
}
return
nil
return
nil
...
@@ -215,14 +225,18 @@ func TestReadme(t *testing.T) {
...
@@ -215,14 +225,18 @@ func TestReadme(t *testing.T) {
//t.Logf("testing (%s): \n%s", subtype, content)
//t.Logf("testing (%s): \n%s", subtype, content)
expectedType
:=
&
api
.
Pod
{}
expectedType
:=
&
api
.
Pod
{}
if
err
:=
latest
.
Codec
.
DecodeInto
([]
byte
(
content
),
expectedType
);
err
!=
nil
{
json
,
err
:=
yaml
.
ToJSON
([]
byte
(
content
))
if
err
!=
nil
{
t
.
Errorf
(
"%s could not be converted to JSON: %v
\n
%s"
,
path
,
err
,
string
(
content
))
}
if
err
:=
latest
.
Codec
.
DecodeInto
(
json
,
expectedType
);
err
!=
nil
{
t
.
Errorf
(
"%s did not decode correctly: %v
\n
%s"
,
path
,
err
,
string
(
content
))
t
.
Errorf
(
"%s did not decode correctly: %v
\n
%s"
,
path
,
err
,
string
(
content
))
continue
continue
}
}
if
errors
:=
validateObject
(
expectedType
);
len
(
errors
)
>
0
{
if
errors
:=
validateObject
(
expectedType
);
len
(
errors
)
>
0
{
t
.
Errorf
(
"%s did not validate correctly: %v"
,
path
,
errors
)
t
.
Errorf
(
"%s did not validate correctly: %v"
,
path
,
errors
)
}
}
_
,
err
:
=
latest
.
Codec
.
Encode
(
expectedType
)
_
,
err
=
latest
.
Codec
.
Encode
(
expectedType
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Errorf
(
"Could not encode object: %v"
,
err
)
t
.
Errorf
(
"Could not encode object: %v"
,
err
)
continue
continue
...
...
pkg/api/validation/schema.go
View file @
6918a4d3
...
@@ -22,9 +22,9 @@ import (
...
@@ -22,9 +22,9 @@ import (
"reflect"
"reflect"
"strings"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/yaml"
"github.com/emicklei/go-restful/swagger"
"github.com/emicklei/go-restful/swagger"
"github.com/golang/glog"
"github.com/golang/glog"
"gopkg.in/yaml.v2"
)
)
type
InvalidTypeError
struct
{
type
InvalidTypeError
struct
{
...
@@ -65,11 +65,15 @@ func NewSwaggerSchemaFromBytes(data []byte) (Schema, error) {
...
@@ -65,11 +65,15 @@ func NewSwaggerSchemaFromBytes(data []byte) (Schema, error) {
func
(
s
*
SwaggerSchema
)
ValidateBytes
(
data
[]
byte
)
error
{
func
(
s
*
SwaggerSchema
)
ValidateBytes
(
data
[]
byte
)
error
{
var
obj
interface
{}
var
obj
interface
{}
err
:=
yaml
.
Unmarshal
(
data
,
&
obj
)
out
,
err
:=
yaml
.
ToJSON
(
data
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
fields
:=
obj
.
(
map
[
interface
{}]
interface
{})
data
=
out
if
err
:=
json
.
Unmarshal
(
data
,
&
obj
);
err
!=
nil
{
return
err
}
fields
:=
obj
.
(
map
[
string
]
interface
{})
apiVersion
:=
fields
[
"apiVersion"
]
.
(
string
)
apiVersion
:=
fields
[
"apiVersion"
]
.
(
string
)
kind
:=
fields
[
"kind"
]
.
(
string
)
kind
:=
fields
[
"kind"
]
.
(
string
)
return
s
.
ValidateObject
(
obj
,
apiVersion
,
""
,
apiVersion
+
"."
+
kind
)
return
s
.
ValidateObject
(
obj
,
apiVersion
,
""
,
apiVersion
+
"."
+
kind
)
...
@@ -84,12 +88,12 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, apiVersion, fieldName, t
...
@@ -84,12 +88,12 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, apiVersion, fieldName, t
return
nil
return
nil
}
}
properties
:=
model
.
Properties
properties
:=
model
.
Properties
fields
:=
obj
.
(
map
[
interface
{}
]
interface
{})
fields
:=
obj
.
(
map
[
string
]
interface
{})
if
len
(
fieldName
)
>
0
{
if
len
(
fieldName
)
>
0
{
fieldName
=
fieldName
+
"."
fieldName
=
fieldName
+
"."
}
}
for
key
,
value
:=
range
fields
{
for
key
,
value
:=
range
fields
{
details
,
ok
:=
properties
[
key
.
(
string
)
]
details
,
ok
:=
properties
[
key
]
if
!
ok
{
if
!
ok
{
glog
.
V
(
2
)
.
Infof
(
"couldn't find properties for %s, skipping"
,
key
)
glog
.
V
(
2
)
.
Infof
(
"couldn't find properties for %s, skipping"
,
key
)
continue
continue
...
@@ -99,7 +103,7 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, apiVersion, fieldName, t
...
@@ -99,7 +103,7 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, apiVersion, fieldName, t
glog
.
V
(
2
)
.
Infof
(
"Skipping nil field: %s"
,
key
)
glog
.
V
(
2
)
.
Infof
(
"Skipping nil field: %s"
,
key
)
continue
continue
}
}
err
:=
s
.
validateField
(
value
,
apiVersion
,
fieldName
+
key
.
(
string
)
,
fieldType
,
&
details
)
err
:=
s
.
validateField
(
value
,
apiVersion
,
fieldName
+
key
,
fieldType
,
&
details
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"Validation failed for: %s, %v"
,
key
,
value
)
glog
.
Errorf
(
"Validation failed for: %s, %v"
,
key
,
value
)
return
err
return
err
...
...
pkg/client/clientcmd/api/latest/latest.go
View file @
6918a4d3
...
@@ -18,6 +18,7 @@ package latest
...
@@ -18,6 +18,7 @@ package latest
import
(
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api/v1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api/v1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
)
// Version is the string that represents the current external default version.
// Version is the string that represents the current external default version.
...
@@ -37,4 +38,4 @@ var Versions = []string{"v1"}
...
@@ -37,4 +38,4 @@ var Versions = []string{"v1"}
// the latest supported version. Use this Codec when writing to
// the latest supported version. Use this Codec when writing to
// disk, a data store that is not dynamically versioned, or in tests.
// disk, a data store that is not dynamically versioned, or in tests.
// This codec can decode any object that Kubernetes is aware of.
// This codec can decode any object that Kubernetes is aware of.
var
Codec
=
v1
.
Codec
var
Codec
=
runtime
.
YAMLDecoder
(
v1
.
Codec
)
pkg/conversion/decode.go
View file @
6918a4d3
...
@@ -17,13 +17,12 @@ limitations under the License.
...
@@ -17,13 +17,12 @@ limitations under the License.
package
conversion
package
conversion
import
(
import
(
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"github.com/ghodss/yaml"
)
)
// Decode converts a
YAML or
JSON string back into a pointer to an api object.
// Decode converts a JSON string back into a pointer to an api object.
// Deduces the type based upon the fields added by the MetaInsertionFactory
// Deduces the type based upon the fields added by the MetaInsertionFactory
// technique. The object will be converted, if necessary, into the
// technique. The object will be converted, if necessary, into the
// s.InternalVersion type before being returned. Decode will not decode
// s.InternalVersion type before being returned. Decode will not decode
...
@@ -44,16 +43,12 @@ func (s *Scheme) Decode(data []byte) (interface{}, error) {
...
@@ -44,16 +43,12 @@ func (s *Scheme) Decode(data []byte) (interface{}, error) {
return
nil
,
err
return
nil
,
err
}
}
// yaml is a superset of json, so we use it to decode here. That way,
if
err
:=
json
.
Unmarshal
(
data
,
obj
);
err
!=
nil
{
// we understand both.
err
=
yaml
.
Unmarshal
(
data
,
obj
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
// Version and Kind should be blank in memory.
// Version and Kind should be blank in memory.
err
=
s
.
SetVersionAndKind
(
""
,
""
,
obj
)
if
err
:=
s
.
SetVersionAndKind
(
""
,
""
,
obj
);
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -63,8 +58,7 @@ func (s *Scheme) Decode(data []byte) (interface{}, error) {
...
@@ -63,8 +58,7 @@ func (s *Scheme) Decode(data []byte) (interface{}, error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
err
=
s
.
converter
.
Convert
(
obj
,
objOut
,
0
,
s
.
generateConvertMeta
(
version
,
s
.
InternalVersion
))
if
err
:=
s
.
converter
.
Convert
(
obj
,
objOut
,
0
,
s
.
generateConvertMeta
(
version
,
s
.
InternalVersion
));
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
obj
=
objOut
obj
=
objOut
...
@@ -72,16 +66,13 @@ func (s *Scheme) Decode(data []byte) (interface{}, error) {
...
@@ -72,16 +66,13 @@ func (s *Scheme) Decode(data []byte) (interface{}, error) {
return
obj
,
nil
return
obj
,
nil
}
}
// DecodeInto parses a
YAML or
JSON string and stores it in obj. Returns an error
// DecodeInto parses a JSON string and stores it in obj. Returns an error
// if data.Kind is set and doesn't match the type of obj. Obj should be a
// if data.Kind is set and doesn't match the type of obj. Obj should be a
// pointer to an api type.
// pointer to an api type.
// If obj's version doesn't match that in data, an attempt will be made to convert
// If obj's version doesn't match that in data, an attempt will be made to convert
// data into obj's version.
// data into obj's version.
func
(
s
*
Scheme
)
DecodeInto
(
data
[]
byte
,
obj
interface
{})
error
{
func
(
s
*
Scheme
)
DecodeInto
(
data
[]
byte
,
obj
interface
{})
error
{
if
len
(
data
)
==
0
{
if
len
(
data
)
==
0
{
// This is valid YAML, but it's a bad idea not to return an error
// for an empty string-- that's almost certainly not what the caller
// was expecting.
return
errors
.
New
(
"empty input"
)
return
errors
.
New
(
"empty input"
)
}
}
dataVersion
,
dataKind
,
err
:=
s
.
DataVersionAndKind
(
data
)
dataVersion
,
dataKind
,
err
:=
s
.
DataVersionAndKind
(
data
)
...
@@ -107,14 +98,10 @@ func (s *Scheme) DecodeInto(data []byte, obj interface{}) error {
...
@@ -107,14 +98,10 @@ func (s *Scheme) DecodeInto(data []byte, obj interface{}) error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
// yaml is a superset of json, so we use it to decode here. That way,
if
err
:=
json
.
Unmarshal
(
data
,
external
);
err
!=
nil
{
// we understand both.
err
=
yaml
.
Unmarshal
(
data
,
external
)
if
err
!=
nil
{
return
err
return
err
}
}
err
=
s
.
converter
.
Convert
(
external
,
obj
,
0
,
s
.
generateConvertMeta
(
dataVersion
,
objVersion
))
if
err
:=
s
.
converter
.
Convert
(
external
,
obj
,
0
,
s
.
generateConvertMeta
(
dataVersion
,
objVersion
));
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
pkg/conversion/meta.go
View file @
6918a4d3
...
@@ -17,10 +17,9 @@ limitations under the License.
...
@@ -17,10 +17,9 @@ limitations under the License.
package
conversion
package
conversion
import
(
import
(
"encoding/json"
"fmt"
"fmt"
"reflect"
"reflect"
"github.com/ghodss/yaml"
)
)
// MetaFactory is used to store and retrieve the version and kind
// MetaFactory is used to store and retrieve the version and kind
...
@@ -33,13 +32,13 @@ type MetaFactory interface {
...
@@ -33,13 +32,13 @@ type MetaFactory interface {
Interpret
(
data
[]
byte
)
(
version
,
kind
string
,
err
error
)
Interpret
(
data
[]
byte
)
(
version
,
kind
string
,
err
error
)
}
}
// DefaultMetaFactory is a default factory for versioning objects in JSON
/YAML
. The object
// DefaultMetaFactory is a default factory for versioning objects in JSON. The object
// in memory and in the default JSON serialization will use the "kind" and "apiVersion"
// in memory and in the default JSON serialization will use the "kind" and "apiVersion"
// fields.
// fields.
var
DefaultMetaFactory
=
SimpleMetaFactory
{
KindField
:
"Kind"
,
VersionField
:
"APIVersion"
}
var
DefaultMetaFactory
=
SimpleMetaFactory
{
KindField
:
"Kind"
,
VersionField
:
"APIVersion"
}
// SimpleMetaFactory provides default methods for retrieving the type and version of objects
// SimpleMetaFactory provides default methods for retrieving the type and version of objects
// that are identified with an "apiVersion" and "kind" fields in their JSON
/YAML
// that are identified with an "apiVersion" and "kind" fields in their JSON
// serialization. It may be parameterized with the names of the fields in memory, or an
// serialization. It may be parameterized with the names of the fields in memory, or an
// optional list of base structs to search for those fields in memory.
// optional list of base structs to search for those fields in memory.
type
SimpleMetaFactory
struct
{
type
SimpleMetaFactory
struct
{
...
@@ -51,16 +50,14 @@ type SimpleMetaFactory struct {
...
@@ -51,16 +50,14 @@ type SimpleMetaFactory struct {
BaseFields
[]
string
BaseFields
[]
string
}
}
// Interpret will return the APIVersion and Kind of the JSON
/YAML
wire-format
// Interpret will return the APIVersion and Kind of the JSON wire-format
// encoding of an object, or an error.
// encoding of an object, or an error.
func
(
SimpleMetaFactory
)
Interpret
(
data
[]
byte
)
(
version
,
kind
string
,
err
error
)
{
func
(
SimpleMetaFactory
)
Interpret
(
data
[]
byte
)
(
version
,
kind
string
,
err
error
)
{
findKind
:=
struct
{
findKind
:=
struct
{
APIVersion
string
`json:"apiVersion,omitempty"`
APIVersion
string
`json:"apiVersion,omitempty"`
Kind
string
`json:"kind,omitempty"`
Kind
string
`json:"kind,omitempty"`
}{}
}{}
// yaml is a superset of json, so we use it to decode here. That way,
err
=
json
.
Unmarshal
(
data
,
&
findKind
)
// we understand both.
err
=
yaml
.
Unmarshal
(
data
,
&
findKind
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
""
,
fmt
.
Errorf
(
"couldn't get version/kind: %v"
,
err
)
return
""
,
""
,
fmt
.
Errorf
(
"couldn't get version/kind: %v"
,
err
)
}
}
...
...
pkg/kubectl/resource/mapper.go
View file @
6918a4d3
...
@@ -22,6 +22,7 @@ import (
...
@@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/yaml"
)
)
// Mapper is a convenience struct for holding references to the three interfaces
// Mapper is a convenience struct for holding references to the three interfaces
...
@@ -36,6 +37,11 @@ type Mapper struct {
...
@@ -36,6 +37,11 @@ type Mapper struct {
// if any of the decoding or client lookup steps fail. Name and namespace will be
// if any of the decoding or client lookup steps fail. Name and namespace will be
// set into Info if the mapping's MetadataAccessor can retrieve them.
// set into Info if the mapping's MetadataAccessor can retrieve them.
func
(
m
*
Mapper
)
InfoForData
(
data
[]
byte
,
source
string
)
(
*
Info
,
error
)
{
func
(
m
*
Mapper
)
InfoForData
(
data
[]
byte
,
source
string
)
(
*
Info
,
error
)
{
json
,
err
:=
yaml
.
ToJSON
(
data
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"unable to parse %q: %v"
,
err
)
}
data
=
json
version
,
kind
,
err
:=
m
.
DataVersionAndKind
(
data
)
version
,
kind
,
err
:=
m
.
DataVersionAndKind
(
data
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"unable to get type info from %q: %v"
,
source
,
err
)
return
nil
,
fmt
.
Errorf
(
"unable to get type info from %q: %v"
,
source
,
err
)
...
...
pkg/kubectl/resource_printer_test.go
View file @
6918a4d3
...
@@ -196,7 +196,7 @@ func testPrinter(t *testing.T, printer ResourcePrinter, unmarshalFunc func(data
...
@@ -196,7 +196,7 @@ func testPrinter(t *testing.T, printer ResourcePrinter, unmarshalFunc func(data
}
}
// Use real decode function to undo the versioning process.
// Use real decode function to undo the versioning process.
poutput
=
testStruct
{}
poutput
=
testStruct
{}
err
=
testapi
.
Codec
(
)
.
DecodeInto
(
buf
.
Bytes
(),
&
poutput
)
err
=
runtime
.
YAMLDecoder
(
testapi
.
Codec
()
)
.
DecodeInto
(
buf
.
Bytes
(),
&
poutput
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
...
@@ -217,7 +217,7 @@ func testPrinter(t *testing.T, printer ResourcePrinter, unmarshalFunc func(data
...
@@ -217,7 +217,7 @@ func testPrinter(t *testing.T, printer ResourcePrinter, unmarshalFunc func(data
}
}
// Use real decode function to undo the versioning process.
// Use real decode function to undo the versioning process.
objOut
=
api
.
Pod
{}
objOut
=
api
.
Pod
{}
err
=
testapi
.
Codec
(
)
.
DecodeInto
(
buf
.
Bytes
(),
&
objOut
)
err
=
runtime
.
YAMLDecoder
(
testapi
.
Codec
()
)
.
DecodeInto
(
buf
.
Bytes
(),
&
objOut
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
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