Skip to content

Commit

Permalink
Merge pull request #97 from slok/slok/owner-references
Browse files Browse the repository at this point in the history
Add owner reference to the created secrets by the operator
  • Loading branch information
jillianwilson authored Apr 7, 2022
2 parents 6286f7e + 79868ae commit 4864652
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 18 deletions.
20 changes: 17 additions & 3 deletions pkg/controller/deployment/deployment_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"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/handler"
logf "sigs.k8s.io/controller-runtime/pkg/log"
Expand Down Expand Up @@ -114,7 +116,7 @@ func (r *ReconcileDeployment) Reconcile(request reconcile.Request) (reconcile.Re
}
}
// 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{}, nil
Expand Down Expand Up @@ -187,7 +189,7 @@ func (r *ReconcileDeployment) removeOnePasswordFinalizerFromDeployment(deploymen
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)

secretName := annotations[op.NameAnnotation]
Expand All @@ -204,5 +206,17 @@ func (r *ReconcileDeployment) HandleApplyingDeployment(namespace string, annotat
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)
}
16 changes: 15 additions & 1 deletion pkg/controller/onepassworditem/onepassworditem_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import (

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
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/handler"
logf "sigs.k8s.io/controller-runtime/pkg/log"
Expand Down Expand Up @@ -154,5 +156,17 @@ func (r *ReconcileOnePasswordItem) HandleOnePasswordItem(resource *onepasswordv1
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)
}
20 changes: 13 additions & 7 deletions pkg/kubernetessecrets/kubernetes_secrets_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var ErrCannotUpdateSecretType = errs.New("Cannot change secret type. Secret type

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)

Expand All @@ -57,7 +57,7 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa
}

// "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{}
err := kubeClient.Get(context.Background(), types.NamespacedName{Name: secret.Name, Namespace: secret.Namespace}, currentSecret)
Expand Down Expand Up @@ -87,13 +87,19 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa
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{
ObjectMeta: metav1.ObjectMeta{
Name: formatSecretName(name),
Namespace: namespace,
Annotations: annotations,
Labels: labels,
Name: formatSecretName(name),
Namespace: namespace,
Annotations: annotations,
Labels: labels,
OwnerReferences: ownerRefs,
},
Data: BuildKubernetesSecretData(item.Fields, item.Files),
Type: corev1.SecretType(secretType),
Expand Down
61 changes: 55 additions & 6 deletions pkg/kubernetessecrets/kubernetes_secrets_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/1Password/connect-sdk-go/onepassword"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
kubeValidate "k8s.io/apimachinery/pkg/util/validation"
"k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -37,7 +38,7 @@ func TestCreateKubernetesSecretFromOnePasswordItem(t *testing.T) {
}
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 {
t.Errorf("Unexpected error: %v", err)
}
Expand All @@ -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) {
secretName := "test-secret-update"
namespace := "test"
Expand All @@ -70,7 +119,7 @@ func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) {
secretAnnotations := map[string]string{}
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 {
t.Errorf("Unexpected error: %v", err)
Expand All @@ -82,7 +131,7 @@ func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) {
newItem.Version = 456
newItem.Vault.ID = "hfnjvi6aymbsnfc2xeeoheizda"
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 {
t.Errorf("Unexpected error: %v", err)
}
Expand Down Expand Up @@ -118,7 +167,7 @@ func TestBuildKubernetesSecretFromOnePasswordItem(t *testing.T) {
labels := map[string]string{}
secretType := ""

kubeSecret := BuildKubernetesSecretFromOnePasswordItem(name, namespace, annotations, labels, secretType, item)
kubeSecret := BuildKubernetesSecretFromOnePasswordItem(name, namespace, annotations, labels, secretType, item, nil)
if kubeSecret.Name != strings.ToLower(name) {
t.Errorf("Expected name value: %v but got: %v", name, kubeSecret.Name)
}
Expand Down Expand Up @@ -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
if kubeSecret.Name != expectedName {
Expand Down Expand Up @@ -188,7 +237,7 @@ func TestCreateKubernetesTLSSecretFromOnePasswordItem(t *testing.T) {
}
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 {
t.Errorf("Unexpected error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/onepassword/secret_update_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (h *SecretUpdateHandler) updateKubernetesSecrets() (map[string]map[string]*
log.Info(fmt.Sprintf("Updating kubernetes secret '%v'", secret.GetName()))
secret.Annotations[VersionAnnotation] = itemVersion
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]))
h.client.Update(context.Background(), updatedSecret)
if updatedSecrets[secret.Namespace] == nil {
Expand Down

0 comments on commit 4864652

Please sign in to comment.