Fix reference to versioned object in kubectl apply

Fixes #19639
pull/6/head
Sam Ghods 2016-02-09 16:07:02 -08:00
parent 494186f40e
commit fd5747f89c
5 changed files with 96 additions and 9 deletions

View File

@ -107,6 +107,7 @@ func RunApply(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *Ap
}
encoder := f.JSONEncoder()
decoder := f.Decoder(false)
count := 0
err = r.Visit(func(info *resource.Info, err error) error {
@ -161,8 +162,18 @@ func RunApply(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *Ap
return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving original configuration from:\n%v\nfor:", info), info.Source, err)
}
// Create the versioned struct from the original from the server for
// strategic patch.
// TODO: Move all structs in apply to use raw data. Can be done once
// builder has a RawResult method which delivers raw data instead of
// internal objects.
versionedObject, _, err := decoder.Decode(current, nil, nil)
if err != nil {
return cmdutil.AddSourceToErr(fmt.Sprintf("converting encoded server-side object back to versioned struct:\n%v\nfor:", info), info.Source, err)
}
// Compute a three way strategic merge patch to send to server.
patch, err := strategicpatch.CreateThreeWayMergePatch(original, modified, current, info.VersionedObject, true)
patch, err := strategicpatch.CreateThreeWayMergePatch(original, modified, current, versionedObject, true)
if err != nil {
format := "creating patch with:\noriginal:\n%s\nmodified:\n%s\ncurrent:\n%s\nfrom:\n%v\nfor:"
return cmdutil.AddSourceToErr(fmt.Sprintf(format, original, modified, current, info), info.Source, err)

View File

@ -52,8 +52,9 @@ func validateApplyArgs(cmd *cobra.Command, args []string) error {
}
const (
filenameRC = "../../../examples/guestbook/redis-master-controller.yaml"
filenameSVC = "../../../examples/guestbook/frontend-service.yaml"
filenameRC = "../../../test/fixtures/pkg/kubectl/cmd/apply/rc.yaml"
filenameSVC = "../../../test/fixtures/pkg/kubectl/cmd/apply/service.yaml"
filenameRCSVC = "../../../test/fixtures/pkg/kubectl/cmd/apply/rc-service.yaml"
)
func readBytesFromFile(t *testing.T, filename string) []byte {
@ -245,7 +246,15 @@ func TestApplyNonExistObject(t *testing.T) {
}
}
func TestApplyMultipleObject(t *testing.T) {
func TestApplyMultipleObjectsAsList(t *testing.T) {
testApplyMultipleObjects(t, true)
}
func TestApplyMultipleObjectsAsFiles(t *testing.T) {
testApplyMultipleObjects(t, false)
}
func testApplyMultipleObjects(t *testing.T, asList bool) {
nameRC, currentRC := readAndAnnotateReplicationController(t, filenameRC)
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
@ -282,8 +291,12 @@ func TestApplyMultipleObject(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply(f, buf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("filename", filenameSVC)
if asList {
cmd.Flags().Set("filename", filenameRCSVC)
} else {
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("filename", filenameSVC)
}
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
@ -291,8 +304,10 @@ func TestApplyMultipleObject(t *testing.T) {
// Names should come from the REST response, NOT the files
expectRC := "replicationcontroller/" + nameRC + "\n"
expectSVC := "service/" + nameSVC + "\n"
expect := expectRC + expectSVC
if buf.String() != expect {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expect)
// Test both possible orders since output is non-deterministic.
expectOne := expectRC + expectSVC
expectTwo := expectSVC + expectRC
if buf.String() != expectOne && buf.String() != expectTwo {
t.Fatalf("unexpected output: %s\nexpected: %s OR %s", buf.String(), expectOne, expectTwo)
}
}

View File

@ -0,0 +1,32 @@
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: Service
metadata:
name: test-service
labels:
name: test-service
spec:
ports:
- port: 80
selector:
name: test-rc
- apiVersion: v1
kind: ReplicationController
metadata:
name: test-rc
labels:
name: test-rc
spec:
replicas: 1
template:
metadata:
labels:
name: test-rc
spec:
containers:
- name: test-rc
image: nginx
ports:
- containerPort: 80

View File

@ -0,0 +1,18 @@
apiVersion: v1
kind: ReplicationController
metadata:
name: test-rc
labels:
name: test-rc
spec:
replicas: 1
template:
metadata:
labels:
name: test-rc
spec:
containers:
- name: test-rc
image: nginx
ports:
- containerPort: 80

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: test-service
labels:
name: test-service
spec:
ports:
- port: 80
selector:
name: test-rc