mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-01-11 21:23:12 +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:
|
||||
recovery:
|
||||
backup:
|
||||
name: backup-example
|
||||
usePlugin: true
|
||||
source: source
|
||||
|
||||
plugins:
|
||||
- name: barman-cloud.cloudnative-pg.io
|
||||
# parameters:
|
||||
# barmanObjectName: minio-store
|
||||
externalClusters:
|
||||
- name: source
|
||||
plugin:
|
||||
name: barman-cloud.cloudnative-pg.io
|
||||
parameters:
|
||||
barmanObjectName: minio-store
|
||||
serverName: cluster-example
|
||||
|
||||
storage:
|
||||
size: 1Gi
|
||||
|
||||
34
go.mod
34
go.mod
@ -6,20 +6,20 @@ toolchain go1.23.1
|
||||
|
||||
require (
|
||||
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/cnpg-i v0.0.0-20241021130537-c4a74d755f0a
|
||||
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241031170209-ad2b0d78a230
|
||||
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/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/gomega v1.34.2
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/spf13/viper v1.19.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
k8s.io/api v0.31.1
|
||||
k8s.io/apimachinery v0.31.1
|
||||
k8s.io/client-go v0.31.1
|
||||
k8s.io/api v0.31.2
|
||||
k8s.io/apimachinery v0.31.2
|
||||
k8s.io/client-go v0.31.2
|
||||
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 (
|
||||
@ -74,8 +74,8 @@ require (
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // 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/client_golang v1.20.4 // indirect
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.77.2 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.59.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/zap v1.27.0 // 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/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/term v0.24.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/term v0.25.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
golang.org/x/tools v0.25.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // 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/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.31.1 // indirect
|
||||
k8s.io/apiserver v0.31.1 // indirect
|
||||
k8s.io/component-base v0.31.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.31.2 // indirect
|
||||
k8s.io/apiserver v0.31.2 // indirect
|
||||
k8s.io/component-base v0.31.2 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // 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/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/cloudnative-pg v1.24.1-0.20241017151552-20297270038b h1:47OKNQRgSs9XWvIt2bm8B1Yo7TA5oxBGjQPqF0j+Llw=
|
||||
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241017151552-20297270038b/go.mod h1:0grklCuA9WSA5lazBeTgDqLHjxP13fqAhqlveDx7hPg=
|
||||
github.com/cloudnative-pg/cnpg-i v0.0.0-20241021130537-c4a74d755f0a h1:K4c+gX96NAt9C3AeffB8T4tvI3Qn9Fpi5x7Kzd+Iiyg=
|
||||
github.com/cloudnative-pg/cnpg-i v0.0.0-20241021130537-c4a74d755f0a/go.mod h1:fAU7ySVzjpt/RZntxWZiWJCjaBJayzIxEnd0NuO7oQc=
|
||||
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.20241031170209-ad2b0d78a230/go.mod h1:La89zdElTqqZ5LXHFm/UjOwvS9iHSE8GuOW4fYUgHw8=
|
||||
github.com/cloudnative-pg/cnpg-i v0.0.0-20241030162745-80b6d07403c1 h1:v3Vr+FH5BXmS7Eqx17u51oijZ4T7y62vUMCUAr7CffE=
|
||||
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/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-20241010122207-5ac7af31ef72/go.mod h1:bWp1Es5zlxElg4Z/c5f0RKOkDcyNvDHdYIvNcPQU4WM=
|
||||
github.com/cloudnative-pg/machinery v0.0.0-20241014090714-c27747f9974b h1:4Q2VQsPlLHliJdi87zodQ0FHLd1cJINMm4N70eu8rRg=
|
||||
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/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=
|
||||
@ -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.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
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.1/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.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
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.2/go.mod h1:D0KY8md81DQKdaR/cXwnhoWB3MYYyc/UjvqE8GFkIvA=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
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/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
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-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.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
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/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
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-20190412213103-97732733099d/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.25.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.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||
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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||
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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
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.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
|
||||
k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40=
|
||||
k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ=
|
||||
k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
|
||||
k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c=
|
||||
k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM=
|
||||
k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
|
||||
k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
|
||||
k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8=
|
||||
k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w=
|
||||
k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0=
|
||||
k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk=
|
||||
k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0=
|
||||
k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM=
|
||||
k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
|
||||
k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4=
|
||||
k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE=
|
||||
k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc=
|
||||
k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs=
|
||||
k8s.io/component-base v0.31.2 h1:Z1J1LIaC0AV+nzcPRFqfK09af6bZ4D1nAOpWsy9owlA=
|
||||
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/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
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=
|
||||
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/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q=
|
||||
sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
|
||||
sigs.k8s.io/controller-runtime v0.19.1 h1:Son+Q40+Be3QWb+niBXAg2vFiYWolDjjRfO8hn/cxOk=
|
||||
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/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
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("backup-to-restore", "BACKUP_TO_RESTORE")
|
||||
_ = viper.BindEnv("barman-archive-configuration", "BARMAN_OBJECT_NAME")
|
||||
_ = viper.BindEnv("cluster-name", "CLUSTER_NAME")
|
||||
_ = viper.BindEnv("pod-name", "POD_NAME")
|
||||
_ = 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 (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
@ -11,6 +10,7 @@ import (
|
||||
barmanBackup "github.com/cloudnative-pg/barman-cloud/pkg/backup"
|
||||
barmanCapabilities "github.com/cloudnative-pg/barman-cloud/pkg/capabilities"
|
||||
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/cnpg-i/pkg/backup"
|
||||
"github.com/cloudnative-pg/machinery/pkg/fileutils"
|
||||
@ -20,6 +20,7 @@ import (
|
||||
"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/common"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||
)
|
||||
|
||||
@ -69,6 +70,11 @@ func (b BackupServiceImplementation) 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
|
||||
if err := b.Client.Get(ctx, b.BarmanObjectKey, &objectStore); err != nil {
|
||||
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
|
||||
// PGHOST (and the like) to be available
|
||||
osEnvironment := os.Environ()
|
||||
caBundleEnvironment := getRestoreCABundleEnv(&objectStore.Spec.Configuration)
|
||||
caBundleEnvironment := common.GetRestoreCABundleEnv(&objectStore.Spec.Configuration)
|
||||
env, err := barmanCredentials.EnvSetBackupCloudCredentials(
|
||||
ctx,
|
||||
b.Client,
|
||||
objectStore.Namespace,
|
||||
&objectStore.Spec.Configuration,
|
||||
mergeEnv(osEnvironment, caBundleEnvironment))
|
||||
common.MergeEnv(osEnvironment, caBundleEnvironment))
|
||||
if err != nil {
|
||||
contextLogger.Error(err, "while setting backup cloud credentials")
|
||||
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()))
|
||||
|
||||
if err = backupCmd.Take(
|
||||
ctx,
|
||||
backupName,
|
||||
objectStore.Name,
|
||||
serverName,
|
||||
env,
|
||||
barmanCloudExecutor{},
|
||||
postgres.BackupTemporaryDirectory,
|
||||
@ -122,7 +137,7 @@ func (b BackupServiceImplementation) Backup(
|
||||
executedBackupInfo, err := backupCmd.GetExecutedBackupInfo(
|
||||
ctx,
|
||||
backupName,
|
||||
objectStore.Name,
|
||||
serverName,
|
||||
barmanCloudExecutor{},
|
||||
env)
|
||||
if err != nil {
|
||||
@ -130,25 +145,6 @@ func (b BackupServiceImplementation) Backup(
|
||||
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)
|
||||
return &backup.BackupResult{
|
||||
BackupId: executedBackupInfo.ID,
|
||||
@ -166,13 +162,6 @@ func (b BackupServiceImplementation) Backup(
|
||||
"version": metadata.Data.Version,
|
||||
"name": metadata.Data.Name,
|
||||
"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
|
||||
}
|
||||
|
||||
@ -6,10 +6,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
||||
"github.com/cloudnative-pg/barman-cloud/pkg/archiver"
|
||||
barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command"
|
||||
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
||||
@ -21,6 +19,7 @@ import (
|
||||
"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/common"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||
)
|
||||
|
||||
@ -66,6 +65,21 @@ func (w WALServiceImplementation) Archive(
|
||||
ctx context.Context,
|
||||
request *wal.WALArchiveRequest,
|
||||
) (*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
|
||||
if err := w.Client.Get(ctx, w.BarmanObjectKey, &objectStore); err != nil {
|
||||
return nil, err
|
||||
@ -95,7 +109,7 @@ func (w WALServiceImplementation) Archive(
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -111,6 +125,7 @@ func (w WALServiceImplementation) Archive(
|
||||
}
|
||||
|
||||
// Restore implements the WALService interface
|
||||
// nolint: gocognit
|
||||
func (w WALServiceImplementation) Restore(
|
||||
ctx context.Context,
|
||||
request *wal.WALRestoreRequest,
|
||||
@ -134,7 +149,7 @@ func (w WALServiceImplementation) Restore(
|
||||
|
||||
barmanConfiguration := &objectStore.Spec.Configuration
|
||||
|
||||
env := getRestoreCABundleEnv(barmanConfiguration)
|
||||
env := common.GetRestoreCABundleEnv(barmanConfiguration)
|
||||
credentialsEnv, err := barmanCredentials.EnvSetBackupCloudCredentials(
|
||||
ctx,
|
||||
w.Client,
|
||||
@ -145,9 +160,19 @@ func (w WALServiceImplementation) Restore(
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, fmt.Errorf("while getting barman-cloud-wal-restore options: %w", err)
|
||||
}
|
||||
@ -254,68 +279,6 @@ func (w WALServiceImplementation) SetFirstRequired(
|
||||
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.
|
||||
func isStreamingAvailable(cluster *cnpgv1.Cluster, podName string) bool {
|
||||
if cluster == nil {
|
||||
|
||||
@ -16,6 +16,7 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"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"
|
||||
)
|
||||
|
||||
@ -103,13 +104,11 @@ func reconcileJob(
|
||||
pluginConfiguration *config.PluginConfiguration,
|
||||
) (*lifecycle.OperatorLifecycleResponse, error) {
|
||||
contextLogger := log.FromContext(ctx).WithName("lifecycle")
|
||||
if !cluster.UsePluginForBootstrapRecoveryBackup() {
|
||||
contextLogger.Debug("cluster does not use the plugin for recovery, skipping")
|
||||
if pluginConfig := cluster.GetRecoverySourcePlugin(); pluginConfig == nil || pluginConfig.Name != metadata.PluginName {
|
||||
contextLogger.Debug("cluster does not use the this plugin for recovery, skipping")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
backupSource := cluster.Spec.Bootstrap.Recovery.Backup
|
||||
|
||||
var job batchv1.Job
|
||||
if err := decoder.DecodeObject(
|
||||
request.GetObjectDefinition(),
|
||||
@ -138,12 +137,6 @@ func reconcileJob(
|
||||
"full-recovery",
|
||||
corev1.Container{
|
||||
Args: []string{"restore"},
|
||||
Env: []corev1.EnvVar{
|
||||
{
|
||||
Name: "BACKUP_TO_RESTORE",
|
||||
Value: backupSource.Name,
|
||||
},
|
||||
},
|
||||
},
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("while reconciling pod spec for job: %w", err)
|
||||
@ -231,9 +224,6 @@ func reconcilePodSpec(
|
||||
sidecarConfig.Name = "plugin-barman-cloud"
|
||||
sidecarConfig.Image = viper.GetString("sidecar-image")
|
||||
sidecarConfig.ImagePullPolicy = cluster.Spec.ImagePullPolicy
|
||||
sidecarConfig.Command = []string{
|
||||
"/manager",
|
||||
}
|
||||
|
||||
// merge the main container envs if they aren't already set
|
||||
for _, container := range spec.Containers {
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||
|
||||
@ -34,17 +33,31 @@ var _ = Describe("LifecycleImplementation", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
pluginConfiguration = &config.PluginConfiguration{
|
||||
BarmanObjectName: "barman-object",
|
||||
BarmanObjectName: "minio-store-dest",
|
||||
}
|
||||
cluster = &cnpgv1.Cluster{
|
||||
Spec: cnpgv1.ClusterSpec{
|
||||
Bootstrap: &cnpgv1.BootstrapConfiguration{
|
||||
Recovery: &cnpgv1.BootstrapRecovery{
|
||||
Backup: &cnpgv1.BackupSource{
|
||||
LocalObjectReference: cnpgv1.LocalObjectReference{
|
||||
Name: "backup-object",
|
||||
Source: "origin-server",
|
||||
},
|
||||
},
|
||||
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)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(patch).To(ContainElement(HaveKeyWithValue("op", "add")))
|
||||
Expect(patch).To(ContainElement(HaveKeyWithValue("path", "/spec/containers/1")))
|
||||
Expect(patch).To(ContainElement(HaveKeyWithValue("value", HaveKeyWithValue("name", "plugin-barman-cloud"))))
|
||||
Expect(patch).To(ContainElement(HaveKeyWithValue("path", "/spec/initContainers")))
|
||||
Expect(patch).To(ContainElement(
|
||||
HaveKey("value")))
|
||||
})
|
||||
|
||||
It("returns an error for invalid pod definition", func(ctx SpecContext) {
|
||||
|
||||
@ -15,7 +15,7 @@ import (
|
||||
"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/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/specs"
|
||||
)
|
||||
@ -75,14 +75,16 @@ func (r ReconcilerImplementation) Pre(
|
||||
pluginConfiguration := config.NewFromCluster(&cluster)
|
||||
|
||||
contextLogger.Debug("parsing barman object configuration")
|
||||
var barmanObject *barmancloudv1.ObjectStore
|
||||
|
||||
var barmanObjects []barmancloudv1.ObjectStore
|
||||
|
||||
// this could be empty during recoveries
|
||||
if pluginConfiguration.BarmanObjectName != "" {
|
||||
barmanObject = &barmancloudv1.ObjectStore{}
|
||||
var barmanObject barmancloudv1.ObjectStore
|
||||
if err := r.Client.Get(ctx, client.ObjectKey{
|
||||
Namespace: cluster.Namespace,
|
||||
Name: pluginConfiguration.BarmanObjectName,
|
||||
}, barmanObject); err != nil {
|
||||
}, &barmanObject); err != nil {
|
||||
if apierrs.IsNotFound(err) {
|
||||
contextLogger.Info("barman object configuration not found, requeuing")
|
||||
return &reconciler.ReconcilerHooksResult{
|
||||
@ -92,28 +94,23 @@ func (r ReconcilerImplementation) Pre(
|
||||
|
||||
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
|
||||
if cluster.UsePluginForBootstrapRecoveryBackup() {
|
||||
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 {
|
||||
if err := r.ensureRole(ctx, &cluster, barmanObjects, additionalSecretNames); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -127,6 +124,30 @@ func (r ReconcilerImplementation) Pre(
|
||||
}, 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
|
||||
func (r ReconcilerImplementation) Post(
|
||||
_ context.Context,
|
||||
@ -140,11 +161,11 @@ func (r ReconcilerImplementation) Post(
|
||||
func (r ReconcilerImplementation) ensureRole(
|
||||
ctx context.Context,
|
||||
cluster *cnpgv1.Cluster,
|
||||
barmanObject *barmancloudv1.ObjectStore,
|
||||
barmanObjects []barmancloudv1.ObjectStore,
|
||||
additionalSecretNames []string,
|
||||
) error {
|
||||
contextLogger := log.FromContext(ctx)
|
||||
newRole := specs.BuildRole(cluster, barmanObject, additionalSecretNames)
|
||||
newRole := specs.BuildRole(cluster, barmanObjects, additionalSecretNames)
|
||||
|
||||
var role rbacv1.Role
|
||||
if err := r.Client.Get(ctx, client.ObjectKey{
|
||||
|
||||
@ -14,7 +14,7 @@ import (
|
||||
// BuildRole builds the Role object for this cluster
|
||||
func BuildRole(
|
||||
cluster *cnpgv1.Cluster,
|
||||
barmanObject *barmancloudv1.ObjectStore,
|
||||
barmanObjects []barmancloudv1.ObjectStore,
|
||||
additionalSecretNames []string,
|
||||
) *rbacv1.Role {
|
||||
role := &rbacv1.Role{
|
||||
@ -27,8 +27,7 @@ func BuildRole(
|
||||
}
|
||||
|
||||
secretsSet := stringset.New()
|
||||
// TODO: we should handle removals too?
|
||||
if barmanObject != nil {
|
||||
for _, barmanObject := range barmanObjects {
|
||||
role.Rules = append(role.Rules, rbacv1.PolicyRule{
|
||||
APIGroups: []string{
|
||||
"barmancloud.cnpg.io",
|
||||
|
||||
@ -32,9 +32,7 @@ func Start(ctx context.Context) error {
|
||||
setupLog := log.FromContext(ctx)
|
||||
setupLog.Info("Starting barman cloud instance plugin")
|
||||
namespace := viper.GetString("namespace")
|
||||
archiveConfiguration := viper.GetString("barman-archive-configuration")
|
||||
clusterName := viper.GetString("cluster-name")
|
||||
backupToRestoreName := viper.GetString("backup-to-restore")
|
||||
|
||||
objs := map[client.Object]cache.ByObject{
|
||||
&cnpgv1.Cluster{}: {
|
||||
@ -43,20 +41,6 @@ func Start(ctx context.Context) error {
|
||||
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{
|
||||
@ -68,6 +52,7 @@ func Start(ctx context.Context) error {
|
||||
Cache: &client.CacheOptions{
|
||||
DisableFor: []client.Object{
|
||||
&corev1.Secret{},
|
||||
&barmancloudv1.ObjectStore{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -80,18 +65,10 @@ func Start(ctx context.Context) error {
|
||||
if err := mgr.Add(&CNPGI{
|
||||
PluginPath: viper.GetString("plugin-path"),
|
||||
SpoolDirectory: viper.GetString("spool-directory"),
|
||||
ArchiveConfiguration: client.ObjectKey{
|
||||
Namespace: namespace,
|
||||
Name: archiveConfiguration,
|
||||
},
|
||||
ClusterObjectKey: client.ObjectKey{
|
||||
Namespace: namespace,
|
||||
Name: clusterName,
|
||||
},
|
||||
BackupToRestoreObjectKey: client.ObjectKey{
|
||||
Namespace: namespace,
|
||||
Name: backupToRestoreName,
|
||||
},
|
||||
Client: mgr.GetClient(),
|
||||
PGDataPath: viper.GetString("pgdata"),
|
||||
}); err != nil {
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"github.com/cloudnative-pg/barman-cloud/pkg/api"
|
||||
barmanArchiver "github.com/cloudnative-pg/barman-cloud/pkg/archiver"
|
||||
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"
|
||||
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
||||
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/fileutils"
|
||||
"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"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
@ -44,7 +46,6 @@ type JobHookImpl struct {
|
||||
Client client.Client
|
||||
ClusterObjectKey client.ObjectKey
|
||||
BackupToRestore client.ObjectKey
|
||||
ArchiveConfiguration client.ObjectKey
|
||||
SpoolDirectory string
|
||||
PgDataPath string
|
||||
PgWalFolderToSymlink string
|
||||
@ -78,32 +79,70 @@ func (impl JobHookImpl) Restore(
|
||||
); 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 err := impl.checkBackupDestination(ctx, &cluster); err != nil {
|
||||
|
||||
recoveryPluginConfiguration := cluster.GetRecoverySourcePlugin()
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
var backup cnpgv1.Backup
|
||||
|
||||
if err := decoder.DecodeObject(
|
||||
req.GetBackupDefinition(),
|
||||
&backup,
|
||||
cnpgv1.GroupVersion.WithKind("Backup"),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
var targetObjectStoreName types.NamespacedName
|
||||
for _, plugin := range cluster.Spec.Plugins {
|
||||
if plugin.IsEnabled() && plugin.Name == metadata.PluginName {
|
||||
targetObjectStoreName = types.NamespacedName{
|
||||
Namespace: cluster.Namespace,
|
||||
Name: plugin.Parameters["barmanObjectName"],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
if err := impl.restoreDataDir(ctx, &backup, env); err != nil {
|
||||
if err := impl.restoreDataDir(
|
||||
ctx,
|
||||
backup,
|
||||
env,
|
||||
&recoveryObjectStore.Spec.Configuration,
|
||||
); err != nil {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -126,7 +165,12 @@ func (impl JobHookImpl) Restore(
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
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.BackupID)
|
||||
|
||||
creds, err := common.GetCredentialsFromBackup(backup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options, err = barmanCommand.AppendCloudProviderOptionsFromBackup(ctx, options, creds)
|
||||
options, err := barmanCommand.AppendCloudProviderOptionsFromConfiguration(ctx, options, barmanConfiguration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -168,9 +208,9 @@ func (impl JobHookImpl) restoreDataDir(ctx context.Context, backup *cnpgv1.Backu
|
||||
|
||||
func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL(
|
||||
ctx context.Context,
|
||||
cluster *cnpgv1.Cluster,
|
||||
env []string,
|
||||
backup *cnpgv1.Backup,
|
||||
barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration,
|
||||
) error {
|
||||
// it's the full path of the file that will temporarily contain the LastCheckpointRedoWAL
|
||||
const testWALPath = RecoveryTemporaryDirectory + "/test.wal"
|
||||
@ -191,17 +231,7 @@ func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL(
|
||||
return err
|
||||
}
|
||||
|
||||
creds, err := common.GetCredentialsFromBackup(backup)
|
||||
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)
|
||||
opts, err := barmanCommand.CloudWalRestoreOptions(ctx, barmanConfiguration, backup.Status.ServerName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -216,21 +246,13 @@ func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL(
|
||||
func (impl *JobHookImpl) checkBackupDestination(
|
||||
ctx context.Context,
|
||||
cluster *cnpgv1.Cluster,
|
||||
barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration,
|
||||
) 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
|
||||
env, err := barmanCredentials.EnvSetRestoreCloudCredentials(ctx,
|
||||
impl.Client,
|
||||
barmanObj.Namespace,
|
||||
&barmanObj.Spec.Configuration,
|
||||
cluster.Namespace,
|
||||
barmanConfiguration,
|
||||
os.Environ())
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
// 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
|
||||
checkWalOptions, err := walArchiver.BarmanCloudCheckWalArchiveOptions(
|
||||
ctx, &barmanObj.Spec.Configuration, barmanObj.Name)
|
||||
ctx, barmanConfiguration, serverName)
|
||||
if err != nil {
|
||||
log.Error(err, "while getting barman-cloud-wal-archive options")
|
||||
return err
|
||||
@ -267,34 +299,6 @@ func (impl *JobHookImpl) checkBackupDestination(
|
||||
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
|
||||
// returns indicating if any changes were made and any error encountered in the process
|
||||
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
|
||||
// to complete the WAL recovery from the object storage and then start
|
||||
// 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
|
||||
|
||||
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.ServerName)
|
||||
|
||||
creds, err := common.GetCredentialsFromBackup(backup)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cmd, err = barmanCommand.AppendCloudProviderOptionsFromBackup(ctx, cmd, creds)
|
||||
cmd, err = barmanCommand.AppendCloudProviderOptionsFromConfiguration(ctx, cmd, barmanConfiguration)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -361,3 +364,96 @@ func getRestoreWalConfig(ctx context.Context, backup *cnpgv1.Backup) (string, er
|
||||
|
||||
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
|
||||
type CNPGI struct {
|
||||
PluginPath string
|
||||
SpoolDirectory string
|
||||
ArchiveConfiguration client.ObjectKey
|
||||
ClusterObjectKey client.ObjectKey
|
||||
BackupToRestoreObjectKey client.ObjectKey
|
||||
Client client.Client
|
||||
PGDataPath string
|
||||
PluginPath string
|
||||
SpoolDirectory string
|
||||
ClusterObjectKey client.ObjectKey
|
||||
Client client.Client
|
||||
PGDataPath string
|
||||
}
|
||||
|
||||
// Start starts the GRPC service
|
||||
@ -29,11 +27,9 @@ func (c *CNPGI) Start(ctx context.Context) error {
|
||||
restore.RegisterRestoreJobHooksServer(server, &JobHookImpl{
|
||||
Client: c.Client,
|
||||
ClusterObjectKey: c.ClusterObjectKey,
|
||||
BackupToRestore: c.BackupToRestoreObjectKey,
|
||||
SpoolDirectory: c.SpoolDirectory,
|
||||
PgDataPath: c.PGDataPath,
|
||||
PgWalFolderToSymlink: PgWalVolumePgWalPath,
|
||||
ArchiveConfiguration: c.ArchiveConfiguration,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user