add versionconverter

This commit is contained in:
jennybuckley
2018-11-28 13:47:45 -08:00
parent 5fd36d635f
commit 21332930cf
3 changed files with 186 additions and 0 deletions

4
Godeps/Godeps.json generated
View File

@@ -4025,6 +4025,10 @@
"ImportPath": "sigs.k8s.io/structured-merge-diff/fieldpath",
"Rev": "01332b709372d8d83b4d7653b30a1961680a47d5"
},
{
"ImportPath": "sigs.k8s.io/structured-merge-diff/merge",
"Rev": "01332b709372d8d83b4d7653b30a1961680a47d5"
},
{
"ImportPath": "sigs.k8s.io/structured-merge-diff/schema",
"Rev": "01332b709372d8d83b4d7653b30a1961680a47d5"

View File

@@ -0,0 +1,67 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apply
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/structured-merge-diff/fieldpath"
"sigs.k8s.io/structured-merge-diff/merge"
"sigs.k8s.io/structured-merge-diff/typed"
)
// versionConverter is an implementation of
// sigs.k8s.io/structured-merge-diff/merge.Converter
type versionConverter struct {
typeConverter TypeConverter
objectConvertor runtime.ObjectConvertor
}
var _ merge.Converter = &versionConverter{}
// NewVersionConverter builds a VersionConverter from a TypeConverter and an ObjectConvertor.
func NewVersionConverter(t TypeConverter, o runtime.ObjectConvertor) merge.Converter {
return &versionConverter{
typeConverter: t,
objectConvertor: o,
}
}
// Convert implements sigs.k8s.io/structured-merge-diff/merge.Converter
func (v *versionConverter) Convert(object typed.TypedValue, version fieldpath.APIVersion) (typed.TypedValue, error) {
// Convert the smd typed value to a kubernetes object.
objectToConvert, err := v.typeConverter.TypedToObject(object)
if err != nil {
return object, err
}
// Parse the target groupVersion.
groupVersion, err := schema.ParseGroupVersion(string(version))
if err != nil {
return object, err
}
// Convert the object into the target version
convertedObject, err := v.objectConvertor.ConvertToVersion(objectToConvert, groupVersion)
if err != nil {
return object, err
}
// Convert the object back to a smd typed value and return it.
return v.typeConverter.ObjectToTyped(convertedObject)
}

View File

@@ -0,0 +1,115 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apply
import (
"fmt"
"path/filepath"
"reflect"
"testing"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kube-openapi/pkg/util/proto"
prototesting "k8s.io/kube-openapi/pkg/util/proto/testing"
"sigs.k8s.io/structured-merge-diff/fieldpath"
)
var fakeSchema = prototesting.Fake{
Path: filepath.Join(
"..", "..", "..", "..", "..", "..", "..", "..",
"api", "openapi-spec", "swagger.json"),
}
// TestVersionConverter tests the version converter
func TestVersionConverter(t *testing.T) {
d, err := fakeSchema.OpenAPISchema()
if err != nil {
t.Fatalf("Failed to parse OpenAPI schema: %v", err)
}
m, err := proto.NewOpenAPIData(d)
if err != nil {
t.Fatalf("Failed to build OpenAPI models: %v", err)
}
tc, err := NewTypeConverter(m)
if err != nil {
t.Fatalf("Failed to build TypeConverter: %v", err)
}
oc := fakeObjectConvertor{
gvkForVersion("v1beta1"): objForGroupVersion("apps/v1beta1"),
gvkForVersion("v1"): objForGroupVersion("apps/v1"),
}
vc := NewVersionConverter(tc, oc)
input, err := tc.ObjectToTyped(objForGroupVersion("apps/v1beta1"))
if err != nil {
t.Fatalf("error creating converting input object to a typed value: %v", err)
}
expected := objForGroupVersion("apps/v1")
output, err := vc.Convert(input, fieldpath.APIVersion("apps/v1"))
if err != nil {
t.Fatalf("expected err to be nil but got %v", err)
}
actual, err := tc.TypedToObject(output)
if err != nil {
t.Fatalf("error converting output typed value to an object %v", err)
}
if !reflect.DeepEqual(expected, actual) {
t.Fatalf("expected to get %v but got %v", expected, actual)
}
}
func gvkForVersion(v string) schema.GroupVersionKind {
return schema.GroupVersionKind{
Group: "apps",
Version: v,
Kind: "Deployment",
}
}
func objForGroupVersion(gv string) runtime.Object {
return &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": gv,
"kind": "Deployment",
},
}
}
type fakeObjectConvertor map[schema.GroupVersionKind]runtime.Object
var _ runtime.ObjectConvertor = fakeObjectConvertor{}
func (c fakeObjectConvertor) ConvertToVersion(_ runtime.Object, gv runtime.GroupVersioner) (runtime.Object, error) {
allKinds := make([]schema.GroupVersionKind, 0)
for kind := range c {
allKinds = append(allKinds, kind)
}
gvk, _ := gv.KindForGroupVersionKinds(allKinds)
return c[gvk], nil
}
func (fakeObjectConvertor) Convert(_, _, _ interface{}) error {
return fmt.Errorf("function not implemented")
}
func (fakeObjectConvertor) ConvertFieldLabel(_ schema.GroupVersionKind, _, _ string) (string, string, error) {
return "", "", fmt.Errorf("function not implemented")
}