mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-08 16:33:26 +02:00
Standby cluster promotion by changing manifest (#2472)
* Standby cluster promotion by changing manifest * Updated the documentation --------- Co-authored-by: Senthilnathan M <snathanm@vmware.com>
This commit is contained in:
co-authored by
Senthilnathan M
parent
bbba15f9bf
commit
dad5b132ec
@@ -2,6 +2,7 @@ package cluster
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
@@ -480,6 +481,140 @@ func TestCheckAndSetGlobalPostgreSQLConfiguration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncStandbyClusterConfiguration(t *testing.T) {
|
||||
client, _ := newFakeK8sSyncClient()
|
||||
clusterName := "acid-standby-cluster"
|
||||
applicationLabel := "spilo"
|
||||
namespace := "default"
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
pg := acidv1.Postgresql{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: clusterName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: acidv1.PostgresSpec{
|
||||
NumberOfInstances: int32(1),
|
||||
Volume: acidv1.Volume{
|
||||
Size: "1Gi",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var cluster = New(
|
||||
Config{
|
||||
OpConfig: config.Config{
|
||||
PatroniAPICheckInterval: time.Duration(1),
|
||||
PatroniAPICheckTimeout: time.Duration(5),
|
||||
PodManagementPolicy: "ordered_ready",
|
||||
Resources: config.Resources{
|
||||
ClusterLabels: map[string]string{"application": applicationLabel},
|
||||
ClusterNameLabel: "cluster-name",
|
||||
DefaultCPURequest: "300m",
|
||||
DefaultCPULimit: "300m",
|
||||
DefaultMemoryRequest: "300Mi",
|
||||
DefaultMemoryLimit: "300Mi",
|
||||
MinInstances: int32(-1),
|
||||
MaxInstances: int32(-1),
|
||||
PodRoleLabel: "spilo-role",
|
||||
ResourceCheckInterval: time.Duration(3),
|
||||
ResourceCheckTimeout: time.Duration(10),
|
||||
},
|
||||
},
|
||||
}, client, pg, logger, eventRecorder)
|
||||
|
||||
cluster.Name = clusterName
|
||||
cluster.Namespace = namespace
|
||||
|
||||
// mocking a config after getConfig is called
|
||||
mockClient := mocks.NewMockHTTPClient(ctrl)
|
||||
configJson := `{"ttl": 20}`
|
||||
r := ioutil.NopCloser(bytes.NewReader([]byte(configJson)))
|
||||
response := http.Response{
|
||||
StatusCode: 200,
|
||||
Body: r,
|
||||
}
|
||||
mockClient.EXPECT().Get(gomock.Any()).Return(&response, nil).AnyTimes()
|
||||
|
||||
// mocking a config after setConfig is called
|
||||
standbyJson := `{"standby_cluster":{"create_replica_methods":["bootstrap_standby_with_wale","basebackup_fast_xlog"],"restore_command":"envdir \"/run/etc/wal-e.d/env-standby\" /scripts/restore_command.sh \"%f\" \"%p\""}}`
|
||||
r = ioutil.NopCloser(bytes.NewReader([]byte(standbyJson)))
|
||||
response = http.Response{
|
||||
StatusCode: 200,
|
||||
Body: r,
|
||||
}
|
||||
mockClient.EXPECT().Do(gomock.Any()).Return(&response, nil).AnyTimes()
|
||||
p := patroni.New(patroniLogger, mockClient)
|
||||
cluster.patroni = p
|
||||
|
||||
mockPod := newMockPod("192.168.100.1")
|
||||
mockPod.Name = fmt.Sprintf("%s-0", clusterName)
|
||||
mockPod.Namespace = namespace
|
||||
podLabels := map[string]string{
|
||||
"cluster-name": clusterName,
|
||||
"application": applicationLabel,
|
||||
"spilo-role": "master",
|
||||
}
|
||||
mockPod.Labels = podLabels
|
||||
client.PodsGetter.Pods(namespace).Create(context.TODO(), mockPod, metav1.CreateOptions{})
|
||||
|
||||
// create a statefulset
|
||||
sts, err := cluster.createStatefulSet()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// check that pods do not have a STANDBY_* environment variable
|
||||
assert.NotContains(t, sts.Spec.Template.Spec.Containers[0].Env, v1.EnvVar{Name: "STANDBY_METHOD", Value: "STANDBY_WITH_WALE"})
|
||||
|
||||
// add standby section
|
||||
cluster.Spec.StandbyCluster = &acidv1.StandbyDescription{
|
||||
S3WalPath: "s3://custom/path/to/bucket/",
|
||||
}
|
||||
cluster.syncStatefulSet()
|
||||
updatedSts := cluster.Statefulset
|
||||
|
||||
// check that pods do not have a STANDBY_* environment variable
|
||||
assert.Contains(t, updatedSts.Spec.Template.Spec.Containers[0].Env, v1.EnvVar{Name: "STANDBY_METHOD", Value: "STANDBY_WITH_WALE"})
|
||||
|
||||
// this should update the Patroni config
|
||||
err = cluster.syncStandbyClusterConfiguration()
|
||||
assert.NoError(t, err)
|
||||
|
||||
configJson = `{"standby_cluster":{"create_replica_methods":["bootstrap_standby_with_wale","basebackup_fast_xlog"],"restore_command":"envdir \"/run/etc/wal-e.d/env-standby\" /scripts/restore_command.sh \"%f\" \"%p\""}, "ttl": 20}`
|
||||
r = ioutil.NopCloser(bytes.NewReader([]byte(configJson)))
|
||||
response = http.Response{
|
||||
StatusCode: 200,
|
||||
Body: r,
|
||||
}
|
||||
mockClient.EXPECT().Get(gomock.Any()).Return(&response, nil).AnyTimes()
|
||||
|
||||
pods, err := cluster.listPods()
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, _, err = cluster.patroni.GetConfig(&pods[0])
|
||||
assert.NoError(t, err)
|
||||
// ToDo extend GetConfig to return standy_cluster setting to compare
|
||||
/*
|
||||
defaultStandbyParameters := map[string]interface{}{
|
||||
"create_replica_methods": []string{"bootstrap_standby_with_wale", "basebackup_fast_xlog"},
|
||||
"restore_command": "envdir \"/run/etc/wal-e.d/env-standby\" /scripts/restore_command.sh \"%f\" \"%p\"",
|
||||
}
|
||||
assert.True(t, reflect.DeepEqual(defaultStandbyParameters, standbyCluster))
|
||||
*/
|
||||
// remove standby section
|
||||
cluster.Spec.StandbyCluster = &acidv1.StandbyDescription{}
|
||||
cluster.syncStatefulSet()
|
||||
updatedSts2 := cluster.Statefulset
|
||||
|
||||
// check that pods do not have a STANDBY_* environment variable
|
||||
assert.NotContains(t, updatedSts2.Spec.Template.Spec.Containers[0].Env, v1.EnvVar{Name: "STANDBY_METHOD", Value: "STANDBY_WITH_WALE"})
|
||||
|
||||
// this should update the Patroni config again
|
||||
err = cluster.syncStandbyClusterConfiguration()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestUpdateSecret(t *testing.T) {
|
||||
testName := "test syncing secrets"
|
||||
client, _ := newFakeK8sSyncSecretsClient()
|
||||
|
||||
Reference in New Issue
Block a user