mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-21 23:18:06 +00:00
Upgrade to Operator SDK 1.41.1 (#211)
* Add missing improvements from Operator SDK 1.34.1 These were not mentioned in the upgrade documentation for version 1.34.x (https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.34.0/), but I've found them by compating the release with the previous one (https://github.com/operator-framework/operator-sdk/compare/v1.33.0...v1.34.1). * Upgrade to Operator SDK 1.36.0 Source of upgrade steps: https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.36.0/ Key differences: - Go packages `k8s.io/*` are already at a version higher than the one in the upgrade. - `ENVTEST_K8S_VERSION` is at a version higher than the one in the upgrade - We didn't have the golangci-lint make command before, thus we only needed to add things. * Upgrade to Operator SDK 1.38.0 Source of upgrade steps: https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.38.0/ * Upgrade to Operator SDK 1.39.0 Source of upgrade steps: https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.39.0/ * Upgrade to Operator SDK 1.40.0 Source of upgrade steps: https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.40.0/ I didn't do the "Add app.kubernetes.io/name label to your manifests" since it seems that we have it already, and it's customized. * Address lint errors * Update golangci-lint version used to support Go 1.24 * Improve workflows - Make workflow targets more specific. - Make build workflow only build (i.e. remove test part of it). - Rearrange steps and improve naming for build workflow. * Add back deleted test Initially the test has been removed due to lint saying that it was duplicate code, but it falsely errored since the values are different. * Improve code and add missing upgrade pieces * Upgrade to Operator SDK 1.41.1 Source of upgrade steps: https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.41.0/ Upgrading to 1.41.1 from 1.40.0 doesn't have any migration steps. Key elements: - Upgrade to golangci-lint v2 - Made the manifests using the updated controller tools * Address linter errors golanci-lint v2 seems to be more robust than the previous one, which is beneficial. Thus, we address the linter errors thrown by v2 and improve our code even further. * Add Makefile improvements These were brought in by comparing the Makefile of a freshly created operator using the latest operator-sdk with ours. * Add missing default kustomization for 1.40.0 upgrade * Bring default kustomization to latest version This is done by putting the file's content from a newly-generated operator. * Switch metrics-bind-address default value back to 8080 This ensures that the upgrade is backwards-compatible. * Add webhook-related scaffolding This enables us to easily add support for webhooks by running `operator-sdk create webhook` whenever we want to add them. * Fix typo
This commit is contained in:
161
cmd/main.go
161
cmd/main.go
@@ -26,10 +26,12 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@@ -46,9 +48,12 @@ import (
|
||||
"k8s.io/client-go/rest"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
|
||||
"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"
|
||||
|
||||
onepasswordcomv1 "github.com/1Password/onepassword-operator/api/v1"
|
||||
"github.com/1Password/onepassword-operator/internal/controller"
|
||||
@@ -56,7 +61,7 @@ import (
|
||||
opclient "github.com/1Password/onepassword-operator/pkg/onepassword/client"
|
||||
"github.com/1Password/onepassword-operator/pkg/utils"
|
||||
"github.com/1Password/onepassword-operator/version"
|
||||
//+kubebuilder:scaffold:imports
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -73,13 +78,6 @@ const (
|
||||
annotationRegExpString = "^operator.1password.io\\/[a-zA-Z\\.]+"
|
||||
)
|
||||
|
||||
// Change below variables to serve metrics on different host or port.
|
||||
var (
|
||||
metricsHost = "0.0.0.0"
|
||||
metricsPort int32 = 8383
|
||||
operatorMetricsPort int32 = 8686
|
||||
)
|
||||
|
||||
func printVersion() {
|
||||
setupLog.Info(fmt.Sprintf("Operator Version: %s", version.OperatorVersion))
|
||||
setupLog.Info(fmt.Sprintf("Go Version: %s", runtime.Version()))
|
||||
@@ -91,18 +89,36 @@ func init() {
|
||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||
|
||||
utilruntime.Must(onepasswordcomv1.AddToScheme(scheme))
|
||||
//+kubebuilder:scaffold:scheme
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
func main() {
|
||||
var metricsAddr string
|
||||
var metricsCertPath, metricsCertName, metricsCertKey string
|
||||
var webhookCertPath, webhookCertName, webhookCertKey string
|
||||
var enableLeaderElection bool
|
||||
var probeAddr string
|
||||
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
|
||||
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
|
||||
var secureMetrics bool
|
||||
var enableHTTP2 bool
|
||||
var tlsOpts []func(*tls.Config)
|
||||
flag.StringVar(&metricsAddr, "metrics-bind-address", "8080",
|
||||
"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.StringVar(&metricsCertPath, "metrics-cert-path", "",
|
||||
"The directory that contains the metrics server certificate.")
|
||||
flag.StringVar(&metricsCertName, "metrics-cert-name", "tls.crt",
|
||||
"The name of the metrics server certificate file.")
|
||||
flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key",
|
||||
"The name of the metrics server key file.")
|
||||
flag.BoolVar(&enableHTTP2, "enable-http2", false,
|
||||
"If set, HTTP/2 will be enabled for the metrics")
|
||||
opts := zap.Options{
|
||||
Development: true,
|
||||
}
|
||||
@@ -111,6 +127,21 @@ func main() {
|
||||
|
||||
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 Cancelation 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 !enableHTTP2 {
|
||||
tlsOpts = append(tlsOpts, disableHTTP2)
|
||||
}
|
||||
|
||||
printVersion()
|
||||
|
||||
// Create a root context that will be cancelled on termination signals
|
||||
@@ -128,12 +159,104 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create watchers for metrics and webhooks certificates
|
||||
var metricsCertWatcher, webhookCertWatcher *certwatcher.CertWatcher
|
||||
|
||||
// Initial webhook TLS options
|
||||
webhookTLSOpts := tlsOpts
|
||||
|
||||
if len(webhookCertPath) > 0 {
|
||||
setupLog.Info("Initializing webhook certificate watcher using provided certificates",
|
||||
"webhook-cert-path", webhookCertPath, "webhook-cert-name", webhookCertName, "webhook-cert-key", webhookCertKey)
|
||||
|
||||
var err error
|
||||
webhookCertWatcher, err = certwatcher.New(
|
||||
filepath.Join(webhookCertPath, webhookCertName),
|
||||
filepath.Join(webhookCertPath, webhookCertKey),
|
||||
)
|
||||
if err != nil {
|
||||
setupLog.Error(err, "Failed to initialize webhook certificate watcher")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
webhookTLSOpts = append(webhookTLSOpts, func(config *tls.Config) {
|
||||
config.GetCertificate = webhookCertWatcher.GetCertificate
|
||||
})
|
||||
}
|
||||
|
||||
webhookServer := webhook.NewServer(webhook.Options{
|
||||
TLSOpts: webhookTLSOpts,
|
||||
})
|
||||
|
||||
// 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.21.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
|
||||
}
|
||||
|
||||
// If the certificate is not specified, controller-runtime will automatically
|
||||
// generate self-signed certificates for the metrics server. While convenient for development and testing,
|
||||
// this setup is not recommended for production.
|
||||
//
|
||||
// TODO(user): If you enable certManager, uncomment the following lines:
|
||||
// - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates
|
||||
// managed by cert-manager for the metrics server.
|
||||
// - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification.
|
||||
if len(metricsCertPath) > 0 {
|
||||
setupLog.Info("Initializing metrics certificate watcher using provided certificates",
|
||||
"metrics-cert-path", metricsCertPath, "metrics-cert-name", metricsCertName, "metrics-cert-key", metricsCertKey)
|
||||
|
||||
var err error
|
||||
metricsCertWatcher, err = certwatcher.New(
|
||||
filepath.Join(metricsCertPath, metricsCertName),
|
||||
filepath.Join(metricsCertPath, metricsCertKey),
|
||||
)
|
||||
if err != nil {
|
||||
setupLog.Error(err, "Failed to initialize metrics certificate watcher")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
metricsServerOptions.TLSOpts = append(metricsServerOptions.TLSOpts, func(config *tls.Config) {
|
||||
config.GetCertificate = metricsCertWatcher.GetCertificate
|
||||
})
|
||||
}
|
||||
|
||||
options := ctrl.Options{
|
||||
Scheme: scheme,
|
||||
Metrics: metricsserver.Options{BindAddress: metricsAddr},
|
||||
Metrics: metricsServerOptions,
|
||||
WebhookServer: webhookServer,
|
||||
HealthProbeBindAddress: probeAddr,
|
||||
LeaderElection: enableLeaderElection,
|
||||
LeaderElectionID: "c26807fd.onepassword.com",
|
||||
// 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,
|
||||
}
|
||||
|
||||
// Add support for MultiNamespace set in WATCH_NAMESPACE (e.g ns1,ns2)
|
||||
@@ -184,14 +307,14 @@ func main() {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Deployment")
|
||||
os.Exit(1)
|
||||
}
|
||||
//+kubebuilder:scaffold:builder
|
||||
// +kubebuilder:scaffold:builder
|
||||
|
||||
//Setup 1PasswordConnect
|
||||
// Setup 1PasswordConnect
|
||||
if shouldManageConnect() {
|
||||
setupLog.Info("Automated Connect Management Enabled")
|
||||
go func(ctx context.Context) {
|
||||
connectStarted := false
|
||||
for connectStarted == false {
|
||||
for !connectStarted {
|
||||
err := op.SetupConnect(ctx, mgr.GetClient(), deploymentNamespace)
|
||||
// Cache Not Started is an acceptable error. Retry until cache is started.
|
||||
if err != nil && !errors.Is(err, &cache.ErrCacheNotStarted{}) {
|
||||
@@ -226,6 +349,14 @@ func main() {
|
||||
}
|
||||
}(ctx)
|
||||
|
||||
if metricsCertWatcher != nil {
|
||||
setupLog.Info("Adding metrics certificate watcher to manager")
|
||||
if err := mgr.Add(metricsCertWatcher); err != nil {
|
||||
setupLog.Error(err, "Unable to add metrics certificate watcher to manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||
setupLog.Error(err, "unable to set up health check")
|
||||
os.Exit(1)
|
||||
|
Reference in New Issue
Block a user