-
Notifications
You must be signed in to change notification settings - Fork 8.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
[Uptime] Update TLS settings #64111
[Uptime] Update TLS settings #64111
Conversation
Pinging @elastic/uptime (Team:uptime) |
db90149
to
7d2bf4c
Compare
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.
Left a comment on the move from the optional settings?
value in the store to settings
. I haven't reviewed the rest yet. This is a meaty topic worthy of discussion.
loadError?: Error; | ||
saveError?: Error; | ||
loading: boolean; | ||
} | ||
|
||
const initialState: DynamicSettingsState = { | ||
settings: DYNAMIC_SETTINGS_DEFAULTS, |
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 feels cleaner for the settings page in some ways because it reduces LoC, but unless I'm missing something carries hidden complexity that will be paid during the construction of other features.
Before this change one could simply check !!settings
to see if they had a reasonably recent value to use. Now, however, one must reason about the state of loadError
, saveError
and loading
, otherwise you might display to the user the default value, which could be terribly incorrect. The settings page itself must reason about all these variables but there's no escaping the fact that the settings page's concern is the current value of these items and their state transitions. Paying that cost in the code of the settings component is expected. Other consumers of settings don't care about anything other than that a fairly recent value of settings
was loaded. What they don't want, however, is a fake default value. That could do some damage.
Imagine we use settings
on another page, the alert flyout for instance. Before this change we would only need to check !!settings
. One might think that now one needs to check !loading
instead, however, is that the right thing? What if a reload was triggered but the values haven't changed. Well, we don't know, now we have to subscribe to an update. What if the load fails? Now we also need to check loadError
, so now we need to check !loading && !loadError
. What if the load failed, but the settings values are still current enough? Do we now do !loading && !loadError && settings != DEFAULT_SETTINGS
, which will tell us if it loaded at least once successfully, but only in the case where the user changed the settings? This would be an easy bug to miss in a code review, and it's more thinking. If later we change any of these variables for any reason then we need to hunt down this logic all over the app, or use a helper function. It'd be much easier to just use the optional settings?
.
TL;DR Reasoning about the lifecycle of settings carefully on the settings page makes sense, that's that page's job. Everywhere else it should be as simple as possible. The settings
object is truly an optional, we can't hide that.
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.
Point taken about the risk of displaying incorrect values and the associated awfulness. I had initially thought about compromising by making all the settings values Partial
, but we discussed this a bit offline and decided that someone could add a Type
value in the future, which would open us up to the same problem. It's better to make this optional at the root and add branching code where it's necessary.
I think the true representation is an optional Partial
type, where all the fields are also optional. We could conceivably have some valid fields and others invalid.
I'll make an edit and ping you.
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've made the settings field optional again.
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.
Thank you for taking care of it, just few suggestion and it will be good to go.
export const DYNAMIC_SETTINGS_DEFAULTS: DynamicSettings = { | ||
heartbeatIndices: 'heartbeat-8*', | ||
certificatesThresholds: { | ||
expiration: 7, |
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 think this should be 30 days be default.
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.
Fixed in d0246a7.
export const CertificatesStatesThresholdType = t.interface({ | ||
warningState: t.number, | ||
errorState: t.number, | ||
export const CertificatesStatesThresholdType = t.partial({ |
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 think this shouldn't be partial.
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.
would it make sense just to rename it CertStateThresholds WDYT?
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.
Done!
id="xpack.uptime.sourceConfiguration.stateThresholds" | ||
defaultMessage="Expiration State Thresholds" | ||
id="xpack.uptime.sourceConfiguration.expirationThreshold" | ||
defaultMessage="Expiration/Age Thresholds" |
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.
we should also add that text here which got updated in ACs "Change the threshold for displaying and alerting on certificate errors. Note, this will affect any configured alerts"
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.
@@ -63,7 +62,7 @@ export const IndicesForm: React.FC<SettingsFormProps> = ({ | |||
id="xpack.uptime.sourceConfiguration.heartbeatIndicesDefaultValue" | |||
defaultMessage="The default value is {defaultValue}" | |||
values={{ | |||
defaultValue: <EuiCode>{defaultDynamicSettings.heartbeatIndices}</EuiCode>, | |||
defaultValue: <EuiCode>{dss.settings.heartbeatIndices}</EuiCode>, |
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 will display the current value? default value should come from constant?
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.
Right you are, we don't want that to change!
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 is using defaults again now.
const errorStateErr = certificatesThresholds?.errorState ? null : blankStr; | ||
const warningStateErr = certificatesThresholds?.warningState ? null : blankStr; | ||
const errorStateErr = certificatesThresholds?.expiration ? null : blankStr; | ||
const warningStateErr = certificatesThresholds?.age ? null : blankStr; |
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.
can you also rename var name?
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 realized we needed to improve this, so I added a type and renamed the var usage in 59e60e8.
} | ||
}; | ||
const onChangeFormField: OnFieldChangeType = changedField => | ||
setFormFields(Object.assign({ ...merge(formFields, changedField) })); |
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.
We are using merge bcoz Object.assign doesn't take of nested merging, right?
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've gotten rid of merge altogether because it isn't pure and it was editing the state var. I'm wondering if settings shouldn't just be a flat object to avoid recursive concerns when editing slices of it.
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.
yes i think having a right data structure is important, i do agree, having nested have made a lot of complexity. if you think, it's worth an effort, go ahead.
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'll make a follow-up issue.
We have other more important stuff we need to review and it's not worth holding that up for more work in this patch. We don't have any further settings changes planned for the time being, so this complexity shouldn't increase any more than what it is right now until we can get to it. It should be a light patch.
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.
Issue: elastic/uptime#175
[String(setDynamicSettings)]: state => ({ | ||
...state, | ||
loading: true, | ||
}), | ||
[String(setDynamicSettingsSuccess)]: (state, action: Action<DynamicSettings>) => ({ | ||
...state, |
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.
it's not necessary to destructure prev state to return new state, if you know what new state can be in absolute terms.
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 removed these additions in 8412951
I think initially I thought some state-related issue was happening because of the lack of spread
on unreferenced state params, and then never removed them after the fact.
const errorInput = await testSubjects.find('error-state-threshold-input-loaded', 5000); | ||
const warningInput = await testSubjects.find('warning-state-threshold-input-loaded', 5000); | ||
const errorInput = await testSubjects.find('expiration-threshold-input-loaded', 5000); | ||
const warningInput = await testSubjects.find('age-threshold-input-loaded', 5000); |
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.
var name rename plz :)
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.
Renamed in f7678b6
@shahzad31 I think I've addressed your feedback, should be ok for a second look when you have time. |
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.
LGTM !!
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
* Refactor settings form event handling and modify certs fields. * Fix/improve broken types/unit/integration/api tests. * Modify default expiration threshold. * Rename test vars. * Implement PR feedback. * Refresh snapshots, fix broken tests/types. * Remove unnecessary state spreading. * Add type for settings field errors. * Refresh test snapshots. * Improve punctuation.
…bana into ingest-node-pipeline/open-flyout-create-edit * 'feature/ingest-node-pipelines' of github.com:elastic/kibana: (116 commits) [Ingest Node Pipelines] More lenient treatment of on-failure value (elastic#64411) Report Deletion via UI- functional test (elastic#64031) Bump handlebars dependency from 4.5.3 to 4.7.6 (elastic#64402) [Uptime] Update TLS settings (elastic#64111) [alerting] removes usage of any throughout Alerting Services code (elastic#64161) [CANVAS] Moves notify to a canvas service (elastic#63268) [Canvas] Misc NP Stuff (elastic#63703) update apm index pattern (elastic#64232) Task/hostlist pagination (elastic#63722) [NP] Vega migration (elastic#63849) Move ensureDefaultIndexPattern into data plugin (elastic#63100) [Fleet] Fix agent status count to not include unenrolled agents (elastic#64106) Migrate graph_workspace saved object registration to Kibana platform (elastic#64157) Index pattern management UI -> TypeScript and New Platform Ready (edit_index_pattern) (elastic#64184) [ML] EuiDataGrid ml/transform components. (elastic#63447) [ML] Moving to kibana capabilities (elastic#64057) Move input_control_vis into NP (elastic#63333) remove reference to local application service in graph (elastic#64288) KQL removes leading zero and breaks query (elastic#62748) [FieldFormats] Cleanup: rename IFieldFormatType -> FieldFormatInstanceType (elastic#64193) ...
* [Uptime] Update TLS settings (#64111) * Refactor settings form event handling and modify certs fields. * Fix/improve broken types/unit/integration/api tests. * Modify default expiration threshold. * Rename test vars. * Implement PR feedback. * Refresh snapshots, fix broken tests/types. * Remove unnecessary state spreading. * Add type for settings field errors. * Refresh test snapshots. * Improve punctuation. * Change default index pattern from 8.x to 7.x value. Co-authored-by: Elastic Machine <[email protected]>
Summary
We had previously made changes that added some fields to the Settings page in the Uptime solution. The needs for these fields have changed, so this patch renames them. Additional refactoring went into the way the form components receive input and interact with our state store.
Testing
Navigate to the Uptime settings page and modify the values for each field. Make sure that the values you provide are persisted.
Also, log in as a user who has readonly access in the current space, and ensure they're unable to edit the values on the page. No changes were made to the API side of this feature, so you shouldn't need to check access restrictions, but you can test that as well to ensure it's working if you choose.
Refactoring summary
Constant values
Previously, we had some default values that were hosted in our
runtime_types
directory. I don't think this is the place to put those values, because we're not doing that anywhere else in the app, and we're referencing those values from many places. I moved them to a new file in theconstants
folder, and I think that will be a good place to centrally locate all our default settings values as that feature grows.State management
The settings form had an optional field for its state in the store. Given that the server will return the default values discussed above, we should feel comfortable referencing the default values in our store's bootstrap code as well. I made that field required and referenced the default values. Doing this means we'll never not have values for the settings in practice, unless something strange is done to the saved objects outside the scope of this code.
Because we're guaranteeing settings values now, we can remove a lot of branching code in the settings page.
Additionally, I adopted the translation pattern we've discussed previously offline and extracted all the
i18n
references from the settings page and added them to a dedicated file that the other pages can eventually reference as well.We're spending a lot of energy thinking and talking about shortening value names like
dateRangeStart
. Given that we're already nesting cert settings values in a dedicated object, I gave the values themselves short names.Checklist
Delete any items that are not applicable to this PR.
For maintainers