diff --git a/API.md b/API.md index 342f0cf..c0aecd7 100644 --- a/API.md +++ b/API.md @@ -2,6 +2,306 @@ ## Constructs +### ExternalSecretV1 + +#### Initializers + +```typescript +import { ExternalSecretV1 } from '@opencdk8s/cdk8s-external-secrets' + +new ExternalSecretV1(scope: Construct, id: string, props: ExternalSecretProps) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| scope | constructs.Construct | the scope in which to define this object. | +| id | string | a scope-local name for the object. | +| props | ExternalSecretProps | initialization props. | + +--- + +##### `scope`Required + +- *Type:* constructs.Construct + +the scope in which to define this object. + +--- + +##### `id`Required + +- *Type:* string + +a scope-local name for the object. + +--- + +##### `props`Required + +- *Type:* ExternalSecretProps + +initialization props. + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| toString | Returns a string representation of this construct. | +| addDependency | Create a dependency between this ApiObject and other constructs. | +| addJsonPatch | Applies a set of RFC-6902 JSON-Patch operations to the manifest synthesized for this API object. | +| toJson | Renders the object to Kubernetes JSON. | + +--- + +##### `toString` + +```typescript +public toString(): string +``` + +Returns a string representation of this construct. + +##### `addDependency` + +```typescript +public addDependency(dependencies: IConstruct): void +``` + +Create a dependency between this ApiObject and other constructs. + +These can be other ApiObjects, Charts, or custom. + +###### `dependencies`Required + +- *Type:* constructs.IConstruct + +the dependencies to add. + +--- + +##### `addJsonPatch` + +```typescript +public addJsonPatch(ops: JsonPatch): void +``` + +Applies a set of RFC-6902 JSON-Patch operations to the manifest synthesized for this API object. + +*Example* + +```typescript + kubePod.addJsonPatch(JsonPatch.replace('/spec/enableServiceLinks', true)); +``` + + +###### `ops`Required + +- *Type:* cdk8s.JsonPatch + +The JSON-Patch operations to apply. + +--- + +##### `toJson` + +```typescript +public toJson(): any +``` + +Renders the object to Kubernetes JSON. + +To disable sorting of dictionary keys in output object set the +`CDK8S_DISABLE_SORT` environment variable to any non-empty value. + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| isConstruct | Checks if `x` is a construct. | +| of | Returns the `ApiObject` named `Resource` which is a child of the given construct. | +| manifest | *No description.* | + +--- + +##### ~~`isConstruct`~~ + +```typescript +import { ExternalSecretV1 } from '@opencdk8s/cdk8s-external-secrets' + +ExternalSecretV1.isConstruct(x: any) +``` + +Checks if `x` is a construct. + +###### `x`Required + +- *Type:* any + +Any object. + +--- + +##### `of` + +```typescript +import { ExternalSecretV1 } from '@opencdk8s/cdk8s-external-secrets' + +ExternalSecretV1.of(c: IConstruct) +``` + +Returns the `ApiObject` named `Resource` which is a child of the given construct. + +If `c` is an `ApiObject`, it is returned directly. Throws an +exception if the construct does not have a child named `Default` _or_ if +this child is not an `ApiObject`. + +###### `c`Required + +- *Type:* constructs.IConstruct + +The higher-level construct. + +--- + +##### `manifest` + +```typescript +import { ExternalSecretV1 } from '@opencdk8s/cdk8s-external-secrets' + +ExternalSecretV1.manifest(props: ExternalSecretProps) +``` + +###### `props`Required + +- *Type:* ExternalSecretProps + +initialization props. + +--- + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| apiGroup | string | The group portion of the API version (e.g. `authorization.k8s.io`). | +| apiVersion | string | The object's API version (e.g. `authorization.k8s.io/v1`). | +| chart | cdk8s.Chart | The chart in which this object is defined. | +| kind | string | The object kind. | +| metadata | cdk8s.ApiObjectMetadataDefinition | Metadata associated with this API object. | +| name | string | The name of the API object. | + +--- + +##### `node`Required + +```typescript +public readonly node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `apiGroup`Required + +```typescript +public readonly apiGroup: string; +``` + +- *Type:* string + +The group portion of the API version (e.g. `authorization.k8s.io`). + +--- + +##### `apiVersion`Required + +```typescript +public readonly apiVersion: string; +``` + +- *Type:* string + +The object's API version (e.g. `authorization.k8s.io/v1`). + +--- + +##### `chart`Required + +```typescript +public readonly chart: Chart; +``` + +- *Type:* cdk8s.Chart + +The chart in which this object is defined. + +--- + +##### `kind`Required + +```typescript +public readonly kind: string; +``` + +- *Type:* string + +The object kind. + +--- + +##### `metadata`Required + +```typescript +public readonly metadata: ApiObjectMetadataDefinition; +``` + +- *Type:* cdk8s.ApiObjectMetadataDefinition + +Metadata associated with this API object. + +--- + +##### `name`Required + +```typescript +public readonly name: string; +``` + +- *Type:* string + +The name of the API object. + +If a name is specified in `metadata.name` this will be the name returned. +Otherwise, a name will be generated by calling +`Chart.of(this).generatedObjectName(this)`, which by default uses the +construct path to generate a DNS-compatible name for the resource. + +--- + +#### Constants + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| GVK | cdk8s.GroupVersionKind | *No description.* | + +--- + +##### `GVK`Required + +```typescript +public readonly GVK: GroupVersionKind; +``` + +- *Type:* cdk8s.GroupVersionKind + +--- + ### ExternalSecretV1Beta1 #### Initializers @@ -49447,12 +49747,23 @@ const externalSecretData: ExternalSecretData = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | -| remoteRef | ExternalSecretDataRemoteRef | *No description.* | | secretKey | string | *No description.* | +| remoteRef | ExternalSecretDataRemoteRef | *No description.* | +| sourceRef | SourceRef | *No description.* | --- -##### `remoteRef`Required +##### `secretKey`Required + +```typescript +public readonly secretKey: string; +``` + +- *Type:* string + +--- + +##### `remoteRef`Optional ```typescript public readonly remoteRef: ExternalSecretDataRemoteRef; @@ -49462,13 +49773,13 @@ public readonly remoteRef: ExternalSecretDataRemoteRef; --- -##### `secretKey`Required +##### `sourceRef`Optional ```typescript -public readonly secretKey: string; +public readonly sourceRef: SourceRef; ``` -- *Type:* string +- *Type:* SourceRef --- @@ -49489,6 +49800,7 @@ const externalSecretDataFromRemoteRef: ExternalSecretDataFromRemoteRef = { ... } | extract | ExternalSecretDataRemoteRef | *No description.* | | find | ExternalSecretFind | *No description.* | | rewrite | ExternalSecretRewrite[] | *No description.* | +| sourceRef | SourceRef | *No description.* | --- @@ -49522,6 +49834,16 @@ public readonly rewrite: ExternalSecretRewrite[]; --- +##### `sourceRef`Optional + +```typescript +public readonly sourceRef: SourceRef; +``` + +- *Type:* SourceRef + +--- + ### ExternalSecretDataRemoteRef #### Initializer @@ -49797,24 +50119,15 @@ const externalSecretSpec: ExternalSecretSpec = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | -| secretStoreRef | SecretStoreRef | *No description.* | | data | ExternalSecretData[] | *No description.* | | dataFrom | ExternalSecretDataFromRemoteRef[] | *No description.* | | refreshInterval | string | *No description.* | +| refreshPolicy | string | *No description.* | +| secretStoreRef | SecretStoreRef | *No description.* | | target | ExternalSecretTarget | *No description.* | --- -##### `secretStoreRef`Required - -```typescript -public readonly secretStoreRef: SecretStoreRef; -``` - -- *Type:* SecretStoreRef - ---- - ##### `data`Optional ```typescript @@ -49845,6 +50158,26 @@ public readonly refreshInterval: string; --- +##### `refreshPolicy`Optional + +```typescript +public readonly refreshPolicy: string; +``` + +- *Type:* string + +--- + +##### `secretStoreRef`Optional + +```typescript +public readonly secretStoreRef: SecretStoreRef; +``` + +- *Type:* SecretStoreRef + +--- + ##### `target`Optional ```typescript @@ -50694,6 +51027,56 @@ Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volume --- +### GeneratorRef + +#### Initializer + +```typescript +import { GeneratorRef } from '@opencdk8s/cdk8s-external-secrets' + +const generatorRef: GeneratorRef = { ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| apiVersion | string | *No description.* | +| kind | string | *No description.* | +| name | string | *No description.* | + +--- + +##### `apiVersion`Required + +```typescript +public readonly apiVersion: string; +``` + +- *Type:* string + +--- + +##### `kind`Required + +```typescript +public readonly kind: string; +``` + +- *Type:* string + +--- + +##### `name`Required + +```typescript +public readonly name: string; +``` + +- *Type:* string + +--- + ### GitRepoVolumeSource Represents a volume that is populated with the contents of a git repository. @@ -71082,6 +71465,45 @@ clientIP contains the configurations of Client IP based session affinity. --- +### SourceRef + +#### Initializer + +```typescript +import { SourceRef } from '@opencdk8s/cdk8s-external-secrets' + +const sourceRef: SourceRef = { ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| generatorRef | GeneratorRef | *No description.* | +| storeRef | StoreRef | *No description.* | + +--- + +##### `generatorRef`Optional + +```typescript +public readonly generatorRef: GeneratorRef; +``` + +- *Type:* GeneratorRef + +--- + +##### `storeRef`Optional + +```typescript +public readonly storeRef: StoreRef; +``` + +- *Type:* StoreRef + +--- + ### StatefulSetSpec A StatefulSetSpec is the specification of a StatefulSet. @@ -71650,6 +72072,45 @@ If no namespace is specified then the Pod's namespace will be used. This allows --- +### StoreRef + +#### Initializer + +```typescript +import { StoreRef } from '@opencdk8s/cdk8s-external-secrets' + +const storeRef: StoreRef = { ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| kind | string | *No description.* | +| name | string | *No description.* | + +--- + +##### `kind`Required + +```typescript +public readonly kind: string; +``` + +- *Type:* string + +--- + +##### `name`Required + +```typescript +public readonly name: string; +``` + +- *Type:* string + +--- + ### Subject Subject contains a reference to the object or user identities a role binding applies to. diff --git a/src/index.ts b/src/index.ts index 9875423..d95180f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -44,9 +44,26 @@ export interface ExternalSecretTarget { readonly immutable?: boolean; } +export interface SourceRef { + readonly storeRef?: StoreRef; + readonly generatorRef?: GeneratorRef; +} + +export interface StoreRef { + readonly name: string; + readonly kind: string; +} + +export interface GeneratorRef { + readonly apiVersion: string; + readonly kind: string; + readonly name: string; +} + export interface ExternalSecretData { readonly secretKey: string; - readonly remoteRef: ExternalSecretDataRemoteRef; + readonly remoteRef?: ExternalSecretDataRemoteRef; + readonly sourceRef?: SourceRef; } export interface ExternalSecretDataRemoteRef { @@ -59,6 +76,7 @@ export interface ExternalSecretDataRemoteRef { } export interface ExternalSecretDataFromRemoteRef { + readonly sourceRef?: SourceRef; readonly extract?: ExternalSecretDataRemoteRef; readonly find?: ExternalSecretFind; readonly rewrite?: ExternalSecretRewrite[]; @@ -86,9 +104,10 @@ export interface FindName { } export interface ExternalSecretSpec { - readonly secretStoreRef: SecretStoreRef; + readonly secretStoreRef?: SecretStoreRef; readonly target?: ExternalSecretTarget; readonly refreshInterval?: string; + readonly refreshPolicy?: 'CreatedOnce' | 'Periodic' | 'OnChange'; readonly data?: ExternalSecretData[]; readonly dataFrom?: ExternalSecretDataFromRemoteRef[]; } @@ -122,3 +141,30 @@ export class ExternalSecretV1Beta1 extends ApiObject { super(scope, id, ExternalSecretV1Beta1.manifest(props)); } } + +export class ExternalSecretV1 extends ApiObject { + public static readonly GVK: GroupVersionKind = { + apiVersion: 'external-secrets.io/v1', + kind: 'ExternalSecret', + }; + /** + * @param props initialization props + */ + public static manifest(props: ExternalSecretProps): any { + return { + ...ExternalSecretV1.GVK, + ...props, + }; + } + + /** + * @param scope the scope in which to define this object + * @param id a scope-local name for the object + * @param props initialization props + */ + public constructor(scope: Construct, id: string, props: ExternalSecretProps) { + super(scope, id, ExternalSecretV1.manifest(props)); + } +} + +export const ExternalSecret = ExternalSecretV1; diff --git a/test/__snapshots__/hello.test.ts.snap b/test/__snapshots__/hello.test.ts.snap index 9a501fe..3207651 100644 --- a/test/__snapshots__/hello.test.ts.snap +++ b/test/__snapshots__/hello.test.ts.snap @@ -1,12 +1,95 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`hello 1`] = ` +exports[`ExternalSecret (default v1) 1`] = ` +Array [ + Object { + "apiVersion": "external-secrets.io/v1", + "kind": "ExternalSecret", + "metadata": Object { + "name": "test-default", + }, + "spec": Object { + "dataFrom": Array [ + Object { + "extract": Object { + "key": "all-keys-example-secret", + }, + }, + ], + "refreshInterval": "1h", + "secretStoreRef": Object { + "kind": "SecretStore", + "name": "example", + }, + "target": Object { + "creationPolicy": "Owner", + "name": "secret-to-be-created", + }, + }, + }, +] +`; + +exports[`ExternalSecret v1 1`] = ` +Array [ + Object { + "apiVersion": "external-secrets.io/v1", + "kind": "ExternalSecret", + "metadata": Object { + "name": "test-v1", + }, + "spec": Object { + "data": Array [ + Object { + "remoteRef": Object { + "key": "secret/data/database", + "property": "username", + }, + "secretKey": "api-key", + "sourceRef": Object { + "storeRef": Object { + "kind": "SecretStore", + "name": "vault-backend", + }, + }, + }, + ], + "dataFrom": Array [ + Object { + "extract": Object { + "key": "all-keys-example-secret", + }, + "sourceRef": Object { + "generatorRef": Object { + "apiVersion": "generators.external-secrets.io/v1alpha1", + "kind": "Password", + "name": "password-generator", + }, + }, + }, + ], + "refreshInterval": "1h", + "refreshPolicy": "Periodic", + "secretStoreRef": Object { + "kind": "SecretStore", + "name": "example", + }, + "target": Object { + "creationPolicy": "Owner", + "name": "secret-to-be-created", + }, + }, + }, +] +`; + +exports[`ExternalSecret v1beta1 1`] = ` Array [ Object { "apiVersion": "external-secrets.io/v1beta1", "kind": "ExternalSecret", "metadata": Object { - "name": "test", + "name": "test-v1beta1", }, "spec": Object { "dataFrom": Array [ diff --git a/test/hello.test.ts b/test/hello.test.ts index 6e6c801..a961cf2 100644 --- a/test/hello.test.ts +++ b/test/hello.test.ts @@ -1,11 +1,12 @@ import { Testing, Chart } from 'cdk8s'; import * as t from '../src/index'; -test('hello', () => { + +test('ExternalSecret v1beta1', () => { const app = Testing.app(); - const chart = new Chart(app, 'test'); - new t.ExternalSecretV1Beta1(chart, 'test', { + const chart = new Chart(app, 'test-v1beta1'); + new t.ExternalSecretV1Beta1(chart, 'test-v1beta1', { metadata: { - name: 'test', + name: 'test-v1beta1', }, spec: { refreshInterval: '1h', @@ -27,6 +28,88 @@ test('hello', () => { }, }); + expect(Testing.synth(chart)).toMatchSnapshot(); +}); + +test('ExternalSecret v1', () => { + const app = Testing.app(); + const chart = new Chart(app, 'test-v1'); + new t.ExternalSecretV1(chart, 'test-v1', { + metadata: { + name: 'test-v1', + }, + spec: { + refreshInterval: '1h', + refreshPolicy: 'Periodic', + secretStoreRef: { + kind: 'SecretStore', + name: 'example', + }, + target: { + name: 'secret-to-be-created', + creationPolicy: 'Owner', + }, + data: [ + { + secretKey: 'api-key', + sourceRef: { + storeRef: { + name: 'vault-backend', + kind: 'SecretStore', + }, + }, + remoteRef: { + key: 'secret/data/database', + property: 'username', + }, + }, + ], + dataFrom: [ + { + sourceRef: { + generatorRef: { + apiVersion: 'generators.external-secrets.io/v1alpha1', + kind: 'Password', + name: 'password-generator', + }, + }, + extract: { + key: 'all-keys-example-secret', + }, + }, + ], + }, + }); + + expect(Testing.synth(chart)).toMatchSnapshot(); +}); + +test('ExternalSecret (default v1)', () => { + const app = Testing.app(); + const chart = new Chart(app, 'test-default'); + new t.ExternalSecret(chart, 'test-default', { + metadata: { + name: 'test-default', + }, + spec: { + refreshInterval: '1h', + secretStoreRef: { + kind: 'SecretStore', + name: 'example', + }, + target: { + name: 'secret-to-be-created', + creationPolicy: 'Owner', + }, + dataFrom: [ + { + extract: { + key: 'all-keys-example-secret', + }, + }, + ], + }, + }); expect(Testing.synth(chart)).toMatchSnapshot(); });