Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Init container updates for persisting kibana plugins. #8389

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2e7be97
Init container for persisting kibana plugins.
naemono Jan 2, 2025
af17827
rendering configmap script.
naemono Jan 2, 2025
0ca1bca
Adding missing file.
naemono Jan 3, 2025
e7488db
Fixing newpodtemplatespec unit test
naemono Jan 3, 2025
30aca6c
Fix unit tests.
naemono Jan 3, 2025
39d0f3e
Remove unneeded vars/funcs
naemono Jan 3, 2025
2b6b9ef
Add missing duration function
naemono Jan 3, 2025
4280ae5
wip
naemono Jan 6, 2025
77346ac
cleanup
naemono Jan 6, 2025
d43755a
cleanup
naemono Jan 6, 2025
4989861
cleanup
naemono Jan 6, 2025
a485485
re-order the initcontainer config script
naemono Jan 6, 2025
437ef96
Cleanup
naemono Jan 6, 2025
ee769ba
Fix unit tests
naemono Jan 7, 2025
3712ed6
Add test for rendering template.
naemono Jan 7, 2025
87c6bf4
fix e2e kb test telemetry.
naemono Jan 7, 2025
e56d346
optimization
naemono Jan 7, 2025
24b1a88
Add additional unit tests
naemono Jan 7, 2025
e1bd658
Add additional unit tests
naemono Jan 7, 2025
c7c9e86
Add back commented tests
naemono Jan 7, 2025
0ff1cad
Add additional comments/godoc.
naemono Jan 8, 2025
47ec183
Fix comments.
naemono Jan 8, 2025
00b24ed
Add comments, and update comments.
naemono Jan 8, 2025
6d8c390
Adjust namers test to include all namers
naemono Jan 9, 2025
aa648f8
Also consider labels and annotations for needing update.
naemono Jan 9, 2025
accc292
Add 'already copied plugins' file.
naemono Jan 9, 2025
267ba54
always have scripts configmap
naemono Jan 10, 2025
d5903cc
Just use text/template, not html.
naemono Jan 10, 2025
bf06b56
use consistent if err syntax.
naemono Jan 10, 2025
99547b8
don't export.
naemono Jan 10, 2025
566a81d
Check for subset of maps, not equality.
naemono Jan 10, 2025
43a8087
Add labels and annotations to updateReconciled as well.
naemono Jan 10, 2025
af7edef
Inline some functions.
naemono Jan 10, 2025
9f95cbf
remove var
naemono Jan 10, 2025
70799c3
Fix unit tests
naemono Jan 10, 2025
e477764
Also watch configmaps owned by kb.
naemono Jan 10, 2025
a867725
Fix linting issues
naemono Jan 10, 2025
6e9d36a
more linting issues
naemono Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion pkg/apis/kibana/v1/name.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import (
common_name "github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/name"
)

const httpServiceSuffix = "http"
const (
httpServiceSuffix = "http"
scriptsConfigMapSuffix = "scripts"
configSecretSuffix = "config"
)

// KBNamer is a KBNamer that is configured with the defaults for resources related to a Kibana resource.
var KBNamer = common_name.NewNamer("kb")
Expand All @@ -20,3 +24,13 @@ func HTTPService(kbName string) string {
func Deployment(kbName string) string {
return KBNamer.Suffix(kbName)
}

// ScriptsConfigMap returns the name of the ConfigMap containing scripts for the given Kibana resource.
func ScriptsConfigMap(kbName string) string {
return KBNamer.Suffix(kbName, scriptsConfigMapSuffix)
}

// ConfigSecret returns the name of the Secret containing the Kibana configuration for the given Kibana resource.
func ConfigSecret(kb Kibana) string {
return KBNamer.Suffix(kb.Name, configSecretSuffix)
}
52 changes: 40 additions & 12 deletions pkg/apis/kibana/v1/name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,55 @@ package v1

import (
"testing"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestHTTPService(t *testing.T) {
type args struct {
kbName string
}
func TestNamers(t *testing.T) {
tests := []struct {
name string
args args
want string
name string
namer any
arg any
want string
}{
{
name: "sample",
args: args{kbName: "sample"},
want: "sample-kb-http",
name: "test httpService namer",
namer: HTTPService,
arg: "sample",
want: "sample-kb-http",
},
{
name: "test deployment namer",
namer: Deployment,
arg: "sample",
want: "sample-kb",
},
{
name: "test scripts configmap namer",
namer: ScriptsConfigMap,
arg: "sample",
want: "sample-kb-scripts",
},
{
name: "test ConfigSecret namer",
namer: ConfigSecret,
arg: Kibana{ObjectMeta: metav1.ObjectMeta{Name: "sample"}},
want: "sample-kb-config",
},
naemono marked this conversation as resolved.
Show resolved Hide resolved
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := HTTPService(tt.args.kbName); got != tt.want {
t.Errorf("HTTPService() = %v, want %v", got, tt.want)
switch f := tt.namer.(type) {
case func(string) string:
arg := tt.arg.(string) //nolint:forcetypeassert
if got := f(arg); got != tt.want {
t.Errorf("%s = %v, want %v", tt.name, got, tt.want)
}
case func(Kibana) string:
arg := tt.arg.(Kibana) //nolint:forcetypeassert
if got := f(arg); got != tt.want {
t.Errorf("%s = %v, want %v", tt.name, got, tt.want)
}
}
})
}
Expand Down
40 changes: 2 additions & 38 deletions pkg/controller/kibana/config_reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,51 +18,15 @@ import (
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/labels"
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/reconciler"
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/tracing"
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/volume"
kblabel "github.com/elastic/cloud-on-k8s/v2/pkg/controller/kibana/label"
"github.com/elastic/cloud-on-k8s/v2/pkg/utils/k8s"
)

// Constants to use for the config files in a Kibana pod.
const (
ConfigVolumeName = "elastic-internal-kibana-config-local"
ConfigVolumeMountPath = "/usr/share/kibana/config"
InitContainerConfigVolumeMountPath = "/mnt/elastic-internal/kibana-config-local"

// InternalConfigVolumeName is a volume which contains the generated configuration.
InternalConfigVolumeName = "elastic-internal-kibana-config"
InternalConfigVolumeMountPath = "/mnt/elastic-internal/kibana-config"

TelemetryFilename = "telemetry.yml"
)

var (
// ConfigSharedVolume contains the Kibana config/ directory, it's an empty volume where the required configuration
// is initialized by the elastic-internal-init-config init container. Its content is then shared by the init container
// that creates the keystore and the main Kibana container.
// This is needed in order to have in a same directory both the generated configuration and the keystore file which
// is created in /usr/share/kibana/config since Kibana 7.9
ConfigSharedVolume = volume.SharedVolume{
VolumeName: ConfigVolumeName,
InitContainerMountPath: InitContainerConfigVolumeMountPath,
ContainerMountPath: ConfigVolumeMountPath,
}
)

// ConfigVolume returns a SecretVolume to hold the Kibana config of the given Kibana resource.
func ConfigVolume(kb kbv1.Kibana) volume.SecretVolume {
return volume.NewSecretVolumeWithMountPath(
SecretName(kb),
InternalConfigVolumeName,
InternalConfigVolumeMountPath,
)
}

// SecretName is the name of the secret that holds the Kibana config for the given Kibana resource.
func SecretName(kb kbv1.Kibana) string {
return kb.Name + "-kb-config"
}

// ReconcileConfigSecret reconciles the expected Kibana config secret for the given Kibana resource.
// This managed secret is mounted into each pod of the Kibana deployment.
func ReconcileConfigSecret(
Expand Down Expand Up @@ -95,7 +59,7 @@ func ReconcileConfigSecret(
expected := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: kb.Namespace,
Name: SecretName(kb),
Name: kbv1.ConfigSecret(kb),
Labels: labels.AddCredentialsLabel(map[string]string{
kblabel.KibanaNameLabelName: kb.Name,
}),
Expand All @@ -111,7 +75,7 @@ func ReconcileConfigSecret(
// if the Secret or usage key doesn't exist yet.
func getTelemetryYamlBytes(client k8s.Client, kb kbv1.Kibana) ([]byte, error) {
var secret corev1.Secret
if err := client.Get(context.Background(), types.NamespacedName{Namespace: kb.Namespace, Name: SecretName(kb)}, &secret); err != nil {
if err := client.Get(context.Background(), types.NamespacedName{Namespace: kb.Namespace, Name: kbv1.ConfigSecret(kb)}, &secret); err != nil {
if apierrors.IsNotFound(err) {
// this secret is just about to be created, we don't know usage yet
return nil, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/kibana/config_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ type reusableSettings struct {
func getExistingConfig(ctx context.Context, client k8s.Client, kb kbv1.Kibana) (*settings.CanonicalConfig, error) {
log := ulog.FromContext(ctx)
var secret corev1.Secret
err := client.Get(context.Background(), types.NamespacedName{Name: SecretName(kb), Namespace: kb.Namespace}, &secret)
err := client.Get(context.Background(), types.NamespacedName{Name: kbv1.ConfigSecret(kb), Namespace: kb.Namespace}, &secret)
if err != nil && apierrors.IsNotFound(err) {
log.V(1).Info("Kibana config secret does not exist", "namespace", kb.Namespace, "kibana_name", kb.Name)
return nil, nil
Expand Down
20 changes: 10 additions & 10 deletions pkg/controller/kibana/config_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func Test_reuseOrGenerateSecrets(t *testing.T) {
args: args{
c: k8s.NewFakeClient(
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Namespace: defaultKb.Namespace, Name: SecretName(defaultKb)},
ObjectMeta: metav1.ObjectMeta{Namespace: defaultKb.Namespace, Name: kbv1.ConfigSecret(defaultKb)},
Data: map[string][]byte{
SettingsFilename: defaultConfig,
},
Expand All @@ -127,7 +127,7 @@ func Test_reuseOrGenerateSecrets(t *testing.T) {
args: args{
c: k8s.NewFakeClient(
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Namespace: defaultKb.Namespace, Name: SecretName(defaultKb)},
ObjectMeta: metav1.ObjectMeta{Namespace: defaultKb.Namespace, Name: kbv1.ConfigSecret(defaultKb)},
Data: map[string][]byte{
SettingsFilename: esAssociationConfig,
},
Expand All @@ -151,7 +151,7 @@ func Test_reuseOrGenerateSecrets(t *testing.T) {
args: args{
c: k8s.NewFakeClient(
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Namespace: defaultKb.Namespace, Name: SecretName(defaultKb)},
ObjectMeta: metav1.ObjectMeta{Namespace: defaultKb.Namespace, Name: kbv1.ConfigSecret(defaultKb)},
Data: map[string][]byte{
SettingsFilename: esAssociationConfig,
},
Expand Down Expand Up @@ -186,7 +186,7 @@ func TestNewConfigSettings(t *testing.T) {
defaultKb := mkKibana()
existingSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: SecretName(defaultKb),
Name: kbv1.ConfigSecret(defaultKb),
Namespace: defaultKb.Namespace,
},
Data: map[string][]byte{
Expand Down Expand Up @@ -519,7 +519,7 @@ func TestNewConfigSettings(t *testing.T) {
args: args{
client: k8s.NewFakeClient(&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: SecretName(defaultKb),
Name: kbv1.ConfigSecret(defaultKb),
Namespace: defaultKb.Namespace,
},
Data: map[string][]byte{
Expand All @@ -544,7 +544,7 @@ func TestNewConfigSettings(t *testing.T) {
args: args{
client: k8s.NewFakeClient(&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: SecretName(defaultKb),
Name: kbv1.ConfigSecret(defaultKb),
Namespace: defaultKb.Namespace,
},
Data: map[string][]byte{
Expand Down Expand Up @@ -607,7 +607,7 @@ func TestNewConfigSettingsExistingEncryptionKey(t *testing.T) {
savedObjsKey := "savedObjsKey"
existingSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: SecretName(kb),
Name: kbv1.ConfigSecret(kb),
Namespace: kb.Namespace,
},
Data: map[string][]byte{
Expand Down Expand Up @@ -686,7 +686,7 @@ func Test_getExistingConfig(t *testing.T) {
}
testValidSecret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: SecretName(testKb),
Name: kbv1.ConfigSecret(testKb),
Namespace: testKb.Namespace,
},
Data: map[string][]byte{
Expand All @@ -695,7 +695,7 @@ func Test_getExistingConfig(t *testing.T) {
}
testNoYaml := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: SecretName(testKb),
Name: kbv1.ConfigSecret(testKb),
Namespace: testKb.Namespace,
},
Data: map[string][]byte{
Expand All @@ -704,7 +704,7 @@ func Test_getExistingConfig(t *testing.T) {
}
testInvalidYaml := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: SecretName(testKb),
Name: kbv1.ConfigSecret(testKb),
Namespace: testKb.Namespace,
},
Data: map[string][]byte{
Expand Down
8 changes: 8 additions & 0 deletions pkg/controller/kibana/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileKibana
return err
}

// Watch configmaps
if err := c.Watch(source.Kind(mgr.GetCache(), &corev1.ConfigMap{}, handler.TypedEnqueueRequestForOwner[*corev1.ConfigMap](
mgr.GetScheme(), mgr.GetRESTMapper(),
&kbv1.Kibana{}, handler.OnlyControllerOwner(),
))); err != nil {
return err
}

// dynamically watch referenced secrets to connect to Elasticsearch
return c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, r.dynamicWatches.Secrets))
}
Expand Down
17 changes: 10 additions & 7 deletions pkg/controller/kibana/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/version"
commonvolume "github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/volume"
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/watches"
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/kibana/initcontainer"
kblabel "github.com/elastic/cloud-on-k8s/v2/pkg/controller/kibana/label"
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/kibana/network"
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/kibana/stackmon"
Expand Down Expand Up @@ -160,8 +161,7 @@ func (d *driver) Reconcile(
return results.WithError(err)
}

err = ReconcileConfigSecret(ctx, d.client, *kb, kbSettings)
if err != nil {
if err = ReconcileConfigSecret(ctx, d.client, *kb, kbSettings); err != nil {
return results.WithError(err)
}

Expand All @@ -170,8 +170,11 @@ func (d *driver) Reconcile(
return results.WithError(err)
}

err = stackmon.ReconcileConfigSecrets(ctx, d.client, *kb, basePath)
if err != nil {
if err = stackmon.ReconcileConfigSecrets(ctx, d.client, *kb, basePath); err != nil {
return results.WithError(err)
}

if err = initcontainer.ReconcileScriptsConfigMap(ctx, d.client, *kb); err != nil {
return results.WithError(err)
}

Expand Down Expand Up @@ -226,7 +229,7 @@ func (d *driver) getStrategyType(kb *kbv1.Kibana) (appsv1.DeploymentStrategyType
}

func (d *driver) deploymentParams(ctx context.Context, kb *kbv1.Kibana, policyAnnotations map[string]string, basePath string, setDefaultSecurityContext bool) (deployment.Params, error) {
initContainersParameters, err := newInitContainersParameters(kb)
initContainersParameters, err := initcontainer.NewInitContainersParameters(kb)
if err != nil {
return deployment.Params{}, err
}
Expand Down Expand Up @@ -282,7 +285,7 @@ func (d *driver) deploymentParams(ctx context.Context, kb *kbv1.Kibana, policyAn

// get config secret to add its content to the config checksum
configSecret := corev1.Secret{}
err = d.client.Get(ctx, types.NamespacedName{Name: SecretName(*kb), Namespace: kb.Namespace}, &configSecret)
err = d.client.Get(ctx, types.NamespacedName{Name: kbv1.ConfigSecret(*kb), Namespace: kb.Namespace}, &configSecret)
if err != nil {
return deployment.Params{}, err
}
Expand Down Expand Up @@ -314,7 +317,7 @@ func (d *driver) deploymentParams(ctx context.Context, kb *kbv1.Kibana, policyAn
}

func (d *driver) buildVolumes(kb *kbv1.Kibana) ([]commonvolume.VolumeLike, error) {
volumes := []commonvolume.VolumeLike{DataVolume, ConfigSharedVolume, ConfigVolume(*kb)}
volumes := []commonvolume.VolumeLike{DataVolume, initcontainer.ConfigSharedVolume, initcontainer.ConfigVolume(*kb)}

esAssocConf, err := kb.EsAssociation().AssociationConf()
if err != nil {
Expand Down
Loading