diff --git a/cmd/authentication-operator/main.go b/cmd/authentication-operator/main.go index 529253026..9b306fae7 100644 --- a/cmd/authentication-operator/main.go +++ b/cmd/authentication-operator/main.go @@ -13,7 +13,6 @@ import ( "k8s.io/component-base/cli" kmshealth "github.com/openshift/library-go/pkg/operator/encryption/kms/health" - kmspreflight "github.com/openshift/library-go/pkg/operator/encryption/kms/preflight" "github.com/openshift/library-go/pkg/operator/v1helpers" ) @@ -47,7 +46,6 @@ func NewAuthenticationOperatorCommand() *cobra.Command { // is implemented in library-go. return nil, nil })) - cmd.AddCommand(kmspreflight.NewCommand(context.Background())) return cmd } diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/helpers.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/helpers.go deleted file mode 100644 index c5031ce2a..000000000 --- a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/helpers.go +++ /dev/null @@ -1,66 +0,0 @@ -package kms - -import ( - "fmt" - - "github.com/openshift/api/features" - "github.com/openshift/library-go/pkg/operator/configobserver/featuregates" - corev1 "k8s.io/api/core/v1" -) - -// AddKMSPluginVolumeAndMountToPodSpec conditionally adds the KMS plugin volume mount to the specified container. -// It assumes the pod spec does not already contain the KMS volume or mount; no deduplication is performed. -// Deprecated: this is a temporary solution to get KMS TP v1 out. We should come up with a different approach afterwards. -func AddKMSPluginVolumeAndMountToPodSpec(podSpec *corev1.PodSpec, containerName string, featureGateAccessor featuregates.FeatureGateAccess) error { - if podSpec == nil { - return fmt.Errorf("pod spec cannot be nil") - } - - if !featureGateAccessor.AreInitialFeatureGatesObserved() { - return nil - } - - featureGates, err := featureGateAccessor.CurrentFeatureGates() - if err != nil { - return fmt.Errorf("failed to get feature gates: %w", err) - } - - if !featureGates.Enabled(features.FeatureGateKMSEncryption) { - return nil - } - - containerIndex := -1 - for i, container := range podSpec.Containers { - if container.Name == containerName { - containerIndex = i - break - } - } - - if containerIndex < 0 { - return fmt.Errorf("container %s not found", containerName) - } - - container := &podSpec.Containers[containerIndex] - container.VolumeMounts = append(container.VolumeMounts, - corev1.VolumeMount{ - Name: "kms-plugin-socket", - MountPath: "/var/run/kmsplugin", - }, - ) - - directoryOrCreate := corev1.HostPathDirectoryOrCreate - podSpec.Volumes = append(podSpec.Volumes, - corev1.Volume{ - Name: "kms-plugin-socket", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: "/var/run/kmsplugin", - Type: &directoryOrCreate, - }, - }, - }, - ) - - return nil -} diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml b/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml deleted file mode 100644 index 84963feca..000000000 --- a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: {{.PodName}} - namespace: {{.Namespace}} -spec: - # This is a one-shot preflight check, not a long-running pod. - # The operator creates it, waits for completion, and inspects the result. - restartPolicy: Never - containers: - - name: kms-preflight-check - image: {{.OperatorImage}} - command: [{{.Command}}] - args: - - --kms-call-timeout={{.KMSCallTimeout}} - # TODO: figure out good resource request values. - resources: - requests: - memory: 50Mi - cpu: 5m diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/bindata.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/bindata.go deleted file mode 100644 index 1ed616068..000000000 --- a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/bindata.go +++ /dev/null @@ -1,16 +0,0 @@ -package preflight - -import ( - "embed" -) - -//go:embed assets/* -var f embed.FS - -func mustAsset(name string) []byte { - data, err := f.ReadFile(name) - if err != nil { - panic(err) - } - return data -} diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/checker.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/checker.go deleted file mode 100644 index 4570218fb..000000000 --- a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/checker.go +++ /dev/null @@ -1,108 +0,0 @@ -package preflight - -import ( - "bytes" - "context" - "crypto/rand" - "fmt" - "io" - "strings" - "time" - - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/klog/v2" - kmsservice "k8s.io/kms/pkg/service" -) - -// healthzOK is the value the KMS plugin returns when healthy. -// See https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/kms/apis/v2/api.proto#L39 -const healthzOK = "ok" - -// checker runs the preflight check against a KMS plugin by calling -// Status, Encrypt, and Decrypt on the kmsservice.Service interface. -// this is the same interface the apiserver uses. -type checker struct { - service kmsservice.Service - randReader io.Reader - statusTimeout time.Duration - statusInterval time.Duration -} - -func newChecker(service kmsservice.Service) *checker { - return &checker{ - service: service, - randReader: rand.Reader, - statusTimeout: 30 * time.Second, - statusInterval: 2 * time.Second, - } -} - -func (c *checker) check(ctx context.Context) error { - if err := c.checkStatus(ctx); err != nil { - return err - } - return c.checkEncryptDecrypt(ctx) -} - -// checkStatus polls the KMS plugin status endpoint until it reports healthy. -// The plugin may not be immediately available after startup, so we retry -// before reporting a failure. -func (c *checker) checkStatus(ctx context.Context) error { - klog.Infof("[1/3] Checking KMS plugin status endpoint (interval %v, timeout %v)", c.statusInterval, c.statusTimeout) - return wait.PollUntilContextTimeout(ctx, c.statusInterval, c.statusTimeout, true, func(ctx context.Context) (bool, error) { - start := time.Now() - resp, err := c.service.Status(ctx) - elapsed := time.Since(start) - if err != nil { - klog.Infof(" not ready: %v, latency=%v", err, elapsed) - return false, nil - } - // we only check healthz here. - // version and keyID validation is the apiserver's responsibility, - // the preflight check just confirms the plugin is reachable and healthy. - if resp.Healthz != healthzOK { - klog.Infof(" not ready: healthz=%q, latency=%v", resp.Healthz, elapsed) - return false, nil - } - klog.Infof(" Status: healthz=%q, version=%q, keyID=%q, latency=%v", resp.Healthz, resp.Version, resp.KeyID, elapsed) - return true, nil - }) -} - -func (c *checker) checkEncryptDecrypt(ctx context.Context) error { - klog.Info("[2/3] Checking KMS plugin encrypt endpoint") - plainText := make([]byte, 32) - if _, err := io.ReadFull(c.randReader, plainText); err != nil { - return fmt.Errorf("failed to generate random plaintext: %w", err) - } - // unique per run, used for tracing - uid := fmt.Sprintf("preflight-check-%x", plainText[:4]) - start := time.Now() - encResp, err := c.service.Encrypt(ctx, uid, plainText) - elapsed := time.Since(start) - if err != nil { - return fmt.Errorf("encrypt call failed, latency=%v: %w", elapsed, err) - } - if bytes.Equal(encResp.Ciphertext, plainText) { - return fmt.Errorf("encrypt returned plaintext unchanged, expected encrypted data") - } - var annotations []string - for k, v := range encResp.Annotations { - annotations = append(annotations, fmt.Sprintf("%s=%q", k, v)) - } - klog.Infof(" Encrypt: keyID=%q, ciphertext=%d bytes, annotations=[%s], latency=%v", encResp.KeyID, len(encResp.Ciphertext), strings.Join(annotations, ", "), elapsed) - - klog.Info("[3/3] Checking KMS plugin decrypt endpoint") - decryptReq := &kmsservice.DecryptRequest{Ciphertext: encResp.Ciphertext, KeyID: encResp.KeyID, Annotations: encResp.Annotations} - start = time.Now() - decrypted, err := c.service.Decrypt(ctx, uid, decryptReq) - elapsed = time.Since(start) - if err != nil { - return fmt.Errorf("decrypt call failed, latency=%v: %w", elapsed, err) - } - if !bytes.Equal(decrypted, plainText) { - return fmt.Errorf("decrypt roundtrip mismatch: got %q, want %q", decrypted, plainText) - } - klog.Infof(" Decrypt: plaintext=%d bytes, latency=%v", len(decrypted), elapsed) - return nil -} diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/cmd.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/cmd.go deleted file mode 100644 index f64390e6d..000000000 --- a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/cmd.go +++ /dev/null @@ -1,69 +0,0 @@ -package preflight - -import ( - "context" - "fmt" - "time" - - "github.com/spf13/cobra" - "github.com/spf13/pflag" - - k8senvelopekmsv2 "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2" - "k8s.io/klog/v2" -) - -const kmsSocketEndpoint = "unix:///var/run/kmsplugin/kms.sock" - -type options struct { - kmsCallTimeout time.Duration -} - -// NewCommand creates the kms-preflight cobra command. -func NewCommand(ctx context.Context) *cobra.Command { - o := &options{} - - cmd := &cobra.Command{ - Use: "kms-preflight", - Short: "Validates that the configured KMS plugin is functional.", - RunE: func(cmd *cobra.Command, args []string) error { - if err := o.validate(); err != nil { - return err - } - return o.run(ctx) - }, - } - - o.addFlags(cmd.Flags()) - return cmd -} - -func (o *options) addFlags(fs *pflag.FlagSet) { - fs.DurationVar(&o.kmsCallTimeout, "kms-call-timeout", 0, "timeout for each gRPC call to the KMS plugin") -} - -func (o *options) validate() error { - if o.kmsCallTimeout <= 0 { - return fmt.Errorf("--kms-call-timeout must be greater than 0") - } - return nil -} - -func (o *options) run(ctx context.Context) error { - klog.Infof("Running KMS preflight check at %s", kmsSocketEndpoint) - - // k8senvelopekmsv2.NewGRPCService is not a public API and may change. - // If it breaks, we can inline a minimal gRPC client using k8s.io/kms directly. - service, err := k8senvelopekmsv2.NewGRPCService(ctx, kmsSocketEndpoint, "preflight", o.kmsCallTimeout) - if err != nil { - return fmt.Errorf("failed to create KMS gRPC client: %w", err) - } - - checker := newChecker(service) - start := time.Now() - if err = checker.check(ctx); err != nil { - return fmt.Errorf("kms preflight check failed: %w", err) - } - - klog.Infof("KMS preflight check passed, total latency=%v", time.Since(start)) - return nil -} diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/pod_template.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/pod_template.go deleted file mode 100644 index 8554bf14d..000000000 --- a/vendor/github.com/openshift/library-go/pkg/operator/encryption/kms/preflight/pod_template.go +++ /dev/null @@ -1,62 +0,0 @@ -package preflight - -import ( - "bytes" - "fmt" - "strings" - "text/template" - "time" - - corev1 "k8s.io/api/core/v1" - - "github.com/openshift/library-go/pkg/operator/configobserver/featuregates" - encryptionkms "github.com/openshift/library-go/pkg/operator/encryption/kms" - "github.com/openshift/library-go/pkg/operator/resource/resourceread" -) - -type kmsPreflightTemplate struct { - PodName string - Namespace string - OperatorImage string - Command string - KMSCallTimeout string -} - -// GeneratePodTemplate renders the KMS preflight pod YAML template. -// The pod has a single container that connects to the KMS plugin via -// a hostPath-mounted unix socket at /var/run/kmsplugin. -// The KMS plugin volume and mount are added via AddKMSPluginVolumeAndMountToPodSpec. -func GeneratePodTemplate(namespace string, podName string, operatorImage string, operatorCommand []string, kmsCallTimeout time.Duration, featureGateAccessor featuregates.FeatureGateAccess) (*corev1.Pod, error) { - rawManifest := mustAsset("assets/kms-preflight-pod.yaml") - - operatorCommandQuoted := make([]string, len(operatorCommand)) - for i, cmd := range operatorCommand { - operatorCommandQuoted[i] = fmt.Sprintf("%q", cmd) - } - - tmplVal := kmsPreflightTemplate{ - PodName: podName, - Namespace: namespace, - OperatorImage: operatorImage, - Command: strings.Join(operatorCommandQuoted, ","), - KMSCallTimeout: kmsCallTimeout.String(), - } - tmpl, err := template.New("kms-preflight").Parse(string(rawManifest)) - if err != nil { - return nil, err - } - var buf bytes.Buffer - if err = tmpl.Execute(&buf, tmplVal); err != nil { - return nil, err - } - - pod, err := resourceread.ReadPodV1(buf.Bytes()) - if err != nil { - return nil, fmt.Errorf("failed to parse rendered pod template: %w", err) - } - // TODO: once the KMS plugin lifecycle code is present, reuse it instead of AddKMSPluginVolumeAndMountToPodSpec. - if err = encryptionkms.AddKMSPluginVolumeAndMountToPodSpec(&pod.Spec, "kms-preflight-check", featureGateAccessor); err != nil { - return nil, fmt.Errorf("failed to add KMS plugin volume: %w", err) - } - return pod, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 31c04a64a..6beb9f6b3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -428,10 +428,8 @@ github.com/openshift/library-go/pkg/operator/encryption/crypto github.com/openshift/library-go/pkg/operator/encryption/deployer github.com/openshift/library-go/pkg/operator/encryption/encoding github.com/openshift/library-go/pkg/operator/encryption/encryptiondata -github.com/openshift/library-go/pkg/operator/encryption/kms github.com/openshift/library-go/pkg/operator/encryption/kms/health github.com/openshift/library-go/pkg/operator/encryption/kms/pluginlifecycle -github.com/openshift/library-go/pkg/operator/encryption/kms/preflight github.com/openshift/library-go/pkg/operator/encryption/observer github.com/openshift/library-go/pkg/operator/encryption/secrets github.com/openshift/library-go/pkg/operator/encryption/state