github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/nomad/mock/variables.go (about)

     1  package mock
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"sort"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/brianvoe/gofakeit/v6"
    11  	"github.com/hashicorp/nomad/nomad/structs"
    12  )
    13  
    14  type MockVariables map[string]*structs.VariableDecrypted
    15  
    16  func Variable() *structs.VariableDecrypted {
    17  	return &structs.VariableDecrypted{
    18  		VariableMetadata: mockVariableMetadata(),
    19  		Items: structs.VariableItems{
    20  			"key1": "value1",
    21  			"key2": "value2",
    22  		},
    23  	}
    24  }
    25  
    26  // Variables returns a random number of variables between min
    27  // and max inclusive.
    28  func Variables(minU, maxU uint8) MockVariables {
    29  	// the unsignedness of the args is to prevent goofy parameters, they're
    30  	// easier to work with as ints in this code.
    31  	min := int(minU)
    32  	max := int(maxU)
    33  	vc := min
    34  	// handle cases with irrational arguments. Max < Min = min
    35  	if max > min {
    36  		vc = rand.Intn(max-min) + min
    37  	}
    38  	svs := make([]*structs.VariableDecrypted, vc)
    39  	paths := make(map[string]*structs.VariableDecrypted, vc)
    40  	for i := 0; i < vc; i++ {
    41  		nv := Variable()
    42  		// There is an extremely rare chance of path collision because the mock
    43  		// variables generate their paths randomly. This check will add
    44  		// an extra component on conflict to (ideally) disambiguate them.
    45  		if _, found := paths[nv.Path]; found {
    46  			nv.Path = nv.Path + "/" + fmt.Sprint(time.Now().UnixNano())
    47  		}
    48  		paths[nv.Path] = nv
    49  		svs[i] = nv
    50  	}
    51  	return paths
    52  }
    53  
    54  func (svs MockVariables) ListPaths() []string {
    55  	out := make([]string, 0, len(svs))
    56  	for _, sv := range svs {
    57  		out = append(out, sv.Path)
    58  	}
    59  	sort.Strings(out)
    60  	return out
    61  }
    62  
    63  func (svs MockVariables) List() []*structs.VariableDecrypted {
    64  	out := make([]*structs.VariableDecrypted, 0, len(svs))
    65  	for _, p := range svs.ListPaths() {
    66  		pc := svs[p].Copy()
    67  		out = append(out, &pc)
    68  	}
    69  	return out
    70  }
    71  
    72  type MockVariablesEncrypted map[string]*structs.VariableEncrypted
    73  
    74  func VariableEncrypted() *structs.VariableEncrypted {
    75  	return &structs.VariableEncrypted{
    76  		VariableMetadata: mockVariableMetadata(),
    77  		VariableData: structs.VariableData{
    78  			KeyID: "foo",
    79  			Data:  []byte("foo"),
    80  		},
    81  	}
    82  }
    83  
    84  // VariablesEncrypted returns a random number of variables between min
    85  // and max inclusive.
    86  func VariablesEncrypted(minU, maxU uint8) MockVariablesEncrypted {
    87  	// the unsignedness of the args is to prevent goofy parameters, they're
    88  	// easier to work with as ints in this code.
    89  	min := int(minU)
    90  	max := int(maxU)
    91  	vc := min
    92  	// handle cases with irrational arguments. Max < Min = min
    93  	if max > min {
    94  		vc = rand.Intn(max-min) + min
    95  	}
    96  	svs := make([]*structs.VariableEncrypted, vc)
    97  	paths := make(map[string]*structs.VariableEncrypted, vc)
    98  	for i := 0; i < vc; i++ {
    99  		nv := VariableEncrypted()
   100  		// There is an extremely rare chance of path collision because the mock
   101  		// variables generate their paths randomly. This check will add
   102  		// an extra component on conflict to (ideally) disambiguate them.
   103  		if _, found := paths[nv.Path]; found {
   104  			nv.Path = nv.Path + "/" + fmt.Sprint(time.Now().UnixNano())
   105  		}
   106  		paths[nv.Path] = nv
   107  		svs[i] = nv
   108  	}
   109  	return paths
   110  }
   111  
   112  func (svs MockVariablesEncrypted) ListPaths() []string {
   113  	out := make([]string, 0, len(svs))
   114  	for _, sv := range svs {
   115  		out = append(out, sv.Path)
   116  	}
   117  	sort.Strings(out)
   118  	return out
   119  }
   120  
   121  func (svs MockVariablesEncrypted) List() []*structs.VariableEncrypted {
   122  	out := make([]*structs.VariableEncrypted, 0, len(svs))
   123  	for _, p := range svs.ListPaths() {
   124  		pc := svs[p].Copy()
   125  		out = append(out, &pc)
   126  	}
   127  	return out
   128  }
   129  
   130  func mockVariableMetadata() structs.VariableMetadata {
   131  	envs := []string{"dev", "test", "prod"}
   132  	envIdx := rand.Intn(3)
   133  	env := envs[envIdx]
   134  	domain := gofakeit.DomainName()
   135  
   136  	out := structs.VariableMetadata{
   137  		Namespace:   "default",
   138  		Path:        strings.ReplaceAll(env+"."+domain, ".", "/"),
   139  		CreateIndex: uint64(rand.Intn(100) + 100),
   140  		CreateTime:  gofakeit.DateRange(time.Now().AddDate(0, -1, 0), time.Now()).UnixNano(),
   141  	}
   142  	out.ModifyIndex = out.CreateIndex
   143  	out.ModifyTime = out.CreateTime
   144  
   145  	// Flip a coin to see if we should return a "modified" object
   146  	if gofakeit.Bool() {
   147  		out.ModifyTime = gofakeit.DateRange(time.Unix(0, out.CreateTime), time.Now()).UnixNano()
   148  		out.ModifyIndex = out.CreateIndex + uint64(rand.Intn(100))
   149  	}
   150  	return out
   151  }