Example #1
0
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
}
Example #2
0
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
}
Example #3
0
// 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)
		}
	}
}
Example #4
0
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)
}