summaryrefslogtreecommitdiff
path: root/validate.go
diff options
context:
space:
mode:
Diffstat (limited to 'validate.go')
-rw-r--r--validate.go220
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
+}