util.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // package for logicing client and server code
  2. package logic
  3. import (
  4. "crypto/rand"
  5. "encoding/base32"
  6. "encoding/base64"
  7. "encoding/json"
  8. "fmt"
  9. "net"
  10. "os"
  11. "strings"
  12. "time"
  13. "unicode"
  14. "github.com/blang/semver"
  15. "github.com/c-robinson/iplib"
  16. "github.com/gravitl/netmaker/database"
  17. "github.com/gravitl/netmaker/logger"
  18. )
  19. // IsBase64 - checks if a string is in base64 format
  20. // This is used to validate public keys (make sure they're base64 encoded like all public keys should be).
  21. func IsBase64(s string) bool {
  22. _, err := base64.StdEncoding.DecodeString(s)
  23. return err == nil
  24. }
  25. // CheckEndpoint - checks if an endpoint is valid
  26. func CheckEndpoint(endpoint string) bool {
  27. endpointarr := strings.Split(endpoint, ":")
  28. return len(endpointarr) == 2
  29. }
  30. // FileExists - checks if local file exists
  31. func FileExists(f string) bool {
  32. info, err := os.Stat(f)
  33. if os.IsNotExist(err) {
  34. return false
  35. }
  36. return !info.IsDir()
  37. }
  38. // IsAddressInCIDR - util to see if an address is in a cidr or not
  39. func IsAddressInCIDR(address net.IP, cidr string) bool {
  40. var _, currentCIDR, cidrErr = net.ParseCIDR(cidr)
  41. if cidrErr != nil {
  42. return false
  43. }
  44. return currentCIDR.Contains(address)
  45. }
  46. // SetNetworkNodesLastModified - sets the network nodes last modified
  47. func SetNetworkNodesLastModified(networkName string) error {
  48. timestamp := time.Now().Unix()
  49. network, err := GetParentNetwork(networkName)
  50. if err != nil {
  51. return err
  52. }
  53. network.NodesLastModified = timestamp
  54. data, err := json.Marshal(&network)
  55. if err != nil {
  56. return err
  57. }
  58. err = database.Insert(networkName, string(data), database.NETWORKS_TABLE_NAME)
  59. if err != nil {
  60. return err
  61. }
  62. return nil
  63. }
  64. // RandomString - returns a random string in a charset
  65. func RandomString(length int) string {
  66. randombytes := make([]byte, length)
  67. _, err := rand.Read(randombytes)
  68. if err != nil {
  69. logger.Log(0, "random string", err.Error())
  70. return ""
  71. }
  72. return base32.StdEncoding.EncodeToString(randombytes)[:length]
  73. }
  74. // StringSliceContains - sees if a string slice contains a string element
  75. func StringSliceContains(slice []string, item string) bool {
  76. for _, s := range slice {
  77. if s == item {
  78. return true
  79. }
  80. }
  81. return false
  82. }
  83. // NormalizeCIDR - returns the first address of CIDR
  84. func NormalizeCIDR(address string) (string, error) {
  85. ip, IPNet, err := net.ParseCIDR(address)
  86. if err != nil {
  87. return "", err
  88. }
  89. if ip.To4() == nil {
  90. net6 := iplib.Net6FromStr(IPNet.String())
  91. IPNet.IP = net6.FirstAddress()
  92. } else {
  93. net4 := iplib.Net4FromStr(IPNet.String())
  94. IPNet.IP = net4.NetworkAddress()
  95. }
  96. return IPNet.String(), nil
  97. }
  98. // StringDifference - returns the elements in `a` that aren't in `b`.
  99. func StringDifference(a, b []string) []string {
  100. mb := make(map[string]struct{}, len(b))
  101. for _, x := range b {
  102. mb[x] = struct{}{}
  103. }
  104. var diff []string
  105. for _, x := range a {
  106. if _, found := mb[x]; !found {
  107. diff = append(diff, x)
  108. }
  109. }
  110. return diff
  111. }
  112. // CheckIfFileExists - checks if file exists or not in the given path
  113. func CheckIfFileExists(filePath string) bool {
  114. if _, err := os.Stat(filePath); os.IsNotExist(err) {
  115. return false
  116. }
  117. return true
  118. }
  119. // RemoveStringSlice - removes an element at given index i
  120. // from a given string slice
  121. func RemoveStringSlice(slice []string, i int) []string {
  122. return append(slice[:i], slice[i+1:]...)
  123. }
  124. // IsSlicesEqual tells whether a and b contain the same elements.
  125. // A nil argument is equivalent to an empty slice.
  126. func IsSlicesEqual(a, b []string) bool {
  127. if len(a) != len(b) {
  128. return false
  129. }
  130. for i, v := range a {
  131. if v != b[i] {
  132. return false
  133. }
  134. }
  135. return true
  136. }
  137. // VersionLessThan checks if v1 < v2 semantically
  138. // dev is the latest version
  139. func VersionLessThan(v1, v2 string) (bool, error) {
  140. if v1 == "dev" {
  141. return false, nil
  142. }
  143. if v2 == "dev" {
  144. return true, nil
  145. }
  146. semVer1 := strings.TrimFunc(v1, func(r rune) bool {
  147. return !unicode.IsNumber(r)
  148. })
  149. semVer2 := strings.TrimFunc(v2, func(r rune) bool {
  150. return !unicode.IsNumber(r)
  151. })
  152. sv1, err := semver.Parse(semVer1)
  153. if err != nil {
  154. return false, fmt.Errorf("failed to parse semver1 (%s): %w", semVer1, err)
  155. }
  156. sv2, err := semver.Parse(semVer2)
  157. if err != nil {
  158. return false, fmt.Errorf("failed to parse semver2 (%s): %w", semVer2, err)
  159. }
  160. return sv1.LT(sv2), nil
  161. }