func validateObject(obj interface{}) (errors []error) { switch t := obj.(type) { case *api.ReplicationController: errors = api.ValidateManifest(&t.DesiredState.PodTemplate.DesiredState.Manifest) case *api.ReplicationControllerList: for i := range t.Items { errors = append(errors, validateObject(&t.Items[i])...) } case *api.Service: errors = api.ValidateService(t) case *api.ServiceList: for i := range t.Items { errors = append(errors, validateObject(&t.Items[i])...) } case *api.Pod: errors = api.ValidateManifest(&t.DesiredState.Manifest) case *api.PodList: for i := range t.Items { errors = append(errors, validateObject(&t.Items[i])...) } default: return []error{fmt.Errorf("no validation defined for %#v", obj)} } return errors }
func ValidatePod(pod *Pod) (errors []error) { if !util.IsDNSSubdomain(pod.Name) { errors = append(errors, apierrs.NewInvalid("Pod.Name", pod.Name)) } if errs := api.ValidateManifest(&pod.Manifest); len(errs) != 0 { errors = append(errors, errs...) } return errors }
// syncLoop is the main loop for processing changes. It watches for changes from // four channels (file, etcd, server, and http) and creates a union of them. For // any new change seen, will run a sync against desired state and running state. If // no changes are seen to the configuration, will synchronize the last known desired // state every sync_frequency seconds. // Never returns. func (kl *Kubelet) syncLoop(updateChannel <-chan manifestUpdate, handler SyncHandler) { last := make(map[string][]api.ContainerManifest) for { select { case u := <-updateChannel: glog.Infof("Got configuration from %s: %+v", u.source, u.manifests) last[u.source] = u.manifests case <-time.After(kl.SyncFrequency): } allManifests := []api.ContainerManifest{} allIds := util.StringSet{} for src, srcManifests := range last { for i := range srcManifests { allErrs := []error{} m := &srcManifests[i] if allIds.Has(m.ID) { allErrs = append(allErrs, api.ValidationError{api.ErrTypeDuplicate, "ContainerManifest.ID", m.ID}) } else { allIds.Insert(m.ID) } if errs := api.ValidateManifest(m); len(errs) != 0 { allErrs = append(allErrs, errs...) } // Check for host-wide HostPort conflicts. if errs := checkHostPortConflicts(allManifests, m); len(errs) != 0 { allErrs = append(allErrs, errs...) } if len(allErrs) > 0 { glog.Warningf("Manifest from %s failed validation, ignoring: %v", src, allErrs) } } // TODO(thockin): There's no reason to collect manifests by value. Don't pessimize. allManifests = append(allManifests, srcManifests...) } err := handler.SyncManifests(allManifests) if err != nil { glog.Errorf("Couldn't sync containers : %v", err) } } }
func (s *SourceURL) extractFromURL() error { resp, err := http.Get(s.url) if err != nil { return err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { return err } if len(data) == 0 { return fmt.Errorf("zero-length data received from %v", s.url) } // First try as if it's a single manifest var manifest api.ContainerManifest singleErr := yaml.Unmarshal(data, &manifest) if singleErr == nil { if errs := api.ValidateManifest(&manifest); len(errs) > 0 { singleErr = fmt.Errorf("invalid manifest: %v", errs) } } if singleErr == nil { pod := kubelet.Pod{Name: manifest.ID, Manifest: manifest} if pod.Name == "" { pod.Name = "1" } s.updates <- kubelet.PodUpdate{[]kubelet.Pod{pod}, kubelet.SET} return nil } // That didn't work, so try an array of manifests. var manifests []api.ContainerManifest multiErr := yaml.Unmarshal(data, &manifests) // We're not sure if the person reading the logs is going to care about the single or // multiple manifest unmarshalling attempt, so we need to put both in the logs, as is // done at the end. Hence not returning early here. if multiErr == nil { for _, manifest := range manifests { if errs := api.ValidateManifest(&manifest); len(errs) > 0 { multiErr = fmt.Errorf("invalid manifest: %v", errs) break } } } if multiErr == nil { pods := []kubelet.Pod{} for i, manifest := range manifests { pod := kubelet.Pod{Name: manifest.ID, Manifest: manifest} if pod.Name == "" { pod.Name = fmt.Sprintf("%d", i+1) } pods = append(pods, pod) } s.updates <- kubelet.PodUpdate{pods, kubelet.SET} return nil } return fmt.Errorf("%v: received '%v', but couldn't parse as a "+ "single manifest (%v: %+v) or as multiple manifests (%v: %+v).\n", s.url, string(data), singleErr, manifest, multiErr, manifests) }