Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
} from './cli/FrodoCommand';
import idm from './cli/idm/idm';
import idp from './cli/idp/idp';
import iga from './cli/iga/iga';
import info from './cli/info/info';
import journey from './cli/journey/journey';
import log from './cli/log/log';
Expand Down Expand Up @@ -90,6 +91,7 @@ process.argv = normalizeExpandedHelpArgv(process.argv);
program.addCommand(esv());
program.addCommand(idm());
program.addCommand(idp());
program.addCommand(iga());
program.addCommand(info());
program.addCommand(journey());
program.addCommand(log());
Expand Down
16 changes: 7 additions & 9 deletions src/cli/FrodoCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,15 +388,13 @@ function decorateDescriptionWithStability(
*/
function cloneOption(option: Option): Option {
const cloned = Object.assign(new Option(option.flags, option.description), {
defaultValue: option.defaultValue,
defaultValueDescription: option.defaultValueDescription,
presetArg: option.presetArg,
envVar: option.envVar,
parseArg: option.parseArg,
hidden: option.hidden,
mandatory: option.mandatory,
argChoices: option.argChoices ? [...option.argChoices] : option.argChoices,
helpGroupHeading: option.helpGroupHeading,
...option,
// @ts-expect-error: CommanderJS Typings needs an update for node_modules to recognize conflictsWith
conflictsWith: option.conflictsWith
? // @ts-expect-error: Linter will do this and ts-expect-error cant be multi line.
[...option.conflictsWith]
: // @ts-expect-error: Linter will do this and ts-expect-error cant be multi line.
option.conflictsWith,
});

setStabilityMetadata(cloned, getStabilityMetadata(option));
Expand Down
8 changes: 8 additions & 0 deletions src/cli/config/config-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ export default function setup() {
'Export managed.idm.json objects separately in their own directory. Ignored with -a.'
)
)
.addOption(
new Option(
'-c, --only-custom',
'Only export custom request types (IGA cloud deployments only).'
)
)
.addOption(
new Option(
'--include-active-values',
Expand Down Expand Up @@ -170,6 +176,7 @@ export default function setup() {
includeReadOnly: options.readOnly,
onlyRealm: options.realmOnly,
onlyGlobal: options.globalOnly,
onlyCustom: options.onlyCustom
}
);
if (!outcome) process.exitCode = 1;
Expand Down Expand Up @@ -202,6 +209,7 @@ export default function setup() {
includeReadOnly: options.readOnly,
onlyRealm: options.realmOnly,
onlyGlobal: options.globalOnly,
onlyCustom: options.onlyCustom
}
);
if (!outcome) process.exitCode = 1;
Expand Down
9 changes: 9 additions & 0 deletions src/cli/config/config-import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ export default function setup() {
'Import all scripts including the default scripts.'
)
)
.addOption(
new Option(
'-c, --only-custom',
'Only import custom request types (IGA cloud deployments only).'
)
)
.addOption(
new Option(
'--include-active-values',
Expand Down Expand Up @@ -129,6 +135,7 @@ export default function setup() {
includeDefault: options.default,
includeActiveValues: options.includeActiveValues,
source: options.source,
onlyCustom: options.onlyCustom
});
if (!outcome) process.exitCode = 1;
}
Expand All @@ -152,6 +159,7 @@ export default function setup() {
includeDefault: options.default,
includeActiveValues: options.includeActiveValues,
source: options.source,
onlyCustom: options.onlyCustom
});
if (!outcome) process.exitCode = 1;
}
Expand All @@ -169,6 +177,7 @@ export default function setup() {
includeDefault: options.default,
includeActiveValues: options.includeActiveValues,
source: options.source,
onlyCustom: options.onlyCustom
}
);
if (!outcome) process.exitCode = 1;
Expand Down
116 changes: 116 additions & 0 deletions src/cli/iga/glossary/iga-glossary-delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { frodo, state } from '@rockcarver/frodo-lib';
import { GlossaryObjectType } from '@rockcarver/frodo-lib/types/api/cloud/iga/IgaGlossaryApi';
import { Option } from 'commander';

import { getTokens } from '../../../ops/AuthenticateOps';
import {
deleteGlossarySchema,
deleteGlossarySchemas,
} from '../../../ops/cloud/iga/IgaGlossaryOps';
import { printMessage, verboseMessage } from '../../../utils/Console.js';
import { FrodoCommand } from '../../FrodoCommand';

const { CLOUD_DEPLOYMENT_TYPE_KEY } = frodo.utils.constants;

const deploymentTypes = [CLOUD_DEPLOYMENT_TYPE_KEY];

const glossaryTypeMap: Record<string, GlossaryObjectType> = {
role: '/openidm/managed/role',
entitlement: '/openidm/managed/assignment',
application: '/openidm/managed/application',
account: '/iga/governance/account',
};

export default function setup() {
const program = new FrodoCommand('frodo iga glossary delete');

program
.description('Delete glossaries.')
.addOption(
new Option(
'-i, --glossary-id <glossary-id>',
'glossary id. If specified, -n and -a cannot be used. '
).conflicts(['glossaryName', 'all'])
)
.addOption(
new Option(
'-n, --glossary-name <glossary-name>',
'Specify a glossary name. If specified, -i cannot be used.'
).conflicts(['glossaryId'])
)
.addOption(
new Option(
'-a, --all',
'Delete all glossaries. Cannot be used with -a and -i.'
).conflicts(['glossaryName', 'glossaryId'])
)
.addOption(
new Option(
'-t, --glossary-type <type>',
'Filter glossary schema by type: role, entitlement, application, or account'
)
)
.action(
// implement command logic inside action handler
async (host, realm, user, password, options, command) => {
command.handleDefaultArgsAndOpts(
host,
realm,
user,
password,
options,
command
);
if (!options.glossaryId && !options.glossaryName && !options.all) {
printMessage(
'Unrecognized combination of options or no options...',
'error'
);
process.exitCode = 1;
program.help();
}
const getTokensIsSuccessful = await getTokens(
false,
true,
deploymentTypes
);
if (!getTokensIsSuccessful) process.exit(1);
if (!state.getIsIGA()) {
printMessage(
'Command not supported for non-IGA cloud tenants',
'error'
);
process.exit(1);
}
const objectType = options.glossaryType
? glossaryTypeMap[options.glossaryType]
: null;

if (options.glossaryType && !objectType) {
printMessage('Please provide a valid Object Type', 'error');
process.exitCode = 1;
program.help();
}

// delete by id
if (options.glossaryId || options.glossaryName) {
verboseMessage('Deleting glossary...');
const outcome = await deleteGlossarySchema(
options.glossaryId,
options.glossaryName,
objectType
);
if (!outcome) process.exitCode = 1;
}
// --all -a
else if (options.all) {
verboseMessage('Deleting all glossaries...');
const outcome = await deleteGlossarySchemas(objectType);
if (!outcome) process.exitCode = 1;
}
}
// end command logic inside action handler
);

return program;
}
102 changes: 102 additions & 0 deletions src/cli/iga/glossary/iga-glossary-describe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { frodo, state } from '@rockcarver/frodo-lib';
import { GlossaryObjectType } from '@rockcarver/frodo-lib/types/api/cloud/iga/IgaGlossaryApi';
import { Option } from 'commander';

import { getTokens } from '../../../ops/AuthenticateOps';
import { describeGlossary } from '../../../ops/cloud/iga/IgaGlossaryOps';
import { printMessage, verboseMessage } from '../../../utils/Console';
import { FrodoCommand } from '../../FrodoCommand';

const { CLOUD_DEPLOYMENT_TYPE_KEY } = frodo.utils.constants;

const deploymentTypes = [CLOUD_DEPLOYMENT_TYPE_KEY];

const glossaryTypeMap: Record<string, GlossaryObjectType> = {
role: '/openidm/managed/role',
entitlement: '/openidm/managed/assignment',
application: '/openidm/managed/application',
account: '/iga/governance/account',
};

export default function setup() {
const program = new FrodoCommand('frodo iga glossary describe');

program
.description('Describe glossaries.')
.addOption(
new Option(
'-i, --glossary-id <glossary-id>',
'glossary id. If not specified, will describe first glossary in the provided export file.'
).conflicts(['glossaryName'])
)
.addOption(
new Option(
'-n, --glossary-name <glossary-name>',
'Specify a glossary name. If specified, -i cannot be used.'
).conflicts(['glossaryId'])
)
.addOption(
new Option(
'-f, --file <file>',
'Name of the glossary export file to describe. If not specified, will automatically pull the glossary export data of the provided id from the tenant.'
)
)
.addOption(
new Option(
'-t, --glossary-type <type>',
'Filter glossary schema by type: role, entitlement, application, or account'
)
)
.action(async (host, realm, user, password, options, command) => {
command.handleDefaultArgsAndOpts(
host,
realm,
user,
password,
options,
command
);
if (!options.glossaryId && !options.glossaryName && !options.file) {
printMessage(
'Unrecognized combination of options or no options...',
'error'
);
process.exitCode = 1;
program.help();
}
const getTokensIsSuccessful = await getTokens(
false,
true,
deploymentTypes
);
if (!getTokensIsSuccessful) process.exit(1);

if (!state.getIsIGA()) {
printMessage(
'Command not supported for non-IGA cloud tenants',
'error'
);
process.exit(1);
}
const objectType = options.glossaryType
? glossaryTypeMap[options.glossaryType]
: null;
if (options.glossaryType && !objectType) {
printMessage('Please provide a valid Object Type', 'error');
process.exitCode = 1;
program.help();
}
verboseMessage(
`Describing glossary ${options.glossaryName ? options.glossaryId : options.glossaryName}...`
);
const outcome = await describeGlossary(
options.glossaryId,
options.glossaryName,
objectType,
options.file
);
if (!outcome) process.exitCode = 1;
});

return program;
}
Loading