Skip to content

Commit

Permalink
Add support for DSE 6.9 and HCD (#662)
Browse files Browse the repository at this point in the history
* Add support for DSE 6.9, remove DSE 7.0 and add support for HCD serverType

* CHANGELOG

* Fix error string assert in the webhook_validation_test

* Change config pulling directory to /opt/hcd/resources/cassandra/conf/ for HCD

* Add HCD_AUTO_CONF_OFF = all to env variables

* Test all env vars for Cassandra, HCD and DSE

* Change regexp error string again..
  • Loading branch information
burmanm authored May 30, 2024
1 parent 721bfd5 commit 8d34919
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 38 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Changelog for Cass Operator, new PRs should update the `main / unreleased` secti

## unreleased

* [FEATURE] [#659](https://github.com/k8ssandra/cass-operator/issues/659) Add support for HCD serverType with versions 1.x.x. It will be deployed like Cassandra >= 4.1 for now.
* [FEATURE] [#660](https://github.com/k8ssandra/cass-operator/issues/660) Add support for DSE version 6.9.x and remove support for DSE 7.x.x. DSE 6.9 will be deployed like DSE 6.8.
* [BUGFIX] [#652](https://github.com/k8ssandra/cass-operator/issues/652) Update nodeStatuses info when a pod is recreated

## v1.20.0
Expand Down
15 changes: 11 additions & 4 deletions apis/cassandra/v1beta1/cassandradatacenter_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,16 @@ type CassandraDatacenterSpec struct {

// Version string for config builder,
// used to generate Cassandra server configuration
// +kubebuilder:validation:Pattern=(6\.8\.\d+)|(3\.11\.\d+)|(4\.\d+\.\d+)|(5\.\d+\.\d+)|(7\.\d+\.\d+)
// +kubebuilder:validation:Pattern=(6\.[89]\.\d+)|(3\.11\.\d+)|(4\.\d+\.\d+)|(5\.\d+\.\d+)|(1\.\d+\.\d+)
ServerVersion string `json:"serverVersion"`

// Cassandra server image name. Use of ImageConfig to match ServerVersion is recommended instead of this value.
// This value will override anything set in the ImageConfig matching the ServerVersion
// More info: https://kubernetes.io/docs/concepts/containers/images
ServerImage string `json:"serverImage,omitempty"`

// Server type: "cassandra" or "dse"
// +kubebuilder:validation:Enum=cassandra;dse
// Server type: "cassandra", "dse" or "hcd"
// +kubebuilder:validation:Enum=cassandra;dse;hcd
ServerType string `json:"serverType"`

// DEPRECATED This setting does nothing and defaults to true. Use SecurityContext instead.
Expand Down Expand Up @@ -970,7 +970,14 @@ func (dc *CassandraDatacenter) DatacenterName() string {
}

func (dc *CassandraDatacenter) UseClientImage() bool {
return dc.Spec.ServerType == "cassandra" && semver.Compare(fmt.Sprintf("v%s", dc.Spec.ServerVersion), "v4.1.0") >= 0
if dc.Spec.ServerType == "hcd" {
return true
}

if dc.Spec.ServerType == "cassandra" && semver.Compare(fmt.Sprintf("v%s", dc.Spec.ServerVersion), "v4.1.0") >= 0 {
return true
}
return false
}

func (dc *CassandraDatacenter) GenerationChanged() bool {
Expand Down
10 changes: 10 additions & 0 deletions apis/cassandra/v1beta1/cassandradatacenter_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ func TestUseClientImage(t *testing.T) {
version: "6.8.39",
should: false,
},
{
serverType: "dse",
version: "6.9.0",
should: false,
},
{
serverType: "hcd",
version: "1.0.0",
should: true,
},
{
serverType: "dse",
version: "4.1.2",
Expand Down
6 changes: 6 additions & 0 deletions apis/cassandra/v1beta1/cassandradatacenter_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ func ValidateSingleDatacenter(dc CassandraDatacenter) error {
}
}

if dc.Spec.ServerType == "hcd" {
if !images.IsHCDVersionSupported(dc.Spec.ServerVersion) {
return attemptedTo("use unsupported HCD version '%s'", dc.Spec.ServerVersion)
}
}

if dc.Spec.ServerType == "cassandra" && dc.Spec.DseWorkloads != nil {
if dc.Spec.DseWorkloads.AnalyticsEnabled || dc.Spec.DseWorkloads.GraphEnabled || dc.Spec.DseWorkloads.SearchEnabled {
return attemptedTo("enable DSE workloads if server type is Cassandra")
Expand Down
38 changes: 32 additions & 6 deletions apis/cassandra/v1beta1/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func Test_ValidateSingleDatacenter(t *testing.T) {
errString string
}{
{
name: "Dse Valid",
name: "DSE Valid",
dc: &CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
Expand All @@ -35,7 +35,7 @@ func Test_ValidateSingleDatacenter(t *testing.T) {
errString: "",
},
{
name: "Dse 6.8.4 Valid",
name: "DSE 6.8.4 Valid",
dc: &CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
Expand All @@ -48,20 +48,46 @@ func Test_ValidateSingleDatacenter(t *testing.T) {
errString: "",
},
{
name: "Dse 7.0.0 Valid",
name: "DSE 6.9.1 Valid",
dc: &CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
},
Spec: CassandraDatacenterSpec{
ServerType: "dse",
ServerVersion: "7.0.0",
ServerVersion: "6.9.1",
},
},
errString: "",
},
{
name: "HCD 1.0.0 Valid",
dc: &CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
},
Spec: CassandraDatacenterSpec{
ServerType: "hcd",
ServerVersion: "1.0.0",
},
},
errString: "",
},
{
name: "Dse Invalid",
name: "DSE 7.0.0 invalid",
dc: &CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
},
Spec: CassandraDatacenterSpec{
ServerType: "dse",
ServerVersion: "7.0.0",
},
},
errString: "use unsupported DSE version '7.0.0'",
},
{
name: "DSE Invalid",
dc: &CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
Expand All @@ -74,7 +100,7 @@ func Test_ValidateSingleDatacenter(t *testing.T) {
errString: "use unsupported DSE version '4.8.0'",
},
{
name: "Dse 5 Invalid",
name: "DSE 5 Invalid",
dc: &CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
Expand Down
2 changes: 2 additions & 0 deletions apis/config/v1beta1/imageconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ type DefaultImages struct {
CassandraImageComponent ImageComponent `json:"cassandra,omitempty"`

DSEImageComponent ImageComponent `json:"dse,omitempty"`

HCDImageComponent ImageComponent `json:"hcd,omitempty"`
}

type ImageComponent struct {
Expand Down
1 change: 1 addition & 0 deletions apis/config/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8887,16 +8887,17 @@ spec:
More info: https://kubernetes.io/docs/concepts/containers/images
type: string
serverType:
description: 'Server type: "cassandra" or "dse"'
description: 'Server type: "cassandra", "dse" or "hcd"'
enum:
- cassandra
- dse
- hcd
type: string
serverVersion:
description: |-
Version string for config builder,
used to generate Cassandra server configuration
pattern: (6\.8\.\d+)|(3\.11\.\d+)|(4\.\d+\.\d+)|(5\.\d+\.\d+)|(7\.\d+\.\d+)
pattern: (6\.[89]\.\d+)|(3\.11\.\d+)|(4\.\d+\.\d+)|(5\.\d+\.\d+)|(1\.\d+\.\d+)
type: string
serviceAccount:
description: Deprecated DeprecatedServiceAccount Use ServiceAccountName
Expand Down
5 changes: 4 additions & 1 deletion config/manager/image_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ defaults:
# Note, postfix is ignored if repository is not set
cassandra:
repository: "k8ssandra/cass-management-api"
# suffix: "-ubi8"
suffix: "-ubi8"
dse:
repository: "datastax/dse-mgmtapi-6_8"
suffix: "-ubi8"
hcd:
repository: "datastax/hcd"
suffix: "-ubi"
32 changes: 25 additions & 7 deletions pkg/images/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ var (
)

const (
ValidDseVersionRegexp = "(6\\.8\\.\\d+)|(7\\.\\d+\\.\\d+)"
ValidDseVersionRegexp = "(6\\.[89]\\.\\d+)"
ValidHcdVersionRegexp = "(1\\.\\d+\\.\\d+)"
ValidOssVersionRegexp = "(3\\.11\\.\\d+)|(4\\.\\d+\\.\\d+)|(5\\.\\d+\\.\\d+)"
DefaultCassandraRepository = "k8ssandra/cass-management-api"
DefaultDSERepository = "datastax/dse-server"
DefaultDSERepository = "datastax/dse-mgmtapi-6_8"
DefaultHCDRepository = "datastax/hcd"
)

func init() {
Expand Down Expand Up @@ -71,6 +73,11 @@ func IsOssVersionSupported(version string) bool {
return validVersions.MatchString(version)
}

func IsHCDVersionSupported(version string) bool {
validVersions := regexp.MustCompile(ValidHcdVersionRegexp)
return validVersions.MatchString(version)
}

func stripRegistry(image string) string {
comps := strings.Split(image, "/")

Expand Down Expand Up @@ -133,10 +140,14 @@ func getImageComponents(serverType string) (string, string) {
defaults := GetImageConfig().DefaultImages
if defaults != nil {
var component configv1beta1.ImageComponent
if serverType == "dse" {
switch serverType {
case "dse":
component = defaults.DSEImageComponent
}
if serverType == "cassandra" {
case "cassandra":
component = defaults.CassandraImageComponent
case "hcd":
component = defaults.HCDImageComponent
default:
component = defaults.CassandraImageComponent
}

Expand All @@ -153,14 +164,21 @@ func GetCassandraImage(serverType, version string) (string, error) {
return ApplyRegistry(image), nil
}

if serverType == "dse" {
switch serverType {
case "dse":
if !IsDseVersionSupported(version) {
return "", fmt.Errorf("server 'dse' and version '%s' do not work together", version)
}
} else {
case "cassandra":
if !IsOssVersionSupported(version) {
return "", fmt.Errorf("server 'cassandra' and version '%s' do not work together", version)
}
case "hcd":
if !IsHCDVersionSupported(version) {
return "", fmt.Errorf("server 'hcd' and version '%s' do not work together", version)
}
default:
return "", fmt.Errorf("server type '%s' is not supported", serverType)
}

prefix, suffix := getImageComponents(serverType)
Expand Down
17 changes: 12 additions & 5 deletions pkg/images/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ func TestCassandraOverride(t *testing.T) {
}

func TestDefaultImageConfigParsing(t *testing.T) {
t.Skip()
assert := require.New(t)
imageConfigFile := filepath.Join("..", "..", "config", "manager", "image_config.yaml")
err := ParseImageConfig(imageConfigFile)
Expand All @@ -80,14 +79,22 @@ func TestDefaultImageConfigParsing(t *testing.T) {
assert.NotNil(GetImageConfig().Images)
assert.True(strings.Contains(GetImageConfig().Images.SystemLogger, "k8ssandra/system-logger:"))
assert.True(strings.Contains(GetImageConfig().Images.ConfigBuilder, "datastax/cass-config-builder:"))
assert.True(strings.Contains(GetImageConfig().Images.Client, "datastax/k8ssandra-client:"))
assert.True(strings.Contains(GetImageConfig().Images.Client, "k8ssandra/k8ssandra-client:"))

assert.Equal("k8ssandra/cass-management-api", GetImageConfig().DefaultImages.CassandraImageComponent.Repository)
assert.Equal("datastax/dse-mgmtapi-6_8", GetImageConfig().DefaultImages.DSEImageComponent.Repository)

path, err := GetCassandraImage("dse", "6.8.17")
path, err := GetCassandraImage("dse", "6.8.47")
assert.NoError(err)
assert.Equal("datastax/dse-mgmtapi-6_8:6.8.47-ubi8", path)

path, err = GetCassandraImage("hcd", "1.0.0")
assert.NoError(err)
assert.Equal("datastax/hcd:1.0.0-ubi", path)

path, err = GetCassandraImage("cassandra", "4.1.4")
assert.NoError(err)
assert.Equal("datastax/dse-mgmtapi-6_8:6.8.17-ubi8", path)
assert.Equal("k8ssandra/cass-management-api:4.1.4-ubi8", path)
}

func TestImageConfigParsing(t *testing.T) {
Expand Down Expand Up @@ -133,7 +140,7 @@ func TestDefaultRepositories(t *testing.T) {

path, err = GetCassandraImage("dse", "6.8.17")
assert.NoError(err)
assert.Equal("datastax/dse-server:6.8.17", path)
assert.Equal("datastax/dse-mgmtapi-6_8:6.8.17", path)
}

func TestOssValidVersions(t *testing.T) {
Expand Down
25 changes: 17 additions & 8 deletions pkg/reconciliation/construct_podtemplatespec.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,11 @@ func buildInitContainers(dc *api.CassandraDatacenter, rackName string, baseTempl
}

configContainer.Command = []string{"/bin/sh"}
configContainer.Args = []string{"-c", "cp -rf /etc/cassandra/* /cassandra-base-config/"}
if dc.Spec.ServerType == "cassandra" {
configContainer.Args = []string{"-c", "cp -rf /etc/cassandra/* /cassandra-base-config/"}
} else if dc.Spec.ServerType == "hcd" {
configContainer.Args = []string{"-c", "cp -rf /opt/hcd/resources/cassandra/conf/* /cassandra-base-config/"}
}
}

configContainer.VolumeMounts = []corev1.VolumeMount{configBaseMount}
Expand Down Expand Up @@ -631,17 +635,22 @@ func buildContainers(dc *api.CassandraDatacenter, baseTemplate *corev1.PodTempla
{Name: "POD_NAME", ValueFrom: selectorFromFieldPath("metadata.name")},
{Name: "NODE_NAME", ValueFrom: selectorFromFieldPath("spec.nodeName")},
{Name: "DS_LICENSE", Value: "accept"},
{Name: "DSE_AUTO_CONF_OFF", Value: "all"},
{Name: "USE_MGMT_API", Value: "true"},
{Name: "MGMT_API_EXPLICIT_START", Value: "true"},
// TODO remove this post 1.0
{Name: "DSE_MGMT_EXPLICIT_START", Value: "true"},
}

if dc.Spec.ServerType == "dse" && dc.Spec.DseWorkloads != nil {
envDefaults = append(
envDefaults,
corev1.EnvVar{Name: "JVM_EXTRA_OPTS", Value: getJvmExtraOpts(dc)})
if dc.Spec.ServerType == "dse" {
envDefaults = append(envDefaults, corev1.EnvVar{Name: "DSE_AUTO_CONF_OFF", Value: "all"})
envDefaults = append(envDefaults, corev1.EnvVar{Name: "DSE_MGMT_EXPLICIT_START", Value: "true"})
if dc.Spec.DseWorkloads != nil {
envDefaults = append(
envDefaults,
corev1.EnvVar{Name: "JVM_EXTRA_OPTS", Value: getJvmExtraOpts(dc)})
}
}

if dc.Spec.ServerType == "hcd" {
envDefaults = append(envDefaults, corev1.EnvVar{Name: "HCD_AUTO_CONF_OFF", Value: "all"})
}

cassContainer.Env = combineEnvSlices(envDefaults, cassContainer.Env)
Expand Down
Loading

0 comments on commit 8d34919

Please sign in to comment.