mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Merge pull request #13181 from mikedanese/daemon_experimental
Auto commit by PR queue bot
This commit is contained in:
commit
282bf64dcd
@ -291,69 +291,6 @@ func deepCopy_api_ContainerStatus(in ContainerStatus, out *ContainerStatus, c *c
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_Daemon(in Daemon, out *Daemon, c *conversion.Cloner) error {
|
||||
if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_api_DaemonSpec(in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_api_DaemonStatus(in.Status, &out.Status, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_DaemonList(in DaemonList, out *DaemonList, c *conversion.Cloner) error {
|
||||
if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]Daemon, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := deepCopy_api_Daemon(in.Items[i], &out.Items[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_DaemonSpec(in DaemonSpec, out *DaemonSpec, c *conversion.Cloner) error {
|
||||
if in.Selector != nil {
|
||||
out.Selector = make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
out.Selector[key] = val
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.Template != nil {
|
||||
out.Template = new(PodTemplateSpec)
|
||||
if err := deepCopy_api_PodTemplateSpec(*in.Template, out.Template, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_DaemonStatus(in DaemonStatus, out *DaemonStatus, c *conversion.Cloner) error {
|
||||
out.CurrentNumberScheduled = in.CurrentNumberScheduled
|
||||
out.NumberMisscheduled = in.NumberMisscheduled
|
||||
out.DesiredNumberScheduled = in.DesiredNumberScheduled
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_DeleteOptions(in DeleteOptions, out *DeleteOptions, c *conversion.Cloner) error {
|
||||
if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
@ -2199,10 +2136,6 @@ func init() {
|
||||
deepCopy_api_ContainerStateTerminated,
|
||||
deepCopy_api_ContainerStateWaiting,
|
||||
deepCopy_api_ContainerStatus,
|
||||
deepCopy_api_Daemon,
|
||||
deepCopy_api_DaemonList,
|
||||
deepCopy_api_DaemonSpec,
|
||||
deepCopy_api_DaemonStatus,
|
||||
deepCopy_api_DeleteOptions,
|
||||
deepCopy_api_EmptyDirVolumeSource,
|
||||
deepCopy_api_EndpointAddress,
|
||||
|
@ -83,7 +83,6 @@ var standardResources = util.NewStringSet(
|
||||
string(ResourceQuotas),
|
||||
string(ResourceServices),
|
||||
string(ResourceReplicationControllers),
|
||||
string(ResourceDaemon),
|
||||
string(ResourceSecrets),
|
||||
string(ResourcePersistentVolumeClaims),
|
||||
string(ResourceStorage))
|
||||
|
@ -95,7 +95,6 @@ func init() {
|
||||
"PodExecOptions",
|
||||
"PodAttachOptions",
|
||||
"PodProxyOptions",
|
||||
"Daemon",
|
||||
"ThirdPartyResource",
|
||||
"ThirdPartyResourceData",
|
||||
"ThirdPartyResourceList")
|
||||
|
@ -32,8 +32,6 @@ func init() {
|
||||
&PodTemplateList{},
|
||||
&ReplicationControllerList{},
|
||||
&ReplicationController{},
|
||||
&DaemonList{},
|
||||
&Daemon{},
|
||||
&ServiceList{},
|
||||
&Service{},
|
||||
&NodeList{},
|
||||
@ -85,8 +83,6 @@ func (*PodTemplate) IsAnAPIObject() {}
|
||||
func (*PodTemplateList) IsAnAPIObject() {}
|
||||
func (*ReplicationController) IsAnAPIObject() {}
|
||||
func (*ReplicationControllerList) IsAnAPIObject() {}
|
||||
func (*Daemon) IsAnAPIObject() {}
|
||||
func (*DaemonList) IsAnAPIObject() {}
|
||||
func (*Service) IsAnAPIObject() {}
|
||||
func (*ServiceList) IsAnAPIObject() {}
|
||||
func (*Endpoints) IsAnAPIObject() {}
|
||||
|
@ -120,7 +120,7 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
|
||||
c.FuzzNoCustom(j) // fuzz self without calling this function again
|
||||
//j.TemplateRef = nil // this is required for round trip
|
||||
},
|
||||
func(j *api.DaemonSpec, c fuzz.Continue) {
|
||||
func(j *expapi.DaemonSpec, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(j) // fuzz self without calling this function again
|
||||
},
|
||||
func(j *api.List, c fuzz.Continue) {
|
||||
|
@ -1058,54 +1058,6 @@ type ReplicationControllerList struct {
|
||||
Items []ReplicationController `json:"items"`
|
||||
}
|
||||
|
||||
// DaemonSpec is the specification of a daemon.
|
||||
type DaemonSpec struct {
|
||||
// Selector is a label query over pods that are managed by the daemon.
|
||||
Selector map[string]string `json:"selector"`
|
||||
|
||||
// Template is the object that describes the pod that will be created.
|
||||
// The Daemon will create exactly one copy of this pod on every node
|
||||
// that matches the template's node selector (or on every node if no node
|
||||
// selector is specified).
|
||||
Template *PodTemplateSpec `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonStatus represents the current status of a daemon.
|
||||
type DaemonStatus struct {
|
||||
// CurrentNumberScheduled is the number of nodes that are running exactly 1 copy of the
|
||||
// daemon and are supposed to run the daemon.
|
||||
CurrentNumberScheduled int `json:"currentNumberScheduled"`
|
||||
|
||||
// NumberMisscheduled is the number of nodes that are running the daemon, but are
|
||||
// not supposed to run the daemon.
|
||||
NumberMisscheduled int `json:"numberMisscheduled"`
|
||||
|
||||
// DesiredNumberScheduled is the total number of nodes that should be running the daemon
|
||||
// (including nodes correctly running the daemon).
|
||||
DesiredNumberScheduled int `json:"desiredNumberScheduled"`
|
||||
}
|
||||
|
||||
// Daemon represents the configuration of a daemon.
|
||||
type Daemon struct {
|
||||
TypeMeta `json:",inline"`
|
||||
ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the desired behavior of this daemon.
|
||||
Spec DaemonSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current status of this daemon. This data may be
|
||||
// out of date by some window of time.
|
||||
Status DaemonStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonList is a collection of daemon.
|
||||
type DaemonList struct {
|
||||
TypeMeta `json:",inline"`
|
||||
ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []Daemon `json:"items"`
|
||||
}
|
||||
|
||||
const (
|
||||
// ClusterIPNone - do not assign a cluster IP
|
||||
// no proxying required and no environment variables should be created for pods
|
||||
@ -1978,8 +1930,6 @@ const (
|
||||
ResourceServices ResourceName = "services"
|
||||
// ReplicationControllers, number
|
||||
ResourceReplicationControllers ResourceName = "replicationcontrollers"
|
||||
// Daemon, number
|
||||
ResourceDaemon ResourceName = "daemon"
|
||||
// ResourceQuotas, number
|
||||
ResourceQuotas ResourceName = "resourcequotas"
|
||||
// ResourceSecrets, number
|
||||
|
@ -326,81 +326,6 @@ func convert_api_ContainerStatus_To_v1_ContainerStatus(in *api.ContainerStatus,
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_api_Daemon_To_v1_Daemon(in *api.Daemon, out *Daemon, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.Daemon))(in)
|
||||
}
|
||||
if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_api_DaemonSpec_To_v1_DaemonSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_api_DaemonStatus_To_v1_DaemonStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_api_DaemonList_To_v1_DaemonList(in *api.DaemonList, out *DaemonList, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.DaemonList))(in)
|
||||
}
|
||||
if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]Daemon, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := convert_api_Daemon_To_v1_Daemon(&in.Items[i], &out.Items[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_api_DaemonSpec_To_v1_DaemonSpec(in *api.DaemonSpec, out *DaemonSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.DaemonSpec))(in)
|
||||
}
|
||||
if in.Selector != nil {
|
||||
out.Selector = make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
out.Selector[key] = val
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.Template != nil {
|
||||
out.Template = new(PodTemplateSpec)
|
||||
if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_api_DaemonStatus_To_v1_DaemonStatus(in *api.DaemonStatus, out *DaemonStatus, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.DaemonStatus))(in)
|
||||
}
|
||||
out.CurrentNumberScheduled = in.CurrentNumberScheduled
|
||||
out.NumberMisscheduled = in.NumberMisscheduled
|
||||
out.DesiredNumberScheduled = in.DesiredNumberScheduled
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_api_DeleteOptions_To_v1_DeleteOptions(in *api.DeleteOptions, out *DeleteOptions, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.DeleteOptions))(in)
|
||||
@ -2691,81 +2616,6 @@ func convert_v1_ContainerStatus_To_api_ContainerStatus(in *ContainerStatus, out
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_Daemon_To_api_Daemon(in *Daemon, out *api.Daemon, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*Daemon))(in)
|
||||
}
|
||||
if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_v1_DaemonSpec_To_api_DaemonSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_v1_DaemonStatus_To_api_DaemonStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_DaemonList_To_api_DaemonList(in *DaemonList, out *api.DaemonList, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*DaemonList))(in)
|
||||
}
|
||||
if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]api.Daemon, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := convert_v1_Daemon_To_api_Daemon(&in.Items[i], &out.Items[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_DaemonSpec_To_api_DaemonSpec(in *DaemonSpec, out *api.DaemonSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*DaemonSpec))(in)
|
||||
}
|
||||
if in.Selector != nil {
|
||||
out.Selector = make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
out.Selector[key] = val
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.Template != nil {
|
||||
out.Template = new(api.PodTemplateSpec)
|
||||
if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_DaemonStatus_To_api_DaemonStatus(in *DaemonStatus, out *api.DaemonStatus, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*DaemonStatus))(in)
|
||||
}
|
||||
out.CurrentNumberScheduled = in.CurrentNumberScheduled
|
||||
out.NumberMisscheduled = in.NumberMisscheduled
|
||||
out.DesiredNumberScheduled = in.DesiredNumberScheduled
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_DeleteOptions_To_api_DeleteOptions(in *DeleteOptions, out *api.DeleteOptions, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*DeleteOptions))(in)
|
||||
@ -4771,10 +4621,6 @@ func init() {
|
||||
convert_api_ContainerState_To_v1_ContainerState,
|
||||
convert_api_ContainerStatus_To_v1_ContainerStatus,
|
||||
convert_api_Container_To_v1_Container,
|
||||
convert_api_DaemonList_To_v1_DaemonList,
|
||||
convert_api_DaemonSpec_To_v1_DaemonSpec,
|
||||
convert_api_DaemonStatus_To_v1_DaemonStatus,
|
||||
convert_api_Daemon_To_v1_Daemon,
|
||||
convert_api_DeleteOptions_To_v1_DeleteOptions,
|
||||
convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource,
|
||||
convert_api_EndpointAddress_To_v1_EndpointAddress,
|
||||
@ -4889,10 +4735,6 @@ func init() {
|
||||
convert_v1_ContainerState_To_api_ContainerState,
|
||||
convert_v1_ContainerStatus_To_api_ContainerStatus,
|
||||
convert_v1_Container_To_api_Container,
|
||||
convert_v1_DaemonList_To_api_DaemonList,
|
||||
convert_v1_DaemonSpec_To_api_DaemonSpec,
|
||||
convert_v1_DaemonStatus_To_api_DaemonStatus,
|
||||
convert_v1_Daemon_To_api_Daemon,
|
||||
convert_v1_DeleteOptions_To_api_DeleteOptions,
|
||||
convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource,
|
||||
convert_v1_EndpointAddress_To_api_EndpointAddress,
|
||||
|
@ -306,69 +306,6 @@ func deepCopy_v1_ContainerStatus(in ContainerStatus, out *ContainerStatus, c *co
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_Daemon(in Daemon, out *Daemon, c *conversion.Cloner) error {
|
||||
if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_DaemonSpec(in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_DaemonStatus(in.Status, &out.Status, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_DaemonList(in DaemonList, out *DaemonList, c *conversion.Cloner) error {
|
||||
if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]Daemon, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := deepCopy_v1_Daemon(in.Items[i], &out.Items[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_DaemonSpec(in DaemonSpec, out *DaemonSpec, c *conversion.Cloner) error {
|
||||
if in.Selector != nil {
|
||||
out.Selector = make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
out.Selector[key] = val
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.Template != nil {
|
||||
out.Template = new(PodTemplateSpec)
|
||||
if err := deepCopy_v1_PodTemplateSpec(*in.Template, out.Template, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_DaemonStatus(in DaemonStatus, out *DaemonStatus, c *conversion.Cloner) error {
|
||||
out.CurrentNumberScheduled = in.CurrentNumberScheduled
|
||||
out.NumberMisscheduled = in.NumberMisscheduled
|
||||
out.DesiredNumberScheduled = in.DesiredNumberScheduled
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_DeleteOptions(in DeleteOptions, out *DeleteOptions, c *conversion.Cloner) error {
|
||||
if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
@ -2201,10 +2138,6 @@ func init() {
|
||||
deepCopy_v1_ContainerStateTerminated,
|
||||
deepCopy_v1_ContainerStateWaiting,
|
||||
deepCopy_v1_ContainerStatus,
|
||||
deepCopy_v1_Daemon,
|
||||
deepCopy_v1_DaemonList,
|
||||
deepCopy_v1_DaemonSpec,
|
||||
deepCopy_v1_DaemonStatus,
|
||||
deepCopy_v1_DeleteOptions,
|
||||
deepCopy_v1_EmptyDirVolumeSource,
|
||||
deepCopy_v1_EndpointAddress,
|
||||
|
@ -44,21 +44,6 @@ func addDefaultingFuncs() {
|
||||
*obj.Spec.Replicas = 1
|
||||
}
|
||||
},
|
||||
func(obj *Daemon) {
|
||||
var labels map[string]string
|
||||
if obj.Spec.Template != nil {
|
||||
labels = obj.Spec.Template.Labels
|
||||
}
|
||||
// TODO: support templates defined elsewhere when we support them in the API
|
||||
if labels != nil {
|
||||
if len(obj.Spec.Selector) == 0 {
|
||||
obj.Spec.Selector = labels
|
||||
}
|
||||
if len(obj.Labels) == 0 {
|
||||
obj.Labels = labels
|
||||
}
|
||||
}
|
||||
},
|
||||
func(obj *Volume) {
|
||||
if util.AllPtrFieldsNil(&obj.VolumeSource) {
|
||||
obj.VolumeSource = VolumeSource{
|
||||
|
@ -155,64 +155,6 @@ func TestSetDefaultReplicationController(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultDaemon(t *testing.T) {
|
||||
tests := []struct {
|
||||
dc *versioned.Daemon
|
||||
expectLabelsChange bool
|
||||
}{
|
||||
{
|
||||
dc: &versioned.Daemon{
|
||||
Spec: versioned.DaemonSpec{
|
||||
Template: &versioned.PodTemplateSpec{
|
||||
ObjectMeta: versioned.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectLabelsChange: true,
|
||||
},
|
||||
{
|
||||
dc: &versioned.Daemon{
|
||||
ObjectMeta: versioned.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"bar": "foo",
|
||||
},
|
||||
},
|
||||
Spec: versioned.DaemonSpec{
|
||||
Template: &versioned.PodTemplateSpec{
|
||||
ObjectMeta: versioned.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectLabelsChange: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
dc := test.dc
|
||||
obj2 := roundTrip(t, runtime.Object(dc))
|
||||
dc2, ok := obj2.(*versioned.Daemon)
|
||||
if !ok {
|
||||
t.Errorf("unexpected object: %v", dc2)
|
||||
t.FailNow()
|
||||
}
|
||||
if test.expectLabelsChange != reflect.DeepEqual(dc2.Labels, dc2.Spec.Template.Labels) {
|
||||
if test.expectLabelsChange {
|
||||
t.Errorf("expected: %v, got: %v", dc2.Spec.Template.Labels, dc2.Labels)
|
||||
} else {
|
||||
t.Errorf("unexpected equality: %v", dc.Labels)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newInt(val int) *int {
|
||||
p := new(int)
|
||||
*p = val
|
||||
|
@ -47,8 +47,6 @@ func addKnownTypes() {
|
||||
&PodTemplateList{},
|
||||
&ReplicationController{},
|
||||
&ReplicationControllerList{},
|
||||
&DaemonList{},
|
||||
&Daemon{},
|
||||
&Service{},
|
||||
&ServiceList{},
|
||||
&Endpoints{},
|
||||
@ -100,8 +98,6 @@ func (*PodTemplate) IsAnAPIObject() {}
|
||||
func (*PodTemplateList) IsAnAPIObject() {}
|
||||
func (*ReplicationController) IsAnAPIObject() {}
|
||||
func (*ReplicationControllerList) IsAnAPIObject() {}
|
||||
func (*Daemon) IsAnAPIObject() {}
|
||||
func (*DaemonList) IsAnAPIObject() {}
|
||||
func (*Service) IsAnAPIObject() {}
|
||||
func (*ServiceList) IsAnAPIObject() {}
|
||||
func (*Endpoints) IsAnAPIObject() {}
|
||||
|
@ -1365,67 +1365,6 @@ type ReplicationControllerList struct {
|
||||
Items []ReplicationController `json:"items"`
|
||||
}
|
||||
|
||||
// DaemonSpec is the specification of a daemon.
|
||||
type DaemonSpec struct {
|
||||
// Selector is a label query over pods that are managed by the daemon.
|
||||
// Must match in order to be controlled.
|
||||
// If empty, defaulted to labels on Pod template.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
|
||||
Selector map[string]string `json:"selector,omitempty"`
|
||||
|
||||
// Template is the object that describes the pod that will be created.
|
||||
// The Daemon will create exactly one copy of this pod on every node
|
||||
// that matches the template's node selector (or on every node if no node
|
||||
// selector is specified).
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template
|
||||
Template *PodTemplateSpec `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonStatus represents the current status of a daemon.
|
||||
type DaemonStatus struct {
|
||||
// CurrentNumberScheduled is the number of nodes that are running exactly 1 copy of the
|
||||
// daemon and are supposed to run the daemon.
|
||||
CurrentNumberScheduled int `json:"currentNumberScheduled"`
|
||||
|
||||
// NumberMisscheduled is the number of nodes that are running the daemon, but are
|
||||
// not supposed to run the daemon.
|
||||
NumberMisscheduled int `json:"numberMisscheduled"`
|
||||
|
||||
// DesiredNumberScheduled is the total number of nodes that should be running the daemon
|
||||
// (including nodes correctly running the daemon).
|
||||
DesiredNumberScheduled int `json:"desiredNumberScheduled"`
|
||||
}
|
||||
|
||||
// Daemon represents the configuration of a daemon.
|
||||
type Daemon struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the specification of the desired behavior of this daemon.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec DaemonSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current status of this daemon. This data may be
|
||||
// out of date by some window of time.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status DaemonStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonList is a collection of daemon.
|
||||
type DaemonList struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Standard list metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is a list of daemons.
|
||||
Items []Daemon `json:"items"`
|
||||
}
|
||||
|
||||
// Session Affinity Type string
|
||||
type ServiceAffinity string
|
||||
|
||||
@ -2370,8 +2309,6 @@ const (
|
||||
ResourceServices ResourceName = "services"
|
||||
// ReplicationControllers, number
|
||||
ResourceReplicationControllers ResourceName = "replicationcontrollers"
|
||||
// Daemon, number
|
||||
ResourceDaemon ResourceName = "daemon"
|
||||
// ResourceQuotas, number
|
||||
ResourceQuotas ResourceName = "resourcequotas"
|
||||
// ResourceSecrets, number
|
||||
|
@ -199,48 +199,6 @@ func (ContainerStatus) SwaggerDoc() map[string]string {
|
||||
return map_ContainerStatus
|
||||
}
|
||||
|
||||
var map_Daemon = map[string]string{
|
||||
"": "Daemon represents the configuration of a daemon.",
|
||||
"metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",
|
||||
"spec": "Spec defines the specification of the desired behavior of this daemon. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status",
|
||||
"status": "Status is the current status of this daemon. This data may be out of date by some window of time. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status",
|
||||
}
|
||||
|
||||
func (Daemon) SwaggerDoc() map[string]string {
|
||||
return map_Daemon
|
||||
}
|
||||
|
||||
var map_DaemonList = map[string]string{
|
||||
"": "DaemonList is a collection of daemon.",
|
||||
"metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",
|
||||
"items": "Items is a list of daemons.",
|
||||
}
|
||||
|
||||
func (DaemonList) SwaggerDoc() map[string]string {
|
||||
return map_DaemonList
|
||||
}
|
||||
|
||||
var map_DaemonSpec = map[string]string{
|
||||
"": "DaemonSpec is the specification of a daemon.",
|
||||
"selector": "Selector is a label query over pods that are managed by the daemon. Must match in order to be controlled. If empty, defaulted to labels on Pod template. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors",
|
||||
"template": "Template is the object that describes the pod that will be created. The Daemon will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template",
|
||||
}
|
||||
|
||||
func (DaemonSpec) SwaggerDoc() map[string]string {
|
||||
return map_DaemonSpec
|
||||
}
|
||||
|
||||
var map_DaemonStatus = map[string]string{
|
||||
"": "DaemonStatus represents the current status of a daemon.",
|
||||
"currentNumberScheduled": "CurrentNumberScheduled is the number of nodes that are running exactly 1 copy of the daemon and are supposed to run the daemon.",
|
||||
"numberMisscheduled": "NumberMisscheduled is the number of nodes that are running the daemon, but are not supposed to run the daemon.",
|
||||
"desiredNumberScheduled": "DesiredNumberScheduled is the total number of nodes that should be running the daemon (including nodes correctly running the daemon).",
|
||||
}
|
||||
|
||||
func (DaemonStatus) SwaggerDoc() map[string]string {
|
||||
return map_DaemonStatus
|
||||
}
|
||||
|
||||
var map_DeleteOptions = map[string]string{
|
||||
"": "DeleteOptions may be provided when deleting an API object",
|
||||
"gracePeriodSeconds": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.",
|
||||
|
@ -112,13 +112,6 @@ func ValidateReplicationControllerName(name string, prefix bool) (bool, string)
|
||||
return NameIsDNSSubdomain(name, prefix)
|
||||
}
|
||||
|
||||
// ValidateDaemonName can be used to check whether the given daemon name is valid.
|
||||
// Prefix indicates this name will be used as part of generation, in which case
|
||||
// trailing dashes are allowed.
|
||||
func ValidateDaemonName(name string, prefix bool) (bool, string) {
|
||||
return NameIsDNSSubdomain(name, prefix)
|
||||
}
|
||||
|
||||
// ValidateServiceName can be used to check whether the given service name is valid.
|
||||
// Prefix indicates this name will be used as part of generation, in which case
|
||||
// trailing dashes are allowed.
|
||||
@ -1244,65 +1237,6 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemon tests if required fields in the daemon are set.
|
||||
func ValidateDaemon(controller *api.Daemon) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
allErrs = append(allErrs, ValidateObjectMeta(&controller.ObjectMeta, true, ValidateReplicationControllerName).Prefix("metadata")...)
|
||||
allErrs = append(allErrs, ValidateDaemonSpec(&controller.Spec).Prefix("spec")...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemonUpdate tests if required fields in the daemon are set.
|
||||
func ValidateDaemonUpdate(oldController, controller *api.Daemon) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
allErrs = append(allErrs, ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta).Prefix("metadata")...)
|
||||
allErrs = append(allErrs, ValidateDaemonSpec(&controller.Spec).Prefix("spec")...)
|
||||
allErrs = append(allErrs, ValidateDaemonTemplateUpdate(oldController.Spec.Template, controller.Spec.Template).Prefix("spec.template")...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemonTemplateUpdate tests that certain fields in the daemon's pod template are not updated.
|
||||
func ValidateDaemonTemplateUpdate(oldPodTemplate, podTemplate *api.PodTemplateSpec) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
podSpec := podTemplate.Spec
|
||||
// podTemplate.Spec is not a pointer, so we can modify NodeSelector and NodeName directly.
|
||||
podSpec.NodeSelector = oldPodTemplate.Spec.NodeSelector
|
||||
podSpec.NodeName = oldPodTemplate.Spec.NodeName
|
||||
// In particular, we do not allow updates to container images at this point.
|
||||
if !api.Semantic.DeepEqual(oldPodTemplate.Spec, podSpec) {
|
||||
// TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("spec", "content of spec is not printed out, please refer to the \"details\"", "may not update fields other than spec.nodeSelector"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemonSpec tests if required fields in the daemon spec are set.
|
||||
func ValidateDaemonSpec(spec *api.DaemonSpec) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
|
||||
selector := labels.Set(spec.Selector).AsSelector()
|
||||
if selector.Empty() {
|
||||
allErrs = append(allErrs, errs.NewFieldRequired("selector"))
|
||||
}
|
||||
|
||||
if spec.Template == nil {
|
||||
allErrs = append(allErrs, errs.NewFieldRequired("template"))
|
||||
} else {
|
||||
labels := labels.Set(spec.Template.Labels)
|
||||
if !selector.Matches(labels) {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("template.metadata.labels", spec.Template.Labels, "selector does not match template"))
|
||||
}
|
||||
allErrs = append(allErrs, ValidatePodTemplateSpec(spec.Template).Prefix("template")...)
|
||||
// Daemons typically run on more than one node, so mark Read-Write persistent disks as invalid.
|
||||
allErrs = append(allErrs, ValidateReadOnlyPersistentDisks(spec.Template.Spec.Volumes).Prefix("template.spec.volumes")...)
|
||||
// RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec().
|
||||
if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways {
|
||||
allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)}))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePodTemplateSpec validates the spec of a pod template
|
||||
func ValidatePodTemplateSpec(spec *api.PodTemplateSpec) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
|
@ -2365,418 +2365,6 @@ func TestValidateReplicationController(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDaemonUpdate(t *testing.T) {
|
||||
validSelector := map[string]string{"a": "b"}
|
||||
validSelector2 := map[string]string{"c": "d"}
|
||||
invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
|
||||
|
||||
validPodSpecAbc := api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
}
|
||||
validPodSpecDef := api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
}
|
||||
validPodSpecNodeSelector := api.PodSpec{
|
||||
NodeSelector: validSelector,
|
||||
NodeName: "xyz",
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
}
|
||||
validPodSpecVolume := api.PodSpec{
|
||||
Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
}
|
||||
|
||||
validPodTemplateAbc := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
Spec: validPodSpecAbc,
|
||||
},
|
||||
}
|
||||
validPodTemplateNodeSelector := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
Spec: validPodSpecNodeSelector,
|
||||
},
|
||||
}
|
||||
validPodTemplateAbc2 := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector2,
|
||||
},
|
||||
Spec: validPodSpecAbc,
|
||||
},
|
||||
}
|
||||
validPodTemplateDef := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector2,
|
||||
},
|
||||
Spec: validPodSpecDef,
|
||||
},
|
||||
}
|
||||
invalidPodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: invalidSelector,
|
||||
},
|
||||
},
|
||||
}
|
||||
readWriteVolumePodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
Spec: validPodSpecVolume,
|
||||
},
|
||||
}
|
||||
|
||||
type dcUpdateTest struct {
|
||||
old api.Daemon
|
||||
update api.Daemon
|
||||
}
|
||||
successCases := []dcUpdateTest{
|
||||
{
|
||||
old: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
old: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector2,
|
||||
Template: &validPodTemplateAbc2.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
old: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateNodeSelector.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, successCase := range successCases {
|
||||
successCase.old.ObjectMeta.ResourceVersion = "1"
|
||||
successCase.update.ObjectMeta.ResourceVersion = "1"
|
||||
if errs := ValidateDaemonUpdate(&successCase.old, &successCase.update); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
errorCases := map[string]dcUpdateTest{
|
||||
"change daemon name": {
|
||||
old: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"invalid selector": {
|
||||
old: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: invalidSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"invalid pod": {
|
||||
old: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &invalidPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"change container image": {
|
||||
old: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateDef.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"read-write volume": {
|
||||
old: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &readWriteVolumePodTemplate.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for testName, errorCase := range errorCases {
|
||||
if errs := ValidateDaemonUpdate(&errorCase.old, &errorCase.update); len(errs) == 0 {
|
||||
t.Errorf("expected failure: %s", testName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDaemon(t *testing.T) {
|
||||
validSelector := map[string]string{"a": "b"}
|
||||
validPodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
|
||||
invalidPodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: invalidSelector,
|
||||
},
|
||||
},
|
||||
}
|
||||
successCases := []api.Daemon{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc-123", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, successCase := range successCases {
|
||||
if errs := ValidateDaemon(&successCase); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
errorCases := map[string]api.Daemon{
|
||||
"zero-length ID": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"missing-namespace": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc-123"},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"empty selector": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"selector_doesnt_match": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"invalid manifest": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
},
|
||||
},
|
||||
"invalid_label": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"invalid_label 2": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Template: &invalidPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"invalid_annotation": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Annotations: map[string]string{
|
||||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"invalid restart policy 1": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"invalid restart policy 2": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, v := range errorCases {
|
||||
errs := ValidateDaemon(&v)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected failure for %s", k)
|
||||
}
|
||||
for i := range errs {
|
||||
field := errs[i].(*errors.ValidationError).Field
|
||||
if !strings.HasPrefix(field, "spec.template.") &&
|
||||
field != "metadata.name" &&
|
||||
field != "metadata.namespace" &&
|
||||
field != "spec.selector" &&
|
||||
field != "spec.template" &&
|
||||
field != "GCEPersistentDisk.ReadOnly" &&
|
||||
field != "spec.template.labels" &&
|
||||
field != "metadata.annotations" &&
|
||||
field != "metadata.labels" {
|
||||
t.Errorf("%s: missing prefix for: %v", k, errs[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateNode(t *testing.T) {
|
||||
validSelector := map[string]string{"a": "b"}
|
||||
invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
|
||||
|
13
pkg/client/unversioned/cache/listers.go
vendored
13
pkg/client/unversioned/cache/listers.go
vendored
@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
)
|
||||
|
||||
@ -231,7 +232,7 @@ type StoreToDaemonLister struct {
|
||||
}
|
||||
|
||||
// Exists checks if the given dc exists in the store.
|
||||
func (s *StoreToDaemonLister) Exists(daemon *api.Daemon) (bool, error) {
|
||||
func (s *StoreToDaemonLister) Exists(daemon *expapi.Daemon) (bool, error) {
|
||||
_, exists, err := s.Store.Get(daemon)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@ -241,17 +242,17 @@ func (s *StoreToDaemonLister) Exists(daemon *api.Daemon) (bool, error) {
|
||||
|
||||
// StoreToDaemonLister lists all daemons in the store.
|
||||
// TODO: converge on the interface in pkg/client
|
||||
func (s *StoreToDaemonLister) List() (daemons []api.Daemon, err error) {
|
||||
func (s *StoreToDaemonLister) List() (daemons []expapi.Daemon, err error) {
|
||||
for _, c := range s.Store.List() {
|
||||
daemons = append(daemons, *(c.(*api.Daemon)))
|
||||
daemons = append(daemons, *(c.(*expapi.Daemon)))
|
||||
}
|
||||
return daemons, nil
|
||||
}
|
||||
|
||||
// GetPodDaemons returns a list of daemons managing a pod. Returns an error iff no matching daemons are found.
|
||||
func (s *StoreToDaemonLister) GetPodDaemons(pod *api.Pod) (daemons []api.Daemon, err error) {
|
||||
func (s *StoreToDaemonLister) GetPodDaemons(pod *api.Pod) (daemons []expapi.Daemon, err error) {
|
||||
var selector labels.Selector
|
||||
var daemonController api.Daemon
|
||||
var daemonController expapi.Daemon
|
||||
|
||||
if len(pod.Labels) == 0 {
|
||||
err = fmt.Errorf("No daemons found for pod %v because it has no labels", pod.Name)
|
||||
@ -259,7 +260,7 @@ func (s *StoreToDaemonLister) GetPodDaemons(pod *api.Pod) (daemons []api.Daemon,
|
||||
}
|
||||
|
||||
for _, m := range s.Store.List() {
|
||||
daemonController = *m.(*api.Daemon)
|
||||
daemonController = *m.(*expapi.Daemon)
|
||||
if daemonController.Namespace != pod.Namespace {
|
||||
continue
|
||||
}
|
||||
|
31
pkg/client/unversioned/cache/listers_test.go
vendored
31
pkg/client/unversioned/cache/listers_test.go
vendored
@ -20,6 +20,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
)
|
||||
@ -159,44 +160,44 @@ func TestStoreToDaemonLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
lister := StoreToDaemonLister{store}
|
||||
testCases := []struct {
|
||||
inDCs []*api.Daemon
|
||||
list func() ([]api.Daemon, error)
|
||||
inDCs []*expapi.Daemon
|
||||
list func() ([]expapi.Daemon, error)
|
||||
outDCNames util.StringSet
|
||||
expectErr bool
|
||||
}{
|
||||
// Basic listing
|
||||
{
|
||||
inDCs: []*api.Daemon{
|
||||
inDCs: []*expapi.Daemon{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
},
|
||||
list: func() ([]api.Daemon, error) {
|
||||
list: func() ([]expapi.Daemon, error) {
|
||||
return lister.List()
|
||||
},
|
||||
outDCNames: util.NewStringSet("basic"),
|
||||
},
|
||||
// Listing multiple controllers
|
||||
{
|
||||
inDCs: []*api.Daemon{
|
||||
inDCs: []*expapi.Daemon{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "complex"}},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "complex2"}},
|
||||
},
|
||||
list: func() ([]api.Daemon, error) {
|
||||
list: func() ([]expapi.Daemon, error) {
|
||||
return lister.List()
|
||||
},
|
||||
outDCNames: util.NewStringSet("basic", "complex", "complex2"),
|
||||
},
|
||||
// No pod labels
|
||||
{
|
||||
inDCs: []*api.Daemon{
|
||||
inDCs: []*expapi.Daemon{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
Spec: api.DaemonSpec{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{"foo": "baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]api.Daemon, error) {
|
||||
list: func() ([]expapi.Daemon, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"},
|
||||
}
|
||||
@ -207,12 +208,12 @@ func TestStoreToDaemonLister(t *testing.T) {
|
||||
},
|
||||
// No RC selectors
|
||||
{
|
||||
inDCs: []*api.Daemon{
|
||||
inDCs: []*expapi.Daemon{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
},
|
||||
},
|
||||
list: func() ([]api.Daemon, error) {
|
||||
list: func() ([]expapi.Daemon, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod1",
|
||||
@ -227,21 +228,21 @@ func TestStoreToDaemonLister(t *testing.T) {
|
||||
},
|
||||
// Matching labels to selectors and namespace
|
||||
{
|
||||
inDCs: []*api.Daemon{
|
||||
inDCs: []*expapi.Daemon{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.DaemonSpec{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
|
||||
Spec: api.DaemonSpec{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]api.Daemon, error) {
|
||||
list: func() ([]expapi.Daemon, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod1",
|
||||
|
@ -33,7 +33,6 @@ type Interface interface {
|
||||
PodsNamespacer
|
||||
PodTemplatesNamespacer
|
||||
ReplicationControllersNamespacer
|
||||
DaemonsNamespacer
|
||||
ServicesNamespacer
|
||||
EndpointsNamespacer
|
||||
VersionInterface
|
||||
@ -53,10 +52,6 @@ func (c *Client) ReplicationControllers(namespace string) ReplicationControllerI
|
||||
return newReplicationControllers(c, namespace)
|
||||
}
|
||||
|
||||
func (c *Client) Daemons(namespace string) DaemonInterface {
|
||||
return newDaemons(c, namespace)
|
||||
}
|
||||
|
||||
func (c *Client) Nodes() NodeInterface {
|
||||
return newNodes(c)
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
@ -29,50 +29,50 @@ type DaemonsNamespacer interface {
|
||||
}
|
||||
|
||||
type DaemonInterface interface {
|
||||
List(selector labels.Selector) (*api.DaemonList, error)
|
||||
Get(name string) (*api.Daemon, error)
|
||||
Create(ctrl *api.Daemon) (*api.Daemon, error)
|
||||
Update(ctrl *api.Daemon) (*api.Daemon, error)
|
||||
List(selector labels.Selector) (*expapi.DaemonList, error)
|
||||
Get(name string) (*expapi.Daemon, error)
|
||||
Create(ctrl *expapi.Daemon) (*expapi.Daemon, error)
|
||||
Update(ctrl *expapi.Daemon) (*expapi.Daemon, error)
|
||||
Delete(name string) error
|
||||
Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
|
||||
}
|
||||
|
||||
// daemons implements DaemonsNamespacer interface
|
||||
type daemons struct {
|
||||
r *Client
|
||||
r *ExperimentalClient
|
||||
ns string
|
||||
}
|
||||
|
||||
func newDaemons(c *Client, namespace string) *daemons {
|
||||
func newDaemons(c *ExperimentalClient, namespace string) *daemons {
|
||||
return &daemons{c, namespace}
|
||||
}
|
||||
|
||||
// Ensure statically that daemons implements DaemonInterface.
|
||||
var _ DaemonInterface = &daemons{}
|
||||
|
||||
func (c *daemons) List(selector labels.Selector) (result *api.DaemonList, err error) {
|
||||
result = &api.DaemonList{}
|
||||
func (c *daemons) List(selector labels.Selector) (result *expapi.DaemonList, err error) {
|
||||
result = &expapi.DaemonList{}
|
||||
err = c.r.Get().Namespace(c.ns).Resource("daemons").LabelsSelectorParam(selector).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns information about a particular daemon.
|
||||
func (c *daemons) Get(name string) (result *api.Daemon, err error) {
|
||||
result = &api.Daemon{}
|
||||
func (c *daemons) Get(name string) (result *expapi.Daemon, err error) {
|
||||
result = &expapi.Daemon{}
|
||||
err = c.r.Get().Namespace(c.ns).Resource("daemons").Name(name).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Create creates a new daemon.
|
||||
func (c *daemons) Create(daemon *api.Daemon) (result *api.Daemon, err error) {
|
||||
result = &api.Daemon{}
|
||||
func (c *daemons) Create(daemon *expapi.Daemon) (result *expapi.Daemon, err error) {
|
||||
result = &expapi.Daemon{}
|
||||
err = c.r.Post().Namespace(c.ns).Resource("daemons").Body(daemon).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update updates an existing daemon.
|
||||
func (c *daemons) Update(daemon *api.Daemon) (result *api.Daemon, err error) {
|
||||
result = &api.Daemon{}
|
||||
func (c *daemons) Update(daemon *expapi.Daemon) (result *expapi.Daemon, err error) {
|
||||
result = &expapi.Daemon{}
|
||||
err = c.r.Put().Namespace(c.ns).Resource("daemons").Name(daemon.Name).Body(daemon).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/expapi/testapi"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
)
|
||||
|
||||
@ -36,8 +37,8 @@ func TestListDaemons(t *testing.T) {
|
||||
Path: testapi.ResourcePath(getDCResourceName(), ns, ""),
|
||||
},
|
||||
Response: Response{StatusCode: 200,
|
||||
Body: &api.DaemonList{
|
||||
Items: []api.Daemon{
|
||||
Body: &expapi.DaemonList{
|
||||
Items: []expapi.Daemon{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
@ -46,7 +47,7 @@ func TestListDaemons(t *testing.T) {
|
||||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Template: &api.PodTemplateSpec{},
|
||||
},
|
||||
},
|
||||
@ -65,7 +66,7 @@ func TestGetDaemon(t *testing.T) {
|
||||
Request: testRequest{Method: "GET", Path: testapi.ResourcePath(getDCResourceName(), ns, "foo"), Query: buildQueryValues(nil)},
|
||||
Response: Response{
|
||||
StatusCode: 200,
|
||||
Body: &api.Daemon{
|
||||
Body: &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
@ -73,7 +74,7 @@ func TestGetDaemon(t *testing.T) {
|
||||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Template: &api.PodTemplateSpec{},
|
||||
},
|
||||
},
|
||||
@ -96,14 +97,14 @@ func TestGetDaemonWithNoName(t *testing.T) {
|
||||
|
||||
func TestUpdateDaemon(t *testing.T) {
|
||||
ns := api.NamespaceDefault
|
||||
requestController := &api.Daemon{
|
||||
requestController := &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
|
||||
}
|
||||
c := &testClient{
|
||||
Request: testRequest{Method: "PUT", Path: testapi.ResourcePath(getDCResourceName(), ns, "foo"), Query: buildQueryValues(nil)},
|
||||
Response: Response{
|
||||
StatusCode: 200,
|
||||
Body: &api.Daemon{
|
||||
Body: &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
@ -111,7 +112,7 @@ func TestUpdateDaemon(t *testing.T) {
|
||||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Template: &api.PodTemplateSpec{},
|
||||
},
|
||||
},
|
||||
@ -133,14 +134,14 @@ func TestDeleteDaemon(t *testing.T) {
|
||||
|
||||
func TestCreateDaemon(t *testing.T) {
|
||||
ns := api.NamespaceDefault
|
||||
requestController := &api.Daemon{
|
||||
requestController := &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
}
|
||||
c := &testClient{
|
||||
Request: testRequest{Method: "POST", Path: testapi.ResourcePath(getDCResourceName(), ns, ""), Body: requestController, Query: buildQueryValues(nil)},
|
||||
Response: Response{
|
||||
StatusCode: 200,
|
||||
Body: &api.Daemon{
|
||||
Body: &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
@ -148,7 +149,7 @@ func TestCreateDaemon(t *testing.T) {
|
||||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Template: &api.PodTemplateSpec{},
|
||||
},
|
||||
},
|
||||
|
@ -34,6 +34,7 @@ type ExperimentalInterface interface {
|
||||
VersionInterface
|
||||
HorizontalPodAutoscalersNamespacer
|
||||
ScaleNamespacer
|
||||
DaemonsNamespacer
|
||||
}
|
||||
|
||||
// ExperimentalClient is used to interact with experimental Kubernetes features.
|
||||
@ -80,6 +81,10 @@ func (c *ExperimentalClient) Scales(namespace string) ScaleInterface {
|
||||
return newScales(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExperimentalClient) Daemons(namespace string) DaemonInterface {
|
||||
return newDaemons(c, namespace)
|
||||
}
|
||||
|
||||
// NewExperimental creates a new ExperimentalClient for the given config. This client
|
||||
// provides access to experimental Kubernetes features.
|
||||
// Experimental features are not supported and may be changed or removed in
|
||||
|
@ -45,7 +45,6 @@ func TestResourceQuotaCreate(t *testing.T) {
|
||||
api.ResourcePods: resource.MustParse("10"),
|
||||
api.ResourceServices: resource.MustParse("10"),
|
||||
api.ResourceReplicationControllers: resource.MustParse("10"),
|
||||
api.ResourceDaemon: resource.MustParse("10"),
|
||||
api.ResourceQuotas: resource.MustParse("10"),
|
||||
},
|
||||
},
|
||||
@ -78,7 +77,6 @@ func TestResourceQuotaGet(t *testing.T) {
|
||||
api.ResourcePods: resource.MustParse("10"),
|
||||
api.ResourceServices: resource.MustParse("10"),
|
||||
api.ResourceReplicationControllers: resource.MustParse("10"),
|
||||
api.ResourceDaemon: resource.MustParse("10"),
|
||||
api.ResourceQuotas: resource.MustParse("10"),
|
||||
},
|
||||
},
|
||||
@ -135,7 +133,6 @@ func TestResourceQuotaUpdate(t *testing.T) {
|
||||
api.ResourcePods: resource.MustParse("10"),
|
||||
api.ResourceServices: resource.MustParse("10"),
|
||||
api.ResourceReplicationControllers: resource.MustParse("10"),
|
||||
api.ResourceDaemon: resource.MustParse("10"),
|
||||
api.ResourceQuotas: resource.MustParse("10"),
|
||||
},
|
||||
},
|
||||
@ -163,7 +160,6 @@ func TestResourceQuotaStatusUpdate(t *testing.T) {
|
||||
api.ResourcePods: resource.MustParse("10"),
|
||||
api.ResourceServices: resource.MustParse("10"),
|
||||
api.ResourceReplicationControllers: resource.MustParse("10"),
|
||||
api.ResourceDaemon: resource.MustParse("10"),
|
||||
api.ResourceQuotas: resource.MustParse("10"),
|
||||
},
|
||||
},
|
||||
|
@ -17,8 +17,8 @@ limitations under the License.
|
||||
package testclient
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
kClientLib "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
@ -31,40 +31,43 @@ type FakeDaemons struct {
|
||||
Namespace string
|
||||
}
|
||||
|
||||
const (
|
||||
GetDaemonAction = "get-daemon"
|
||||
UpdateDaemonAction = "update-daemon"
|
||||
WatchDaemonAction = "watch-daemon"
|
||||
DeleteDaemonAction = "delete-daemon"
|
||||
ListDaemonAction = "list-daemons"
|
||||
CreateDaemonAction = "create-daemon"
|
||||
)
|
||||
|
||||
// Ensure statically that FakeDaemons implements DaemonInterface.
|
||||
var _ kClientLib.DaemonInterface = &FakeDaemons{}
|
||||
|
||||
func (c *FakeDaemons) Get(name string) (*api.Daemon, error) {
|
||||
obj, err := c.Fake.Invokes(NewGetAction("daemons", c.Namespace, name), &api.Daemon{})
|
||||
return obj.(*api.Daemon), err
|
||||
func (c *FakeDaemons) Get(name string) (*expapi.Daemon, error) {
|
||||
obj, err := c.Fake.Invokes(NewGetAction("daemons", c.Namespace, name), &expapi.Daemon{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*expapi.Daemon), err
|
||||
}
|
||||
|
||||
func (c *FakeDaemons) List(label labels.Selector) (*api.DaemonList, error) {
|
||||
obj, err := c.Fake.Invokes(NewListAction("daemons", c.Namespace, label, nil), &api.DaemonList{})
|
||||
return obj.(*api.DaemonList), err
|
||||
func (c *FakeDaemons) List(label labels.Selector) (*expapi.DaemonList, error) {
|
||||
obj, err := c.Fake.Invokes(NewListAction("daemons", c.Namespace, label, nil), &expapi.DaemonList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*expapi.DaemonList), err
|
||||
}
|
||||
|
||||
func (c *FakeDaemons) Create(daemon *api.Daemon) (*api.Daemon, error) {
|
||||
obj, err := c.Fake.Invokes(NewCreateAction("daemons", c.Namespace, daemon), &api.Daemon{})
|
||||
return obj.(*api.Daemon), err
|
||||
func (c *FakeDaemons) Create(daemon *expapi.Daemon) (*expapi.Daemon, error) {
|
||||
obj, err := c.Fake.Invokes(NewCreateAction("daemons", c.Namespace, daemon), &expapi.Daemon{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*expapi.Daemon), err
|
||||
}
|
||||
|
||||
func (c *FakeDaemons) Update(daemon *api.Daemon) (*api.Daemon, error) {
|
||||
obj, err := c.Fake.Invokes(NewUpdateAction("daemons", c.Namespace, daemon), &api.Daemon{})
|
||||
return obj.(*api.Daemon), err
|
||||
func (c *FakeDaemons) Update(daemon *expapi.Daemon) (*expapi.Daemon, error) {
|
||||
obj, err := c.Fake.Invokes(NewUpdateAction("daemons", c.Namespace, daemon), &expapi.Daemon{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*expapi.Daemon), err
|
||||
}
|
||||
|
||||
func (c *FakeDaemons) Delete(name string) error {
|
||||
_, err := c.Fake.Invokes(NewDeleteAction("daemons", c.Namespace, name), &api.Daemon{})
|
||||
_, err := c.Fake.Invokes(NewDeleteAction("daemons", c.Namespace, name), &expapi.Daemon{})
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -687,6 +687,69 @@ func deepCopy_expapi_APIVersion(in APIVersion, out *APIVersion, c *conversion.Cl
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_expapi_Daemon(in Daemon, out *Daemon, c *conversion.Cloner) error {
|
||||
if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_expapi_DaemonSpec(in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_expapi_DaemonStatus(in.Status, &out.Status, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_expapi_DaemonList(in DaemonList, out *DaemonList, c *conversion.Cloner) error {
|
||||
if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]Daemon, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := deepCopy_expapi_Daemon(in.Items[i], &out.Items[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_expapi_DaemonSpec(in DaemonSpec, out *DaemonSpec, c *conversion.Cloner) error {
|
||||
if in.Selector != nil {
|
||||
out.Selector = make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
out.Selector[key] = val
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.Template != nil {
|
||||
out.Template = new(api.PodTemplateSpec)
|
||||
if err := deepCopy_api_PodTemplateSpec(*in.Template, out.Template, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_expapi_DaemonStatus(in DaemonStatus, out *DaemonStatus, c *conversion.Cloner) error {
|
||||
out.CurrentNumberScheduled = in.CurrentNumberScheduled
|
||||
out.NumberMisscheduled = in.NumberMisscheduled
|
||||
out.DesiredNumberScheduled = in.DesiredNumberScheduled
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_expapi_Deployment(in Deployment, out *Deployment, c *conversion.Cloner) error {
|
||||
if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
@ -1022,6 +1085,10 @@ func init() {
|
||||
deepCopy_api_VolumeSource,
|
||||
deepCopy_resource_Quantity,
|
||||
deepCopy_expapi_APIVersion,
|
||||
deepCopy_expapi_Daemon,
|
||||
deepCopy_expapi_DaemonList,
|
||||
deepCopy_expapi_DaemonSpec,
|
||||
deepCopy_expapi_DaemonStatus,
|
||||
deepCopy_expapi_Deployment,
|
||||
deepCopy_expapi_DeploymentList,
|
||||
deepCopy_expapi_DeploymentSpec,
|
||||
|
@ -36,6 +36,8 @@ func addKnownTypes() {
|
||||
&Scale{},
|
||||
&ThirdPartyResource{},
|
||||
&ThirdPartyResourceList{},
|
||||
&DaemonList{},
|
||||
&Daemon{},
|
||||
)
|
||||
}
|
||||
|
||||
@ -47,3 +49,5 @@ func (*ReplicationControllerDummy) IsAnAPIObject() {}
|
||||
func (*Scale) IsAnAPIObject() {}
|
||||
func (*ThirdPartyResource) IsAnAPIObject() {}
|
||||
func (*ThirdPartyResourceList) IsAnAPIObject() {}
|
||||
func (*Daemon) IsAnAPIObject() {}
|
||||
func (*DaemonList) IsAnAPIObject() {}
|
||||
|
@ -271,3 +271,51 @@ type DeploymentList struct {
|
||||
|
||||
Items []Deployment `json:"items"`
|
||||
}
|
||||
|
||||
// DaemonSpec is the specification of a daemon.
|
||||
type DaemonSpec struct {
|
||||
// Selector is a label query over pods that are managed by the daemon.
|
||||
Selector map[string]string `json:"selector"`
|
||||
|
||||
// Template is the object that describes the pod that will be created.
|
||||
// The Daemon will create exactly one copy of this pod on every node
|
||||
// that matches the template's node selector (or on every node if no node
|
||||
// selector is specified).
|
||||
Template *api.PodTemplateSpec `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonStatus represents the current status of a daemon.
|
||||
type DaemonStatus struct {
|
||||
// CurrentNumberScheduled is the number of nodes that are running exactly 1 copy of the
|
||||
// daemon and are supposed to run the daemon.
|
||||
CurrentNumberScheduled int `json:"currentNumberScheduled"`
|
||||
|
||||
// NumberMisscheduled is the number of nodes that are running the daemon, but are
|
||||
// not supposed to run the daemon.
|
||||
NumberMisscheduled int `json:"numberMisscheduled"`
|
||||
|
||||
// DesiredNumberScheduled is the total number of nodes that should be running the daemon
|
||||
// (including nodes correctly running the daemon).
|
||||
DesiredNumberScheduled int `json:"desiredNumberScheduled"`
|
||||
}
|
||||
|
||||
// Daemon represents the configuration of a daemon.
|
||||
type Daemon struct {
|
||||
api.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the desired behavior of this daemon.
|
||||
Spec DaemonSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current status of this daemon. This data may be
|
||||
// out of date by some window of time.
|
||||
Status DaemonStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonList is a collection of daemon.
|
||||
type DaemonList struct {
|
||||
api.TypeMeta `json:",inline"`
|
||||
api.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []Daemon `json:"items"`
|
||||
}
|
||||
|
@ -1395,6 +1395,81 @@ func convert_expapi_APIVersion_To_v1_APIVersion(in *expapi.APIVersion, out *APIV
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_expapi_Daemon_To_v1_Daemon(in *expapi.Daemon, out *Daemon, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*expapi.Daemon))(in)
|
||||
}
|
||||
if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_expapi_DaemonSpec_To_v1_DaemonSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_expapi_DaemonStatus_To_v1_DaemonStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_expapi_DaemonList_To_v1_DaemonList(in *expapi.DaemonList, out *DaemonList, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*expapi.DaemonList))(in)
|
||||
}
|
||||
if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]Daemon, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := convert_expapi_Daemon_To_v1_Daemon(&in.Items[i], &out.Items[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_expapi_DaemonSpec_To_v1_DaemonSpec(in *expapi.DaemonSpec, out *DaemonSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*expapi.DaemonSpec))(in)
|
||||
}
|
||||
if in.Selector != nil {
|
||||
out.Selector = make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
out.Selector[key] = val
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.Template != nil {
|
||||
out.Template = new(v1.PodTemplateSpec)
|
||||
if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_expapi_DaemonStatus_To_v1_DaemonStatus(in *expapi.DaemonStatus, out *DaemonStatus, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*expapi.DaemonStatus))(in)
|
||||
}
|
||||
out.CurrentNumberScheduled = in.CurrentNumberScheduled
|
||||
out.NumberMisscheduled = in.NumberMisscheduled
|
||||
out.DesiredNumberScheduled = in.DesiredNumberScheduled
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_expapi_Deployment_To_v1_Deployment(in *expapi.Deployment, out *Deployment, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*expapi.Deployment))(in)
|
||||
@ -1737,6 +1812,81 @@ func convert_v1_APIVersion_To_expapi_APIVersion(in *APIVersion, out *expapi.APIV
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_Daemon_To_expapi_Daemon(in *Daemon, out *expapi.Daemon, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*Daemon))(in)
|
||||
}
|
||||
if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_v1_DaemonSpec_To_expapi_DaemonSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_v1_DaemonStatus_To_expapi_DaemonStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_DaemonList_To_expapi_DaemonList(in *DaemonList, out *expapi.DaemonList, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*DaemonList))(in)
|
||||
}
|
||||
if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]expapi.Daemon, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := convert_v1_Daemon_To_expapi_Daemon(&in.Items[i], &out.Items[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_DaemonSpec_To_expapi_DaemonSpec(in *DaemonSpec, out *expapi.DaemonSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*DaemonSpec))(in)
|
||||
}
|
||||
if in.Selector != nil {
|
||||
out.Selector = make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
out.Selector[key] = val
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.Template != nil {
|
||||
out.Template = new(api.PodTemplateSpec)
|
||||
if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_DaemonStatus_To_expapi_DaemonStatus(in *DaemonStatus, out *expapi.DaemonStatus, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*DaemonStatus))(in)
|
||||
}
|
||||
out.CurrentNumberScheduled = in.CurrentNumberScheduled
|
||||
out.NumberMisscheduled = in.NumberMisscheduled
|
||||
out.DesiredNumberScheduled = in.DesiredNumberScheduled
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_Deployment_To_expapi_Deployment(in *Deployment, out *expapi.Deployment, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*Deployment))(in)
|
||||
@ -2107,6 +2257,10 @@ func init() {
|
||||
convert_api_VolumeSource_To_v1_VolumeSource,
|
||||
convert_api_Volume_To_v1_Volume,
|
||||
convert_expapi_APIVersion_To_v1_APIVersion,
|
||||
convert_expapi_DaemonList_To_v1_DaemonList,
|
||||
convert_expapi_DaemonSpec_To_v1_DaemonSpec,
|
||||
convert_expapi_DaemonStatus_To_v1_DaemonStatus,
|
||||
convert_expapi_Daemon_To_v1_Daemon,
|
||||
convert_expapi_DeploymentList_To_v1_DeploymentList,
|
||||
convert_expapi_DeploymentSpec_To_v1_DeploymentSpec,
|
||||
convert_expapi_DeploymentStatus_To_v1_DeploymentStatus,
|
||||
@ -2130,6 +2284,10 @@ func init() {
|
||||
convert_v1_Capabilities_To_api_Capabilities,
|
||||
convert_v1_ContainerPort_To_api_ContainerPort,
|
||||
convert_v1_Container_To_api_Container,
|
||||
convert_v1_DaemonList_To_expapi_DaemonList,
|
||||
convert_v1_DaemonSpec_To_expapi_DaemonSpec,
|
||||
convert_v1_DaemonStatus_To_expapi_DaemonStatus,
|
||||
convert_v1_Daemon_To_expapi_Daemon,
|
||||
convert_v1_DeploymentList_To_expapi_DeploymentList,
|
||||
convert_v1_DeploymentSpec_To_expapi_DeploymentSpec,
|
||||
convert_v1_DeploymentStatus_To_expapi_DeploymentStatus,
|
||||
|
@ -689,6 +689,69 @@ func deepCopy_v1_APIVersion(in APIVersion, out *APIVersion, c *conversion.Cloner
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_Daemon(in Daemon, out *Daemon, c *conversion.Cloner) error {
|
||||
if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_DaemonSpec(in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_DaemonStatus(in.Status, &out.Status, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_DaemonList(in DaemonList, out *DaemonList, c *conversion.Cloner) error {
|
||||
if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]Daemon, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := deepCopy_v1_Daemon(in.Items[i], &out.Items[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_DaemonSpec(in DaemonSpec, out *DaemonSpec, c *conversion.Cloner) error {
|
||||
if in.Selector != nil {
|
||||
out.Selector = make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
out.Selector[key] = val
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.Template != nil {
|
||||
out.Template = new(v1.PodTemplateSpec)
|
||||
if err := deepCopy_v1_PodTemplateSpec(*in.Template, out.Template, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_DaemonStatus(in DaemonStatus, out *DaemonStatus, c *conversion.Cloner) error {
|
||||
out.CurrentNumberScheduled = in.CurrentNumberScheduled
|
||||
out.NumberMisscheduled = in.NumberMisscheduled
|
||||
out.DesiredNumberScheduled = in.DesiredNumberScheduled
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_Deployment(in Deployment, out *Deployment, c *conversion.Cloner) error {
|
||||
if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
@ -1024,6 +1087,10 @@ func init() {
|
||||
deepCopy_v1_VolumeMount,
|
||||
deepCopy_v1_VolumeSource,
|
||||
deepCopy_v1_APIVersion,
|
||||
deepCopy_v1_Daemon,
|
||||
deepCopy_v1_DaemonList,
|
||||
deepCopy_v1_DaemonSpec,
|
||||
deepCopy_v1_DaemonStatus,
|
||||
deepCopy_v1_Deployment,
|
||||
deepCopy_v1_DeploymentList,
|
||||
deepCopy_v1_DeploymentSpec,
|
||||
|
@ -24,5 +24,21 @@ func addDefaultingFuncs() {
|
||||
if len(obj.APIGroup) == 0 {
|
||||
obj.APIGroup = "experimental"
|
||||
}
|
||||
})
|
||||
},
|
||||
func(obj *Daemon) {
|
||||
var labels map[string]string
|
||||
if obj.Spec.Template != nil {
|
||||
labels = obj.Spec.Template.Labels
|
||||
}
|
||||
// TODO: support templates defined elsewhere when we support them in the API
|
||||
if labels != nil {
|
||||
if len(obj.Spec.Selector) == 0 {
|
||||
obj.Spec.Selector = labels
|
||||
}
|
||||
if len(obj.Labels) == 0 {
|
||||
obj.Labels = labels
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
104
pkg/expapi/v1/defaults_test.go
Normal file
104
pkg/expapi/v1/defaults_test.go
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func TestSetDefaultDaemon(t *testing.T) {
|
||||
tests := []struct {
|
||||
dc *Daemon
|
||||
expectLabelsChange bool
|
||||
}{
|
||||
{
|
||||
dc: &Daemon{
|
||||
Spec: DaemonSpec{
|
||||
Template: &v1.PodTemplateSpec{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectLabelsChange: true,
|
||||
},
|
||||
{
|
||||
dc: &Daemon{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"bar": "foo",
|
||||
},
|
||||
},
|
||||
Spec: DaemonSpec{
|
||||
Template: &v1.PodTemplateSpec{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectLabelsChange: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
dc := test.dc
|
||||
obj2 := roundTrip(t, runtime.Object(dc))
|
||||
dc2, ok := obj2.(*Daemon)
|
||||
if !ok {
|
||||
t.Errorf("unexpected object: %v", dc2)
|
||||
t.FailNow()
|
||||
}
|
||||
if test.expectLabelsChange != reflect.DeepEqual(dc2.Labels, dc2.Spec.Template.Labels) {
|
||||
if test.expectLabelsChange {
|
||||
t.Errorf("expected: %v, got: %v", dc2.Spec.Template.Labels, dc2.Labels)
|
||||
} else {
|
||||
t.Errorf("unexpected equality: %v", dc.Labels)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
|
||||
data, err := v1.Codec.Encode(obj)
|
||||
if err != nil {
|
||||
t.Errorf("%v\n %#v", err, obj)
|
||||
return nil
|
||||
}
|
||||
obj2, err := api.Codec.Decode(data)
|
||||
if err != nil {
|
||||
t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj)
|
||||
return nil
|
||||
}
|
||||
obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object)
|
||||
err = api.Scheme.Convert(obj2, obj3)
|
||||
if err != nil {
|
||||
t.Errorf("%v\nSource: %#v", err, obj2)
|
||||
return nil
|
||||
}
|
||||
return obj3
|
||||
}
|
@ -40,6 +40,8 @@ func addKnownTypes() {
|
||||
&Scale{},
|
||||
&ThirdPartyResource{},
|
||||
&ThirdPartyResourceList{},
|
||||
&DaemonList{},
|
||||
&Daemon{},
|
||||
)
|
||||
}
|
||||
|
||||
@ -51,3 +53,5 @@ func (*ReplicationControllerDummy) IsAnAPIObject() {}
|
||||
func (*Scale) IsAnAPIObject() {}
|
||||
func (*ThirdPartyResource) IsAnAPIObject() {}
|
||||
func (*ThirdPartyResourceList) IsAnAPIObject() {}
|
||||
func (*Daemon) IsAnAPIObject() {}
|
||||
func (*DaemonList) IsAnAPIObject() {}
|
||||
|
@ -257,3 +257,64 @@ type DeploymentList struct {
|
||||
|
||||
Items []Deployment `json:"items" description:"list of deployments"`
|
||||
}
|
||||
|
||||
// DaemonSpec is the specification of a daemon.
|
||||
type DaemonSpec struct {
|
||||
// Selector is a label query over pods that are managed by the daemon.
|
||||
// Must match in order to be controlled.
|
||||
// If empty, defaulted to labels on Pod template.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
|
||||
Selector map[string]string `json:"selector,omitempty"`
|
||||
|
||||
// Template is the object that describes the pod that will be created.
|
||||
// The Daemon will create exactly one copy of this pod on every node
|
||||
// that matches the template's node selector (or on every node if no node
|
||||
// selector is specified).
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template
|
||||
Template *v1.PodTemplateSpec `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonStatus represents the current status of a daemon.
|
||||
type DaemonStatus struct {
|
||||
// CurrentNumberScheduled is the number of nodes that are running exactly 1 copy of the
|
||||
// daemon and are supposed to run the daemon.
|
||||
CurrentNumberScheduled int `json:"currentNumberScheduled"`
|
||||
|
||||
// NumberMisscheduled is the number of nodes that are running the daemon, but are
|
||||
// not supposed to run the daemon.
|
||||
NumberMisscheduled int `json:"numberMisscheduled"`
|
||||
|
||||
// DesiredNumberScheduled is the total number of nodes that should be running the daemon
|
||||
// (including nodes correctly running the daemon).
|
||||
DesiredNumberScheduled int `json:"desiredNumberScheduled"`
|
||||
}
|
||||
|
||||
// Daemon represents the configuration of a daemon.
|
||||
type Daemon struct {
|
||||
v1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
v1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the specification of the desired behavior of this daemon.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec DaemonSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current status of this daemon. This data may be
|
||||
// out of date by some window of time.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status DaemonStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonList is a collection of daemon.
|
||||
type DaemonList struct {
|
||||
v1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
v1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is a list of daemons.
|
||||
Items []Daemon `json:"items"`
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
apivalidation "k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
errs "k8s.io/kubernetes/pkg/util/fielderrors"
|
||||
)
|
||||
@ -89,3 +90,69 @@ func ValidateThirdPartyResource(obj *expapi.ThirdPartyResource) errs.ValidationE
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemon tests if required fields in the daemon are set.
|
||||
func ValidateDaemon(controller *expapi.Daemon) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&controller.ObjectMeta, true, apivalidation.ValidateReplicationControllerName).Prefix("metadata")...)
|
||||
allErrs = append(allErrs, ValidateDaemonSpec(&controller.Spec).Prefix("spec")...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemonUpdate tests if required fields in the daemon are set.
|
||||
func ValidateDaemonUpdate(oldController, controller *expapi.Daemon) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta).Prefix("metadata")...)
|
||||
allErrs = append(allErrs, ValidateDaemonSpec(&controller.Spec).Prefix("spec")...)
|
||||
allErrs = append(allErrs, ValidateDaemonTemplateUpdate(oldController.Spec.Template, controller.Spec.Template).Prefix("spec.template")...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemonTemplateUpdate tests that certain fields in the daemon's pod template are not updated.
|
||||
func ValidateDaemonTemplateUpdate(oldPodTemplate, podTemplate *api.PodTemplateSpec) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
podSpec := podTemplate.Spec
|
||||
// podTemplate.Spec is not a pointer, so we can modify NodeSelector and NodeName directly.
|
||||
podSpec.NodeSelector = oldPodTemplate.Spec.NodeSelector
|
||||
podSpec.NodeName = oldPodTemplate.Spec.NodeName
|
||||
// In particular, we do not allow updates to container images at this point.
|
||||
if !api.Semantic.DeepEqual(oldPodTemplate.Spec, podSpec) {
|
||||
// TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("spec", "content of spec is not printed out, please refer to the \"details\"", "may not update fields other than spec.nodeSelector"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemonSpec tests if required fields in the daemon spec are set.
|
||||
func ValidateDaemonSpec(spec *expapi.DaemonSpec) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
|
||||
selector := labels.Set(spec.Selector).AsSelector()
|
||||
if selector.Empty() {
|
||||
allErrs = append(allErrs, errs.NewFieldRequired("selector"))
|
||||
}
|
||||
|
||||
if spec.Template == nil {
|
||||
allErrs = append(allErrs, errs.NewFieldRequired("template"))
|
||||
} else {
|
||||
labels := labels.Set(spec.Template.Labels)
|
||||
if !selector.Matches(labels) {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("template.metadata.labels", spec.Template.Labels, "selector does not match template"))
|
||||
}
|
||||
allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(spec.Template).Prefix("template")...)
|
||||
// Daemons typically run on more than one node, so mark Read-Write persistent disks as invalid.
|
||||
allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(spec.Template.Spec.Volumes).Prefix("template.spec.volumes")...)
|
||||
// RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec().
|
||||
if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways {
|
||||
allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)}))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateDaemonName can be used to check whether the given daemon name is valid.
|
||||
// Prefix indicates this name will be used as part of generation, in which case
|
||||
// trailing dashes are allowed.
|
||||
func ValidateDaemonName(name string, prefix bool) (bool, string) {
|
||||
return apivalidation.NameIsDNSSubdomain(name, prefix)
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
errors "k8s.io/kubernetes/pkg/util/fielderrors"
|
||||
)
|
||||
|
||||
func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
||||
@ -127,3 +128,415 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDaemonUpdate(t *testing.T) {
|
||||
validSelector := map[string]string{"a": "b"}
|
||||
validSelector2 := map[string]string{"c": "d"}
|
||||
invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
|
||||
|
||||
validPodSpecAbc := api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
}
|
||||
validPodSpecDef := api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
}
|
||||
validPodSpecNodeSelector := api.PodSpec{
|
||||
NodeSelector: validSelector,
|
||||
NodeName: "xyz",
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
}
|
||||
validPodSpecVolume := api.PodSpec{
|
||||
Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
}
|
||||
|
||||
validPodTemplateAbc := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
Spec: validPodSpecAbc,
|
||||
},
|
||||
}
|
||||
validPodTemplateNodeSelector := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
Spec: validPodSpecNodeSelector,
|
||||
},
|
||||
}
|
||||
validPodTemplateAbc2 := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector2,
|
||||
},
|
||||
Spec: validPodSpecAbc,
|
||||
},
|
||||
}
|
||||
validPodTemplateDef := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector2,
|
||||
},
|
||||
Spec: validPodSpecDef,
|
||||
},
|
||||
}
|
||||
invalidPodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: invalidSelector,
|
||||
},
|
||||
},
|
||||
}
|
||||
readWriteVolumePodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
Spec: validPodSpecVolume,
|
||||
},
|
||||
}
|
||||
|
||||
type dcUpdateTest struct {
|
||||
old expapi.Daemon
|
||||
update expapi.Daemon
|
||||
}
|
||||
successCases := []dcUpdateTest{
|
||||
{
|
||||
old: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
old: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector2,
|
||||
Template: &validPodTemplateAbc2.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
old: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateNodeSelector.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, successCase := range successCases {
|
||||
successCase.old.ObjectMeta.ResourceVersion = "1"
|
||||
successCase.update.ObjectMeta.ResourceVersion = "1"
|
||||
if errs := ValidateDaemonUpdate(&successCase.old, &successCase.update); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
errorCases := map[string]dcUpdateTest{
|
||||
"change daemon name": {
|
||||
old: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"invalid selector": {
|
||||
old: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: invalidSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"invalid pod": {
|
||||
old: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &invalidPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"change container image": {
|
||||
old: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateDef.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"read-write volume": {
|
||||
old: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplateAbc.Template,
|
||||
},
|
||||
},
|
||||
update: expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &readWriteVolumePodTemplate.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for testName, errorCase := range errorCases {
|
||||
if errs := ValidateDaemonUpdate(&errorCase.old, &errorCase.update); len(errs) == 0 {
|
||||
t.Errorf("expected failure: %s", testName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDaemon(t *testing.T) {
|
||||
validSelector := map[string]string{"a": "b"}
|
||||
validPodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
|
||||
invalidPodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: invalidSelector,
|
||||
},
|
||||
},
|
||||
}
|
||||
successCases := []expapi.Daemon{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc-123", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, successCase := range successCases {
|
||||
if errs := ValidateDaemon(&successCase); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
errorCases := map[string]expapi.Daemon{
|
||||
"zero-length ID": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"missing-namespace": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc-123"},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"empty selector": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"selector_doesnt_match": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"invalid manifest": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
},
|
||||
},
|
||||
"invalid_label": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"invalid_label 2": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Template: &invalidPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"invalid_annotation": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Annotations: map[string]string{
|
||||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
"invalid restart policy 1": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"invalid restart policy 2": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc-123",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: validSelector,
|
||||
Template: &api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validSelector,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, v := range errorCases {
|
||||
errs := ValidateDaemon(&v)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected failure for %s", k)
|
||||
}
|
||||
for i := range errs {
|
||||
field := errs[i].(*errors.ValidationError).Field
|
||||
if !strings.HasPrefix(field, "spec.template.") &&
|
||||
field != "metadata.name" &&
|
||||
field != "metadata.namespace" &&
|
||||
field != "spec.selector" &&
|
||||
field != "spec.template" &&
|
||||
field != "GCEPersistentDisk.ReadOnly" &&
|
||||
field != "spec.template.labels" &&
|
||||
field != "metadata.annotations" &&
|
||||
field != "metadata.labels" {
|
||||
t.Errorf("%s: missing prefix for: %v", k, errs[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/ui"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
||||
daemonetcd "k8s.io/kubernetes/pkg/registry/daemon/etcd"
|
||||
horizontalpodautoscaleretcd "k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
@ -784,12 +785,14 @@ func (m *Master) expapi(c *Config) *apiserver.APIGroupVersion {
|
||||
controllerStorage := expcontrolleretcd.NewStorage(c.ExpDatabaseStorage)
|
||||
autoscalerStorage := horizontalpodautoscaleretcd.NewREST(c.ExpDatabaseStorage)
|
||||
thirdPartyResourceStorage := thirdpartyresourceetcd.NewREST(c.ExpDatabaseStorage)
|
||||
daemonStorage := daemonetcd.NewREST(c.ExpDatabaseStorage)
|
||||
|
||||
storage := map[string]rest.Storage{
|
||||
strings.ToLower("replicationControllers"): controllerStorage.ReplicationController,
|
||||
strings.ToLower("replicationControllers/scale"): controllerStorage.Scale,
|
||||
strings.ToLower("horizontalpodautoscalers"): autoscalerStorage,
|
||||
"thirdpartyresources": thirdPartyResourceStorage,
|
||||
strings.ToLower("thirdpartyresources"): thirdPartyResourceStorage,
|
||||
strings.ToLower("daemons"): daemonStorage,
|
||||
}
|
||||
|
||||
return &apiserver.APIGroupVersion{
|
||||
|
@ -18,6 +18,7 @@ package etcd
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/daemon"
|
||||
@ -39,10 +40,10 @@ var daemonPrefix = "/daemons"
|
||||
// NewREST returns a RESTStorage object that will work against daemons.
|
||||
func NewREST(s storage.Interface) *REST {
|
||||
store := &etcdgeneric.Etcd{
|
||||
NewFunc: func() runtime.Object { return &api.Daemon{} },
|
||||
NewFunc: func() runtime.Object { return &expapi.Daemon{} },
|
||||
|
||||
// NewListFunc returns an object capable of storing results of an etcd list.
|
||||
NewListFunc: func() runtime.Object { return &api.DaemonList{} },
|
||||
NewListFunc: func() runtime.Object { return &expapi.DaemonList{} },
|
||||
// Produces a path that etcd understands, to the root of the resource
|
||||
// by combining the namespace in the context with the given prefix
|
||||
KeyRootFunc: func(ctx api.Context) string {
|
||||
@ -55,7 +56,7 @@ func NewREST(s storage.Interface) *REST {
|
||||
},
|
||||
// Retrieve the name field of a daemon
|
||||
ObjectNameFunc: func(obj runtime.Object) (string, error) {
|
||||
return obj.(*api.Daemon).Name, nil
|
||||
return obj.(*expapi.Daemon).Name, nil
|
||||
},
|
||||
// Used to match objects based on labels/fields for list and watch
|
||||
PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/latest"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
|
||||
@ -46,13 +47,13 @@ func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
}
|
||||
|
||||
// createController is a helper function that returns a controller with the updated resource version.
|
||||
func createController(storage *REST, dc api.Daemon, t *testing.T) (api.Daemon, error) {
|
||||
func createController(storage *REST, dc expapi.Daemon, t *testing.T) (expapi.Daemon, error) {
|
||||
ctx := api.WithNamespace(api.NewContext(), dc.Namespace)
|
||||
obj, err := storage.Create(ctx, &dc)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create controller, %v", err)
|
||||
}
|
||||
newDc := obj.(*api.Daemon)
|
||||
newDc := obj.(*expapi.Daemon)
|
||||
return *newDc, nil
|
||||
}
|
||||
|
||||
@ -75,12 +76,12 @@ var validPodTemplate = api.PodTemplate{
|
||||
},
|
||||
}
|
||||
|
||||
var validControllerSpec = api.DaemonSpec{
|
||||
var validControllerSpec = expapi.DaemonSpec{
|
||||
Selector: validPodTemplate.Template.Labels,
|
||||
Template: &validPodTemplate.Template,
|
||||
}
|
||||
|
||||
var validController = api.Daemon{
|
||||
var validController = expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "default"},
|
||||
Spec: validControllerSpec,
|
||||
}
|
||||
@ -90,8 +91,8 @@ func TestCreate(t *testing.T) {
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test.TestCreate(
|
||||
// valid
|
||||
&api.Daemon{
|
||||
Spec: api.DaemonSpec{
|
||||
&expapi.Daemon{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
@ -103,8 +104,8 @@ func TestCreate(t *testing.T) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.Daemon{
|
||||
Spec: api.DaemonSpec{
|
||||
&expapi.Daemon{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
@ -133,7 +134,7 @@ func TestEtcdGetController(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
controller, ok := ctrl.(*api.Daemon)
|
||||
controller, ok := ctrl.(*expapi.Daemon)
|
||||
if !ok {
|
||||
t.Errorf("Expected a controller, got %#v", ctrl)
|
||||
}
|
||||
@ -151,20 +152,20 @@ func TestEtcdControllerValidatesUpdate(t *testing.T) {
|
||||
t.Errorf("Failed to create controller, cannot proceed with test.")
|
||||
}
|
||||
|
||||
updaters := []func(dc api.Daemon) (runtime.Object, bool, error){
|
||||
func(dc api.Daemon) (runtime.Object, bool, error) {
|
||||
updaters := []func(dc expapi.Daemon) (runtime.Object, bool, error){
|
||||
func(dc expapi.Daemon) (runtime.Object, bool, error) {
|
||||
dc.UID = "newUID"
|
||||
return storage.Update(ctx, &dc)
|
||||
},
|
||||
func(dc api.Daemon) (runtime.Object, bool, error) {
|
||||
func(dc expapi.Daemon) (runtime.Object, bool, error) {
|
||||
dc.Name = ""
|
||||
return storage.Update(ctx, &dc)
|
||||
},
|
||||
func(dc api.Daemon) (runtime.Object, bool, error) {
|
||||
func(dc expapi.Daemon) (runtime.Object, bool, error) {
|
||||
dc.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
||||
return storage.Update(ctx, &dc)
|
||||
},
|
||||
func(dc api.Daemon) (runtime.Object, bool, error) {
|
||||
func(dc expapi.Daemon) (runtime.Object, bool, error) {
|
||||
dc.Spec.Selector = map[string]string{}
|
||||
return storage.Update(ctx, &dc)
|
||||
},
|
||||
@ -224,7 +225,7 @@ func TestEtcdGetControllerDifferentNamespace(t *testing.T) {
|
||||
fakeClient.Set(key2, runtime.EncodeOrDie(latest.Codec, &otherNsController), 0)
|
||||
|
||||
obj, err := storage.Get(ctx1, validController.Name)
|
||||
ctrl1, _ := obj.(*api.Daemon)
|
||||
ctrl1, _ := obj.(*expapi.Daemon)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@ -236,7 +237,7 @@ func TestEtcdGetControllerDifferentNamespace(t *testing.T) {
|
||||
}
|
||||
|
||||
obj, err = storage.Get(ctx2, validController.Name)
|
||||
ctrl2, _ := obj.(*api.Daemon)
|
||||
ctrl2, _ := obj.(*expapi.Daemon)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@ -320,7 +321,7 @@ func TestEtcdListControllers(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
controllers, _ := objList.(*api.DaemonList)
|
||||
controllers, _ := objList.(*expapi.DaemonList)
|
||||
if len(controllers.Items) != 2 || controllers.Items[0].Name != validController.Name || controllers.Items[1].Name != controller.Name {
|
||||
t.Errorf("Unexpected controller list: %#v", controllers)
|
||||
}
|
||||
@ -340,7 +341,7 @@ func TestEtcdListControllersNotFound(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
controllers, _ := objList.(*api.DaemonList)
|
||||
controllers, _ := objList.(*expapi.DaemonList)
|
||||
if len(controllers.Items) != 0 {
|
||||
t.Errorf("Unexpected controller list: %#v", controllers)
|
||||
}
|
||||
@ -376,7 +377,7 @@ func TestEtcdListControllersLabelsMatch(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
controllers, _ := objList.(*api.DaemonList)
|
||||
controllers, _ := objList.(*expapi.DaemonList)
|
||||
if len(controllers.Items) != 1 || controllers.Items[0].Name != controller.Name ||
|
||||
!testLabels.Matches(labels.Set(controllers.Items[0].Labels)) {
|
||||
t.Errorf("Unexpected controller list: %#v for query with labels %#v",
|
||||
@ -430,7 +431,7 @@ func TestEtcdWatchControllersMatch(t *testing.T) {
|
||||
// The watcher above is waiting for these Labels, on receiving them it should
|
||||
// apply the ControllerStatus decorator, which lists pods, causing a query against
|
||||
// the /registry/pods endpoint of the etcd client.
|
||||
controller := &api.Daemon{
|
||||
controller := &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: validController.Spec.Selector,
|
||||
@ -476,13 +477,13 @@ func TestEtcdWatchControllersFields(t *testing.T) {
|
||||
etcdstorage.EtcdCAS,
|
||||
etcdstorage.EtcdDelete}
|
||||
|
||||
controller := &api.Daemon{
|
||||
controller := &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: validController.Spec.Selector,
|
||||
Namespace: "default",
|
||||
},
|
||||
Status: api.DaemonStatus{
|
||||
Status: expapi.DaemonStatus{
|
||||
CurrentNumberScheduled: 2,
|
||||
NumberMisscheduled: 1,
|
||||
DesiredNumberScheduled: 4,
|
||||
@ -549,7 +550,7 @@ func TestEtcdWatchControllersNotMatch(t *testing.T) {
|
||||
}
|
||||
fakeClient.WaitForWatchCompletion()
|
||||
|
||||
controller := &api.Daemon{
|
||||
controller := &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "bar",
|
||||
Labels: map[string]string{
|
||||
|
@ -21,7 +21,8 @@ import (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/expapi/validation"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/generic"
|
||||
@ -45,16 +46,16 @@ func (daemonStrategy) NamespaceScoped() bool {
|
||||
|
||||
// PrepareForCreate clears the status of a daemon before creation.
|
||||
func (daemonStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
daemon := obj.(*api.Daemon)
|
||||
daemon.Status = api.DaemonStatus{}
|
||||
daemon := obj.(*expapi.Daemon)
|
||||
daemon.Status = expapi.DaemonStatus{}
|
||||
|
||||
daemon.Generation = 1
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (daemonStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newDaemon := obj.(*api.Daemon)
|
||||
oldDaemon := old.(*api.Daemon)
|
||||
newDaemon := obj.(*expapi.Daemon)
|
||||
oldDaemon := old.(*expapi.Daemon)
|
||||
|
||||
// Any changes to the spec increment the generation number, any changes to the
|
||||
// status should reflect the generation number of the corresponding object. We push
|
||||
@ -74,7 +75,7 @@ func (daemonStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
|
||||
// Validate validates a new daemon.
|
||||
func (daemonStrategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
daemon := obj.(*api.Daemon)
|
||||
daemon := obj.(*expapi.Daemon)
|
||||
return validation.ValidateDaemon(daemon)
|
||||
}
|
||||
|
||||
@ -86,8 +87,8 @@ func (daemonStrategy) AllowCreateOnUpdate() bool {
|
||||
|
||||
// ValidateUpdate is the default update validation for an end user.
|
||||
func (daemonStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
|
||||
validationErrorList := validation.ValidateDaemon(obj.(*api.Daemon))
|
||||
updateErrorList := validation.ValidateDaemonUpdate(old.(*api.Daemon), obj.(*api.Daemon))
|
||||
validationErrorList := validation.ValidateDaemon(obj.(*expapi.Daemon))
|
||||
updateErrorList := validation.ValidateDaemonUpdate(old.(*expapi.Daemon), obj.(*expapi.Daemon))
|
||||
return append(validationErrorList, updateErrorList...)
|
||||
}
|
||||
|
||||
@ -97,7 +98,7 @@ func (daemonStrategy) AllowUnconditionalUpdate() bool {
|
||||
}
|
||||
|
||||
// DaemonToSelectableFields returns a field set that represents the object.
|
||||
func DaemonToSelectableFields(daemon *api.Daemon) fields.Set {
|
||||
func DaemonToSelectableFields(daemon *expapi.Daemon) fields.Set {
|
||||
return fields.Set{
|
||||
"metadata.name": daemon.Name,
|
||||
}
|
||||
@ -111,7 +112,7 @@ func MatchDaemon(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
Label: label,
|
||||
Field: field,
|
||||
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
daemon, ok := obj.(*api.Daemon)
|
||||
daemon, ok := obj.(*expapi.Daemon)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a daemon.")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user