| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 | package databaseimport (	"encoding/json"	"errors"	"log"	"net"	"strings"	"time"	"github.com/bradfitz/gomemcache/memcache"	"github.com/gravitl/netmaker/servercfg")var MemCachedDatabase *memcache.Clientvar MEMCACHED_FUNCTIONS = map[string]interface{}{	INIT_DB:      initMemcachedDatabase,	CREATE_TABLE: memcachedCreateTable,	INSERT:       memcachedInsert,	INSERT_PEER:  memcachedInsertPeer,	DELETE:       memcachedDeleteRecord,	DELETE_ALL:   memcachedDeleteAllRecords,	FETCH_ALL:    memcachedFetchRecords,	CLOSE_DB:     memcachedCloseDB,}// utility function to make setting memcached servers easierfunc parseMemcachedAddresses(addresses string) string {	addressesArr := strings.Split(addresses, ",")	numAddresses := len(addressesArr)	if numAddresses == 0 {		return "127.0.0.1:11211"	}	newAddresses := ""	log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))	for _, address := range addressesArr {		if isValidIp(address) {			newAddresses += address			if servercfg.GetVerbose() >= 2 {				log.Println("adding " + address + " to memcached servers")			}			if address != addressesArr[numAddresses-1] {				newAddresses += ","			}		}	}	return newAddresses}func initMemcachedDatabase() error {	addresses := parseMemcachedAddresses(servercfg.GetMemcachedAddress())	MemCachedDatabase = memcache.New(addresses)	if MemCachedDatabase == nil {		return errors.New("could not initialize memcached")	}	MemCachedDatabase.Timeout = time.Minute	return nil}func memcachedCreateTable(tableName string) error {	if currentTable, err := memcachedFetchRecords(tableName); (currentTable != nil && len(currentTable) >= 0) || err != nil {		// return if it already exists		return err	} else {		log.Println(currentTable)	}	table := make(map[string]string)	newTable, err := json.Marshal(table)	if err != nil {		return err	}	err = MemCachedDatabase.Set(&memcache.Item{Key: tableName, Value: newTable, Expiration: 0})	if err != nil {		return err	}	return nil}func memcachedInsert(key string, value string, tableName string) error {	if key != "" && value != "" && IsJSONString(value) {		preData, err := MemCachedDatabase.Get(tableName)		if err != nil {			return err		}		var preDataMap map[string]string		if err := json.Unmarshal(preData.Value, &preDataMap); err != nil {			return err		}		preDataMap[key] = value		postData, err := json.Marshal(&preDataMap)		if err != nil {			return err		}		err = MemCachedDatabase.Replace(&memcache.Item{Key: tableName, Value: postData, Expiration: 0})		if err != nil {			return err		}		return nil	} else {		return errors.New("invalid insert " + key + " : " + value)	}}func memcachedInsertPeer(key string, value string) error {	if key != "" && value != "" && IsJSONString(value) {		if err := memcachedInsert(key, value, PEERS_TABLE_NAME); err != nil {			return err		}		return nil	} else {		return errors.New("invalid peer insert " + key + " : " + value)	}}func memcachedDeleteRecord(tableName string, key string) error {	if key != "" {		preData, err := MemCachedDatabase.Get(tableName)		if err != nil {			return err		}		var preDataMap map[string]string		if err := json.Unmarshal(preData.Value, &preDataMap); err != nil {			return err		}		delete(preDataMap, key)		postData, err := json.Marshal(&preDataMap)		if err != nil {			return err		}		err = MemCachedDatabase.Set(&memcache.Item{Key: tableName, Value: postData, Expiration: 0})		if err != nil {			return err		}		return nil	} else {		return errors.New("invalid delete, key is required")	}}func memcachedDeleteAllRecords(tableName string) error {	err := MemCachedDatabase.Delete(tableName)	if err != nil {		return err	}	err = memcachedCreateTable(tableName)	if err != nil {		return err	}	return nil}// func memcachedFetchRecord(tableName string, key string) (string, error) {// 	results, err := memcachedFetchRecords(tableName)// 	if err != nil {// 		return "", err// 	}// 	if results[key] == "" {// 		return "", errors.New(NO_RECORD)// 	}// 	return results[key], nil// }func memcachedFetchRecords(tableName string) (map[string]string, error) {	var records map[string]string	item, err := MemCachedDatabase.Get(tableName)	if err != nil {		return records, err	}	if err = json.Unmarshal(item.Value, &records); err != nil {		return nil, err	}	return records, nil}func memcachedCloseDB() {	// no op for this library..}func isValidIp(ipAddr string) bool {	return net.ParseIP(ipAddr) == nil}
 |