mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-01-13 22:23:11 +01:00
chore: review
Signed-off-by: Leonardo Cecchi <leonardo.cecchi@enterprisedb.com>
This commit is contained in:
parent
4bd0f2ab63
commit
aa70ae33ea
@ -8,14 +8,15 @@ spec:
|
|||||||
|
|
||||||
bootstrap:
|
bootstrap:
|
||||||
recovery:
|
recovery:
|
||||||
backup:
|
source: source
|
||||||
name: backup-example
|
|
||||||
usePlugin: true
|
|
||||||
|
|
||||||
plugins:
|
externalClusters:
|
||||||
- name: barman-cloud.cloudnative-pg.io
|
- name: source
|
||||||
# parameters:
|
plugin:
|
||||||
# barmanObjectName: minio-store
|
name: barman-cloud.cloudnative-pg.io
|
||||||
|
parameters:
|
||||||
|
barmanObjectName: minio-store
|
||||||
|
serverName: cluster-example
|
||||||
|
|
||||||
storage:
|
storage:
|
||||||
size: 1Gi
|
size: 1Gi
|
||||||
|
|||||||
34
go.mod
34
go.mod
@ -6,20 +6,20 @@ toolchain go1.23.1
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a
|
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241017151552-20297270038b
|
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241031170209-ad2b0d78a230
|
||||||
github.com/cloudnative-pg/cnpg-i v0.0.0-20241021130537-c4a74d755f0a
|
github.com/cloudnative-pg/cnpg-i v0.0.0-20241030162745-80b6d07403c1
|
||||||
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241014090747-e9c2b3738d19
|
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241014090747-e9c2b3738d19
|
||||||
github.com/cloudnative-pg/machinery v0.0.0-20241010122207-5ac7af31ef72
|
github.com/cloudnative-pg/machinery v0.0.0-20241014090714-c27747f9974b
|
||||||
github.com/onsi/ginkgo/v2 v2.20.2
|
github.com/onsi/ginkgo/v2 v2.20.2
|
||||||
github.com/onsi/gomega v1.34.2
|
github.com/onsi/gomega v1.34.2
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
github.com/spf13/viper v1.19.0
|
github.com/spf13/viper v1.19.0
|
||||||
google.golang.org/grpc v1.67.1
|
google.golang.org/grpc v1.67.1
|
||||||
k8s.io/api v0.31.1
|
k8s.io/api v0.31.2
|
||||||
k8s.io/apimachinery v0.31.1
|
k8s.io/apimachinery v0.31.2
|
||||||
k8s.io/client-go v0.31.1
|
k8s.io/client-go v0.31.2
|
||||||
k8s.io/utils v0.0.0-20240921022957-49e7df575cb6
|
k8s.io/utils v0.0.0-20240921022957-49e7df575cb6
|
||||||
sigs.k8s.io/controller-runtime v0.19.0
|
sigs.k8s.io/controller-runtime v0.19.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@ -74,8 +74,8 @@ require (
|
|||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.77.1 // indirect
|
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.77.2 // indirect
|
||||||
github.com/prometheus/client_golang v1.20.4 // indirect
|
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.59.1 // indirect
|
github.com/prometheus/common v0.59.1 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
@ -102,13 +102,13 @@ require (
|
|||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||||
golang.org/x/net v0.29.0 // indirect
|
golang.org/x/net v0.30.0 // indirect
|
||||||
golang.org/x/oauth2 v0.23.0 // indirect
|
golang.org/x/oauth2 v0.23.0 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
golang.org/x/sys v0.26.0 // indirect
|
||||||
golang.org/x/term v0.24.0 // indirect
|
golang.org/x/term v0.25.0 // indirect
|
||||||
golang.org/x/text v0.18.0 // indirect
|
golang.org/x/text v0.19.0 // indirect
|
||||||
golang.org/x/time v0.6.0 // indirect
|
golang.org/x/time v0.7.0 // indirect
|
||||||
golang.org/x/tools v0.25.0 // indirect
|
golang.org/x/tools v0.25.0 // indirect
|
||||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||||
@ -118,9 +118,9 @@ require (
|
|||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
k8s.io/apiextensions-apiserver v0.31.1 // indirect
|
k8s.io/apiextensions-apiserver v0.31.2 // indirect
|
||||||
k8s.io/apiserver v0.31.1 // indirect
|
k8s.io/apiserver v0.31.2 // indirect
|
||||||
k8s.io/component-base v0.31.1 // indirect
|
k8s.io/component-base v0.31.2 // indirect
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect
|
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect
|
||||||
|
|||||||
68
go.sum
68
go.sum
@ -18,14 +18,14 @@ github.com/cloudnative-pg/api v0.0.0-20241004125129-98baa9f4957b h1:LZ9tIgKmWb8Z
|
|||||||
github.com/cloudnative-pg/api v0.0.0-20241004125129-98baa9f4957b/go.mod h1:mzd1EvoLYy16jJdne6/4nwhoj7t4IZ0MqJMEH4mla8Q=
|
github.com/cloudnative-pg/api v0.0.0-20241004125129-98baa9f4957b/go.mod h1:mzd1EvoLYy16jJdne6/4nwhoj7t4IZ0MqJMEH4mla8Q=
|
||||||
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a h1:0v1ML9Eibfq3helbT9GtU0EstqFtG91k/MPO9azY5ME=
|
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a h1:0v1ML9Eibfq3helbT9GtU0EstqFtG91k/MPO9azY5ME=
|
||||||
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a/go.mod h1:Jm0tOp5oB7utpt8wz6RfSv31h1mThOtffjfyxVupriE=
|
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a/go.mod h1:Jm0tOp5oB7utpt8wz6RfSv31h1mThOtffjfyxVupriE=
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241017151552-20297270038b h1:47OKNQRgSs9XWvIt2bm8B1Yo7TA5oxBGjQPqF0j+Llw=
|
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241031170209-ad2b0d78a230 h1:zRqm1WUMOqkPWGyvtvCAdWlQ+WTtb0iQA/rvCar27/E=
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241017151552-20297270038b/go.mod h1:0grklCuA9WSA5lazBeTgDqLHjxP13fqAhqlveDx7hPg=
|
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241031170209-ad2b0d78a230/go.mod h1:La89zdElTqqZ5LXHFm/UjOwvS9iHSE8GuOW4fYUgHw8=
|
||||||
github.com/cloudnative-pg/cnpg-i v0.0.0-20241021130537-c4a74d755f0a h1:K4c+gX96NAt9C3AeffB8T4tvI3Qn9Fpi5x7Kzd+Iiyg=
|
github.com/cloudnative-pg/cnpg-i v0.0.0-20241030162745-80b6d07403c1 h1:v3Vr+FH5BXmS7Eqx17u51oijZ4T7y62vUMCUAr7CffE=
|
||||||
github.com/cloudnative-pg/cnpg-i v0.0.0-20241021130537-c4a74d755f0a/go.mod h1:fAU7ySVzjpt/RZntxWZiWJCjaBJayzIxEnd0NuO7oQc=
|
github.com/cloudnative-pg/cnpg-i v0.0.0-20241030162745-80b6d07403c1/go.mod h1:fAU7ySVzjpt/RZntxWZiWJCjaBJayzIxEnd0NuO7oQc=
|
||||||
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241014090747-e9c2b3738d19 h1:qy+LrScvQpIwt4qeg9FfCJuoC9CbX/kpFGLF8vSobXg=
|
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241014090747-e9c2b3738d19 h1:qy+LrScvQpIwt4qeg9FfCJuoC9CbX/kpFGLF8vSobXg=
|
||||||
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241014090747-e9c2b3738d19/go.mod h1:X6r1fRuUEIAv4+5SSBY2RmQ201K6GcptOXgnmaX/8tY=
|
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241014090747-e9c2b3738d19/go.mod h1:X6r1fRuUEIAv4+5SSBY2RmQ201K6GcptOXgnmaX/8tY=
|
||||||
github.com/cloudnative-pg/machinery v0.0.0-20241010122207-5ac7af31ef72 h1:3pgtSYhv3RDd+51bnlqICNrcVpWQQvriCOvkxtbZpaE=
|
github.com/cloudnative-pg/machinery v0.0.0-20241014090714-c27747f9974b h1:4Q2VQsPlLHliJdi87zodQ0FHLd1cJINMm4N70eu8rRg=
|
||||||
github.com/cloudnative-pg/machinery v0.0.0-20241010122207-5ac7af31ef72/go.mod h1:bWp1Es5zlxElg4Z/c5f0RKOkDcyNvDHdYIvNcPQU4WM=
|
github.com/cloudnative-pg/machinery v0.0.0-20241014090714-c27747f9974b/go.mod h1:+mUFdys1IX+qwQUrV+/i56Tey/mYh8ZzWZYttwivRns=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -140,10 +140,10 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.77.1 h1:XGoEXT6WTTihO+MD8MAao+YaQIH905HbK0WK2lyo28k=
|
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.77.2 h1:F/MALZ518KfI1zEg+Kg8/uTzoXKDyqw+LNC/5irJlJE=
|
||||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.77.1/go.mod h1:D0KY8md81DQKdaR/cXwnhoWB3MYYyc/UjvqE8GFkIvA=
|
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.77.2/go.mod h1:D0KY8md81DQKdaR/cXwnhoWB3MYYyc/UjvqE8GFkIvA=
|
||||||
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=
|
github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=
|
||||||
@ -228,8 +228,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -240,16 +240,16 @@ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
|||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||||
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
@ -286,18 +286,18 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU=
|
k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0=
|
||||||
k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
|
k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk=
|
||||||
k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40=
|
k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0=
|
||||||
k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ=
|
k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM=
|
||||||
k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
|
k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
|
||||||
k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||||
k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c=
|
k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4=
|
||||||
k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM=
|
k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE=
|
||||||
k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
|
k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc=
|
||||||
k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
|
k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs=
|
||||||
k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8=
|
k8s.io/component-base v0.31.2 h1:Z1J1LIaC0AV+nzcPRFqfK09af6bZ4D1nAOpWsy9owlA=
|
||||||
k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w=
|
k8s.io/component-base v0.31.2/go.mod h1:9PeyyFN/drHjtJZMCTkSpQJS3U9OXORnHQqMLDz0sUQ=
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 h1:1dWzkmJrrprYvjGwh9kEUxmcUV/CtNU8QM7h1FLWQOo=
|
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 h1:1dWzkmJrrprYvjGwh9kEUxmcUV/CtNU8QM7h1FLWQOo=
|
||||||
@ -306,8 +306,8 @@ k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY
|
|||||||
k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
||||||
sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q=
|
sigs.k8s.io/controller-runtime v0.19.1 h1:Son+Q40+Be3QWb+niBXAg2vFiYWolDjjRfO8hn/cxOk=
|
||||||
sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
|
sigs.k8s.io/controller-runtime v0.19.1/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
|
||||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||||
|
|||||||
@ -36,8 +36,6 @@ func NewCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ = viper.BindEnv("namespace", "NAMESPACE")
|
_ = viper.BindEnv("namespace", "NAMESPACE")
|
||||||
_ = viper.BindEnv("backup-to-restore", "BACKUP_TO_RESTORE")
|
|
||||||
_ = viper.BindEnv("barman-archive-configuration", "BARMAN_OBJECT_NAME")
|
|
||||||
_ = viper.BindEnv("cluster-name", "CLUSTER_NAME")
|
_ = viper.BindEnv("cluster-name", "CLUSTER_NAME")
|
||||||
_ = viper.BindEnv("pod-name", "POD_NAME")
|
_ = viper.BindEnv("pod-name", "POD_NAME")
|
||||||
_ = viper.BindEnv("pgdata", "PGDATA")
|
_ = viper.BindEnv("pgdata", "PGDATA")
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
|
||||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetCredentialsFromBackup extracts the Barman credentials from the backup
|
|
||||||
func GetCredentialsFromBackup(backup *cnpgv1.Backup) (barmanapi.BarmanCredentials, error) {
|
|
||||||
rawCred := backup.Status.PluginMetadata["credentials"]
|
|
||||||
|
|
||||||
var creds barmanapi.BarmanCredentials
|
|
||||||
if err := json.Unmarshal([]byte(rawCred), &creds); err != nil {
|
|
||||||
return barmanapi.BarmanCredentials{}, fmt.Errorf("while unmarshaling credentials: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return creds, nil
|
|
||||||
}
|
|
||||||
72
internal/cnpgi/common/common.go
Normal file
72
internal/cnpgi/common/common.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: refactor.
|
||||||
|
const (
|
||||||
|
// ScratchDataDirectory is the directory to be used for scratch data.
|
||||||
|
ScratchDataDirectory = "/controller"
|
||||||
|
|
||||||
|
// CertificatesDir location to store the certificates.
|
||||||
|
CertificatesDir = ScratchDataDirectory + "/certificates/"
|
||||||
|
|
||||||
|
// BarmanBackupEndpointCACertificateLocation is the location where the barman endpoint
|
||||||
|
// CA certificate is stored.
|
||||||
|
BarmanBackupEndpointCACertificateLocation = CertificatesDir + BarmanBackupEndpointCACertificateFileName
|
||||||
|
|
||||||
|
// BarmanBackupEndpointCACertificateFileName is the name of the file in which the barman endpoint
|
||||||
|
// CA certificate for backups is stored.
|
||||||
|
BarmanBackupEndpointCACertificateFileName = "backup-" + BarmanEndpointCACertificateFileName
|
||||||
|
|
||||||
|
// BarmanRestoreEndpointCACertificateFileName is the name of the file in which the barman endpoint
|
||||||
|
// CA certificate for restores is stored.
|
||||||
|
BarmanRestoreEndpointCACertificateFileName = "restore-" + BarmanEndpointCACertificateFileName
|
||||||
|
|
||||||
|
// BarmanEndpointCACertificateFileName is the name of the file in which the barman endpoint
|
||||||
|
// CA certificate is stored.
|
||||||
|
BarmanEndpointCACertificateFileName = "barman-ca.crt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetRestoreCABundleEnv gets the enveronment variables to be used when custom
|
||||||
|
// Object Store CA is present
|
||||||
|
func GetRestoreCABundleEnv(configuration *barmanapi.BarmanObjectStoreConfiguration) []string {
|
||||||
|
var env []string
|
||||||
|
|
||||||
|
if configuration.EndpointCA != nil && configuration.BarmanCredentials.AWS != nil {
|
||||||
|
env = append(env, fmt.Sprintf("AWS_CA_BUNDLE=%s", BarmanBackupEndpointCACertificateLocation))
|
||||||
|
} else if configuration.EndpointCA != nil && configuration.BarmanCredentials.Azure != nil {
|
||||||
|
env = append(env, fmt.Sprintf("REQUESTS_CA_BUNDLE=%s", BarmanBackupEndpointCACertificateLocation))
|
||||||
|
}
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergeEnv merges all the values inside incomingEnv into env.
|
||||||
|
func MergeEnv(env []string, incomingEnv []string) []string {
|
||||||
|
result := make([]string, len(env), len(env)+len(incomingEnv))
|
||||||
|
copy(result, env)
|
||||||
|
|
||||||
|
for _, incomingItem := range incomingEnv {
|
||||||
|
incomingKV := strings.SplitAfterN(incomingItem, "=", 2)
|
||||||
|
if len(incomingKV) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for idx, item := range result {
|
||||||
|
if strings.HasPrefix(item, incomingKV[0]) {
|
||||||
|
result[idx] = incomingItem
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
result = append(result, incomingItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@ -2,7 +2,6 @@ package instance
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -11,6 +10,7 @@ import (
|
|||||||
barmanBackup "github.com/cloudnative-pg/barman-cloud/pkg/backup"
|
barmanBackup "github.com/cloudnative-pg/barman-cloud/pkg/backup"
|
||||||
barmanCapabilities "github.com/cloudnative-pg/barman-cloud/pkg/capabilities"
|
barmanCapabilities "github.com/cloudnative-pg/barman-cloud/pkg/capabilities"
|
||||||
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
||||||
|
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||||
"github.com/cloudnative-pg/cloudnative-pg/pkg/postgres"
|
"github.com/cloudnative-pg/cloudnative-pg/pkg/postgres"
|
||||||
"github.com/cloudnative-pg/cnpg-i/pkg/backup"
|
"github.com/cloudnative-pg/cnpg-i/pkg/backup"
|
||||||
"github.com/cloudnative-pg/machinery/pkg/fileutils"
|
"github.com/cloudnative-pg/machinery/pkg/fileutils"
|
||||||
@ -20,6 +20,7 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/common"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -69,6 +70,11 @@ func (b BackupServiceImplementation) Backup(
|
|||||||
|
|
||||||
contextLogger.Info("Starting backup")
|
contextLogger.Info("Starting backup")
|
||||||
|
|
||||||
|
var cluster cnpgv1.Cluster
|
||||||
|
if err := b.Client.Get(ctx, b.ClusterObjectKey, &cluster); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var objectStore barmancloudv1.ObjectStore
|
var objectStore barmancloudv1.ObjectStore
|
||||||
if err := b.Client.Get(ctx, b.BarmanObjectKey, &objectStore); err != nil {
|
if err := b.Client.Get(ctx, b.BarmanObjectKey, &objectStore); err != nil {
|
||||||
contextLogger.Error(err, "while getting object store", "key", b.BarmanObjectKey)
|
contextLogger.Error(err, "while getting object store", "key", b.BarmanObjectKey)
|
||||||
@ -93,24 +99,33 @@ func (b BackupServiceImplementation) Backup(
|
|||||||
// We need to connect to PostgreSQL and to do that we need
|
// We need to connect to PostgreSQL and to do that we need
|
||||||
// PGHOST (and the like) to be available
|
// PGHOST (and the like) to be available
|
||||||
osEnvironment := os.Environ()
|
osEnvironment := os.Environ()
|
||||||
caBundleEnvironment := getRestoreCABundleEnv(&objectStore.Spec.Configuration)
|
caBundleEnvironment := common.GetRestoreCABundleEnv(&objectStore.Spec.Configuration)
|
||||||
env, err := barmanCredentials.EnvSetBackupCloudCredentials(
|
env, err := barmanCredentials.EnvSetBackupCloudCredentials(
|
||||||
ctx,
|
ctx,
|
||||||
b.Client,
|
b.Client,
|
||||||
objectStore.Namespace,
|
objectStore.Namespace,
|
||||||
&objectStore.Spec.Configuration,
|
&objectStore.Spec.Configuration,
|
||||||
mergeEnv(osEnvironment, caBundleEnvironment))
|
common.MergeEnv(osEnvironment, caBundleEnvironment))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
contextLogger.Error(err, "while setting backup cloud credentials")
|
contextLogger.Error(err, "while setting backup cloud credentials")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serverName := cluster.Name
|
||||||
|
for _, plugin := range cluster.Spec.Plugins {
|
||||||
|
if plugin.IsEnabled() && plugin.Name == metadata.PluginName {
|
||||||
|
if pluginServerName, ok := plugin.Parameters["serverName"]; ok {
|
||||||
|
serverName = pluginServerName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
backupName := fmt.Sprintf("backup-%v", pgTime.ToCompactISO8601(time.Now()))
|
backupName := fmt.Sprintf("backup-%v", pgTime.ToCompactISO8601(time.Now()))
|
||||||
|
|
||||||
if err = backupCmd.Take(
|
if err = backupCmd.Take(
|
||||||
ctx,
|
ctx,
|
||||||
backupName,
|
backupName,
|
||||||
objectStore.Name,
|
serverName,
|
||||||
env,
|
env,
|
||||||
barmanCloudExecutor{},
|
barmanCloudExecutor{},
|
||||||
postgres.BackupTemporaryDirectory,
|
postgres.BackupTemporaryDirectory,
|
||||||
@ -122,7 +137,7 @@ func (b BackupServiceImplementation) Backup(
|
|||||||
executedBackupInfo, err := backupCmd.GetExecutedBackupInfo(
|
executedBackupInfo, err := backupCmd.GetExecutedBackupInfo(
|
||||||
ctx,
|
ctx,
|
||||||
backupName,
|
backupName,
|
||||||
objectStore.Name,
|
serverName,
|
||||||
barmanCloudExecutor{},
|
barmanCloudExecutor{},
|
||||||
env)
|
env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -130,25 +145,6 @@ func (b BackupServiceImplementation) Backup(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cred, err := json.Marshal(objectStore.Spec.Configuration.BarmanCredentials)
|
|
||||||
if err != nil {
|
|
||||||
contextLogger.Error(err, "while marshalling credentials")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var endpointCA *backup.KeyName
|
|
||||||
if objectStore.Spec.Configuration.EndpointCA != nil {
|
|
||||||
endpointCA = &backup.KeyName{
|
|
||||||
Name: objectStore.Spec.Configuration.EndpointCA.Name,
|
|
||||||
Key: objectStore.Spec.Configuration.EndpointCA.Key,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var encryption string
|
|
||||||
if objectStore.Spec.Configuration.Data != nil {
|
|
||||||
encryption = string(objectStore.Spec.Configuration.Data.Encryption)
|
|
||||||
}
|
|
||||||
|
|
||||||
contextLogger.Info("Backup completed", "backup", executedBackupInfo.ID)
|
contextLogger.Info("Backup completed", "backup", executedBackupInfo.ID)
|
||||||
return &backup.BackupResult{
|
return &backup.BackupResult{
|
||||||
BackupId: executedBackupInfo.ID,
|
BackupId: executedBackupInfo.ID,
|
||||||
@ -166,13 +162,6 @@ func (b BackupServiceImplementation) Backup(
|
|||||||
"version": metadata.Data.Version,
|
"version": metadata.Data.Version,
|
||||||
"name": metadata.Data.Name,
|
"name": metadata.Data.Name,
|
||||||
"displayName": metadata.Data.DisplayName,
|
"displayName": metadata.Data.DisplayName,
|
||||||
// TODO: is it safe?
|
|
||||||
"credentials": string(cred),
|
|
||||||
},
|
},
|
||||||
ServerName: objectStore.Name,
|
|
||||||
EndpointUrl: objectStore.Spec.Configuration.EndpointURL,
|
|
||||||
DestinationPath: objectStore.Spec.Configuration.DestinationPath,
|
|
||||||
EndpointCa: endpointCA,
|
|
||||||
Encryption: encryption,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,10 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
|
||||||
"github.com/cloudnative-pg/barman-cloud/pkg/archiver"
|
"github.com/cloudnative-pg/barman-cloud/pkg/archiver"
|
||||||
barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command"
|
barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command"
|
||||||
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
||||||
@ -21,6 +19,7 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/common"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,6 +65,21 @@ func (w WALServiceImplementation) Archive(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *wal.WALArchiveRequest,
|
request *wal.WALArchiveRequest,
|
||||||
) (*wal.WALArchiveResult, error) {
|
) (*wal.WALArchiveResult, error) {
|
||||||
|
var cluster cnpgv1.Cluster
|
||||||
|
if err := w.Client.Get(ctx, w.ClusterObjectKey, &cluster); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: refactor this code elsewhere
|
||||||
|
serverName := cluster.Name
|
||||||
|
for _, plugin := range cluster.Spec.Plugins {
|
||||||
|
if plugin.IsEnabled() && plugin.Name == metadata.PluginName {
|
||||||
|
if pluginServerName, ok := plugin.Parameters["serverName"]; ok {
|
||||||
|
serverName = pluginServerName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var objectStore barmancloudv1.ObjectStore
|
var objectStore barmancloudv1.ObjectStore
|
||||||
if err := w.Client.Get(ctx, w.BarmanObjectKey, &objectStore); err != nil {
|
if err := w.Client.Get(ctx, w.BarmanObjectKey, &objectStore); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -95,7 +109,7 @@ func (w WALServiceImplementation) Archive(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
options, err := arch.BarmanCloudWalArchiveOptions(ctx, &objectStore.Spec.Configuration, objectStore.Name)
|
options, err := arch.BarmanCloudWalArchiveOptions(ctx, &objectStore.Spec.Configuration, serverName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -111,6 +125,7 @@ func (w WALServiceImplementation) Archive(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore implements the WALService interface
|
// Restore implements the WALService interface
|
||||||
|
// nolint: gocognit
|
||||||
func (w WALServiceImplementation) Restore(
|
func (w WALServiceImplementation) Restore(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *wal.WALRestoreRequest,
|
request *wal.WALRestoreRequest,
|
||||||
@ -134,7 +149,7 @@ func (w WALServiceImplementation) Restore(
|
|||||||
|
|
||||||
barmanConfiguration := &objectStore.Spec.Configuration
|
barmanConfiguration := &objectStore.Spec.Configuration
|
||||||
|
|
||||||
env := getRestoreCABundleEnv(barmanConfiguration)
|
env := common.GetRestoreCABundleEnv(barmanConfiguration)
|
||||||
credentialsEnv, err := barmanCredentials.EnvSetBackupCloudCredentials(
|
credentialsEnv, err := barmanCredentials.EnvSetBackupCloudCredentials(
|
||||||
ctx,
|
ctx,
|
||||||
w.Client,
|
w.Client,
|
||||||
@ -145,9 +160,19 @@ func (w WALServiceImplementation) Restore(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("while getting recover credentials: %w", err)
|
return nil, fmt.Errorf("while getting recover credentials: %w", err)
|
||||||
}
|
}
|
||||||
env = mergeEnv(env, credentialsEnv)
|
env = common.MergeEnv(env, credentialsEnv)
|
||||||
|
|
||||||
options, err := barmanCommand.CloudWalRestoreOptions(ctx, barmanConfiguration, objectStore.Name)
|
// TODO: refactor this code elsewhere
|
||||||
|
serverName := cluster.Name
|
||||||
|
for _, plugin := range cluster.Spec.Plugins {
|
||||||
|
if plugin.IsEnabled() && plugin.Name == metadata.PluginName {
|
||||||
|
if pluginServerName, ok := plugin.Parameters["serverName"]; ok {
|
||||||
|
serverName = pluginServerName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
options, err := barmanCommand.CloudWalRestoreOptions(ctx, barmanConfiguration, serverName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("while getting barman-cloud-wal-restore options: %w", err)
|
return nil, fmt.Errorf("while getting barman-cloud-wal-restore options: %w", err)
|
||||||
}
|
}
|
||||||
@ -254,68 +279,6 @@ func (w WALServiceImplementation) SetFirstRequired(
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
// mergeEnv merges all the values inside incomingEnv into env.
|
|
||||||
func mergeEnv(env []string, incomingEnv []string) []string {
|
|
||||||
result := make([]string, len(env), len(env)+len(incomingEnv))
|
|
||||||
copy(result, env)
|
|
||||||
|
|
||||||
for _, incomingItem := range incomingEnv {
|
|
||||||
incomingKV := strings.SplitAfterN(incomingItem, "=", 2)
|
|
||||||
if len(incomingKV) != 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
found := false
|
|
||||||
for idx, item := range result {
|
|
||||||
if strings.HasPrefix(item, incomingKV[0]) {
|
|
||||||
result[idx] = incomingItem
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
result = append(result, incomingItem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: refactor.
|
|
||||||
const (
|
|
||||||
// ScratchDataDirectory is the directory to be used for scratch data.
|
|
||||||
ScratchDataDirectory = "/controller"
|
|
||||||
|
|
||||||
// CertificatesDir location to store the certificates.
|
|
||||||
CertificatesDir = ScratchDataDirectory + "/certificates/"
|
|
||||||
|
|
||||||
// BarmanBackupEndpointCACertificateLocation is the location where the barman endpoint
|
|
||||||
// CA certificate is stored.
|
|
||||||
BarmanBackupEndpointCACertificateLocation = CertificatesDir + BarmanBackupEndpointCACertificateFileName
|
|
||||||
|
|
||||||
// BarmanBackupEndpointCACertificateFileName is the name of the file in which the barman endpoint
|
|
||||||
// CA certificate for backups is stored.
|
|
||||||
BarmanBackupEndpointCACertificateFileName = "backup-" + BarmanEndpointCACertificateFileName
|
|
||||||
|
|
||||||
// BarmanRestoreEndpointCACertificateFileName is the name of the file in which the barman endpoint
|
|
||||||
// CA certificate for restores is stored.
|
|
||||||
BarmanRestoreEndpointCACertificateFileName = "restore-" + BarmanEndpointCACertificateFileName
|
|
||||||
|
|
||||||
// BarmanEndpointCACertificateFileName is the name of the file in which the barman endpoint
|
|
||||||
// CA certificate is stored.
|
|
||||||
BarmanEndpointCACertificateFileName = "barman-ca.crt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getRestoreCABundleEnv(configuration *barmanapi.BarmanObjectStoreConfiguration) []string {
|
|
||||||
var env []string
|
|
||||||
|
|
||||||
if configuration.EndpointCA != nil && configuration.BarmanCredentials.AWS != nil {
|
|
||||||
env = append(env, fmt.Sprintf("AWS_CA_BUNDLE=%s", BarmanBackupEndpointCACertificateLocation))
|
|
||||||
} else if configuration.EndpointCA != nil && configuration.BarmanCredentials.Azure != nil {
|
|
||||||
env = append(env, fmt.Sprintf("REQUESTS_CA_BUNDLE=%s", BarmanBackupEndpointCACertificateLocation))
|
|
||||||
}
|
|
||||||
return env
|
|
||||||
}
|
|
||||||
|
|
||||||
// isStreamingAvailable checks if this pod can replicate via streaming connection.
|
// isStreamingAvailable checks if this pod can replicate via streaming connection.
|
||||||
func isStreamingAvailable(cluster *cnpgv1.Cluster, podName string) bool {
|
func isStreamingAvailable(cluster *cnpgv1.Cluster, podName string) bool {
|
||||||
if cluster == nil {
|
if cluster == nil {
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import (
|
|||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/utils/ptr"
|
"k8s.io/utils/ptr"
|
||||||
|
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -103,13 +104,11 @@ func reconcileJob(
|
|||||||
pluginConfiguration *config.PluginConfiguration,
|
pluginConfiguration *config.PluginConfiguration,
|
||||||
) (*lifecycle.OperatorLifecycleResponse, error) {
|
) (*lifecycle.OperatorLifecycleResponse, error) {
|
||||||
contextLogger := log.FromContext(ctx).WithName("lifecycle")
|
contextLogger := log.FromContext(ctx).WithName("lifecycle")
|
||||||
if !cluster.UsePluginForBootstrapRecoveryBackup() {
|
if pluginConfig := cluster.GetRecoverySourcePlugin(); pluginConfig == nil || pluginConfig.Name != metadata.PluginName {
|
||||||
contextLogger.Debug("cluster does not use the plugin for recovery, skipping")
|
contextLogger.Debug("cluster does not use the this plugin for recovery, skipping")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
backupSource := cluster.Spec.Bootstrap.Recovery.Backup
|
|
||||||
|
|
||||||
var job batchv1.Job
|
var job batchv1.Job
|
||||||
if err := decoder.DecodeObject(
|
if err := decoder.DecodeObject(
|
||||||
request.GetObjectDefinition(),
|
request.GetObjectDefinition(),
|
||||||
@ -138,12 +137,6 @@ func reconcileJob(
|
|||||||
"full-recovery",
|
"full-recovery",
|
||||||
corev1.Container{
|
corev1.Container{
|
||||||
Args: []string{"restore"},
|
Args: []string{"restore"},
|
||||||
Env: []corev1.EnvVar{
|
|
||||||
{
|
|
||||||
Name: "BACKUP_TO_RESTORE",
|
|
||||||
Value: backupSource.Name,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, fmt.Errorf("while reconciling pod spec for job: %w", err)
|
return nil, fmt.Errorf("while reconciling pod spec for job: %w", err)
|
||||||
@ -231,9 +224,6 @@ func reconcilePodSpec(
|
|||||||
sidecarConfig.Name = "plugin-barman-cloud"
|
sidecarConfig.Name = "plugin-barman-cloud"
|
||||||
sidecarConfig.Image = viper.GetString("sidecar-image")
|
sidecarConfig.Image = viper.GetString("sidecar-image")
|
||||||
sidecarConfig.ImagePullPolicy = cluster.Spec.ImagePullPolicy
|
sidecarConfig.ImagePullPolicy = cluster.Spec.ImagePullPolicy
|
||||||
sidecarConfig.Command = []string{
|
|
||||||
"/manager",
|
|
||||||
}
|
|
||||||
|
|
||||||
// merge the main container envs if they aren't already set
|
// merge the main container envs if they aren't already set
|
||||||
for _, container := range spec.Containers {
|
for _, container := range spec.Containers {
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import (
|
|||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/utils/ptr"
|
|
||||||
|
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||||
|
|
||||||
@ -34,17 +33,31 @@ var _ = Describe("LifecycleImplementation", func() {
|
|||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
pluginConfiguration = &config.PluginConfiguration{
|
pluginConfiguration = &config.PluginConfiguration{
|
||||||
BarmanObjectName: "barman-object",
|
BarmanObjectName: "minio-store-dest",
|
||||||
}
|
}
|
||||||
cluster = &cnpgv1.Cluster{
|
cluster = &cnpgv1.Cluster{
|
||||||
Spec: cnpgv1.ClusterSpec{
|
Spec: cnpgv1.ClusterSpec{
|
||||||
Bootstrap: &cnpgv1.BootstrapConfiguration{
|
Bootstrap: &cnpgv1.BootstrapConfiguration{
|
||||||
Recovery: &cnpgv1.BootstrapRecovery{
|
Recovery: &cnpgv1.BootstrapRecovery{
|
||||||
Backup: &cnpgv1.BackupSource{
|
Source: "origin-server",
|
||||||
LocalObjectReference: cnpgv1.LocalObjectReference{
|
},
|
||||||
Name: "backup-object",
|
},
|
||||||
|
ExternalClusters: []cnpgv1.ExternalCluster{
|
||||||
|
{
|
||||||
|
Name: "origin-server",
|
||||||
|
PluginConfiguration: &cnpgv1.PluginConfiguration{
|
||||||
|
Name: "barman-cloud.cloudnative-pg.io",
|
||||||
|
Parameters: map[string]string{
|
||||||
|
"barmanObjectName": "minio-store-source",
|
||||||
},
|
},
|
||||||
UsePlugin: ptr.To(true),
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Plugins: cnpgv1.PluginConfigurationList{
|
||||||
|
{
|
||||||
|
Name: "barman-cloud.cloudnative-pg.io",
|
||||||
|
Parameters: map[string]string{
|
||||||
|
"barmanObjectName": "minio-store-dest",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -180,8 +193,9 @@ var _ = Describe("LifecycleImplementation", func() {
|
|||||||
err = json.Unmarshal(response.JsonPatch, &patch)
|
err = json.Unmarshal(response.JsonPatch, &patch)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(patch).To(ContainElement(HaveKeyWithValue("op", "add")))
|
Expect(patch).To(ContainElement(HaveKeyWithValue("op", "add")))
|
||||||
Expect(patch).To(ContainElement(HaveKeyWithValue("path", "/spec/containers/1")))
|
Expect(patch).To(ContainElement(HaveKeyWithValue("path", "/spec/initContainers")))
|
||||||
Expect(patch).To(ContainElement(HaveKeyWithValue("value", HaveKeyWithValue("name", "plugin-barman-cloud"))))
|
Expect(patch).To(ContainElement(
|
||||||
|
HaveKey("value")))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns an error for invalid pod definition", func(ctx SpecContext) {
|
It("returns an error for invalid pod definition", func(ctx SpecContext) {
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/common"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/specs"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/specs"
|
||||||
)
|
)
|
||||||
@ -75,14 +75,16 @@ func (r ReconcilerImplementation) Pre(
|
|||||||
pluginConfiguration := config.NewFromCluster(&cluster)
|
pluginConfiguration := config.NewFromCluster(&cluster)
|
||||||
|
|
||||||
contextLogger.Debug("parsing barman object configuration")
|
contextLogger.Debug("parsing barman object configuration")
|
||||||
var barmanObject *barmancloudv1.ObjectStore
|
|
||||||
|
var barmanObjects []barmancloudv1.ObjectStore
|
||||||
|
|
||||||
// this could be empty during recoveries
|
// this could be empty during recoveries
|
||||||
if pluginConfiguration.BarmanObjectName != "" {
|
if pluginConfiguration.BarmanObjectName != "" {
|
||||||
barmanObject = &barmancloudv1.ObjectStore{}
|
var barmanObject barmancloudv1.ObjectStore
|
||||||
if err := r.Client.Get(ctx, client.ObjectKey{
|
if err := r.Client.Get(ctx, client.ObjectKey{
|
||||||
Namespace: cluster.Namespace,
|
Namespace: cluster.Namespace,
|
||||||
Name: pluginConfiguration.BarmanObjectName,
|
Name: pluginConfiguration.BarmanObjectName,
|
||||||
}, barmanObject); err != nil {
|
}, &barmanObject); err != nil {
|
||||||
if apierrs.IsNotFound(err) {
|
if apierrs.IsNotFound(err) {
|
||||||
contextLogger.Info("barman object configuration not found, requeuing")
|
contextLogger.Info("barman object configuration not found, requeuing")
|
||||||
return &reconciler.ReconcilerHooksResult{
|
return &reconciler.ReconcilerHooksResult{
|
||||||
@ -92,28 +94,23 @@ func (r ReconcilerImplementation) Pre(
|
|||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
barmanObjects = append(barmanObjects, barmanObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
if barmanObject, err := r.getRecoveryBarmanObject(ctx, &cluster); err != nil {
|
||||||
|
if apierrs.IsNotFound(err) {
|
||||||
|
contextLogger.Info("barman recovery object configuration not found, requeuing")
|
||||||
|
return &reconciler.ReconcilerHooksResult{
|
||||||
|
Behavior: reconciler.ReconcilerHooksResult_BEHAVIOR_REQUEUE,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
} else if barmanObject != nil {
|
||||||
|
barmanObjects = append(barmanObjects, *barmanObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
var additionalSecretNames []string
|
var additionalSecretNames []string
|
||||||
if cluster.UsePluginForBootstrapRecoveryBackup() {
|
if err := r.ensureRole(ctx, &cluster, barmanObjects, additionalSecretNames); err != nil {
|
||||||
var backup cnpgv1.Backup
|
|
||||||
if err := r.Client.Get(ctx, client.ObjectKey{
|
|
||||||
Namespace: cluster.Namespace,
|
|
||||||
Name: cluster.Spec.Bootstrap.Recovery.Backup.Name,
|
|
||||||
}, &backup); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
credentials, err := common.GetCredentialsFromBackup(&backup)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
additionalSecretNames = append(additionalSecretNames, specs.CollectSecretNamesFromCredentials(&credentials)...)
|
|
||||||
|
|
||||||
if backup.Status.EndpointCA != nil {
|
|
||||||
additionalSecretNames = append(additionalSecretNames, backup.Status.EndpointCA.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := r.ensureRole(ctx, &cluster, barmanObject, additionalSecretNames); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +124,30 @@ func (r ReconcilerImplementation) Pre(
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r ReconcilerImplementation) getRecoveryBarmanObject(
|
||||||
|
ctx context.Context,
|
||||||
|
cluster *cnpgv1.Cluster,
|
||||||
|
) (*barmancloudv1.ObjectStore, error) {
|
||||||
|
recoveryConfig := cluster.GetRecoverySourcePlugin()
|
||||||
|
if recoveryConfig != nil && recoveryConfig.Name == metadata.PluginName {
|
||||||
|
// TODO: refactor -> cnpg-i-machinery should be able to help us on getting
|
||||||
|
// the configuration for a recovery plugin
|
||||||
|
if recoveryObjectStore, ok := recoveryConfig.Parameters["barmanObjectName"]; ok {
|
||||||
|
var barmanObject barmancloudv1.ObjectStore
|
||||||
|
if err := r.Client.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: cluster.Namespace,
|
||||||
|
Name: recoveryObjectStore,
|
||||||
|
}, &barmanObject); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &barmanObject, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Post implements the reconciler interface
|
// Post implements the reconciler interface
|
||||||
func (r ReconcilerImplementation) Post(
|
func (r ReconcilerImplementation) Post(
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
@ -140,11 +161,11 @@ func (r ReconcilerImplementation) Post(
|
|||||||
func (r ReconcilerImplementation) ensureRole(
|
func (r ReconcilerImplementation) ensureRole(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
cluster *cnpgv1.Cluster,
|
cluster *cnpgv1.Cluster,
|
||||||
barmanObject *barmancloudv1.ObjectStore,
|
barmanObjects []barmancloudv1.ObjectStore,
|
||||||
additionalSecretNames []string,
|
additionalSecretNames []string,
|
||||||
) error {
|
) error {
|
||||||
contextLogger := log.FromContext(ctx)
|
contextLogger := log.FromContext(ctx)
|
||||||
newRole := specs.BuildRole(cluster, barmanObject, additionalSecretNames)
|
newRole := specs.BuildRole(cluster, barmanObjects, additionalSecretNames)
|
||||||
|
|
||||||
var role rbacv1.Role
|
var role rbacv1.Role
|
||||||
if err := r.Client.Get(ctx, client.ObjectKey{
|
if err := r.Client.Get(ctx, client.ObjectKey{
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import (
|
|||||||
// BuildRole builds the Role object for this cluster
|
// BuildRole builds the Role object for this cluster
|
||||||
func BuildRole(
|
func BuildRole(
|
||||||
cluster *cnpgv1.Cluster,
|
cluster *cnpgv1.Cluster,
|
||||||
barmanObject *barmancloudv1.ObjectStore,
|
barmanObjects []barmancloudv1.ObjectStore,
|
||||||
additionalSecretNames []string,
|
additionalSecretNames []string,
|
||||||
) *rbacv1.Role {
|
) *rbacv1.Role {
|
||||||
role := &rbacv1.Role{
|
role := &rbacv1.Role{
|
||||||
@ -27,8 +27,7 @@ func BuildRole(
|
|||||||
}
|
}
|
||||||
|
|
||||||
secretsSet := stringset.New()
|
secretsSet := stringset.New()
|
||||||
// TODO: we should handle removals too?
|
for _, barmanObject := range barmanObjects {
|
||||||
if barmanObject != nil {
|
|
||||||
role.Rules = append(role.Rules, rbacv1.PolicyRule{
|
role.Rules = append(role.Rules, rbacv1.PolicyRule{
|
||||||
APIGroups: []string{
|
APIGroups: []string{
|
||||||
"barmancloud.cnpg.io",
|
"barmancloud.cnpg.io",
|
||||||
|
|||||||
@ -32,9 +32,7 @@ func Start(ctx context.Context) error {
|
|||||||
setupLog := log.FromContext(ctx)
|
setupLog := log.FromContext(ctx)
|
||||||
setupLog.Info("Starting barman cloud instance plugin")
|
setupLog.Info("Starting barman cloud instance plugin")
|
||||||
namespace := viper.GetString("namespace")
|
namespace := viper.GetString("namespace")
|
||||||
archiveConfiguration := viper.GetString("barman-archive-configuration")
|
|
||||||
clusterName := viper.GetString("cluster-name")
|
clusterName := viper.GetString("cluster-name")
|
||||||
backupToRestoreName := viper.GetString("backup-to-restore")
|
|
||||||
|
|
||||||
objs := map[client.Object]cache.ByObject{
|
objs := map[client.Object]cache.ByObject{
|
||||||
&cnpgv1.Cluster{}: {
|
&cnpgv1.Cluster{}: {
|
||||||
@ -43,20 +41,6 @@ func Start(ctx context.Context) error {
|
|||||||
namespace: {},
|
namespace: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&cnpgv1.Backup{}: {
|
|
||||||
Field: fields.OneTermEqualSelector("metadata.name", backupToRestoreName),
|
|
||||||
Namespaces: map[string]cache.Config{
|
|
||||||
namespace: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if archiveConfiguration != "" {
|
|
||||||
objs[&barmancloudv1.ObjectStore{}] = cache.ByObject{
|
|
||||||
Field: fields.OneTermEqualSelector("metadata.name", archiveConfiguration),
|
|
||||||
Namespaces: map[string]cache.Config{
|
|
||||||
namespace: {},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
||||||
@ -68,6 +52,7 @@ func Start(ctx context.Context) error {
|
|||||||
Cache: &client.CacheOptions{
|
Cache: &client.CacheOptions{
|
||||||
DisableFor: []client.Object{
|
DisableFor: []client.Object{
|
||||||
&corev1.Secret{},
|
&corev1.Secret{},
|
||||||
|
&barmancloudv1.ObjectStore{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -80,18 +65,10 @@ func Start(ctx context.Context) error {
|
|||||||
if err := mgr.Add(&CNPGI{
|
if err := mgr.Add(&CNPGI{
|
||||||
PluginPath: viper.GetString("plugin-path"),
|
PluginPath: viper.GetString("plugin-path"),
|
||||||
SpoolDirectory: viper.GetString("spool-directory"),
|
SpoolDirectory: viper.GetString("spool-directory"),
|
||||||
ArchiveConfiguration: client.ObjectKey{
|
|
||||||
Namespace: namespace,
|
|
||||||
Name: archiveConfiguration,
|
|
||||||
},
|
|
||||||
ClusterObjectKey: client.ObjectKey{
|
ClusterObjectKey: client.ObjectKey{
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Name: clusterName,
|
Name: clusterName,
|
||||||
},
|
},
|
||||||
BackupToRestoreObjectKey: client.ObjectKey{
|
|
||||||
Namespace: namespace,
|
|
||||||
Name: backupToRestoreName,
|
|
||||||
},
|
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
PGDataPath: viper.GetString("pgdata"),
|
PGDataPath: viper.GetString("pgdata"),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/cloudnative-pg/barman-cloud/pkg/api"
|
"github.com/cloudnative-pg/barman-cloud/pkg/api"
|
||||||
barmanArchiver "github.com/cloudnative-pg/barman-cloud/pkg/archiver"
|
barmanArchiver "github.com/cloudnative-pg/barman-cloud/pkg/archiver"
|
||||||
barmanCapabilities "github.com/cloudnative-pg/barman-cloud/pkg/capabilities"
|
barmanCapabilities "github.com/cloudnative-pg/barman-cloud/pkg/capabilities"
|
||||||
|
barmanCatalog "github.com/cloudnative-pg/barman-cloud/pkg/catalog"
|
||||||
barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command"
|
barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command"
|
||||||
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
||||||
barmanRestorer "github.com/cloudnative-pg/barman-cloud/pkg/restorer"
|
barmanRestorer "github.com/cloudnative-pg/barman-cloud/pkg/restorer"
|
||||||
@ -22,10 +23,11 @@ import (
|
|||||||
"github.com/cloudnative-pg/machinery/pkg/execlog"
|
"github.com/cloudnative-pg/machinery/pkg/execlog"
|
||||||
"github.com/cloudnative-pg/machinery/pkg/fileutils"
|
"github.com/cloudnative-pg/machinery/pkg/fileutils"
|
||||||
"github.com/cloudnative-pg/machinery/pkg/log"
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/common"
|
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,7 +46,6 @@ type JobHookImpl struct {
|
|||||||
Client client.Client
|
Client client.Client
|
||||||
ClusterObjectKey client.ObjectKey
|
ClusterObjectKey client.ObjectKey
|
||||||
BackupToRestore client.ObjectKey
|
BackupToRestore client.ObjectKey
|
||||||
ArchiveConfiguration client.ObjectKey
|
|
||||||
SpoolDirectory string
|
SpoolDirectory string
|
||||||
PgDataPath string
|
PgDataPath string
|
||||||
PgWalFolderToSymlink string
|
PgWalFolderToSymlink string
|
||||||
@ -78,32 +79,70 @@ func (impl JobHookImpl) Restore(
|
|||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Before starting the restore we check if the archive destination is safe to use
|
|
||||||
// otherwise, we stop creating the cluster
|
recoveryPluginConfiguration := cluster.GetRecoverySourcePlugin()
|
||||||
if err := impl.checkBackupDestination(ctx, &cluster); err != nil {
|
|
||||||
|
var recoveryObjectStore barmancloudv1.ObjectStore
|
||||||
|
if err := impl.Client.Get(ctx, types.NamespacedName{
|
||||||
|
Namespace: cluster.Namespace,
|
||||||
|
// TODO: refactor -> cnpg-i-machinery should be able to help us on getting
|
||||||
|
// the configuration for a recovery plugin
|
||||||
|
Name: recoveryPluginConfiguration.Parameters["barmanObjectName"],
|
||||||
|
}, &recoveryObjectStore); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var backup cnpgv1.Backup
|
var targetObjectStoreName types.NamespacedName
|
||||||
|
for _, plugin := range cluster.Spec.Plugins {
|
||||||
if err := decoder.DecodeObject(
|
if plugin.IsEnabled() && plugin.Name == metadata.PluginName {
|
||||||
req.GetBackupDefinition(),
|
targetObjectStoreName = types.NamespacedName{
|
||||||
&backup,
|
Namespace: cluster.Namespace,
|
||||||
cnpgv1.GroupVersion.WithKind("Backup"),
|
Name: plugin.Parameters["barmanObjectName"],
|
||||||
); err != nil {
|
}
|
||||||
return nil, err
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
env, err := impl.getBarmanEnvFromBackup(ctx, &backup)
|
var targetObjectStore barmancloudv1.ObjectStore
|
||||||
|
if targetObjectStoreName.Name != "" {
|
||||||
|
if err := impl.Client.Get(ctx, targetObjectStoreName, &targetObjectStore); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before starting the restore we check if the archive destination is safe to use,
|
||||||
|
// otherwise we stop creating the cluster
|
||||||
|
if targetObjectStoreName.Name != "" {
|
||||||
|
if err := impl.checkBackupDestination(ctx, &cluster, &targetObjectStore.Spec.Configuration); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect the backup to recover
|
||||||
|
backup, env, err := loadBackupObjectFromExternalCluster(
|
||||||
|
ctx,
|
||||||
|
impl.Client,
|
||||||
|
&cluster,
|
||||||
|
&recoveryObjectStore.Spec.Configuration,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := impl.ensureArchiveContainsLastCheckpointRedoWAL(ctx, &cluster, env, &backup); err != nil {
|
if err := impl.ensureArchiveContainsLastCheckpointRedoWAL(
|
||||||
|
ctx,
|
||||||
|
env,
|
||||||
|
backup,
|
||||||
|
&recoveryObjectStore.Spec.Configuration,
|
||||||
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := impl.restoreDataDir(ctx, &backup, env); err != nil {
|
if err := impl.restoreDataDir(
|
||||||
|
ctx,
|
||||||
|
backup,
|
||||||
|
env,
|
||||||
|
&recoveryObjectStore.Spec.Configuration,
|
||||||
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +152,7 @@ func (impl JobHookImpl) Restore(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := getRestoreWalConfig(ctx, &backup)
|
config, err := getRestoreWalConfig(ctx, backup, &recoveryObjectStore.Spec.Configuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -126,7 +165,12 @@ func (impl JobHookImpl) Restore(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// restoreDataDir restores PGDATA from an existing backup
|
// restoreDataDir restores PGDATA from an existing backup
|
||||||
func (impl JobHookImpl) restoreDataDir(ctx context.Context, backup *cnpgv1.Backup, env []string) error {
|
func (impl JobHookImpl) restoreDataDir(
|
||||||
|
ctx context.Context,
|
||||||
|
backup *cnpgv1.Backup,
|
||||||
|
env []string,
|
||||||
|
barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration,
|
||||||
|
) error {
|
||||||
var options []string
|
var options []string
|
||||||
|
|
||||||
if backup.Status.EndpointURL != "" {
|
if backup.Status.EndpointURL != "" {
|
||||||
@ -136,11 +180,7 @@ func (impl JobHookImpl) restoreDataDir(ctx context.Context, backup *cnpgv1.Backu
|
|||||||
options = append(options, backup.Status.ServerName)
|
options = append(options, backup.Status.ServerName)
|
||||||
options = append(options, backup.Status.BackupID)
|
options = append(options, backup.Status.BackupID)
|
||||||
|
|
||||||
creds, err := common.GetCredentialsFromBackup(backup)
|
options, err := barmanCommand.AppendCloudProviderOptionsFromConfiguration(ctx, options, barmanConfiguration)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
options, err = barmanCommand.AppendCloudProviderOptionsFromBackup(ctx, options, creds)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -168,9 +208,9 @@ func (impl JobHookImpl) restoreDataDir(ctx context.Context, backup *cnpgv1.Backu
|
|||||||
|
|
||||||
func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL(
|
func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
cluster *cnpgv1.Cluster,
|
|
||||||
env []string,
|
env []string,
|
||||||
backup *cnpgv1.Backup,
|
backup *cnpgv1.Backup,
|
||||||
|
barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration,
|
||||||
) error {
|
) error {
|
||||||
// it's the full path of the file that will temporarily contain the LastCheckpointRedoWAL
|
// it's the full path of the file that will temporarily contain the LastCheckpointRedoWAL
|
||||||
const testWALPath = RecoveryTemporaryDirectory + "/test.wal"
|
const testWALPath = RecoveryTemporaryDirectory + "/test.wal"
|
||||||
@ -191,17 +231,7 @@ func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
creds, err := common.GetCredentialsFromBackup(backup)
|
opts, err := barmanCommand.CloudWalRestoreOptions(ctx, barmanConfiguration, backup.Status.ServerName)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
opts, err := barmanCommand.CloudWalRestoreOptions(ctx, &api.BarmanObjectStoreConfiguration{
|
|
||||||
BarmanCredentials: creds,
|
|
||||||
EndpointCA: backup.Status.EndpointCA,
|
|
||||||
EndpointURL: backup.Status.EndpointURL,
|
|
||||||
DestinationPath: backup.Status.DestinationPath,
|
|
||||||
ServerName: backup.Status.ServerName,
|
|
||||||
}, cluster.Name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -216,21 +246,13 @@ func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL(
|
|||||||
func (impl *JobHookImpl) checkBackupDestination(
|
func (impl *JobHookImpl) checkBackupDestination(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
cluster *cnpgv1.Cluster,
|
cluster *cnpgv1.Cluster,
|
||||||
|
barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration,
|
||||||
) error {
|
) error {
|
||||||
if impl.ArchiveConfiguration.Name == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var barmanObj barmancloudv1.ObjectStore
|
|
||||||
if err := impl.Client.Get(ctx, impl.ArchiveConfiguration, &barmanObj); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get environment from cache
|
// Get environment from cache
|
||||||
env, err := barmanCredentials.EnvSetRestoreCloudCredentials(ctx,
|
env, err := barmanCredentials.EnvSetRestoreCloudCredentials(ctx,
|
||||||
impl.Client,
|
impl.Client,
|
||||||
barmanObj.Namespace,
|
cluster.Namespace,
|
||||||
&barmanObj.Spec.Configuration,
|
barmanConfiguration,
|
||||||
os.Environ())
|
os.Environ())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't get credentials for cluster %v: %w", cluster.Name, err)
|
return fmt.Errorf("can't get credentials for cluster %v: %w", cluster.Name, err)
|
||||||
@ -251,9 +273,19 @@ func (impl *JobHookImpl) checkBackupDestination(
|
|||||||
return fmt.Errorf("while creating the archiver: %w", err)
|
return fmt.Errorf("while creating the archiver: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: refactor this code elsewhere
|
||||||
|
serverName := cluster.Name
|
||||||
|
for _, plugin := range cluster.Spec.Plugins {
|
||||||
|
if plugin.IsEnabled() && plugin.Name == metadata.PluginName {
|
||||||
|
if pluginServerName, ok := plugin.Parameters["serverName"]; ok {
|
||||||
|
serverName = pluginServerName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get WAL archive options
|
// Get WAL archive options
|
||||||
checkWalOptions, err := walArchiver.BarmanCloudCheckWalArchiveOptions(
|
checkWalOptions, err := walArchiver.BarmanCloudCheckWalArchiveOptions(
|
||||||
ctx, &barmanObj.Spec.Configuration, barmanObj.Name)
|
ctx, barmanConfiguration, serverName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err, "while getting barman-cloud-wal-archive options")
|
log.Error(err, "while getting barman-cloud-wal-archive options")
|
||||||
return err
|
return err
|
||||||
@ -267,34 +299,6 @@ func (impl *JobHookImpl) checkBackupDestination(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (impl JobHookImpl) getBarmanEnvFromBackup(
|
|
||||||
ctx context.Context,
|
|
||||||
backup *cnpgv1.Backup,
|
|
||||||
) ([]string, error) {
|
|
||||||
creds, err := common.GetCredentialsFromBackup(backup)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
env, err := barmanCredentials.EnvSetRestoreCloudCredentials(
|
|
||||||
ctx,
|
|
||||||
impl.Client,
|
|
||||||
impl.BackupToRestore.Namespace,
|
|
||||||
&api.BarmanObjectStoreConfiguration{
|
|
||||||
BarmanCredentials: creds,
|
|
||||||
EndpointURL: backup.Status.EndpointURL,
|
|
||||||
EndpointCA: backup.Status.EndpointCA,
|
|
||||||
DestinationPath: backup.Status.DestinationPath,
|
|
||||||
ServerName: backup.Status.ServerName,
|
|
||||||
},
|
|
||||||
os.Environ())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Recovering existing backup", "backup", backup)
|
|
||||||
return env, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// restoreCustomWalDir moves the current pg_wal data to the specified custom wal dir and applies the symlink
|
// restoreCustomWalDir moves the current pg_wal data to the specified custom wal dir and applies the symlink
|
||||||
// returns indicating if any changes were made and any error encountered in the process
|
// returns indicating if any changes were made and any error encountered in the process
|
||||||
func (impl JobHookImpl) restoreCustomWalDir(ctx context.Context) (bool, error) {
|
func (impl JobHookImpl) restoreCustomWalDir(ctx context.Context) (bool, error) {
|
||||||
@ -332,7 +336,11 @@ func (impl JobHookImpl) restoreCustomWalDir(ctx context.Context) (bool, error) {
|
|||||||
// getRestoreWalConfig obtains the content to append to `custom.conf` allowing PostgreSQL
|
// getRestoreWalConfig obtains the content to append to `custom.conf` allowing PostgreSQL
|
||||||
// to complete the WAL recovery from the object storage and then start
|
// to complete the WAL recovery from the object storage and then start
|
||||||
// as a new primary
|
// as a new primary
|
||||||
func getRestoreWalConfig(ctx context.Context, backup *cnpgv1.Backup) (string, error) {
|
func getRestoreWalConfig(
|
||||||
|
ctx context.Context,
|
||||||
|
backup *cnpgv1.Backup,
|
||||||
|
barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration,
|
||||||
|
) (string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
cmd := []string{barmanCapabilities.BarmanCloudWalRestore}
|
cmd := []string{barmanCapabilities.BarmanCloudWalRestore}
|
||||||
@ -342,12 +350,7 @@ func getRestoreWalConfig(ctx context.Context, backup *cnpgv1.Backup) (string, er
|
|||||||
cmd = append(cmd, backup.Status.DestinationPath)
|
cmd = append(cmd, backup.Status.DestinationPath)
|
||||||
cmd = append(cmd, backup.Status.ServerName)
|
cmd = append(cmd, backup.Status.ServerName)
|
||||||
|
|
||||||
creds, err := common.GetCredentialsFromBackup(backup)
|
cmd, err = barmanCommand.AppendCloudProviderOptionsFromConfiguration(ctx, cmd, barmanConfiguration)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd, err = barmanCommand.AppendCloudProviderOptionsFromBackup(ctx, cmd, creds)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -361,3 +364,96 @@ func getRestoreWalConfig(ctx context.Context, backup *cnpgv1.Backup) (string, er
|
|||||||
|
|
||||||
return recoveryFileContents, nil
|
return recoveryFileContents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadBackupObjectFromExternalCluster generates an in-memory Backup structure given a reference to
|
||||||
|
// an external cluster, loading the required information from the object store
|
||||||
|
func loadBackupObjectFromExternalCluster(
|
||||||
|
ctx context.Context,
|
||||||
|
typedClient client.Client,
|
||||||
|
cluster *cnpgv1.Cluster,
|
||||||
|
recoveryObjectStore *api.BarmanObjectStoreConfiguration,
|
||||||
|
) (*cnpgv1.Backup, []string, error) {
|
||||||
|
contextLogger := log.FromContext(ctx)
|
||||||
|
sourceName := cluster.Spec.Bootstrap.Recovery.Source
|
||||||
|
|
||||||
|
if sourceName == "" {
|
||||||
|
return nil, nil, fmt.Errorf("recovery source not specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
server, found := cluster.ExternalCluster(sourceName)
|
||||||
|
if !found {
|
||||||
|
return nil, nil, fmt.Errorf("missing external cluster: %v", sourceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: document this, should this be in the helper?
|
||||||
|
var serverName string
|
||||||
|
if pluginServerName, ok := server.PluginConfiguration.Parameters["serverName"]; ok {
|
||||||
|
serverName = pluginServerName
|
||||||
|
} else {
|
||||||
|
serverName = server.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
contextLogger.Info("Recovering from external cluster",
|
||||||
|
"sourceName", sourceName,
|
||||||
|
"serverName", serverName)
|
||||||
|
|
||||||
|
env, err := barmanCredentials.EnvSetRestoreCloudCredentials(
|
||||||
|
ctx,
|
||||||
|
typedClient,
|
||||||
|
cluster.Namespace,
|
||||||
|
recoveryObjectStore,
|
||||||
|
os.Environ())
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
backupCatalog, err := barmanCommand.GetBackupList(ctx, recoveryObjectStore, serverName, env)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are now choosing the right backup to restore
|
||||||
|
var targetBackup *barmanCatalog.BarmanBackup
|
||||||
|
if cluster.Spec.Bootstrap.Recovery != nil &&
|
||||||
|
cluster.Spec.Bootstrap.Recovery.RecoveryTarget != nil {
|
||||||
|
targetBackup, err = backupCatalog.FindBackupInfo(
|
||||||
|
cluster.Spec.Bootstrap.Recovery.RecoveryTarget,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
targetBackup = backupCatalog.LatestBackupInfo()
|
||||||
|
}
|
||||||
|
if targetBackup == nil {
|
||||||
|
return nil, nil, fmt.Errorf("no target backup found")
|
||||||
|
}
|
||||||
|
|
||||||
|
contextLogger.Info("Target backup found", "backup", targetBackup)
|
||||||
|
|
||||||
|
return &cnpgv1.Backup{
|
||||||
|
Spec: cnpgv1.BackupSpec{
|
||||||
|
Cluster: cnpgv1.LocalObjectReference{
|
||||||
|
Name: serverName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: cnpgv1.BackupStatus{
|
||||||
|
BarmanCredentials: recoveryObjectStore.BarmanCredentials,
|
||||||
|
EndpointCA: recoveryObjectStore.EndpointCA,
|
||||||
|
EndpointURL: recoveryObjectStore.EndpointURL,
|
||||||
|
DestinationPath: recoveryObjectStore.DestinationPath,
|
||||||
|
ServerName: serverName,
|
||||||
|
BackupID: targetBackup.ID,
|
||||||
|
Phase: cnpgv1.BackupPhaseCompleted,
|
||||||
|
StartedAt: &metav1.Time{Time: targetBackup.BeginTime},
|
||||||
|
StoppedAt: &metav1.Time{Time: targetBackup.EndTime},
|
||||||
|
BeginWal: targetBackup.BeginWal,
|
||||||
|
EndWal: targetBackup.EndWal,
|
||||||
|
BeginLSN: targetBackup.BeginLSN,
|
||||||
|
EndLSN: targetBackup.EndLSN,
|
||||||
|
Error: targetBackup.Error,
|
||||||
|
CommandOutput: "",
|
||||||
|
CommandError: "",
|
||||||
|
},
|
||||||
|
}, env, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -11,13 +11,11 @@ import (
|
|||||||
|
|
||||||
// CNPGI is the implementation of the PostgreSQL sidecar
|
// CNPGI is the implementation of the PostgreSQL sidecar
|
||||||
type CNPGI struct {
|
type CNPGI struct {
|
||||||
PluginPath string
|
PluginPath string
|
||||||
SpoolDirectory string
|
SpoolDirectory string
|
||||||
ArchiveConfiguration client.ObjectKey
|
ClusterObjectKey client.ObjectKey
|
||||||
ClusterObjectKey client.ObjectKey
|
Client client.Client
|
||||||
BackupToRestoreObjectKey client.ObjectKey
|
PGDataPath string
|
||||||
Client client.Client
|
|
||||||
PGDataPath string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the GRPC service
|
// Start starts the GRPC service
|
||||||
@ -29,11 +27,9 @@ func (c *CNPGI) Start(ctx context.Context) error {
|
|||||||
restore.RegisterRestoreJobHooksServer(server, &JobHookImpl{
|
restore.RegisterRestoreJobHooksServer(server, &JobHookImpl{
|
||||||
Client: c.Client,
|
Client: c.Client,
|
||||||
ClusterObjectKey: c.ClusterObjectKey,
|
ClusterObjectKey: c.ClusterObjectKey,
|
||||||
BackupToRestore: c.BackupToRestoreObjectKey,
|
|
||||||
SpoolDirectory: c.SpoolDirectory,
|
SpoolDirectory: c.SpoolDirectory,
|
||||||
PgDataPath: c.PGDataPath,
|
PgDataPath: c.PGDataPath,
|
||||||
PgWalFolderToSymlink: PgWalVolumePgWalPath,
|
PgWalFolderToSymlink: PgWalVolumePgWalPath,
|
||||||
ArchiveConfiguration: c.ArchiveConfiguration,
|
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user