mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-01-11 21:23:12 +01:00
feat: operator plugin and manifests (#18)
Signed-off-by: Leonardo Cecchi <leonardo.cecchi@enterprisedb.com>
This commit is contained in:
parent
88e8762858
commit
dd6548c4a2
@ -1,177 +1,90 @@
|
|||||||
/*
|
// Package main is the entrypoint of operator plugin
|
||||||
Copyright 2024.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Package main contains the implementation of the CNPG-i operator plugin
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"context"
|
||||||
"flag"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
// +kubebuilder:scaffold:imports
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"github.com/sourcegraph/conc/pool"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
"github.com/spf13/cobra"
|
||||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
"github.com/spf13/viper"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
|
|
||||||
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/controller"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/manager"
|
||||||
|
|
||||||
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
|
|
||||||
// to ensure that exec-entrypoint and run can make use of them.
|
|
||||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
scheme = runtime.NewScheme()
|
|
||||||
setupLog = ctrl.Log.WithName("setup")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
|
||||||
|
|
||||||
utilruntime.Must(barmancloudv1.AddToScheme(scheme))
|
|
||||||
// +kubebuilder:scaffold:scheme
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var metricsAddr string
|
cobra.EnableTraverseRunHooks = true
|
||||||
var enableLeaderElection bool
|
|
||||||
var probeAddr string
|
|
||||||
var secureMetrics bool
|
|
||||||
var enableHTTP2 bool
|
|
||||||
var tlsOpts []func(*tls.Config)
|
|
||||||
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
|
|
||||||
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
|
|
||||||
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
|
|
||||||
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
|
|
||||||
"Enable leader election for controller manager. "+
|
|
||||||
"Enabling this will ensure there is only one active controller manager.")
|
|
||||||
flag.BoolVar(&secureMetrics, "metrics-secure", true,
|
|
||||||
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
|
|
||||||
flag.BoolVar(&enableHTTP2, "enable-http2", false,
|
|
||||||
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
|
|
||||||
opts := zap.Options{
|
|
||||||
Development: true,
|
|
||||||
}
|
|
||||||
opts.BindFlags(flag.CommandLine)
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
|
logFlags := &log.Flags{}
|
||||||
|
rootCmd := &cobra.Command{
|
||||||
// if the enable-http2 flag is false (the default), http/2 should be disabled
|
Use: "plugin-barman-cloud",
|
||||||
// due to its vulnerabilities. More specifically, disabling http/2 will
|
PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
|
||||||
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
|
logFlags.ConfigureLogging()
|
||||||
// Rapid Reset CVEs. For more information see:
|
return nil
|
||||||
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
|
},
|
||||||
// - https://github.com/advisories/GHSA-4374-p667-p6c8
|
|
||||||
disableHTTP2 := func(c *tls.Config) {
|
|
||||||
setupLog.Info("disabling http/2")
|
|
||||||
c.NextProtos = []string{"http/1.1"}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !enableHTTP2 {
|
logFlags.AddFlags(rootCmd.PersistentFlags())
|
||||||
tlsOpts = append(tlsOpts, disableHTTP2)
|
rootCmd.AddCommand(newOperatorCommand())
|
||||||
}
|
|
||||||
|
|
||||||
webhookServer := webhook.NewServer(webhook.Options{
|
if err := rootCmd.Execute(); err != nil {
|
||||||
TLSOpts: tlsOpts,
|
fmt.Println(err)
|
||||||
})
|
|
||||||
|
|
||||||
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
|
|
||||||
// More info:
|
|
||||||
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/server
|
|
||||||
// - https://book.kubebuilder.io/reference/metrics.html
|
|
||||||
metricsServerOptions := metricsserver.Options{
|
|
||||||
BindAddress: metricsAddr,
|
|
||||||
SecureServing: secureMetrics,
|
|
||||||
// TODO(user): TLSOpts is used to allow configuring the TLS config used for the server. If certificates are
|
|
||||||
// not provided, self-signed certificates will be generated by default. This option is not recommended for
|
|
||||||
// production environments as self-signed certificates do not offer the same level of trust and security
|
|
||||||
// as certificates issued by a trusted Certificate Authority (CA). The primary risk is potentially allowing
|
|
||||||
// unauthorized access to sensitive metrics data. Consider replacing with CertDir, CertName, and KeyName
|
|
||||||
// to provide certificates, ensuring the server communicates using trusted and secure certificates.
|
|
||||||
TLSOpts: tlsOpts,
|
|
||||||
}
|
|
||||||
|
|
||||||
if secureMetrics {
|
|
||||||
// FilterProvider is used to protect the metrics endpoint with authn/authz.
|
|
||||||
// These configurations ensure that only authorized users and service accounts
|
|
||||||
// can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
|
|
||||||
// https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/filters#WithAuthenticationAndAuthorization
|
|
||||||
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
|
|
||||||
}
|
|
||||||
|
|
||||||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
|
||||||
Scheme: scheme,
|
|
||||||
Metrics: metricsServerOptions,
|
|
||||||
WebhookServer: webhookServer,
|
|
||||||
HealthProbeBindAddress: probeAddr,
|
|
||||||
LeaderElection: enableLeaderElection,
|
|
||||||
LeaderElectionID: "822e3f5c.cnpg.io",
|
|
||||||
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
|
|
||||||
// when the Manager ends. This requires the binary to immediately end when the
|
|
||||||
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
|
|
||||||
// speeds up voluntary leader transitions as the new leader don't have to wait
|
|
||||||
// LeaseDuration time first.
|
|
||||||
//
|
|
||||||
// In the default scaffold provided, the program ends immediately after
|
|
||||||
// the manager stops, so would be fine to enable this option. However,
|
|
||||||
// if you are doing or is intended to do any operation such as perform cleanups
|
|
||||||
// after the manager stops then its usage might be unsafe.
|
|
||||||
// LeaderElectionReleaseOnCancel: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
setupLog.Error(err, "unable to start manager")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = (&controller.ObjectStoreReconciler{
|
|
||||||
Client: mgr.GetClient(),
|
|
||||||
Scheme: mgr.GetScheme(),
|
|
||||||
}).SetupWithManager(mgr); err != nil {
|
|
||||||
setupLog.Error(err, "unable to create controller", "controller", "ObjectStore")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
// +kubebuilder:scaffold:builder
|
|
||||||
|
|
||||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
|
||||||
setupLog.Error(err, "unable to set up health check")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
|
|
||||||
setupLog.Error(err, "unable to set up ready check")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := mgr.Add(&operator.CNPGI{}); err != nil {
|
|
||||||
setupLog.Error(err, "unable to create CNPGI webserver")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
setupLog.Info("starting manager")
|
|
||||||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
|
|
||||||
setupLog.Error(err, "problem running manager")
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newOperatorCommand() *cobra.Command {
|
||||||
|
cmd := operator.NewCommand()
|
||||||
|
cmd.Use = "operator"
|
||||||
|
cmd.Short = "Starts the BarmanObjectStore reconciler and the Barman Cloud CNPG-i plugin"
|
||||||
|
grpcServer := cmd.RunE
|
||||||
|
|
||||||
|
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
|
ctrl.SetupSignalHandler()
|
||||||
|
operatorPool := pool.
|
||||||
|
New().
|
||||||
|
WithContext(cmd.Context()).
|
||||||
|
WithCancelOnError().
|
||||||
|
WithFirstError()
|
||||||
|
operatorPool.Go(func(ctx context.Context) error {
|
||||||
|
cmd.SetContext(ctx)
|
||||||
|
|
||||||
|
if len(viper.GetString("sidecar-image")) == 0 {
|
||||||
|
return fmt.Errorf("missing required SIDECAR_IMAGE environment variable")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := grpcServer(cmd, args)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
operatorPool.Go(manager.Start)
|
||||||
|
return operatorPool.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().String("metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
|
||||||
|
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
|
||||||
|
_ = viper.BindPFlag("metrics-bind-address", cmd.Flags().Lookup("metrics-bind-address"))
|
||||||
|
|
||||||
|
cmd.Flags().String("health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
|
||||||
|
_ = viper.BindPFlag("health-probe-bind-address", cmd.Flags().Lookup("health-probe-bind-address"))
|
||||||
|
|
||||||
|
cmd.Flags().Bool("leader-elect", false,
|
||||||
|
"Enable leader election for controller manager. "+
|
||||||
|
"Enabling this will ensure there is only one active controller manager.")
|
||||||
|
_ = viper.BindPFlag("leader-elect", cmd.Flags().Lookup("leader-elect"))
|
||||||
|
|
||||||
|
cmd.Flags().Bool("metrics-secure", true,
|
||||||
|
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
|
||||||
|
_ = viper.BindPFlag("metrics-secure", cmd.Flags().Lookup("metrics-secure"))
|
||||||
|
|
||||||
|
cmd.Flags().Bool("enable-http2", false,
|
||||||
|
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
|
||||||
|
_ = viper.BindPFlag("enable-http2", cmd.Flags().Lookup("enable-http2"))
|
||||||
|
|
||||||
|
_ = viper.BindEnv("sidecar-image", "SIDECAR_IMAGE")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|||||||
@ -91,5 +91,5 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 64Mi
|
memory: 64Mi
|
||||||
serviceAccountName: controller-manager
|
serviceAccountName: plugin-barman-cloud
|
||||||
terminationGracePeriodSeconds: 10
|
terminationGracePeriodSeconds: 10
|
||||||
|
|||||||
@ -11,5 +11,5 @@ roleRef:
|
|||||||
name: leader-election-role
|
name: leader-election-role
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: controller-manager
|
name: plugin-barman-cloud
|
||||||
namespace: system
|
namespace: cnpg-system
|
||||||
|
|||||||
@ -8,5 +8,5 @@ roleRef:
|
|||||||
name: metrics-auth-role
|
name: metrics-auth-role
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: controller-manager
|
name: plugin-barman-cloud
|
||||||
namespace: system
|
namespace: cnpg-system
|
||||||
|
|||||||
@ -11,5 +11,5 @@ roleRef:
|
|||||||
name: manager-role
|
name: manager-role
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: controller-manager
|
name: plugin-barman-cloud
|
||||||
namespace: system
|
namespace: cnpg-system
|
||||||
|
|||||||
@ -4,5 +4,4 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: plugin-barman-cloud
|
app.kubernetes.io/name: plugin-barman-cloud
|
||||||
app.kubernetes.io/managed-by: kustomize
|
app.kubernetes.io/managed-by: kustomize
|
||||||
name: controller-manager
|
name: plugin-barman-cloud
|
||||||
namespace: system
|
|
||||||
|
|||||||
12
docs/examples/cluster-example.yaml
Normal file
12
docs/examples/cluster-example.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: postgresql.cnpg.io/v1
|
||||||
|
kind: Cluster
|
||||||
|
metadata:
|
||||||
|
name: cluster-example
|
||||||
|
spec:
|
||||||
|
instances: 3
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- name: barman-cloud.cloudnative-pg.io
|
||||||
|
|
||||||
|
storage:
|
||||||
|
size: 1Gi
|
||||||
9
go.mod
9
go.mod
@ -10,7 +10,11 @@ require (
|
|||||||
github.com/cloudnative-pg/machinery v0.0.0-20241001075747-34c8797af80f
|
github.com/cloudnative-pg/machinery v0.0.0-20241001075747-34c8797af80f
|
||||||
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/sourcegraph/conc v0.3.0
|
||||||
|
github.com/spf13/cobra v1.8.1
|
||||||
|
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/apimachinery v0.31.1
|
k8s.io/apimachinery v0.31.1
|
||||||
k8s.io/client-go v0.31.1
|
k8s.io/client-go v0.31.1
|
||||||
sigs.k8s.io/controller-runtime v0.19.0
|
sigs.k8s.io/controller-runtime v0.19.0
|
||||||
@ -75,12 +79,10 @@ require (
|
|||||||
github.com/robfig/cron v1.2.0 // indirect
|
github.com/robfig/cron v1.2.0 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
github.com/snorwin/jsonpatch v1.5.0 // indirect
|
||||||
github.com/spf13/afero v1.11.0 // indirect
|
github.com/spf13/afero v1.11.0 // indirect
|
||||||
github.com/spf13/cast v1.6.0 // indirect
|
github.com/spf13/cast v1.6.0 // indirect
|
||||||
github.com/spf13/cobra v1.8.1 // indirect
|
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/spf13/viper v1.19.0 // indirect
|
|
||||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/thoas/go-funk v0.9.3 // indirect
|
github.com/thoas/go-funk v0.9.3 // indirect
|
||||||
@ -112,7 +114,6 @@ 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/api v0.31.1 // indirect
|
|
||||||
k8s.io/apiextensions-apiserver v0.31.0 // indirect
|
k8s.io/apiextensions-apiserver v0.31.0 // indirect
|
||||||
k8s.io/apiserver v0.31.0 // indirect
|
k8s.io/apiserver v0.31.0 // indirect
|
||||||
k8s.io/component-base v0.31.0 // indirect
|
k8s.io/component-base v0.31.0 // indirect
|
||||||
|
|||||||
4
go.sum
4
go.sum
@ -43,6 +43,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
|
|||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||||
|
github.com/go-faker/faker/v4 v4.4.1 h1:LY1jDgjVkBZWIhATCt+gkl0x9i/7wC61gZx73GTFb+Q=
|
||||||
|
github.com/go-faker/faker/v4 v4.4.1/go.mod h1:HRLrjis+tYsbFtIHufEPTAIzcZiRu0rS9EYl2Ccwme4=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
@ -155,6 +157,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke
|
|||||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||||
|
github.com/snorwin/jsonpatch v1.5.0 h1:0m56YSt9cHiJOn8U+OcqdPGcDQZmhPM/zsG7Dv5QQP0=
|
||||||
|
github.com/snorwin/jsonpatch v1.5.0/go.mod h1:e0IDKlyFBLTFPqM0wa79dnMwjMs3XFvmKcrgCRpDqok=
|
||||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||||
|
|||||||
@ -8,6 +8,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/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IdentityImplementation implements IdentityServer
|
// IdentityImplementation implements IdentityServer
|
||||||
@ -22,7 +23,7 @@ func (i IdentityImplementation) GetPluginMetadata(
|
|||||||
_ context.Context,
|
_ context.Context,
|
||||||
_ *identity.GetPluginMetadataRequest,
|
_ *identity.GetPluginMetadataRequest,
|
||||||
) (*identity.GetPluginMetadataResponse, error) {
|
) (*identity.GetPluginMetadataResponse, error) {
|
||||||
return &Data, nil
|
return &metadata.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPluginCapabilities implements IdentityServer
|
// GetPluginCapabilities implements IdentityServer
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package instance
|
package metadata
|
||||||
|
|
||||||
import "github.com/cloudnative-pg/cnpg-i/pkg/identity"
|
import "github.com/cloudnative-pg/cnpg-i/pkg/identity"
|
||||||
|
|
||||||
3
internal/cnpgi/metadata/doc.go
Normal file
3
internal/cnpgi/metadata/doc.go
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Package metadata contains the common metadata on the operator
|
||||||
|
// and on the instance manager
|
||||||
|
package metadata
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package operator
|
|
||||||
|
|
||||||
import "github.com/cloudnative-pg/cnpg-i/pkg/identity"
|
|
||||||
|
|
||||||
// PluginName is the name of this plugin
|
|
||||||
const PluginName = "operator.barman-cloud.cloudnative-pg.io"
|
|
||||||
|
|
||||||
// Data is the metadata of this plugin.
|
|
||||||
var Data = identity.GetPluginMetadataResponse{
|
|
||||||
Name: PluginName,
|
|
||||||
Version: "0.0.1",
|
|
||||||
DisplayName: "BarmanCloudOperator",
|
|
||||||
ProjectUrl: "https://github.com/cloudnative-pg/plugin-barman-cloud",
|
|
||||||
RepositoryUrl: "https://github.com/cloudnative-pg/plugin-barman-cloud",
|
|
||||||
License: "APACHE 2.0",
|
|
||||||
LicenseUrl: "https://github.com/cloudnative-pg/plugin-barman-cloud/LICENSE",
|
|
||||||
Maturity: "alpha",
|
|
||||||
}
|
|
||||||
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/cloudnative-pg/cnpg-i/pkg/identity"
|
"github.com/cloudnative-pg/cnpg-i/pkg/identity"
|
||||||
|
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IdentityImplementation is the implementation of the CNPG-i
|
// IdentityImplementation is the implementation of the CNPG-i
|
||||||
@ -17,7 +19,7 @@ func (i IdentityImplementation) GetPluginMetadata(
|
|||||||
_ context.Context,
|
_ context.Context,
|
||||||
_ *identity.GetPluginMetadataRequest,
|
_ *identity.GetPluginMetadataRequest,
|
||||||
) (*identity.GetPluginMetadataResponse, error) {
|
) (*identity.GetPluginMetadataResponse, error) {
|
||||||
return &Data, nil
|
return &metadata.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPluginCapabilities implements identity
|
// GetPluginCapabilities implements identity
|
||||||
|
|||||||
79
internal/cnpgi/operator/lifecycle.go
Normal file
79
internal/cnpgi/operator/lifecycle.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package operator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/decoder"
|
||||||
|
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/object"
|
||||||
|
"github.com/cloudnative-pg/cnpg-i/pkg/lifecycle"
|
||||||
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LifecycleImplementation is the implementation of the lifecycle handler
|
||||||
|
type LifecycleImplementation struct {
|
||||||
|
lifecycle.UnimplementedOperatorLifecycleServer
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCapabilities exposes the lifecycle capabilities
|
||||||
|
func (impl LifecycleImplementation) GetCapabilities(
|
||||||
|
_ context.Context,
|
||||||
|
_ *lifecycle.OperatorLifecycleCapabilitiesRequest,
|
||||||
|
) (*lifecycle.OperatorLifecycleCapabilitiesResponse, error) {
|
||||||
|
return &lifecycle.OperatorLifecycleCapabilitiesResponse{
|
||||||
|
LifecycleCapabilities: []*lifecycle.OperatorLifecycleCapabilities{
|
||||||
|
{
|
||||||
|
Group: "",
|
||||||
|
Kind: "Pod",
|
||||||
|
OperationTypes: []*lifecycle.OperatorOperationType{
|
||||||
|
{
|
||||||
|
Type: lifecycle.OperatorOperationType_TYPE_CREATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: lifecycle.OperatorOperationType_TYPE_PATCH,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LifecycleHook is called when creating Kubernetes services
|
||||||
|
func (impl LifecycleImplementation) LifecycleHook(
|
||||||
|
ctx context.Context,
|
||||||
|
request *lifecycle.OperatorLifecycleRequest,
|
||||||
|
) (*lifecycle.OperatorLifecycleResponse, error) {
|
||||||
|
contextLogger := log.FromContext(ctx).WithName("plugin-barman-cloud-lifecycle")
|
||||||
|
|
||||||
|
operation := request.GetOperationType().GetType().Enum()
|
||||||
|
if operation == nil {
|
||||||
|
return nil, errors.New("no operation set")
|
||||||
|
}
|
||||||
|
|
||||||
|
pod, err := decoder.DecodePodJSON(request.GetObjectDefinition())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mutatedPod := pod.DeepCopy()
|
||||||
|
err = object.InjectPluginSidecar(mutatedPod, &corev1.Container{
|
||||||
|
Name: "plugin-barman-cloud",
|
||||||
|
Image: viper.GetString("sidecar-image"),
|
||||||
|
}, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
patch, err := object.CreatePatch(mutatedPod, pod)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: change to debug
|
||||||
|
contextLogger.Info("generated patch", "content", string(patch))
|
||||||
|
return &lifecycle.OperatorLifecycleResponse{
|
||||||
|
JsonPatch: patch,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@ -1,26 +1,21 @@
|
|||||||
package operator
|
package operator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
|
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
|
||||||
"github.com/cloudnative-pg/cnpg-i/pkg/identity"
|
"github.com/cloudnative-pg/cnpg-i/pkg/lifecycle"
|
||||||
"github.com/cloudnative-pg/cnpg-i/pkg/reconciler"
|
"github.com/cloudnative-pg/cnpg-i/pkg/reconciler"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CNPGI is the implementation of the Operator plugin
|
// NewCommand creates the command to start the GRPC server
|
||||||
type CNPGI struct{}
|
// of the operator plugin
|
||||||
|
func NewCommand() *cobra.Command {
|
||||||
// Start starts the GRPC server
|
|
||||||
func (c *CNPGI) Start(ctx context.Context) error {
|
|
||||||
cmd := http.CreateMainCmd(IdentityImplementation{}, func(server *grpc.Server) error {
|
cmd := http.CreateMainCmd(IdentityImplementation{}, func(server *grpc.Server) error {
|
||||||
// Register the declared implementations
|
|
||||||
identity.RegisterIdentityServer(server, IdentityImplementation{})
|
|
||||||
reconciler.RegisterReconcilerHooksServer(server, ReconcilerImplementation{})
|
reconciler.RegisterReconcilerHooksServer(server, ReconcilerImplementation{})
|
||||||
|
lifecycle.RegisterOperatorLifecycleServer(server, LifecycleImplementation{})
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
cmd.Use = "plugin-operator"
|
cmd.Use = "plugin"
|
||||||
|
return cmd
|
||||||
return cmd.ExecuteContext(ctx) //nolint:wrapcheck
|
|
||||||
}
|
}
|
||||||
|
|||||||
161
internal/manager/manager.go
Normal file
161
internal/manager/manager.go
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2024.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package manager contains the implementation of the ObjectStore controller manager
|
||||||
|
package manager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"flag"
|
||||||
|
|
||||||
|
// +kubebuilder:scaffold:imports
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||||
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
|
||||||
|
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||||
|
|
||||||
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/controller"
|
||||||
|
|
||||||
|
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
|
||||||
|
// to ensure that exec-entrypoint and run can make use of them.
|
||||||
|
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
scheme = runtime.NewScheme()
|
||||||
|
setupLog = ctrl.Log.WithName("setup")
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||||
|
|
||||||
|
utilruntime.Must(barmancloudv1.AddToScheme(scheme))
|
||||||
|
// +kubebuilder:scaffold:scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start starts the manager
|
||||||
|
func Start(ctx context.Context) error {
|
||||||
|
var tlsOpts []func(*tls.Config)
|
||||||
|
|
||||||
|
opts := zap.Options{
|
||||||
|
Development: true,
|
||||||
|
}
|
||||||
|
opts.BindFlags(flag.CommandLine)
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
|
||||||
|
|
||||||
|
// if the enable-http2 flag is false (the default), http/2 should be disabled
|
||||||
|
// due to its vulnerabilities. More specifically, disabling http/2 will
|
||||||
|
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
|
||||||
|
// Rapid Reset CVEs. For more information see:
|
||||||
|
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
|
||||||
|
// - https://github.com/advisories/GHSA-4374-p667-p6c8
|
||||||
|
disableHTTP2 := func(c *tls.Config) {
|
||||||
|
setupLog.Info("disabling http/2")
|
||||||
|
c.NextProtos = []string{"http/1.1"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !viper.GetBool("enable-http2") {
|
||||||
|
tlsOpts = append(tlsOpts, disableHTTP2)
|
||||||
|
}
|
||||||
|
|
||||||
|
webhookServer := webhook.NewServer(webhook.Options{
|
||||||
|
TLSOpts: tlsOpts,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
|
||||||
|
// More info:
|
||||||
|
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/server
|
||||||
|
// - https://book.kubebuilder.io/reference/metrics.html
|
||||||
|
metricsServerOptions := metricsserver.Options{
|
||||||
|
BindAddress: viper.GetString("metrics-bind-address"),
|
||||||
|
SecureServing: viper.GetBool("metrics-secure"),
|
||||||
|
// TODO(user): TLSOpts is used to allow configuring the TLS config used for the server. If certificates are
|
||||||
|
// not provided, self-signed certificates will be generated by default. This option is not recommended for
|
||||||
|
// production environments as self-signed certificates do not offer the same level of trust and security
|
||||||
|
// as certificates issued by a trusted Certificate Authority (CA). The primary risk is potentially allowing
|
||||||
|
// unauthorized access to sensitive metrics data. Consider replacing with CertDir, CertName, and KeyName
|
||||||
|
// to provide certificates, ensuring the server communicates using trusted and secure certificates.
|
||||||
|
TLSOpts: tlsOpts,
|
||||||
|
}
|
||||||
|
|
||||||
|
if viper.GetBool("metrics-secure") {
|
||||||
|
// FilterProvider is used to protect the metrics endpoint with authn/authz.
|
||||||
|
// These configurations ensure that only authorized users and service accounts
|
||||||
|
// can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
|
||||||
|
// https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/filters#WithAuthenticationAndAuthorization
|
||||||
|
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
||||||
|
Scheme: scheme,
|
||||||
|
Metrics: metricsServerOptions,
|
||||||
|
WebhookServer: webhookServer,
|
||||||
|
HealthProbeBindAddress: viper.GetString("health-probe-bind-address"),
|
||||||
|
LeaderElection: viper.GetBool("leader-elect"),
|
||||||
|
LeaderElectionID: "822e3f5c.cnpg.io",
|
||||||
|
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
|
||||||
|
// when the Manager ends. This requires the binary to immediately end when the
|
||||||
|
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
|
||||||
|
// speeds up voluntary leader transitions as the new leader don't have to wait
|
||||||
|
// LeaseDuration time first.
|
||||||
|
//
|
||||||
|
// In the default scaffold provided, the program ends immediately after
|
||||||
|
// the manager stops, so would be fine to enable this option. However,
|
||||||
|
// if you are doing or is intended to do any operation such as perform cleanups
|
||||||
|
// after the manager stops then its usage might be unsafe.
|
||||||
|
// LeaderElectionReleaseOnCancel: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
setupLog.Error(err, "unable to start manager")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = (&controller.ObjectStoreReconciler{
|
||||||
|
Client: mgr.GetClient(),
|
||||||
|
Scheme: mgr.GetScheme(),
|
||||||
|
}).SetupWithManager(mgr); err != nil {
|
||||||
|
setupLog.Error(err, "unable to create controller", "controller", "ObjectStore")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// +kubebuilder:scaffold:builder
|
||||||
|
|
||||||
|
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||||
|
setupLog.Error(err, "unable to set up health check")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
|
||||||
|
setupLog.Error(err, "unable to set up ready check")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
setupLog.Info("starting manager")
|
||||||
|
if err := mgr.Start(ctx); err != nil {
|
||||||
|
setupLog.Error(err, "problem running manager")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
6
kubernetes/certificate-issuer.yaml
Normal file
6
kubernetes/certificate-issuer.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Issuer
|
||||||
|
metadata:
|
||||||
|
name: selfsigned-issuer
|
||||||
|
spec:
|
||||||
|
selfSigned: {}
|
||||||
19
kubernetes/client-certificate.yaml
Normal file
19
kubernetes/client-certificate.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: barman-cloud-client
|
||||||
|
spec:
|
||||||
|
secretName: barman-cloud-client-tls
|
||||||
|
|
||||||
|
commonName: "barman-cloud-client"
|
||||||
|
duration: 2160h # 90d
|
||||||
|
renewBefore: 360h # 15d
|
||||||
|
|
||||||
|
isCA: false
|
||||||
|
usages:
|
||||||
|
- client auth
|
||||||
|
|
||||||
|
issuerRef:
|
||||||
|
name: selfsigned-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
50
kubernetes/deployment.yaml
Normal file
50
kubernetes/deployment.yaml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: barman-cloud
|
||||||
|
name: barman-cloud
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: barman-cloud
|
||||||
|
strategy: {}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: barman-cloud
|
||||||
|
spec:
|
||||||
|
serviceAccountName: plugin-barman-cloud
|
||||||
|
containers:
|
||||||
|
- image: plugin-barman-cloud:latest
|
||||||
|
name: barman-cloud
|
||||||
|
ports:
|
||||||
|
- containerPort: 9090
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: SIDECAR_IMAGE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
key: SIDECAR_IMAGE
|
||||||
|
name: plugin-barman-cloud
|
||||||
|
args:
|
||||||
|
- operator
|
||||||
|
- --server-cert=/server/tls.crt
|
||||||
|
- --server-key=/server/tls.key
|
||||||
|
- --client-cert=/client/tls.crt
|
||||||
|
- --server-address=:9090
|
||||||
|
- --leader-elect
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /server
|
||||||
|
name: server
|
||||||
|
- mountPath: /client
|
||||||
|
name: client
|
||||||
|
resources: {}
|
||||||
|
volumes:
|
||||||
|
- name: server
|
||||||
|
secret:
|
||||||
|
secretName: barman-cloud-server-tls
|
||||||
|
- name: client
|
||||||
|
secret:
|
||||||
|
secretName: barman-cloud-client-tls
|
||||||
17
kubernetes/kustomization.yaml
Normal file
17
kubernetes/kustomization.yaml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: cnpg-system
|
||||||
|
resources:
|
||||||
|
- certificate-issuer.yaml
|
||||||
|
- client-certificate.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- server-certificate.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ../config/crd
|
||||||
|
- ../config/rbac
|
||||||
|
images:
|
||||||
|
- name: plugin-barman-cloud
|
||||||
|
secretGenerator:
|
||||||
|
- literals:
|
||||||
|
- SIDECAR_IMAGE=plugin-sidecar
|
||||||
|
name: plugin-barman-cloud
|
||||||
21
kubernetes/server-certificate.yaml
Normal file
21
kubernetes/server-certificate.yaml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: barman-cloud-server
|
||||||
|
spec:
|
||||||
|
secretName: barman-cloud-server-tls
|
||||||
|
commonName: barman-cloud
|
||||||
|
dnsNames:
|
||||||
|
- barman-cloud
|
||||||
|
|
||||||
|
duration: 2160h # 90d
|
||||||
|
renewBefore: 360h # 15d
|
||||||
|
|
||||||
|
isCA: false
|
||||||
|
usages:
|
||||||
|
- server auth
|
||||||
|
|
||||||
|
issuerRef:
|
||||||
|
name: selfsigned-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
18
kubernetes/service.yaml
Normal file
18
kubernetes/service.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: barman-cloud
|
||||||
|
cnpg.io/pluginName: barman-cloud.cloudnative-pg.io
|
||||||
|
annotations:
|
||||||
|
cnpg.io/pluginClientSecret: barman-cloud-client-tls
|
||||||
|
cnpg.io/pluginServerSecret: barman-cloud-server-tls
|
||||||
|
cnpg.io/pluginPort: "9090"
|
||||||
|
name: barman-cloud
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: 9090
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: 9090
|
||||||
|
selector:
|
||||||
|
app: barman-cloud
|
||||||
22
scripts/run.sh
Executable file
22
scripts/run.sh
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.." || exit
|
||||||
|
|
||||||
|
if [ -f .env ]; then
|
||||||
|
source .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_context=$(kubectl config view --raw -o json | jq -r '."current-context"' | sed "s/kind-//")
|
||||||
|
operator_image=$(KIND_CLUSTER_NAME="$current_context" KO_DOCKER_REPO=kind.local ko build -BP ./cmd/operator)
|
||||||
|
instance_image=$(KIND_CLUSTER_NAME="$current_context" KO_DOCKER_REPO=kind.local ko build -BP ./cmd/instance)
|
||||||
|
|
||||||
|
(
|
||||||
|
cd kubernetes;
|
||||||
|
kustomize edit set image "plugin-barman-cloud=$operator_image"
|
||||||
|
kustomize edit set secret plugin-barman-cloud "--from-literal=SIDECAR_IMAGE=$instance_image"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now we deploy the plugin inside the `cnpg-system` workspace
|
||||||
|
kubectl apply -k kubernetes/
|
||||||
Loading…
Reference in New Issue
Block a user