Documentation ¶
Overview ¶
Package conversion provides go object versioning and encoding/decoding mechanisms.
Specifically, conversion provides a way for you to define multiple versions of the same object. You may write functions which implement conversion logic, but for the fields which did not change, copying is automated. This makes it easy to modify the structures you use in memory without affecting the format you store on disk or respond to in your external API calls.
The second offering of this package is automated encoding/decoding. The version and type of the object is recorded in the output, so it can be recreated upon reading. Currently, conversion writes JSON output, and interprets both JSON and YAML input.
In the future, we plan to more explicitly separate the above two mechanisms, and add more serialization options, such as gob.
Index ¶
- Variables
- func EnforcePtr(obj interface{}) (reflect.Value, error)
- func UpdateVersionAndKind(baseFields []string, versionField, version, kindField, kind string, ...) error
- type Converter
- type DebugLogger
- type FieldMatchingFlags
- type Meta
- type MetaFactory
- type Scheme
- func (s *Scheme) AddConversionFuncs(conversionFuncs ...interface{}) error
- func (s *Scheme) AddKnownTypeWithName(version, kind string, obj interface{})
- func (s *Scheme) AddKnownTypes(version string, types ...interface{})
- func (s *Scheme) Convert(in, out interface{}) error
- func (s *Scheme) ConvertToVersion(in interface{}, outVersion string) (interface{}, error)
- func (s *Scheme) DataVersionAndKind(data []byte) (version, kind string, err error)
- func (s *Scheme) Decode(data []byte) (interface{}, error)
- func (s *Scheme) DecodeInto(data []byte, obj interface{}) error
- func (s *Scheme) EncodeToVersion(obj interface{}, destVersion string) (data []byte, err error)
- func (s *Scheme) KnownTypes(version string) map[string]reflect.Type
- func (s *Scheme) Log(l DebugLogger)
- func (s *Scheme) NewObject(versionName, typeName string) (interface{}, error)
- func (s *Scheme) ObjectVersionAndKind(obj interface{}) (apiVersion, kind string, err error)
- func (s *Scheme) SetVersionAndKind(version, kind string, obj interface{}) error
- type Scope
- type SimpleMetaFactory
Constants ¶
This section is empty.
Variables ¶
var DefaultMetaFactory = SimpleMetaFactory{KindField: "Kind", VersionField: "APIVersion"}
DefaultMetaFactory is a default factory for versioning objects in JSON/YAML. The object in memory and in the default JSON serialization will use the "kind" and "apiVersion" fields.
Functions ¶
func EnforcePtr ¶
EnforcePtr ensures that obj is a pointer of some sort. Returns a reflect.Value of the dereferenced pointer, ensuring that it is settable/addressable. Returns an error if this is not possible.
func UpdateVersionAndKind ¶
func UpdateVersionAndKind(baseFields []string, versionField, version, kindField, kind string, obj interface{}) error
UpdateVersionAndKind uses reflection to find and set the versionField and kindField fields on a pointer to a struct to version and kind. Provided as a convenience for others implementing MetaFactory. Pass an array to baseFields to check one or more nested structs for the named fields. The version field is treated as optional if it is not present in the struct.
Types ¶
type Converter ¶
type Converter struct { // If non-nil, will be called to print helpful debugging info. Quite verbose. Debug DebugLogger // NameFunc is called to retrieve the name of a type; this name is used for the // purpose of deciding whether two types match or not (i.e., will we attempt to // do a conversion). The default returns the go type name. NameFunc func(t reflect.Type) string // contains filtered or unexported fields }
Converter knows how to convert one type to another.
func (*Converter) Convert ¶
func (c *Converter) Convert(src, dest interface{}, flags FieldMatchingFlags, meta *Meta) error
Convert will translate src to dest if it knows how. Both must be pointers. If no conversion func is registered and the default copying mechanism doesn't work on this type pair, an error will be returned. Read the comments on the various FieldMatchingFlags constants to understand what the 'flags' parameter does. 'meta' is given to allow you to pass information to conversion functions, it is not used by Convert() other than storing it in the scope. Not safe for objects with cyclic references!
func (*Converter) Register ¶
Register registers a conversion func with the Converter. conversionFunc must take three parameters: a pointer to the input type, a pointer to the output type, and a conversion.Scope (which should be used if recursive conversion calls are desired). It must return an error.
Example: c.Register(func(in *Pod, out *v1beta1.Pod, s Scope) error { ... return nil })
type DebugLogger ¶
type DebugLogger interface {
Logf(format string, args ...interface{})
}
DebugLogger allows you to get debugging messages if necessary.
type FieldMatchingFlags ¶
type FieldMatchingFlags int
FieldMatchingFlags contains a list of ways in which struct fields could be copied. These constants may be | combined.
const ( // Loop through destination fields, search for matching source // field to copy it from. Source fields with no corresponding // destination field will be ignored. If SourceToDest is // specified, this flag is ignored. If niether is specified, // or no flags are passed, this flag is the default. DestFromSource FieldMatchingFlags = 0 // Loop through source fields, search for matching dest field // to copy it into. Destination fields with no corresponding // source field will be ignored. SourceToDest FieldMatchingFlags = 1 << iota // Don't treat it as an error if the corresponding source or // dest field can't be found. IgnoreMissingFields // Don't require type names to match. AllowDifferentFieldTypeNames )
func (FieldMatchingFlags) IsSet ¶
func (f FieldMatchingFlags) IsSet(flag FieldMatchingFlags) bool
IsSet returns true if the given flag or combination of flags is set.
type MetaFactory ¶
type MetaFactory interface { // Update sets the given version and kind onto the object. Update(version, kind string, obj interface{}) error // Interpret should return the version and kind of the wire-format of // the object. Interpret(data []byte) (version, kind string, err error) }
MetaFactory is used to store and retrieve the version and kind information for all objects in a scheme.
type Scheme ¶
type Scheme struct { // Indent will cause the JSON output from Encode to be indented, iff it is true. Indent bool // InternalVersion is the default internal version. It is recommended that // you use "" for the internal version. InternalVersion string // MetaInsertionFactory is used to create an object to store and retrieve // the version and kind information for all objects. The default uses the // keys "apiVersion" and "kind" respectively. MetaFactory MetaFactory // contains filtered or unexported fields }
Scheme defines an entire encoding and decoding scheme.
func (*Scheme) AddConversionFuncs ¶
AddConversionFuncs adds functions to the list of conversion functions. The given functions should know how to convert between two of your API objects, or their sub-objects. We deduce how to call these functions from the types of their two parameters; see the comment for Converter.Register.
Note that, if you need to copy sub-objects that didn't change, you can use the conversion.Scope object that will be passed to your conversion function. Additionally, all conversions started by Scheme will set the SrcVersion and DestVersion fields on the Meta object. Example:
s.AddConversionFuncs(
func(in *InternalObject, out *ExternalObject, scope conversion.Scope) error { // You can depend on Meta() being non-nil, and this being set to // the source version, e.g., "" s.Meta().SrcVersion // You can depend on this being set to the destination version, // e.g., "v1beta1". s.Meta().DestVersion // Call scope.Convert to copy sub-fields. s.Convert(&in.SubFieldThatMoved, &out.NewLocation.NewName, 0) return nil },
)
(For more detail about conversion functions, see Converter.Register's comment.)
Also note that the default behavior, if you don't add a conversion function, is to sanely copy fields that have the same names and same type names. It's OK if the destination type has extra fields, but it must not remove any. So you only need to add conversion functions for things with changed/removed fields.
func (*Scheme) AddKnownTypeWithName ¶
AddKnownTypeWithName is like AddKnownTypes, but it lets you specify what this type should be encoded as. Useful for testing when you don't want to make multiple packages to define your structs.
func (*Scheme) AddKnownTypes ¶
AddKnownTypes registers all types passed in 'types' as being members of version 'version. Encode() will refuse objects unless their type has been registered with AddKnownTypes. All objects passed to types should be pointers to structs. The name that go reports for the struct becomes the "kind" field when encoding.
func (*Scheme) Convert ¶
Convert will attempt to convert in into out. Both must be pointers. For easy testing of conversion functions. Returns an error if the conversion isn't possible. You can call this with types that haven't been registered (for example, a to test conversion of types that are nested within registered types), but in that case, the conversion.Scope object passed to your conversion functions won't have SrcVersion or DestVersion fields set correctly in Meta().
func (*Scheme) ConvertToVersion ¶ added in v0.5.1
ConvertToVersion attempts to convert an input object to its matching Kind in another version within this scheme. Will return an error if the provided version does not contain the inKind (or a mapping by name defined with AddKnownTypeWithName).
func (*Scheme) DataVersionAndKind ¶
DataVersionAndKind will return the APIVersion and Kind of the given wire-format encoding of an API Object, or an error.
func (*Scheme) Decode ¶
Decode converts a YAML or JSON string back into a pointer to an api object. Deduces the type based upon the fields added by the MetaInsertionFactory technique. The object will be converted, if necessary, into the s.InternalVersion type before being returned. Decode will not decode objects without version set unless InternalVersion is also "".
func (*Scheme) DecodeInto ¶
DecodeInto parses a YAML or 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 pointer to an api type. If obj's version doesn't match that in data, an attempt will be made to convert data into obj's version.
func (*Scheme) EncodeToVersion ¶
EncodeToVersion turns the given api object into an appropriate JSON string. Obj may be a pointer to a struct, or a struct. If a struct, a copy will be made, therefore it's recommended to pass a pointer to a struct. The type must have been registered.
Memory/wire format differences:
- Having to keep track of the Kind and Version fields makes tests very annoying, so the rule is that they are set only in wire format (json), not when in native (memory) format. This is possible because both pieces of information are implicit in the go typed object.
- An exception: note that, if there are embedded API objects of known type, for example, PodList{... Items []Pod ...}, these embedded objects must be of the same version of the object they are embedded within, and their Version and Kind must both be empty.
- Note that the exception does not apply to a generic APIObject type which recursively does Encode()/Decode(), and is capable of expressing any API object.
- Only versioned objects should be encoded. This means that, if you pass a native object, Encode will convert it to a versioned object. For example, an api.Pod will get converted to a v1beta1.Pod. However, if you pass in an object that's already versioned (v1beta1.Pod), Encode will not modify it.
The purpose of the above complex conversion behavior is to allow us to change the memory format yet not break compatibility with any stored objects, whether they be in our storage layer (e.g., etcd), or in user's config files.
func (*Scheme) KnownTypes ¶
KnownTypes returns an array of the types that are known for a particular version.
func (*Scheme) Log ¶
func (s *Scheme) Log(l DebugLogger)
Log sets a logger on the scheme. For test purposes only
func (*Scheme) NewObject ¶
NewObject returns a new object of the given version and name, or an error if it hasn't been registered.
func (*Scheme) ObjectVersionAndKind ¶
ObjectVersionAndKind returns the API version and kind of the go object, or an error if it's not a pointer or is unregistered.
func (*Scheme) SetVersionAndKind ¶
SetVersionAndKind sets the version and kind fields (with help from MetaInsertionFactory). Returns an error if this isn't possible. obj must be a pointer.
type Scope ¶
type Scope interface { // Call Convert to convert sub-objects. Note that if you call it with your own exact // parameters, you'll run out of stack space before anything useful happens. Convert(src, dest interface{}, flags FieldMatchingFlags) error // SrcTags and DestTags contain the struct tags that src and dest had, respectively. // If the enclosing object was not a struct, then these will contain no tags, of course. SrcTag() reflect.StructTag DestTag() reflect.StructTag // Flags returns the flags with which the conversion was started. Flags() FieldMatchingFlags // Meta returns any information originally passed to Convert. Meta() *Meta }
Scope is passed to conversion funcs to allow them to continue an ongoing conversion. If multiple converters exist in the system, Scope will allow you to use the correct one from a conversion function--that is, the one your conversion function was called by.
type SimpleMetaFactory ¶
type SimpleMetaFactory struct { // The name of the API version field in memory of the struct VersionField string // The name of the kind field in memory of the struct. KindField string // Optional, if set will look in the named inline structs to find the fields to set. BaseFields []string }
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 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.
func (SimpleMetaFactory) Interpret ¶
func (SimpleMetaFactory) Interpret(data []byte) (version, kind string, err error)
Interpret will return the APIVersion and Kind of the JSON/YAML wire-format encoding of an object, or an error.
func (SimpleMetaFactory) Update ¶
func (f SimpleMetaFactory) Update(version, kind string, obj interface{}) error