Repository: godaddy/kubernetes-external-secrets
Pull request #204 (2019-11-08 02:57:20)

feat: use spec in external secret resource, keeping secretDescriptor …
…for backwards compat


Patch:
diff --git a/README.md b/README.md
index 467063f..34c2b29 100644
--- a/README.md
+++ b/README.md
@@ -120,7 +120,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: hello-service
-secretDescriptor:
+spec:
   backendType: secretsManager
   # optional: specify role to assume when retrieving the data
   roleArn: arn:aws:iam::123456789012:role/test-role
@@ -142,7 +142,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: hello-service
-secretDescriptor:
+spec:
   backendType: systemManager
   data:
     - key: /hello-service/password
@@ -242,7 +242,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: hello-service
-secretDescriptor:
+spec:
   backendType: secretsManager
   # optional: specify role to assume when retrieving the data
   roleArn: arn:aws:iam::123456789012:role/test-role
@@ -262,7 +262,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: hello-service
-secretDescriptor:
+spec:
   backendType: secretsManager
   # optional: specify role to assume when retrieving the data
   roleArn: arn:aws:iam::123456789012:role/test-role
@@ -277,7 +277,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: hello-service
-secretDescriptor:
+spec:
   backendType: secretsManager
   # optional: specify role to assume when retrieving the data
   roleArn: arn:aws:iam::123456789012:role/test-role
diff --git a/api.md b/api.md
index 58796ed..1d4522d 100644
--- a/api.md
+++ b/api.md
@@ -67,7 +67,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: db-secrets
-secretDescriptor:
+spec:
   backendType: secretsManager
   data:
     - key: db/password
@@ -79,7 +79,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: client-secrets
-secretDescriptor:
+spec:
   backendType: secretsManager
   data:
     - key: api/key
diff --git a/charts/kubernetes-external-secrets/README.md b/charts/kubernetes-external-secrets/README.md
index 315ed90..6ccf7b7 100644
--- a/charts/kubernetes-external-secrets/README.md
+++ b/charts/kubernetes-external-secrets/README.md
@@ -97,7 +97,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: hello-service
-secretDescriptor:
+spec:
   backendType: secretsManager
   data:
     - key: hello-service/password
diff --git a/examples/dockerconfig-example.yml b/examples/dockerconfig-example.yml
index 3fcf812..d9f93bd 100644
--- a/examples/dockerconfig-example.yml
+++ b/examples/dockerconfig-example.yml
@@ -2,7 +2,7 @@ apiVersion: kubernetes-client.io/v1
 kind: ExternalSecret
 metadata:
   name: dockerhub-secret
-secretDescriptor:
+spec:
   backendType: secretsManager
   type: kubernetes.io/dockerconfigjson
   data:
diff --git a/examples/hello-service-external-secret.yml b/examples/hello-service-external-secret.yml
index 15776d4..d6f4ff6 100644
--- a/examples/hello-service-external-secret.yml
+++ b/examples/hello-service-external-secret.yml
@@ -2,7 +2,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: hello-service
-secretDescriptor:
+spec:
   backendType: secretsManager
   data:
     - key: hello-service/password
diff --git a/examples/secretsmanager-example.yaml b/examples/secretsmanager-example.yaml
index a1c1470..bb3f91f 100644
--- a/examples/secretsmanager-example.yaml
+++ b/examples/secretsmanager-example.yaml
@@ -2,7 +2,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: demo-service
-secretDescriptor:
+spec:
   backendType: secretsManager
   # optional: specify role to assume when retrieving the data
   roleArn: arn:aws:iam::123412341234:role/let-other-account-access-secrets
diff --git a/examples/ssm-example.yaml b/examples/ssm-example.yaml
index 98cb19a..6db6567 100644
--- a/examples/ssm-example.yaml
+++ b/examples/ssm-example.yaml
@@ -2,7 +2,7 @@ apiVersion: 'kubernetes-client.io/v1'
 kind: ExternalSecret
 metadata:
   name: ssm-secret-key
-secretDescriptor:
+spec:
   backendType: systemManager
   # optional: specify role to assume when retrieving the data
   roleArn: arn:aws:iam::123456789012:role/test-role
diff --git a/examples/tls-example.yml b/examples/tls-example.yml
index db87ff2..c15279f 100644
--- a/examples/tls-example.yml
+++ b/examples/tls-example.yml
@@ -2,7 +2,7 @@ apiVersion: kubernetes-client.io/v1
 kind: ExternalSecret
 metadata:
   name: dockerhub-secret
-secretDescriptor:
+spec:
   backendType: secretsManager
   type: kubernetes.io/tls
   data:
diff --git a/lib/backends/kv-backend.js b/lib/backends/kv-backend.js
index 302d5fe..e4e5a41 100644
--- a/lib/backends/kv-backend.js
+++ b/lib/backends/kv-backend.js
@@ -81,12 +81,12 @@ class KVBackend extends AbstractBackend {
 
   /**
    * Fetch Kubernetes secret manifest data.
-   * @param {SecretDescriptor} secretDescriptor - Kubernetes secret descriptor.
+   * @param {ExternalSecretSpec} spec - Kubernetes ExternalSecret spec.
    * @returns {Promise} Promise object representing Kubernetes secret manifest data.
    */
   async getSecretManifestData ({
-    secretDescriptor: {
-      // Use secretDescriptor.properties to be backwards compatible.
+    spec: {
+      // Use properties to be backwards compatible.
       properties = [],
       data = properties,
       dataFrom = [],
diff --git a/lib/poller.js b/lib/poller.js
index 91cc236..069aeff 100644
--- a/lib/poller.js
+++ b/lib/poller.js
@@ -49,7 +49,7 @@ class Poller {
     this._customResourceManifest = customResourceManifest
 
     this._externalSecret = externalSecret
-    this._secretDescriptor = externalSecret.secretDescriptor
+    this._spec = externalSecret.spec || externalSecret.secretDescriptor
 
     const { name, uid, namespace } = externalSecret.metadata
 
@@ -74,10 +74,10 @@ class Poller {
    * @returns {Object} Promise object representing Kubernetes manifest.
    */
   async _createSecretManifest () {
-    const secretDescriptor = this._secretDescriptor
-    const template = secretDescriptor.template
-    const data = await this._backends[secretDescriptor.backendType]
-      .getSecretManifestData({ secretDescriptor })
+    const spec = this._spec
+    const template = spec.template
+    const data = await this._backends[spec.backendType]
+      .getSecretManifestData({ spec })
     let secretManifest = {
       apiVersion: 'v1',
       kind: 'Secret',
@@ -87,7 +87,7 @@ class Poller {
           this._ownerReference
         ]
       },
-      type: secretDescriptor.type || 'Opaque',
+      type: spec.type || 'Opaque',
       data
     }
 
@@ -112,7 +112,7 @@ class Poller {
       this._metrics.observeSync({
         name: this._name,
         namespace: this._namespace,
-        backend: this._secretDescriptor.backendType,
+        backend: this._spec.backendType,
         status: 'success'
       })
     } catch (err) {
@@ -122,7 +122,7 @@ class Poller {
       this._metrics.observeSync({
         name: this._name,
         namespace: this._namespace,
-        backend: this._secretDescriptor.backendType,
+        backend: this._spec.backendType,
         status: 'error'
       })
     }
@@ -137,7 +137,7 @@ class Poller {
 
     // check if namespace is allowed to fetch this secret
     const ns = await kubeNamespace.get()
-    const verdict = this._isPermitted(ns.body, this._secretDescriptor)
+    const verdict = this._isPermitted(ns.body, this._spec)
 
     if (!verdict.allowed) {
       throw (new Error(`not allowed to fetch secret: ${this._namespace}/${this._name}: ${verdict.reason}`))


Test patch:
diff --git a/lib/backends/kv-backend.test.js b/lib/backends/kv-backend.test.js
index fede2a6..4098ee3 100644
--- a/lib/backends/kv-backend.test.js
+++ b/lib/backends/kv-backend.test.js
@@ -6,7 +6,7 @@ const sinon = require('sinon')
 
 const KVBackend = require('./kv-backend')
 
-describe('SecretsManagerBackend', () => {
+describe('kv-backend', () => {
   let loggerMock
   let kvBackend
 
@@ -220,7 +220,7 @@ describe('SecretsManagerBackend', () => {
 
       const manifestData = await kvBackend
         .getSecretManifestData({
-          secretDescriptor: { }
+          spec: { }
         })
 
       expect(manifestData).deep.equals({
@@ -238,14 +238,14 @@ describe('SecretsManagerBackend', () => {
       kvBackend._fetchDataFromValues.resolves([undefined])
 
       const manifestData = await kvBackend
-        .getSecretManifestData({ secretDescriptor: { } })
+        .getSecretManifestData({ spec: { } })
 
       expect(manifestData).deep.equals({})
     })
 
     it('makes correct calls - with data and role', async () => {
       await kvBackend.getSecretManifestData({
-        secretDescriptor: {
+        spec: {
           data: [
             {
               key: 'fakePropertyKey1',
@@ -278,7 +278,7 @@ describe('SecretsManagerBackend', () => {
 
     it('makes correct calls - with properties and dataFrom', async () => {
       await kvBackend.getSecretManifestData({
-        secretDescriptor: {
+        spec: {
           properties: [
             {
               key: 'fakePropertyKey1',
@@ -313,7 +313,7 @@ describe('SecretsManagerBackend', () => {
 
     it('makes correct calls - with only dataFrom', async () => {
       await kvBackend.getSecretManifestData({
-        secretDescriptor: {
+        spec: {
           dataFrom: [
             'fakeDataFromKey1',
             'fakeDataFromKey2'
diff --git a/lib/daemon.test.js b/lib/daemon.test.js
index dc4c41b..938e59b 100644
--- a/lib/daemon.test.js
+++ b/lib/daemon.test.js
@@ -44,7 +44,7 @@ describe('Daemon', () => {
             namespace: 'foo',
             resourceVersion: '1'
           },
-          secretDescriptor: {}
+          spec: {}
         }
       }
     }())
diff --git a/lib/external-secret.test.js b/lib/external-secret.test.js
index ee47ede..9a59768 100644
--- a/lib/external-secret.test.js
+++ b/lib/external-secret.test.js
@@ -54,7 +54,7 @@ describe('getExternalSecretEvents', () => {
         name: 'my-secret',
         namespace: 'default'
       },
-      secretDescriptor: { backendType: 'secretsManager', data: [] }
+      spec: { backendType: 'secretsManager', data: [] }
     }
 
     const events = getExternalSecretEvents({
diff --git a/lib/poller.test.js b/lib/poller.test.js
index 8603cfc..afc6d2e 100644
--- a/lib/poller.test.js
+++ b/lib/poller.test.js
@@ -75,14 +75,14 @@ describe('Poller', () => {
       }
     }
 
-    pollerFactory = (secretDescriptor = {
+    pollerFactory = (spec = {
       backendType: 'fakeBackendType',
       properties: [
         'fakePropertyName1',
         'fakePropertyName2'
       ]
     }) => {
-      fakeExternalSecret.secretDescriptor = secretDescriptor
+      fakeExternalSecret.spec = spec
       return new Poller({
         backends: {
           fakeBackendType: backendMock
@@ -102,6 +102,30 @@ describe('Poller', () => {
     sinon.restore()
   })
 
+  it('backwards compat with secretDescriptor', () => {
+    const mySpec = {
+      dataFrom: ['some-key', 'some-other'],
+      backendType: 'my-magical-backend'
+    }
+
+    fakeExternalSecret.secretDescriptor = mySpec
+
+    const myPoller = new Poller({
+      backends: {
+        fakeBackendType: backendMock
+      },
+      metrics: metricsMock,
+      intervalMilliseconds: 5000,
+      kubeClient: kubeClientMock,
+      logger: loggerMock,
+      externalSecret: fakeExternalSecret,
+      rolePermittedAnnotation,
+      customResourceManifest: fakeCustomResourceManifest
+    })
+
+    expect(myPoller._spec).to.deep.equal(mySpec)
+  })
+
   describe('_createSecretManifest', () => {
     let clock
 
@@ -134,7 +158,7 @@ describe('Poller', () => {
       const secretManifest = await poller._createSecretManifest()
 
       expect(backendMock.getSecretManifestData.calledWith({
-        secretDescriptor: {
+        spec: {
           backendType: 'fakeBackendType',
           name: 'fakeSecretName',
           properties: [
@@ -178,7 +202,7 @@ describe('Poller', () => {
       const secretManifest = await poller._createSecretManifest()
 
       expect(backendMock.getSecretManifestData.calledWith({
-        secretDescriptor: {
+        spec: {
           type: 'dummy-test-type',
           backendType: 'fakeBackendType',
           name: 'fakeSecretName',
@@ -234,7 +258,7 @@ describe('Poller', () => {
       const secretManifest = await poller._createSecretManifest()
 
       expect(backendMock.getSecretManifestData.calledWith({
-        secretDescriptor: {
+        spec: {
           type: 'dummy-test-type',
           backendType: 'fakeBackendType',
           name: 'fakeSecretName',