consul/testing/deployer/topology/images.go

155 lines
3.8 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package topology
import (
"strings"
goversion "github.com/hashicorp/go-version"
)
var (
MinVersionAgentTokenPartition = goversion.Must(goversion.NewVersion("v1.11.0"))
MinVersionPeering = goversion.Must(goversion.NewVersion("v1.13.0"))
MinVersionTLS = goversion.Must(goversion.NewVersion("v1.12.0"))
)
type Images struct {
// Consul is the image used for creating the container,
// Use ChooseConsul() to control which image (ConsulCE or ConsulEnterprise) assign to Consul
Consul string `json:",omitempty"`
// ConsulCE sets the CE image
ConsulCE string `json:",omitempty"`
// consulVersion is the version part of Consul image,
// e.g., if Consul image is hashicorp/consul-enterprise:1.15.0-ent,
// consulVersion is 1.15.0-ent
consulVersion string
// ConsulEnterprise sets the ent image
ConsulEnterprise string `json:",omitempty"`
Envoy string
Dataplane string
}
func (i Images) LocalDataplaneImage() string {
if i.Dataplane == "" {
return ""
}
img, tag, ok := strings.Cut(i.Dataplane, ":")
if !ok {
tag = "latest"
}
name := strings.ReplaceAll(img, "/", "-")
// ex: local/hashicorp-consul-dataplane:1.1.0
return "local/" + name + ":" + tag
}
func (i Images) LocalDataplaneTProxyImage() string {
return spliceImageNamesAndTags(i.Dataplane, i.Consul, "tproxy")
}
func (i Images) EnvoyConsulImage() string {
return spliceImageNamesAndTags(i.Consul, i.Envoy, "")
}
func spliceImageNamesAndTags(base1, base2, nameSuffix string) string {
if base1 == "" || base2 == "" {
return ""
}
img1, tag1, ok1 := strings.Cut(base1, ":")
img2, tag2, ok2 := strings.Cut(base2, ":")
if !ok1 {
tag1 = "latest"
}
if !ok2 {
tag2 = "latest"
}
name1 := strings.ReplaceAll(img1, "/", "-")
name2 := strings.ReplaceAll(img2, "/", "-")
if nameSuffix != "" {
nameSuffix = "-" + nameSuffix
}
// ex: local/hashicorp-consul-and-envoyproxy-envoy:1.15.0-with-v1.26.2
return "local/" + name1 + "-and-" + name2 + nameSuffix + ":" + tag1 + "-with-" + tag2
}
// TODO: what is this for and why do we need to do this and why is it named this?
func (i Images) ChooseNode(kind NodeKind) Images {
switch kind {
case NodeKindServer:
i.Envoy = ""
i.Dataplane = ""
case NodeKindClient:
i.Dataplane = ""
case NodeKindDataplane:
i.Envoy = ""
default:
// do nothing
}
return i
}
// ChooseConsul controls which image assigns to Consul
func (i Images) ChooseConsul(enterprise bool) Images {
if enterprise {
i.Consul = i.ConsulEnterprise
} else {
i.Consul = i.ConsulCE
}
i.ConsulEnterprise = ""
i.ConsulCE = ""
// extract the version part of Consul
i.consulVersion = i.Consul[strings.Index(i.Consul, ":")+1:]
return i
}
// GreaterThanVersion compares the image version to a specified version
func (i Images) GreaterThanVersion(version *goversion.Version) bool {
if i.consulVersion == "local" {
return true
}
iVer := goversion.Must(goversion.NewVersion(i.consulVersion))
return iVer.GreaterThanOrEqual(version)
}
func (i Images) OverrideWith(i2 Images) Images {
if i2.Consul != "" {
i.Consul = i2.Consul
}
if i2.ConsulCE != "" {
i.ConsulCE = i2.ConsulCE
}
if i2.ConsulEnterprise != "" {
i.ConsulEnterprise = i2.ConsulEnterprise
}
if i2.Envoy != "" {
i.Envoy = i2.Envoy
}
if i2.Dataplane != "" {
i.Dataplane = i2.Dataplane
}
return i
}
// DefaultImages controls which specific docker images are used as default
// values for topology components that do not specify values.
//
// These can be bulk-updated using the make target 'make update-defaults'
func DefaultImages() Images {
return Images{
Consul: "",
ConsulCE: DefaultConsulCEImage,
ConsulEnterprise: DefaultConsulEnterpriseImage,
Envoy: DefaultEnvoyImage,
Dataplane: DefaultDataplaneImage,
}
}