2023-04-10 15:36:59 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2022-09-22 18:49:58 +00:00
|
|
|
package mock
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"math/rand"
|
|
|
|
"sort"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/brianvoe/gofakeit/v6"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
|
|
)
|
|
|
|
|
|
|
|
type MockVariables map[string]*structs.VariableDecrypted
|
|
|
|
|
|
|
|
func Variable() *structs.VariableDecrypted {
|
|
|
|
return &structs.VariableDecrypted{
|
|
|
|
VariableMetadata: mockVariableMetadata(),
|
|
|
|
Items: structs.VariableItems{
|
|
|
|
"key1": "value1",
|
|
|
|
"key2": "value2",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Variables returns a random number of variables between min
|
|
|
|
// and max inclusive.
|
|
|
|
func Variables(minU, maxU uint8) MockVariables {
|
|
|
|
// the unsignedness of the args is to prevent goofy parameters, they're
|
|
|
|
// easier to work with as ints in this code.
|
|
|
|
min := int(minU)
|
|
|
|
max := int(maxU)
|
|
|
|
vc := min
|
|
|
|
// handle cases with irrational arguments. Max < Min = min
|
|
|
|
if max > min {
|
|
|
|
vc = rand.Intn(max-min) + min
|
|
|
|
}
|
|
|
|
svs := make([]*structs.VariableDecrypted, vc)
|
|
|
|
paths := make(map[string]*structs.VariableDecrypted, vc)
|
|
|
|
for i := 0; i < vc; i++ {
|
|
|
|
nv := Variable()
|
|
|
|
// There is an extremely rare chance of path collision because the mock
|
|
|
|
// variables generate their paths randomly. This check will add
|
|
|
|
// an extra component on conflict to (ideally) disambiguate them.
|
|
|
|
if _, found := paths[nv.Path]; found {
|
|
|
|
nv.Path = nv.Path + "/" + fmt.Sprint(time.Now().UnixNano())
|
|
|
|
}
|
|
|
|
paths[nv.Path] = nv
|
|
|
|
svs[i] = nv
|
|
|
|
}
|
|
|
|
return paths
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svs MockVariables) ListPaths() []string {
|
|
|
|
out := make([]string, 0, len(svs))
|
|
|
|
for _, sv := range svs {
|
|
|
|
out = append(out, sv.Path)
|
|
|
|
}
|
|
|
|
sort.Strings(out)
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svs MockVariables) List() []*structs.VariableDecrypted {
|
|
|
|
out := make([]*structs.VariableDecrypted, 0, len(svs))
|
|
|
|
for _, p := range svs.ListPaths() {
|
|
|
|
pc := svs[p].Copy()
|
|
|
|
out = append(out, &pc)
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
type MockVariablesEncrypted map[string]*structs.VariableEncrypted
|
|
|
|
|
|
|
|
func VariableEncrypted() *structs.VariableEncrypted {
|
|
|
|
return &structs.VariableEncrypted{
|
|
|
|
VariableMetadata: mockVariableMetadata(),
|
|
|
|
VariableData: structs.VariableData{
|
|
|
|
KeyID: "foo",
|
|
|
|
Data: []byte("foo"),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// VariablesEncrypted returns a random number of variables between min
|
|
|
|
// and max inclusive.
|
|
|
|
func VariablesEncrypted(minU, maxU uint8) MockVariablesEncrypted {
|
|
|
|
// the unsignedness of the args is to prevent goofy parameters, they're
|
|
|
|
// easier to work with as ints in this code.
|
|
|
|
min := int(minU)
|
|
|
|
max := int(maxU)
|
|
|
|
vc := min
|
|
|
|
// handle cases with irrational arguments. Max < Min = min
|
|
|
|
if max > min {
|
|
|
|
vc = rand.Intn(max-min) + min
|
|
|
|
}
|
|
|
|
svs := make([]*structs.VariableEncrypted, vc)
|
|
|
|
paths := make(map[string]*structs.VariableEncrypted, vc)
|
|
|
|
for i := 0; i < vc; i++ {
|
|
|
|
nv := VariableEncrypted()
|
|
|
|
// There is an extremely rare chance of path collision because the mock
|
|
|
|
// variables generate their paths randomly. This check will add
|
|
|
|
// an extra component on conflict to (ideally) disambiguate them.
|
|
|
|
if _, found := paths[nv.Path]; found {
|
|
|
|
nv.Path = nv.Path + "/" + fmt.Sprint(time.Now().UnixNano())
|
|
|
|
}
|
|
|
|
paths[nv.Path] = nv
|
|
|
|
svs[i] = nv
|
|
|
|
}
|
|
|
|
return paths
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svs MockVariablesEncrypted) ListPaths() []string {
|
|
|
|
out := make([]string, 0, len(svs))
|
|
|
|
for _, sv := range svs {
|
|
|
|
out = append(out, sv.Path)
|
|
|
|
}
|
|
|
|
sort.Strings(out)
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svs MockVariablesEncrypted) List() []*structs.VariableEncrypted {
|
|
|
|
out := make([]*structs.VariableEncrypted, 0, len(svs))
|
|
|
|
for _, p := range svs.ListPaths() {
|
|
|
|
pc := svs[p].Copy()
|
|
|
|
out = append(out, &pc)
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
func mockVariableMetadata() structs.VariableMetadata {
|
|
|
|
envs := []string{"dev", "test", "prod"}
|
|
|
|
envIdx := rand.Intn(3)
|
|
|
|
env := envs[envIdx]
|
|
|
|
domain := gofakeit.DomainName()
|
|
|
|
|
|
|
|
out := structs.VariableMetadata{
|
|
|
|
Namespace: "default",
|
|
|
|
Path: strings.ReplaceAll(env+"."+domain, ".", "/"),
|
|
|
|
CreateIndex: uint64(rand.Intn(100) + 100),
|
|
|
|
CreateTime: gofakeit.DateRange(time.Now().AddDate(0, -1, 0), time.Now()).UnixNano(),
|
|
|
|
}
|
|
|
|
out.ModifyIndex = out.CreateIndex
|
|
|
|
out.ModifyTime = out.CreateTime
|
|
|
|
|
|
|
|
// Flip a coin to see if we should return a "modified" object
|
|
|
|
if gofakeit.Bool() {
|
|
|
|
out.ModifyTime = gofakeit.DateRange(time.Unix(0, out.CreateTime), time.Now()).UnixNano()
|
|
|
|
out.ModifyIndex = out.CreateIndex + uint64(rand.Intn(100))
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|