Repository: godaddy/kubernetes-external-secrets (js)

Issue:
Delete secret when externalsecret is removed
It would be nice if the created secret was removed if I remove the external secret resource.

Pull request:
Add ownerreference to remove created secret when external secret is removed
Fixes #93

Not sure how you would like it configureable and what kind of defaults?

Figured I'd just draft a PR first 😄 

Im abit unsure about whether I plugged it in, in the right place. Seeing how `secretDescriptors` is an array being sent around, but its always just one?

I could add the ownerReference into the `secretDescriptor` object (https://github.com/godaddy/kubernetes-external-secrets/pull/95/files#diff-5c2754430010d5f3e95b45e1bb36d58bR55) but it feels weird to put it in there as well as its just some metadata and not part of the secretDescriptor 

Patch:
diff --git a/api.md b/api.md
new file mode 100644
index 0000000..58796ed
--- /dev/null
+++ b/api.md
@@ -0,0 +1,102 @@
+# Kubernetes External Secrets Storage Frontends
+
+Kubernetes External Secrets supports several "frontends" for storing
+secret data and presenting it to applications:
+
+* [Secret frontend](#secret-frontend)
+* [Volume frontend](#volume-frontend)
+
+## Secret frontend
+
+TODO.
+
+## Volume frontend
+
+The volume frontend writes secret data to volumes included in `Pod`
+specs. The volume frontend implements a behavior analogous to the
+secret volume type. You specify `ExternalSecret` objects to use as
+volumes and the External Secret controller creates files containing
+secret data.
+
+To emulate an "externalSecret" volume type, you configure which
+volumes the External Secret controller writes data to by adding the
+`externalsecrets.kubernetes-client.io/volumes` annotation to a `Pod`
+manifest". With the manifest below, the External Secret controller
+should:
+
+* create password and username files in the db-secrets volume;
+* fetch the value of db/password from AWS Secrets Manager and write
+  that value to password file in the db-secrets volume;
+* fetch the value of db/username from AWS Secrets Manager and write
+  that value to the username file in the db-secrets volume;
+* create a key file in the client-secrets volume; and
+* fetch the value of api/key from AWS Secrets Manager and write that
+  values to the api file in the client-secrets volume.
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+  generateName: pod-example-
+  annotations:
+    externalsecrets.kubernetes-client.io/volumes: |
+      - name: "db-secrets"
+        externalSecret:
+          externalSecretName: "db-secrets"
+      - name: "client-secrets"
+        externalSecret:
+          externalSecretName: "client-secrets"
+spec:
+  containers:
+  - image: busybox
+    name: busybox
+    volumeMounts:
+    - mountPath: /db-secrets
+      name: db-secrets
+    - mountPath: /client-secrets
+      name: client-secrets
+  volumes:
+  - name: db-secrets
+    emptyDir:
+      medium: Memory
+  - name: client-secrets
+    emptyDir:
+      medium: Memory
+---
+apiVersion: 'kubernetes-client.io/v1'
+kind: ExternalSecret
+metadata:
+  name: db-secrets
+secretDescriptor:
+  backendType: secretsManager
+  data:
+    - key: db/password
+      name: password
+    - key: db/username
+      name: username
+---
+apiVersion: 'kubernetes-client.io/v1'
+kind: ExternalSecret
+metadata:
+  name: client-secrets
+secretDescriptor:
+  backendType: secretsManager
+  data:
+    - key: api/key
+      name: key
+```
+
+The value of `externalsecrets.kubernetes-client.io/volumes` is a JSON or
+YAML serialized array of volume configuration objects:
+
+|Property|Type|Description|
+|--------|----|-----------|
+|`name`|string|Name of volume to write secret data to|
+|`externalSecretName`|string|Name of ExternalSecret to get secret data from|
+
+You can configure any [type of
+volume](https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes)
+to hold secret data. To avoid storing secret data on disk,
+use an
+[`emptyDir`](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir)
+volume and set `emptyDir.medium` field to `"Memory"`.
diff --git a/lib/daemon.js b/lib/daemon.js
index 075c4a8..f6ead9a 100644
--- a/lib/daemon.js
+++ b/lib/daemon.js
@@ -30,14 +30,15 @@ class Daemon {
     this._pollers = {}
   }
 
-  _createPoller ({ namespace, secretDescriptors }) {
+  _createPoller ({ namespace, secretDescriptors, ownerReference }) {
     return new Poller({
       backends: this._backends,
       intervalMilliseconds: this._pollerIntervalMilliseconds,
       kubeClient: this._kubeClient,
       logger: this._logger,
       namespace,
-      secretDescriptors
+      secretDescriptors,
+      ownerReference
     })
   }
 
@@ -52,7 +53,15 @@ class Daemon {
     // NOTE(jdaeli): hash this in case resource version becomes too long?
     const id = `${name}_${resourceVersion}`
     const secretDescriptors = [{ ...secretDescriptor, name }]
-    return { id, namespace, secretDescriptors }
+    const ownerReference = {
+      apiVersion: object.apiVersion,
+      controller: true,
+      kind: object.kind,
+      name: metadata.name,
+      uid: metadata.uid
+    }
+
+    return { id, namespace, secretDescriptors, ownerReference }
   }
 
   /**
@@ -82,7 +91,8 @@ class Daemon {
 
         const poller = this._createPoller({
           namespace: descriptor.namespace,
-          secretDescriptors: descriptor.secretDescriptors
+          secretDescriptors: descriptor.secretDescriptors,
+          ownerReference: descriptor.ownerReference
         })
 
         // handle duplicate ADDED events
diff --git a/lib/poller.js b/lib/poller.js
index feae886..8c66fd1 100644
--- a/lib/poller.js
+++ b/lib/poller.js
@@ -23,14 +23,22 @@ class Poller {
    * @param {string} namespace - Kubernetes namespace.
    * @param {SecretDescriptor[]} secretDescriptors - Kubernetes secret descriptors.
    */
-  constructor ({ backends, intervalMilliseconds, kubeClient, logger, namespace, secretDescriptors }) {
+  constructor ({
+    backends,
+    intervalMilliseconds,
+    kubeClient,
+    logger,
+    namespace,
+    secretDescriptors,
+    ownerReference
+  }) {
     this._backends = backends
     this._intervalMilliseconds = intervalMilliseconds
     this._kubeClient = kubeClient
     this._logger = logger
     this._namespace = namespace
     this._secretDescriptors = secretDescriptors
-
+    this._ownerReference = ownerReference
     this._interval = null
   }
 
@@ -46,7 +54,10 @@ class Poller {
       apiVersion: 'v1',
       kind: 'Secret',
       metadata: {
-        name: secretDescriptor.name
+        name: secretDescriptor.name,
+        ownerReferences: [
+          this._ownerReference
+        ]
       },
       type: 'Opaque',
       data


Test patch:
diff --git a/lib/poller.test.js b/lib/poller.test.js
index 42fbdfa..5667660 100644
--- a/lib/poller.test.js
+++ b/lib/poller.test.js
@@ -12,6 +12,14 @@ describe('Poller', () => {
   let loggerMock
   let poller
 
+  const ownerReference = {
+    apiVersion: 'owner-api/v1',
+    controller: true,
+    kind: 'MyKind',
+    name: 'fakeSecretName',
+    uid: '4c10d879-2646-40dc-8595-d0b06b60a9ed'
+  }
+
   beforeEach(() => {
     backendMock = sinon.mock()
     kubeClientMock = sinon.mock()
@@ -27,7 +35,8 @@ describe('Poller', () => {
       intervalMilliseconds: 5000,
       kubeClient: kubeClientMock,
       logger: loggerMock,
-      namespace: 'fakeNamespace'
+      namespace: 'fakeNamespace',
+      ownerReference
     })
   })
 
@@ -72,7 +81,8 @@ describe('Poller', () => {
         apiVersion: 'v1',
         kind: 'Secret',
         metadata: {
-          name: 'fakeSecretName'
+          name: 'fakeSecretName',
+          ownerReferences: [ownerReference]
         },
         type: 'Opaque',
         data: {
@@ -154,7 +164,7 @@ describe('Poller', () => {
         secretDescriptor: {
           backendType: 'fakeBackendType',
           name: 'fakeSecretName',
-          properties: ['fakePropertyName1']
+          properties: ['fakePropertyName']
         }
       }
     })