@codemowers/oidc-key-manager 1.0.0 → 1.1.1
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 +16 -12
- package/dist/commands/initialize.d.ts +1 -0
- package/dist/commands/initialize.js +3 -2
- package/dist/commands/rotate.d.ts +1 -0
- package/dist/commands/rotate.js +2 -3
- package/dist/helpers/common-flags.d.ts +1 -0
- package/dist/helpers/common-flags.js +1 -0
- package/dist/helpers/kube-api-service.d.ts +2 -2
- package/dist/helpers/kube-api-service.js +9 -5
- package/dist/helpers/secret.d.ts +1 -1
- package/dist/helpers/secret.js +6 -3
- package/oclif.manifest.json +27 -2
- package/package.json +1 -1
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.
|
|
17
|
+
@codemowers/oidc-key-manager/1.1.1 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>
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
|
|
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.
|
|
63
|
+
_See code: [src/commands/initialize.ts](https://github.com/codemowers/oidc-key-manager/blob/v1.1.1/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>] [
|
|
69
|
-
[--max-number-of-jwks <value>] [--max-number-of-cookie-keys <value>] [--restart-deployment-backoff
|
|
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.
|
|
96
|
+
_See code: [src/commands/rotate.ts](https://github.com/codemowers/oidc-key-manager/blob/v1.1.1/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
|
-
|
|
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>;
|
package/dist/commands/rotate.js
CHANGED
|
@@ -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,19 @@ 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
|
-
|
|
88
|
+
try {
|
|
89
|
+
await this.coreV1Api.createNamespacedSecret(this.namespace, secret.toKubeSecret(this.secretName, labels));
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error(error);
|
|
93
|
+
}
|
|
90
94
|
this.command.log(`Created secret ${this.secretName}`);
|
|
91
95
|
}
|
|
92
|
-
async replaceSecret(secret) {
|
|
96
|
+
async replaceSecret(secret, labels) {
|
|
93
97
|
this.command.log(`Replacing secret ${this.secretName}`);
|
|
94
|
-
await this.coreV1Api.replaceNamespacedSecret(this.secretName, this.namespace, secret.toKubeSecret(this.secretName));
|
|
98
|
+
await this.coreV1Api.replaceNamespacedSecret(this.secretName, this.namespace, secret.toKubeSecret(this.secretName, labels));
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
101
|
exports.KubeApiService = KubeApiService;
|
package/dist/helpers/secret.d.ts
CHANGED
|
@@ -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;
|
package/dist/helpers/secret.js
CHANGED
|
@@ -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
|
};
|
package/oclif.manifest.json
CHANGED
|
@@ -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.
|
|
229
|
+
"version": "1.1.1"
|
|
205
230
|
}
|