mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Trust certificates from keystore and specified files
This commit is contained in:
parent
457995c749
commit
ebbe345290
2
pom.xml
2
pom.xml
@ -195,7 +195,7 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
<properties>
|
||||
<commons.version>1.1.6</commons.version>
|
||||
<commons.version>1.1.7</commons.version>
|
||||
<antlr.version>4.7.2</antlr.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
||||
@ -388,7 +388,7 @@
|
||||
<dependency>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>k8s-helper</artifactId>
|
||||
<version>1.0.4</version>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
|
||||
@ -167,7 +167,7 @@ import io.onedev.server.maintenance.RestoreDatabase;
|
||||
import io.onedev.server.maintenance.Upgrade;
|
||||
import io.onedev.server.migration.JpaConverter;
|
||||
import io.onedev.server.migration.PersistentBagConverter;
|
||||
import io.onedev.server.model.support.DiscoveredJobExecutor;
|
||||
import io.onedev.server.model.support.AutoDiscoveredJobExecutor;
|
||||
import io.onedev.server.model.support.authenticator.Authenticator;
|
||||
import io.onedev.server.notification.CodeCommentNotificationManager;
|
||||
import io.onedev.server.notification.CommitNotificationManager;
|
||||
@ -391,12 +391,12 @@ public class CoreModule extends AbstractPluginModule {
|
||||
|
||||
@Override
|
||||
public Class<?> getAbstractClass() {
|
||||
return DiscoveredJobExecutor.class;
|
||||
return AutoDiscoveredJobExecutor.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<?>> getImplementations() {
|
||||
return Sets.newHashSet(DiscoveredJobExecutor.class);
|
||||
return Sets.newHashSet(AutoDiscoveredJobExecutor.class);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@ -33,8 +33,8 @@ import io.onedev.server.maintenance.DataManager;
|
||||
import io.onedev.server.persistence.PersistManager;
|
||||
import io.onedev.server.persistence.SessionManager;
|
||||
import io.onedev.server.persistence.annotation.Sessional;
|
||||
import io.onedev.server.util.ServerConfig;
|
||||
import io.onedev.server.util.jetty.JettyRunner;
|
||||
import io.onedev.server.util.serverconfig.ServerConfig;
|
||||
|
||||
public class OneDev extends AbstractPlugin implements Serializable {
|
||||
|
||||
@ -127,7 +127,7 @@ public class OneDev extends AbstractPlugin implements Serializable {
|
||||
if (serverConfig.getHttpPort() != 0)
|
||||
serverUrl = "http://" + hostName + ":" + serverConfig.getHttpPort();
|
||||
else
|
||||
serverUrl = "https://" + hostName + ":" + serverConfig.getSslConfig().getPort();
|
||||
serverUrl = "https://" + hostName + ":" + serverConfig.getHttpsPort();
|
||||
|
||||
return StringUtils.stripEnd(serverUrl, "/");
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ import io.onedev.server.persistence.annotation.Sessional;
|
||||
import io.onedev.server.security.CodePullAuthorizationSource;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.storage.StorageManager;
|
||||
import io.onedev.server.util.serverconfig.ServerConfig;
|
||||
import io.onedev.server.util.ServerConfig;
|
||||
import io.onedev.server.util.work.WorkExecutor;
|
||||
|
||||
@Singleton
|
||||
@ -128,12 +128,12 @@ public class GitFilter implements Filter {
|
||||
doNotCache(response);
|
||||
response.setHeader("Content-Type", "application/x-" + service + "-result");
|
||||
|
||||
final Map<String, String> environments = new HashMap<>();
|
||||
Map<String, String> environments = new HashMap<>();
|
||||
String serverUrl;
|
||||
if (serverConfig.getHttpPort() != 0)
|
||||
serverUrl = "http://localhost:" + serverConfig.getHttpPort();
|
||||
else
|
||||
serverUrl = "https://localhost:" + serverConfig.getSslConfig().getPort();
|
||||
serverUrl = "https://localhost:" + serverConfig.getHttpsPort();
|
||||
|
||||
environments.put("ONEDEV_CURL", configManager.getSystemSetting().getCurlConfig().getExecutable());
|
||||
environments.put("ONEDEV_URL", serverUrl);
|
||||
|
||||
@ -38,7 +38,7 @@ import io.onedev.server.event.system.SystemStarting;
|
||||
import io.onedev.server.model.Setting;
|
||||
import io.onedev.server.model.Setting.Key;
|
||||
import io.onedev.server.model.User;
|
||||
import io.onedev.server.model.support.DiscoveredJobExecutor;
|
||||
import io.onedev.server.model.support.AutoDiscoveredJobExecutor;
|
||||
import io.onedev.server.model.support.setting.BackupSetting;
|
||||
import io.onedev.server.model.support.setting.GlobalIssueSetting;
|
||||
import io.onedev.server.model.support.setting.MailSetting;
|
||||
@ -154,7 +154,7 @@ public class DefaultDataManager implements DataManager, Serializable {
|
||||
}
|
||||
setting = settingManager.getSetting(Key.JOB_EXECUTORS);
|
||||
if (setting == null) {
|
||||
settingManager.saveJobExecutors(Lists.newArrayList(new DiscoveredJobExecutor()));
|
||||
settingManager.saveJobExecutors(Lists.newArrayList(new AutoDiscoveredJobExecutor()));
|
||||
}
|
||||
|
||||
setting = settingManager.getSetting(Key.MAIL);
|
||||
|
||||
@ -110,7 +110,14 @@ public class Upgrade extends DefaultPersistManager {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (upgradeDir.list().length != 0) {
|
||||
boolean isEmpty = true;
|
||||
for (File file: upgradeDir.listFiles()) {
|
||||
if (!file.getName().equals("lost+found")) {
|
||||
isEmpty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isEmpty) {
|
||||
if (!new File(upgradeDir, "boot/bootstrap.keys").exists()) {
|
||||
logger.error("Invalid OneDev installation directory: {}, make sure you are specifying the top level "
|
||||
+ "installation directory (it contains sub directories such as \"bin\", \"boot\", \"conf\", etc)",
|
||||
|
||||
@ -13,7 +13,7 @@ import io.onedev.server.web.editable.EditableUtils;
|
||||
import io.onedev.server.web.editable.annotation.Editable;
|
||||
|
||||
@Editable(order=10000, description="Discover appropriate job executor automatically to run CI jobs")
|
||||
public class DiscoveredJobExecutor extends JobExecutor {
|
||||
public class AutoDiscoveredJobExecutor extends JobExecutor {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
package io.onedev.server.util.serverconfig;
|
||||
package io.onedev.server.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface ServerConfig {
|
||||
|
||||
@ -12,15 +16,15 @@ public interface ServerConfig {
|
||||
*/
|
||||
int getHttpPort();
|
||||
|
||||
/**
|
||||
* Get ssl config of the server.
|
||||
* <p>
|
||||
* @return
|
||||
* ssl config of the server, or <tt>null</tt> if ssl setting is not defined.
|
||||
* In case ssl setting is not defined, {@link #getHttpPort()} must not
|
||||
* return <i>0</i>
|
||||
*/
|
||||
SslConfig getSslConfig();
|
||||
int getHttpsPort();
|
||||
|
||||
@Nullable
|
||||
File getKeystoreFile();
|
||||
|
||||
String getKeystorePassword();
|
||||
|
||||
@Nullable
|
||||
File getTrustCertsDir();
|
||||
|
||||
/**
|
||||
* Get web session timeout in seconds.
|
||||
@ -1,9 +0,0 @@
|
||||
package io.onedev.server.util.serverconfig;
|
||||
|
||||
public interface SslConfig {
|
||||
int getPort();
|
||||
|
||||
String getKeystore();
|
||||
|
||||
String getKeystorePassword();
|
||||
}
|
||||
@ -6,7 +6,7 @@ import javax.inject.Singleton;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
|
||||
import io.onedev.server.util.serverconfig.ServerConfig;
|
||||
import io.onedev.server.util.ServerConfig;
|
||||
|
||||
@Singleton
|
||||
public class WebSocketPolicyProvider implements Provider<WebSocketPolicy> {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>server-plugin-kubernetes</artifactId>
|
||||
@ -7,6 +8,13 @@
|
||||
<artifactId>server-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.62</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<moduleClass>io.onedev.server.plugin.kubernetes.KubernetesModule</moduleClass>
|
||||
</properties>
|
||||
|
||||
@ -1,10 +1,21 @@
|
||||
package io.onedev.server.plugin.kubernetes;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -16,6 +27,8 @@ import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.bouncycastle.util.io.pem.PemObject;
|
||||
import org.bouncycastle.util.io.pem.PemWriter;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -45,6 +58,7 @@ import io.onedev.server.model.support.JobExecutor;
|
||||
import io.onedev.server.model.support.RegistryLogin;
|
||||
import io.onedev.server.plugin.kubernetes.KubernetesExecutor.TestData;
|
||||
import io.onedev.server.util.JobLogger;
|
||||
import io.onedev.server.util.ServerConfig;
|
||||
import io.onedev.server.util.inputspec.SecretInput;
|
||||
import io.onedev.server.web.editable.annotation.Editable;
|
||||
import io.onedev.server.web.editable.annotation.NameOfEmptyValue;
|
||||
@ -410,6 +424,72 @@ public class KubernetesExecutor extends JobExecutor implements Testable<TestData
|
||||
}
|
||||
}
|
||||
|
||||
private String getCertContent(Certificate cert) {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
try (PemWriter pemWriter = new PemWriter(stringWriter)) {
|
||||
pemWriter.writeObject(new PemObject("CERTIFICATE", cert.getEncoded()));
|
||||
pemWriter.flush();
|
||||
} catch (CertificateEncodingException|IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return stringWriter.toString().trim();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String createTrustCertsConfigMap(JobLogger logger) {
|
||||
Map<String, String> configMapData = new LinkedHashMap<>();
|
||||
ServerConfig serverConfig = OneDev.getInstance(ServerConfig.class);
|
||||
File keystoreFile = serverConfig.getKeystoreFile();
|
||||
if (keystoreFile != null) {
|
||||
try (InputStream is = new FileInputStream(keystoreFile)) {
|
||||
KeyStore keystore = KeyStore.getInstance("pkcs12");
|
||||
keystore.load(is, serverConfig.getKeystorePassword().toCharArray());
|
||||
Enumeration<String> aliases = keystore.aliases();
|
||||
while (aliases.hasMoreElements()) {
|
||||
String alias = aliases.nextElement();
|
||||
String siteCertContent = getCertContent(keystore.getCertificate(alias));
|
||||
String safeAlias = alias.replaceAll("[^a-zA-Z0-9\\.\\_]", "-");
|
||||
configMapData.put("keystore-site-cert-" + safeAlias + ".pem", siteCertContent);
|
||||
|
||||
Certificate chain[] = keystore.getCertificateChain(alias);
|
||||
if (chain != null) {
|
||||
for (int i=0; i<chain.length; i++) {
|
||||
String caCertContent = getCertContent(chain[i]);
|
||||
if (!caCertContent.equals(siteCertContent))
|
||||
configMapData.put("keystore-ca-cert-" + safeAlias + "-" + i + ".pem", caCertContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException|KeyStoreException|NoSuchAlgorithmException|CertificateException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
File trustCertsDir = serverConfig.getTrustCertsDir();
|
||||
if (trustCertsDir != null) {
|
||||
for (File file: trustCertsDir.listFiles()) {
|
||||
if (file.isFile()) {
|
||||
try {
|
||||
configMapData.put("specified-cert-" + file.getName(), FileUtils.readFileToString(file));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!configMapData.isEmpty()) {
|
||||
Map<Object, Object> configMapDef = Maps.newLinkedHashMap(
|
||||
"apiVersion", "v1",
|
||||
"kind", "ConfigMap",
|
||||
"metadata", Maps.newLinkedHashMap(
|
||||
"generateName", "configmap-",
|
||||
"namespace", "onedev"),
|
||||
"data", configMapData);
|
||||
return createResource(configMapDef, new HashSet<>(), logger);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(String dockerImage, String jobToken, JobLogger logger, @Nullable JobContext jobContext) {
|
||||
logger.log("Executing job with Kubernetes executor...");
|
||||
|
||||
@ -417,10 +497,12 @@ public class KubernetesExecutor extends JobExecutor implements Testable<TestData
|
||||
|
||||
String jobSecretName = null;
|
||||
String imagePullSecretName = null;
|
||||
String trustCertsConfigMapName = null;
|
||||
try {
|
||||
Map<String, String> jobSecrets = Maps.newLinkedHashMap(KubernetesHelper.ENV_JOB_TOKEN, jobToken);
|
||||
jobSecretName = createSecret(jobSecrets, null, logger);
|
||||
imagePullSecretName = createImagePullSecret(logger);
|
||||
trustCertsConfigMapName = createTrustCertsConfigMap(logger);
|
||||
|
||||
String osName = getOSName(logger);
|
||||
|
||||
@ -433,28 +515,36 @@ public class KubernetesExecutor extends JobExecutor implements Testable<TestData
|
||||
String k8sHelperClassPath;
|
||||
String containerCIHome;
|
||||
String containerCacheHome;
|
||||
String trustCertsHome;
|
||||
if (osName.equalsIgnoreCase("linux")) {
|
||||
containerCIHome = "/onedev-ci";
|
||||
containerCacheHome = containerCIHome + "/cache";
|
||||
trustCertsHome = containerCIHome + "/trust-certs";
|
||||
k8sHelperClassPath = "/k8s-helper/*";
|
||||
mainContainerSpec.put("command", Lists.newArrayList("sh"));
|
||||
mainContainerSpec.put("args", Lists.newArrayList(containerCIHome + "/commands.sh"));
|
||||
} else {
|
||||
containerCIHome = "C:\\onedev-ci";
|
||||
containerCacheHome = containerCIHome + "\\cache";
|
||||
trustCertsHome = containerCIHome + "\\trust-certs";
|
||||
k8sHelperClassPath = "C:\\k8s-helper\\*";
|
||||
mainContainerSpec.put("command", Lists.newArrayList("cmd"));
|
||||
mainContainerSpec.put("args", Lists.newArrayList("/c", containerCIHome + "\\commands.bat"));
|
||||
}
|
||||
|
||||
Map<String, String> ciPathMount = Maps.newLinkedHashMap(
|
||||
Map<String, String> ciHomeMount = Maps.newLinkedHashMap(
|
||||
"name", "ci-home",
|
||||
"mountPath", containerCIHome);
|
||||
Map<String, String> cacheHomeMount = Maps.newLinkedHashMap(
|
||||
"name", "cache-home",
|
||||
"mountPath", containerCacheHome);
|
||||
Map<String, String> trustCertsMount = Maps.newLinkedHashMap(
|
||||
"name", "trust-certs-home",
|
||||
"mountPath", trustCertsHome);
|
||||
|
||||
List<Object> volumeMounts = Lists.<Object>newArrayList(ciPathMount, cacheHomeMount);
|
||||
List<Object> volumeMounts = Lists.<Object>newArrayList(ciHomeMount, cacheHomeMount);
|
||||
if (trustCertsConfigMapName != null)
|
||||
volumeMounts.add(trustCertsMount);
|
||||
|
||||
mainContainerSpec.put("volumeMounts", volumeMounts);
|
||||
|
||||
@ -512,8 +602,15 @@ public class KubernetesExecutor extends JobExecutor implements Testable<TestData
|
||||
"hostPath", Maps.newLinkedHashMap(
|
||||
"path", getCacheHome(osName),
|
||||
"type", "DirectoryOrCreate"));
|
||||
|
||||
podSpec.put("volumes", Lists.<Object>newArrayList(ciHomeVolume, cacheHomeVolume));
|
||||
List<Object> volumes = Lists.<Object>newArrayList(ciHomeVolume, cacheHomeVolume);
|
||||
if (trustCertsConfigMapName != null) {
|
||||
Map<Object, Object> trustCertsHomeVolume = Maps.newLinkedHashMap(
|
||||
"name", "trust-certs-home",
|
||||
"configMap", Maps.newLinkedHashMap(
|
||||
"name", trustCertsConfigMapName));
|
||||
volumes.add(trustCertsHomeVolume);
|
||||
}
|
||||
podSpec.put("volumes", volumes);
|
||||
|
||||
Map<Object, Object> podDef = Maps.newLinkedHashMap(
|
||||
"apiVersion", "v1",
|
||||
@ -648,6 +745,8 @@ public class KubernetesExecutor extends JobExecutor implements Testable<TestData
|
||||
deleteResource("pod", podName, logger);
|
||||
}
|
||||
} finally {
|
||||
if (trustCertsConfigMapName != null)
|
||||
deleteResource("configmap", trustCertsConfigMapName, logger);
|
||||
if (jobSecretName != null)
|
||||
deleteResource("secret", jobSecretName, logger);
|
||||
if (imagePullSecretName != null)
|
||||
|
||||
104
server-product/k8s/base/deployments.yaml
Normal file
104
server-product/k8s/base/deployments.yaml
Normal file
@ -0,0 +1,104 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: onedev
|
||||
labels:
|
||||
tier: server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
tier: server
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
name: onedev
|
||||
labels:
|
||||
tier: server
|
||||
spec:
|
||||
containers:
|
||||
- name: onedev
|
||||
image: 1dev/server
|
||||
volumeMounts:
|
||||
- mountPath: "/opt/onedev"
|
||||
name: onedev
|
||||
ports:
|
||||
- containerPort: 6610
|
||||
env:
|
||||
- name: hibernate_dialect
|
||||
value: org.hibernate.dialect.MySQL5InnoDBDialect
|
||||
- name: hibernate_connection_driver_class
|
||||
value: com.mysql.cj.jdbc.Driver
|
||||
- name: hibernate_connection_url
|
||||
value: jdbc:mysql://mysql:3306/onedev?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false
|
||||
- name: hibernate_connection_username
|
||||
value: onedev
|
||||
- name: hibernate_connection_password
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysql
|
||||
key: password
|
||||
initContainers:
|
||||
- name: init
|
||||
image: busybox
|
||||
command: ["sh", "-c", "until nslookup mysql.onedev.svc.cluster.local; do echo waiting for mysql; sleep 2; done;"]
|
||||
volumes:
|
||||
- name: onedev
|
||||
persistentVolumeClaim:
|
||||
claimName: onedev
|
||||
serviceAccountName: onedev
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
tier: database
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
tier: database
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
tier: database
|
||||
spec:
|
||||
containers:
|
||||
- name: mysql
|
||||
image: mysql:5.7
|
||||
args:
|
||||
- "--ignore-db-dir=lost+found"
|
||||
env:
|
||||
- name: MYSQL_RANDOM_ROOT_PASSWORD
|
||||
value: "yes"
|
||||
- name: MYSQL_DATABASE
|
||||
value: onedev
|
||||
- name: MYSQL_USER
|
||||
value: onedev
|
||||
- name: MYSQL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysql
|
||||
key: password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
volumeMounts:
|
||||
- name: mysql
|
||||
mountPath: /var/lib/mysql
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- bash
|
||||
- "-c"
|
||||
- |
|
||||
mysql -uonedev -p$MYSQL_PASSWORD -e 'SELECT 1'
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 2
|
||||
timeoutSeconds: 1
|
||||
volumes:
|
||||
- name: mysql
|
||||
persistentVolumeClaim:
|
||||
claimName: mysql
|
||||
15
server-product/k8s/base/kustomization.yaml
Normal file
15
server-product/k8s/base/kustomization.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
namespace: onedev
|
||||
commonLabels:
|
||||
app: onedev
|
||||
secretGenerator:
|
||||
- name: mysql
|
||||
literals:
|
||||
- password=changeit
|
||||
resources:
|
||||
- namespaces.yaml
|
||||
- service-accounts.yaml
|
||||
- roles.yaml
|
||||
- role-bindings.yaml
|
||||
- services.yaml
|
||||
- deployments.yaml
|
||||
- persistent-volume-claims.yaml
|
||||
4
server-product/k8s/base/namespaces.yaml
Normal file
4
server-product/k8s/base/namespaces.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: onedev
|
||||
19
server-product/k8s/base/persistent-volume-claims.yaml
Normal file
19
server-product/k8s/base/persistent-volume-claims.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: onedev
|
||||
labels:
|
||||
tier: server
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
tier: database
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
23
server-product/k8s/base/role-bindings.yaml
Normal file
23
server-product/k8s/base/role-bindings.yaml
Normal file
@ -0,0 +1,23 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: onedev
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: onedev
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: onedev
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: onedev
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: onedev
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: onedev
|
||||
20
server-product/k8s/base/roles.yaml
Normal file
20
server-product/k8s/base/roles.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: onedev
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["namespaces"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes"]
|
||||
verbs: ["get", "list", "patch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: onedev
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods", "pods/log", "secrets", "configmaps", "events"]
|
||||
verbs: ["create", "get", "list", "watch", "delete"]
|
||||
4
server-product/k8s/base/service-accounts.yaml
Normal file
4
server-product/k8s/base/service-accounts.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: onedev
|
||||
27
server-product/k8s/base/services.yaml
Normal file
27
server-product/k8s/base/services.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: onedev
|
||||
labels:
|
||||
tier: server
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 6610
|
||||
protocol: TCP
|
||||
selector:
|
||||
tier: server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
tier: database
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
selector:
|
||||
tier: database
|
||||
1
server-product/k8s/mini/README.md
Normal file
1
server-product/k8s/mini/README.md
Normal file
@ -0,0 +1 @@
|
||||
This folder configures OneDev with minimum resource requirements to use in resource-constrainted environments such as minikube
|
||||
25
server-product/k8s/mini/cpu-settings.yaml
Normal file
25
server-product/k8s/mini/cpu-settings.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: onedev
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: onedev
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: mysql
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
17
server-product/k8s/mini/disk-settings.yaml
Normal file
17
server-product/k8s/mini/disk-settings.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: onedev
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
7
server-product/k8s/mini/kustomization.yaml
Normal file
7
server-product/k8s/mini/kustomization.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
namespace: onedev
|
||||
bases:
|
||||
- ../base
|
||||
patchesStrategicMerge:
|
||||
- cpu-settings.yaml
|
||||
- memory-settings.yaml
|
||||
- disk-settings.yaml
|
||||
25
server-product/k8s/mini/memory-settings.yaml
Normal file
25
server-product/k8s/mini/memory-settings.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: onedev
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: onedev
|
||||
resources:
|
||||
requests:
|
||||
memory: 1Gi
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: mysql
|
||||
resources:
|
||||
requests:
|
||||
memory: 500Mi
|
||||
25
server-product/k8s/production/cpu-settings.yaml
Normal file
25
server-product/k8s/production/cpu-settings.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: onedev
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: onedev
|
||||
resources:
|
||||
requests:
|
||||
cpu: "1"
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: mysql
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
@ -69,6 +69,8 @@ spec:
|
||||
containers:
|
||||
- name: mysql
|
||||
image: mysql:5.7
|
||||
args:
|
||||
- "--ignore-db-dir=lost+found"
|
||||
env:
|
||||
- name: MYSQL_RANDOM_ROOT_PASSWORD
|
||||
value: "yes"
|
||||
|
||||
17
server-product/k8s/production/disk-settings.yaml
Normal file
17
server-product/k8s/production/disk-settings.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: onedev
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 100Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
@ -1,17 +1,9 @@
|
||||
namespace: onedev
|
||||
bases:
|
||||
- ../base
|
||||
commonLabels:
|
||||
app: onedev
|
||||
secretGenerator:
|
||||
- name: mysql
|
||||
literals:
|
||||
- password=change-me
|
||||
resources:
|
||||
- namespaces.yaml
|
||||
- service-accounts.yaml
|
||||
- roles.yaml
|
||||
- role-bindings.yaml
|
||||
- services.yaml
|
||||
- deployments.yaml
|
||||
- persistent-volume-claims.yaml
|
||||
patchesStrategicMerge:
|
||||
- settings.yaml
|
||||
- cpu-settings.yaml
|
||||
- memory-settings.yaml
|
||||
- disk-settings.yaml
|
||||
|
||||
@ -9,8 +9,6 @@ spec:
|
||||
- name: onedev
|
||||
resources:
|
||||
requests:
|
||||
memory: 1Gi
|
||||
limits:
|
||||
memory: 4Gi
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
@ -24,24 +22,4 @@ spec:
|
||||
- name: mysql
|
||||
resources:
|
||||
requests:
|
||||
memory: 512Mi
|
||||
limits:
|
||||
memory: 4Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: onedev
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
memory: 1Gi
|
||||
@ -16,5 +16,5 @@ metadata:
|
||||
name: onedev
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods", "pods/log", "secrets", "events"]
|
||||
resources: ["pods", "pods/log", "secrets", "configmaps", "events"]
|
||||
verbs: ["create", "get", "list", "watch", "delete"]
|
||||
|
||||
1
server-product/k8s/ssl/README.md
Normal file
1
server-product/k8s/ssl/README.md
Normal file
@ -0,0 +1 @@
|
||||
This folder demonstrates how to enable SSL support
|
||||
@ -1,47 +0,0 @@
|
||||
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
|
||||
@ -22,11 +22,11 @@ spec:
|
||||
name: keystore
|
||||
key: password
|
||||
volumeMounts:
|
||||
- name: config
|
||||
- name: keystore
|
||||
mountPath: /root/config
|
||||
ports:
|
||||
- containerPort: 6643
|
||||
volumes:
|
||||
- name: config
|
||||
- name: keystore
|
||||
configMap:
|
||||
name: keystore
|
||||
|
||||
@ -4,11 +4,11 @@ bases:
|
||||
configMapGenerator:
|
||||
- name: keystore
|
||||
files:
|
||||
- keystore=change-me.p12.base64 #PKCS file in base64 encoding
|
||||
- keystore=changeit.pfx.base64 # base64 encoded pkcs12 keystore
|
||||
secretGenerator:
|
||||
- name: keystore
|
||||
literals:
|
||||
- password=change-me
|
||||
- password=changeit
|
||||
patchesStrategicMerge:
|
||||
- deployments.yaml
|
||||
- services.yaml
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: onedev #base64
|
||||
name: onedev
|
||||
spec:
|
||||
ports:
|
||||
- name: https
|
||||
|
||||
1
server-product/k8s/trust-certs/README.md
Normal file
1
server-product/k8s/trust-certs/README.md
Normal file
@ -0,0 +1 @@
|
||||
This folder demonstrates how to configure OneDev to trust specified certificates
|
||||
21
server-product/k8s/trust-certs/deployments.yaml
Normal file
21
server-product/k8s/trust-certs/deployments.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: onedev
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: onedev
|
||||
spec:
|
||||
containers:
|
||||
- name: onedev
|
||||
env:
|
||||
- name: trust_certs
|
||||
value: /root/config/trust-certs
|
||||
volumeMounts:
|
||||
- name: trust-certs
|
||||
mountPath: /root/config/trust-certs
|
||||
volumes:
|
||||
- name: trust-certs
|
||||
configMap:
|
||||
name: trust-certs
|
||||
9
server-product/k8s/trust-certs/kustomization.yaml
Normal file
9
server-product/k8s/trust-certs/kustomization.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
namespace: onedev
|
||||
bases:
|
||||
- ../production
|
||||
configMapGenerator:
|
||||
- name: trust-certs
|
||||
files:
|
||||
- onedev.pem
|
||||
patchesStrategicMerge:
|
||||
- deployments.yaml
|
||||
@ -7,13 +7,13 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.glassfish.jersey.internal.guava.Preconditions;
|
||||
|
||||
import io.onedev.commons.launcher.bootstrap.Bootstrap;
|
||||
import io.onedev.commons.utils.FileUtils;
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.OneException;
|
||||
import io.onedev.server.util.serverconfig.ServerConfig;
|
||||
import io.onedev.server.util.serverconfig.SslConfig;
|
||||
import io.onedev.server.util.ServerConfig;
|
||||
|
||||
@Singleton
|
||||
public class DefaultServerConfig implements ServerConfig {
|
||||
@ -24,49 +24,54 @@ public class DefaultServerConfig implements ServerConfig {
|
||||
|
||||
private static final String PROP_KEYSTORE = "keystore";
|
||||
|
||||
private static final String PROP_TRUST_CERTS = "trust_certs";
|
||||
|
||||
private static final String PROP_KEYSTORE_ENCODING = "keystore_encoding";
|
||||
|
||||
private static final String PROP_KEYSTOREPASSWORD = "keystore_password";
|
||||
|
||||
private static final String PROP_SESSION_TIMEOUT = "session_timeout";
|
||||
|
||||
private int httpPort;
|
||||
|
||||
private int sessionTimeout = 1800;
|
||||
private int sessionTimeout;
|
||||
|
||||
private SslConfig sslConfig;
|
||||
private int httpsPort;
|
||||
|
||||
private File trustCertsDir;
|
||||
|
||||
private File keystoreFile;
|
||||
|
||||
private String keystorePassword;
|
||||
|
||||
@Inject
|
||||
public DefaultServerConfig(ServerProperties props) {
|
||||
String httpPortStr = System.getenv(PROP_HTTPPORT);
|
||||
if (httpPortStr == null)
|
||||
if (StringUtils.isBlank(httpPortStr))
|
||||
httpPortStr = props.getProperty(PROP_HTTPPORT);
|
||||
if (httpPortStr != null)
|
||||
if (StringUtils.isNotBlank(httpPortStr))
|
||||
httpPort = Integer.parseInt(httpPortStr.trim());
|
||||
|
||||
String httpsPortStr = System.getenv(PROP_HTTPSPORT);
|
||||
if (httpsPortStr == null)
|
||||
if (StringUtils.isBlank(httpsPortStr))
|
||||
httpsPortStr = props.getProperty(PROP_HTTPSPORT);
|
||||
if (StringUtils.isNotBlank(httpsPortStr))
|
||||
httpsPort = Integer.parseInt(httpsPortStr.trim());
|
||||
|
||||
if (httpsPortStr != null) {
|
||||
SslConfigBean sslConfigBean = new SslConfigBean();
|
||||
sslConfigBean.setPort(Integer.parseInt(httpsPortStr.trim()));
|
||||
|
||||
String keystorePath = System.getenv(PROP_KEYSTORE);
|
||||
if (keystorePath == null)
|
||||
keystorePath = props.getProperty(PROP_KEYSTORE);
|
||||
if (keystorePath != null)
|
||||
keystorePath = keystorePath.trim();
|
||||
else
|
||||
throw new OneException("Keystore file is required for https support");
|
||||
|
||||
String keystorePassword = System.getenv(PROP_KEYSTOREPASSWORD);
|
||||
if (keystorePassword == null)
|
||||
keystorePassword = props.getProperty(PROP_KEYSTOREPASSWORD);
|
||||
if (keystorePassword != null)
|
||||
keystorePassword = keystorePassword.trim();
|
||||
|
||||
File keystoreFile = new File(keystorePath);
|
||||
if (httpPort == 0 && httpsPort == 0)
|
||||
throw new RuntimeException("Either " + PROP_HTTPPORT + " or " + PROP_HTTPSPORT + " or both should be enabled");
|
||||
|
||||
String keystore = System.getenv(PROP_KEYSTORE);
|
||||
if (StringUtils.isBlank(keystore))
|
||||
keystore = props.getProperty(PROP_KEYSTORE);
|
||||
if (StringUtils.isNotBlank(keystore)) {
|
||||
keystoreFile = new File(keystore.trim());
|
||||
if (!keystoreFile.isAbsolute())
|
||||
keystoreFile = new File(Bootstrap.getConfDir(), keystorePath);
|
||||
keystoreFile = new File(Bootstrap.getConfDir(), keystore);
|
||||
|
||||
Preconditions.checkState(keystoreFile.exists(),
|
||||
"Keystore file not exist: " + keystoreFile.getAbsolutePath());
|
||||
|
||||
String keystoreEncoding = System.getenv(PROP_KEYSTORE_ENCODING);
|
||||
if (keystoreEncoding == null)
|
||||
keystoreEncoding = props.getProperty(PROP_KEYSTORE_ENCODING);
|
||||
@ -75,25 +80,40 @@ public class DefaultServerConfig implements ServerConfig {
|
||||
if ("base64".equals(keystoreEncoding)) {
|
||||
try {
|
||||
String content = FileUtils.readFileToString(keystoreFile);
|
||||
keystoreFile = File.createTempFile("keystore", "p12");
|
||||
keystoreFile = File.createTempFile("keystore", "pfx");
|
||||
FileUtils.writeByteArrayToFile(keystoreFile, Base64.decodeBase64(content));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
sslConfigBean.setKeyStorePath(keystoreFile.getAbsolutePath());
|
||||
sslConfigBean.setKeyStorePassword(keystorePassword);
|
||||
|
||||
sslConfig = sslConfigBean;
|
||||
} else if (httpsPort != 0) {
|
||||
throw new OneException(PROP_KEYSTORE + " is required for https support");
|
||||
}
|
||||
|
||||
if (httpPort == 0 && sslConfig == null)
|
||||
throw new RuntimeException("Either httpPort or httpsPort or both should be enabled.");
|
||||
keystorePassword = System.getenv(PROP_KEYSTOREPASSWORD);
|
||||
if (keystorePassword == null)
|
||||
keystorePassword = props.getProperty(PROP_KEYSTOREPASSWORD);
|
||||
if (keystorePassword == null)
|
||||
keystorePassword = "";
|
||||
|
||||
String trustCerts = System.getenv(PROP_TRUST_CERTS);
|
||||
if (StringUtils.isBlank(trustCerts))
|
||||
trustCerts = props.getProperty(PROP_TRUST_CERTS);
|
||||
if (StringUtils.isNotBlank(trustCerts)) {
|
||||
trustCertsDir = new File(trustCerts.trim());
|
||||
if (!trustCertsDir.isAbsolute())
|
||||
trustCertsDir = new File(Bootstrap.getConfDir(), trustCerts);
|
||||
Preconditions.checkState(trustCertsDir.exists(),
|
||||
"Trust certs directory not exist: " + trustCertsDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
String sessionTimeoutStr = props.getProperty("session_timeout");
|
||||
String sessionTimeoutStr = System.getenv(PROP_SESSION_TIMEOUT);
|
||||
if (StringUtils.isBlank(sessionTimeoutStr))
|
||||
sessionTimeoutStr = props.getProperty(PROP_SESSION_TIMEOUT);
|
||||
if (StringUtils.isNotBlank(sessionTimeoutStr))
|
||||
sessionTimeout = Integer.parseInt(sessionTimeoutStr.trim());
|
||||
else
|
||||
throw new RuntimeException(PROP_SESSION_TIMEOUT + " should be specified");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -101,14 +121,29 @@ public class DefaultServerConfig implements ServerConfig {
|
||||
return httpPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SslConfig getSslConfig() {
|
||||
return sslConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSessionTimeout() {
|
||||
return sessionTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpsPort() {
|
||||
return httpsPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getKeystoreFile() {
|
||||
return keystoreFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeystorePassword() {
|
||||
return keystorePassword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getTrustCertsDir() {
|
||||
return trustCertsDir;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -9,9 +9,8 @@ import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
import io.onedev.server.util.ServerConfig;
|
||||
import io.onedev.server.util.jetty.ServerConfigurator;
|
||||
import io.onedev.server.util.serverconfig.ServerConfig;
|
||||
import io.onedev.server.util.serverconfig.SslConfig;
|
||||
|
||||
public class ProductConfigurator implements ServerConfigurator {
|
||||
|
||||
@ -31,15 +30,14 @@ public class ProductConfigurator implements ServerConfigurator {
|
||||
server.addConnector(connector);
|
||||
}
|
||||
|
||||
SslConfig sslConfig = serverConfig.getSslConfig();
|
||||
if (sslConfig != null) {
|
||||
if (serverConfig.getHttpsPort() != 0) {
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setKeyStoreType("pkcs12");
|
||||
sslContextFactory.setKeyStorePath(sslConfig.getKeystore());
|
||||
sslContextFactory.setKeyStorePassword(sslConfig.getKeystorePassword());
|
||||
sslContextFactory.setKeyStorePath(serverConfig.getKeystoreFile().getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePassword(serverConfig.getKeystorePassword());
|
||||
|
||||
ServerConnector connector = new ServerConnector(server, sslContextFactory);
|
||||
connector.setPort(sslConfig.getPort());
|
||||
connector.setPort(serverConfig.getHttpsPort());
|
||||
|
||||
HttpConfiguration configuration = new HttpConfiguration();
|
||||
configuration.addCustomizer(new SecureRequestCustomizer());
|
||||
|
||||
@ -9,9 +9,9 @@ import io.onedev.commons.launcher.loader.AbstractPluginModule;
|
||||
import io.onedev.commons.utils.FileUtils;
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.util.ServerConfig;
|
||||
import io.onedev.server.util.jetty.ServerConfigurator;
|
||||
import io.onedev.server.util.jetty.ServletConfigurator;
|
||||
import io.onedev.server.util.serverconfig.ServerConfig;
|
||||
|
||||
public class ProductModule extends AbstractPluginModule {
|
||||
|
||||
|
||||
@ -21,10 +21,10 @@ import io.onedev.server.git.GitFilter;
|
||||
import io.onedev.server.git.GitPostReceiveCallback;
|
||||
import io.onedev.server.git.GitPreReceiveCallback;
|
||||
import io.onedev.server.security.OneWebEnvironment;
|
||||
import io.onedev.server.util.ServerConfig;
|
||||
import io.onedev.server.util.jetty.ClasspathAssetServlet;
|
||||
import io.onedev.server.util.jetty.FileAssetServlet;
|
||||
import io.onedev.server.util.jetty.ServletConfigurator;
|
||||
import io.onedev.server.util.serverconfig.ServerConfig;
|
||||
import io.onedev.server.web.component.markdown.AttachmentUploadServlet;
|
||||
import io.onedev.server.web.img.Img;
|
||||
import io.onedev.server.web.websocket.WebSocketManager;
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
package io.onedev.server.product;
|
||||
|
||||
import io.onedev.server.util.serverconfig.SslConfig;
|
||||
|
||||
class SslConfigBean implements SslConfig {
|
||||
|
||||
private int port;
|
||||
|
||||
private String keyStorePath;
|
||||
|
||||
private String keyStorePassword;
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeystore() {
|
||||
return keyStorePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeystorePassword() {
|
||||
return keyStorePassword;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void setKeyStorePath(String keyStorePath) {
|
||||
this.keyStorePath = keyStorePath;
|
||||
}
|
||||
|
||||
public void setKeyStorePassword(String keyStorePassword) {
|
||||
this.keyStorePassword = keyStorePassword;
|
||||
}
|
||||
|
||||
}
|
||||
@ -12,7 +12,7 @@ http_port=6610
|
||||
#https_port=6643
|
||||
|
||||
# path to PKCS12 keystore. Non-absolute path is considered to be relative to OneDev conf directory
|
||||
#keystore=change-me.p12
|
||||
#keystore=changeit.pfx
|
||||
|
||||
# password of the keystore
|
||||
#keystore_password=change-me
|
||||
#keystore_password=changeit
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user