github.com/Cloud-Foundations/Dominator@v0.3.4/lib/filegen/mdbFieldDirectory.go (about)

     1  package filegen
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"reflect"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/Cloud-Foundations/Dominator/lib/log"
    13  	"github.com/Cloud-Foundations/Dominator/lib/mdb"
    14  )
    15  
    16  var (
    17  	machineType = reflect.TypeOf(mdb.Machine{})
    18  )
    19  
    20  type mdbFieldDirectoryType struct {
    21  	directory string
    22  	index     []int
    23  	tagKey    string
    24  }
    25  
    26  func makeGenerator(field string) (*mdbFieldDirectoryType, error) {
    27  	if fParts := strings.Split(field, "."); len(fParts) == 2 {
    28  		if fParts[0] == "Tags" {
    29  			return &mdbFieldDirectoryType{tagKey: fParts[1]}, nil
    30  		}
    31  	}
    32  	structField, found := machineType.FieldByName(field)
    33  	if !found {
    34  		return nil, fmt.Errorf(
    35  			"field: \"%s\" not found in mdb.Machine type", field)
    36  	}
    37  	if structField.Type.Kind() != reflect.String {
    38  		return nil, fmt.Errorf(
    39  			"field: \"%s\" is not string type", field)
    40  	}
    41  	return &mdbFieldDirectoryType{index: structField.Index}, nil
    42  }
    43  
    44  func sendNotifications(notifierChannel chan<- string,
    45  	interval time.Duration) {
    46  	for ; ; time.Sleep(interval) {
    47  		notifierChannel <- ""
    48  	}
    49  }
    50  
    51  func (m *Manager) registerMdbFieldDirectoryForPath(pathname string,
    52  	field, directory string, interval time.Duration) error {
    53  	generator, err := makeGenerator(field)
    54  	if err != nil {
    55  		return err
    56  	}
    57  	generator.directory = directory
    58  	notifierChannel := m.RegisterGeneratorForPath(pathname,
    59  		generator)
    60  	if interval <= 0 {
    61  		close(notifierChannel)
    62  		return nil
    63  	}
    64  	go sendNotifications(notifierChannel, interval)
    65  	return nil
    66  }
    67  
    68  func (g *mdbFieldDirectoryType) Generate(machine mdb.Machine,
    69  	logger log.Logger) ([]byte, time.Time, error) {
    70  	var fieldValue string
    71  	if g.tagKey != "" {
    72  		fieldValue = machine.Tags[g.tagKey]
    73  	} else {
    74  		fieldValue = reflect.ValueOf(machine).FieldByIndex(
    75  			g.index).String()
    76  	}
    77  	if fieldValue == "" {
    78  		fieldValue = "*"
    79  	}
    80  	pathname := filepath.Join(g.directory,
    81  		filepath.Clean(fieldValue))
    82  	if data, err := ioutil.ReadFile(pathname); err != nil {
    83  		if os.IsNotExist(err) && fieldValue != "*" {
    84  			data, err := ioutil.ReadFile(filepath.Join(g.directory,
    85  				"*"))
    86  			if err == nil {
    87  				return data, time.Time{}, nil
    88  			}
    89  		}
    90  		return nil, time.Time{}, err
    91  	} else {
    92  		return data, time.Time{}, nil
    93  	}
    94  }