github.com/hernad/nomad@v1.6.112/nomad/mock/variables.go (about)

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