consul/internal/resource/demo/demo.go

203 lines
4.5 KiB
Go

// Package demo includes fake resource types for working on Consul's generic
// state storage without having to refer to specific features.
package demo
import (
"fmt"
"math/rand"
"strings"
"time"
"google.golang.org/protobuf/types/known/anypb"
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/proto-public/pbresource"
pbdemov1 "github.com/hashicorp/consul/proto/private/pbdemo/v1"
pbdemov2 "github.com/hashicorp/consul/proto/private/pbdemo/v2"
)
var (
// TenancyDefault contains the default values for all tenancy units.
TenancyDefault = &pbresource.Tenancy{
Partition: "default",
PeerName: "local",
Namespace: "default",
}
// TypeV1Artist represents a musician or group of musicians.
TypeV1Artist = &pbresource.Type{
Group: "demo",
GroupVersion: "v1",
Kind: "artist",
}
// TypeV1Album represents a collection of an artist's songs.
TypeV1Album = &pbresource.Type{
Group: "demo",
GroupVersion: "v1",
Kind: "album",
}
// TypeV2Artist represents a musician or group of musicians.
TypeV2Artist = &pbresource.Type{
Group: "demo",
GroupVersion: "v2",
Kind: "artist",
}
// TypeV2Album represents a collection of an artist's songs.
TypeV2Album = &pbresource.Type{
Group: "demo",
GroupVersion: "v2",
Kind: "album",
}
)
// Register demo types. Should only be called in tests and dev mode.
func Register(r resource.Registry) {
r.Register(resource.Registration{
Type: TypeV1Artist,
Proto: &pbdemov1.Artist{},
})
r.Register(resource.Registration{
Type: TypeV1Album,
Proto: &pbdemov1.Album{},
})
r.Register(resource.Registration{
Type: TypeV2Artist,
Proto: &pbdemov2.Artist{},
})
r.Register(resource.Registration{
Type: TypeV2Album,
Proto: &pbdemov2.Album{},
})
}
// GenerateV2Artist generates a random Artist resource.
func GenerateV2Artist() (*pbresource.Resource, error) {
adjective := adjectives[rand.Intn(len(adjectives))]
noun := nouns[rand.Intn(len(nouns))]
numMembers := rand.Intn(5) + 1
groupMembers := make(map[string]string, numMembers)
for i := 0; i < numMembers; i++ {
groupMembers[members[rand.Intn(len(members))]] = instruments[rand.Intn(len(instruments))]
}
data, err := anypb.New(&pbdemov2.Artist{
Name: fmt.Sprintf("%s %s", adjective, noun),
Genre: randomGenre(),
GroupMembers: groupMembers,
})
if err != nil {
return nil, err
}
return &pbresource.Resource{
Id: &pbresource.ID{
Type: TypeV2Artist,
Tenancy: TenancyDefault,
Name: fmt.Sprintf("%s-%s", strings.ToLower(adjective), strings.ToLower(noun)),
},
Data: data,
Metadata: map[string]string{
"generated_at": time.Now().Format(time.RFC3339),
},
}, nil
}
// GenerateV2Album generates a random Album resource, owned by the Artist with
// the given ID.
func GenerateV2Album(artistID *pbresource.ID) (*pbresource.Resource, error) {
adjective := adjectives[rand.Intn(len(adjectives))]
noun := nouns[rand.Intn(len(nouns))]
numTracks := 3 + rand.Intn(3)
tracks := make([]string, numTracks)
for i := 0; i < numTracks; i++ {
words := nouns
if i%3 == 0 {
words = adjectives
}
tracks[i] = words[rand.Intn(len(words))]
}
data, err := anypb.New(&pbdemov2.Album{
Title: fmt.Sprintf("%s %s", adjective, noun),
YearOfRelease: int32(1990 + rand.Intn(time.Now().Year()-1990)),
CriticallyAclaimed: rand.Int()%2 == 0,
Tracks: tracks,
})
if err != nil {
return nil, err
}
return &pbresource.Resource{
Id: &pbresource.ID{
Type: TypeV2Album,
Tenancy: artistID.Tenancy,
Name: fmt.Sprintf("%s/%s-%s", artistID.Name, strings.ToLower(adjective), strings.ToLower(noun)),
},
Owner: artistID,
Data: data,
Metadata: map[string]string{
"generated_at": time.Now().Format(time.RFC3339),
},
}, nil
}
func randomGenre() pbdemov2.Genre {
return pbdemov2.Genre(rand.Intn(len(pbdemov1.Genre_name)-1) + 1)
}
var (
adjectives = []string{
"Purple",
"Angry",
"Euphoric",
"Unexpected",
"Cheesy",
"Rancid",
"Pleasant",
"Mumbling",
"Enlightened",
}
nouns = []string{
"Speakerphone",
"Fox",
"Guppy",
"Smile",
"Emacs",
"Grapefruit",
"Engineer",
"Basketball",
}
members = []string{
"Owl",
"Tiger",
"Beetle",
"Lion",
"Chicken",
"Snake",
"Monkey",
"Kitten",
"Hound",
}
instruments = []string{
"Guitar",
"Bass",
"Lead Vocals",
"Backing Vocals",
"Drums",
"Synthesizer",
"Triangle",
"Standing by the stage looking cool",
}
)