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

RHOAIENG-14782: fix(PipelineV2ServerST): remove obsolete devflags and use the public route for pipelines server api #168

Merged
merged 3 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions src/main/java/io/odh/test/platform/KFPv2Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,26 @@ public class KFPv2Client {
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.enable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION)
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
private final HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.followRedirects(HttpClient.Redirect.NORMAL)
.build();

private final HttpClient httpClient;
private final String baseUrl;
private final String oauthToken;

public KFPv2Client(String baseUrl) {
public KFPv2Client(HttpClient httpClient, String baseUrl, String oauthToken) {
this.httpClient = httpClient;
this.baseUrl = baseUrl;
this.oauthToken = oauthToken;
}

@SneakyThrows
public Pipeline importPipeline(String name, String description, String filePath) {
MultipartFormDataBodyPublisher requestBody = new MultipartFormDataBodyPublisher()
.addFile("uploadfile", Path.of(filePath), "application/yaml");

HttpRequest createPipelineRequest = HttpRequest.newBuilder()
HttpRequest createPipelineRequest = buildRequest()
.uri(new URI(baseUrl + "/apis/v2beta1/pipelines/upload?name=%s&description=%s".formatted(name, description)))
.header("Content-Type", requestBody.contentType())
.POST(requestBody)
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();
HttpResponse<String> responseCreate = httpClient.send(createPipelineRequest, HttpResponse.BodyHandlers.ofString());

Expand All @@ -69,10 +68,9 @@ public Pipeline importPipeline(String name, String description, String filePath)

@SneakyThrows
public @Nonnull List<Pipeline> listPipelines() {
HttpRequest request = HttpRequest.newBuilder()
HttpRequest request = buildRequest()
.uri(URI.create(baseUrl + "/apis/v2beta1/pipelines"))
.GET()
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();

HttpResponse<String> reply = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Expand All @@ -86,10 +84,9 @@ public Pipeline importPipeline(String name, String description, String filePath)

@SneakyThrows
public @Nonnull List<PipelineVersion> listPipelineVersions(String pipelineId) {
HttpRequest request = HttpRequest.newBuilder()
HttpRequest request = buildRequest()
.uri(URI.create(baseUrl + "/apis/v2beta1/pipelines/" + pipelineId + "/versions"))
.GET()
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();

HttpResponse<String> reply = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Expand All @@ -113,10 +110,9 @@ public PipelineRun runPipeline(String pipelineTestRunBasename, String pipelineId
pipelineRun.runtimeConfig = new RuntimeConfig();
pipelineRun.runtimeConfig.parameters = parameters;
}
HttpRequest request = HttpRequest.newBuilder()
HttpRequest request = buildRequest()
.uri(URI.create(baseUrl + "/apis/v2beta1/runs"))
.POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(pipelineRun)))
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();
HttpResponse<String> reply = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

Expand All @@ -126,10 +122,9 @@ public PipelineRun runPipeline(String pipelineTestRunBasename, String pipelineId

@SneakyThrows
public List<PipelineRun> getPipelineRunStatus() {
HttpRequest request = HttpRequest.newBuilder()
HttpRequest request = buildRequest()
.uri(URI.create(baseUrl + "/apis/v2beta1/runs"))
.GET()
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();
HttpResponse<String> reply = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

Expand All @@ -139,10 +134,9 @@ public List<PipelineRun> getPipelineRunStatus() {

@SneakyThrows
public PipelineRun waitForPipelineRun(String pipelineRunId) {
HttpRequest request = HttpRequest.newBuilder()
HttpRequest request = buildRequest()
.uri(URI.create(baseUrl + "/apis/v2beta1/runs/" + pipelineRunId))
.GET()
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();

AtomicReference<PipelineRun> run = new AtomicReference<>();
Expand Down Expand Up @@ -177,32 +171,29 @@ public PipelineRun waitForPipelineRun(String pipelineRunId) {

@SneakyThrows
public void deletePipelineRun(String runId) {
HttpRequest request = HttpRequest.newBuilder()
HttpRequest request = buildRequest()
.uri(URI.create(baseUrl + "/apis/v2beta1/runs/" + runId))
.DELETE()
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();
HttpResponse<String> reply = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Assertions.assertEquals(200, reply.statusCode(), reply.body());
}

@SneakyThrows
public void deletePipeline(String pipelineId) {
HttpRequest request = HttpRequest.newBuilder()
HttpRequest request = buildRequest()
.uri(URI.create(baseUrl + "/apis/v2beta1/pipelines/" + pipelineId))
.DELETE()
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();
HttpResponse<String> reply = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Assertions.assertEquals(200, reply.statusCode(), reply.body());
}

@SneakyThrows
public void deletePipelineVersion(String pipelineId, String pipelineVersionId) {
HttpRequest request = HttpRequest.newBuilder()
HttpRequest request = buildRequest()
.uri(URI.create(baseUrl + "/apis/v2beta1/pipelines/" + pipelineId + "/versions/" + pipelineVersionId))
.DELETE()
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()))
.build();
HttpResponse<String> reply = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Assertions.assertEquals(200, reply.statusCode(), reply.body());
Expand Down Expand Up @@ -270,4 +261,13 @@ public static class RuntimeConfig {
public Object parameters;
public String pipelineRoot;
}

private HttpRequest.Builder buildRequest() {
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.timeout(Duration.of(DEFAULT_TIMEOUT_DURATION, DEFAULT_TIMEOUT_UNIT.toChronoUnit()));
if (oauthToken != null) {
requestBuilder.header("Authorization", "Bearer " + oauthToken);
}
return requestBuilder;
}
}
59 changes: 59 additions & 0 deletions src/main/java/io/odh/test/platform/httpClient/OAuthToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright Skodjob authors.
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
*/
package io.odh.test.platform.httpClient;

import io.fabric8.openshift.api.model.OAuthAccessToken;
import io.fabric8.openshift.api.model.OAuthAccessTokenBuilder;
import io.fabric8.openshift.api.model.OAuthClient;
import io.fabric8.openshift.api.model.OAuthClientBuilder;
import io.fabric8.openshift.api.model.User;
import io.skodjob.testframe.resources.KubeResourceManager;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Random;

public class OAuthToken {
public String getToken(String redirectUrl) throws NoSuchAlgorithmException {
// https://github.com/openshift/cluster-authentication-operator/blob/master/test/library/client.go#L35-L44
MessageDigest digest = MessageDigest.getInstance("SHA-256");
String sha256Prefix = "sha256~";
String randomToken = "nottoorandom%d".formatted(new Random().nextInt());
byte[] hashed = digest.digest(randomToken.getBytes(StandardCharsets.UTF_8));
String privateToken = sha256Prefix + randomToken;
String publicToken = sha256Prefix + Base64.getUrlEncoder().withoutPadding().encodeToString(hashed);

User user = KubeResourceManager.getKubeClient().getOpenShiftClient().users().withName("kubeadmin").get();

final String oauthClientName = "oauth-client";
OAuthClient client = new OAuthClientBuilder()
.withNewMetadata()
.withName(oauthClientName)
.endMetadata()
.withSecret("the-secret-for-oauth-client")
.withRedirectURIs("https://localhost")
.withGrantMethod("auto")
.withAccessTokenInactivityTimeoutSeconds(300)
.build();
KubeResourceManager.getInstance().createResourceWithoutWait(client);

OAuthAccessToken token = new OAuthAccessTokenBuilder()
.withNewMetadata()
.withName(publicToken)
.endMetadata()
.withExpiresIn(86400L)
.withScopes("user:full")
.withRedirectURI(redirectUrl)
.withClientName(oauthClientName)
.withUserName(user.getMetadata().getName())
.withUserUID(user.getMetadata().getUid())
.build();
KubeResourceManager.getInstance().createResourceWithWait(token);

return privateToken;
}
}
50 changes: 3 additions & 47 deletions src/test/java/io/odh/test/e2e/standard/DistributedST.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,15 @@
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
import io.fabric8.openshift.api.model.OAuthAccessToken;
import io.fabric8.openshift.api.model.OAuthAccessTokenBuilder;
import io.fabric8.openshift.api.model.OAuthClient;
import io.fabric8.openshift.api.model.OAuthClientBuilder;
import io.fabric8.openshift.api.model.Route;
import io.fabric8.openshift.api.model.User;
import io.fabric8.openshift.client.OpenShiftClient;
import io.odh.test.Environment;
import io.odh.test.OdhAnnotationsLabels;
import io.odh.test.TestUtils;
import io.odh.test.install.InstallTypes;
import io.odh.test.platform.RayClient;
import io.odh.test.platform.TlsUtils;
import io.odh.test.platform.httpClient.OAuthToken;
import io.odh.test.utils.CsvUtils;
import io.odh.test.utils.DscUtils;
import io.opendatahub.datasciencecluster.v1.DataScienceCluster;
Expand Down Expand Up @@ -53,12 +49,8 @@
import org.slf4j.LoggerFactory;

import java.net.http.HttpClient;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;

Expand Down Expand Up @@ -197,44 +189,8 @@ void testDistributedWorkloadWithKueue() throws Exception {
final String clusterQueueName = "cluster-queue";
final String localQueueName = "local-queue";

// https://github.com/openshift/cluster-authentication-operator/blob/master/test/library/client.go#L35-L44
MessageDigest digest = MessageDigest.getInstance("SHA-256");
String sha256Prefix = "sha256~";
String randomToken = "nottoorandom%d".formatted(new Random().nextInt());
byte[] hashed = digest.digest(randomToken.getBytes(StandardCharsets.UTF_8));
String privateToken = sha256Prefix + randomToken;
String publicToken = sha256Prefix + Base64.getUrlEncoder().withoutPadding().encodeToString(hashed);

String oauthToken = Allure.step("Create OAuth Token", () -> {
User user = kubeClient.users().withName("kubeadmin").get();

final String oauthClientName = "oauth-client";
OAuthClient client = new OAuthClientBuilder()
.withNewMetadata()
.withName(oauthClientName)
.endMetadata()
.withSecret("the-secret-for-oauth-client")
.withRedirectURIs("https://localhost")
.withGrantMethod("auto")
.withAccessTokenInactivityTimeoutSeconds(300)
.build();
KubeResourceManager.getInstance().createResourceWithoutWait(client);

OAuthAccessToken token = new OAuthAccessTokenBuilder()
.withNewMetadata()
.withName(publicToken)
.endMetadata()
.withExpiresIn(86400L)
.withScopes("user:full")
.withRedirectURI("https://ray-dashboard-koranteng-test-codeflare.apps-crc.testing/oauth/callback")
.withClientName(oauthClientName)
.withUserName(user.getMetadata().getName())
.withUserUID(user.getMetadata().getUid())
.build();
KubeResourceManager.getInstance().createResourceWithWait(token);

return privateToken;
});
String redirectUrl = "https://ray-dashboard-koranteng-test-codeflare.apps-crc.testing/oauth/callback";
String oauthToken = Allure.step("Create OAuth Token", () -> new OAuthToken().getToken(redirectUrl));

Allure.step("Setup resources", () -> {
Allure.step("Create namespace", () -> {
Expand Down
Loading