feat: additional environment variables

Signed-off-by: Leonardo Cecchi <leonardo.cecchi@enterprisedb.com>
This commit is contained in:
Leonardo Cecchi 2024-12-03 09:13:03 +01:00
parent e30edd2318
commit b038e2e499
4 changed files with 115 additions and 12 deletions

View File

@ -18,6 +18,8 @@ package v1
import (
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@ -29,6 +31,10 @@ type InstanceSidecarConfiguration struct {
// +kubebuilder:validation:Maximum=3600
// +kubebuilder:default=180
CacheTTL *int `json:"cacheTTL,omitempty"`
// The environment to be explicitely passed to the sidecar
// +optional
Env []corev1.EnvVar `json:"env,omitempty"`
}
// GetCacheTTL returns the cache TTL value, defaulting to 180 seconds if not set.

View File

@ -14,8 +14,11 @@ import (
"github.com/spf13/viper"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
)
@ -23,6 +26,7 @@ import (
// LifecycleImplementation is the implementation of the lifecycle handler
type LifecycleImplementation struct {
lifecycle.UnimplementedOperatorLifecycleServer
Client client.Client
}
// GetCapabilities exposes the lifecycle capabilities
@ -94,20 +98,85 @@ func (impl LifecycleImplementation) LifecycleHook(
switch kind {
case "Pod":
contextLogger.Info("Reconciling pod")
return reconcilePod(ctx, &cluster, request, pluginConfiguration)
return impl.reconcilePod(ctx, &cluster, request, pluginConfiguration)
case "Job":
contextLogger.Info("Reconciling job")
return reconcileJob(ctx, &cluster, request, pluginConfiguration)
return impl.reconcileJob(ctx, &cluster, request, pluginConfiguration)
default:
return nil, fmt.Errorf("unsupported kind: %s", kind)
}
}
func (impl LifecycleImplementation) collectAdditionalEnvs(
ctx context.Context,
namespace string,
pluginConfiguration *config.PluginConfiguration,
) ([]corev1.EnvVar, error) {
var result []corev1.EnvVar
if len(pluginConfiguration.BarmanObjectName) > 0 {
envs, err := impl.collectObjectStoreEnvs(
ctx,
types.NamespacedName{
Name: pluginConfiguration.BarmanObjectName,
Namespace: namespace,
},
)
if err != nil {
return nil, err
}
result = append(result, envs...)
}
if len(pluginConfiguration.RecoveryBarmanObjectName) > 0 {
envs, err := impl.collectObjectStoreEnvs(
ctx,
types.NamespacedName{
Name: pluginConfiguration.RecoveryBarmanObjectName,
Namespace: namespace,
},
)
if err != nil {
return nil, err
}
result = append(result, envs...)
}
return result, nil
}
func (impl LifecycleImplementation) collectObjectStoreEnvs(
ctx context.Context,
barmanObjectKey types.NamespacedName,
) ([]corev1.EnvVar, error) {
var objectStore barmancloudv1.ObjectStore
if err := impl.Client.Get(ctx, barmanObjectKey, &objectStore); err != nil {
return nil, err
}
return objectStore.Spec.InstanceSidecarConfiguration.Env, nil
}
func (impl LifecycleImplementation) reconcileJob(
ctx context.Context,
cluster *cnpgv1.Cluster,
request *lifecycle.OperatorLifecycleRequest,
pluginConfiguration *config.PluginConfiguration,
) (*lifecycle.OperatorLifecycleResponse, error) {
env, err := impl.collectAdditionalEnvs(ctx, cluster.Namespace, pluginConfiguration)
if err != nil {
return nil, nil
}
return reconcileJob(ctx, cluster, request, pluginConfiguration, env)
}
func reconcileJob(
ctx context.Context,
cluster *cnpgv1.Cluster,
request *lifecycle.OperatorLifecycleRequest,
pluginConfiguration *config.PluginConfiguration,
env []corev1.EnvVar,
) (*lifecycle.OperatorLifecycleResponse, error) {
contextLogger := log.FromContext(ctx).WithName("lifecycle")
if pluginConfig := cluster.GetRecoverySourcePlugin(); pluginConfig == nil || pluginConfig.Name != metadata.PluginName {
@ -144,6 +213,7 @@ func reconcileJob(
corev1.Container{
Args: []string{"restore"},
},
env,
); err != nil {
return nil, fmt.Errorf("while reconciling pod spec for job: %w", err)
}
@ -159,11 +229,26 @@ func reconcileJob(
}, nil
}
func (impl LifecycleImplementation) reconcilePod(
ctx context.Context,
cluster *cnpgv1.Cluster,
request *lifecycle.OperatorLifecycleRequest,
pluginConfiguration *config.PluginConfiguration,
) (*lifecycle.OperatorLifecycleResponse, error) {
env, err := impl.collectAdditionalEnvs(ctx, cluster.Namespace, pluginConfiguration)
if err != nil {
return nil, nil
}
return reconcilePod(ctx, cluster, request, pluginConfiguration, env)
}
func reconcilePod(
ctx context.Context,
cluster *cnpgv1.Cluster,
request *lifecycle.OperatorLifecycleRequest,
pluginConfiguration *config.PluginConfiguration,
env []corev1.EnvVar,
) (*lifecycle.OperatorLifecycleResponse, error) {
pod, err := decoder.DecodePodJSON(request.GetObjectDefinition())
if err != nil {
@ -176,9 +261,16 @@ func reconcilePod(
mutatedPod := pod.DeepCopy()
if len(pluginConfiguration.BarmanObjectName) != 0 {
if err := reconcilePodSpec(pluginConfiguration, cluster, &mutatedPod.Spec, "postgres", corev1.Container{
Args: []string{"instance"},
}); err != nil {
if err := reconcilePodSpec(
pluginConfiguration,
cluster,
&mutatedPod.Spec,
"postgres",
corev1.Container{
Args: []string{"instance"},
},
env,
); err != nil {
return nil, fmt.Errorf("while reconciling pod spec for pod: %w", err)
}
} else {
@ -202,6 +294,7 @@ func reconcilePodSpec(
spec *corev1.PodSpec,
mainContainerName string,
sidecarConfig corev1.Container,
additionalEnvs []corev1.EnvVar,
) error {
envs := []corev1.EnvVar{
{
@ -246,6 +339,8 @@ func reconcilePodSpec(
)
}
envs = append(envs, additionalEnvs...)
baseProbe := &corev1.Probe{
FailureThreshold: 3,
ProbeHandler: corev1.ProbeHandler{

View File

@ -107,7 +107,7 @@ var _ = Describe("LifecycleImplementation", func() {
ObjectDefinition: jobJSON,
}
response, err := reconcileJob(ctx, cluster, request, pluginConfiguration)
response, err := reconcileJob(ctx, cluster, request, pluginConfiguration, nil)
Expect(err).NotTo(HaveOccurred())
Expect(response).NotTo(BeNil())
Expect(response.JsonPatch).NotTo(BeEmpty())
@ -128,7 +128,7 @@ var _ = Describe("LifecycleImplementation", func() {
ObjectDefinition: jobJSON,
}
response, err := reconcileJob(ctx, cluster, request, pluginConfiguration)
response, err := reconcileJob(ctx, cluster, request, pluginConfiguration, nil)
Expect(err).NotTo(HaveOccurred())
Expect(response).To(BeNil())
})
@ -138,7 +138,7 @@ var _ = Describe("LifecycleImplementation", func() {
ObjectDefinition: []byte("invalid-json"),
}
response, err := reconcileJob(ctx, cluster, request, pluginConfiguration)
response, err := reconcileJob(ctx, cluster, request, pluginConfiguration, nil)
Expect(err).To(HaveOccurred())
Expect(response).To(BeNil())
})
@ -165,7 +165,7 @@ var _ = Describe("LifecycleImplementation", func() {
ObjectDefinition: jobJSON,
}
response, err := reconcileJob(ctx, cluster, request, pluginConfiguration)
response, err := reconcileJob(ctx, cluster, request, pluginConfiguration, nil)
Expect(err).NotTo(HaveOccurred())
Expect(response).To(BeNil())
})
@ -185,7 +185,7 @@ var _ = Describe("LifecycleImplementation", func() {
ObjectDefinition: podJSON,
}
response, err := reconcilePod(ctx, cluster, request, pluginConfiguration)
response, err := reconcilePod(ctx, cluster, request, pluginConfiguration, nil)
Expect(err).NotTo(HaveOccurred())
Expect(response).NotTo(BeNil())
Expect(response.JsonPatch).NotTo(BeEmpty())
@ -203,7 +203,7 @@ var _ = Describe("LifecycleImplementation", func() {
ObjectDefinition: []byte("invalid-json"),
}
response, err := reconcilePod(ctx, cluster, request, pluginConfiguration)
response, err := reconcilePod(ctx, cluster, request, pluginConfiguration, nil)
Expect(err).To(HaveOccurred())
Expect(response).To(BeNil())
})

View File

@ -27,7 +27,9 @@ func (c *CNPGI) Start(ctx context.Context) error {
reconciler.RegisterReconcilerHooksServer(server, ReconcilerImplementation{
Client: c.Client,
})
lifecycle.RegisterOperatorLifecycleServer(server, LifecycleImplementation{})
lifecycle.RegisterOperatorLifecycleServer(server, LifecycleImplementation{
Client: c.Client,
})
return nil
}