Update types, add defaulting code, conversions and validation.
This commit is contained in:
		@@ -312,11 +312,11 @@ type DaemonSetUpdateStrategy struct {
 | 
				
			|||||||
	// Type of daemon set update. Only "RollingUpdate" is supported at this time. Default is RollingUpdate.
 | 
						// Type of daemon set update. Only "RollingUpdate" is supported at this time. Default is RollingUpdate.
 | 
				
			||||||
	Type DaemonSetUpdateStrategyType `json:"type,omitempty"`
 | 
						Type DaemonSetUpdateStrategyType `json:"type,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Rolling update config params. Present only if DeploymentStrategyType =
 | 
						// Rolling update config params. Present only if DaemonSetUpdateStrategy =
 | 
				
			||||||
	// RollingUpdate.
 | 
						// RollingUpdate.
 | 
				
			||||||
	//---
 | 
						//---
 | 
				
			||||||
	// TODO: Update this to follow our convention for oneOf, whatever we decide it
 | 
						// TODO: Update this to follow our convention for oneOf, whatever we decide it
 | 
				
			||||||
	// to be. Same as DeploymentStrategy.RollingUpdate
 | 
						// to be. Same as DeploymentStrategy.RollingUpdate.
 | 
				
			||||||
	RollingUpdate *RollingUpdateDaemonSet `json:"rollingUpdate,omitempty"`
 | 
						RollingUpdate *RollingUpdateDaemonSet `json:"rollingUpdate,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -324,7 +324,7 @@ type DaemonSetUpdateStrategyType string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	// Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.
 | 
						// Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.
 | 
				
			||||||
	RollingUpdateDaemonSetUpdateStrategyType DaemonSetUpdateStrategyType = "RollingUpdate"
 | 
						RollingUpdateDaemonSetStrategyType DaemonSetUpdateStrategyType = "RollingUpdate"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Spec to control the desired behavior of daemon set rolling update.
 | 
					// Spec to control the desired behavior of daemon set rolling update.
 | 
				
			||||||
@@ -333,6 +333,7 @@ type RollingUpdateDaemonSet struct {
 | 
				
			|||||||
	// update. Value can be an absolute number (ex: 5) or a percentage of total
 | 
						// update. Value can be an absolute number (ex: 5) or a percentage of total
 | 
				
			||||||
	// number of DaemonSet pods at the start of the update (ex: 10%). Absolute
 | 
						// number of DaemonSet pods at the start of the update (ex: 10%). Absolute
 | 
				
			||||||
	// number is calculated from percentage by rounding up.
 | 
						// number is calculated from percentage by rounding up.
 | 
				
			||||||
 | 
						// This cannot be 0.
 | 
				
			||||||
	// Default value is 1.
 | 
						// Default value is 1.
 | 
				
			||||||
	// Example: when this is set to 30%, 30% of the currently running DaemonSet
 | 
						// Example: when this is set to 30%, 30% of the currently running DaemonSet
 | 
				
			||||||
	// pods can be stopped for an update at any given time. The update starts
 | 
						// pods can be stopped for an update at any given time. The update starts
 | 
				
			||||||
@@ -358,17 +359,33 @@ type DaemonSetSpec struct {
 | 
				
			|||||||
	// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
 | 
						// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
 | 
				
			||||||
	Selector *LabelSelector `json:"selector,omitempty"`
 | 
						Selector *LabelSelector `json:"selector,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The update strategy to use to replace existing DaemonSet with a new one.
 | 
					 | 
				
			||||||
	Strategy DaemonSetUpdateStrategy `json:"strategy,omitempty"`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Template is the object that describes the pod that will be created.
 | 
						// Template is the object that describes the pod that will be created.
 | 
				
			||||||
	// The DaemonSet will create exactly one copy of this pod on every node
 | 
						// The DaemonSet 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
 | 
						// that matches the template's node selector (or on every node if no node
 | 
				
			||||||
	// selector is specified).
 | 
						// selector is specified).
 | 
				
			||||||
	// More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template
 | 
						// More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template
 | 
				
			||||||
	Template *api.PodTemplateSpec `json:"template,omitempty"`
 | 
						Template *api.PodTemplateSpec `json:"template,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Update strategy to replace existing DaemonSet pods with new pods.
 | 
				
			||||||
 | 
						UpdateStrategy DaemonSetUpdateStrategy `json:"updateStrategy,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Label key that is added to DaemonSet pods to distinguish between old and
 | 
				
			||||||
 | 
						// new pod templates during DaemonSet update.
 | 
				
			||||||
 | 
						// Users can set this to an empty string to indicate that the system should
 | 
				
			||||||
 | 
						// not add any label. If unspecified, system uses
 | 
				
			||||||
 | 
						// DefaultDaemonSetUniqueLabelKey("daemonset.kubernetes.io/podTemplateHash").
 | 
				
			||||||
 | 
						// Value of this key is hash of DaemonSetSpec.PodTemplateSpec.
 | 
				
			||||||
 | 
						// No label is added if this is set to empty string.
 | 
				
			||||||
 | 
						UniqueLabelKey string `json:"uniqueLabelKey,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// DefaultDaemonSetUniqueLabelKey is the default key of the labels that is added
 | 
				
			||||||
 | 
						// to daemon set pods to distinguish between old and new pod templates during
 | 
				
			||||||
 | 
						// DaemonSet update. See DaemonSetSpec's UniqueLabelKey field for more information.
 | 
				
			||||||
 | 
						DefaultDaemonSetUniqueLabelKey string = "daemonset.kubernetes.io/podTemplateHash"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DaemonSetStatus represents the current status of a daemon set.
 | 
					// DaemonSetStatus represents the current status of a daemon set.
 | 
				
			||||||
type DaemonSetStatus struct {
 | 
					type DaemonSetStatus struct {
 | 
				
			||||||
	// CurrentNumberScheduled is the number of nodes that are running at least 1
 | 
						// CurrentNumberScheduled is the number of nodes that are running at least 1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,6 +38,12 @@ func addConversionFuncs(scheme *runtime.Scheme) {
 | 
				
			|||||||
		Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy,
 | 
							Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy,
 | 
				
			||||||
		Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment,
 | 
							Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment,
 | 
				
			||||||
		Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment,
 | 
							Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment,
 | 
				
			||||||
 | 
							Convert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec,
 | 
				
			||||||
 | 
							Convert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec,
 | 
				
			||||||
 | 
							Convert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy,
 | 
				
			||||||
 | 
							Convert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy,
 | 
				
			||||||
 | 
							Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet,
 | 
				
			||||||
 | 
							Convert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
@@ -387,3 +393,121 @@ func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *v1.PodSecurityC
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Convert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *extensions.DaemonSetSpec, out *DaemonSetSpec, s conversion.Scope) error {
 | 
				
			||||||
 | 
						if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
 | 
				
			||||||
 | 
							defaulting.(func(*extensions.DaemonSetSpec))(in)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// unable to generate simple pointer conversion for extensions.LabelSelector -> v1beta1.LabelSelector
 | 
				
			||||||
 | 
						if in.Selector != nil {
 | 
				
			||||||
 | 
							out.Selector = new(LabelSelector)
 | 
				
			||||||
 | 
							if err := Convert_extensions_LabelSelector_To_v1beta1_LabelSelector(in.Selector, out.Selector, s); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							out.Selector = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// unable to generate simple pointer conversion for api.PodTemplateSpec -> v1.PodTemplateSpec
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := Convert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out.UniqueLabelKey = new(string)
 | 
				
			||||||
 | 
						*out.UniqueLabelKey = in.UniqueLabelKey
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Convert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error {
 | 
				
			||||||
 | 
						if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
 | 
				
			||||||
 | 
							defaulting.(func(*DaemonSetSpec))(in)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// unable to generate simple pointer conversion for v1beta1.LabelSelector -> extensions.LabelSelector
 | 
				
			||||||
 | 
						if in.Selector != nil {
 | 
				
			||||||
 | 
							out.Selector = new(extensions.LabelSelector)
 | 
				
			||||||
 | 
							if err := Convert_v1beta1_LabelSelector_To_extensions_LabelSelector(in.Selector, out.Selector, s); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							out.Selector = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// unable to generate simple pointer conversion for v1.PodTemplateSpec -> api.PodTemplateSpec
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := Convert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if in.UniqueLabelKey != nil {
 | 
				
			||||||
 | 
							out.UniqueLabelKey = *in.UniqueLabelKey
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Convert_extensions_DaemonSetUpdateStrategy_To_v1beta1_DaemonSetUpdateStrategy(in *extensions.DaemonSetUpdateStrategy, out *DaemonSetUpdateStrategy, s conversion.Scope) error {
 | 
				
			||||||
 | 
						if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
 | 
				
			||||||
 | 
							defaulting.(func(*extensions.DaemonSetUpdateStrategy))(in)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out.Type = DaemonSetUpdateStrategyType(in.Type)
 | 
				
			||||||
 | 
						if in.RollingUpdate != nil {
 | 
				
			||||||
 | 
							out.RollingUpdate = new(RollingUpdateDaemonSet)
 | 
				
			||||||
 | 
							if err := Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							out.RollingUpdate = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Convert_v1beta1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in *DaemonSetUpdateStrategy, out *extensions.DaemonSetUpdateStrategy, s conversion.Scope) error {
 | 
				
			||||||
 | 
						if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
 | 
				
			||||||
 | 
							defaulting.(func(*DaemonSetUpdateStrategy))(in)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out.Type = extensions.DaemonSetUpdateStrategyType(in.Type)
 | 
				
			||||||
 | 
						if in.RollingUpdate != nil {
 | 
				
			||||||
 | 
							out.RollingUpdate = new(extensions.RollingUpdateDaemonSet)
 | 
				
			||||||
 | 
							if err := Convert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in.RollingUpdate, out.RollingUpdate, s); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							out.RollingUpdate = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Convert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *RollingUpdateDaemonSet, s conversion.Scope) error {
 | 
				
			||||||
 | 
						if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
 | 
				
			||||||
 | 
							defaulting.(func(*extensions.RollingUpdateDaemonSet))(in)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if out.MaxUnavailable == nil {
 | 
				
			||||||
 | 
							out.MaxUnavailable = &intstr.IntOrString{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := s.Convert(&in.MaxUnavailable, out.MaxUnavailable, 0); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out.MinReadySeconds = int32(in.MinReadySeconds)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Convert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet(in *RollingUpdateDaemonSet, out *extensions.RollingUpdateDaemonSet, s conversion.Scope) error {
 | 
				
			||||||
 | 
						if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
 | 
				
			||||||
 | 
							defaulting.(func(*RollingUpdateDaemonSet))(in)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out.MinReadySeconds = int(in.MinReadySeconds)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,25 @@ func addDefaultingFuncs(scheme *runtime.Scheme) {
 | 
				
			|||||||
					obj.Labels = labels
 | 
										obj.Labels = labels
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								updateStrategy := &obj.Spec.UpdateStrategy
 | 
				
			||||||
 | 
								if updateStrategy.Type == "" {
 | 
				
			||||||
 | 
									updateStrategy.Type = RollingUpdateDaemonSetStrategyType
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if updateStrategy.Type == RollingUpdateDaemonSetStrategyType {
 | 
				
			||||||
 | 
									if updateStrategy.RollingUpdate == nil {
 | 
				
			||||||
 | 
										rollingUpdate := RollingUpdateDaemonSet{}
 | 
				
			||||||
 | 
										updateStrategy.RollingUpdate = &rollingUpdate
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if updateStrategy.RollingUpdate.MaxUnavailable == nil {
 | 
				
			||||||
 | 
										// Set default MaxUnavailable as 1 by default.
 | 
				
			||||||
 | 
										maxUnavailable := intstr.FromInt(1)
 | 
				
			||||||
 | 
										updateStrategy.RollingUpdate.MaxUnavailable = &maxUnavailable
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if obj.Spec.UniqueLabelKey == nil {
 | 
				
			||||||
 | 
									obj.Spec.UniqueLabelKey = new(string)
 | 
				
			||||||
 | 
									*obj.Spec.UniqueLabelKey = DefaultDaemonSetUniqueLabelKey
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		func(obj *Deployment) {
 | 
							func(obj *Deployment) {
 | 
				
			||||||
			// Default labels and selector to labels from pod template spec.
 | 
								// Default labels and selector to labels from pod template spec.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,59 +30,155 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestSetDefaultDaemonSet(t *testing.T) {
 | 
					func TestSetDefaultDaemonSet(t *testing.T) {
 | 
				
			||||||
	tests := []struct {
 | 
						defaultIntOrString := intstr.FromInt(1)
 | 
				
			||||||
		ds                 *DaemonSet
 | 
						defaultLabels := map[string]string{"foo": "bar"}
 | 
				
			||||||
		expectLabelsChange bool
 | 
						period := int64(v1.DefaultTerminationGracePeriodSeconds)
 | 
				
			||||||
	}{
 | 
						defaultTemplate := &v1.PodTemplateSpec{
 | 
				
			||||||
		{
 | 
							Spec: v1.PodSpec{
 | 
				
			||||||
			ds: &DaemonSet{
 | 
								DNSPolicy:                     v1.DNSClusterFirst,
 | 
				
			||||||
				Spec: DaemonSetSpec{
 | 
								RestartPolicy:                 v1.RestartPolicyAlways,
 | 
				
			||||||
					Template: &v1.PodTemplateSpec{
 | 
								SecurityContext:               &v1.PodSecurityContext{},
 | 
				
			||||||
 | 
								TerminationGracePeriodSeconds: &period,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		ObjectMeta: v1.ObjectMeta{
 | 
							ObjectMeta: v1.ObjectMeta{
 | 
				
			||||||
							Labels: map[string]string{
 | 
								Labels: defaultLabels,
 | 
				
			||||||
								"foo": "bar",
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							original *DaemonSet
 | 
				
			||||||
 | 
							expected *DaemonSet
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{ // Labels change/defaulting test.
 | 
				
			||||||
 | 
								original: &DaemonSet{
 | 
				
			||||||
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
 | 
										Template: defaultTemplate,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: &DaemonSet{
 | 
				
			||||||
 | 
									ObjectMeta: v1.ObjectMeta{
 | 
				
			||||||
 | 
										Labels: defaultLabels,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
 | 
										Selector: &LabelSelector{
 | 
				
			||||||
 | 
											MatchLabels: defaultLabels,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										Template: defaultTemplate,
 | 
				
			||||||
 | 
										UpdateStrategy: DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											Type: RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
											RollingUpdate: &RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
												MaxUnavailable: &defaultIntOrString,
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										UniqueLabelKey: newString(DefaultDaemonSetUniqueLabelKey),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
				},
 | 
							{ // Labels change/defaulting test.
 | 
				
			||||||
			},
 | 
								original: &DaemonSet{
 | 
				
			||||||
			expectLabelsChange: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			ds: &DaemonSet{
 | 
					 | 
				
			||||||
				ObjectMeta: v1.ObjectMeta{
 | 
									ObjectMeta: v1.ObjectMeta{
 | 
				
			||||||
					Labels: map[string]string{
 | 
										Labels: map[string]string{
 | 
				
			||||||
						"bar": "foo",
 | 
											"bar": "foo",
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Spec: DaemonSetSpec{
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
					Template: &v1.PodTemplateSpec{
 | 
										Template: defaultTemplate,
 | 
				
			||||||
 | 
										UpdateStrategy: DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											Type: RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
											RollingUpdate: &RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
												MaxUnavailable: &defaultIntOrString,
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: &DaemonSet{
 | 
				
			||||||
				ObjectMeta: v1.ObjectMeta{
 | 
									ObjectMeta: v1.ObjectMeta{
 | 
				
			||||||
					Labels: map[string]string{
 | 
										Labels: map[string]string{
 | 
				
			||||||
								"foo": "bar",
 | 
											"bar": "foo",
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
 | 
										Selector: &LabelSelector{
 | 
				
			||||||
 | 
											MatchLabels: defaultLabels,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										Template: defaultTemplate,
 | 
				
			||||||
 | 
										UpdateStrategy: DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											Type: RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
											RollingUpdate: &RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
												MaxUnavailable: &defaultIntOrString,
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										UniqueLabelKey: newString(DefaultDaemonSetUniqueLabelKey),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{ // Update strategy.
 | 
				
			||||||
 | 
								original: &DaemonSet{},
 | 
				
			||||||
 | 
								expected: &DaemonSet{
 | 
				
			||||||
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
 | 
										UpdateStrategy: DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											Type: RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
											RollingUpdate: &RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
												MaxUnavailable: &defaultIntOrString,
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										UniqueLabelKey: newString(DefaultDaemonSetUniqueLabelKey),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{ // Update strategy.
 | 
				
			||||||
 | 
								original: &DaemonSet{
 | 
				
			||||||
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
 | 
										UpdateStrategy: DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											RollingUpdate: &RollingUpdateDaemonSet{},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: &DaemonSet{
 | 
				
			||||||
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
 | 
										UpdateStrategy: DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											Type: RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
											RollingUpdate: &RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
												MaxUnavailable: &defaultIntOrString,
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										UniqueLabelKey: newString(DefaultDaemonSetUniqueLabelKey),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{ // Custom unique label key.
 | 
				
			||||||
 | 
								original: &DaemonSet{
 | 
				
			||||||
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
 | 
										UpdateStrategy: DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											RollingUpdate: &RollingUpdateDaemonSet{},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										UniqueLabelKey: newString("customDaemonSetKey"),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: &DaemonSet{
 | 
				
			||||||
 | 
									Spec: DaemonSetSpec{
 | 
				
			||||||
 | 
										UpdateStrategy: DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											Type: RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
											RollingUpdate: &RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
												MaxUnavailable: &defaultIntOrString,
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										UniqueLabelKey: newString("customDaemonSetKey"),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			expectLabelsChange: false,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, test := range tests {
 | 
						for i, test := range tests {
 | 
				
			||||||
		ds := test.ds
 | 
							original := test.original
 | 
				
			||||||
		obj2 := roundTrip(t, runtime.Object(ds))
 | 
							expected := test.expected
 | 
				
			||||||
		ds2, ok := obj2.(*DaemonSet)
 | 
							obj2 := roundTrip(t, runtime.Object(original))
 | 
				
			||||||
 | 
							got, ok := obj2.(*DaemonSet)
 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			t.Errorf("unexpected object: %v", ds2)
 | 
								t.Errorf("(%d) unexpected object: %v", i, got)
 | 
				
			||||||
			t.FailNow()
 | 
								t.FailNow()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if test.expectLabelsChange != reflect.DeepEqual(ds2.Labels, ds2.Spec.Template.Labels) {
 | 
							if !reflect.DeepEqual(got.Spec, expected.Spec) {
 | 
				
			||||||
			if test.expectLabelsChange {
 | 
								t.Errorf("(%d) got different than expected\ngot:\n\t%+v\nexpected:\n\t%+v", i, got.Spec, expected.Spec)
 | 
				
			||||||
				t.Errorf("expected: %v, got: %v", ds2.Spec.Template.Labels, ds2.Labels)
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				t.Errorf("unexpected equality: %v", ds.Labels)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -302,11 +302,11 @@ type DaemonSetUpdateStrategy struct {
 | 
				
			|||||||
	// Type of daemon set update. Only "RollingUpdate" is supported at this time. Default is RollingUpdate.
 | 
						// Type of daemon set update. Only "RollingUpdate" is supported at this time. Default is RollingUpdate.
 | 
				
			||||||
	Type DaemonSetUpdateStrategyType `json:"type,omitempty"`
 | 
						Type DaemonSetUpdateStrategyType `json:"type,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Rolling update config params. Present only if DeploymentStrategyType =
 | 
						// Rolling update config params. Present only if DaemonSetUpdateStrategy =
 | 
				
			||||||
	// RollingUpdate.
 | 
						// RollingUpdate.
 | 
				
			||||||
	//---
 | 
						//---
 | 
				
			||||||
	// TODO: Update this to follow our convention for oneOf, whatever we decide it
 | 
						// TODO: Update this to follow our convention for oneOf, whatever we decide it
 | 
				
			||||||
	// to be. Same as DeploymentStrategy.RollingUpdate
 | 
						// to be. Same as DeploymentStrategy.RollingUpdate.
 | 
				
			||||||
	RollingUpdate *RollingUpdateDaemonSet `json:"rollingUpdate,omitempty"`
 | 
						RollingUpdate *RollingUpdateDaemonSet `json:"rollingUpdate,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -314,7 +314,7 @@ type DaemonSetUpdateStrategyType string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	// Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.
 | 
						// Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.
 | 
				
			||||||
	RollingUpdateDaemonSetUpdateStrategyType DaemonSetUpdateStrategyType = "RollingUpdate"
 | 
						RollingUpdateDaemonSetStrategyType DaemonSetUpdateStrategyType = "RollingUpdate"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Spec to control the desired behavior of daemon set rolling update.
 | 
					// Spec to control the desired behavior of daemon set rolling update.
 | 
				
			||||||
@@ -323,6 +323,7 @@ type RollingUpdateDaemonSet struct {
 | 
				
			|||||||
	// update. Value can be an absolute number (ex: 5) or a percentage of total
 | 
						// update. Value can be an absolute number (ex: 5) or a percentage of total
 | 
				
			||||||
	// number of DaemonSet pods at the start of the update (ex: 10%). Absolute
 | 
						// number of DaemonSet pods at the start of the update (ex: 10%). Absolute
 | 
				
			||||||
	// number is calculated from percentage by rounding up.
 | 
						// number is calculated from percentage by rounding up.
 | 
				
			||||||
 | 
						// This cannot be 0.
 | 
				
			||||||
	// Default value is 1.
 | 
						// Default value is 1.
 | 
				
			||||||
	// Example: when this is set to 30%, 30% of the currently running DaemonSet
 | 
						// Example: when this is set to 30%, 30% of the currently running DaemonSet
 | 
				
			||||||
	// pods can be stopped for an update at any given time. The update starts
 | 
						// pods can be stopped for an update at any given time. The update starts
 | 
				
			||||||
@@ -348,17 +349,33 @@ type DaemonSetSpec struct {
 | 
				
			|||||||
	// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
 | 
						// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
 | 
				
			||||||
	Selector *LabelSelector `json:"selector,omitempty"`
 | 
						Selector *LabelSelector `json:"selector,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The update strategy to use to replace existing DaemonSet with a new one.
 | 
					 | 
				
			||||||
	Strategy DaemonSetUpdateStrategy `json:"strategy,omitempty"`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Template is the object that describes the pod that will be created.
 | 
						// Template is the object that describes the pod that will be created.
 | 
				
			||||||
	// The DaemonSet will create exactly one copy of this pod on every node
 | 
						// The DaemonSet 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
 | 
						// that matches the template's node selector (or on every node if no node
 | 
				
			||||||
	// selector is specified).
 | 
						// selector is specified).
 | 
				
			||||||
	// More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template
 | 
						// More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template
 | 
				
			||||||
	Template *v1.PodTemplateSpec `json:"template,omitempty"`
 | 
						Template *v1.PodTemplateSpec `json:"template,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Update strategy to replace existing DaemonSet pods with new pods.
 | 
				
			||||||
 | 
						UpdateStrategy DaemonSetUpdateStrategy `json:"updateStrategy,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Label key that is added to DaemonSet pods to distinguish between old and
 | 
				
			||||||
 | 
						// new pod templates during DaemonSet update.
 | 
				
			||||||
 | 
						// Users can set this to an empty string to indicate that the system should
 | 
				
			||||||
 | 
						// not add any label. If unspecified, system uses
 | 
				
			||||||
 | 
						// DefaultDaemonSetUniqueLabelKey("daemonset.kubernetes.io/podTemplateHash").
 | 
				
			||||||
 | 
						// Value of this key is hash of DaemonSetSpec.PodTemplateSpec.
 | 
				
			||||||
 | 
						// No label is added if this is set to empty string.
 | 
				
			||||||
 | 
						UniqueLabelKey *string `json:"uniqueLabelKey,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// DefaultDaemonSetUniqueLabelKey is the default key of the labels that is added
 | 
				
			||||||
 | 
						// to daemon set pods to distinguish between old and new pod templates during
 | 
				
			||||||
 | 
						// DaemonSet update. See DaemonSetSpec's UniqueLabelKey field for more information.
 | 
				
			||||||
 | 
						DefaultDaemonSetUniqueLabelKey string = "daemonset.kubernetes.io/podTemplateHash"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DaemonSetStatus represents the current status of a daemon set.
 | 
					// DaemonSetStatus represents the current status of a daemon set.
 | 
				
			||||||
type DaemonSetStatus struct {
 | 
					type DaemonSetStatus struct {
 | 
				
			||||||
	// CurrentNumberScheduled is the number of nodes that are running at least 1
 | 
						// CurrentNumberScheduled is the number of nodes that are running at least 1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -179,17 +179,46 @@ func ValidateDaemonSetTemplateUpdate(podTemplate, oldPodTemplate *api.PodTemplat
 | 
				
			|||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ValidateRollingUpdateDaemonSet(rollingUpdate *extensions.RollingUpdateDaemonSet, fldPath *field.Path) field.ErrorList {
 | 
				
			||||||
 | 
						allErrs := field.ErrorList{}
 | 
				
			||||||
 | 
						allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
 | 
				
			||||||
 | 
						if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 {
 | 
				
			||||||
 | 
							// MaxUnavailable cannot be 0.
 | 
				
			||||||
 | 
							allErrs = append(allErrs, field.Invalid(fldPath.Child("maxUnavailable"), rollingUpdate.MaxUnavailable, "cannot be 0"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Validate that MaxUnavailable is not more than 100%.
 | 
				
			||||||
 | 
						allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
 | 
				
			||||||
 | 
						allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(rollingUpdate.MinReadySeconds), fldPath.Child("minReadySeconds"))...)
 | 
				
			||||||
 | 
						return allErrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ValidateDaemonSetUpdateStrategy(strategy *extensions.DaemonSetUpdateStrategy, fldPath *field.Path) field.ErrorList {
 | 
				
			||||||
 | 
						allErrs := field.ErrorList{}
 | 
				
			||||||
 | 
						// Only rolling update is supported at this time.
 | 
				
			||||||
 | 
						if strategy.Type != extensions.RollingUpdateDaemonSetStrategyType {
 | 
				
			||||||
 | 
							allErrs = append(allErrs, field.Invalid(fldPath.Child("type"), strategy.Type, "RollingUpdate is the only supported type"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Make sure RollingUpdate field isn't nil.
 | 
				
			||||||
 | 
						if strategy.RollingUpdate == nil {
 | 
				
			||||||
 | 
							allErrs = append(allErrs, field.Required(fldPath.Child("rollingUpdate"), ""))
 | 
				
			||||||
 | 
							return allErrs
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						allErrs = append(allErrs, ValidateRollingUpdateDaemonSet(strategy.RollingUpdate, fldPath.Child("rollingUpdate"))...)
 | 
				
			||||||
 | 
						return allErrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set.
 | 
					// ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set.
 | 
				
			||||||
func ValidateDaemonSetSpec(spec *extensions.DaemonSetSpec, fldPath *field.Path) field.ErrorList {
 | 
					func ValidateDaemonSetSpec(spec *extensions.DaemonSetSpec, fldPath *field.Path) field.ErrorList {
 | 
				
			||||||
	allErrs := field.ErrorList{}
 | 
						allErrs := field.ErrorList{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	allErrs = append(allErrs, ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...)
 | 
						// The order of these checks is important because spec.Template is tested for nil value here
 | 
				
			||||||
 | 
						// before accessing its labels in the following check.
 | 
				
			||||||
	if spec.Template == nil {
 | 
						if spec.Template == nil {
 | 
				
			||||||
		allErrs = append(allErrs, field.Required(fldPath.Child("template"), ""))
 | 
							allErrs = append(allErrs, field.Required(fldPath.Child("template"), ""))
 | 
				
			||||||
		return allErrs
 | 
							return allErrs
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						allErrs = append(allErrs, ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...)
 | 
				
			||||||
	selector, err := extensions.LabelSelectorAsSelector(spec.Selector)
 | 
						selector, err := extensions.LabelSelectorAsSelector(spec.Selector)
 | 
				
			||||||
	if err == nil && !selector.Matches(labels.Set(spec.Template.Labels)) {
 | 
						if err == nil && !selector.Matches(labels.Set(spec.Template.Labels)) {
 | 
				
			||||||
		allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "metadata", "labels"), spec.Template.Labels, "`selector` does not match template `labels`"))
 | 
							allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "metadata", "labels"), spec.Template.Labels, "`selector` does not match template `labels`"))
 | 
				
			||||||
@@ -203,6 +232,8 @@ func ValidateDaemonSetSpec(spec *extensions.DaemonSetSpec, fldPath *field.Path)
 | 
				
			|||||||
		allErrs = append(allErrs, field.NotSupported(fldPath.Child("template", "spec", "restartPolicy"), spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)}))
 | 
							allErrs = append(allErrs, field.NotSupported(fldPath.Child("template", "spec", "restartPolicy"), spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)}))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						allErrs = append(allErrs, ValidateDaemonSetUpdateStrategy(&spec.UpdateStrategy, fldPath.Child("updateStrategy"))...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -283,6 +283,13 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
	validSelector2 := map[string]string{"c": "d"}
 | 
						validSelector2 := map[string]string{"c": "d"}
 | 
				
			||||||
	invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
 | 
						invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						validUpdateStrategy := extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
							Type: extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
							RollingUpdate: &extensions.RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
								MaxUnavailable: intstr.FromInt(1),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	validPodSpecAbc := api.PodSpec{
 | 
						validPodSpecAbc := api.PodSpec{
 | 
				
			||||||
		RestartPolicy: api.RestartPolicyAlways,
 | 
							RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
		DNSPolicy:     api.DNSClusterFirst,
 | 
							DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
@@ -370,6 +377,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			update: extensions.DaemonSet{
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
@@ -377,6 +385,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -386,6 +395,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			update: extensions.DaemonSet{
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
@@ -393,6 +403,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector2},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector2},
 | 
				
			||||||
					Template:       &validPodTemplateAbc2.Template,
 | 
										Template:       &validPodTemplateAbc2.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -402,6 +413,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			update: extensions.DaemonSet{
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
@@ -409,6 +421,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateNodeSelector.Template,
 | 
										Template:       &validPodTemplateNodeSelector.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -427,6 +440,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			update: extensions.DaemonSet{
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
@@ -434,6 +448,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -443,6 +458,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			update: extensions.DaemonSet{
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
@@ -450,6 +466,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: invalidSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: invalidSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -459,6 +476,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			update: extensions.DaemonSet{
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
@@ -466,6 +484,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &invalidPodTemplate.Template,
 | 
										Template:       &invalidPodTemplate.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -475,6 +494,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			update: extensions.DaemonSet{
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
@@ -482,6 +502,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateDef.Template,
 | 
										Template:       &validPodTemplateDef.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -491,6 +512,7 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &validPodTemplateAbc.Template,
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			update: extensions.DaemonSet{
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
@@ -498,6 +520,28 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
				Spec: extensions.DaemonSetSpec{
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
					Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
					Template:       &readWriteVolumePodTemplate.Template,
 | 
										Template:       &readWriteVolumePodTemplate.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"invalid update strategy": {
 | 
				
			||||||
 | 
								old: extensions.DaemonSet{
 | 
				
			||||||
 | 
									ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
 | 
				
			||||||
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
										Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
 | 
										Template:       &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								update: extensions.DaemonSet{
 | 
				
			||||||
 | 
									ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
				
			||||||
 | 
									Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
										Selector: &extensions.LabelSelector{MatchLabels: invalidSelector},
 | 
				
			||||||
 | 
										Template: &validPodTemplateAbc.Template,
 | 
				
			||||||
 | 
										UpdateStrategy: extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
											Type:          extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
											RollingUpdate: nil,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -511,6 +555,12 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestValidateDaemonSet(t *testing.T) {
 | 
					func TestValidateDaemonSet(t *testing.T) {
 | 
				
			||||||
	validSelector := map[string]string{"a": "b"}
 | 
						validSelector := map[string]string{"a": "b"}
 | 
				
			||||||
 | 
						validUpdateStrategy := extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
							Type: extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
							RollingUpdate: &extensions.RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
								MaxUnavailable: intstr.FromInt(1),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	validPodTemplate := api.PodTemplate{
 | 
						validPodTemplate := api.PodTemplate{
 | 
				
			||||||
		Template: api.PodTemplateSpec{
 | 
							Template: api.PodTemplateSpec{
 | 
				
			||||||
			ObjectMeta: api.ObjectMeta{
 | 
								ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
@@ -541,6 +591,7 @@ func TestValidateDaemonSet(t *testing.T) {
 | 
				
			|||||||
			Spec: extensions.DaemonSetSpec{
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
				Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
									Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
				Template:       &validPodTemplate.Template,
 | 
									Template:       &validPodTemplate.Template,
 | 
				
			||||||
 | 
									UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -548,6 +599,7 @@ func TestValidateDaemonSet(t *testing.T) {
 | 
				
			|||||||
			Spec: extensions.DaemonSetSpec{
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
				Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
									Selector:       &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
				Template:       &validPodTemplate.Template,
 | 
									Template:       &validPodTemplate.Template,
 | 
				
			||||||
 | 
									UpdateStrategy: validUpdateStrategy,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -585,7 +637,7 @@ func TestValidateDaemonSet(t *testing.T) {
 | 
				
			|||||||
				Template: &validPodTemplate.Template,
 | 
									Template: &validPodTemplate.Template,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"invalid manifest": {
 | 
							"invalid template": {
 | 
				
			||||||
			ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
								ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
				
			||||||
			Spec: extensions.DaemonSetSpec{
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
				Selector: &extensions.LabelSelector{MatchLabels: validSelector},
 | 
									Selector: &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
@@ -667,6 +719,104 @@ func TestValidateDaemonSet(t *testing.T) {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							"invalid update strategy - Type is not RollingUpdate": {
 | 
				
			||||||
 | 
								ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
									Name:      "abc-123",
 | 
				
			||||||
 | 
									Namespace: api.NamespaceDefault,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
									Selector: &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
 | 
									Template: &validPodTemplate.Template,
 | 
				
			||||||
 | 
									UpdateStrategy: extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
										Type: "",
 | 
				
			||||||
 | 
										RollingUpdate: &extensions.RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
											MaxUnavailable: intstr.FromInt(1),
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"invalid update strategy - RollingUpdate field is nil": {
 | 
				
			||||||
 | 
								ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
									Name:      "abc-123",
 | 
				
			||||||
 | 
									Namespace: api.NamespaceDefault,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
									Selector: &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
 | 
									Template: &validPodTemplate.Template,
 | 
				
			||||||
 | 
									UpdateStrategy: extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
										Type:          extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
										RollingUpdate: nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"invalid update strategy - MaxUnavailable is 0": {
 | 
				
			||||||
 | 
								ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
									Name:      "abc-123",
 | 
				
			||||||
 | 
									Namespace: api.NamespaceDefault,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
									Selector: &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
 | 
									Template: &validPodTemplate.Template,
 | 
				
			||||||
 | 
									UpdateStrategy: extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
										Type: extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
										RollingUpdate: &extensions.RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
											MaxUnavailable:  intstr.FromInt(0),
 | 
				
			||||||
 | 
											MinReadySeconds: 1,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"invalid update strategy - MaxUnavailable is greater than 100%": {
 | 
				
			||||||
 | 
								ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
									Name:      "abc-123",
 | 
				
			||||||
 | 
									Namespace: api.NamespaceDefault,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
									Selector: &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
 | 
									Template: &validPodTemplate.Template,
 | 
				
			||||||
 | 
									UpdateStrategy: extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
										Type: extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
										RollingUpdate: &extensions.RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
											MaxUnavailable:  intstr.FromString("150%"),
 | 
				
			||||||
 | 
											MinReadySeconds: 1,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"invalid update strategy - MaxUnavailable is negative": {
 | 
				
			||||||
 | 
								ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
									Name:      "abc-123",
 | 
				
			||||||
 | 
									Namespace: api.NamespaceDefault,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
									Selector: &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
 | 
									Template: &validPodTemplate.Template,
 | 
				
			||||||
 | 
									UpdateStrategy: extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
										Type: extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
										RollingUpdate: &extensions.RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
											MaxUnavailable:  intstr.FromInt(-1),
 | 
				
			||||||
 | 
											MinReadySeconds: 0,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"invalid update strategy - MinReadySeconds is negative": {
 | 
				
			||||||
 | 
								ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
									Name:      "abc-123",
 | 
				
			||||||
 | 
									Namespace: api.NamespaceDefault,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
									Selector: &extensions.LabelSelector{MatchLabels: validSelector},
 | 
				
			||||||
 | 
									Template: &validPodTemplate.Template,
 | 
				
			||||||
 | 
									UpdateStrategy: extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
										Type: extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
										RollingUpdate: &extensions.RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
											MaxUnavailable:  intstr.FromInt(-1),
 | 
				
			||||||
 | 
											MinReadySeconds: -1,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for k, v := range errorCases {
 | 
						for k, v := range errorCases {
 | 
				
			||||||
		errs := ValidateDaemonSet(&v)
 | 
							errs := ValidateDaemonSet(&v)
 | 
				
			||||||
@@ -676,6 +826,7 @@ func TestValidateDaemonSet(t *testing.T) {
 | 
				
			|||||||
		for i := range errs {
 | 
							for i := range errs {
 | 
				
			||||||
			field := errs[i].Field
 | 
								field := errs[i].Field
 | 
				
			||||||
			if !strings.HasPrefix(field, "spec.template.") &&
 | 
								if !strings.HasPrefix(field, "spec.template.") &&
 | 
				
			||||||
 | 
									!strings.HasPrefix(field, "spec.updateStrategy") &&
 | 
				
			||||||
				field != "metadata.name" &&
 | 
									field != "metadata.name" &&
 | 
				
			||||||
				field != "metadata.namespace" &&
 | 
									field != "metadata.namespace" &&
 | 
				
			||||||
				field != "spec.selector" &&
 | 
									field != "spec.selector" &&
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,7 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/registry/registrytest"
 | 
						"k8s.io/kubernetes/pkg/registry/registrytest"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
						"k8s.io/kubernetes/pkg/runtime"
 | 
				
			||||||
	etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
 | 
						etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/util/intstr"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
 | 
					func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
 | 
				
			||||||
@@ -59,6 +60,13 @@ func newValidDaemonSet() *extensions.DaemonSet {
 | 
				
			|||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
								UpdateStrategy: extensions.DaemonSetUpdateStrategy{
 | 
				
			||||||
 | 
									Type: extensions.RollingUpdateDaemonSetStrategyType,
 | 
				
			||||||
 | 
									RollingUpdate: &extensions.RollingUpdateDaemonSet{
 | 
				
			||||||
 | 
										MaxUnavailable: intstr.FromInt(1),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								UniqueLabelKey: "foo-label",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -81,6 +89,14 @@ func TestCreate(t *testing.T) {
 | 
				
			|||||||
				Template: validDaemonSet.Spec.Template,
 | 
									Template: validDaemonSet.Spec.Template,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							// invalid update strategy
 | 
				
			||||||
 | 
							&extensions.DaemonSet{
 | 
				
			||||||
 | 
								Spec: extensions.DaemonSetSpec{
 | 
				
			||||||
 | 
									Selector:       validDaemonSet.Spec.Selector,
 | 
				
			||||||
 | 
									Template:       validDaemonSet.Spec.Template,
 | 
				
			||||||
 | 
									UniqueLabelKey: validDaemonSet.Spec.UniqueLabelKey,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -118,6 +134,11 @@ func TestUpdate(t *testing.T) {
 | 
				
			|||||||
			object.Spec.Selector = &extensions.LabelSelector{MatchLabels: map[string]string{}}
 | 
								object.Spec.Selector = &extensions.LabelSelector{MatchLabels: map[string]string{}}
 | 
				
			||||||
			return object
 | 
								return object
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							func(obj runtime.Object) runtime.Object {
 | 
				
			||||||
 | 
								object := obj.(*extensions.DaemonSet)
 | 
				
			||||||
 | 
								object.Spec.UpdateStrategy = extensions.DaemonSetUpdateStrategy{}
 | 
				
			||||||
 | 
								return object
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user