Skip to content

Commit

Permalink
che-starter redhat-developer#254: Multi-cluster support. Cleanup & Re…
Browse files Browse the repository at this point in the history
…factoring

Signed-off-by: Ilya Buziuk <ibuziuk@redhat.com>
  • Loading branch information
ibuziuk committed Jan 12, 2018
1 parent 2d6db29 commit 3e904ed
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ public enum CheRestEndpoints {
STOP_WORKSPACE ("/api/workspace/{id}/runtime"),
LIST_STACKS ("/api/stack?maxItems=1000"),
DELETE_PROJECT ("/project/{id}"),
SET_OAUTH_TOKEN_V1 ("/wsmaster/api/oauth/token?oauth_provider={provider}"),
SET_OAUTH_TOKEN_V2 ("/wsmaster/api/token/github"),
SET_OAUTH_TOKEN ("/wsmaster/api/token/github"),
GET_PREFERENCES ("/wsmaster/api/preferences"),
UPDATE_PREFERENCES ("/wsmaster/api/preferences");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class GitHubClient {
*/
public void setGitHubOAuthToken(final String cheServerURL, final String gitHubToken, final String keycloakToken)
throws IOException, GitHubOAthTokenException {
String url = cheServerURL + CheRestEndpoints.SET_OAUTH_TOKEN_V1.getEndpoint().replace("{provider}", "github");
String url = cheServerURL + CheRestEndpoints.SET_OAUTH_TOKEN.getEndpoint();

Token token = new Token();
token.setToken(gitHubToken);
Expand All @@ -66,13 +66,9 @@ public void setGitHubOAuthToken(final String cheServerURL, final String gitHubTo

try {
template.postForLocation(url, entity);
LOG.debug("GitHub OAuth token has been successfully set via '{}'", url);
} catch (Exception e) {
LOG.info("Trying new version of API - Unable to set GitHub OAuth token via '{}'", url);
try {
setGitHubOAuthTokenVersion2(cheServerURL, template, entity);
} catch (Exception ex) {
throw new GitHubOAthTokenException("Error setting GitHub OAuth token", ex);
}
throw new GitHubOAthTokenException("Error setting GitHub OAuth token", e);
}
}

Expand Down Expand Up @@ -102,10 +98,4 @@ public GitHubEmail getPrimaryEmail(final String gitHubToken) {
return primary;
}

private void setGitHubOAuthTokenVersion2(String cheServerURL, RestTemplate template, HttpEntity<Token> entity) {
String url = cheServerURL + CheRestEndpoints.SET_OAUTH_TOKEN_V2.getEndpoint();
template.postForLocation(url, entity);
LOG.info("GitHub OAuth token has been successfully set via '{}'", url);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
* http://www.eclipse.org/legal/epl-v10.html
* #L%
*/
package io.fabric8.che.starter.client.keycloak;
package io.fabric8.che.starter.client.github;

import java.io.IOException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -27,33 +26,17 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.fabric8.che.starter.client.keycloak.KeycloakRestTemplate;
import io.fabric8.che.starter.exception.KeycloakException;

@Component
public class KeycloakClient {
private static final Logger LOG = LoggerFactory.getLogger(KeycloakClient.class);
public class GitHubTokenProvider {
private static final Logger LOG = LoggerFactory.getLogger(GitHubTokenProvider.class);
private static final String ACCESS_TOKEN = "access_token";

@Value("${OSO_ADMIN_TOKEN:#{null}}")
private String openShiftAdminToken;

@Value("${OPENSHIFT_TOKEN_URL:https://sso.prod-preview.openshift.io/auth/realms/fabric8/broker/openshift-v3/token}")
private String openShiftTokenUrl;

@Value("${GITHUB_TOKEN_URL:https://auth.prod-preview.openshift.io/api/token?for=https://github.com}")
private String gitHubTokenUrl;

public String getOpenShiftToken(String keycloakToken) throws JsonProcessingException, IOException, KeycloakException {
if (StringUtils.isNotBlank(openShiftAdminToken)) {
LOG.info("Using OpenShift admin token");
return openShiftAdminToken;
}
LOG.info("OpenShift token url - {}", openShiftTokenUrl);
// {"access_token":"token","expires_in":86400,"scope":"user:full","token_type":"Bearer"}
String token = getAccessToken(openShiftTokenUrl, keycloakToken);
return token;
}

public String getGitHubToken(String keycloakToken) throws KeycloakException, JsonProcessingException, IOException {
LOG.info("GitHub token url - {}", gitHubTokenUrl);
// {"access_token":"token","scope":"admin:repo_hook,gist,read:org,repo,user","token_type":"bearer"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import org.springframework.web.bind.annotation.RestController;

import io.fabric8.che.starter.client.CheServerClient;
import io.fabric8.che.starter.client.keycloak.KeycloakClient;
import io.fabric8.che.starter.client.github.GitHubTokenProvider;
import io.fabric8.che.starter.client.keycloak.KeycloakTokenValidator;
import io.fabric8.che.starter.exception.MultiTenantMigrationException;
import io.fabric8.che.starter.exception.RouteNotFoundException;
Expand All @@ -42,7 +42,7 @@ public class CheServerController {
OpenShiftClientWrapper openShiftClientWrapper;

@Autowired
KeycloakClient keycloakClient;
GitHubTokenProvider keycloakClient;

@Autowired
CheServerClient cheServerClient;
Expand Down Expand Up @@ -80,15 +80,6 @@ public CheServerInfo startCheServer(@RequestParam String masterUrl, @RequestPara
return info;
}

@ApiOperation(value = "Start Che Server")
@PatchMapping("/server/oso")
public CheServerInfo startCheServerOnOpenShift(@RequestParam String masterUrl, @RequestParam String namespace,
@ApiParam(value = "OpenShift token", required = true) @RequestHeader("Authorization") String openShiftToken, HttpServletResponse response, HttpServletRequest request) throws Exception {

CheServerInfo info = startServer(masterUrl, openShiftToken, null, namespace, response, request);
return info;
}

private CheServerInfo startServer(String masterUrl, String openShiftToken, String keycloakToken, String namespace, HttpServletResponse response,
HttpServletRequest request) throws RouteNotFoundException, MultiTenantMigrationException {
OpenShiftClient openShiftClient = openShiftClientWrapper.get(masterUrl, openShiftToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,50 +27,29 @@
import com.fasterxml.jackson.core.JsonProcessingException;

import io.fabric8.che.starter.client.StackClient;
import io.fabric8.che.starter.client.keycloak.KeycloakClient;
import io.fabric8.che.starter.client.keycloak.KeycloakTokenValidator;
import io.fabric8.che.starter.exception.KeycloakException;
import io.fabric8.che.starter.exception.RouteNotFoundException;
import io.fabric8.che.starter.model.stack.Stack;
import io.fabric8.che.starter.openshift.OpenShiftClientWrapper;
import io.fabric8.che.starter.multi.tenant.CheServer;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@CrossOrigin
@RestController
public class StackController {
private static final Logger LOG = LoggerFactory.getLogger(StackController.class);

@Autowired
private StackClient stackClient;

@Autowired
private OpenShiftClientWrapper openShiftClientWrapper;

@Autowired
KeycloakClient keycloakClient;
private CheServer cheServer;

@ApiOperation(value = "List the available stacks")
@GetMapping("/stack")
public List<Stack> list(@RequestParam String masterUrl, @RequestParam String namespace, @ApiParam(value = "Keycloak token", required = true) @RequestHeader("Authorization") String keycloakToken)
throws RouteNotFoundException, JsonProcessingException, IOException, KeycloakException {
KeycloakTokenValidator.validate(keycloakToken);
String openShiftToken = keycloakClient.getOpenShiftToken(keycloakToken);
return getStacks(masterUrl, namespace, openShiftToken, keycloakToken);
}

@ApiOperation(value = "List the available stacks")
@GetMapping("/stack/oso")
public List<Stack> listOnOpenShift(@RequestParam String masterUrl, @RequestParam String namespace, @ApiParam(value = "OpenShift token", required = true) @RequestHeader("Authorization") String openShiftToken)
throws RouteNotFoundException, JsonProcessingException, IOException {
return getStacks(masterUrl, namespace, openShiftToken, null);
}

private List<Stack> getStacks(String masterUrl, String namespace, String openShiftToken, String keycloakToken) throws RouteNotFoundException {
LOG.info("Getting stacks from masterUrl {}", masterUrl);
LOG.info("Getting stacks from namespace {}", namespace);

String cheServerUrl = openShiftClientWrapper.getCheServerUrl(masterUrl, namespace, openShiftToken, keycloakToken);
String cheServerUrl = cheServer.getUrl();
return stackClient.listStacks(cheServerUrl, keycloakToken);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import io.fabric8.che.starter.client.WorkspaceClient;
import io.fabric8.che.starter.client.WorkspacePreferencesClient;
import io.fabric8.che.starter.client.github.GitHubClient;
import io.fabric8.che.starter.client.keycloak.KeycloakClient;
import io.fabric8.che.starter.client.github.GitHubTokenProvider;
import io.fabric8.che.starter.client.keycloak.KeycloakTokenValidator;
import io.fabric8.che.starter.exception.GitHubOAthTokenException;
import io.fabric8.che.starter.exception.KeycloakException;
Expand Down Expand Up @@ -70,7 +70,7 @@ public class WorkspaceController {
ProjectClient projectClient;

@Autowired
KeycloakClient keycloakClient;
GitHubTokenProvider keycloakClient;

@Autowired
GitHubClient tokenClient;
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/io/fabric8/che/starter/multi/tenant/CheServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*-
* #%L
* che-starter
* %%
* Copyright (C) 2017 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
* #L%
*/
package io.fabric8.che.starter.multi.tenant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class CheServer {

@Value("${MULTI_TENANT_CHE_SERVER_URL:https://che.prod-preview.openshift.io}")
private String multiTenantCheServerURL;

public String getUrl() {
return multiTenantCheServerURL;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ public class OpenShiftClientWrapper {
@Value("${FABRIC8_PLATFORM_DEV_MODE:false}")
private boolean fabric8PlatformDevMode;

@Value("${MULTI_TENANT_CHE_SERVER_URL:https://che.prod-preview.openshift.io}")
private String multiTenantCheServerURL;

/**
* Gets OpenShift client. When using, you are responsible for closing it.
*
Expand Down Expand Up @@ -80,25 +77,25 @@ public OpenShiftClient get(String masterUrl, String token) {
return new DefaultOpenShiftClient(config);
}

/**
* Gets URL of Che server running in user's namespace on OpenShift.
*
* @param masterUrl URL of OpenShift master
* @param namespace user's namespace
* @param osoToken authorization token
* @return URL of Che server
* @throws RouteNotFoundException
*/
public String getCheServerUrl(String masterUrl, String namespace, String osoToken, String keycloakToken) throws RouteNotFoundException {
if (toggle.isMultiTenant(keycloakToken)) {
return multiTenantCheServerURL;
}
try (OpenShiftClient openShiftClient = this.get(masterUrl, osoToken)) {
dc.deployCheIfSuspended(openShiftClient, namespace);
String routeURL = route.getUrl(openShiftClient, namespace);
LOG.info("Che server route URL {}", routeURL);
return routeURL;
}
}
// /**
// * Gets URL of Che server running in user's namespace on OpenShift.
// *
// * @param masterUrl URL of OpenShift master
// * @param namespace user's namespace
// * @param osoToken authorization token
// * @return URL of Che server
// * @throws RouteNotFoundException
// */
// public String getCheServerUrl(String masterUrl, String namespace, String osoToken, String keycloakToken) throws RouteNotFoundException {
// if (toggle.isMultiTenant(keycloakToken)) {
// return multiTenantCheServerURL;
// }
// try (OpenShiftClient openShiftClient = this.get(masterUrl, osoToken)) {
// dc.deployCheIfSuspended(openShiftClient, namespace);
// String routeURL = route.getUrl(openShiftClient, namespace);
// LOG.info("Che server route URL {}", routeURL);
// return routeURL;
// }
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* http://www.eclipse.org/legal/epl-v10.html
* #L%
*/
package io.fabric8.che.starter.client.keycloak;
package io.fabric8.che.starter.client.github;

import java.io.IOException;

Expand All @@ -23,26 +23,21 @@
import com.fasterxml.jackson.core.JsonProcessingException;

import io.fabric8.che.starter.TestConfig;
import io.fabric8.che.starter.client.github.GitHubTokenProvider;
import io.fabric8.che.starter.exception.KeycloakException;

@Ignore("Valid keycloak token must be provided")
public class KeycloakTest extends TestConfig {
private static final Logger LOG = LoggerFactory.getLogger(KeycloakTest.class);
public class GitHubTokenProviderTest extends TestConfig {
private static final Logger LOG = LoggerFactory.getLogger(GitHubTokenProviderTest.class);
private static final String KEYCLOAK_TOKEN = "Bearer <KEYCLOAK TOKEN>";

@Autowired
KeycloakClient keycloakClient;
GitHubTokenProvider gitHubTokenProvider;

@Test
public void getGitHubToken() throws KeycloakException, JsonProcessingException, IOException {
String gitHubToken = keycloakClient.getGitHubToken(KEYCLOAK_TOKEN);
String gitHubToken = gitHubTokenProvider.getGitHubToken(KEYCLOAK_TOKEN);
LOG.info("GitHub Token: {}", gitHubToken);
}

@Test
public void getOpenShiftToken() throws JsonProcessingException, IOException, KeycloakException {
String openShiftToken = keycloakClient.getOpenShiftToken(KEYCLOAK_TOKEN);
LOG.info("OpenShift Token: {}", openShiftToken);
}

}

0 comments on commit 3e904ed

Please sign in to comment.