diff options
Diffstat (limited to 'validate.go')
| -rw-r--r-- | validate.go | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/validate.go b/validate.go new file mode 100644 index 0000000..979d201 --- /dev/null +++ b/validate.go @@ -0,0 +1,220 @@ +package virtigoxml + +/* + 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" + "os" + "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 CheckUniqueMac(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 insertFilename(cluster *pb.Cluster, d *pb.Droplet, filename string) (*pb.Event, error) { + dupd := lookupFilename(cluster, filename) + if dupd != nil { + log.Info("file", filename, "already on droplet", dupd.Hostname) + log.Info("file", filename, "on new droplet", d.Hostname) + if os.Getenv("VIRTIGO_IGNORE_DISKDUP") == "" { + log.Info("duplicate disk names (--xml-ignore-disk to ignore)") + return nil, errors.New("duplicate disk names") + } else { + log.Info("ignore duplicate disk names (--xml-ignore-disk=true)") + } + } + filebase := filepath.Base(filename) + dir := filepath.Dir(filename) + for _, disk := range d.Disks { + if disk.Filename == filebase { + log.Info("already have disk", filename) + return nil, nil + } + } + // make a new Add Event + e := d.NewChangeEvent("Add Disk", "", filename) + + // add the disk protobuf entry + var disk *pb.Disk + disk = new(pb.Disk) + disk.Filename = filebase + disk.Filepath = dir + d.Disks = append(d.Disks, disk) + log.Info("New filename", filebase, dir) + return e, nil +} + +func checkUniqueFilenames(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 checkDiskFilenames(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 +} + +func checkDroplets(cluster *pb.Cluster, dump bool) bool { + // 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") + + if dump { + for u, hostname := range umap { + log.Println("uuid:", u, "hostname:", hostname) + } + + for mac, uuid := range macs { + log.Println("mac:", mac, "uuid", uuid, "hostname:", umap[uuid]) + } + } + + return false +} |
