From 213800477f73d1ffd3431eee5972e7838745a9ee Mon Sep 17 00:00:00 2001 From: Thomas Kirk Date: Thu, 27 Mar 2025 10:48:24 -0400 Subject: [PATCH] add --include-default-roles flag to `env export terraform` command --- .../env/export/generators/RoleGenerator.ts | 8 +++++-- source/commands/env/export/index.tsx | 11 ++++++++++ source/commands/env/export/types.ts | 1 + source/components/export/ExportContent.tsx | 7 ++++-- source/hooks/export/useExport.ts | 22 ++++++++++++++++--- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/source/commands/env/export/generators/RoleGenerator.ts b/source/commands/env/export/generators/RoleGenerator.ts index 9a1d3e8f..501c6fd0 100644 --- a/source/commands/env/export/generators/RoleGenerator.ts +++ b/source/commands/env/export/generators/RoleGenerator.ts @@ -71,6 +71,7 @@ export class RoleGenerator implements HCLGenerator { constructor( private permit: Permit, private warningCollector: WarningCollector, + private includeDefaultRoles: boolean = false, ) { // Register Handlebars helpers this.registerHandlebarsHelpers(); @@ -300,8 +301,11 @@ export class RoleGenerator implements HCLGenerator { const validRoles: RoleData[] = []; for (const role of roles) { - // Skip default global roles that already exist in the system - if (DEFAULT_GLOBAL_ROLES.includes(role.key)) { + // Skip default global roles that already exist in the system unless includeDefaultRoles is true + if ( + DEFAULT_GLOBAL_ROLES.includes(role.key) && + !this.includeDefaultRoles + ) { // Still add to the ID map for role derivations this.roleIdMap.set(role.key, role.key); continue; diff --git a/source/commands/env/export/index.tsx b/source/commands/env/export/index.tsx index 606dc838..6e0b8f16 100644 --- a/source/commands/env/export/index.tsx +++ b/source/commands/env/export/index.tsx @@ -23,6 +23,17 @@ export const options = zod.object({ alias: 'f', }), ), + includeDefaultRoles: zod + .boolean() + .optional() + .default(false) + .describe( + option({ + description: + 'Include default roles (admin, editor, viewer) in the export', + alias: 'i', + }), + ), }); type Props = { diff --git a/source/commands/env/export/types.ts b/source/commands/env/export/types.ts index 90955fd9..32a69c89 100644 --- a/source/commands/env/export/types.ts +++ b/source/commands/env/export/types.ts @@ -8,6 +8,7 @@ export interface ExportState { export interface ExportOptions { key?: string; file?: string; + includeDefaultRoles?: boolean; } export interface HCLGenerator { diff --git a/source/components/export/ExportContent.tsx b/source/components/export/ExportContent.tsx index 27f03510..9b6daeb0 100644 --- a/source/components/export/ExportContent.tsx +++ b/source/components/export/ExportContent.tsx @@ -9,12 +9,15 @@ import fs from 'node:fs/promises'; import { Text } from 'ink'; export const ExportContent: FC<{ options: ExportOptions }> = ({ - options: { key: apiKey, file }, + options: { key: apiKey, file, includeDefaultRoles }, }) => { const { validateApiKeyScope } = useApiKeyApi(); const { authToken } = useAuth(); const key = apiKey || authToken; - const { state, setState, exportConfig } = useExport(key); + const { state, setState, exportConfig } = useExport({ + apiKey: key, + includeDefaultRoles, + }); const [hclOutput, setHclOutput] = useState(null); const hasRunRef = useRef(false); diff --git a/source/hooks/export/useExport.ts b/source/hooks/export/useExport.ts index f3356a7f..e9bf4c33 100644 --- a/source/hooks/export/useExport.ts +++ b/source/hooks/export/useExport.ts @@ -51,7 +51,15 @@ type ExtendedRelationGenerator = Omit & { getRelationIdMap?: () => Map; }; -export const useExport = (apiKey: string) => { +interface UseExportProps { + apiKey?: string; + includeDefaultRoles?: boolean; +} + +export const useExport = ({ + apiKey, + includeDefaultRoles, +}: UseExportProps = {}) => { const [state, setState] = useState({ status: '', isComplete: false, @@ -59,10 +67,14 @@ export const useExport = (apiKey: string) => { warnings: [], }); - const permit = usePermitSDK(apiKey); + const permit = apiKey ? usePermitSDK(apiKey) : null; const exportConfig = async (scope: ExportScope) => { try { + if (!permit) { + throw new Error('No API key provided. Please provide a key or login first.'); + } + const warningCollector = createWarningCollector(); let hcl = `# Generated by Permit CLI @@ -73,7 +85,11 @@ ${generateProviderBlock()}`; // Create all generators first const resourceGenerator = new ResourceGenerator(permit, warningCollector); - const roleGenerator = new RoleGenerator(permit, warningCollector); + const roleGenerator = new RoleGenerator( + permit, + warningCollector, + includeDefaultRoles, + ); const userAttributesGenerator = new UserAttributesGenerator( permit, warningCollector,