diff --git a/api/api-rules/violation_exceptions.list b/api/api-rules/violation_exceptions.list index ebb0bd6f40f..0e6a3e73057 100644 --- a/api/api-rules/violation_exceptions.list +++ b/api/api-rules/violation_exceptions.list @@ -90,7 +90,6 @@ API rule violation: list_type_missing,k8s.io/api/core/v1,EphemeralContainerCommo API rule violation: list_type_missing,k8s.io/api/core/v1,EphemeralContainerCommon,Command API rule violation: list_type_missing,k8s.io/api/core/v1,EphemeralContainerCommon,Env API rule violation: list_type_missing,k8s.io/api/core/v1,EphemeralContainerCommon,EnvFrom -API rule violation: list_type_missing,k8s.io/api/core/v1,EphemeralContainerCommon,Ports API rule violation: list_type_missing,k8s.io/api/core/v1,EphemeralContainerCommon,VolumeDevices API rule violation: list_type_missing,k8s.io/api/core/v1,EphemeralContainerCommon,VolumeMounts API rule violation: list_type_missing,k8s.io/api/core/v1,ExecAction,Command diff --git a/pkg/apis/core/types_test.go b/pkg/apis/core/types_test.go new file mode 100644 index 00000000000..813036d13a0 --- /dev/null +++ b/pkg/apis/core/types_test.go @@ -0,0 +1,41 @@ +/* +Copyright 2021 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 core + +import ( + "reflect" + "testing" +) + +// TestEphemeralContainer ensures that the tags of Container and EphemeralContainerCommon are kept in sync. +func TestEphemeralContainer(t *testing.T) { + ephemeralType := reflect.TypeOf(EphemeralContainerCommon{}) + containerType := reflect.TypeOf(Container{}) + + ephemeralFields := ephemeralType.NumField() + containerFields := containerType.NumField() + if containerFields != ephemeralFields { + t.Fatalf("%v has %d fields, %v has %d fields", ephemeralType, ephemeralFields, containerType, containerFields) + } + for i := 0; i < ephemeralFields; i++ { + ephemeralField := ephemeralType.Field(i) + containerField := containerType.Field(i) + if !reflect.DeepEqual(ephemeralField, containerField) { + t.Errorf("field %v differs:\n\t%#v\n\t%#v", ephemeralField.Name, ephemeralField, containerField) + } + } +} diff --git a/staging/src/k8s.io/api/core/v1/types.go b/staging/src/k8s.io/api/core/v1/types.go index eece7073612..c5325d71b21 100644 --- a/staging/src/k8s.io/api/core/v1/types.go +++ b/staging/src/k8s.io/api/core/v1/types.go @@ -3475,7 +3475,13 @@ type EphemeralContainerCommon struct { // +optional WorkingDir string `json:"workingDir,omitempty" protobuf:"bytes,5,opt,name=workingDir"` // Ports are not allowed for ephemeral containers. - Ports []ContainerPort `json:"ports,omitempty" protobuf:"bytes,6,rep,name=ports"` + // +optional + // +patchMergeKey=containerPort + // +patchStrategy=merge + // +listType=map + // +listMapKey=containerPort + // +listMapKey=protocol + Ports []ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` // List of sources to populate environment variables in the container. // The keys defined within a source must be a C_IDENTIFIER. All invalid keys // will be reported as an event when the container is starting. When a key exists in multiple diff --git a/staging/src/k8s.io/api/core/v1/types_test.go b/staging/src/k8s.io/api/core/v1/types_test.go index 6c602403bef..923c3b868b5 100644 --- a/staging/src/k8s.io/api/core/v1/types_test.go +++ b/staging/src/k8s.io/api/core/v1/types_test.go @@ -39,3 +39,22 @@ func Test_ServiceSpecRemovedFieldProtobufNumberReservation(t *testing.T) { } } } + +// TestEphemeralContainer ensures that the tags of Container and EphemeralContainerCommon are kept in sync. +func TestEphemeralContainer(t *testing.T) { + ephemeralType := reflect.TypeOf(EphemeralContainerCommon{}) + containerType := reflect.TypeOf(Container{}) + + ephemeralFields := ephemeralType.NumField() + containerFields := containerType.NumField() + if containerFields != ephemeralFields { + t.Fatalf("%v has %d fields, %v has %d fields", ephemeralType, ephemeralFields, containerType, containerFields) + } + for i := 0; i < ephemeralFields; i++ { + ephemeralField := ephemeralType.Field(i) + containerField := containerType.Field(i) + if !reflect.DeepEqual(ephemeralField, containerField) { + t.Errorf("field %v differs:\n\t%#v\n\t%#v", ephemeralField.Name, ephemeralField, containerField) + } + } +}