Skip to content

added secret resolver for handling annotations directly on secrets#30

Open
danieldonoghue wants to merge 2 commits intomasterfrom
29-use-annotated-secrets
Open

added secret resolver for handling annotations directly on secrets#30
danieldonoghue wants to merge 2 commits intomasterfrom
29-use-annotated-secrets

Conversation

@danieldonoghue
Copy link
Owner

No description provided.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for handling annotations directly on Secret resources, expanding the operator's capability beyond deployment-based synchronization. The changes enable secrets to be synced to Vault using annotations on the Secret objects themselves.

  • Adds a new SecretReconciler controller to handle Secret resources with vault-sync annotations
  • Extracts common synchronization logic into shared functions to avoid code duplication
  • Updates metric labels from "deployment" to "resource" to accommodate both deployment and secret sync operations

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
internal/metrics/metrics.go Updated metric labels from "deployment" to "resource" to support both deployment and secret sync
internal/controller/sync_common.go New shared sync functionality for both deployment and secret controllers
internal/controller/secret_controller_test.go Comprehensive test suite for the SecretReconciler
internal/controller/secret_controller.go New SecretReconciler implementation for handling Secret resources
internal/controller/deployment_controller.go Added comment clarifying this file implements DeploymentReconciler
examples/secret-level-sync-example.yaml Example configurations for direct secret synchronization
examples/README.md Updated documentation to include secret-level sync examples
docs/PROJECT_SUMMARY.md Updated project documentation to reflect dual sync modes
config/rbac/role.yaml Updated RBAC permissions to support secret management
cmd/main.go Registered the new SecretReconciler controller
README.md Enhanced documentation with secret sync usage examples

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Type string // "deployment" or "secret"
}

// Note: SecretConfig is defined in deployment_controller.go to avoid duplication
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment references SecretConfig being defined in deployment_controller.go, but this creates a dependency that should be documented or the type should be defined in this shared file instead.

Suggested change
// Note: SecretConfig is defined in deployment_controller.go to avoid duplication
// SecretConfig defines the structure for custom secret configuration.
type SecretConfig struct {
Name string `json:"name"`
Keys []string `json:"keys"`
Prefix string `json:"prefix,omitempty"`
}

Copilot uses AI. Check for mistakes.
return changed
}

// Note: getSecretKeys is defined in deployment_controller.go to avoid duplication
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment indicates getSecretKeys is defined elsewhere to avoid duplication, but since this is shared functionality, it should be defined in this common file or the dependency should be clearly documented.

Suggested change
// Note: getSecretKeys is defined in deployment_controller.go to avoid duplication
// getSecretKeys returns the keys of the provided Kubernetes Secret.
func getSecretKeys(secret *corev1.Secret) []string {
keys := make([]string, 0, len(secret.Data))
for k := range secret.Data {
keys = append(keys, k)
}
return keys
}

Copilot uses AI. Check for mistakes.

// getLastKnownSecretVersions retrieves the last known secret versions from secret annotations.
func (r *SecretReconciler) getLastKnownSecretVersions(secret *corev1.Secret) map[string]string {
versionsAnnotation, exists := secret.Annotations[VaultSecretVersionsAnnotation]
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constant VaultSecretVersionsAnnotation is used but not defined in this file. It should be imported from a constants file or defined locally to improve maintainability.

Copilot uses AI. Check for mistakes.
}

// Check if vault-sync is enabled for this secret (presence of vault path annotation)
vaultPath, vaultSyncEnabled := secret.Annotations[VaultPathAnnotation]
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple annotation constants (VaultPathAnnotation, VaultSyncFinalizer, etc.) are used throughout the file but not defined here. These should be imported from a constants file or defined locally to improve code maintainability and reduce coupling.

Copilot uses AI. Check for mistakes.
vaultPath, vaultSyncEnabled := secret.Annotations[VaultPathAnnotation]
if !vaultSyncEnabled || vaultPath == "" {
// Remove finalizer if it exists but sync is disabled
if controllerutil.ContainsFinalizer(secret, VaultSyncFinalizer) {
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple annotation constants (VaultPathAnnotation, VaultSyncFinalizer, etc.) are used throughout the file but not defined here. These should be imported from a constants file or defined locally to improve code maintainability and reduce coupling.

Copilot uses AI. Check for mistakes.
preserveOnDelete := secret.Annotations[VaultPreserveOnDeleteAnnotation] == "true"

// Get the vault path
vaultPath, exists := secret.Annotations[VaultPathAnnotation]
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple annotation constants (VaultPathAnnotation, VaultSyncFinalizer, etc.) are used throughout the file but not defined here. These should be imported from a constants file or defined locally to improve code maintainability and reduce coupling.

Copilot uses AI. Check for mistakes.
}

// Check if custom secrets configuration is provided
secretsToSync, hasCustomConfig := secret.Annotations[VaultSecretsAnnotation]
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple annotation constants (VaultPathAnnotation, VaultSyncFinalizer, etc.) are used throughout the file but not defined here. These should be imported from a constants file or defined locally to improve code maintainability and reduce coupling.

Copilot uses AI. Check for mistakes.

// getLastKnownSecretVersions retrieves the last known secret versions from secret annotations.
func (r *SecretReconciler) getLastKnownSecretVersions(secret *corev1.Secret) map[string]string {
versionsAnnotation, exists := secret.Annotations[VaultSecretVersionsAnnotation]
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple annotation constants (VaultPathAnnotation, VaultSyncFinalizer, etc.) are used throughout the file but not defined here. These should be imported from a constants file or defined locally to improve code maintainability and reduce coupling.

Copilot uses AI. Check for mistakes.

// isRotationCheckDisabled checks if secret rotation detection is disabled for this secret.
func (r *SecretReconciler) isRotationCheckDisabled(secret *corev1.Secret) bool {
rotationCheck, exists := secret.Annotations[VaultRotationCheckAnnotation]
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple annotation constants (VaultPathAnnotation, VaultSyncFinalizer, etc.) are used throughout the file but not defined here. These should be imported from a constants file or defined locally to improve code maintainability and reduce coupling.

Copilot uses AI. Check for mistakes.
// getReconcileInterval parses the reconciliation interval from the vault-sync.io/reconcile annotation.
// Returns the duration if valid, or zero duration if disabled or invalid.
func (r *SecretReconciler) getReconcileInterval(secret *corev1.Secret) time.Duration {
reconcileValue, exists := secret.Annotations[VaultReconcileAnnotation]
Copy link

Copilot AI Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple annotation constants (VaultPathAnnotation, VaultSyncFinalizer, etc.) are used throughout the file but not defined here. These should be imported from a constants file or defined locally to improve code maintainability and reduce coupling.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TODO: allow the operator to work directly on deployed secrets

2 participants