Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GCP secret engine configuration Create/Edit views #29423

Merged
merged 9 commits into from
Jan 30, 2025

Conversation

Monkeychip
Copy link
Contributor

@Monkeychip Monkeychip commented Jan 27, 2025

Description

  • Adds the ability to configure GCP secret engine.
  • For enterprise users, allows them to configure WIF
  • enterprise tests pass

Walk through of the changes
https://github.com/user-attachments/assets/cca57d1c-0860-4bf3-95b3-bdd109be123b

Screenshots:

  1. By marking this a wif engine, we automatically get the IdentityTokenKey param/workflow added to the mount view.
image
  1. Identity Token on the configuration details view after a fresh mount
image
  1. Configure for GCP account access type.
image
  1. Configure for WIF access type
image
  1. If I set any wif fields, automatically defaults to wif access type
image
  1. Details view
image

@github-actions github-actions bot added the hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed label Jan 27, 2025
Copy link

github-actions bot commented Jan 27, 2025

CI Results:
All Go tests succeeded! ✅

@Monkeychip Monkeychip added this to the 1.19.0-rc milestone Jan 27, 2025
@Monkeychip Monkeychip added the ui label Jan 27, 2025
@@ -3,10 +3,11 @@
* SPDX-License-Identifier: BUSL-1.1
*/

import { click, visit, currentURL } from '@ember/test-helpers';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not as clean of a diff as I would have like, but rearranged some tests to better align with Azure and AWS acceptance tests

@Monkeychip Monkeychip marked this pull request as ready for review January 27, 2025 22:07
@Monkeychip Monkeychip requested review from a team as code owners January 27, 2025 22:07
@Monkeychip Monkeychip requested a review from mladlow January 27, 2025 22:07
Copy link

Build Results:
All builds succeeded! ✅

@@ -65,8 +69,45 @@ export default class GcpConfig extends Model {
'identityTokenTtl',
];

get isWifPluginConfigured() {
return !!this.identityTokenAudience || !!this.identityTokenTtl || !!this.serviceAccountEmail;
Copy link
Contributor

Choose a reason for hiding this comment

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

Only one of these needs to be set for WIF to be configured?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The user can set serviceAccountEmail as a stand alone and that means it's wif accessType, but if they set identityTokenAudience we required serviceAccountEmail (may be a miss on the backend validation). Thus, defaulting to any of these fields being set means it's wif.

Comment on lines 76 to 81
get isAccountPluginConfigured() {
// credentials is not checked here because it's never return by the API
// additionally credentials can be set via GOOGLE_APPLICATION_CREDENTIALS env var so we cannot call it a required field in the ui.
// thus we can never say for sure if the account accessType has been configured so we always return false
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is always false then this doesn't need to be a getter and can just be a property on the model. Also it might be helpful to clarify that we're referring to the "credentials" parameter here, since credentials can refer to a set of params in some instances

Suggested change
get isAccountPluginConfigured() {
// credentials is not checked here because it's never return by the API
// additionally credentials can be set via GOOGLE_APPLICATION_CREDENTIALS env var so we cannot call it a required field in the ui.
// thus we can never say for sure if the account accessType has been configured so we always return false
return false;
}
isAccountPluginConfigured = false
// credentials is not checked here because it's never return by the API
// additionally credentials can be set via GOOGLE_APPLICATION_CREDENTIALS env var so we cannot call it a required field in the ui.
// thus we can never say for sure if the account accessType has been configured so we always return false

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like it. Thanks.

await runCmd(`delete sys/mounts/${this.path}`);
});

module('isCommunity', function (hooks) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I think we tend to make module names human readable and not written like variables. So I'd expect this to just be "Community"

assert.dom(GENERAL.emptyStateActions).doesNotContainText('Configure GCP');
// cleanup
await runCmd(`delete sys/mounts/${path}`);
module('details', function () {
Copy link
Contributor

@hellobontempo hellobontempo Jan 30, 2025

Choose a reason for hiding this comment

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

do we need to wrap each of these tests in an additional module (details, create, edit? It seems like slightly unnecessary nesting since each only contains one or two tests

Copy link
Contributor Author

@Monkeychip Monkeychip Jan 30, 2025

Choose a reason for hiding this comment

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

Breaking it up this way helped me make sure I was covering all the logic related to if the model had been already configured or not (edit vs create). For the details module, this tested workflow on a different route. While there's are only several tests in each, I think it helps break up the relevant logic. Again, this was more helpful in test writing, so if you think it's confusing for test reading, I'll default to making the later easier.

Copy link
Contributor

@hellobontempo hellobontempo Jan 30, 2025

Choose a reason for hiding this comment

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

No need to change for this, I just think the modules should be used sparingly and for setting up shared test context. A lot of nesting seems like it's just setting us up for future flakiness.

In the future I think a CRUD module is sufficient (if it's even necessary)

Comment on lines 272 to 289
export const fillInGcpConfig = async (situation = 'gcp') => {
if (situation === 'gcp') {
await click(GENERAL.toggleGroup('More options'));
await click(GENERAL.ttl.toggle('Config TTL'));
await fillIn(GENERAL.ttl.input('Config TTL'), '7200');
await click(GENERAL.ttl.toggle('Max TTL'));
await fillIn(GENERAL.ttl.input('Max TTL'), '8200');
await click(GENERAL.textToggle);
await fillIn(GENERAL.textToggleTextarea, '{"some-key":"some-value"}');
}
if (situation === 'withWif') {
await click(SES.wif.accessType('wif')); // toggle to wif
await fillIn(GENERAL.inputByAttr('identityTokenAudience'), 'azure-audience');
await click(GENERAL.ttl.toggle('Identity token TTL'));
await fillIn(GENERAL.ttl.input('Identity token TTL'), '7200');
await fillIn(GENERAL.inputByAttr('serviceAccountEmail'), '[email protected]');
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

since the method name is fillInGcpConfig I think it's safe to assume either situation is gcp related, another slightly more concise way to write this could be:

export const fillInGcpConfig = async (withWif = false) => {
  if (withWif) {
    await click(SES.wif.accessType('wif')); // toggle to wif
    await fillIn(GENERAL.inputByAttr('identityTokenAudience'), 'azure-audience');
    await click(GENERAL.ttl.toggle('Identity token TTL'));
    await fillIn(GENERAL.ttl.input('Identity token TTL'), '7200');
    await fillIn(GENERAL.inputByAttr('serviceAccountEmail'), '[email protected]');
else {
    await click(GENERAL.toggleGroup('More options'));
    await click(GENERAL.ttl.toggle('Config TTL'));
    await fillIn(GENERAL.ttl.input('Config TTL'), '7200');
    await click(GENERAL.ttl.toggle('Max TTL'));
    await fillIn(GENERAL.ttl.input('Max TTL'), '8200');
    await click(GENERAL.textToggle);
    await fillIn(GENERAL.textToggleTextarea, '{"some-key":"some-value"}');
  }
};

Unless you wanted to combine all of the different engine types then perhaps a switch statement would make sense.

Copy link
Contributor Author

@Monkeychip Monkeychip Jan 30, 2025

Choose a reason for hiding this comment

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

Good catch; there was some modification to this and I ended up removing another situation but missed the clean up.

Copy link
Contributor

@hellobontempo hellobontempo left a comment

Choose a reason for hiding this comment

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

Looks good! Just some small cleanup suggestions, the main one I think to address is the model getter (still small, though!). Thanks for including the video walkthrough - I'm unable to see it without downloading it. Is it possible to add a screenshot or two?

Comment on lines +76 to +79
isAccountPluginConfigured = false;
// the "credentials" param is not checked for "isAccountPluginConfigured" because it's never return by the API
// additionally credentials can be set via GOOGLE_APPLICATION_CREDENTIALS env var so we cannot call it a required field in the ui.
// thus we can never say for sure if the account accessType has been configured so we always return false
Copy link
Contributor

Choose a reason for hiding this comment

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

In the future, I think it's helpful for comments to be before the thing they're describing. No need to change as that will make the approval stale, but just as a future suggestion

Copy link
Contributor

@hellobontempo hellobontempo left a comment

Choose a reason for hiding this comment

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

Nice work getting this over the finish line! It's hard to follow all of the details of the WIF workflow, so I'm trusting that your test coverage is sufficient! Thanks for adding coverage ⭐

@Monkeychip Monkeychip merged commit 14082d0 into main Jan 30, 2025
32 of 33 checks passed
@Monkeychip Monkeychip deleted the ui/VAULT-33155/gcp branch January 30, 2025 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed ui
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants