@flowcore/cli-plugin-iam 1.5.0 → 1.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.6.0](https://github.com/flowcore-io/cli-plugin-iam/compare/v1.5.0...v1.6.0) (2025-02-16)
4
+
5
+
6
+ ### Features
7
+
8
+ * add edit role command to modify role details interactively ([d67eb3a](https://github.com/flowcore-io/cli-plugin-iam/commit/d67eb3a28d25ca7cac0683fb9aeb6f478386f8e8))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * :rotating_light: fixed linting errors ([7f481bd](https://github.com/flowcore-io/cli-plugin-iam/commit/7f481bd90bf67edfbd483dbd351b52ebba0d0bd2))
14
+
3
15
  ## [1.5.0](https://github.com/flowcore-io/cli-plugin-iam/compare/v1.4.0...v1.5.0) (2025-02-16)
4
16
 
5
17
 
package/README.md CHANGED
@@ -18,7 +18,7 @@ $ npm install -g @flowcore/cli-plugin-iam
18
18
  $ iam COMMAND
19
19
  running command...
20
20
  $ iam (--version)
21
- @flowcore/cli-plugin-iam/1.5.0 linux-x64 node-v20.16.0
21
+ @flowcore/cli-plugin-iam/1.6.0 linux-x64 node-v20.16.0
22
22
  $ iam --help [COMMAND]
23
23
  USAGE
24
24
  $ iam COMMAND
@@ -30,6 +30,7 @@ USAGE
30
30
  * [`iam delete policy NAME`](#iam-delete-policy-name)
31
31
  * [`iam delete role NAME`](#iam-delete-role-name)
32
32
  * [`iam edit policy NAME`](#iam-edit-policy-name)
33
+ * [`iam edit role NAME`](#iam-edit-role-name)
33
34
  * [`iam get policy [NAME]`](#iam-get-policy-name)
34
35
  * [`iam get role [NAME]`](#iam-get-role-name)
35
36
 
@@ -54,7 +55,7 @@ DESCRIPTION
54
55
  Delete a policy
55
56
  ```
56
57
 
57
- _See code: [src/commands/delete/policy.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.5.0/src/commands/delete/policy.ts)_
58
+ _See code: [src/commands/delete/policy.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.6.0/src/commands/delete/policy.ts)_
58
59
 
59
60
  ## `iam delete role NAME`
60
61
 
@@ -77,7 +78,7 @@ DESCRIPTION
77
78
  Delete a role
78
79
  ```
79
80
 
80
- _See code: [src/commands/delete/role.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.5.0/src/commands/delete/role.ts)_
81
+ _See code: [src/commands/delete/role.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.6.0/src/commands/delete/role.ts)_
81
82
 
82
83
  ## `iam edit policy NAME`
83
84
 
@@ -103,7 +104,33 @@ EXAMPLES
103
104
  $ FC_EDITOR=code flowcore iam edit policy my-policy -t my-tenant
104
105
  ```
105
106
 
106
- _See code: [src/commands/edit/policy.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.5.0/src/commands/edit/policy.ts)_
107
+ _See code: [src/commands/edit/policy.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.6.0/src/commands/edit/policy.ts)_
108
+
109
+ ## `iam edit role NAME`
110
+
111
+ Edit a role in your preferred editor
112
+
113
+ ```
114
+ USAGE
115
+ $ iam edit role NAME -t <value> [--profile <value>]
116
+
117
+ ARGUMENTS
118
+ NAME name
119
+
120
+ FLAGS
121
+ -t, --tenant=<value> (required) tenant
122
+ --profile=<value> Specify the configuration profile to use
123
+
124
+ DESCRIPTION
125
+ Edit a role in your preferred editor
126
+
127
+ EXAMPLES
128
+ $ flowcore iam edit role my-role -t my-tenant
129
+
130
+ $ FC_EDITOR=code flowcore iam edit role my-role -t my-tenant
131
+ ```
132
+
133
+ _See code: [src/commands/edit/role.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.6.0/src/commands/edit/role.ts)_
107
134
 
108
135
  ## `iam get policy [NAME]`
109
136
 
@@ -126,7 +153,7 @@ DESCRIPTION
126
153
  Get a policy
127
154
  ```
128
155
 
129
- _See code: [src/commands/get/policy.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.5.0/src/commands/get/policy.ts)_
156
+ _See code: [src/commands/get/policy.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.6.0/src/commands/get/policy.ts)_
130
157
 
131
158
  ## `iam get role [NAME]`
132
159
 
@@ -149,5 +176,5 @@ DESCRIPTION
149
176
  Get a role
150
177
  ```
151
178
 
152
- _See code: [src/commands/get/role.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.5.0/src/commands/get/role.ts)_
179
+ _See code: [src/commands/get/role.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.6.0/src/commands/get/role.ts)_
153
180
  <!-- commandsstop -->
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from "@flowcore/cli-plugin-config";
2
+ export declare const EDIT_ROLE_ARGS: {
3
+ NAME: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
4
+ };
5
+ export default class EditRole extends BaseCommand<typeof EditRole> {
6
+ static args: {
7
+ NAME: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
8
+ };
9
+ static description: string;
10
+ static examples: string[];
11
+ static flags: {
12
+ tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<void>;
15
+ private spawnEditor;
16
+ }
@@ -0,0 +1,115 @@
1
+ import { BaseCommand, ValidateLogin } from "@flowcore/cli-plugin-config";
2
+ import { ClientFactory } from "@flowcore/cli-plugin-core";
3
+ import { Args, Flags } from "@oclif/core";
4
+ import { spawn } from "node:child_process";
5
+ import { unlink, writeFile } from "node:fs/promises";
6
+ import { tmpdir } from "node:os";
7
+ import { join } from "node:path";
8
+ import { tryit } from "radash";
9
+ import { v4 as uuidv4 } from "uuid";
10
+ import { OrganizationService } from "../../services/organization.service.js";
11
+ import { Api as IamApi } from "../../utils/clients/iam/Api.js";
12
+ export const EDIT_ROLE_ARGS = {
13
+ NAME: Args.string({ description: "name", required: true }),
14
+ };
15
+ export default class EditRole extends BaseCommand {
16
+ static args = EDIT_ROLE_ARGS;
17
+ static description = "Edit a role in your preferred editor";
18
+ static examples = [
19
+ "$ flowcore iam edit role my-role -t my-tenant",
20
+ "$ FC_EDITOR=code flowcore iam edit role my-role -t my-tenant",
21
+ ];
22
+ static flags = {
23
+ tenant: Flags.string({
24
+ char: "t",
25
+ description: "tenant",
26
+ required: true,
27
+ }),
28
+ };
29
+ async run() {
30
+ const { args, flags } = await this.parse(EditRole);
31
+ const graphqlClient = await ClientFactory.create(this.cliConfiguration, this.logger);
32
+ const organizationService = new OrganizationService(graphqlClient);
33
+ const organizations = await organizationService.getMyOrganizations();
34
+ const iamClient = new IamApi();
35
+ const config = this.cliConfiguration.getConfig();
36
+ const login = new ValidateLogin(config.login.url);
37
+ await login.validate(config, this.cliConfiguration, true);
38
+ const { auth } = config;
39
+ if (!auth?.accessToken) {
40
+ this.logger.fatal("Not logged in, run 'flowcore login'");
41
+ }
42
+ const organization = organizations.me.organizations.find((org) => org.organization.org === flags.tenant);
43
+ if (!organization) {
44
+ this.logger.fatal(`Organization ${flags.tenant} not found, or you are not a member`);
45
+ }
46
+ const [rolesErr, roles] = await tryit(iamClient.getApiV1RoleAssociationsOrganizationByOrganizationId)(organization.organization.id, {
47
+ headers: {
48
+ Authorization: `Bearer ${auth?.accessToken}`,
49
+ },
50
+ });
51
+ if (rolesErr) {
52
+ this.logger.fatal(`Failed to get roles: ${rolesErr.message}`);
53
+ }
54
+ const role = roles.data.find((role) => role.name === args.NAME);
55
+ if (!role) {
56
+ this.logger.fatal(`Role ${args.NAME} not found in tenant: ${flags.tenant}`);
57
+ }
58
+ // Create a temporary file with the role content
59
+ const tmpFile = join(tmpdir(), `role-${uuidv4()}.json`);
60
+ const roleContent = JSON.stringify({
61
+ description: role.description,
62
+ name: role.name,
63
+ }, null, 2);
64
+ try {
65
+ await writeFile(tmpFile, roleContent, "utf8");
66
+ await this.spawnEditor(tmpFile);
67
+ // Read and parse the edited content
68
+ const editedContent = await import(tmpFile, {
69
+ assert: { type: "json" },
70
+ });
71
+ // Update the role
72
+ const [updateErr] = await tryit(iamClient.patchApiV1RolesById)(role.id, {
73
+ description: editedContent.default.description,
74
+ id: role.id,
75
+ name: editedContent.default.name,
76
+ organizationId: organization.organization.id,
77
+ }, {
78
+ headers: {
79
+ Authorization: `Bearer ${auth?.accessToken}`,
80
+ },
81
+ });
82
+ if (updateErr) {
83
+ this.logger.fatal(`Failed to update role: ${updateErr.message}`);
84
+ }
85
+ this.logger.info(`Role ${role.name} updated successfully`);
86
+ }
87
+ catch (error) {
88
+ this.logger.fatal(`Error editing role: ${error}`);
89
+ }
90
+ finally {
91
+ await unlink(tmpFile).catch(() => {
92
+ // Ignore error if file doesn't exist
93
+ });
94
+ }
95
+ }
96
+ async spawnEditor(filePath) {
97
+ return new Promise((resolve, reject) => {
98
+ const editor = process.env.FC_EDITOR || process.env.EDITOR || "vim";
99
+ const child = spawn(editor, [filePath], {
100
+ stdio: "inherit",
101
+ });
102
+ child.on("exit", (code) => {
103
+ if (code === 0) {
104
+ resolve();
105
+ }
106
+ else {
107
+ reject(new Error(`Editor process exited with code ${code}`));
108
+ }
109
+ });
110
+ child.on("error", (err) => {
111
+ reject(err);
112
+ });
113
+ });
114
+ }
115
+ }
@@ -1,5 +1,101 @@
1
1
  {
2
2
  "commands": {
3
+ "edit:policy": {
4
+ "aliases": [],
5
+ "args": {
6
+ "NAME": {
7
+ "description": "name",
8
+ "name": "NAME",
9
+ "required": true
10
+ }
11
+ },
12
+ "description": "Edit a policy in your preferred editor",
13
+ "examples": [
14
+ "$ flowcore iam edit policy my-policy -t my-tenant",
15
+ "$ FC_EDITOR=code flowcore iam edit policy my-policy -t my-tenant"
16
+ ],
17
+ "flags": {
18
+ "profile": {
19
+ "description": "Specify the configuration profile to use",
20
+ "name": "profile",
21
+ "hasDynamicHelp": false,
22
+ "multiple": false,
23
+ "type": "option"
24
+ },
25
+ "tenant": {
26
+ "char": "t",
27
+ "description": "tenant",
28
+ "name": "tenant",
29
+ "required": true,
30
+ "hasDynamicHelp": false,
31
+ "multiple": false,
32
+ "type": "option"
33
+ }
34
+ },
35
+ "hasDynamicHelp": false,
36
+ "hiddenAliases": [],
37
+ "id": "edit:policy",
38
+ "pluginAlias": "@flowcore/cli-plugin-iam",
39
+ "pluginName": "@flowcore/cli-plugin-iam",
40
+ "pluginType": "core",
41
+ "strict": true,
42
+ "enableJsonFlag": false,
43
+ "isESM": true,
44
+ "relativePath": [
45
+ "dist",
46
+ "commands",
47
+ "edit",
48
+ "policy.js"
49
+ ]
50
+ },
51
+ "edit:role": {
52
+ "aliases": [],
53
+ "args": {
54
+ "NAME": {
55
+ "description": "name",
56
+ "name": "NAME",
57
+ "required": true
58
+ }
59
+ },
60
+ "description": "Edit a role in your preferred editor",
61
+ "examples": [
62
+ "$ flowcore iam edit role my-role -t my-tenant",
63
+ "$ FC_EDITOR=code flowcore iam edit role my-role -t my-tenant"
64
+ ],
65
+ "flags": {
66
+ "profile": {
67
+ "description": "Specify the configuration profile to use",
68
+ "name": "profile",
69
+ "hasDynamicHelp": false,
70
+ "multiple": false,
71
+ "type": "option"
72
+ },
73
+ "tenant": {
74
+ "char": "t",
75
+ "description": "tenant",
76
+ "name": "tenant",
77
+ "required": true,
78
+ "hasDynamicHelp": false,
79
+ "multiple": false,
80
+ "type": "option"
81
+ }
82
+ },
83
+ "hasDynamicHelp": false,
84
+ "hiddenAliases": [],
85
+ "id": "edit:role",
86
+ "pluginAlias": "@flowcore/cli-plugin-iam",
87
+ "pluginName": "@flowcore/cli-plugin-iam",
88
+ "pluginType": "core",
89
+ "strict": true,
90
+ "enableJsonFlag": false,
91
+ "isESM": true,
92
+ "relativePath": [
93
+ "dist",
94
+ "commands",
95
+ "edit",
96
+ "role.js"
97
+ ]
98
+ },
3
99
  "delete:policy": {
4
100
  "aliases": [],
5
101
  "args": {
@@ -243,55 +339,7 @@
243
339
  "get",
244
340
  "role.js"
245
341
  ]
246
- },
247
- "edit:policy": {
248
- "aliases": [],
249
- "args": {
250
- "NAME": {
251
- "description": "name",
252
- "name": "NAME",
253
- "required": true
254
- }
255
- },
256
- "description": "Edit a policy in your preferred editor",
257
- "examples": [
258
- "$ flowcore iam edit policy my-policy -t my-tenant",
259
- "$ FC_EDITOR=code flowcore iam edit policy my-policy -t my-tenant"
260
- ],
261
- "flags": {
262
- "profile": {
263
- "description": "Specify the configuration profile to use",
264
- "name": "profile",
265
- "hasDynamicHelp": false,
266
- "multiple": false,
267
- "type": "option"
268
- },
269
- "tenant": {
270
- "char": "t",
271
- "description": "tenant",
272
- "name": "tenant",
273
- "required": true,
274
- "hasDynamicHelp": false,
275
- "multiple": false,
276
- "type": "option"
277
- }
278
- },
279
- "hasDynamicHelp": false,
280
- "hiddenAliases": [],
281
- "id": "edit:policy",
282
- "pluginAlias": "@flowcore/cli-plugin-iam",
283
- "pluginName": "@flowcore/cli-plugin-iam",
284
- "pluginType": "core",
285
- "strict": true,
286
- "enableJsonFlag": false,
287
- "isESM": true,
288
- "relativePath": [
289
- "dist",
290
- "commands",
291
- "edit",
292
- "policy.js"
293
- ]
294
342
  }
295
343
  },
296
- "version": "1.5.0"
344
+ "version": "1.6.0"
297
345
  }
package/package.json CHANGED
@@ -91,7 +91,7 @@
91
91
  "version": "oclif readme && git add README.md",
92
92
  "update-schema": "rover graph introspect https://graph.api.flowcore.io/graphql -o schema.gql"
93
93
  },
94
- "version": "1.5.0",
94
+ "version": "1.6.0",
95
95
  "bugs": "https://github.com/flowcore-io/cli-plugin-iam/issues",
96
96
  "keywords": [
97
97
  "oclif"