Skip to content
Merged
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
  •  
  •  
  •  
36 changes: 26 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,9 @@
"typescript": "^5.2.2",
"uuid": "^9.0.0",
"yesno": "^0.4.0"
},
"dependencies": {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be devDependencies?

"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
55 changes: 55 additions & 0 deletions src/cli/idm/idm-delete.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDM delete command is not necessary for the promotion, this should be in a separate PR

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 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left over dead code from copying the service command.

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

program
.description('Delete AM services.')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update descriptions to be descriptive of idm and not 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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code


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

return program;
}
3 changes: 3 additions & 0 deletions src/cli/idm/idm.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDM delete command is not necessary for the promotion, this should be in a separate PR

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full delete is not necessary but I did have to pull inn the command from the library

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FrodoStubCommand } from '../FrodoCommand';
import CountCmd from './idm-count.js';
import DeleteCmd from './idm-delete.js';
import ExportCmd from './idm-export.js';
import ImportCmd from './idm-import.js';
import ListCmd from './idm-list.js';
Expand All @@ -17,5 +18,7 @@ export default function setup() {

program.addCommand(CountCmd().name('count'));

program.addCommand(DeleteCmd().name(`delete`));

return program;
}
45 changes: 45 additions & 0 deletions src/cli/idp/idp-delete.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IdP delete command is not necessary for the promotion, this should be in a separate PR

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { state } from '@rockcarver/frodo-lib';
import { Option } from 'commander';

import { getTokens } from '../../ops/AuthenticateOps';
import { deleteSocialIdentityProviderById } from '../../ops/IdpOps';
import { printMessage, verboseMessage } from '../../utils/Console';
import { FrodoCommand } from '../FrodoCommand';

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

program
.description('Delete (social) identity providers.')
.addOption(new Option('-i, --idp-id <idp-id>', 'Id/name of a provider.'))
.action(
// implement command logic inside action handler
async (host, realm, user, password, options, command) => {
command.handleDefaultArgsAndOpts(
host,
realm,
user,
password,
options,
command
);
if ((await getTokens()) && options.idpId) {
verboseMessage(
`Deleting idp ${options.idpId} in realm "${state.getRealm()}"...`
);
const outcome = await deleteSocialIdentityProviderById(options.idpId);
if (!outcome) process.exitCode = 1;
} else {
printMessage(
'Unrecognized combination of options or no options...',
'error'
);
program.help();
process.exitCode = 1;
}
}
// end command logic inside action handler
);

return program;
}
3 changes: 3 additions & 0 deletions src/cli/idp/idp.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IdP delete command is not necessary for the promotion, this should be in a separate PR

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FrodoStubCommand } from '../FrodoCommand';
import DeleteCmd from './idp-delete';
import ExportCmd from './idp-export.js';
import ImportCmd from './idp-import.js';
import ListCmd from './idp-list.js';
Expand All @@ -14,5 +15,7 @@ export default function setup() {

program.addCommand(ImportCmd().name('import'));

program.addCommand(DeleteCmd().name('delete'));

return program;
}
6 changes: 4 additions & 2 deletions src/cli/oauth/oauth-client-delete.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OAuth client delete command is not necessary for the promotion, this should be in a separate PR. Additionally, might as well implement the -a flag too, and --no-deep if applicable.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Option } from 'commander';

import { getTokens } from '../../ops/AuthenticateOps';
import { deleteOauth2ClientById } from '../../ops/OAuth2ClientOps';
import { FrodoCommand } from '../FrodoCommand';

export default function setup() {
Expand Down Expand Up @@ -34,8 +35,9 @@ export default function setup() {
options,
command
);
if (await getTokens()) {
// code goes here
if (options.appId && (await getTokens())) {
const outcome = deleteOauth2ClientById(options.appId);
if (!outcome) process.exitCode = 1;
} else {
process.exitCode = 1;
}
Expand Down
4 changes: 2 additions & 2 deletions src/cli/oauth/oauth-client.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OAuth client delete command is not necessary for the promotion, this should be in a separate PR

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { FrodoStubCommand } from '../FrodoCommand';
// import DescribeCmd from './oauth-client-describe.js';
import DeleteCmd from './oauth-client-delete.js';
import ExportCmd from './oauth-client-export.js';
import ImportCmd from './oauth-client-import.js';
import ListCmd from './oauth-client-list.js';
// import DeleteCmd from './oauth-client-delete.js';

export default function setup() {
const program = new FrodoStubCommand('frodo oauth client');
Expand All @@ -18,7 +18,7 @@ export default function setup() {

program.addCommand(ImportCmd().name('import'));

// program.addCommand(DeleteCmd().name('delete'));
program.addCommand(DeleteCmd().name('delete'));

return program;
}
124 changes: 124 additions & 0 deletions src/cli/promote/promote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { FrodoError } from '@rockcarver/frodo-lib';
import { Option } from 'commander';

import { getTokens } from '../../ops/AuthenticateOps';
import { compareExportToDirectory } from '../../ops/PromoteOps';
import { verboseMessage } from '../../utils/Console.js';
import { FrodoCommand } from '../FrodoCommand';

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

export default function setup() {
const program = new FrodoCommand('promote');

program
.description('Prepares a tenant to be promoted')
.addHelpText(
'after',
'This is used to compare two directories and automatically import and delete' +
'configurations so the tenant can be promoted. It will compare a master export to a current export' +
'and make the changes based off that diff. A file will be generated to show what has changed. \n' +
`Usage Examples:\n` +
'\n' +
'frodo promote -M ./master -E ./export [testTenant]\n' +
'\n' +
'This will run the promote command making the changes from master to the export, with the master being the one we are going to.' +
'\n' +
'\n' +
'frodo promote --what-if -M ./master -E ./export [testTenant]\n' +
'\n' +
'This will output the changes that would be made if the promote was run but will not do those changes'
)
.addOption(
new Option(
'-E, --frodo-export-dir <directory>',
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd lean towards lowercase flags when possible.

'The directory where the frodo export is located.'
)
)
.addOption(
new Option(
'--what-if',
'Runs a what if of the comparison, so it wont do any changes'
).default(false, 'false')
)
.addOption(
new Option(
'-M, --master-dir <directory>',
'The directory where the master configurations is located.'
)
)
.addOption(
new Option(
'--propmt-prune',
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spelling

'Will prompt for Frodo Journey Prune on all realms'
).default(false, 'false')
)
.addOption(
new Option('--no-prune', 'Will stop prune from running').default(
false,
'false'
)
)
.addOption(
new Option(
'-S --effect-secrets',
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spelling

'Will effect the secrets, otherwise we will not change the secrets but will compare them'
).default(false, 'false')
)
.addOption(
new Option(
'-W --wait-secrets',
'When secrets are effected we need to run a refresh on the enviornment. This will cause the command to wait until the refresh is finished.'
).default(false, 'false')
)
.addOption(
new Option(
'-P --print-diff',
'Outputs the diff to a file in the directory where the command was run.'
).default(false, 'false')
)
.addOption(
new Option(
'--target <host url>',
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? The promotion staging should all be for the single environment for now.

'Host URL of the environment to perform secret value encryption. The URL must resolve to an existing connection profile. Use this option to generate an export that can be imported into the target environment without requiring admin access to the source environment.'
)
)
.action(
async (host, realm, user, password, options, command) => {
command.handleDefaultArgsAndOpts(
host,
realm,
user,
password,
options,
command
);
if (
(await getTokens(false, true, deploymentTypes)) &&
options.masterDir &&
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reorder to validate option prior to making the request for tokens

options.frodoExportDir
) {
verboseMessage('Comparing export...');
verboseMessage('comparing');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This second verbose message is not needed, first one should suffice

const outcome = await compareExportToDirectory(
options.masterDir,
options.frodoExportDir,
options.whatIf,
options.effectSecrets,
options.waitSecrets,
options.promptPrune,
options.noPrune,
options.printDiff
);
verboseMessage('done');
if (!outcome) process.exitCode = 1;
} else {
new FrodoError('need to designate a master dir and export directory');
}
}
//end command logic inside action handler
//"/home/trivir/Frodo/golden1-git/identity-cloud-config"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete this comment with the file path

);

return program;
}
Loading
Loading