Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ff86879
Replace shell with nodejs repl
cparkertrivir Nov 26, 2024
357197a
Add difference checker to compare a master configuration to an export
mmercer884 Sep 23, 2024
30f94f7
Add imports for the different types that have been either changed or …
mmercer884 Sep 24, 2024
4ced311
Add in deletes for items that need to be deleted
mmercer884 Oct 28, 2024
ebd24cf
Add mappings, service, sync, variable, idp, application, theme, manag…
mmercer884 Oct 29, 2024
67b3e0f
Add running an environment restart to apply the variables when they a…
mmercer884 Nov 1, 2024
25bccc3
Add Prune to Promote
mmercer884 Nov 22, 2024
fdc8d8a
Remove unecessary code and add comments to functions
mmercer884 Dec 4, 2024
f218600
remove unused packages
cparkertrivir Dec 4, 2024
f7c2387
Update journey import mock recordings to pass tests
phalestrivir Dec 4, 2024
68a10cc
Fix --watch to work for script imports when done in the current direc…
phalestrivir Dec 6, 2024
eef007e
add new option to separate managed objects into individual files
cparkertrivir Dec 9, 2024
5e71302
update tests
cparkertrivir Dec 9, 2024
08d87b5
Update tests so idp imports work
phalestrivir Dec 9, 2024
02c614a
Update tests to pass after removing duplicate IdPs. Minor refactor to…
phalestrivir Dec 10, 2024
4460572
Add new export flags to give options for including read only config a…
phalestrivir Dec 11, 2024
404b0ca
add new commands for managed objects
cparkertrivir Dec 18, 2024
c329172
add and update tests
cparkertrivir Dec 18, 2024
9c9af7b
Merge pull request #456 from trivir/shell-repl
vscheuber Jan 23, 2025
462d77d
Merge branch '3.0.1' into promotion-tool2
vscheuber Jan 23, 2025
a99e946
Merge pull request #458 from mmercer884/promotion-tool2
vscheuber Jan 23, 2025
facaa7d
Merge pull request #460 from trivir/fix/fix-journey-imports
vscheuber Jan 23, 2025
74da083
Merge pull request #461 from trivir/split-managed-json-config
vscheuber Jan 23, 2025
891c137
Merge pull request #462 from trivir/fix/fix-script-watch
vscheuber Jan 23, 2025
81fda68
Merge branch 'pr/463' into 3.0.1
vscheuber Jan 23, 2025
d03b7f1
remove
vscheuber Jan 24, 2025
f4f4c04
remove
vscheuber Jan 24, 2025
87cdf19
remove
vscheuber Jan 24, 2025
0fd6695
Merge branch 'pr/465' into 3.0.1
vscheuber Jan 24, 2025
30edfd7
Update tests to pass after removing duplicate IdPs. Minor refactor to…
phalestrivir Dec 10, 2024
a802156
remove
vscheuber Jan 24, 2025
0e3c4ce
Merge pull request #466 from trivir/fix/fix-idp-duplication
vscheuber Jan 24, 2025
52465e6
remove
vscheuber Jan 24, 2025
9b57fa2
add new commands for managed objects
cparkertrivir Dec 18, 2024
3b20d46
add and update tests
cparkertrivir Dec 18, 2024
998c660
remove
vscheuber Jan 24, 2025
ec9bb54
Merge branch '3.0.1' into pr/467
vscheuber Jan 24, 2025
2f01ddc
Merge pull request #470 from rockcarver/pr/467
vscheuber Jan 24, 2025
eb66250
Update idm schema object export/import to have the env file flag
phalestrivir Feb 3, 2025
54bf118
Update tests to pass
phalestrivir Feb 3, 2025
13dfe48
Merge pull request #473 from trivir/fix/fix-tests
vscheuber Feb 5, 2025
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
  •  
  •  
  •  
327 changes: 26 additions & 301 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-simple-import-sort": "^10.0.0",
"fs-extra": "^11.1.1",
"fuzzy": "^0.1.3",
"inquirer": "^8.2.5",
"inquirer-autocomplete-prompt": "^2.0.0",
"jest": "^29.3.1",
"loglevel": "^1.9.1",
"map-stream": "^0.0.7",
Expand All @@ -158,5 +155,9 @@
"typescript": "^5.2.2",
"uuid": "^9.0.0",
"yesno": "^0.4.0"
},
"dependencies": {
"deep-diff": "^1.0.2",
"tmp": "^0.2.3"
}
}
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import journey from './cli/journey/journey';
import log from './cli/log/log';
import mapping from './cli/mapping/mapping';
import oauth from './cli/oauth/oauth';
import promote from './cli/promote/promote';
import realm from './cli/realm/realm';
import role from './cli/role/role';
import saml from './cli/saml/saml';
Expand Down Expand Up @@ -73,6 +74,7 @@ const { initTokenCache } = frodo.cache;
await program.addCommand(log());
program.addCommand(mapping());
program.addCommand(oauth());
program.addCommand(promote());
program.addCommand(realm());
program.addCommand(role());
program.addCommand(saml());
Expand Down
49 changes: 45 additions & 4 deletions src/cli/config/config-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@

program
.description(
'Export full cloud configuration for all ops that currently support export.'
`Export full cloud configuration.\n` +
`By default, it only exports importable config (i.e. config that is not read-only) for the current deployment (e.g. if exporting from cloud, realm config would NOT be exported since it can't be imported back into cloud even though it can be imported into classic deployments). There is a flag to export all config including read only config.\n` +
`Additionally, there is a flag to export config for only the specified realm, a flag to export only global config, and many other flags to customize the export. Use the -h or --help to see them all and to also see usage examples.`
)
.addOption(new Option('-f, --file <file>', 'Name of the export file.'))
.addOption(new Option('-a, --all', 'Export everything to a single file.'))
Expand Down Expand Up @@ -61,12 +63,36 @@
'Export all scripts including the default scripts.'
)
)
.addOption(
new Option(
'-R, --read-only',
'Export read-only config (with the exception of default scripts) in addition to the importable config.'
)
)
.addOption(
new Option(
'-r, --realm-only',
'Export only the config for the active realm. If -g, --global-only is also active, then the global config will also be exported.'
)
)
.addOption(
new Option(
'-g, --global-only',
'Export only the global config. If -r, --realm-only is also active, then the corresponding active realm config will also be exported.'
)
)
.addOption(
new Option(
'-s, --separate-mappings',
'Export sync.idm.json mappings separately in their own directory. Ignored with -a.'
)
)
.addOption(
new Option(
'-o, --separate-objects',
'Export managed.idm.json objects separately in their own directory. Ignored with -a.'
)
)
.addOption(
new Option(
'--include-active-values',
Expand All @@ -86,15 +112,23 @@
'brightGreen'
] +
`Usage Examples:\n` +
` Backup global and active realm configuration including active secret values to a single file (Note: only values of active and loaded secrets can be exported):\n` +
` Export global and realm configuration for version control (e.g. Git) into the current directory.\n` +
` Note that -x and -s separates script and mapping config to better track changes made to them, and -N removes metadata since it changes every export (you may consider using --no-coords as well if you don't care to track node positions in journeys):\n` +
` $ frodo config export -sxAND . ${s.connId}\n`['brightCyan'] +
` Export global and realm configuration from cloud to be later imported into a classic, on-prem deployment.\n` +
` Note -dR is used for exporting all read-only config from cloud since certain cloud read-only config (like the realm config) can be imported into a classic on-prem deployment:\n` +
` $ frodo config export -adR ${s.connId}\n`['brightCyan'] +
` Export only the bravo realm configuration:\n` +
` $ frodo config export -ar ${s.connId} bravo\n`['brightCyan'] +
` Backup global and realm configuration including active secret values to a single file (Note: only values of active and loaded secrets can be exported):\n` +
` $ frodo config export -a --include-active-values ${s.connId}\n`[
'brightCyan'
] +
` Backup global and active realm configuration including active secret values to individual files in a directory structure (Note: only values of active and loaded secrets can be exported):\n` +
` Backup global and realm configuration including active secret values to individual files in a directory structure (Note: only values of active and loaded secrets can be exported):\n` +
` $ frodo config export -A -D ${s.connId}-backup --include-active-values ${s.connId}\n`[
'brightCyan'
] +
` Export global and active realm configuration including active secret values for import into another environment.\n` +
` Export global and realm configuration including active secret values for import into another environment.\n` +
` The --target parameter instructs frodo to encrypt the exported secret values using the target environment so they can be imported into that target environment without requiring the source environment they were exported from.\n` +
` Using the --target parameter, the target environment must be available at the time of export and the person performing the export must have a connection profile for the target environment.\n` +
` Without the --target parameter, the source environment must be available at the time of import and the person performing the import must have a connection profile for the source environment.\n` +
Expand Down Expand Up @@ -126,6 +160,9 @@
includeDefault: options.default,
includeActiveValues: options.includeActiveValues,
target: options.target,
includeReadOnly: options.readOnly,

Check failure on line 163 in src/cli/config/config-export.ts

View workflow job for this annotation

GitHub Actions / Build

Object literal may only specify known properties, and 'includeReadOnly' does not exist in type 'FullExportOptions'.
onlyRealm: options.realmOnly,
onlyGlobal: options.globalOnly,
}
);
if (!outcome) process.exitCode = 1;
Expand All @@ -145,6 +182,7 @@
const outcome = await exportEverythingToFiles(
options.extract,
options.separateMappings,
options.separateObjects,
options.metadata,
{
useStringArrays: options.useStringArrays,
Expand All @@ -153,6 +191,9 @@
includeDefault: options.default,
includeActiveValues: options.includeActiveValues,
target: options.target,
includeReadOnly: options.readOnly,

Check failure on line 194 in src/cli/config/config-export.ts

View workflow job for this annotation

GitHub Actions / Build

Object literal may only specify known properties, and 'includeReadOnly' does not exist in type 'FullExportOptions'.
onlyRealm: options.realmOnly,
onlyGlobal: options.globalOnly,
}
);
if (!outcome) process.exitCode = 1;
Expand Down
55 changes: 55 additions & 0 deletions src/cli/idm/idm-delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Option } from 'commander';

import { getTokens } from '../../ops/AuthenticateOps';
import { deleteConfigEntityById } from '../../ops/IdmOps';
import { FrodoCommand } from '../FrodoCommand';

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

interface ServiceDeleteOptions {
id?: string;
type?: string;
insecure?: boolean;
verbose?: boolean;
debug?: boolean;
curlirize?: boolean;
all?: boolean;
global?: boolean;
}

program
.description('Delete AM services.')
.addOption(new Option('-i, --id <id>', 'Id of Service to be deleted.'))
.action(
async (
host: string,
realm: string,
user: string,
password: string,
options: ServiceDeleteOptions,
command
) => {
command.handleDefaultArgsAndOpts(
host,
realm,
user,
password,
options,
command
);

// const globalConfig = options.global ?? false;

if (options.id && (await getTokens())) {
const outcome = await deleteConfigEntityById(options.id);
if (!outcome) process.exitCode = 1;
} else {
program.help();
process.exitCode = 1;
}
}
);

return program;
}
8 changes: 8 additions & 0 deletions src/cli/idm/idm-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ export default function setup() {
'Export sync.idm.json mappings separately in their own directory. Ignored with -a.'
)
)
.addOption(
new Option(
'-o, --separate-objects',
'Export managed.idm.json objects separately in their own directory. Ignored with -a.'
)
)
.addOption(
new Option(
'-N, --no-metadata',
Expand Down Expand Up @@ -95,6 +101,7 @@ export default function setup() {
options.file,
options.envFile,
options.separateMappings,
options.separateObjects,
options.metadata
);
if (!outcome) process.exitCode = 1;
Expand Down Expand Up @@ -136,6 +143,7 @@ export default function setup() {
options.entitiesFile,
options.envFile,
options.separateMappings,
options.separateObjects,
options.metadata
);
if (!outcome) process.exitCode = 1;
Expand Down
131 changes: 131 additions & 0 deletions src/cli/idm/idm-schema-object-export.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { state } from '@rockcarver/frodo-lib';
import { Option } from 'commander';

import { getTokens } from '../../ops/AuthenticateOps';
import {
exportConfigEntityToFile,
exportManagedObjectToFile,
warnAboutOfflineConnectorServers,
} from '../../ops/IdmOps';
import { printMessage, verboseMessage } from '../../utils/Console';
import { FrodoCommand } from '../FrodoCommand';

const deploymentTypes = ['cloud', 'forgeops'];

export default function setup() {
const program = new FrodoCommand(
'frodo idm schema object export',
[],
deploymentTypes
);

program
.description('Export IDM configuration managed objects.')
.addOption(
new Option(
'-a, --all',
'Export all IDM configuration managed objects into a single file in directory -D.'
)
)
.addOption(
new Option(
'-A, --all-separate',
'Export all IDM configuration managed objects into separate JSON files in directory -D.'
)
)
.addOption(
new Option(
'-i, --individual-object <name>',
'Export an individual managed object by specifying an objects name. E.g. "alpha_user", "bravo_role", etc. If specified, -a and -A are ignored.'
)
)
.addOption(new Option('-f, --file [file]', 'Export file. Ignored with -A.'))
.addOption(new Option('-e, --env-file [envfile]', 'Name of the env file.'))
.addOption(
new Option(
'-N, --no-metadata',
'Does not include metadata in the export file.'
)
)
.action(
// implement command logic inside action handler
async (host, realm, user, password, options, command) => {
command.handleDefaultArgsAndOpts(
host,
realm,
user,
password,
options,
command
);
const envMessage = options.envFile
? ` using ${options.envFile} for variable replacement`
: '';
const fileMessage = options.file ? ` into ${options.file}` : '';
const directoryMessage = state.getDirectory()
? ` into separate files in ${state.getDirectory()}`
: '';
// -i, --individual-object <name>
if (
options.individualObject &&
(await getTokens(false, true, deploymentTypes))
) {
verboseMessage(
`Exporting managed object "${options.individualObject}"${envMessage}${fileMessage}...`
);
const outcome = await exportManagedObjectToFile(
options.individualObject,
options.file,
options.envFile
);
if (!outcome) process.exitCode = 1;
} // -a, --all
else if (
options.all &&
(await getTokens(false, true, deploymentTypes))
) {
verboseMessage(
`Exporting managed objects ${envMessage}${fileMessage}...`
);
const outcome = await exportConfigEntityToFile(
'managed',
options.file,
options.envFile,
false,
false,
options.metadata
);
if (!outcome) process.exitCode = 1;
} // -A, --all-separate
else if (
options.allSeparate &&
(await getTokens(false, true, deploymentTypes))
) {
verboseMessage(
`Exporting managed objects ${envMessage}${directoryMessage}...`
);
const outcome = await exportConfigEntityToFile(
'managed',
options.file,
options.envFile,
false,
true,
options.metadata
);
if (!outcome) process.exitCode = 1;
await warnAboutOfflineConnectorServers();
} // unrecognized combination of options or no options
else {
printMessage(
'Unrecognized combination of options or no options...',
'error'
);
program.help();
process.exitCode = 1;
}
}
// end command logic inside action handler
);

return program;
}
Loading
Loading