-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #630 from BIX-Digital/bugfix/preflight-check-opens…
…hift-project-key-is-missing adds openshift project key preflight check
- Loading branch information
Showing
16 changed files
with
627 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
src/main/java/org/opendevstack/provision/config/OpenshiftServiceConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* | ||
* Copyright 2017-2019 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package org.opendevstack.provision.config; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import org.opendevstack.provision.services.openshift.OpenshiftClient; | ||
import org.opendevstack.provision.services.openshift.OpenshiftService; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.core.io.Resource; | ||
import org.springframework.core.io.ResourceLoader; | ||
import org.springframework.util.Assert; | ||
|
||
/** @author Sebastian Titakis */ | ||
@Configuration | ||
@ConditionalOnProperty( | ||
name = "services.openshift.enabled", | ||
havingValue = "true", | ||
matchIfMissing = true) | ||
public class OpenshiftServiceConfig { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(OpenshiftServiceConfig.class); | ||
|
||
public static final String DEFAULT_KUBERNETES_IO_SERVICEACCOUNT_TOKEN_FILE = | ||
"file:///var/run/secrets/kubernetes.io/serviceaccount/token"; | ||
|
||
@Value( | ||
"${openshift.provisioning-app.service-account.file:" | ||
+ DEFAULT_KUBERNETES_IO_SERVICEACCOUNT_TOKEN_FILE | ||
+ "}") | ||
private String ocTokenResourceFile; | ||
|
||
@Value("${openshift.provisioning-app.service-account.token:}") | ||
private String ocToken; | ||
|
||
@Value("${openshift.api.uri}") | ||
private String openshiftApiUri; | ||
|
||
@Autowired private ResourceLoader resourceLoader; | ||
|
||
@Bean | ||
public OpenshiftService openshiftService(OpenshiftClient openshiftClient) { | ||
return new OpenshiftService(openshiftClient); | ||
} | ||
|
||
@Bean | ||
public OpenshiftClient openshiftClient() { | ||
|
||
if (null != ocToken && !ocToken.isEmpty()) { | ||
logger.info( | ||
"Found oc token configured in property 'openshift.provisioning-app.service-account.token'. Using it to log into to openshift! [openshift.api.uri={}]", | ||
openshiftApiUri); | ||
|
||
return create(openshiftApiUri, ocToken); | ||
|
||
} else if (null != ocTokenResourceFile) { | ||
|
||
if (!ocTokenResourceFile.equals(DEFAULT_KUBERNETES_IO_SERVICEACCOUNT_TOKEN_FILE)) { | ||
logger.info( | ||
"Found oc service account file configured in property 'openshift.provisioning-app.service-account.file'. Using it to log into to openshift! [openshift.api.uri={}, serviceAccountTokenFile={}]", | ||
openshiftApiUri, | ||
ocTokenResourceFile); | ||
} else { | ||
logger.info( | ||
"Using default service account file to connect to openshift! [openshift.api.uri={}, serviceAccountTokenFile={}]", | ||
openshiftApiUri, | ||
DEFAULT_KUBERNETES_IO_SERVICEACCOUNT_TOKEN_FILE); | ||
} | ||
|
||
Resource resource = resourceLoader.getResource(ocTokenResourceFile); | ||
|
||
if (!resource.exists()) { | ||
throw new RuntimeException( | ||
"Cannot load oc token from file because file does not exists! [file=" | ||
+ ocTokenResourceFile | ||
+ "]"); | ||
} | ||
|
||
return create(openshiftApiUri, resource); | ||
|
||
} else { | ||
throw new RuntimeException("This should never happens! Ask developers to take a look!"); | ||
} | ||
} | ||
|
||
private OpenshiftClient create(String openshiftApiUri, Resource token) { | ||
Assert.notNull(token, "Parameter 'token' is null!"); | ||
|
||
try { | ||
if (!token.exists()) { | ||
throw new RuntimeException( | ||
String.format( | ||
"File with oc token does not exists! [file=%s]!", token.getURI().toString())); | ||
} | ||
|
||
String ocToken = new String(Files.readAllBytes(Path.of(token.getURI()))); | ||
|
||
return create(openshiftApiUri, ocToken); | ||
|
||
} catch (IOException ex) { | ||
logger.error("Failed to create openshift service!", ex); | ||
throw new RuntimeException(ex); | ||
} | ||
} | ||
|
||
private OpenshiftClient create(String openshiftApiUri, String token) { | ||
Assert.notNull(openshiftApiUri, "Parameter 'openshiftApiUri' is null!"); | ||
Assert.notNull(token, "Parameter 'token' is null!"); | ||
|
||
return new OpenshiftClient(openshiftApiUri, token); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
src/main/java/org/opendevstack/provision/services/openshift/OpenshiftClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright 2017-2019 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package org.opendevstack.provision.services.openshift; | ||
|
||
import com.openshift.restclient.ClientBuilder; | ||
import com.openshift.restclient.IClient; | ||
import com.openshift.restclient.model.IResource; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
/** @author Sebastian Titakis */ | ||
public class OpenshiftClient { | ||
|
||
private final IClient iClient; | ||
|
||
private final String url; | ||
|
||
public OpenshiftClient(String url, String token) { | ||
this(url, new ClientBuilder(url).usingToken(token).build()); | ||
} | ||
|
||
public OpenshiftClient(String url, IClient ocClient) { | ||
this.url = url; | ||
this.iClient = ocClient; | ||
} | ||
|
||
public Set<String> projects() { | ||
|
||
List<IResource> projectResource = iClient.list("Project"); | ||
|
||
return projectResource.stream().map(project -> project.getName()).collect(Collectors.toSet()); | ||
} | ||
|
||
public String getUrl() { | ||
return url; | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
src/main/java/org/opendevstack/provision/services/openshift/OpenshiftService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* Copyright 2017-2019 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package org.opendevstack.provision.services.openshift; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import org.opendevstack.provision.adapter.exception.AdapterException; | ||
import org.opendevstack.provision.adapter.exception.CreateProjectPreconditionException; | ||
import org.opendevstack.provision.controller.CheckPreconditionFailure; | ||
import org.opendevstack.provision.model.OpenProjectData; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.util.Assert; | ||
|
||
/** @author Sebastian Titakis */ | ||
public class OpenshiftService { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(OpenshiftService.class); | ||
|
||
public static final String SERVICE_NAME = "openshiftService"; | ||
|
||
private OpenshiftClient openshiftClient; | ||
|
||
public OpenshiftService(OpenshiftClient openshiftClient) { | ||
this.openshiftClient = openshiftClient; | ||
} | ||
|
||
public List<CheckPreconditionFailure> checkCreateProjectPreconditions(OpenProjectData newProject) | ||
throws CreateProjectPreconditionException { | ||
|
||
try { | ||
Assert.notNull(newProject, "Parameter 'newProject' is null!"); | ||
Assert.notNull( | ||
newProject.projectKey, "Properties 'projectKey' of parameter 'newProject' is null!"); | ||
|
||
logger.info("checking create project preconditions for project '{}'!", newProject.projectKey); | ||
|
||
List<CheckPreconditionFailure> preconditionFailures = | ||
createProjectKeyExistsCheck(newProject.projectKey); | ||
|
||
logger.info( | ||
"done with check create project preconditions for project '{}'!", newProject.projectKey); | ||
|
||
return preconditionFailures; | ||
|
||
} catch (AdapterException e) { | ||
throw new CreateProjectPreconditionException(SERVICE_NAME, newProject.projectKey, e); | ||
} catch (Exception e) { | ||
String message = | ||
String.format( | ||
"Unexpected error when checking precondition for creation of project '%s'", | ||
newProject.projectKey); | ||
logger.error(message, e); | ||
throw new CreateProjectPreconditionException(SERVICE_NAME, newProject.projectKey, message); | ||
} | ||
} | ||
|
||
public List<CheckPreconditionFailure> createProjectKeyExistsCheck(String projectKey) { | ||
|
||
try { | ||
logger.info("Checking if ODS project '{}-*' exists in openshift!", projectKey); | ||
|
||
List<CheckPreconditionFailure> preconditionFailures = new ArrayList<>(); | ||
|
||
Set<String> projects = openshiftClient.projects(); | ||
List<String> existingProjects = | ||
projects.stream() | ||
.filter(s -> s.toLowerCase().startsWith(projectKey.toLowerCase() + "-")) | ||
.collect(Collectors.toList()); | ||
|
||
if (existingProjects.size() > 0) { | ||
String message = | ||
String.format( | ||
"Project name (namespace) with prefix '%s' already exists in '%s'! [existingProjects=%s]", | ||
projectKey, SERVICE_NAME, Arrays.asList(existingProjects.toArray())); | ||
preconditionFailures.add(CheckPreconditionFailure.getProjectExistsInstance(message)); | ||
} | ||
|
||
return preconditionFailures; | ||
|
||
} catch (Exception ex) { | ||
throw new AdapterException(ex); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.