mirror of
https://github.com/ctripcorp/zeus.git
synced 2024-09-22 00:26:05 +08:00
finish cert upload impl
This commit is contained in:
parent
5fe9dce08c
commit
b5220207eb
|
@ -2,16 +2,15 @@ package com.ctrip.zeus.client;
|
||||||
|
|
||||||
import com.ctrip.zeus.auth.impl.IPAuthenticationFilter;
|
import com.ctrip.zeus.auth.impl.IPAuthenticationFilter;
|
||||||
import com.ctrip.zeus.auth.impl.TokenManager;
|
import com.ctrip.zeus.auth.impl.TokenManager;
|
||||||
import com.netflix.config.DynamicBooleanProperty;
|
|
||||||
import com.netflix.config.DynamicIntProperty;
|
import com.netflix.config.DynamicIntProperty;
|
||||||
import com.netflix.config.DynamicPropertyFactory;
|
import com.netflix.config.DynamicPropertyFactory;
|
||||||
import org.glassfish.jersey.client.ClientConfig;
|
import org.glassfish.jersey.client.ClientConfig;
|
||||||
import org.glassfish.jersey.client.ClientProperties;
|
import org.glassfish.jersey.client.ClientProperties;
|
||||||
|
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
||||||
import org.glassfish.jersey.uri.UriComponent;
|
import org.glassfish.jersey.uri.UriComponent;
|
||||||
|
|
||||||
import javax.ws.rs.client.Client;
|
import javax.ws.rs.client.Client;
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
import javax.ws.rs.client.Invocation;
|
|
||||||
import javax.ws.rs.client.WebTarget;
|
import javax.ws.rs.client.WebTarget;
|
||||||
import javax.ws.rs.core.MultivaluedHashMap;
|
import javax.ws.rs.core.MultivaluedHashMap;
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
|
@ -28,10 +27,12 @@ public abstract class AbstractRestClient {
|
||||||
private static DynamicIntProperty readTimeout = DynamicPropertyFactory.getInstance().getIntProperty("client.read.timeout", 30000);
|
private static DynamicIntProperty readTimeout = DynamicPropertyFactory.getInstance().getIntProperty("client.read.timeout", 30000);
|
||||||
|
|
||||||
protected AbstractRestClient(String url) {
|
protected AbstractRestClient(String url) {
|
||||||
ClientConfig config = new ClientConfig();
|
Client client = ClientBuilder.newBuilder()
|
||||||
Client client = ClientBuilder.newClient(config);
|
.withConfig(new ClientConfig())
|
||||||
|
.register(MultiPartFeature.class)
|
||||||
|
.build();
|
||||||
client.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout.get());
|
client.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout.get());
|
||||||
client.property(ClientProperties.READ_TIMEOUT,readTimeout.get());
|
client.property(ClientProperties.READ_TIMEOUT, readTimeout.get());
|
||||||
webTarget = client.target(url);
|
webTarget = client.target(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +40,11 @@ public abstract class AbstractRestClient {
|
||||||
return UriComponent.encode(url, UriComponent.Type.PATH_SEGMENT);
|
return UriComponent.encode(url, UriComponent.Type.PATH_SEGMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected WebTarget getTarget(){
|
protected WebTarget getTarget() {
|
||||||
return webTarget;
|
return webTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MultivaluedMap<String, Object> getDefaultHeaders(){
|
protected MultivaluedMap<String, Object> getDefaultHeaders() {
|
||||||
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
|
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
|
||||||
map.putSingle(IPAuthenticationFilter.SERVER_TOKEN_HEADER, TokenManager.generateToken());
|
map.putSingle(IPAuthenticationFilter.SERVER_TOKEN_HEADER, TokenManager.generateToken());
|
||||||
return map;
|
return map;
|
||||||
|
|
|
@ -269,12 +269,12 @@ public class OperationResource {
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
@Authorize(name = "uploadCerts")
|
@Authorize(name = "uploadCerts")
|
||||||
public Response uploadCerts(@Context HttpServletRequest request,
|
public Response uploadCerts(@Context HttpServletRequest request,
|
||||||
@Context HttpHeaders hh,
|
@Context HttpHeaders hh,
|
||||||
@FormDataParam("cert") InputStream cert,
|
@FormDataParam("cert") InputStream cert,
|
||||||
@FormDataParam("key") InputStream key,
|
@FormDataParam("key") InputStream key,
|
||||||
@QueryParam("vsId") Long vsId,
|
@QueryParam("vsId") Long vsId,
|
||||||
@QueryParam("ip") List<String> ips,
|
@QueryParam("ip") List<String> ips,
|
||||||
@QueryParam("domain") String domain) throws Exception {
|
@QueryParam("domain") String domain) throws Exception {
|
||||||
if (domain != null && !domain.isEmpty()) {
|
if (domain != null && !domain.isEmpty()) {
|
||||||
Set<Long> check = virtualServerCriteriaQuery.queryByDomain(domain);
|
Set<Long> check = virtualServerCriteriaQuery.queryByDomain(domain);
|
||||||
if (!check.contains(vsId))
|
if (!check.contains(vsId))
|
||||||
|
@ -303,6 +303,20 @@ public class OperationResource {
|
||||||
return responseHandler.handle("Certificates uploaded.", hh.getMediaType());
|
return responseHandler.handle("Certificates uploaded.", hh.getMediaType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/installcerts")
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@Authorize(name = "installCerts")
|
||||||
|
public Response installCerts(@Context HttpServletRequest request,
|
||||||
|
@Context HttpHeaders hh,
|
||||||
|
@FormDataParam("cert") InputStream cert,
|
||||||
|
@FormDataParam("key") InputStream key,
|
||||||
|
@QueryParam("vsId") Long vsId) throws Exception {
|
||||||
|
final String installDir = "/data/nginx/ssl/" + vsId;
|
||||||
|
certificateService.save(cert, key, installDir);
|
||||||
|
return responseHandler.handle("Certificates are installed successfully.", hh.getMediaType());
|
||||||
|
}
|
||||||
|
|
||||||
private Response memberOps(HttpHeaders hh, Long groupId, List<String> ips, boolean up, String type) throws Exception {
|
private Response memberOps(HttpHeaders hh, Long groupId, List<String> ips, boolean up, String type) throws Exception {
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.ctrip.zeus.service.nginx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by zhoumy on 2015/10/30.
|
||||||
|
*/
|
||||||
|
public class CertificateConfig {
|
||||||
|
public static final boolean OVERWRITE_IF_EXIST = false;
|
||||||
|
public static final boolean APPEND_ONLY = true;
|
||||||
|
|
||||||
|
private String cacheDir;
|
||||||
|
private boolean writeFileOption;
|
||||||
|
|
||||||
|
public CertificateConfig() {
|
||||||
|
cacheDir = "tmp/certs/";
|
||||||
|
writeFileOption = OVERWRITE_IF_EXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCacheDir() {
|
||||||
|
return cacheDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCacheDir(String cacheDir) {
|
||||||
|
if (!cacheDir.endsWith("/"))
|
||||||
|
cacheDir += "/";
|
||||||
|
this.cacheDir = cacheDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getWriteFileOption() {
|
||||||
|
return writeFileOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWriteFileOption(boolean writeFileOption) {
|
||||||
|
this.writeFileOption = writeFileOption;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,9 +8,11 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface CertificateService {
|
public interface CertificateService {
|
||||||
|
|
||||||
|
CertificateConfig getConfig();
|
||||||
|
|
||||||
void cache(InputStream cert, InputStream key, Long vsId) throws Exception;
|
void cache(InputStream cert, InputStream key, Long vsId) throws Exception;
|
||||||
|
|
||||||
void cache(InputStream cert, InputStream key, String dir) throws Exception;
|
void save(InputStream cert, InputStream key, String dir) throws Exception;
|
||||||
|
|
||||||
void sendIfExist(Long vsId, List<String> ip);
|
void sendIfExist(Long vsId, List<String> ips) throws Exception;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
package com.ctrip.zeus.service.nginx.impl;
|
package com.ctrip.zeus.service.nginx.impl;
|
||||||
|
|
||||||
|
import com.ctrip.zeus.client.AbstractRestClient;
|
||||||
|
import com.ctrip.zeus.exceptions.ValidationException;
|
||||||
|
import com.ctrip.zeus.service.nginx.CertificateConfig;
|
||||||
import com.ctrip.zeus.service.nginx.CertificateService;
|
import com.ctrip.zeus.service.nginx.CertificateService;
|
||||||
import com.ctrip.zeus.util.IOUtils;
|
import com.ctrip.zeus.util.IOUtils;
|
||||||
|
import org.glassfish.jersey.media.multipart.MultiPart;
|
||||||
|
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.Entity;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -12,29 +20,80 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Service("certificateService")
|
@Service("certificateService")
|
||||||
public class CertificateServiceImpl implements CertificateService {
|
public class CertificateServiceImpl implements CertificateService {
|
||||||
private final static String TempDir = "tmp/certs/";
|
private CertificateConfig config = new CertificateConfig();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cache(InputStream cert, InputStream key, Long vsId) throws Exception {
|
public CertificateConfig getConfig() {
|
||||||
cache(cert, key, TempDir + vsId);
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cache(InputStream cert, InputStream key, String dir) throws Exception {
|
public void cache(InputStream cert, InputStream key, Long vsId) throws Exception {
|
||||||
|
save(cert, key, config.getCacheDir() + vsId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(InputStream cert, InputStream key, String dir) throws Exception {
|
||||||
File f = new File(dir);
|
File f = new File(dir);
|
||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
f.mkdirs();
|
f.mkdirs();
|
||||||
}
|
}
|
||||||
OutputStream certos = new FileOutputStream(f.getPath() + "/ssl.crt");
|
OutputStream certos = new FileOutputStream(f.getPath() + "/ssl.crt", config.getWriteFileOption());
|
||||||
IOUtils.copy(cert, certos);
|
OutputStream keyos = new FileOutputStream(f.getPath() + "/ssl.key", config.getWriteFileOption());
|
||||||
certos.flush();
|
try {
|
||||||
OutputStream keyos = new FileOutputStream(f.getPath()+"/ssl.key");
|
IOUtils.copy(cert, certos);
|
||||||
IOUtils.copy(key, keyos);
|
certos.flush();
|
||||||
certos.flush();
|
IOUtils.copy(key, keyos);
|
||||||
|
certos.flush();
|
||||||
|
} finally {
|
||||||
|
certos.close();
|
||||||
|
keyos.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendIfExist(Long vsId, List<String> ip) {
|
public void sendIfExist(Long vsId, List<String> ips) throws Exception {
|
||||||
|
String errMsg = "";
|
||||||
|
boolean success = true;
|
||||||
|
for (String ip : ips) {
|
||||||
|
CertSyncClient c = new CertSyncClient("http://" + ip + ":8099/api/op/installcerts", config.getCacheDir() + vsId);
|
||||||
|
Response res = c.sync(vsId);
|
||||||
|
// retry
|
||||||
|
if (res.getStatus() / 100 > 2)
|
||||||
|
res = c.sync(vsId);
|
||||||
|
// still failed after retry
|
||||||
|
if (res.getStatus() / 100 > 2) {
|
||||||
|
success &= false;
|
||||||
|
try {
|
||||||
|
errMsg += ip + ":" + IOUtils.inputStreamStringify((InputStream) res.getEntity()) + ";";
|
||||||
|
} catch (IOException e) {
|
||||||
|
errMsg += ip + ":" + "Unable to parse response entity.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (success)
|
||||||
|
return;
|
||||||
|
throw new Exception(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CertSyncClient extends AbstractRestClient {
|
||||||
|
private final String fileDir;
|
||||||
|
|
||||||
|
protected CertSyncClient(String url, String fileDir) {
|
||||||
|
super(url);
|
||||||
|
this.fileDir = fileDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response sync(Long vsId) throws ValidationException {
|
||||||
|
File cert = new File(fileDir + "/ssl.crt");
|
||||||
|
File key = new File(fileDir + "/ssl.key");
|
||||||
|
if (cert.exists() && key.exists()) {
|
||||||
|
MultiPart mp = new MultiPart().bodyPart(new FileDataBodyPart("cert", cert, MediaType.APPLICATION_OCTET_STREAM_TYPE))
|
||||||
|
.bodyPart(new FileDataBodyPart("key", key, MediaType.APPLICATION_OCTET_STREAM_TYPE));
|
||||||
|
return getTarget().queryParam("vsId", vsId).request(MediaType.MULTIPART_FORM_DATA).post(
|
||||||
|
Entity.entity(mp, mp.getMediaType()));
|
||||||
|
}
|
||||||
|
throw new ValidationException("Certificate files cannot be found under " + fileDir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue