mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-22 15:38:06 +00:00
Add owner reference to the created secrets
Signed-off-by: Xabier Larrakoetxea <me@slok.dev>
This commit is contained in:
@@ -14,9 +14,11 @@ import (
|
|||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
@@ -114,7 +116,7 @@ func (r *ReconcileDeployment) Reconcile(request reconcile.Request) (reconcile.Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handles creation or updating secrets for deployment if needed
|
// Handles creation or updating secrets for deployment if needed
|
||||||
if err := r.HandleApplyingDeployment(deployment.Namespace, annotations, request); err != nil {
|
if err := r.HandleApplyingDeployment(deployment, deployment.Namespace, annotations, request); err != nil {
|
||||||
return reconcile.Result{}, err
|
return reconcile.Result{}, err
|
||||||
}
|
}
|
||||||
return reconcile.Result{}, nil
|
return reconcile.Result{}, nil
|
||||||
@@ -187,7 +189,7 @@ func (r *ReconcileDeployment) removeOnePasswordFinalizerFromDeployment(deploymen
|
|||||||
return r.kubeClient.Update(context.Background(), deployment)
|
return r.kubeClient.Update(context.Background(), deployment)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReconcileDeployment) HandleApplyingDeployment(namespace string, annotations map[string]string, request reconcile.Request) error {
|
func (r *ReconcileDeployment) HandleApplyingDeployment(deployment *appsv1.Deployment, namespace string, annotations map[string]string, request reconcile.Request) error {
|
||||||
reqLog := log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name)
|
reqLog := log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name)
|
||||||
|
|
||||||
secretName := annotations[op.NameAnnotation]
|
secretName := annotations[op.NameAnnotation]
|
||||||
@@ -204,5 +206,17 @@ func (r *ReconcileDeployment) HandleApplyingDeployment(namespace string, annotat
|
|||||||
return fmt.Errorf("Failed to retrieve item: %v", err)
|
return fmt.Errorf("Failed to retrieve item: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return kubeSecrets.CreateKubernetesSecretFromItem(r.kubeClient, secretName, namespace, item, annotations[op.RestartDeploymentsAnnotation], secretLabels, secretType, annotations)
|
// Create owner reference.
|
||||||
|
gvk, err := apiutil.GVKForObject(deployment, r.scheme)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not to retrieve group version kind: %v", err)
|
||||||
|
}
|
||||||
|
ownerRef := &metav1.OwnerReference{
|
||||||
|
APIVersion: gvk.GroupVersion().String(),
|
||||||
|
Kind: gvk.Kind,
|
||||||
|
Name: deployment.GetName(),
|
||||||
|
UID: deployment.GetUID(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return kubeSecrets.CreateKubernetesSecretFromItem(r.kubeClient, secretName, namespace, item, annotations[op.RestartDeploymentsAnnotation], secretLabels, secretType, annotations, ownerRef)
|
||||||
}
|
}
|
||||||
|
@@ -14,9 +14,11 @@ import (
|
|||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
kubeClient "sigs.k8s.io/controller-runtime/pkg/client"
|
kubeClient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
@@ -154,5 +156,17 @@ func (r *ReconcileOnePasswordItem) HandleOnePasswordItem(resource *onepasswordv1
|
|||||||
return fmt.Errorf("Failed to retrieve item: %v", err)
|
return fmt.Errorf("Failed to retrieve item: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return kubeSecrets.CreateKubernetesSecretFromItem(r.kubeClient, secretName, resource.Namespace, item, autoRestart, labels, secretType, annotations)
|
// Create owner reference.
|
||||||
|
gvk, err := apiutil.GVKForObject(resource, r.scheme)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not to retrieve group version kind: %v", err)
|
||||||
|
}
|
||||||
|
ownerRef := &metav1.OwnerReference{
|
||||||
|
APIVersion: gvk.GroupVersion().String(),
|
||||||
|
Kind: gvk.Kind,
|
||||||
|
Name: resource.GetName(),
|
||||||
|
UID: resource.GetUID(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return kubeSecrets.CreateKubernetesSecretFromItem(r.kubeClient, secretName, resource.Namespace, item, autoRestart, labels, secretType, annotations, ownerRef)
|
||||||
}
|
}
|
||||||
|
@@ -35,7 +35,7 @@ var ErrCannotUpdateSecretType = errs.New("Cannot change secret type. Secret type
|
|||||||
|
|
||||||
var log = logf.Log
|
var log = logf.Log
|
||||||
|
|
||||||
func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretName, namespace string, item *onepassword.Item, autoRestart string, labels map[string]string, secretType string, secretAnnotations map[string]string) error {
|
func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretName, namespace string, item *onepassword.Item, autoRestart string, labels map[string]string, secretType string, secretAnnotations map[string]string, ownerRef *metav1.OwnerReference) error {
|
||||||
|
|
||||||
itemVersion := fmt.Sprint(item.Version)
|
itemVersion := fmt.Sprint(item.Version)
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// "Opaque" and "" secret types are treated the same by Kubernetes.
|
// "Opaque" and "" secret types are treated the same by Kubernetes.
|
||||||
secret := BuildKubernetesSecretFromOnePasswordItem(secretName, namespace, secretAnnotations, labels, secretType, *item)
|
secret := BuildKubernetesSecretFromOnePasswordItem(secretName, namespace, secretAnnotations, labels, secretType, *item, ownerRef)
|
||||||
|
|
||||||
currentSecret := &corev1.Secret{}
|
currentSecret := &corev1.Secret{}
|
||||||
err := kubeClient.Get(context.Background(), types.NamespacedName{Name: secret.Name, Namespace: secret.Namespace}, currentSecret)
|
err := kubeClient.Get(context.Background(), types.NamespacedName{Name: secret.Name, Namespace: secret.Namespace}, currentSecret)
|
||||||
@@ -87,13 +87,19 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildKubernetesSecretFromOnePasswordItem(name, namespace string, annotations map[string]string, labels map[string]string, secretType string, item onepassword.Item) *corev1.Secret {
|
func BuildKubernetesSecretFromOnePasswordItem(name, namespace string, annotations map[string]string, labels map[string]string, secretType string, item onepassword.Item, ownerRef *metav1.OwnerReference) *corev1.Secret {
|
||||||
|
var ownerRefs []metav1.OwnerReference
|
||||||
|
if ownerRef != nil {
|
||||||
|
ownerRefs = []metav1.OwnerReference{*ownerRef}
|
||||||
|
}
|
||||||
|
|
||||||
return &corev1.Secret{
|
return &corev1.Secret{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: formatSecretName(name),
|
Name: formatSecretName(name),
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Annotations: annotations,
|
Annotations: annotations,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
|
OwnerReferences: ownerRefs,
|
||||||
},
|
},
|
||||||
Data: BuildKubernetesSecretData(item.Fields, item.Files),
|
Data: BuildKubernetesSecretData(item.Fields, item.Files),
|
||||||
Type: corev1.SecretType(secretType),
|
Type: corev1.SecretType(secretType),
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/1Password/connect-sdk-go/onepassword"
|
"github.com/1Password/connect-sdk-go/onepassword"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
kubeValidate "k8s.io/apimachinery/pkg/util/validation"
|
kubeValidate "k8s.io/apimachinery/pkg/util/validation"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
@@ -37,7 +38,7 @@ func TestCreateKubernetesSecretFromOnePasswordItem(t *testing.T) {
|
|||||||
}
|
}
|
||||||
secretType := ""
|
secretType := ""
|
||||||
|
|
||||||
err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations)
|
err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -55,6 +56,54 @@ func TestCreateKubernetesSecretFromOnePasswordItem(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestKubernetesSecretFromOnePasswordItemOwnerReferences(t *testing.T) {
|
||||||
|
secretName := "test-secret-name"
|
||||||
|
namespace := "test"
|
||||||
|
|
||||||
|
item := onepassword.Item{}
|
||||||
|
item.Fields = generateFields(5)
|
||||||
|
item.Version = 123
|
||||||
|
item.Vault.ID = "hfnjvi6aymbsnfc2xeeoheizda"
|
||||||
|
item.ID = "h46bb3jddvay7nxopfhvlwg35q"
|
||||||
|
|
||||||
|
kubeClient := fake.NewFakeClient()
|
||||||
|
secretLabels := map[string]string{}
|
||||||
|
secretAnnotations := map[string]string{
|
||||||
|
"testAnnotation": "exists",
|
||||||
|
}
|
||||||
|
secretType := ""
|
||||||
|
|
||||||
|
ownerRef := &metav1.OwnerReference{
|
||||||
|
Kind: "Deployment",
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Name: "test-deployment",
|
||||||
|
UID: types.UID("test-uid"),
|
||||||
|
}
|
||||||
|
err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations, ownerRef)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
createdSecret := &corev1.Secret{}
|
||||||
|
err = kubeClient.Get(context.Background(), types.NamespacedName{Name: secretName, Namespace: namespace}, createdSecret)
|
||||||
|
|
||||||
|
// Check owner references.
|
||||||
|
gotOwnerRefs := createdSecret.ObjectMeta.OwnerReferences
|
||||||
|
if len(gotOwnerRefs) != 1 {
|
||||||
|
t.Errorf("Expected owner references length: 1 but got: %d", len(gotOwnerRefs))
|
||||||
|
}
|
||||||
|
|
||||||
|
expOwnerRef := metav1.OwnerReference{
|
||||||
|
Kind: "Deployment",
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Name: "test-deployment",
|
||||||
|
UID: types.UID("test-uid"),
|
||||||
|
}
|
||||||
|
gotOwnerRef := gotOwnerRefs[0]
|
||||||
|
if gotOwnerRef != expOwnerRef {
|
||||||
|
t.Errorf("Expected owner reference value: %v but got: %v", expOwnerRef, gotOwnerRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) {
|
func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) {
|
||||||
secretName := "test-secret-update"
|
secretName := "test-secret-update"
|
||||||
namespace := "test"
|
namespace := "test"
|
||||||
@@ -70,7 +119,7 @@ func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) {
|
|||||||
secretAnnotations := map[string]string{}
|
secretAnnotations := map[string]string{}
|
||||||
secretType := ""
|
secretType := ""
|
||||||
|
|
||||||
err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations)
|
err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@@ -82,7 +131,7 @@ func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) {
|
|||||||
newItem.Version = 456
|
newItem.Version = 456
|
||||||
newItem.Vault.ID = "hfnjvi6aymbsnfc2xeeoheizda"
|
newItem.Vault.ID = "hfnjvi6aymbsnfc2xeeoheizda"
|
||||||
newItem.ID = "h46bb3jddvay7nxopfhvlwg35q"
|
newItem.ID = "h46bb3jddvay7nxopfhvlwg35q"
|
||||||
err = CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &newItem, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations)
|
err = CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &newItem, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -118,7 +167,7 @@ func TestBuildKubernetesSecretFromOnePasswordItem(t *testing.T) {
|
|||||||
labels := map[string]string{}
|
labels := map[string]string{}
|
||||||
secretType := ""
|
secretType := ""
|
||||||
|
|
||||||
kubeSecret := BuildKubernetesSecretFromOnePasswordItem(name, namespace, annotations, labels, secretType, item)
|
kubeSecret := BuildKubernetesSecretFromOnePasswordItem(name, namespace, annotations, labels, secretType, item, nil)
|
||||||
if kubeSecret.Name != strings.ToLower(name) {
|
if kubeSecret.Name != strings.ToLower(name) {
|
||||||
t.Errorf("Expected name value: %v but got: %v", name, kubeSecret.Name)
|
t.Errorf("Expected name value: %v but got: %v", name, kubeSecret.Name)
|
||||||
}
|
}
|
||||||
@@ -153,7 +202,7 @@ func TestBuildKubernetesSecretFixesInvalidLabels(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
kubeSecret := BuildKubernetesSecretFromOnePasswordItem(name, namespace, annotations, labels, secretType, item)
|
kubeSecret := BuildKubernetesSecretFromOnePasswordItem(name, namespace, annotations, labels, secretType, item, nil)
|
||||||
|
|
||||||
// Assert Secret's meta.name was fixed
|
// Assert Secret's meta.name was fixed
|
||||||
if kubeSecret.Name != expectedName {
|
if kubeSecret.Name != expectedName {
|
||||||
@@ -188,7 +237,7 @@ func TestCreateKubernetesTLSSecretFromOnePasswordItem(t *testing.T) {
|
|||||||
}
|
}
|
||||||
secretType := "kubernetes.io/tls"
|
secretType := "kubernetes.io/tls"
|
||||||
|
|
||||||
err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations)
|
err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, secretAnnotations, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@@ -140,7 +140,7 @@ func (h *SecretUpdateHandler) updateKubernetesSecrets() (map[string]map[string]*
|
|||||||
log.Info(fmt.Sprintf("Updating kubernetes secret '%v'", secret.GetName()))
|
log.Info(fmt.Sprintf("Updating kubernetes secret '%v'", secret.GetName()))
|
||||||
secret.Annotations[VersionAnnotation] = itemVersion
|
secret.Annotations[VersionAnnotation] = itemVersion
|
||||||
secret.Annotations[ItemPathAnnotation] = itemPathString
|
secret.Annotations[ItemPathAnnotation] = itemPathString
|
||||||
updatedSecret := kubeSecrets.BuildKubernetesSecretFromOnePasswordItem(secret.Name, secret.Namespace, secret.Annotations, secret.Labels, string(secret.Type), *item)
|
updatedSecret := kubeSecrets.BuildKubernetesSecretFromOnePasswordItem(secret.Name, secret.Namespace, secret.Annotations, secret.Labels, string(secret.Type), *item, nil)
|
||||||
log.Info(fmt.Sprintf("New secret path: %v and version: %v", updatedSecret.Annotations[ItemPathAnnotation], updatedSecret.Annotations[VersionAnnotation]))
|
log.Info(fmt.Sprintf("New secret path: %v and version: %v", updatedSecret.Annotations[ItemPathAnnotation], updatedSecret.Annotations[VersionAnnotation]))
|
||||||
h.client.Update(context.Background(), updatedSecret)
|
h.client.Update(context.Background(), updatedSecret)
|
||||||
if updatedSecrets[secret.Namespace] == nil {
|
if updatedSecrets[secret.Namespace] == nil {
|
||||||
|
Reference in New Issue
Block a user