//ValidEntity used to make sure AddressAssignment is in a valid state 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 }
//ValidEntity validate that Service has all required fields 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)) } } if vErr.HasError() { return vErr } return nil }
//ValidEntity validates Host fields func (h *Host) ValidEntity() error { glog.V(4).Info("Validating host") //if err := validation.ValidHostID(entity.ID); err != nil { // return fmt.Errorf("invalid hostid:'%s' for host Name:'%s' IP:%s", entity.ID, entity.Name, entity.IPAddr) //} trimmedID := strings.TrimSpace(h.ID) violations := validation.NewValidationError() violations.Add(validation.NotEmpty("Host.ID", h.ID)) violations.Add(validation.ValidHostID(h.ID)) violations.Add(validation.StringsEqual(h.ID, trimmedID, "leading and trailing spaces not allowed for host id")) violations.Add(validation.ValidPort(h.RPCPort)) violations.Add(validation.NotEmpty("Host.PoolID", h.PoolID)) violations.Add(validation.IsIP(h.IPAddr)) //TODO: what should we be validating here? It doesn't seem to work for glog.V(4).Infof("Validating IPAddr %v for host %s", h.IPAddr, h.ID) ipAddr, err := net.ResolveIPAddr("ip4", h.IPAddr) if err != nil { glog.Errorf("Could not resolve: %s to an ip4 address: %v", h.IPAddr, err) violations.Add(err) } else if ipAddr.IP.IsLoopback() { glog.Errorf("Can not use %s as host address because it is a loopback address", h.IPAddr) violations.Add(errors.New("host ip can not be a loopback address")) } if len(violations.Errors) > 0 { return violations } return nil }
func (ss ServiceState) ValidEntity() error { vErr := validation.NewValidationError() vErr.Add(validation.NotEmpty("ID", ss.ID)) vErr.Add(validation.NotEmpty("ServiceID", ss.ServiceID)) vErr.Add(validation.NotEmpty("HostID", ss.HostID)) if vErr.HasError() { return vErr } return nil }
//ValidEntity makes sure all serviceTemplateWrapper have non-empty values func (st *serviceTemplateWrapper) ValidEntity() error { v := validation.NewValidationError() v.Add(validation.NotEmpty("ID", st.ID)) v.Add(validation.NotEmpty("Name", st.Name)) v.Add(validation.NotEmpty("Data", st.Data)) if v.HasError() { return v } return nil }
//SetItem adds or replaces the VhostEndpoint to the key in registry. Returns the path of the node in the registry func (vr *VhostRegistry) SetItem(conn client.Connection, key string, node VhostEndpoint) (string, error) { verr := validation.NewValidationError() verr.Add(validation.NotEmpty("ServiceID", node.ServiceID)) verr.Add(validation.NotEmpty("EndpointName", node.EndpointName)) if verr.HasError() { return "", verr } nodeID := fmt.Sprintf("%s_%s", node.ServiceID, node.EndpointName) return vr.setItem(conn, key, nodeID, &node) }
// validateEndpointNode validates EndpointNode func validateEndpointNode(node EndpointNode) error { verr := validation.NewValidationError() verr.Add(validation.NotEmpty("ServiceID", node.ServiceID)) verr.Add(validation.NotEmpty("TenantID", node.TenantID)) verr.Add(validation.NotEmpty("EndpointID", node.EndpointID)) verr.Add(validation.NotEmpty("ContainerID", node.ContainerID)) verr.Add(validation.NotEmpty("HostID", node.HostID)) if verr.HasError() { return verr } return nil }
//ValidEntity validates Host fields func (u *User) ValidEntity() error { glog.V(4).Info("Validating User") trimmed := strings.TrimSpace(u.Name) violations := validation.NewValidationError() violations.Add(validation.NotEmpty("User.Name", u.Name)) violations.Add(validation.StringsEqual(u.Name, trimmed, "leading and trailing spaces not allowed for user name")) violations.Add(validation.NotEmpty("User.Password", u.Password)) if len(violations.Errors) > 0 { return violations } return nil }
//ValidEntity validates Host fields func (p *ResourcePool) ValidEntity() error { glog.V(4).Info("Validating ResourcePool") trimmedID := strings.TrimSpace(p.ID) violations := validation.NewValidationError() violations.Add(validation.NotEmpty("Pool.ID", p.ID)) violations.Add(validation.StringsEqual(p.ID, trimmedID, "leading and trailing spaces not allowed for pool id")) trimmedRealm := strings.TrimSpace(p.Realm) violations.Add(validation.NotEmpty("Pool.Realm", p.Realm)) violations.Add(validation.StringsEqual(p.Realm, trimmedRealm, "leading and trailing spaces not allowed for pool realm")) if len(violations.Errors) > 0 { return violations } return nil }
//ValidEntity check if fields are valid func (scf SvcConfigFile) ValidEntity() error { vErr := validation.NewValidationError() vErr.Add(validation.NotEmpty("ID", scf.ID)) vErr.Add(validation.NotEmpty("ServiceTenantID", scf.ServiceTenantID)) vErr.Add(validation.NotEmpty("ServicePath", scf.ServicePath)) //path must start with / if !strings.HasPrefix(scf.ServicePath, "/") { vErr.AddViolation("field ServicePath must start with /") } vErr.Add(validation.NotEmpty("Content", scf.ConfFile.Content)) vErr.Add(validation.NotEmpty("FileName", scf.ConfFile.Filename)) if vErr.HasError() { return vErr } return nil }
// ValidEntity ensure that a ServiceTemplate has valid values func (st *ServiceTemplate) ValidEntity() error { // trimmedID := strings.TrimSpace(st.ID) violations := validation.NewValidationError() violations.Add(validation.NotEmpty("ServiceTemplate.ID", st.ID)) // violations.Add(validation.StringsEqual(st.ID, trimmedID, "leading and trailing spaces not allowed for service template id")) //TODO: check name, description, config files. //TODO: do servicedefinition names need to be unique? //TODO: Is there any special validation if more than one top level service definition? for _, sd := range st.Services { if err := sd.ValidEntity(); err != nil { violations.Add(err) } } //keep track of seen vhosts vhosts := make(map[string]struct{}) //grab the vhost from every endpoing visit := func(sd *servicedefinition.ServiceDefinition) error { for _, ep := range sd.Endpoints { for _, vhost := range ep.VHosts { if _, found := vhosts[vhost]; found { return fmt.Errorf("duplicate vhost found: %s; ServiceDefintion %s", vhost, sd) } vhosts[vhost] = struct{}{} } } return nil } for _, sd := range st.Services { violations.Add(servicedefinition.Walk(&sd, visit)) } if len(violations.Errors) > 0 { return violations } return nil }