-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Conversation
CI Results: |
@@ -3,10 +3,11 @@ | |||
* SPDX-License-Identifier: BUSL-1.1 | |||
*/ | |||
|
|||
import { click, visit, currentURL } from '@ember/test-helpers'; |
There was a problem hiding this comment.
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
Build Results: |
@@ -65,8 +69,45 @@ export default class GcpConfig extends Model { | |||
'identityTokenTtl', | |||
]; | |||
|
|||
get isWifPluginConfigured() { | |||
return !!this.identityTokenAudience || !!this.identityTokenTtl || !!this.serviceAccountEmail; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
ui/app/models/gcp/config.js
Outdated
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; | ||
} |
There was a problem hiding this comment.
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
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 |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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 () { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
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]'); | ||
} | ||
}; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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?
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 |
There was a problem hiding this comment.
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
There was a problem hiding this 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 ⭐
Description
Walk through of the changes
https://github.com/user-attachments/assets/cca57d1c-0860-4bf3-95b3-bdd109be123b
Screenshots: