package main /* validate / sanity check / consistancy check the data here is some code to do smart things like: * check mac addresses are unique * check uuid's are unique * double check filenames are unique * return a unique mac address * return a unique uuid */ import ( "errors" "path/filepath" "github.com/google/uuid" pb "go.wit.com/lib/protobuf/virtbuf" "go.wit.com/log" ) // will make sure the mac address is unique func ValidateUniqueMac(cluster *pb.Cluster, mac string) bool { for _, d := range cluster.Droplets { for _, n := range d.Networks { if n.Mac == mac { log.Info("duplicate MAC", n.Mac, "in droplet", d.Hostname) return false } } } return true } // records all the known paths. this should go in the protobuf func addClusterFilepath(cluster *pb.Cluster, dir string) *pb.Event { var found bool = false var e *pb.Event for _, d := range cluster.Dirs { if d == dir { // found dir found = true break } } if !found { if dir != "." { // make a new Add Event e = pb.NewAddEvent(nil, "Add Cluster Directory", dir) cluster.Dirs = append(cluster.Dirs, dir) } } return e } // returns the droplet using a filename func lookupFilename(cluster *pb.Cluster, filename string) *pb.Droplet { filebase := filepath.Base(filename) for _, d := range cluster.Droplets { for _, disk := range d.Disks { if filebase == disk.Filename { return d } } } return nil } func ValidateUniqueFilenames(cluster *pb.Cluster) bool { var ok bool = true var disks map[string]string disks = make(map[string]string) for _, d := range cluster.Droplets { for _, disk := range d.Disks { filename := disk.Filename addClusterFilepath(cluster, disk.Filepath) if _, ok := disks[filename]; ok { /* if argv.IgnDisk { log.Info("ignore dup disk", filename, disks[filename], d.Hostname) } else { } */ log.Info("file", filename, "on droplet", disks[filename]) log.Info("file", filename, "on droplet", d.Hostname) log.Info("duplicate disk names (--xml-ignore-disk to ignore)") ok = false } disks[filename] = d.Hostname } } if ok { log.Println("validated okay: no duplicate disk images") } return ok } func ValidateDiskFilenames(cluster *pb.Cluster) []*pb.Event { var alle []*pb.Event for _, d := range cluster.Droplets { for _, disk := range d.Disks { filename := disk.Filename filebase := filepath.Base(filename) dir := filepath.Dir(filename) addClusterFilepath(cluster, dir) if disk.Filename != filebase { // update filename e := d.NewChangeEvent("Disk.Filename", disk.Filename, filebase) alle = append(alle, e) disk.Filename = filebase } if dir == "." { continue } if dir == "" { continue } if disk.Filepath != dir { // update filename e := d.NewChangeEvent("Disk.Filepath", disk.Filepath, dir) alle = append(alle, e) disk.Filepath = dir } } } return alle } // runs on startup. dies if there are duplicates // the config file must then be edited by hand func ValidateDroplets(cluster *pb.Cluster) (map[string]string, map[string]string, error) { // uuid map to check for duplicates var umap map[string]string umap = make(map[string]string) // mac address map to check for duplicates var macs map[string]string macs = make(map[string]string) for _, d := range cluster.Droplets { // Generate a new UUID if d.Uuid == "" { u := uuid.New() d.Uuid = u.String() } // seconds, ok := timeZone[tz]; ok { if _, ok := umap[d.Uuid]; ok { // UUID already exists log.Info("duplicate UUID", d.Uuid, umap[d.Uuid]) log.Info("duplicate UUID", d.Uuid, d.Hostname) return umap, macs, errors.New("duplicate UUID: " + d.Uuid) } umap[d.Uuid] = d.Hostname for _, n := range d.Networks { // log.Println("network:", n.Mac, d.Uuid, d.Hostname) if _, ok := macs[n.Mac]; ok { // UUID already exists log.Info("duplicate MAC", n.Mac, macs[n.Mac], umap[macs[n.Mac]]) log.Info("duplicate MAC", n.Mac, d.Hostname) return umap, macs, errors.New("duplicate MAC: " + n.Mac) } macs[n.Mac] = d.Uuid } } log.Println("validated okay: no duplicate MAC addr") log.Println("validated okay: no duplicate UUID") return umap, macs, nil } /* func safeValidateDroplets(cluster *pb.Cluster) (map[string]string, map[string]string) { // uuid map to check for duplicates var umap map[string]string umap = make(map[string]string) // mac address map to check for duplicates var macs map[string]string macs = make(map[string]string) for _, d := range cluster.Droplets { // Generate a new UUID if d.Uuid == "" { u := uuid.New() d.Uuid = u.String() } // seconds, ok := timeZone[tz]; ok { if _, ok := umap[d.Uuid]; ok { // UUID already exists log.Info("duplicate UUID", d.Uuid, umap[d.Uuid]) log.Info("duplicate UUID", d.Uuid, d.Hostname) // os.Exit(-1) } umap[d.Uuid] = d.Hostname for _, n := range d.Networks { // log.Println("network:", n.Mac, d.Uuid, d.Hostname) if _, ok := macs[n.Mac]; ok { // UUID already exists log.Info("duplicate MAC", n.Mac, macs[n.Mac], umap[macs[n.Mac]]) log.Info("duplicate MAC", n.Mac, d.Hostname) // os.Exit(-1) } macs[n.Mac] = d.Uuid } } log.Println("validated okay: no duplicate MAC addr") log.Println("validated okay: no duplicate UUID") return umap, macs } */