@codemowers/oidc-key-manager 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,7 +14,7 @@ $ npm install -g @codemowers/oidc-key-manager
14
14
  $ key-manager COMMAND
15
15
  running command...
16
16
  $ key-manager (--version)
17
- @codemowers/oidc-key-manager/1.0.0 linux-x64 node-v20.12.0
17
+ @codemowers/oidc-key-manager/1.1.0 linux-x64 node-v22.17.1
18
18
  $ key-manager --help [COMMAND]
19
19
  USAGE
20
20
  $ key-manager COMMAND
@@ -32,14 +32,15 @@ Initialize the secret with initial keys
32
32
 
33
33
  ```
34
34
  USAGE
35
- $ key-manager initialize -c local|cluster [--json] [-n <value>] [-s <value>] [--recreate]
35
+ $ key-manager initialize -c local|cluster [--json] [-n <value>] [-s <value>] [-l <value>] [--recreate]
36
36
 
37
37
  FLAGS
38
- -c, --config=<option> (required) use local or in-cluster Kubernetes config
39
- <options: local|cluster>
40
- -n, --namespace=<value> namespace, defaults to current namespace if service account is used
41
- -s, --secret=<value> [default: oidc-keys] secret name
42
- --recreate recreate the secret if it exists
38
+ -c, --config=<option> (required) use local or in-cluster Kubernetes config
39
+ <options: local|cluster>
40
+ -l, --additionalLabel=<value>... Add custom Kubernetes label (may be repeated)
41
+ -n, --namespace=<value> namespace, defaults to current namespace if service account is used
42
+ -s, --secret=<value> [default: oidc-keys] secret name
43
+ --recreate recreate the secret if it exists
43
44
 
44
45
  GLOBAL FLAGS
45
46
  --json Format output as json.
@@ -55,9 +56,11 @@ EXAMPLES
55
56
  $ key-manager initialize -n <kube namespace> -s <secret name>
56
57
 
57
58
  $ key-manager initialize --namespace <kube namespace> --secret <secret name> --recreate
59
+
60
+ $ key-manager initialize --additional-label "app.kubernetes.io/instance: passmower"
58
61
  ```
59
62
 
60
- _See code: [src/commands/initialize.ts](https://github.com/codemowers/oidc-key-manager/blob/v1.0.0/src/commands/initialize.ts)_
63
+ _See code: [src/commands/initialize.ts](https://github.com/codemowers/oidc-key-manager/blob/v1.1.0/src/commands/initialize.ts)_
61
64
 
62
65
  ## `key-manager rotate`
63
66
 
@@ -65,13 +68,14 @@ Append new JWK|cookie key|both and rotate the array, optionally restarting the d
65
68
 
66
69
  ```
67
70
  USAGE
68
- $ key-manager rotate -c local|cluster [-n <value>] [-s <value>] [--both] [--jwks] [--cookie-keys]
69
- [--max-number-of-jwks <value>] [--max-number-of-cookie-keys <value>] [--restart-deployment-backoff <value>
70
- --restart-deployment <value>]
71
+ $ key-manager rotate -c local|cluster [-n <value>] [-s <value>] [-l <value>] [--both] [--jwks]
72
+ [--cookie-keys] [--max-number-of-jwks <value>] [--max-number-of-cookie-keys <value>] [--restart-deployment-backoff
73
+ <value> --restart-deployment <value>]
71
74
 
72
75
  FLAGS
73
76
  -c, --config=<option> (required) use local or in-cluster Kubernetes config
74
77
  <options: local|cluster>
78
+ -l, --additionalLabel=<value>... Add custom Kubernetes label (may be repeated)
75
79
  -n, --namespace=<value> namespace, defaults to current namespace if service account is used
76
80
  -s, --secret=<value> [default: oidc-keys] secret name
77
81
  --both rotate both JWKs and cookie keys
@@ -89,5 +93,5 @@ EXAMPLES
89
93
  $ key-manager rotate
90
94
  ```
91
95
 
92
- _See code: [src/commands/rotate.ts](https://github.com/codemowers/oidc-key-manager/blob/v1.0.0/src/commands/rotate.ts)_
96
+ _See code: [src/commands/rotate.ts](https://github.com/codemowers/oidc-key-manager/blob/v1.1.0/src/commands/rotate.ts)_
93
97
  <!-- commandsstop -->
@@ -8,6 +8,7 @@ export default class Initialize extends Command {
8
8
  namespace: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
9
  secret: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
10
  config: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ additionalLabel: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
12
  };
12
13
  static args: {};
13
14
  run(): Promise<void>;
@@ -12,7 +12,7 @@ class Initialize extends core_1.Command {
12
12
  kubeApiService.printConfiguration();
13
13
  const exists = await kubeApiService.getSecret();
14
14
  if (exists && !flags.recreate) {
15
- this.exit(0);
15
+ return;
16
16
  }
17
17
  if (exists) {
18
18
  await kubeApiService.deleteSecret();
@@ -20,7 +20,7 @@ class Initialize extends core_1.Command {
20
20
  const secret = new secret_1.Secret(this);
21
21
  this.log('Generating secret');
22
22
  secret.generateNew();
23
- await kubeApiService.createSecret(secret);
23
+ await kubeApiService.createSecret(secret, flags.additionalLabel);
24
24
  }
25
25
  }
26
26
  Initialize.description = 'Initialize the secret with initial keys';
@@ -30,6 +30,7 @@ Initialize.examples = [
30
30
  '<%= config.bin %> <%= command.id %>',
31
31
  '<%= config.bin %> <%= command.id %> -n <kube namespace> -s <secret name>',
32
32
  '<%= config.bin %> <%= command.id %> --namespace <kube namespace> --secret <secret name> --recreate',
33
+ '<%= config.bin %> <%= command.id %> --additional-label "app.kubernetes.io/instance: passmower"',
33
34
  ];
34
35
  Initialize.flags = {
35
36
  ...common_flags_1.default,
@@ -13,6 +13,7 @@ export default class Rotate extends Command {
13
13
  namespace: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
14
  secret: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
15
15
  config: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ additionalLabel: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
16
17
  };
17
18
  static args: {};
18
19
  run(): Promise<void>;
@@ -13,7 +13,6 @@ class Rotate extends core_1.Command {
13
13
  const kubeSecret = await kubeApiService.getSecret();
14
14
  if (!kubeSecret) {
15
15
  this.error('Secret does not exist');
16
- this.exit(1);
17
16
  }
18
17
  const secret = new secret_1.Secret(this);
19
18
  secret.fromKubeSecret(kubeSecret);
@@ -23,7 +22,7 @@ class Rotate extends core_1.Command {
23
22
  if (flags.both || flags['cookie-keys']) {
24
23
  secret.appendCookieKey(flags['max-number-of-cookie-keys']);
25
24
  }
26
- await kubeApiService.replaceSecret(secret);
25
+ await kubeApiService.replaceSecret(secret, flags.additionalLabel);
27
26
  let restarted = false;
28
27
  if (flags['restart-deployment']) {
29
28
  try {
@@ -41,7 +40,7 @@ class Rotate extends core_1.Command {
41
40
  if (flags.both || flags.jwks) {
42
41
  secret.rotateCookieKeys();
43
42
  }
44
- await kubeApiService.replaceSecret(secret);
43
+ await kubeApiService.replaceSecret(secret, flags.additionalLabel);
45
44
  if (flags['restart-deployment']) {
46
45
  try {
47
46
  await kubeApiService.restartDeployment(flags['restart-deployment'], flags['restart-deployment-backoff']);
@@ -11,5 +11,6 @@ declare const _default: {
11
11
  namespace: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
12
  secret: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
13
13
  config: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ additionalLabel: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
15
  };
15
16
  export default _default;
@@ -11,4 +11,5 @@ exports.default = {
11
11
  namespace: core_1.Flags.string({ char: 'n', description: 'namespace, defaults to current namespace if service account is used', aliases: ['namespace'], required: false }),
12
12
  secret: core_1.Flags.string({ char: 's', description: 'secret name', aliases: ['secret'], default: 'oidc-keys', required: false }),
13
13
  config: core_1.Flags.string({ char: 'c', description: 'use local or in-cluster Kubernetes config', aliases: ['config'], required: true, options: [ConfigType.Local, ConfigType.InCluster] }),
14
+ additionalLabel: core_1.Flags.string({ char: 'l', description: 'Add custom Kubernetes label (may be repeated)', aliases: ['additional-label'], required: false, multiple: true }),
14
15
  };
@@ -15,6 +15,6 @@ export declare class KubeApiService {
15
15
  restartDeployment(deploymentName: string, timeoutInSeconds: number): Promise<any>;
16
16
  getSecret(): Promise<V1Secret | undefined | null>;
17
17
  deleteSecret(): Promise<void>;
18
- createSecret(secret: Secret): Promise<void>;
19
- replaceSecret(secret: Secret): Promise<void>;
18
+ createSecret(secret: Secret, labels?: any): Promise<void>;
19
+ replaceSecret(secret: Secret, labels?: any): Promise<void>;
20
20
  }
@@ -72,7 +72,6 @@ class KubeApiService {
72
72
  .catch(error => {
73
73
  if (error.statusCode !== 404) {
74
74
  this.command.error(error);
75
- this.command.exit(1);
76
75
  }
77
76
  return null;
78
77
  });
@@ -84,14 +83,14 @@ class KubeApiService {
84
83
  await this.coreV1Api.deleteNamespacedSecret(this.secretName, this.namespace).then(() => true);
85
84
  this.command.log(`Existing secret ${this.secretName} deleted`);
86
85
  }
87
- async createSecret(secret) {
86
+ async createSecret(secret, labels) {
88
87
  this.command.log(`Creating secret ${this.secretName}`);
89
- await this.coreV1Api.createNamespacedSecret(this.namespace, secret.toKubeSecret(this.secretName));
88
+ await this.coreV1Api.createNamespacedSecret(this.namespace, secret.toKubeSecret(this.secretName, labels));
90
89
  this.command.log(`Created secret ${this.secretName}`);
91
90
  }
92
- async replaceSecret(secret) {
91
+ async replaceSecret(secret, labels) {
93
92
  this.command.log(`Replacing secret ${this.secretName}`);
94
- await this.coreV1Api.replaceNamespacedSecret(this.secretName, this.namespace, secret.toKubeSecret(this.secretName));
93
+ await this.coreV1Api.replaceNamespacedSecret(this.secretName, this.namespace, secret.toKubeSecret(this.secretName, labels));
95
94
  }
96
95
  }
97
96
  exports.KubeApiService = KubeApiService;
@@ -7,7 +7,7 @@ export declare class Secret {
7
7
  private command;
8
8
  constructor(command: Command);
9
9
  generateNew(): void;
10
- toKubeSecret(secretName: string): V1Secret;
10
+ toKubeSecret(secretName: string, labels?: any): V1Secret;
11
11
  fromKubeSecret(kubeSecret: V1Secret): void;
12
12
  appendJWK(maxNumber: number): void;
13
13
  appendCookieKey(maxNumber: number): void;
@@ -19,9 +19,9 @@ class Secret {
19
19
  this.JWKs = [tslib_1.__classPrivateFieldGet(this, _Secret_instances, "m", _Secret_generateRSAJwk).call(this, 4096)];
20
20
  this.CookieKeys = [tslib_1.__classPrivateFieldGet(this, _Secret_instances, "m", _Secret_generateCookieKey).call(this, 32)];
21
21
  }
22
- toKubeSecret(secretName) {
22
+ toKubeSecret(secretName, labels) {
23
23
  const secret = new client_node_1.V1Secret();
24
- secret.metadata = tslib_1.__classPrivateFieldGet(this, _Secret_instances, "m", _Secret_getKubeSecretMetadata).call(this, secretName);
24
+ secret.metadata = tslib_1.__classPrivateFieldGet(this, _Secret_instances, "m", _Secret_getKubeSecretMetadata).call(this, secretName, labels);
25
25
  secret.data = {};
26
26
  secret.data[JWKSKeyName] = tslib_1.__classPrivateFieldGet(this, _Secret_instances, "m", _Secret_arrayToB64String).call(this, this.JWKs);
27
27
  secret.data[CookieKeysKeyName] = tslib_1.__classPrivateFieldGet(this, _Secret_instances, "m", _Secret_arrayToB64String).call(this, this.CookieKeys);
@@ -73,8 +73,11 @@ _Secret_instances = new WeakSet(), _Secret_append = function _Secret_append(prop
73
73
  }, _Secret_arrayToB64String = function _Secret_arrayToB64String(array) {
74
74
  const b = Buffer.from(JSON.stringify(array));
75
75
  return b.toString('base64');
76
- }, _Secret_getKubeSecretMetadata = function _Secret_getKubeSecretMetadata(secretName) {
76
+ }, _Secret_getKubeSecretMetadata = function _Secret_getKubeSecretMetadata(secretName, labels) {
77
77
  const metaData = new client_node_1.V1ObjectMeta();
78
78
  metaData.name = secretName;
79
+ if (labels) {
80
+ metaData.labels = labels;
81
+ }
79
82
  return metaData;
80
83
  };
@@ -8,7 +8,8 @@
8
8
  "<%= config.bin %> <%= command.id %>",
9
9
  "<%= config.bin %> <%= command.id %>",
10
10
  "<%= config.bin %> <%= command.id %> -n <kube namespace> -s <secret name>",
11
- "<%= config.bin %> <%= command.id %> --namespace <kube namespace> --secret <secret name> --recreate"
11
+ "<%= config.bin %> <%= command.id %> --namespace <kube namespace> --secret <secret name> --recreate",
12
+ "<%= config.bin %> <%= command.id %> --additional-label \"app.kubernetes.io/instance: passmower\""
12
13
  ],
13
14
  "flags": {
14
15
  "json": {
@@ -59,6 +60,18 @@
59
60
  ],
60
61
  "type": "option"
61
62
  },
63
+ "additionalLabel": {
64
+ "aliases": [
65
+ "additional-label"
66
+ ],
67
+ "char": "l",
68
+ "description": "Add custom Kubernetes label (may be repeated)",
69
+ "name": "additionalLabel",
70
+ "required": false,
71
+ "hasDynamicHelp": false,
72
+ "multiple": true,
73
+ "type": "option"
74
+ },
62
75
  "recreate": {
63
76
  "aliases": [
64
77
  "recreate"
@@ -134,6 +147,18 @@
134
147
  ],
135
148
  "type": "option"
136
149
  },
150
+ "additionalLabel": {
151
+ "aliases": [
152
+ "additional-label"
153
+ ],
154
+ "char": "l",
155
+ "description": "Add custom Kubernetes label (may be repeated)",
156
+ "name": "additionalLabel",
157
+ "required": false,
158
+ "hasDynamicHelp": false,
159
+ "multiple": true,
160
+ "type": "option"
161
+ },
137
162
  "both": {
138
163
  "description": "rotate both JWKs and cookie keys",
139
164
  "name": "both",
@@ -201,5 +226,5 @@
201
226
  ]
202
227
  }
203
228
  },
204
- "version": "1.0.0"
229
+ "version": "1.1.0"
205
230
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemowers/oidc-key-manager",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "CLI to manage secret keys required by oidc-gateway",
5
5
  "author": "Erki Aas",
6
6
  "bin": {