//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 used to make sure AddressResourceConfig is in a valid state func (arc AddressResourceConfig) ValidEntity() error { //check if protocol set or port not 0 violations := validation.NewValidationError() if arc.Protocol != "" || arc.Port > 0 { //some setting, now lets make sure they are valid if err := validation.ValidPort(int(arc.Port)); err != nil { violations.Add(fmt.Errorf("error AddressResourceConfig: %v", err)) } if err := validation.StringIn(arc.Protocol, commons.TCP, commons.UDP); err != nil { violations.Add(fmt.Errorf("error AddressResourceConfig: invalid protocol: %v", err)) } } if violations.HasError() { return violations } 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 }
// Mount attempts to mount the nfsPath to the localPath func Mount(driver Driver, remotePath, localPath string) error { // check if the driver is installed if err := driver.Installed(); err != nil { return err } // validate that the remote path if ok := func(remotePath string) bool { parts := strings.Split(remotePath, ":") if len(parts) != 2 { return false } ip := net.ParseIP(parts[0]) if ip == nil { return false } dest := filepath.Clean(parts[1]) return dest != "/" && filepath.IsAbs(dest) }(remotePath); !ok { return ErrMalformedNFSMountpoint } var mountInfo proc.NFSMountInfo mountError := driver.Info(localPath, &mountInfo) if mountError == proc.ErrMountPointNotFound { // the mountpoint is not found so try to mount glog.Infof("Creating new mount for %s -> %s", remotePath, localPath) if err := driver.Mount(remotePath, localPath, time.Second*30); err != nil { glog.Errorf("Error while creating mount point for %s -> %s: %s", remotePath, localPath, err) return err } // get the mount point mountError = driver.Info(localPath, &mountInfo) } if mountError != nil { // we should have a mount point by now or bust glog.Errorf("Could not get volume info for %s (mounting from %s): %s", localPath, remotePath, mountError) return mountError } // validate mount info glog.Infof("Mount Info: %+v", mountInfo) verr := validation.NewValidationError() verr.Add(validation.StringsEqual(remotePath, mountInfo.RemotePath, "")) verr.Add(validation.StringsEqual("nfs4", mountInfo.FSType, fmt.Sprintf("%s not mounted nfs4, %s instead", mountInfo.LocalPath, mountInfo.FSType))) verr.Add(func(fsid string) error { if fsiduint, err := strconv.ParseUint(fsid, 16, 64); err != nil || fsiduint == 0 { return fmt.Errorf("invalid fsid: %s", fsid) } return nil }(mountInfo.FSID)) if verr.HasError() { // the mountpoint is stale or wrong, so unmount glog.Warningf("Stale mount point at %s (mounting %s)", localPath, remotePath) if err := driver.Unmount(localPath); err != nil { glog.Errorf("Could not unmount %s: %s", localPath, err) } return verr } return nil }