Create selenium test user in Eclipse Che on OCP remotely (#9982)
* Add KeycloakCommandExecutor to create test user in selenium tests * Create test user in Eclipse Che on OCP which is run remotely Signed-off-by: Dmytro Nochevnov <dnochevnov@codenvy.com>6.19.x
parent
4d76916632
commit
e75fbce93f
|
|
@ -47,7 +47,7 @@ public class DockerUtil {
|
|||
String command = "docker run --rm --net host eclipse/che-ip:nightly";
|
||||
|
||||
try {
|
||||
String cheIpAddress = processAgent.execute(command);
|
||||
String cheIpAddress = processAgent.process(command);
|
||||
|
||||
if (cheIpAddress != null && cheHostParameter.contains(cheIpAddress)) {
|
||||
return true;
|
||||
|
|
@ -71,7 +71,7 @@ public class DockerUtil {
|
|||
String copyCommand =
|
||||
format("docker cp %1$s:%2$s %3$s", containerId, pathInsideContainer, copyTo);
|
||||
|
||||
processAgent.execute(copyCommand);
|
||||
processAgent.process(copyCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -88,7 +88,7 @@ public class DockerUtil {
|
|||
"docker ps -q --filter='name=selenium_chromenode*' | xargs docker inspect --format '{{ .Id }} {{ .NetworkSettings.Networks.selenium_selenium_grid_internal.IPAddress }}' | grep %s | awk 'NR>0 {print $1;}'",
|
||||
IP);
|
||||
|
||||
return processAgent.execute(getContainerIdCommand);
|
||||
return processAgent.process(getContainerIdCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -102,6 +102,6 @@ public class DockerUtil {
|
|||
String deleteInsideContainer =
|
||||
format("docker exec -i %s sh -c 'rm -fr %s'", gridNodeContainerId, pathToDelete);
|
||||
|
||||
processAgent.execute(deleteInsideContainer);
|
||||
processAgent.process(deleteInsideContainer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import org.slf4j.LoggerFactory;
|
|||
public class ProcessAgent {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ProcessAgent.class);
|
||||
|
||||
public String execute(String command) throws ProcessAgentException {
|
||||
public String process(String command) throws ProcessAgentException {
|
||||
try {
|
||||
Process process = getProcess(command);
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ public class ProcessAgent {
|
|||
|
||||
return processOutput(exitStatus, in, err);
|
||||
} catch (Exception e) {
|
||||
String errMessage = format("Can't execute command '%s'.", command);
|
||||
String errMessage = format("Can't process command '%s'.", command);
|
||||
throw new ProcessAgentException(errMessage, e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ public abstract class TestWorkspaceLogsReader {
|
|||
try {
|
||||
Files.createDirectories(testLogsDirectory.getParent());
|
||||
|
||||
// execute command to copy logs from workspace container to the workspaceLogsDir
|
||||
processAgent.execute(
|
||||
// process command to copy logs from workspace container to the workspaceLogsDir
|
||||
processAgent.process(
|
||||
getReadLogsCommand(workspaceId, testLogsDirectory, logInfo.getLocationInsideWorkspace()));
|
||||
} catch (Exception e) {
|
||||
log.warn(
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ github.auxiliary.username=<AUXILIARY_GITHUB_USERNAME>
|
|||
github.auxiliary.password=<AUXILIARY_GITHUB_PASSWORD>
|
||||
```
|
||||
|
||||
In case of running of tests for Eclipse Che in Multi User mode you can set your own credentials of test user or admin instead of default ones
|
||||
In case of running the tests for Eclipse Che in Multi User mode you can set your own credentials of test user or admin instead of default ones
|
||||
```
|
||||
export CHE_ADMIN_NAME=<che_admin_name>
|
||||
export CHE_ADMIN_EMAIL=<che_admin_email>
|
||||
export CHE_ADMIN_PASSWORD=<che_admin_password>
|
||||
|
|
@ -32,6 +33,12 @@ export CHE_ADMIN_PASSWORD=<che_admin_password>
|
|||
export CHE_TESTUSER_NAME=<che_test_user_name>
|
||||
export CHE_TESTUSER_EMAIL=<che_test_user_email>
|
||||
export CHE_TESTUSER_PASSWORD=<che_test_user_password>
|
||||
```
|
||||
|
||||
Default values:
|
||||
- CHE_ADMIN_NAME: "admin"
|
||||
- CHE_ADMIN_EMAIL: "admin@admin.com"
|
||||
- CHE_ADMIN_PASSWORD: "admin"
|
||||
|
||||
#### 3. Prepare repository
|
||||
Fork all repositories from [https://github.com/idexmai?tab=repositories](https://github.com/idexmai?tab=repositories) into the main GitHub account.
|
||||
|
|
@ -45,14 +52,32 @@ Follow the guide: [https://github.com/eclipse/che](https://github.com/eclipse/ch
|
|||
|
||||
Simply launch `./selenium-tests.sh`
|
||||
|
||||
### How to run tests on OpenShift
|
||||
### How to run tests on Open Shift
|
||||
#### 1. Set workspace runtime infrastructure implementation
|
||||
export CHE_INFRASTRUCTURE=openshift
|
||||
#### 2. Run tests and specify host and port of Che deployed to OpenShift
|
||||
#### 2. Run tests and specify host and port of Che deployed to Open Shift
|
||||
Launch `./selenium-tests.sh --host=<Che host on openshift> --port=80`
|
||||
|
||||
Example: `./selenium-tests.sh --host=che-spi.192.168.99.100.nip.io --port=80`
|
||||
|
||||
In case of running the tests for Eclipse Che on OCP, which is run remotely with default Eclipse Che admin and test user credentials:
|
||||
```
|
||||
export OPENSHIFT_USERNAME=<openshift_web_console_username>
|
||||
export OPENSHIFT_PASSWORD=<openshift_web_console_password>
|
||||
export OPENSHIFT_TOKEN=<openshift_web_console_bearer_auth_token>
|
||||
export OPENSHIFT_CHE_NAMESPACE=<namespace_of_eclipse_che_deployed_on_openshift>
|
||||
export OPENSHIFT_URL=<url_of_openshift_web_console>
|
||||
```
|
||||
where `OPENSHIFT_TOKEN` is optional and is aimed to replace username/password when Open Shift is configured with oAuth.
|
||||
|
||||
|
||||
Default values:
|
||||
- OPENSHIFT_USERNAME: "developer"
|
||||
- OPENSHIFT_PASSWORD: "any"
|
||||
- OPENSHIFT_CHE_NAMESPACE: "eclipse-che"
|
||||
- OPENSHIFT_URL: https://<che_host_ip>:8443
|
||||
|
||||
|
||||
Run tests configuration properties
|
||||
--------------------------------------
|
||||
```
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@
|
|||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-assistedinject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
package org.eclipse.che.selenium.core;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.executor.DockerKeycloakCommandExecutor;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.executor.KeycloakCommandExecutor;
|
||||
import org.eclipse.che.selenium.core.workspace.CheTestDockerWorkspaceLogsReader;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspaceLogsReader;
|
||||
|
||||
|
|
@ -20,5 +22,6 @@ public class CheSeleniumDockerModule extends AbstractModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
bind(TestWorkspaceLogsReader.class).to(CheTestDockerWorkspaceLogsReader.class);
|
||||
bind(KeycloakCommandExecutor.class).to(DockerKeycloakCommandExecutor.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ import com.google.inject.TypeLiteral;
|
|||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
import org.eclipse.che.selenium.core.client.CheTestDefaultOrganizationServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.CheTestMachineServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.KeycloakTestAuthServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.TestAuthServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.TestMachineServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.TestOrganizationServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.TestOrganizationServiceClientFactory;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.KeycloakTestAuthServiceClient;
|
||||
import org.eclipse.che.selenium.core.provider.AdminTestUserProvider;
|
||||
import org.eclipse.che.selenium.core.provider.DefaultTestUserProvider;
|
||||
import org.eclipse.che.selenium.core.provider.TestUserProvider;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
package org.eclipse.che.selenium.core;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.executor.KeycloakCommandExecutor;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.executor.OpenShiftKeycloakCommandExecutor;
|
||||
import org.eclipse.che.selenium.core.workspace.CheTestOpenshiftWorkspaceLogsReader;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspaceLogsReader;
|
||||
|
||||
|
|
@ -20,5 +22,6 @@ public class CheSeleniumOpenshiftModule extends AbstractModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
bind(TestWorkspaceLogsReader.class).to(CheTestOpenshiftWorkspaceLogsReader.class);
|
||||
bind(KeycloakCommandExecutor.class).to(OpenShiftKeycloakCommandExecutor.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,18 +8,16 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
package org.eclipse.che.selenium.core.client.keycloak;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.eclipse.che.selenium.core.CheSeleniumSuiteModule.DOCKER_INFRASTRUCTURE;
|
||||
import static org.eclipse.che.selenium.core.CheSeleniumSuiteModule.OPENSHIFT_INFRASTRUCTURE;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.executor.KeycloakCommandExecutor;
|
||||
import org.eclipse.che.selenium.core.provider.AdminTestUserProvider;
|
||||
import org.eclipse.che.selenium.core.provider.RemovableUserProvider;
|
||||
import org.eclipse.che.selenium.core.user.AdminTestUser;
|
||||
|
|
@ -27,14 +25,11 @@ import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
|||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
import org.eclipse.che.selenium.core.user.TestUserFactory;
|
||||
import org.eclipse.che.selenium.core.user.TestUserImpl;
|
||||
import org.eclipse.che.selenium.core.utils.DockerUtil;
|
||||
import org.eclipse.che.selenium.core.utils.process.ProcessAgent;
|
||||
import org.eclipse.che.selenium.core.utils.process.ProcessAgentException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This is java-client of 'keycloak/bin/kcadm.sh' command line application of keycloak container
|
||||
* This is java-client of 'keycloak/bin/kcadm.sh' command line application
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
|
|
@ -47,53 +42,20 @@ public class KeycloakAdminConsoleClient {
|
|||
// we need to inject AdminTestUser separately to avoid circular dependency error
|
||||
@Inject private AdminTestUserProvider adminTestUserProvider;
|
||||
|
||||
private final DockerUtil dockerUtil;
|
||||
private final TestUserFactory<DefaultTestUser> defaultTestUserFactory;
|
||||
private final TestUserFactory<TestUserImpl> testUserFactory;
|
||||
private final ProcessAgent processAgent;
|
||||
private final String keycloakContainerId;
|
||||
private final String cheInfrastructure;
|
||||
|
||||
@Inject private KeycloakCommandExecutor executor;
|
||||
|
||||
@Inject
|
||||
public KeycloakAdminConsoleClient(
|
||||
DockerUtil dockerUtil,
|
||||
TestUserFactory<TestUserImpl> testUserFactory,
|
||||
TestUserFactory<DefaultTestUser> defaultTestUserFactory,
|
||||
ProcessAgent processAgent,
|
||||
@Named("che.infrastructure") String cheInfrastructure)
|
||||
throws ProcessAgentException {
|
||||
this.dockerUtil = dockerUtil;
|
||||
TestUserFactory<DefaultTestUser> defaultTestUserFactory) {
|
||||
this.testUserFactory = testUserFactory;
|
||||
this.defaultTestUserFactory = defaultTestUserFactory;
|
||||
this.processAgent = processAgent;
|
||||
this.cheInfrastructure = cheInfrastructure;
|
||||
|
||||
// obtain id of keycloak docker container
|
||||
switch (cheInfrastructure) {
|
||||
case OPENSHIFT_INFRASTRUCTURE:
|
||||
this.keycloakContainerId =
|
||||
processAgent.execute("echo $(docker ps | grep 'keycloak_keycloak-' | cut -d ' ' -f1)");
|
||||
break;
|
||||
|
||||
case DOCKER_INFRASTRUCTURE:
|
||||
default:
|
||||
this.keycloakContainerId =
|
||||
processAgent.execute("echo $(docker ps | grep che_keycloak | cut -d ' ' -f1)");
|
||||
break;
|
||||
}
|
||||
|
||||
if (keycloakContainerId.trim().isEmpty()) {
|
||||
throw new RuntimeException(
|
||||
"Keycloak container is not found. Make sure that correct value is set for `CHE_INFRASTRUCTURE`.");
|
||||
}
|
||||
}
|
||||
|
||||
public TestUserImpl createUser(RemovableUserProvider testUserProvider) throws IOException {
|
||||
if (!dockerUtil.isCheRunLocally()) {
|
||||
throw new IOException(
|
||||
"It's impossible to create test user because of Che is running on the different host.");
|
||||
}
|
||||
|
||||
long currentTimeInMillisec = System.currentTimeMillis();
|
||||
String username = "user" + currentTimeInMillisec;
|
||||
String email = username + "@1.com";
|
||||
|
|
@ -108,11 +70,6 @@ public class KeycloakAdminConsoleClient {
|
|||
|
||||
public DefaultTestUser createDefaultUser(RemovableUserProvider testUserProvider)
|
||||
throws IOException {
|
||||
if (!dockerUtil.isCheRunLocally()) {
|
||||
throw new IOException(
|
||||
"It's impossible to create test user because of Che is running on the different host.");
|
||||
}
|
||||
|
||||
long currentTimeInMillisec = System.currentTimeMillis();
|
||||
String username = "user" + currentTimeInMillisec;
|
||||
String email = username + "@1.com";
|
||||
|
|
@ -133,9 +90,9 @@ public class KeycloakAdminConsoleClient {
|
|||
|
||||
String createUserCommand =
|
||||
format(
|
||||
"docker exec -i %s sh -c 'keycloak/bin/kcadm.sh create users -r che -s username=%s -s enabled=true %s 2>&1'",
|
||||
keycloakContainerId, username, authPartOfCommand);
|
||||
String response = processAgent.execute(createUserCommand);
|
||||
"create users -r che -s username=%s -s enabled=true %s 2>&1",
|
||||
username, authPartOfCommand);
|
||||
String response = executor.execute(createUserCommand);
|
||||
if (!response.contains("Created new user with id ")) {
|
||||
throw new IOException("Test user creation error: " + response);
|
||||
}
|
||||
|
|
@ -145,27 +102,25 @@ public class KeycloakAdminConsoleClient {
|
|||
try {
|
||||
String setTestUsersPermanentPasswordCommand =
|
||||
format(
|
||||
"docker exec -i %s sh -c 'keycloak/bin/kcadm.sh set-password -r che --username %s --new-password %s %s 2>&1'",
|
||||
keycloakContainerId, username, password, authPartOfCommand);
|
||||
processAgent.execute(setTestUsersPermanentPasswordCommand);
|
||||
"set-password -r che --username %s --new-password %s %s 2>&1",
|
||||
username, password, authPartOfCommand);
|
||||
executor.execute(setTestUsersPermanentPasswordCommand);
|
||||
|
||||
String setEmailCommand =
|
||||
format(
|
||||
"docker exec -i %s sh -c 'keycloak/bin/kcadm.sh update users/%s -r che --set email=%s %s 2>&1'",
|
||||
keycloakContainerId, userId, email, authPartOfCommand);
|
||||
processAgent.execute(setEmailCommand);
|
||||
format("update users/%s -r che --set email=%s %s 2>&1", userId, email, authPartOfCommand);
|
||||
executor.execute(setEmailCommand);
|
||||
|
||||
String addUserRoleToUserCommand =
|
||||
format(
|
||||
"docker exec -i %s sh -c 'keycloak/bin/kcadm.sh add-roles -r che --uusername %s --rolename user %s 2>&1'",
|
||||
keycloakContainerId, username, authPartOfCommand);
|
||||
processAgent.execute(addUserRoleToUserCommand);
|
||||
"add-roles -r che --uusername %s --rolename user %s 2>&1",
|
||||
username, authPartOfCommand);
|
||||
executor.execute(addUserRoleToUserCommand);
|
||||
|
||||
String addReadTokenRoleToUserCommand =
|
||||
format(
|
||||
"docker exec -i %s sh -c 'keycloak/bin/kcadm.sh add-roles -r che --uusername %s --cclientid broker --rolename read-token %s 2>&1'",
|
||||
keycloakContainerId, username, authPartOfCommand);
|
||||
processAgent.execute(addReadTokenRoleToUserCommand);
|
||||
"add-roles -r che --uusername %s --cclientid broker --rolename read-token %s 2>&1",
|
||||
username, authPartOfCommand);
|
||||
executor.execute(addReadTokenRoleToUserCommand);
|
||||
} catch (IOException e) {
|
||||
// clean up user
|
||||
delete(userId, username);
|
||||
|
|
@ -184,11 +139,11 @@ public class KeycloakAdminConsoleClient {
|
|||
|
||||
String addReadTokenRoleToUserCommand =
|
||||
format(
|
||||
"docker exec -i %s sh -c 'keycloak/bin/kcadm.sh add-roles -r che --uusername %s --cclientid broker --rolename read-token %s 2>&1'",
|
||||
keycloakContainerId, adminTestUser.getName(), authPartOfCommand);
|
||||
"add-roles -r che --uusername %s --cclientid broker --rolename read-token %s 2>&1",
|
||||
adminTestUser.getName(), authPartOfCommand);
|
||||
|
||||
try {
|
||||
processAgent.execute(addReadTokenRoleToUserCommand);
|
||||
executor.execute(addReadTokenRoleToUserCommand);
|
||||
} catch (IOException e) {
|
||||
// ignore error of adding role to admin because of it can be added before
|
||||
}
|
||||
|
|
@ -212,14 +167,13 @@ public class KeycloakAdminConsoleClient {
|
|||
private void delete(String userId, String username) throws IOException {
|
||||
String commandToDeleteUser =
|
||||
format(
|
||||
"docker exec -i %s sh -c 'keycloak/bin/kcadm.sh delete users/%s -r che -s username=%s --no-config --server http://localhost:8080/auth --user %s --password %s --realm master 2>&1'",
|
||||
keycloakContainerId,
|
||||
"delete users/%s -r che -s username=%s --no-config --server http://localhost:8080/auth --user %s --password %s --realm master 2>&1",
|
||||
userId,
|
||||
username,
|
||||
adminTestUserProvider.get().getName(),
|
||||
adminTestUserProvider.get().getPassword());
|
||||
|
||||
processAgent.execute(commandToDeleteUser);
|
||||
executor.execute(commandToDeleteUser);
|
||||
|
||||
LOG.info("Test user with name='{}' has been removed.", username);
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
package org.eclipse.che.selenium.core.client.keycloak;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
package org.eclipse.che.selenium.core.client.keycloak;
|
||||
|
||||
import static com.google.common.io.BaseEncoding.base64;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
|
@ -34,7 +34,8 @@ import org.eclipse.che.api.core.ApiException;
|
|||
import org.eclipse.che.api.core.rest.DefaultHttpJsonRequestFactory;
|
||||
import org.eclipse.che.commons.lang.IoUtil;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.selenium.core.client.KeycloakToken.TokenDetails;
|
||||
import org.eclipse.che.selenium.core.client.TestAuthServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.KeycloakToken.TokenDetails;
|
||||
import org.eclipse.che.selenium.core.provider.TestOfflineToAccessTokenExchangeApiEndpointUrlProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
package org.eclipse.che.selenium.core.client.keycloak;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
package org.eclipse.che.selenium.core.client.keycloak;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
package org.eclipse.che.selenium.core.client.keycloak;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client.keycloak.executor;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.che.selenium.core.utils.process.ProcessAgent;
|
||||
import org.eclipse.che.selenium.core.utils.process.ProcessAgentException;
|
||||
|
||||
/**
|
||||
* This class is aimed to call Keycloak admin CLI inside Docker container.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
@Singleton
|
||||
public class DockerKeycloakCommandExecutor implements KeycloakCommandExecutor {
|
||||
|
||||
private final ProcessAgent processAgent;
|
||||
|
||||
private String keycloakContainerId;
|
||||
|
||||
@Inject
|
||||
public DockerKeycloakCommandExecutor(ProcessAgent processAgent) {
|
||||
this.processAgent = processAgent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String execute(String command) throws IOException {
|
||||
if (keycloakContainerId == null || keycloakContainerId.trim().isEmpty()) {
|
||||
obtainKeycloakContainerId();
|
||||
}
|
||||
|
||||
String dockerCommand =
|
||||
format("docker exec -i %s sh -c 'keycloak/bin/kcadm.sh %s'", keycloakContainerId, command);
|
||||
return processAgent.process(dockerCommand);
|
||||
}
|
||||
|
||||
private void obtainKeycloakContainerId() throws ProcessAgentException {
|
||||
// obtain id of keycloak docker container
|
||||
keycloakContainerId =
|
||||
processAgent.process("echo $(docker ps | grep che_keycloak | cut -d ' ' -f1)");
|
||||
|
||||
if (keycloakContainerId.trim().isEmpty()) {
|
||||
throw new RuntimeException(
|
||||
"Keycloak container is not found. Make sure that correct value is set for `CHE_INFRASTRUCTURE`, and product to test is run locally");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client.keycloak.executor;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.eclipse.che.selenium.core.utils.process.ProcessAgentException;
|
||||
|
||||
/**
|
||||
* Executor of command of 'keycloak/bin/kcadm.sh' command line application.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public interface KeycloakCommandExecutor {
|
||||
|
||||
/**
|
||||
* Executes command-line interface command.
|
||||
*
|
||||
* @param command CLI command to execute
|
||||
* @return response of CLI command
|
||||
* @throws ProcessAgentException
|
||||
*/
|
||||
String execute(String command) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client.keycloak.executor;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.lang.System.getProperty;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.eclipse.che.selenium.core.provider.OpenShiftWebConsoleUrlProvider;
|
||||
import org.eclipse.che.selenium.core.utils.process.ProcessAgent;
|
||||
import org.eclipse.che.selenium.core.utils.process.ProcessAgentException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This class is aimed to call Keycloak admin CLI inside Open Shift pod.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
@Singleton
|
||||
public class OpenShiftKeycloakCommandExecutor implements KeycloakCommandExecutor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(OpenShiftKeycloakCommandExecutor.class);
|
||||
|
||||
private static final boolean IS_MAC_OS = getProperty("os.name").toLowerCase().startsWith("mac");
|
||||
private static final String DEFAULT_OPENSHIFT_USERNAME = "developer";
|
||||
private static final String DEFAULT_OPENSHIFT_PASSWORD = "any";
|
||||
private static final String DEFAULT_OPENSHIFT_CHE_NAMESPACE = "eclipse-che";
|
||||
|
||||
private static final Path PATH_TO_OPENSHIFT_CLI_DIRECTORY =
|
||||
Paths.get(getProperty("java.io.tmpdir"));
|
||||
|
||||
private static final Path PATH_TO_OPENSHIFT_CLI = PATH_TO_OPENSHIFT_CLI_DIRECTORY.resolve("oc");
|
||||
|
||||
private String keycloakPodName;
|
||||
|
||||
@Inject private ProcessAgent processAgent;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named("env.openshift.username")
|
||||
private String openShiftUsername;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named("env.openshift.password")
|
||||
private String openShiftPassword;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named("env.openshift.token")
|
||||
private String openShiftToken;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named("env.openshift.che.namespace")
|
||||
private String openShiftCheNamespace;
|
||||
|
||||
@Inject private OpenShiftWebConsoleUrlProvider openShiftWebConsoleUrlProvider;
|
||||
|
||||
@Override
|
||||
public String execute(String command) throws IOException {
|
||||
if (keycloakPodName == null || keycloakPodName.trim().isEmpty()) {
|
||||
obtainKeycloakPodName();
|
||||
}
|
||||
|
||||
String openShiftCliCommand =
|
||||
format(
|
||||
"%s exec %s -- /opt/jboss/keycloak/bin/kcadm.sh %s",
|
||||
PATH_TO_OPENSHIFT_CLI, keycloakPodName, command);
|
||||
|
||||
return processAgent.process(openShiftCliCommand);
|
||||
}
|
||||
|
||||
private void obtainKeycloakPodName() throws IOException {
|
||||
if (Files.notExists(PATH_TO_OPENSHIFT_CLI)) {
|
||||
downloadOpenShiftCLI();
|
||||
}
|
||||
|
||||
loginToOpenShift();
|
||||
|
||||
// obtain name of keycloak pod
|
||||
keycloakPodName =
|
||||
processAgent.process(
|
||||
format(
|
||||
"%s get pod --namespace=%s -l app=keycloak --no-headers | awk '{print $1}'",
|
||||
PATH_TO_OPENSHIFT_CLI,
|
||||
openShiftCheNamespace != null
|
||||
? openShiftCheNamespace
|
||||
: DEFAULT_OPENSHIFT_CHE_NAMESPACE));
|
||||
|
||||
if (keycloakPodName.trim().isEmpty()) {
|
||||
throw new RuntimeException(
|
||||
format(
|
||||
"Keycloak pod is not found at namespace %s at Open Shift instance %s.",
|
||||
openShiftCheNamespace != null
|
||||
? openShiftCheNamespace
|
||||
: DEFAULT_OPENSHIFT_CHE_NAMESPACE,
|
||||
openShiftWebConsoleUrlProvider.get()));
|
||||
}
|
||||
}
|
||||
|
||||
private void downloadOpenShiftCLI() throws IOException {
|
||||
if (Files.notExists(PATH_TO_OPENSHIFT_CLI_DIRECTORY)) {
|
||||
Files.createDirectory(PATH_TO_OPENSHIFT_CLI_DIRECTORY);
|
||||
}
|
||||
|
||||
URL url;
|
||||
File packagePath;
|
||||
String commandToUnpackOpenShiftCli;
|
||||
if (IS_MAC_OS) {
|
||||
url =
|
||||
new URL(
|
||||
"https://github.com/openshift/origin/releases/download/v3.9.0/openshift-origin-client-tools-v3.9.0-191fece-mac.zip");
|
||||
packagePath =
|
||||
PATH_TO_OPENSHIFT_CLI_DIRECTORY.resolve("openshift-origin-client-tools.zip").toFile();
|
||||
commandToUnpackOpenShiftCli =
|
||||
format("unzip -d %s %s", PATH_TO_OPENSHIFT_CLI_DIRECTORY, packagePath);
|
||||
} else {
|
||||
url =
|
||||
new URL(
|
||||
"https://github.com/openshift/origin/releases/download/v3.9.0/openshift-origin-client-tools-v3.9.0-191fece-linux-64bit.tar.gz");
|
||||
packagePath =
|
||||
PATH_TO_OPENSHIFT_CLI_DIRECTORY.resolve("openshift-origin-client-tools.tar.gz").toFile();
|
||||
commandToUnpackOpenShiftCli =
|
||||
format("tar --strip 1 -xzf %s -C %s", packagePath, PATH_TO_OPENSHIFT_CLI_DIRECTORY);
|
||||
}
|
||||
|
||||
LOG.info("Downloading Open Shift CLI from {} ...", url);
|
||||
FileUtils.copyURLToFile(url, packagePath);
|
||||
LOG.info("Open Shift CLI has been downloaded.");
|
||||
|
||||
processAgent.process(commandToUnpackOpenShiftCli);
|
||||
|
||||
FileUtils.deleteQuietly(packagePath);
|
||||
}
|
||||
|
||||
private void loginToOpenShift() throws ProcessAgentException {
|
||||
String loginToOpenShiftCliCommand;
|
||||
if (openShiftToken != null) {
|
||||
loginToOpenShiftCliCommand =
|
||||
format(
|
||||
"%s login --server=%s --token=%s --insecure-skip-tls-verify",
|
||||
PATH_TO_OPENSHIFT_CLI, openShiftWebConsoleUrlProvider.get(), openShiftToken);
|
||||
} else {
|
||||
loginToOpenShiftCliCommand =
|
||||
format(
|
||||
"%s login --server=%s -u=%s -p=%s --insecure-skip-tls-verify",
|
||||
PATH_TO_OPENSHIFT_CLI,
|
||||
openShiftWebConsoleUrlProvider.get(),
|
||||
openShiftUsername != null ? openShiftUsername : DEFAULT_OPENSHIFT_USERNAME,
|
||||
openShiftPassword != null ? openShiftPassword : DEFAULT_OPENSHIFT_PASSWORD);
|
||||
}
|
||||
|
||||
processAgent.process(loginToOpenShiftCliCommand);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.provider;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Named;
|
||||
import org.eclipse.che.selenium.core.utils.UrlUtil;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
@Singleton
|
||||
public class OpenShiftWebConsoleUrlProvider implements Provider<URL> {
|
||||
|
||||
private static final int PORT = 8443;
|
||||
private static final String PROTOCOL = "https";
|
||||
|
||||
// extract openshift host from the url like 'che-eclipse-che.172.19.20.137.nip.io'
|
||||
private static final Pattern OPENSHIFT_HOST_REGEXP =
|
||||
Pattern.compile(".*[\\.]([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})[.].*");
|
||||
|
||||
@Inject
|
||||
@Named("che.host")
|
||||
private String cheHost;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named("env.openshift.url")
|
||||
private String openShiftUrl;
|
||||
|
||||
@Override
|
||||
public URL get() {
|
||||
if (openShiftUrl != null) {
|
||||
try {
|
||||
return new URL(openShiftUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
String openShiftHost = obtainOpenShiftHost();
|
||||
return UrlUtil.url(PROTOCOL, openShiftHost, PORT, "/");
|
||||
}
|
||||
|
||||
private String obtainOpenShiftHost() {
|
||||
if (openShiftUrl != null) {
|
||||
return openShiftUrl;
|
||||
}
|
||||
|
||||
Matcher matcher = OPENSHIFT_HOST_REGEXP.matcher(cheHost);
|
||||
if (!matcher.matches()) {
|
||||
throw new RuntimeException(
|
||||
format(
|
||||
"It's impossible to extract Open Shift host from Eclipse Che host '%s'. Make sure that correct value is set for `CHE_INFRASTRUCTURE`.",
|
||||
cheHost));
|
||||
}
|
||||
|
||||
return matcher.group(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ import com.google.inject.Inject;
|
|||
import com.google.inject.name.Named;
|
||||
import java.io.IOException;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.selenium.core.client.KeycloakAdminConsoleClient;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.KeycloakAdminConsoleClient;
|
||||
import org.eclipse.che.selenium.core.provider.AdminTestUserProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import com.google.inject.Inject;
|
|||
import com.google.inject.name.Named;
|
||||
import java.io.IOException;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.selenium.core.client.KeycloakAdminConsoleClient;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.KeycloakAdminConsoleClient;
|
||||
import org.eclipse.che.selenium.core.provider.DefaultTestUserProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ package org.eclipse.che.selenium.core.user;
|
|||
import com.google.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import javax.annotation.PreDestroy;
|
||||
import org.eclipse.che.selenium.core.client.KeycloakAdminConsoleClient;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.KeycloakAdminConsoleClient;
|
||||
import org.eclipse.che.selenium.core.provider.AdminTestUserProvider;
|
||||
import org.eclipse.che.selenium.core.provider.TestUserProvider;
|
||||
import org.slf4j.Logger;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.google.inject.Inject;
|
|||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.client.TestKeycloakSettingsServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.TestKeycloakSettingsServiceClient;
|
||||
import org.eclipse.che.selenium.core.entrance.Entrance;
|
||||
import org.eclipse.che.selenium.core.provider.TestDashboardUrlProvider;
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import com.google.inject.name.Named;
|
|||
import java.util.List;
|
||||
import javax.annotation.PreDestroy;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.client.TestKeycloakSettingsServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.TestKeycloakSettingsServiceClient;
|
||||
import org.eclipse.che.selenium.core.entrance.Entrance;
|
||||
import org.eclipse.che.selenium.core.provider.TestDashboardUrlProvider;
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import com.google.inject.Inject;
|
|||
import com.google.inject.Singleton;
|
||||
import javax.ws.rs.NotSupportedException;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.client.TestKeycloakSettingsServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.keycloak.TestKeycloakSettingsServiceClient;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.support.ui.ExpectedCondition;
|
||||
|
|
|
|||
Loading…
Reference in New Issue