-
Notifications
You must be signed in to change notification settings - Fork 20
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
fix(credentials): set backend storage as default #672
Conversation
4c9d156
to
b07327b
Compare
Actually, I messed around with UI and somehow found this way to consistently reproduce it. The steps are similar to the description of #673 To reproduce
Could you try if this happens on your end too? ObservationsRequests are sent with correct username/password (i.e. credential map holds correct record and console.log shows correct Basic header being added). |
Yes, these reproduction steps work for me. Interestingly, the |
Recordings (broken): Request:
Response:
Events (working): Request:
Response:
|
So it looks like this is probably actually a backend bug after all. Setting the credentials storage to Backend is still an effective workaround. |
Also very interesting. After reproducing the bug with Thuan's steps above, I tried setting the storage to Backend, then closing and reopening the web-client browser tab. Then I went back to the Recordings view. There were multiple |
Interesting, i saw the same issue. It seems like its only broken in Recording view. Should we transfer this issue to the backend repo? Also are we good with this workaround? |
Let's confirm the exact root cause of the problem before transferring the issue, just so we don't end up transferring it back and forth. Worth considering still that there are backend itests that exercise what should be the same code path and those pass, so there's something odd going on at some level or another and I don't think we've fully nailed down what or where it is yet. Anyway I'm good with the workaround of setting the default to backend. That's actually closer to what 2.1 was doing anyway. Could you split out the change that changes the default into a separate PR, which can be merged and backported separately without these other refactoring fixes? Only the change of default should go into a backport for 2.2.1. |
b07327b
to
a57178f
Compare
Okayy updated :D I will open another PR for the clean up. |
Just confirming that I see the same issue. My first instinct is that it might be because computing a jvmId uses back-end credentials instead of using session memory? I'm not sure if it does, but I see after performing the snapshot request:
then maybe it tries to use credentials it can't find... |
Aha, that's a good insight. I didn't check the backend logs during the test run but that makes a lot of sense. I think that's the next most obvious candidate bug to work through. If that is the cause then in order for the Session storage to work properly again we'll need to introduce some larger notion of a request state/session on the backend so that the JMX credentials can follow through the execution path. That might be tough. Though, I'm not sure then why this bug manifests on the Recordings view and not Events. |
(cherry picked from commit 7ba910e) # Conflicts: # src/test/Settings/CredentialsStorage.test.tsx
I think it's just cause eventGet endpoint doesn't generate or get jvmIds but things like RecordingPost, SnapshotPost, MetadataPost all do... I think everything glaringly points to jvmIds at this point, and I agree there the two methods of using credentials should somehow follow the same execution path to compute the ids for the session state to work. I'll see if I can try something to fix this. |
Ahh, those things need the JVM ID present because they do things like storing metadata or archives, and nothing in the Events view does that so the JVM ID code path never gets hit. I see. Yea... that's a little rough. So for session authentication to continue working we do need some way to allow those credentials to pass from the API handlers all the way through the call stack. Not conceptually hard but that's going to be a large refactoring surface. |
Yes, stuff like this.targetConnectionManager.executeConnectedTaskAsync(
new ConnectionDescriptor(
sr.getServiceUri().toString(),
credentialsManager.getCredentials(sr)),
connection -> {
return connection.getJvmId(); wouldn't work because the |
So then perhaps we don't actually have any integration tests that exercise this path then, right? I know we have tests that exercise starting recordings and taking snapshots, test that exercise retrieving event types and templates, and tests that use JMX Auth, but maybe we don't have tests that try to start recordings on targets that need auth.
|
Though, it looks like private void createInMemoryRecordings() throws Exception {
List<CompletableFuture<Void>> cfs = new ArrayList<>();
for (int i = 0; i < CONTAINERS.size(); i++) {
final int fi = i;
CompletableFuture<Void> cf = new CompletableFuture<>();
cfs.add(cf);
Podman.POOL.submit(
() -> {
MultiMap form = MultiMap.caseInsensitiveMultiMap();
form.add("recordingName", "interleaved-" + fi);
form.add("events", "template=Continuous");
webClient
.post(
String.format(
"/api/v1/targets/%s/recordings",
Podman.POD_NAME + ":" + (9093 + fi)))
.putHeader(
"X-JMX-Authorization",
"Basic "
+ Base64.getUrlEncoder()
.encodeToString(
"admin:adminpass123".getBytes()))
.sendForm(
form,
ar -> {
if (assertRequestStatus(ar, cf)) {
cf.complete(null);
}
});
});
}
CompletableFuture.allOf(cfs.toArray(new CompletableFuture[0]))
.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} |
Is JMX auth enabled for those targets? Don't they need a key value pair of "JMX_AUTH, true" in the |
This might be something we wait to fix until Cryostat 3.0, honestly. It seems to me the best way to handle this is to rearchitect a lot of Cryostat's internal infastructure to be scope to the lifetime of the request rather than having a static lifetime for the whole application. ie, there would be a new |
Ha. You are correct, the test is broken and the external app containers don't actually require JMX auth. Wow... |
@BeforeAll
static void setup() throws Exception {
Set<Podman.ImageSpec> specs = new HashSet<>();
for (int i = 0; i < NUM_EXT_CONTAINERS; i++) {
specs.add(
new Podman.ImageSpec(
FIB_DEMO_IMAGESPEC, Map.of("JMX_PORT", String.valueOf(9093 + i))));
--> // This Map also needs "USE_AUTH", "true"
}
for (Podman.ImageSpec spec : specs) {
CONTAINERS.add(Podman.run(spec));
}
CompletableFuture.allOf(
CONTAINERS.stream()
.map(id -> Podman.waitForContainerState(id, "running"))
.collect(Collectors.toList())
.toArray(new CompletableFuture[0]))
.join();
waitForDiscovery(NUM_EXT_CONTAINERS);
} |
@maxcao13 @tthvo would one of you like to take on fixing that itest above so it actually sets up the containers to require credentials? It might end up failing right now, so I think we can mark it as a known failure like this: https://stackoverflow.com/questions/4055022/mark-unit-test-as-an-expected-failure-in-junit , at least until we come up with some fix for the implementation. |
Sure I can do that. |
Related to #656
Use Backend storage as default. This does not fix the issue but just switch it default Backend.