-
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
UI: Upgrade Ember data 5.3.2 (and upgrade minor versions of ember-source
and ember-cli
)
#28798
Conversation
CI Results: |
@@ -24,20 +24,19 @@ | |||
|
|||
This README outlines the details of collaborating on this Ember application. | |||
|
|||
## Ember CLI Version Upgrade Matrix |
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.
"Ember version" wasn't very clear since we have 3 different ember dependencies: ember-source
, ember-data
and ember-cli
so I added separate columns and only included Vault versions where those versions changed. i looked into doing this dynamically but couldn't find a good solution since since we want to include historical versions, not just the current Vault ember versions
https://github.com/hashicorp/vault/blob/release/1.17.x/ui/package.json
https://github.com/hashicorp/vault/blob/release/1.15.x/ui/package.json
https://github.com/hashicorp/vault/blob/release/1.13.x/ui/package.json
https://github.com/hashicorp/vault/blob/release/1.11.x/ui/package.json
https://github.com/hashicorp/vault/blob/release/1.10.x/ui/package.json
https://github.com/hashicorp/vault/blob/release/1.9.x/ui/package.json
Build Results: |
@@ -23,26 +23,21 @@ export default ApplicationAdapter.extend({ | |||
const isUnauthenticated = snapshotRecordArray?.adapterOptions?.unauthenticated; | |||
// sys/internal/ui/mounts returns the actual value of the system TTL | |||
// instead of '0' which just indicates the mount is using system defaults | |||
const useMountsEndpoint = snapshotRecordArray?.adapterOptions?.useMountsEndpoint; |
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.
reverted changes made by https://github.com/hashicorp/vault/pull/26663/files#diff-50667c363b9be9067473f2acbfbf219e7e13c9c8c6d2232ce971e4205e7932cf now that we're using a separate method
}, | ||
urlForUpdateRecord() { | ||
return this._url(...arguments); | ||
}, | ||
|
||
createRecord(store, type, snapshot) { |
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.
resolves
index.js:696 Uncaught Error: Your kmip/config record was saved to the server,
but the response does not have an id and no id has been set client side.
Records must have ids. Please update the server response to provide an id
in the response or generate the id on the client side either before saving the
record or while normalizing the response.
@@ -86,7 +86,7 @@ export default Route.extend(UnloadModelRoute, { | |||
// if you haven't saved a config, the API 404s, so create one here to edit and return it | |||
if (e.httpStatus === 404) { | |||
config = this.store.createRecord(modelType, { | |||
id: backend.id, |
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 can't find where, but somewhere a record is being created by ember-data (that doesn't persist to the server) which caused this error
router.js:1129 Error while processing route: vault.cluster.settings.auth.configure.section
The id oidcNEW has already been used with another 'auth-config/oidc' record.
Error: The id oidcNEW has already been used with another 'auth-config/oidc' record.
|
||
// bust cache in schema service | ||
const schemas = store.getSchemaDefinitionService?.(); | ||
if (schemas) { |
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.
these properties no longer exist when calling store.getSchemaDefinitionService()
@@ -17,7 +17,7 @@ export default Route.extend({ | |||
return this.store.findRecord('kmip/config', this.secretMountPath.currentPath).catch((err) => { | |||
if (err.httpStatus === 404) { | |||
const model = this.store.createRecord('kmip/config'); | |||
model.set('id', this.secretMountPath.currentPath); |
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.
resolves this error. i cannot for the life of me figure out where this record is created and/or sent to the server. I tried skipping .findRecord
but nope, that's not it. My suspicion is that it's something to do with how openApi is generating schemas but I couldn't pin it down
router.js:1129 Error while processing route: vault.cluster.secrets.backend.kmip.configure 'kmip/config' was saved to the server, but the response returned the new id 'kmip', which has already been used with another record.' Error: 'kmip/config' was saved to the server, but the response returned the new id 'kmip', which has already been used with another record.'
{{! private_key is only available after initial save }} | ||
{{#if this.generatedKey.privateKey}} | ||
<Page::PkiKeyDetails | ||
@key={{this.generatedKey}} | ||
@canDelete={{this.generatedKey.canDelete}} | ||
@canEdit={{this.generatedKey.canEdit}} | ||
/> | ||
{{else}} |
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.
just added this part of the conditional, recommend viewing diff with ✅ hide whitespace
@@ -36,4 +36,10 @@ export default class PkiRolesCreateRoute extends Route { | |||
{ label: 'create' }, | |||
]; | |||
} | |||
|
|||
willTransition() { |
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.
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.
yeah, a test caught something. good example of a helpful test.
await fillIn(GENERAL.inputByAttr('keyType'), 'rsa'); | ||
await click(GENERAL.saveButton); | ||
keyId = find(GENERAL.infoRowValue('Key ID')).textContent?.trim(); | ||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys/${keyId}/details`); | ||
assert.strictEqual( |
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.
see code comment above here
After upgrading to 5.3.2
Ember data no longer "stores" data returned from a save response to the record. Sometimes performing a save operation returns generated data (like private_key
info here)
Previously, any data returned after saving a record was stored in that model in the ember-data store until the page was hard refreshed (or the user navigated away from the route). It did not matter that we re-requested the record fro the server, any server data was just added to the record.
Now, this data is no longer cached so when we transition to details, data like generated private_key
is lost because re-requesting the record from the server clears out the record and only data returned by the server is available.
It's important that we return generated data from saving a record, so the user can download or copy it. So we no longer transition and instead show the details on the same page.
ember-source
and ember-cli
)
@@ -64,6 +64,9 @@ export default Component.extend({ | |||
), | |||
|
|||
actions: { | |||
handleToggle(e) { |
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 opted to add this action instead of glimmerize this file to keep scope small and because this file should eventually just be replaced with the Hds::Form::FileInput::Field, instead of continuing to maintain inflexible components
@@ -23,7 +23,7 @@ | |||
name={{concat "useText-" this.elementId}} | |||
class="toggle is-success is-small" | |||
checked={{this.key.enterAsText}} | |||
onchange={{action (toggle "enterAsText" this.key)}} | |||
onchange={{action "handleToggle"}} |
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.
This change and
vault/ui/app/components/pgp-file.js
Lines 67 to 69 in fdf0365
handleToggle(e) { | |
set(this.key, 'enterAsText', e.target.checked); | |
}, |
are the two additional file changes for this PR compared to the original. When digging into the failure, it seemed like the
toggle
helper no longer updated this.key
. I didn't see the template helper used anywhere else in the code base
Integration | Component | pgp file: toggling back and forth: Chrome 130.0
renders the textarea on toggle
Expected:
Element [data-test-pgp-file-textarea] exists once
Result:
Element [data-test-pgp-file-textarea] does not exist
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 did come across this toggle-action
helper
@onChange={{(toggle-action "clusterRoleBinding" this)}} |
and confirmed it still updates
this.clusterRoleBinding
import { v4 as uuidv4 } from 'uuid'; | ||
import { GENERAL } from 'vault/tests/helpers/general-selectors'; | ||
import { mountAuthCmd, runCmd } from 'vault/tests/helpers/commands'; | ||
import { login } from 'vault/tests/helpers/auth/auth-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.
gosh do I sure love to see this happening. that authLogin is used in a lot of places.
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.
Awesome job on the write up and documentation 🥳🚢 I've done some smoke testing as well and all went smooth.
Original PR #28705 (opened a new PR due to
yarn.lock
conflicts on main)Description
This PR upgrades to ember-data 5.3.2 and tackles resulting test failures. In summary, most of our failures are because Vault is not a RESTful API so we don't consistently receive ids for records after creation.
Some of the failures we saw looked like:
This error occurred when navigating to create routes where record schemas were built from openApi. I could not figure out where exactly this error was coming from because this error occurred when navigating to the create form, before a record was even saved. My suspicion is something is happening when open api generates the schema that results in creating a record in the store, but the ember data inspector is broken after upgrading so it's hard to tell what's happening in the store exactly.
To resolve the issue we create the record with a
mutableId
which is used to create the record, generate the URL and returned bycreateRecord
(which is necessary when creating results in a204
which ember data has problems with). See comment here.In addition, we replaced instances of
findAll
withquery
because docsThis means that
findAll
makes a network requests and adds any records to the existing store and then returns all of those. This is bad. The store could contain an outdated or "ghost" record (something we saw more of in this upgrade - unfortunately tracking these down is not straightforward). Either way, two sources of truth is unreliable and we should consistently only rely on the server as the source of truth - not the ember data store.By using
query
we consistently refresh the store with what the API returns which is what we want.TODO only if you're a HashiCorp employee
to N, N-1, and N-2, using the
backport/ent/x.x.x+ent
labels. If this PR is in the CE repo, you should only backport to N, using thebackport/x.x.x
label, not the enterprise labels.of a public function, even if that change is in a CE file, double check that
applying the patch for this PR to the ENT repo and running tests doesn't
break any tests. Sometimes ENT only tests rely on public functions in CE
files.
in the PR description, commit message, or branch name.
description. Also, make sure the changelog is in this PR, not in your ENT PR.