// Validation for Service ServiceDetails entity
439376
func (d *ServiceDetails) ValidEntity() error {
	violations := validation.NewValidationError()
	violations.Add(validation.NotEmpty("ID", d.ID))
	violations.Add(validation.NotEmpty("Name", d.Name))
	violations.Add(validation.NotEmpty("PoolID", d.PoolID))
	violations.Add(d.InstanceLimits.Validate())
	if d.Instances != 0 {
		if d.InstanceLimits.Max != 0 {
			if d.Instances < d.InstanceLimits.Min || d.Instances > d.InstanceLimits.Max {
				violations.Add(fmt.Errorf("Instance count (%d) must be in InstanceLimits range [%d-%d]", d.Instances, d.InstanceLimits.Min, d.InstanceLimits.Max))
			}
		} else if d.Instances < d.InstanceLimits.Min {
			violations.Add(fmt.Errorf("Instance count (%d) must be greater than InstanceLimits min %d", d.Instances, d.InstanceLimits.Min))
		}
	}

	if len(violations.Errors) > 0 {
		return violations
	}

	return nil
}
1334581
func (v KnownServiceValue) Validate() error {
	switch v {
	case SSHRule, JujuControllerRule, JujuApplicationOfferRule:
		return nil
	}
	return errors.NotValidf("known service %q", v)
}
625648
func (s *Service) ValidEntity() error {

	vErr := validation.NewValidationError()
	vErr.Add(validation.NotEmpty("ID", s.ID))
	vErr.Add(validation.NotEmpty("Name", s.Name))
	vErr.Add(validation.NotEmpty("PoolID", s.PoolID))

	vErr.Add(validation.StringIn(s.Launch, commons.AUTO, commons.MANUAL))
	vErr.Add(validation.IntIn(s.DesiredState, int(SVCRun), int(SVCStop), int(SVCPause)))

	// Validate the min/max/default instances
	vErr.Add(s.InstanceLimits.Validate())
	if s.Instances != 0 {
		if s.InstanceLimits.Max != 0 {
			if s.Instances < s.InstanceLimits.Min || s.Instances > s.InstanceLimits.Max {
				vErr.Add(fmt.Errorf("Instance count (%d) must be in InstanceLimits range [%d-%d]", s.Instances, s.InstanceLimits.Min, s.InstanceLimits.Max))
			}
		} else if s.Instances < s.InstanceLimits.Min {
			vErr.Add(fmt.Errorf("Instance count (%d) must be greater than InstanceLimits min %d", s.Instances, s.InstanceLimits.Min))
		}
	}

	// validate the monitoring profile
	vErr.Add(s.MonitoringProfile.ValidEntity())

	for _, ep := range s.Endpoints {
		vErr.Add(ep.ValidEntity())
	}

	for _, hc := range s.HealthChecks {
		vErr.Add(hc.ValidEntity())
	}

	if vErr.HasError() {
		return vErr
	}
	return nil
}
215854
func Service() (c *ServiceController) {
	return &ServiceController{
		List:       serviceList,
		Detail:     serviceDetail,
		Raw:        serviceRaw,
		Logs:       serviceLogs,
		FetchLogs:  serviceFetchLogs,
		Delete:     serviceDelete,
		New:        serviceNew,
		Create:     serviceCreate,
		Edit:       serviceEdit,
		Update:     serviceUpdate,
		Scale:      serviceScale,
		Rollback:   serviceRollback,
		Restart:    serviceRestart,
		PermEdit:   servicePermEdit,
		PermUpdate: permUpdate("service", "name"),
		Stats:      serviceStats,
	}
}
215814
func ValidateServiceUpdate(service, oldService *core.Service) field.ErrorList {
	allErrs := ValidateObjectMetaUpdate(&service.ObjectMeta, &oldService.ObjectMeta, field.NewPath("metadata"))

	// ClusterIP should be immutable for services using it (every type other than ExternalName)
	// which do not have ClusterIP assigned yet (empty string value)
	if service.Spec.Type != core.ServiceTypeExternalName {
		if oldService.Spec.Type != core.ServiceTypeExternalName && oldService.Spec.ClusterIP != "" {
			allErrs = append(allErrs, ValidateImmutableField(service.Spec.ClusterIP, oldService.Spec.ClusterIP, field.NewPath("spec", "clusterIP"))...)
		}
	}

	allErrs = append(allErrs, ValidateService(service)...)
	return allErrs
}
1137199
func (f *Facade) validateServiceMigration(ctx datastore.Context, svcs []service.Service, tenantID string) error {
	svcParentMapNameMap := make(map[string]map[string]struct{})
	endpointMap := make(map[string]string)
	for _, svc := range svcs {
		// check for name uniqueness within the set of new/modified/deployed services
		if svcNameMap, ok := svcParentMapNameMap[svc.ParentServiceID]; ok {
			if _, ok := svcNameMap[svc.Name]; ok {
				glog.Errorf("Found a collision for service name %s and parent %s", svc.Name, svc.ParentServiceID)
				return ErrServiceCollision
			}
			svcParentMapNameMap[svc.ParentServiceID][svc.Name] = struct{}{}
		} else {
			svcParentMapNameMap[svc.ParentServiceID] = make(map[string]struct{})
		}

		// check for endpoint name uniqueness within the set of new/modified/deployed services
		for _, ep := range svc.Endpoints {
			if ep.Purpose == "export" {
				if _, ok := endpointMap[ep.Application]; ok {
					glog.Errorf("Endpoint %s in migrated service %s is a duplicate of an endpoint in one of the other migrated services", ep.Application, svc.Name)
					return ErrServiceDuplicateEndpoint
				}
				endpointMap[ep.Application] = svc.ID
			}
		}
	}

	// check for endpoint name uniqueness btwn the migrated service and the services already defined in
	// the parent application.
	alleps, err := f.GetServiceExportedEndpoints(ctx, tenantID, true)
	if err != nil {
		glog.Errorf("Error looking up exported endpoints for tenant %s: %s", tenantID, err)
		return err
	}
	for _, ep := range alleps {
		if _, ok := endpointMap[ep.Application]; ok {
			if ep.ServiceID != endpointMap[ep.Application] {
				glog.Errorf("Endpoint %s in migrated service is a duplicate of an endpoint already in the application", ep.Application)
				return ErrServiceDuplicateEndpoint
			}
		}
	}

	return nil
}
1148359
func ValidateService(service *api.Service) field.ErrorList {
	allErrs := ValidateObjectMeta(&service.ObjectMeta, true, ValidateServiceName, field.NewPath("metadata"))

	specPath := field.NewPath("spec")
	if len(service.Spec.Ports) == 0 && service.Spec.ClusterIP != api.ClusterIPNone {
		allErrs = append(allErrs, field.Required(specPath.Child("ports"), ""))
	}
	if service.Spec.Type == api.ServiceTypeLoadBalancer {
		for ix := range service.Spec.Ports {
			port := &service.Spec.Ports[ix]
			// This is a workaround for broken cloud environments that
			// over-open firewalls.  Hopefully it can go away when more clouds
			// understand containers better.
			if port.Port == 10250 {
				portPath := specPath.Child("ports").Index(ix)
				allErrs = append(allErrs, field.Invalid(portPath, port.Port, "may not expose port 10250 externally since it is used by kubelet"))
			}
		}
	}

	isHeadlessService := service.Spec.ClusterIP == api.ClusterIPNone
	allPortNames := sets.String{}
	portsPath := specPath.Child("ports")
	for i := range service.Spec.Ports {
		portPath := portsPath.Index(i)
		allErrs = append(allErrs, validateServicePort(&service.Spec.Ports[i], len(service.Spec.Ports) > 1, isHeadlessService, &allPortNames, portPath)...)
	}

	if service.Spec.Selector != nil {
		allErrs = append(allErrs, ValidateLabels(service.Spec.Selector, specPath.Child("selector"))...)
	}

	if len(service.Spec.SessionAffinity) == 0 {
		allErrs = append(allErrs, field.Required(specPath.Child("sessionAffinity"), ""))
	} else if !supportedSessionAffinityType.Has(string(service.Spec.SessionAffinity)) {
		allErrs = append(allErrs, field.NotSupported(specPath.Child("sessionAffinity"), service.Spec.SessionAffinity, supportedSessionAffinityType.List()))
	}

	if api.IsServiceIPSet(service) {
		if ip := net.ParseIP(service.Spec.ClusterIP); ip == nil {
			allErrs = append(allErrs, field.Invalid(specPath.Child("clusterIP"), service.Spec.ClusterIP, "must be empty, 'None', or a valid IP address"))
		}
	}

	ipPath := specPath.Child("externalIPs")
	for i, ip := range service.Spec.ExternalIPs {
		idxPath := ipPath.Index(i)
		if ip == "0.0.0.0" {
			allErrs = append(allErrs, field.Invalid(idxPath, ip, "must be a valid IP address"))
		}
		allErrs = append(allErrs, validateIpIsNotLinkLocalOrLoopback(ip, idxPath)...)
	}

	if len(service.Spec.Type) == 0 {
		allErrs = append(allErrs, field.Required(specPath.Child("type"), ""))
	} else if !supportedServiceType.Has(string(service.Spec.Type)) {
		allErrs = append(allErrs, field.NotSupported(specPath.Child("type"), service.Spec.Type, supportedServiceType.List()))
	}

	if service.Spec.Type == api.ServiceTypeLoadBalancer {
		portsPath := specPath.Child("ports")
		includeProtocols := sets.NewString()
		for i := range service.Spec.Ports {
			portPath := portsPath.Index(i)
			if !supportedPortProtocols.Has(string(service.Spec.Ports[i].Protocol)) {
				allErrs = append(allErrs, field.Invalid(portPath.Child("protocol"), service.Spec.Ports[i].Protocol, "cannot create an external load balancer with non-TCP/UDP ports"))
			} else {
				includeProtocols.Insert(string(service.Spec.Ports[i].Protocol))
			}
		}
		if includeProtocols.Len() > 1 {
			allErrs = append(allErrs, field.Invalid(portsPath, service.Spec.Ports, "cannot create an external load balancer with mix protocols"))
		}
	}

	if service.Spec.Type == api.ServiceTypeClusterIP {
		portsPath := specPath.Child("ports")
		for i := range service.Spec.Ports {
			portPath := portsPath.Index(i)
			if service.Spec.Ports[i].NodePort != 0 {
				allErrs = append(allErrs, field.Invalid(portPath.Child("nodePort"), service.Spec.Ports[i].NodePort, "may not be used when `type` is 'ClusterIP'"))
			}
		}
	}

	// Check for duplicate NodePorts, considering (protocol,port) pairs
	portsPath = specPath.Child("ports")
	nodePorts := make(map[api.ServicePort]bool)
	for i := range service.Spec.Ports {
		port := &service.Spec.Ports[i]
		if port.NodePort == 0 {
			continue
		}
		portPath := portsPath.Index(i)
		var key api.ServicePort
		key.Protocol = port.Protocol
		key.NodePort = port.NodePort
		_, found := nodePorts[key]
		if found {
			allErrs = append(allErrs, field.Duplicate(portPath.Child("nodePort"), port.NodePort))
		}
		nodePorts[key] = true
	}

	return allErrs
}
439679
func (f *Facade) GetEvaluatedService(ctx datastore.Context, serviceID string, instanceID int) (*service.Service, error) {
	defer ctx.Metrics().Stop(ctx.Metrics().Start("Facade.GetEvaluatedService"))
	logger := plog.WithFields(log.Fields{
		"serviceID":  serviceID,
		"instanceID": instanceID,
	})
	logger.Debug("Started Facade.GetEvaluatedService")
	defer logger.Debug("Finished Facade.GetEvaluatedService")

	svc, err := f.GetService(ctx, serviceID)
	if err != nil {
		return nil, err
	}

	if err := f.evaluateService(ctx, svc, instanceID); err != nil {
		return nil, err
	}
	return svc, nil
}
1325313
func (s Service) Validate(renderer shell.Renderer) error {
	if s.Name == "" {
		return errors.New("missing Name")
	}

	if err := s.Conf.Validate(renderer); err != nil {
		return errors.Trace(err)
	}

	return nil
}
223025
func (a *AddressAssignment) ValidEntity() error {
	v := validation.NewValidationError()
	v.Add(validation.NotEmpty("ServiceID", a.ServiceID))
	v.Add(validation.NotEmpty("EndpointName", a.EndpointName))
	v.Add(validation.IsIP(a.IPAddr))
	v.Add(validation.ValidPort(int(a.Port)))
	switch a.AssignmentType {
	case commons.STATIC:
		{
			v.Add(validation.NotEmpty("HostID", a.HostID))
		}
	case commons.VIRTUAL:
		{
			v.Add(validation.NotEmpty("PoolID", a.PoolID))
		}
	default:
		return fmt.Errorf("assignment type must be static of virtual, found %v", a.AssignmentType)
	}

	if v.HasError() {
		return v
	}
	return nil
}
405164
func (c *ServicedCli) services() (data []string) {
	svcs, err := c.driver.GetAllServiceDetails()
	if err != nil || svcs == nil || len(svcs) == 0 {
		c.exit(1)
		return
	}

	data = make([]string, len(svcs))
	for i, s := range svcs {
		data[i] = s.ID
	}

	return
}
440863
func ValidateServiceAccount(serviceAccount *core.ServiceAccount) field.ErrorList {
	allErrs := ValidateObjectMeta(&serviceAccount.ObjectMeta, true, ValidateServiceAccountName, field.NewPath("metadata"))
	return allErrs
}
1233402
func ValidServiceName(service string) error {
	// Blank service names are not allowed.
	if service == "" {
		return ErrUnsetService
	}

	// Service names must consist of the characters [a-z0-9-]
	for _, r := range service {
		if (r < 'a' || r > 'z') && (r < '0' || r > '9') && r != '-' {
			return ErrInvalidService
		}
	}

	return nil
}
1048199
func (f *Facade) validateServiceDeployment(ctx datastore.Context, parentID string, sd *servicedefinition.ServiceDefinition) ([]service.Service, error) {
	store := f.serviceStore
	parent, err := store.Get(ctx, parentID)
	if err != nil {
		glog.Errorf("Could not get parent service %s: %s", parentID, err)
		return nil, err
	}
	// recursively create services
	var deployServices func(*service.Service, *servicedefinition.ServiceDefinition) ([]service.Service, error)
	deployServices = func(parent *service.Service, sd *servicedefinition.ServiceDefinition) ([]service.Service, error) {
		var svcs []service.Service
		svc, err := service.BuildService(*sd, parent.ID, parent.PoolID, int(service.SVCStop), parent.DeploymentID)
		if err != nil {
			glog.Errorf("Could not create service %s: %s", sd.Name, err)
			return nil, err
		}
		// Evaluate templated endpoints
		if err = f.evaluateEndpointTemplates(ctx, svc); err != nil {
			return nil, err
		}

		svcs = append(svcs, *svc)
		for _, sdSvc := range sd.Services {
			childsvcs, err := deployServices(svc, &sdSvc)
			if err != nil {
				return nil, err
			}
			svcs = append(svcs, childsvcs...)
		}
		return svcs, nil
	}
	return deployServices(parent, sd)
}
641201
func ValidateServiceUpdate(service, oldService *api.Service) field.ErrorList {
	allErrs := ValidateObjectMetaUpdate(&service.ObjectMeta, &oldService.ObjectMeta, field.NewPath("metadata"))

	if api.IsServiceIPSet(oldService) {
		allErrs = append(allErrs, ValidateImmutableField(service.Spec.ClusterIP, oldService.Spec.ClusterIP, field.NewPath("spec", "clusterIP"))...)
	}

	allErrs = append(allErrs, ValidateService(service)...)
	return allErrs
}
912508
func (c *ServicedCli) serviceActions(id string) (data []string) {
	svc, err := c.driver.GetService(id)
	if err != nil || svc == nil {
		c.exit(1)
		return
	}

	data = make([]string, len(svc.Actions))
	i := 0
	for a := range svc.Actions {
		data[i] = a
		i++
	}

	return
}
32318
func (s *Service) Validate() error {
	var mErr multierror.Error

	// Ensure the service name is valid per the below RFCs but make an exception
	// for our interpolation syntax by first stripping any environment variables from the name

	serviceNameStripped := args.ReplaceEnvWithPlaceHolder(s.Name, "ENV-VAR")

	if err := s.ValidateName(serviceNameStripped); err != nil {
		mErr.Errors = append(mErr.Errors, fmt.Errorf("service name must be valid per RFC 1123 and can contain only alphanumeric characters or dashes: %q", s.Name))
	}

	switch s.AddressMode {
	case "", AddressModeAuto, AddressModeHost, AddressModeDriver:
		// OK
	default:
		mErr.Errors = append(mErr.Errors, fmt.Errorf("service address_mode must be %q, %q, or %q; not %q", AddressModeAuto, AddressModeHost, AddressModeDriver, s.AddressMode))
	}

	for _, c := range s.Checks {
		if s.PortLabel == "" && c.PortLabel == "" && c.RequiresPort() {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("check %s invalid: check requires a port but neither check nor service %+q have a port", c.Name, s.Name))
			continue
		}

		if err := c.validate(); err != nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("check %s invalid: %v", c.Name, err))
		}
	}

	return mErr.ErrorOrNil()
}