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

Allow Configuration of Azure Secret Engine, including WIF for enterprise users #29047

Merged
merged 20 commits into from
Dec 18, 2024

Conversation

Monkeychip
Copy link
Contributor

@Monkeychip Monkeychip commented Nov 27, 2024

  • ent tests pass (tested again right before merging).

Description

This PR adds to the Secret engine Azure:

  1. Configuration create/edit view
  2. Mount Configuration + Configuration details on one view
  3. WIF configuration fields
WIF Fields Non WIF Fields
Subscription ID Subscription ID
Tenant ID Tenant ID
Client ID Client ID
ID Token Audience Client Secret
ID Token TTL Root Password TTL
Environment Environment

Screenshare walk through:

  • shows adding identity_token_key during mount (already on main).
  • shows new configuration details views, hiding the mount config in toggle and prompting to configure the engine.
  • shows configuring with azure account access type.
  • shows how editing access type is not allowed once azure account information has been saved.
  • then mounts new engine and shows configuring with wif access type.
azurewalkthrough.mov

How it looks in community, no option to change Access Type and therefor select WIF enterprise only params.
image

@github-actions github-actions bot added the hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed label Nov 27, 2024
@Monkeychip Monkeychip added this to the 1.19.0-rc milestone Nov 27, 2024
@Monkeychip Monkeychip added the ui label Nov 27, 2024
Copy link

github-actions bot commented Nov 27, 2024

CI Results:
All Go tests succeeded! ✅

@Monkeychip Monkeychip marked this pull request as ready for review November 27, 2024 18:03
@Monkeychip Monkeychip requested review from a team as code owners November 27, 2024 18:03
@Monkeychip Monkeychip requested review from vishalnayak and removed request for a team November 27, 2024 18:03
Copy link

github-actions bot commented Nov 27, 2024

Build Results:
All builds succeeded! ✅

changelog/29047.txt Outdated Show resolved Hide resolved
changelog/29047.txt Outdated Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

🎉 typescript 🎉 😍

backend,
type,
});
// some of the models return a 200 if they are not configured (ex: azure)
// so instead of checking a catch or httpStatus, we check if the model is configured based on the getter `isConfigured` on the engine's model
// if the engine is not configured we update the record to get the default values
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Azure, at the moment, is the only engine that returns a 200 when the config has not been modified. However, future engines might also keep this pattern / or it could just be an Azure thing. For now, I have this line to handle it and isConfigured getter added to the model. Is it my favorite? No, but I feel like it's pretty smooth for the situation. 🤷‍♀️

}

get modelAttrChanged() {
// "backend" dirties model state so explicity ignore it here
Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW I don't think this would happen if you didn't create a new record, and reused the record from queryRecord. But I'm not 💯 sure

// if the issuer has changed show modal with warning that the config will change
// if the modal is shown, the user has to click confirm to continue saving
this.saveIssuerWarning = `You are updating the global issuer config. This will overwrite Vault's current issuer ${
issuerConfig.queryIssuerError ? 'if it exists ' : ''
Copy link
Contributor

Choose a reason for hiding this comment

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

Personally I don't think we need to hold onto queryIssuerError here and could just always say "if it exists" but that's just me in favor of keeping things simple 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree. This was Chelsea and design working through dynamic language to show a more detailed message if you had read access to this endpoint vs if you didn't. I'll add this comment to the nice-to-have ticket for refactoring the issuer-modal-model save flow.

Comment on lines 117 to 118
// transition if the model was saved successfully
// or transition if no attributes on the model have changed and the issuer was saved successfully
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if this would be clearer as "We only prevent a transition if the model is edited and fails saving." Since the comment explains when we do transition which we can see from the conditional 💬

Comment on lines 83 to 84
// clientSecret is not checked here because it's never return by the API
// however it is an Azure account field
Copy link
Contributor

Choose a reason for hiding this comment

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

thanks for this comment!

@@ -65,4 +65,41 @@ export default class AzureConfig extends Model {
get formFields() {
return expandAttributeMeta(this, this.configurableParams);
}

// "filedGroupsWif" and "fieldGroupsAzure" are passed to the FormFieldGroups component to determine which group to show in the form (ex: @groupName="fieldGroupsWif")
get fieldGroupsWif() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like quite a bit of extra code (these two getters plus the formFieldGroups function below) - I think we already have helpers that do this 🤔 Can we reuse any of the model decorators or existing patterns to get the same functionality?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Did a little updating, let me know if that helps.

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.

Great work, thanks for the additional test coverage! Just left some comments, overall pretty small stuff! I'm brain dead, so I'll give a final review tomorrow!

Comment on lines +12 to +46
<fieldset class="field form-fieldset" id="protection" data-test-access-type-section>
<legend class="is-label">Access Type</legend>
<p class="sub-text" data-test-access-type-subtext>
{{#if this.disableAccessType}}
You cannot edit Access Type if you have already saved access credentials.
{{else}}
Choose the way to configure access to Azure. Access can be configured either using an Azure account or with the
Plugin Workload Identity Federation (WIF).
{{/if}}
</p>
<div>
<RadioButton
id="access-type-azure"
name="azure"
class="radio"
data-test-access-type="azure"
@value="azure"
@groupValue={{this.accessType}}
@onChange={{fn this.onChangeAccessType "azure"}}
@disabled={{this.disableAccessType}}
/>
<label for="access-type-azure">Azure account credentials</label>
<RadioButton
id="access-type-wif"
name="wif"
class="radio has-left-margin-m"
data-test-access-type="wif"
@value="wif"
@groupValue={{this.accessType}}
@onChange={{fn this.onChangeAccessType "wif"}}
@disabled={{this.disableAccessType}}
/>
<label for="access-type-wif">Workload Identity Federation</label>
</div>
</fieldset>
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this is reused in AWS curious why we didn't make a shared component?

Copy link
Contributor Author

@Monkeychip Monkeychip Dec 18, 2024

Choose a reason for hiding this comment

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

GCP, AWS and Azure will all have some small overlap because we're adding this "Access Type" option to enterprise views. However, they are some differences, specifically the group values that relate back to these engine's models.

My preference was to keep all configuration code separate in each engines own configuration file. The win for sharing this chunk of code didn't feel significant enough to introduce a shared component that would have to work around each engine's specific "group" or labeling.

Comment on lines +131 to +134
assert.notOk(
true,
'post request was made to issuer endpoint when on community and data not changed. test should fail.'
);
Copy link
Contributor

@hellobontempo hellobontempo Dec 17, 2024

Choose a reason for hiding this comment

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

Noelle had a great idea that instead of using assert here (which can be kind of confusing and unclear) we can throw an error, like this:
https://github.com/hashicorp/vault/blob/main/ui/tests/integration/components/dashboard/overview-test.js#L105-L108

So instead of the assertion count being the only thing that lets us know this errors, the test actually fails when the bad thing happens

Copy link
Contributor Author

@Monkeychip Monkeychip Dec 18, 2024

Choose a reason for hiding this comment

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

I did this a couple of places, but this test will fail if the server.post gets hit because notOk first param should be false, but here it's true (thus, the assert.expect isn't the only catch).

To me, I prefer the assertion failing like this, but I'm clearly not beholden to one way or the other having used both approaches.

assert.expect(2);
await click(SES.configure);
const url = currentURL();
const path = url.split('/')[3]; // get path from url because we can't pass the path from beforeEach hook to individual test.
Copy link
Contributor

Choose a reason for hiding this comment

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

could we save the path as this.path in the beforeEach hook instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oish, I tried. It doesn't work for a couple reasons that I remember. If I set the path to something dynamic like path-${this.uuid} it changes before each test and then when i call it within the test it changes again. And setting it to something hard coded likepath-azure, makes it a little harder to debug what path is being used in what tests and prone to flakiness even with cleanup after each run.

hellobontempo
hellobontempo previously approved these changes Dec 17, 2024
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.

Approving but there are some minor test improvements and a small cleanup item I think we should address before merging.

Great work! 🌟 Really thorough test coverage 😍

hellobontempo
hellobontempo previously approved these changes Dec 18, 2024
@Monkeychip Monkeychip merged commit 2631ae6 into main Dec 18, 2024
32 of 33 checks passed
@Monkeychip Monkeychip deleted the ui/VAULT-32142/azure-wif-2 branch December 18, 2024 23:28
Monkeychip added a commit that referenced this pull request Dec 20, 2024
…ise users (#29047)

* transfer over all changes from original pr

* changelog

* add serialize catch for no empty string environment

* move ttl format logic to parent route

* Update 29047.txt

* clean up some comments

* Update changelog/29047.txt

Co-authored-by: claire bontempo <[email protected]>

* Update changelog/29047.txt

Co-authored-by: claire bontempo <[email protected]>

* Update ui/app/components/secret-engine/configure-azure.hbs

Co-authored-by: claire bontempo <[email protected]>

* first round of addressing pr comments, holding off on the issue save flow for error messaging to keep separate

* Update CODEOWNERS

merge issue

* small clean up tasks

* updates

* test coverage

* small cleanup

* small clean up

* clean up

* clean up getters on model

---------

Co-authored-by: claire bontempo <[email protected]>
@Monkeychip Monkeychip mentioned this pull request Feb 3, 2025
1 task
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