-
Notifications
You must be signed in to change notification settings - Fork 993
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
Fixes #34300 - correctly construct the fqdn for redirect #9047
Conversation
Issues: #34300 |
[test foreman] |
function construct_fqdn() { | ||
var host_name = $('#host_name').val(); | ||
var domain_name = primary_nic_form() | ||
.find('.interface_domain option:selected') | ||
.text(); | ||
return fqdn(host_name, domain_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 think unmanaged hosts don't have NICs, but I can't check right now since I don't have an unmanaged host. Does this work in that case?
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 test that out, tho I've also remembered the setting append_domain_name_for_hosts
and for that = true
it would not work almost for sure.
I'll test both cases and see if I can figure something better.
EDIT: issue is obviously with append_domain_name_for_hosts = 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 do think the ID of the host is much more reliable than the FQDN, which as we see here is unstable.
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'd agree, but you do not have the id at the time we now calculate the redirect.
I think we need a better approach. @amirfefer I've added test cases for both failing scenarios.
My approach is fixing the first, but as expected it fails for the second (append_domain_name_for_hosts = 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.
Shouldn't the interaction be to POST
and then wait for the response. That should give you the correct URL. Guessing it client side is IMHO a bad way. What if the request fails? Then it will result in a 404.
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 should, but as many things in life, theory and practice do not overlap :(
Just to get this whole thing clear, even if it's just in my head. The code we're talking about is:
foreman/app/assets/javascripts/host_edit.js
Lines 161 to 201 in 2152852
function submit_with_all_params() { | |
var fqdn = $('.fqdn')[0].textContent; | |
$('form.hostresource-form input[type="submit"]').attr('disabled', true); | |
stop_pooling = false; | |
$('body').css('cursor', 'progress'); | |
clear_errors(); | |
animate_progress(); | |
$.ajax({ | |
type: 'POST', | |
url: $('form').attr('action'), | |
data: serializeForm(), | |
success: function(response) { | |
// workaround for redirecting to the new host details page | |
if (!response.includes('id="main"')) { | |
return tfm.nav.pushUrl('/new/hosts/' + fqdn); | |
} | |
$('#host-progress').hide(); | |
$('#content').replaceWith($('#content', response)); | |
$(document.body).trigger('ContentLoad'); | |
if ($("[data-history-url]").exists()) { | |
history.pushState({}, 'Host show', $("[data-history-url]").data('history-url')); | |
} | |
}, | |
error: function(response) { | |
$('#content').html(response.responseText); | |
}, | |
complete: function() { | |
stop_pooling = true; | |
$('body').css('cursor', 'auto'); | |
$('form input[type="submit"]').attr('disabled', false); | |
if (window.location.pathname !== tfm.tools.foremanUrl('/hosts/new')) { | |
// We got redirected to the show page, need to clear the title override | |
tfm.store.dispatch('updateBreadcrumbTitle'); | |
} | |
}, | |
}); | |
return false; | |
} |
And really, in particular the success bit:
foreman/app/assets/javascripts/host_edit.js
Lines 173 to 185 in 2152852
success: function(response) { | |
// workaround for redirecting to the new host details page | |
if (!response.includes('id="main"')) { | |
return tfm.nav.pushUrl('/new/hosts/' + fqdn); | |
} | |
$('#host-progress').hide(); | |
$('#content').replaceWith($('#content', response)); | |
$(document.body).trigger('ContentLoad'); | |
if ($("[data-history-url]").exists()) { | |
history.pushState({}, 'Host show', $("[data-history-url]").data('history-url')); | |
} | |
}, |
That needs to ensure you're on the correct page. In particular the whole success bit. I still don't really see a reason we can't make sure response
has a Location
field and then push that URL to the state.
For the creation we have:
process_success :success_redirect => current_host_details_path(@host) |
Then for updating we have:
foreman/app/controllers/hosts_controller.rb
Line 117 in 2152852
process_success :success_redirect => current_host_details_path(@host) |
This means both go through
current_host_details_path
:foreman/app/controllers/hosts_controller.rb
Lines 926 to 928 in 2152852
def current_host_details_path(host) | |
Setting['host_details_ui'] ? host_details_page_path(host) : host_path(host) | |
end |
So what's the reason we can't use Location
header from that returned response? The server already knows the URL and sends it. We just have to use it.
Note that according to the jquery docs you can specify success as Type: Function( Anything data, String textStatus, jqXHR jqXHR )
. The jqXHR argument has a getResponseHeader(name)
method, so I think it should work to change the signature and use new_url = jqXHR.getResponseHeader('Location')
.
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 thought it would be in the header, but apparently that object (jqXHR) has headers for the redirect, only content for the final page, I thought we could use responseURL
, but this is not implemented in jquery: jquery/jquery#4339
< jqXHR.getResponseHeader('Location')
> null
< jqXHR.getAllResponseHeaders()
> `cache-control: max-age=0, private, must-revalidate\r\ncontent-security-policy: default-src 'self' localhost:3808; child-src 'self'; connect-src 'self' ws: wss: localhost:3808; font-src 'self' data: http://localhost:3808; img-src 'self' data: localhost:3808; script-src 'unsafe-eval' 'unsafe-inline' 'self' localhost:3808; style-src 'unsafe-inline' 'self' localhost:3808\r\ncontent-type: text/html; charset=utf-8\r\netag: W/"4ae9ec52826ccc3a67a7eadbd03c41f1"\r\ntransfer-encoding: chunked\r\nx-content-type-options: nosniff\r\nx-download-options: noopen\r\nx-frame-options: sameorigin\r\nx-permitted-cross-domain-policies: none\r\nx-request-id: d6000a26-bda2-44cb-be4f-93d44f9f4469\r\nx-runtime: 0.125798\r\nx-xss-protection: 1; mode=block\r\n`
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.
Man, software ...
Would it make sense to use native browser methods rather than jquery? It's not like the bad old days where you really wanted jquery for cross browser compatibility.
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, it would most definitelly be better, but we would drop IE10 support and it would mean rewriting quite a significant portion of host_edit.js
which I'd not recommend cherry-picking in 3.1
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.
Are you thinking about the fetch API that IE10 doesn't support? Couldn't you use XmlHttpRequest, which is available for a long time?
Also, it's unclear if we actually need to support IE10. Patternfly 4 doesn't and we've included that since Foreman 2.1: theforeman/theforeman.org#1933. Perhaps we already broke it anyway?
5fa5bca
to
528b9c9
Compare
app/assets/javascripts/host_edit.js
Outdated
success: function(response) { | ||
// workaround for redirecting to the new host details page | ||
if (!response.includes('id="main"')) { | ||
return tfm.nav.pushUrl('/new/hosts/' + fqdn); | ||
return tfm.nav.pushUrl('/new/hosts/' + host_unique_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.
Please see #9047 (comment).
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.
Unfortunatelly I've already tried that. I'm adding those parameters to indicate those were tried with no success.
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.
As of now this fixes the issue for the two cases that I'm aware of and added tests to. It is not perfect and it is hacky, but without serious rewrite of host_edit.js
I do not see a better way.
528b9c9
to
7f72dbb
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.
@amirfefer could you take a look at the JS code?
function update_fqdn() { | ||
var host_name = $('#host_name').val(); | ||
function construct_host_name() { | ||
var $host_name = $('#host_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.
Why $host_name
? is that even valid for a variable name? My JS knowledge is lacking here.
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'm marking the jQuery holding variables like that. It is valid, but weird, so maybe better to avoid if it's causing confusion 👍
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 agree that it's confusing a bit
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.
Thanks @ezr-ondrej and @ekohl
I agree that we should have a better approach, I guess it would be easier when we will drop the old page.
function update_fqdn() { | ||
var host_name = $('#host_name').val(); | ||
function construct_host_name() { | ||
var $host_name = $('#host_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 agree that it's confusing a bit
app/assets/javascripts/host_edit.js
Outdated
// workaround for redirecting to the new host details page | ||
if (!response.includes('id="main"')) { | ||
return tfm.nav.pushUrl('/new/hosts/' + fqdn); | ||
return tfm.nav.pushUrl('/new/hosts/' + host_unique_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.
do we need to wrap it with foremanUrl
?
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, it is not used for anything useful, but it might in the future :)
Tested with managed and unmanaged hosts, creating and editing. works well 👍 |
In host form we've used a hack in 2876578 to redirect to the new Host details page. It relied on the primary interface being the first interface in the table. This fixes it to always incur the correct fqdn.
7f72dbb
to
a2bd297
Compare
[test foreman] |
The test will not finish. It's getting consistently stuck :/ |
CI is stuck so I'm going to merge it now. I trust @amirfefer who said in #9047 (comment) he verified this. |
Cherry pick to 3.1: 700d707 |
Not sure how host names work but I'm having an issue with this pr where the host
|
In host form we've used a hack in 2876578 to redirect to the new Host details page.
It relied on the primary interface being the first interface in the table.
This fixes it to always incur the correct fqdn.