WIP: First cut at input validation for Kubelet

* Add some util functions for basic validation
* Spec api fields more tightly
* Break a dep from util -> api, so I can do the reverse
* Add functions to validate structures
* Call those functions when running manifests

This does not validate as it unmarshals YAML or JSON because I want to be able
to validate structures that come from other inputs without forcing them to be
YAML.

This does not handle all api structures - I am not familiar wnough with the
rest to spec them this tightly - I hope someone else can do that.

There are a number of open questions, marked "FIXME".  Please offer feedback
or opinions.
Do we have any sort of feedback-to-master channel?  The kubelet server
seems to be write-only, and we don't have an etcd protocol for publishing
results (yet).  Should w eblock this change on that?


On Sat, Jun 28, 2014 at 1:17 PM, Daniel Smith <notifications@github.com>
wrote:

> In pkg/kubelet/kubelet.go:
>
> > @@ -726,12 +726,18 @@ func (kl *Kubelet) RunSyncLoop(updateChannel <-chan manifestUpdate, handler Sync
> >  		case <-time.After(kl.SyncFrequency):
> >  		}
> >
> > -		manifests := []api.ContainerManifest{}
> > -		for _, m := range last {
> > -			manifests = append(manifests, m...)
> > +		allManifests := []api.ContainerManifest{}
> > +		for src, manifests := range last {
> > +			for _, m := range manifests {
> > +				if err := api.ValidateManifest(&m); err != nil {
>
> That SGTM.
> ... <#146e420389dac00d_>
> On Jun 28, 2014 1:13 PM, "Tim Hockin" <notifications@github.com> wrote:
> In pkg/kubelet/kubelet.go: > @@ -726,12 +726,18 @@ func (kl *Kubelet)
> RunSyncLoop(updateChannel <-chan manifestUpdate, handler Sync > case
> <-time.After(kl.SyncFrequency): > } > > - manifests :=
> []api.ContainerManifest{} > - for _, m := range last { > - manifests =
> append(manifests, m...) > + allManifests := []api.ContainerManifest{} > +
> for src, manifests := range last { > + for _, m := range manifests { > + if
> err := api.ValidateManifest(&m); err != nil { This is a really good point.
> Since we don't have a synchronous API, maybe we should accept pods and
> immediately put them into an "invalid" state. What do you think? ...
> <#146e41c340d5e510_> On Sat, Jun 28, 2014 at 11:39 AM, Daniel Smith <
> notifications@github.com> wrote: In pkg/kubelet/kubelet.go: > @@ -726,12
> +726,18 @@ func (kl *Kubelet) RunSyncLoop(updateChannel <-chan
> manifestUpdate, handler Sync > case <-time.After(kl.SyncFrequency): > } > >
> - manifests := []api.ContainerManifest{} > - for _, m := range last { > -
> manifests = append(manifests, m...) > + allManifests :=
> []api.ContainerManifest{} > + for src, manifests := range last { > + for _,
> m := range manifests { > + if err := api.ValidateManifest(&m); err != nil {
> We should check both places. My concern with it as written is that kubelet
> silently drops the pod, at least from apiserver's perspective. We need a
> mechanism for kubelet to formally reject a pod, because right now the
> apiserver is just going to think it's reallllllly slow at starting the pod.
> -- Reply to this email directly or view it on GitHub <
> https://github.com/GoogleCloudPlatform/kubernetes/pull/280/files#r14325483>
> . -- Reply to this email directly or view it on GitHub <
> https://github.com/GoogleCloudPlatform/kubernetes/pull/280/files#r14325943>
> .
>
> --
> Reply to this email directly or view it on GitHub
> <https://github.com/GoogleCloudPlatform/kubernetes/pull/280/files#r14325955>
> .
>