Skip to content

Commit

Permalink
Enable client-side CQL encryption in Stargate if it is configured on …
Browse files Browse the repository at this point in the history
…the cluster
  • Loading branch information
olim7t committed Oct 20, 2022
1 parent 237a335 commit 1a6e592
Show file tree
Hide file tree
Showing 15 changed files with 224 additions and 90 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG/CHANGELOG-1.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ When cutting a new release, update the `unreleased` heading to the tag being gen
* [FEATURE] [#599](https://github.com/k8ssandra/k8ssandra-operator/issues/599) Introduce a secrets provider setting in the CRD
* [FEATURE] [#728](https://github.com/k8ssandra/k8ssandra-operator/issues/728) Add token generation utility
* [FEATURE] [#724](https://github.com/k8ssandra/k8ssandra-operator/issues/724) Ability to provide per-node configuration
[FEATURE] [#718](https://github.com/k8ssandra/k8ssandra-operator/issues/718) Make keystore-password, keystore, truststore keys in secret configurable
[FEATURE] [#718](https://github.com/k8ssandra/k8ssandra-operator/issues/718) Make keystore-password, keystore, truststore keys in secret configurable
* [BUGFIX] [#722](https://github.com/k8ssandra/k8ssandra-operator/issues/722) Enable client-side CQL encryption in Stargate if it is configured on the cluster
2 changes: 1 addition & 1 deletion apis/stargate/v1alpha1/stargate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type StargateTemplate struct {
// ContainerImage is the image characteristics to use for Stargate containers. Leave nil
// to use a default image.
// +optional
// +kubebuilder:default={repository:"stargateio", tag:"v1.0.45"}
// +kubebuilder:default={repository:"stargateio", tag:"v1.0.66"}
ContainerImage *images.Image `json:"containerImage,omitempty"`

// ServiceAccount is the service account name to use for Stargate pods.
Expand Down
6 changes: 3 additions & 3 deletions config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8473,7 +8473,7 @@ spec:
containerImage:
default:
repository: stargateio
tag: v1.0.45
tag: v1.0.66
description: ContainerImage is the image characteristics
to use for Stargate containers. Leave nil to use a
default image.
Expand Down Expand Up @@ -9898,7 +9898,7 @@ spec:
containerImage:
default:
repository: stargateio
tag: v1.0.45
tag: v1.0.66
description: ContainerImage is the image characteristics
to use for Stargate containers. Leave nil to
use a default image.
Expand Down Expand Up @@ -18525,7 +18525,7 @@ spec:
containerImage:
default:
repository: stargateio
tag: v1.0.45
tag: v1.0.66
description: ContainerImage is the image characteristics to use
for Stargate containers. Leave nil to use a default image.
properties:
Expand Down
4 changes: 2 additions & 2 deletions config/crd/bases/stargate.k8ssandra.io_stargates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,7 @@ spec:
containerImage:
default:
repository: stargateio
tag: v1.0.45
tag: v1.0.66
description: ContainerImage is the image characteristics to use for
Stargate containers. Leave nil to use a default image.
properties:
Expand Down Expand Up @@ -2265,7 +2265,7 @@ spec:
containerImage:
default:
repository: stargateio
tag: v1.0.45
tag: v1.0.66
description: ContainerImage is the image characteristics to
use for Stargate containers. Leave nil to use a default image.
properties:
Expand Down
65 changes: 43 additions & 22 deletions controllers/stargate/stargate_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,17 @@ func (r *StargateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
}

// if a configmap is specified, we need to read its content to merge it with the generated one
userConfigMapContent := ""
userStargateCassandraYaml := ""
userStargateCqlYaml := ""
if stargate.Spec.CassandraConfigMapRef != nil {
userConfigMap := &corev1.ConfigMap{}
configMapKey := types.NamespacedName{Namespace: req.Namespace, Name: stargate.Spec.CassandraConfigMapRef.Name}
err := r.Get(ctx, configMapKey, userConfigMap)
if err != nil {
return ctrl.Result{}, err
}
userConfigMapContent = userConfigMap.Data["cassandra.yaml"]
userStargateCassandraYaml = userConfigMap.Data["cassandra.yaml"]
userStargateCqlYaml = userConfigMap.Data[stargateutil.CqlConfigName]
}

logger.Info("Reconciling Stargate configmap")
Expand All @@ -154,7 +156,7 @@ func (r *StargateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
}
}

if stargateConfigResult, err := r.reconcileStargateConfigMap(ctx, stargate, dcConfig, userConfigMapContent, req.Namespace, *actualDc, logger); err != nil {
if stargateConfigResult, err := r.reconcileStargateConfigMap(ctx, stargate, dcConfig, userStargateCassandraYaml, userStargateCqlYaml, req.Namespace, *actualDc, logger); err != nil {
return ctrl.Result{}, err
} else {
if stargateConfigResult.Requeue {
Expand Down Expand Up @@ -398,42 +400,39 @@ func (r *StargateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
func (r *StargateReconciler) reconcileStargateConfigMap(
ctx context.Context,
stargateObject *api.Stargate,
desiredConfig map[string]interface{},
userConfigMapContent string,
dcConfig map[string]interface{},
userCassandraYaml, userCqlYaml string,
namespace string,
dc cassdcapi.CassandraDatacenter,
logger logr.Logger,
) (ctrl.Result, error) {
logger.Info(fmt.Sprintf("Reconciling Stargate Cassandra yaml configMap on namespace %s for cluster %s and dc %s", namespace, dc.Spec.ClusterName, dc.Name))
var filteredCassandraConfig map[string]interface{}
desiredCassandraYaml, exists := desiredConfig["cassandra-yaml"]
if exists {
filteredCassandraConfig = stargate.FilterYamlConfig(desiredCassandraYaml.(map[string]interface{}))
}

configYamlString := ""
if len(filteredCassandraConfig) > 0 {
if configYaml, err := yaml.Marshal(filteredCassandraConfig); err != nil {
return ctrl.Result{}, err
} else {
configYamlString = string(configYaml)
}
var cassandraYaml, cqlYaml string
var err error
if cassandraYaml, err = reconcileStargateConfigFile(userCassandraYaml, dcConfig, stargate.CassandraYamlRetainedSettings); err != nil {
return ctrl.Result{}, err
}
if cqlYaml, err = reconcileStargateConfigFile(userCqlYaml, dcConfig, stargate.CqlYamlRetainedSettings); err != nil {
return ctrl.Result{}, err
}
if len(cqlYaml) == 0 {
// The Stargate code fails on an empty file. Replace with this which is valid YAML:
cqlYaml = "{}"
}

mergedConfigMap := stargate.MergeConfigMaps(userConfigMapContent, configYamlString)

configMapKey := client.ObjectKey{
Namespace: namespace,
Name: stargate.GeneratedConfigMapName(dc.Spec.ClusterName, dc.Name),
}

logger = logger.WithValues("StargateConfigMap", configMapKey)
desiredConfigMap := stargate.CreateStargateConfigMap(namespace, mergedConfigMap, dc)
desiredConfigMap := stargate.CreateStargateConfigMap(namespace, cassandraYaml, cqlYaml, dc)
// Compute a hash which will allow to compare desired and actual configMaps
annotations.AddHashAnnotation(desiredConfigMap)
actualConfigMap := &corev1.ConfigMap{}

if err := r.Get(ctx, configMapKey, actualConfigMap); err != nil {
if err = r.Get(ctx, configMapKey, actualConfigMap); err != nil {
if errors.IsNotFound(err) {
if err = controllerutil.SetControllerReference(stargateObject, desiredConfigMap, r.Scheme); err != nil {
return ctrl.Result{}, err
Expand All @@ -454,7 +453,7 @@ func (r *StargateReconciler) reconcileStargateConfigMap(
resourceVersion := actualConfigMap.GetResourceVersion()
desiredConfigMap.DeepCopyInto(actualConfigMap)
actualConfigMap.SetResourceVersion(resourceVersion)
if err := r.Update(ctx, actualConfigMap); err != nil {
if err = r.Update(ctx, actualConfigMap); err != nil {
logger.Error(err, "Failed to update Stargate ConfigMap resource")
return ctrl.Result{}, err
}
Expand All @@ -464,6 +463,28 @@ func (r *StargateReconciler) reconcileStargateConfigMap(
return ctrl.Result{}, nil
}

// reconcileStargateConfigFile builds a Stargate config file from two different sources: userConfig is the user-provided
// config passed via cassandraConfigMapRef in the Stargate spec; dcConfig is the DC-level config from the
// CassandraDatacenter spec, of which we'll only keep retainedOptions.
func reconcileStargateConfigFile(
userConfig string, dcConfig map[string]interface{}, retainedOptions []string,
) (string, error) {
var dcYaml map[string]interface{}
dcFullYaml, exists := dcConfig["cassandra-yaml"]
if exists {
dcYaml = stargate.FilterConfig(dcFullYaml.(map[string]interface{}), retainedOptions)
}
dcYamlString := ""
if len(dcYaml) > 0 {
if out, err := yaml.Marshal(dcYaml); err != nil {
return "", err
} else {
dcYamlString = string(out)
}
}
return stargate.MergeYamlString(userConfig, dcYamlString), nil
}

// SetupWithManager sets up the controller with the Manager.
func (r *StargateReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
Expand Down
9 changes: 6 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/apache/tinkerpop/gremlin-go v0.0.0-20220530191148-29272fa563ec
github.com/bombsimon/logrusr/v2 v2.0.1
github.com/datastax/go-cassandra-native-protocol v0.0.0-20210829124742-a80a54434112
github.com/datastax/go-cassandra-native-protocol v0.0.0-20220706104457-5e8aad05cf90
github.com/davecgh/go-spew v1.1.1
github.com/go-logr/logr v1.2.3
github.com/go-logr/zapr v1.2.3
Expand All @@ -20,8 +20,9 @@ require (
github.com/robfig/cron/v3 v3.0.1
github.com/rs/zerolog v1.20.0
github.com/sirupsen/logrus v1.8.1
github.com/square/certigo v1.16.0
github.com/stargate/stargate-grpc-go-client v0.0.0-20220822130422-9a1c6261d4fa
github.com/stretchr/testify v1.7.0
github.com/stretchr/testify v1.7.5
go.uber.org/zap v1.19.1
google.golang.org/grpc v1.40.0
google.golang.org/protobuf v1.28.0
Expand Down Expand Up @@ -57,6 +58,7 @@ require (
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/go-querystring v1.1.0 // indirect
Expand All @@ -72,13 +74,14 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nicksnyder/go-i18n/v2 v2.2.0 // indirect
github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible // indirect
github.com/pierrec/lz4/v4 v4.0.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/objx v0.4.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
Expand Down
Loading

0 comments on commit 1a6e592

Please sign in to comment.