Squashed merge of Ssl Termination feature

Bug: https://issues.apache.org/jira/browse/CLOUDSTACK-4821
FS: https://cwiki.apache.org/confluence/display/CLOUDSTACK/SSL+Termination+Support

This patch implements the SSL offload feature for loadbalancers
and includes the implementaion for this to work with Netscaler.

The following are the new API's that this patch adds

uploadSslCert
deleteSslCert
listSslCert
assignCertToLoadBalancer
removeCertFromLoadBalancer

Unit tests are also included in the patch.
This commit is contained in:
Syed 2013-11-06 15:08:42 -05:00 committed by Murali Reddy
parent 07b68742c9
commit 0076307863
58 changed files with 3265 additions and 42 deletions

View File

@ -1,3 +1,4 @@
Apache CloudStack CHANGES
======================================

View File

@ -33,6 +33,7 @@ import com.cloud.network.lb.LoadBalancingRule.LbCondition;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
import com.cloud.utils.Pair;
@ -41,6 +42,7 @@ public class LoadBalancerTO {
String srcIp;
int srcPort;
String protocol;
String lbProtocol;
String algorithm;
boolean revoked;
boolean alreadyAdded;
@ -48,6 +50,7 @@ public class LoadBalancerTO {
DestinationTO[] destinations;
private StickinessPolicyTO[] stickinessPolicies;
private HealthCheckPolicyTO[] healthCheckPolicies;
private LbSslCert sslCert; /* XXX: Should this be SslCertTO? */
private AutoScaleVmGroupTO autoScaleVmGroupTO;
final static int MAX_STICKINESS_POLICIES = 1;
final static int MAX_HEALTHCHECK_POLICIES = 1;
@ -66,6 +69,8 @@ public class LoadBalancerTO {
this.inline = inline;
this.destinations = new DestinationTO[destinations.size()];
this.stickinessPolicies = null;
this.sslCert = null;
this.lbProtocol = null;
int i = 0;
for (LbDestination destination : destinations) {
this.destinations[i++] = new DestinationTO(destination.getIpAddress(), destination.getDestinationPortStart(), destination.isRevoked(), false);
@ -77,12 +82,12 @@ public class LoadBalancerTO {
List<LbStickinessPolicy> stickinessPolicies) {
this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, inline, arg_destinations,
stickinessPolicies, null);
stickinessPolicies, null, null, null);
}
public LoadBalancerTO(String id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked,
boolean alreadyAdded, boolean inline, List<LbDestination> arg_destinations,
List<LbStickinessPolicy> stickinessPolicies, List<LbHealthCheckPolicy> healthCheckPolicies) {
List<LbStickinessPolicy> stickinessPolicies, List<LbHealthCheckPolicy> healthCheckPolicies, LbSslCert sslCert, String lbProtocol) {
this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, inline, arg_destinations);
this.stickinessPolicies = null;
this.healthCheckPolicies = null;
@ -117,6 +122,9 @@ public class LoadBalancerTO {
if (index == 0)
this.healthCheckPolicies = null;
}
this.sslCert = sslCert;
this.lbProtocol = lbProtocol;
}
protected LoadBalancerTO() {
@ -142,6 +150,10 @@ public class LoadBalancerTO {
return protocol;
}
public String getLbProtocol() {
return lbProtocol;
}
public boolean isRevoked() {
return revoked;
}
@ -178,6 +190,10 @@ public class LoadBalancerTO {
return this.autoScaleVmGroupTO != null;
}
public LbSslCert getSslCert(){
return this.sslCert;
}
public static class StickinessPolicyTO {
private String _methodName;
private List<Pair<String, String>> _paramsList;
@ -294,6 +310,8 @@ public class LoadBalancerTO {
public String getMonitorState() {
return monitorState;
}
}
public static class CounterTO implements Serializable {
private final String name;
@ -558,5 +576,4 @@ public class LoadBalancerTO {
autoScaleVmGroupTO = new AutoScaleVmGroupTO(autoScaleVmGroup.getUuid(), autoScaleVmGroup.getMinMembers(), autoScaleVmGroup.getMaxMembers(), autoScaleVmGroup.getMemberPort(),
autoScaleVmGroup.getInterval(), autoScalePolicyTOs, autoScaleVmProfileTO, autoScaleVmGroup.getState(), lbAutoScaleVmGroup.getCurrentState());
}
}

View File

@ -133,6 +133,10 @@ public class EventTypes {
public static final String EVENT_LB_HEALTHCHECKPOLICY_CREATE = "LB.HEALTHCHECKPOLICY.CREATE";
public static final String EVENT_LB_HEALTHCHECKPOLICY_DELETE = "LB.HEALTHCHECKPOLICY.DELETE";
public static final String EVENT_LOAD_BALANCER_UPDATE = "LB.UPDATE";
public static final String EVENT_LB_CERT_UPLOAD = "LB.CERT.UPLOAD";
public static final String EVENT_LB_CERT_DELETE = "LB.CERT.DELETE";
public static final String EVENT_LB_CERT_ASSIGN = "LB.CERT.ASSIGN";
public static final String EVENT_LB_CERT_REMOVE = "LB.CERT.REMOVE";
// Global Load Balancer rules
public static final String EVENT_ASSIGN_TO_GLOBAL_LOAD_BALANCER_RULE = "GLOBAL.LB.ASSIGN";
@ -511,6 +515,10 @@ public class EventTypes {
entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_CREATE, LoadBalancer.class.getName());
entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_DELETE, LoadBalancer.class.getName());
entityEventDetails.put(EVENT_LOAD_BALANCER_UPDATE, LoadBalancer.class.getName());
entityEventDetails.put(EVENT_LB_CERT_UPLOAD, LoadBalancer.class.getName());
entityEventDetails.put(EVENT_LB_CERT_DELETE, LoadBalancer.class.getName());
entityEventDetails.put(EVENT_LB_CERT_ASSIGN, LoadBalancer.class.getName());
entityEventDetails.put(EVENT_LB_CERT_REMOVE, LoadBalancer.class.getName());
// Account events
entityEventDetails.put(EVENT_ACCOUNT_DISABLE, Account.class.getName());

View File

@ -181,6 +181,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
public static final Capability SupportedTrafficDirection = new Capability("SupportedTrafficDirection");
public static final Capability SupportedEgressProtocols = new Capability("SupportedEgressProtocols");
public static final Capability HealthCheckPolicy = new Capability("HealthCheckPolicy");
public static final Capability SslTermination = new Capability("SslTermination");
public static final Capability LbSchemes = new Capability("LbSchemes");
public static final Capability DhcpAccrossMultipleSubnets = new Capability("DhcpAccrossMultipleSubnets");

View File

@ -0,0 +1,32 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.network.lb;
import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.ListSslCertsCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
import org.apache.cloudstack.api.response.SslCertResponse;
import java.util.List;
public interface CertService {
public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd);
public void deleteSslCert(DeleteSslCertCmd deleteSslCertCmd);
public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd);
}

View File

@ -36,9 +36,11 @@ public class LoadBalancingRule {
private List<LbStickinessPolicy> stickinessPolicies;
private LbAutoScaleVmGroup autoScaleVmGroup;
private List<LbHealthCheckPolicy> healthCheckPolicies;
private LbSslCert sslCert;
private String lbProtocol;
public LoadBalancingRule(LoadBalancer lb, List<LbDestination> destinations,
List<LbStickinessPolicy> stickinessPolicies, List<LbHealthCheckPolicy> healthCheckPolicies, Ip sourceIp) {
List<LbStickinessPolicy> stickinessPolicies, List<LbHealthCheckPolicy> healthCheckPolicies, Ip sourceIp) {
this.lb = lb;
this.destinations = destinations;
this.stickinessPolicies = stickinessPolicies;
@ -46,6 +48,17 @@ public class LoadBalancingRule {
this.sourceIp = sourceIp;
}
public LoadBalancingRule(LoadBalancer lb, List<LbDestination> destinations,
List<LbStickinessPolicy> stickinessPolicies, List<LbHealthCheckPolicy> healthCheckPolicies, Ip sourceIp, LbSslCert sslCert, String lbProtocol) {
this.lb = lb;
this.destinations = destinations;
this.stickinessPolicies = stickinessPolicies;
this.healthCheckPolicies = healthCheckPolicies;
this.sourceIp = sourceIp;
this.sslCert = sslCert;
this.lbProtocol = lbProtocol;
}
public long getId() {
return lb.getId();
}
@ -90,6 +103,10 @@ public class LoadBalancingRule {
return lb.getProtocol();
}
public String getLbProtocol() {
return this.lbProtocol;
}
public FirewallRule.Purpose getPurpose() {
return FirewallRule.Purpose.LoadBalancing;
}
@ -123,6 +140,10 @@ public class LoadBalancingRule {
return healthCheckPolicies;
}
public LbSslCert getLbSslCert(){
return sslCert;
}
public interface Destination {
String getIpAddress();
@ -415,6 +436,44 @@ public class LoadBalancingRule {
}
}
public static class LbSslCert {
private String cert;
private String key;
private String password=null;
private String chain=null;
private boolean revoked;
public LbSslCert(String cert, String key, String password, String chain, boolean revoked) {
this.cert = cert;
this.key = key;
this.password = password;
this.chain = chain;
this.revoked = revoked;
}
public String getCert() {
return cert;
}
public String getKey() {
return key;
}
public String getPassword() {
return password;
}
public String getChain() {
return chain;
}
public boolean isRevoked(){
return revoked;
}
}
public Ip getSourceIp() {
return sourceIp;
}

View File

@ -52,7 +52,7 @@ public interface LoadBalancingRulesService {
*/
LoadBalancer createPublicLoadBalancerRule(String xId, String name, String description,
int srcPortStart, int srcPortEnd, int defPortStart, int defPortEnd, Long ipAddrId, String protocol, String algorithm,
long networkId, long lbOwnerId, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException;
long networkId, long lbOwnerId, boolean openFirewall, String lbProtocol) throws NetworkRuleConflictException, InsufficientAddressCapacityException;
LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd);
@ -94,10 +94,16 @@ public interface LoadBalancingRulesService {
*/
boolean assignToLoadBalancer(long lbRuleId, List<Long> vmIds);
boolean assignSSLCertToLoadBalancerRule(Long lbRuleId, String certName, String publicCert, String privateKey);
boolean removeFromLoadBalancer(long lbRuleId, List<Long> vmIds);
boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException;
boolean assignCertToLoadBalancer(long lbRuleId, Long CertId);
boolean removeCertFromLoadBalancer(long lbRuleId);
/**
* List instances that have either been applied to a load balancer or are eligible to be assigned to a load
* balancer.

View File

@ -0,0 +1,16 @@
package com.cloud.network.lb;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface SslCert extends InternalIdentity, Identity, ControlledEntity {
public String getCertificate();
public String getKey() ;
public String getChain();
public String getPassword();
public String getFingerPrint();
}

View File

@ -36,6 +36,9 @@ public class ApiConstants {
public static final String CATEGORY = "category";
public static final String CAN_REVERT = "canrevert";
public static final String CERTIFICATE = "certificate";
public static final String CERTIFICATE_CHAIN = "certchain";
public static final String CERTIFICATE_FINGERPRINT = "fingerprint";
public static final String CERTIFICATE_ID = "certid";
public static final String PRIVATE_KEY = "privatekey";
public static final String DOMAIN_SUFFIX = "domainsuffix";
public static final String DNS_SEARCH_ORDER = "dnssearchorder";

View File

@ -0,0 +1,92 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.cloudstack.api.command.user.loadbalancer;
import com.cloud.event.EventTypes;
import com.cloud.exception.*;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.user.Account;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.SslCertResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
@APICommand(name = "assignCertToLoadBalancer", description = "Assigns a certificate to a Load Balancer Rule", responseObject = SuccessResponse.class)
public class AssignCertToLoadBalancerCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger
.getLogger(AssignCertToLoadBalancerCmd.class.getName());
private static final String s_name = "assignCertToLoadBalancer";
@Parameter(name = ApiConstants.LBID, type = CommandType.UUID, entityType = FirewallRuleResponse.class,
required = true, description = "the ID of the load balancer rule")
Long lbRuleId;
@Parameter(name = ApiConstants.CERTIFICATE_ID, type = CommandType.UUID, entityType = SslCertResponse.class,
required = true, description = "the ID of the certificate")
Long certId;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
//To change body of implemented methods use File | Settings | File Templates.
if ( _lbService.assignCertToLoadBalancer( getLbRuleId(), getCertId()) ) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign certificate to loadbalancer");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_LB_CERT_ASSIGN;
}
@Override
public String getCommandName() {
return s_name;
}
@Override
public String getEventDescription() {
return "Assigining a certificate to a loadbalancer";
}
@Override
public long getEntityOwnerId() {
LoadBalancer lb = _entityMgr.findById(LoadBalancer.class, getLbRuleId());
if (lb == null) {
return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
}
return lb.getAccountId();
}
public Long getCertId(){
return certId;
}
public Long getLbRuleId(){
return lbRuleId;
}
}

View File

@ -102,6 +102,9 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements
"rule will be created for. Required when public Ip address is not associated with any Guest network yet (VPC case)")
private Long networkId;
@Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, description="The protocol for the LB")
private String lbProtocol;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -227,6 +230,10 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements
return null;
}
public String getLbProtocol(){
return lbProtocol;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@ -282,7 +289,7 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements
try {
LoadBalancer result = _lbService.createPublicLoadBalancerRule(getXid(), getName(), getDescription(),
getSourcePortStart(), getSourcePortEnd(), getDefaultPortStart(), getDefaultPortEnd(), getSourceIpAddressId(), getProtocol(), getAlgorithm(),
getNetworkId(), getEntityOwnerId(), getOpenFirewall());
getNetworkId(), getEntityOwnerId(), getOpenFirewall(), getLbProtocol());
this.setEntityId(result.getId());
this.setEntityUuid(result.getUuid());
} catch (NetworkRuleConflictException e) {

View File

@ -0,0 +1,83 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.cloudstack.api.command.user.loadbalancer;
import com.cloud.network.lb.CertService;
import org.apache.cloudstack.api.response.SslCertResponse;
import com.cloud.exception.*;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import javax.inject.Inject;
@APICommand(name = "deleteSslCert", description="Delete a certificate to cloudstack", responseObject=SuccessResponse.class)
public class DeleteSslCertCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeleteSslCertCmd.class.getName());
private static final String s_name = "deletesslcertresponse";
@Inject
CertService _certService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name= ApiConstants.ID, type=CommandType.UUID, entityType = SslCertResponse.class, required=true, description="Id of SSL certificate")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try {
_certService.deleteSslCert(this);
SuccessResponse rsp = new SuccessResponse();
rsp.setResponseName(getCommandName());
rsp.setObjectName("success");
this.setResponseObject(rsp);
} catch (Exception e) {
throw new CloudRuntimeException(e);
}
}
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
}

View File

@ -0,0 +1,106 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.cloudstack.api.command.user.loadbalancer;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.SslCertResponse;
import com.cloud.network.lb.CertService;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = "listSslCerts", description="Lists SSL certificates", responseObject=SslCertResponse.class)
public class ListSslCertsCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeleteSslCertCmd.class.getName());
private static final String s_name = "listsslcertsresponse";
@Inject
CertService _certService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name= ApiConstants.CERTIFICATE_ID, type=CommandType.UUID, entityType = SslCertResponse.class, required=false, description="Id of SSL certificate")
private Long certId;
@Parameter(name= ApiConstants.ACCOUNT_ID, type=CommandType.UUID, entityType = AccountResponse.class, required=false, description="Account Id")
private Long accountId;
@Parameter(name= ApiConstants.LBID, type=CommandType.UUID, entityType = FirewallRuleResponse.class, required=false, description="Loadbalancer Rule Id")
private Long lbId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getCertId() {
return certId;
}
public Long getAccountId() {
return accountId;
}
public Long getLbId(){
return lbId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute(){
try {
List<SslCertResponse> certResponseList = _certService.listSslCerts(this);
ListResponse<SslCertResponse> response = new ListResponse<SslCertResponse>();
response.setResponses(certResponseList);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (Exception e) {
throw new CloudRuntimeException(e);
}
}
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
}

View File

@ -0,0 +1,82 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.cloudstack.api.command.user.loadbalancer;
import com.cloud.event.EventTypes;
import com.cloud.exception.*;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.user.Account;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
@APICommand(name = "removeCertFromLoadBalancer", description = "Removes a certificate from a Load Balancer Rule", responseObject = SuccessResponse.class)
public class RemoveCertFromLoadBalancerCmd extends BaseAsyncCmd{
public static final Logger s_logger = Logger.getLogger(RemoveCertFromLoadBalancerCmd.class.getName());
private static final String s_name = "removeCertFromLoadBalancer";
@Parameter(name = ApiConstants.LBID, type = CommandType.UUID, entityType = FirewallRuleResponse.class,
required = true, description = "the ID of the load balancer rule")
Long lbRuleId;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
boolean result = _lbService.removeCertFromLoadBalancer(getLbRuleId());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove certificate from load balancer rule");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_LB_CERT_REMOVE;
}
@Override
public String getCommandName() {
return s_name;
}
@Override
public String getEventDescription() {
return "Removing a certificate from a loadbalancer with ID " + getLbRuleId();
}
@Override
public long getEntityOwnerId() {
LoadBalancer lb = _entityMgr.findById(LoadBalancer.class, getLbRuleId());
if (lb == null) {
return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
}
return lb.getAccountId();
}
public Long getLbRuleId(){
return this.lbRuleId;
}
}

View File

@ -0,0 +1,103 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.cloudstack.api.command.user.loadbalancer;
import org.apache.cloudstack.api.response.SslCertResponse;
import com.cloud.exception.*;
import com.cloud.network.lb.CertService;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import javax.inject.Inject;
@APICommand(name = "uploadSslCert", description="Upload a certificate to cloudstack", responseObject=SslCertResponse.class)
public class UploadSslCertCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(UploadSslCertCmd.class.getName());
private static final String s_name = "uploadsslcertresponse";
@Inject CertService _certService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name= ApiConstants.CERTIFICATE, type=CommandType.STRING, required=true, description="SSL certificate",length=16384)
private String cert;
@Parameter(name=ApiConstants.PRIVATE_KEY, type=CommandType.STRING, required=true, description="Private key", length=16384)
private String key;
@Parameter(name=ApiConstants.CERTIFICATE_CHAIN, type=CommandType.STRING, description="Certificate chain of trust", length=2097152)
private String chain;
@Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, description="Password for the private key")
private String password;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getCert() {
return cert;
}
public String getKey() {
return key;
}
public String getChain() {
return chain;
}
public String getPassword() {
return password;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try{
SslCertResponse response = _certService.uploadSslCert(this);
setResponseObject(response);
response.setResponseName(getCommandName());
} catch (Exception e){
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
}

View File

@ -0,0 +1,90 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.cloudstack.api.response;
import com.cloud.network.lb.SslCert;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import java.util.List;
//import org.apache.cloudstack.api.EntityReference;
@EntityReference(value= SslCert.class)
public class SslCertResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "SSL certificate ID")
private String id;
@SerializedName(ApiConstants.CERTIFICATE)
@Param(description = "certificate")
private String certificate;
@SerializedName(ApiConstants.PRIVATE_KEY)
@Param(description = "private key")
private String privatekey;
@SerializedName(ApiConstants.ACCOUNT)
@Param(description = "account for the certificate")
private String accountName;
@SerializedName(ApiConstants.CERTIFICATE_CHAIN)
@Param(description = "certificate chain")
private String certchain;
@SerializedName(ApiConstants.CERTIFICATE_FINGERPRINT)
@Param(description = "certificate fingerprint")
private String fingerprint;
@SerializedName(ApiConstants.LOAD_BALANCER_RULE_LIST)
@Param(description = "List of loabalancers this certificate is bound to")
List<String> lbIds;
public SslCertResponse() {
}
public void setId(String id) {
this.id = id;
}
public void setCertificate(String cert) {
this.certificate = cert;
}
public void setPrivatekey(String key) {
this.privatekey = key;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public void setCertchain(String chain) {
this.certchain = chain;
}
public void setFingerprint(String fingerprint){
this.fingerprint = fingerprint;
}
public void setLbIds(List<String> lbIds){
this.lbIds = lbIds;
}
}

View File

@ -165,6 +165,14 @@ deleteLBHealthCheckPolicy=15
listLoadBalancerRuleInstances=15
updateLoadBalancerRule=15
##### SSL offload commands
uploadSslCert=15
deleteSslCert=15
listSslCerts=15
assignCertToLoadBalancer=15
removeCertFromLoadBalancer=15
#### autoscale commands
createCounter=1
createCondition=15

View File

@ -33,6 +33,7 @@ public class LoadBalancerConfigCommand extends NetworkElementCommand {
public String lbStatsAuth = "admin1:AdMiN123";
public String lbStatsUri = "/admin?stats";
public String maxconn ="";
public String lbProtocol;
public boolean keepAliveEnabled = false;
NicTO nic;
Long vpcId;

View File

@ -25,6 +25,7 @@ import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
import com.cloud.network.rules.LbStickinessMethod;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.network.rules.LoadBalancerContainer.Scheme;
@ -33,7 +34,8 @@ import com.cloud.user.Account;
public interface LoadBalancingRulesManager {
LoadBalancer createPublicLoadBalancer(String xId, String name, String description,
int srcPort, int destPort, long sourceIpId, String protocol, String algorithm, boolean openFirewall, CallContext caller)
int srcPort, int destPort, long sourceIpId, String protocol, String algorithm,
boolean openFirewall, CallContext caller, String lbProtocol)
throws NetworkRuleConflictException;
boolean removeAllLoadBalanacersForIp(long ipId, Account caller, long callerUserId);
@ -42,6 +44,7 @@ public interface LoadBalancingRulesManager {
List<LbStickinessPolicy> getStickinessPolicies(long lbId);
List<LbStickinessMethod> getStickinessMethods(long networkid);
List<LbHealthCheckPolicy> getHealthCheckPolicies(long lbId);
LbSslCert getLbSslCert(long lbId);
/**
* Remove vm from all load balancers

View File

@ -189,6 +189,7 @@
<bean id="launchPermissionDaoImpl" class="com.cloud.storage.dao.LaunchPermissionDaoImpl" />
<bean id="loadBalancerDaoImpl" class="com.cloud.network.dao.LoadBalancerDaoImpl" />
<bean id="loadBalancerVMMapDaoImpl" class="com.cloud.network.dao.LoadBalancerVMMapDaoImpl" />
<bean id="loadBalancerCertMapDaoImpl" class="com.cloud.network.dao.LoadBalancerCertMapDaoImpl" />
<bean id="managementServerHostDaoImpl" class="com.cloud.cluster.dao.ManagementServerHostDaoImpl" />
<bean id="managementServerHostPeerDaoImpl" class="com.cloud.cluster.dao.ManagementServerHostPeerDaoImpl" />
<bean id="networkAccountDaoImpl" class="com.cloud.network.dao.NetworkAccountDaoImpl" />
@ -252,6 +253,7 @@
<bean id="snapshotDaoImpl" class="com.cloud.storage.dao.SnapshotDaoImpl" />
<bean id="snapshotPolicyDaoImpl" class="com.cloud.storage.dao.SnapshotPolicyDaoImpl" />
<bean id="snapshotScheduleDaoImpl" class="com.cloud.storage.dao.SnapshotScheduleDaoImpl" />
<bean id="sslCertDao" class="com.cloud.network.dao.SslCertDaoImpl" />
<bean id="staticRouteDaoImpl" class="com.cloud.network.vpc.dao.StaticRouteDaoImpl" />
<bean id="storageNetworkIpAddressDaoImpl" class="com.cloud.dc.dao.StorageNetworkIpAddressDaoImpl" />
<bean id="storageNetworkIpRangeDaoImpl" class="com.cloud.dc.dao.StorageNetworkIpRangeDaoImpl" />

View File

@ -0,0 +1,29 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.network.dao;
import com.cloud.network.LBHealthCheckPolicyVO;
import com.cloud.utils.db.GenericDao;
import java.util.List;
public interface LoadBalancerCertMapDao extends GenericDao<LoadBalancerCertMapVO,Long> {
List<LoadBalancerCertMapVO> listByCertId(Long certId);
List<LoadBalancerCertMapVO> listByAccountId(Long accountId);
LoadBalancerCertMapVO findByLbRuleId(Long id);
}

View File

@ -0,0 +1,79 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.network.dao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import javax.ejb.Local;
import javax.inject.Inject;
import java.util.List;
@Local(value = {LoadBalancerCertMapDao.class})
public class LoadBalancerCertMapDaoImpl extends GenericDaoBase<LoadBalancerCertMapVO, Long> implements LoadBalancerCertMapDao {
private final SearchBuilder<LoadBalancerCertMapVO> listByCertId;
private final SearchBuilder<LoadBalancerCertMapVO> findByLbRuleId;
@Inject SslCertDao _sslCertDao;
public LoadBalancerCertMapDaoImpl() {
listByCertId = createSearchBuilder();
listByCertId.and("certificateId", listByCertId.entity().getCertId(), SearchCriteria.Op.EQ);
listByCertId.done();
findByLbRuleId = createSearchBuilder();
findByLbRuleId.and("loadBalancerId", findByLbRuleId.entity().getLbId(), SearchCriteria.Op.EQ);
findByLbRuleId.done();
}
@Override
public List<LoadBalancerCertMapVO> listByCertId(Long certId) {
SearchCriteria<LoadBalancerCertMapVO> sc = listByCertId.create();
sc.setParameters("certificateId", certId);
return listBy(sc);
}
@Override
public LoadBalancerCertMapVO findByLbRuleId(Long LbId) {
SearchCriteria<LoadBalancerCertMapVO> sc = findByLbRuleId.create();
sc.setParameters("loadBalancerId", LbId);
return findOneBy(sc);
}
@Override
public List<LoadBalancerCertMapVO> listByAccountId(Long accountId) {
SearchBuilder<LoadBalancerCertMapVO> listByAccountId;
SearchBuilder<SslCertVO> certsForAccount;
listByAccountId = createSearchBuilder();
certsForAccount = _sslCertDao.createSearchBuilder();
certsForAccount.and("accountId", certsForAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
listByAccountId.join("certsForAccount", certsForAccount, certsForAccount.entity().getId(), listByAccountId.entity().getLbId(), JoinBuilder.JoinType.INNER);
certsForAccount.done();
listByAccountId.done();
SearchCriteria<LoadBalancerCertMapVO> sc = listByAccountId.create();
sc.setParameters("accountId", accountId);
return listBy(sc);
}
}

View File

@ -0,0 +1,96 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.network.dao;
import org.apache.cloudstack.api.InternalIdentity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.UUID;
@Entity
@Table(name="load_balancer_cert_map")
public class LoadBalancerCertMapVO implements InternalIdentity {
@Id
@Column(name="id")
private Long id;
@Column(name="uuid")
private String uuid;
@Column(name="load_balancer_id")
private Long lbId;
@Column(name="certificate_id")
private Long certId;
@Column(name="revoke")
private boolean revoke = false;
public LoadBalancerCertMapVO() {
this.uuid = UUID.randomUUID().toString();
}
public LoadBalancerCertMapVO(Long lbId, Long certId, boolean revoke) {
this.lbId = lbId;
this.certId = certId;
this.revoke = revoke;
this.uuid = UUID.randomUUID().toString();
}
// Getters
@Override
public long getId() {
return id;
}
public String getUuid() {
return uuid;
}
public Long getLbId() {
return lbId;
}
public Long getCertId() {
return certId;
}
public boolean isRevoke() {
return revoke;
}
//Setters
public void setLbId(Long lbId) {
this.lbId = lbId;
}
public void setCertId(Long certId) {
this.certId = certId;
}
public void setRevoke(boolean revoke) {
this.revoke = revoke;
}
}

View File

@ -59,10 +59,15 @@ public class LoadBalancerVO extends FirewallRuleVO implements LoadBalancer {
@Column(name="scheme")
Scheme scheme = Scheme.Public;
@Column(name="lb_protocol")
String lbProtocol;
public LoadBalancerVO() {
}
public LoadBalancerVO(String xId, String name, String description, long srcIpId, int srcPort, int dstPort, String algorithm, long networkId, long accountId, long domainId) {
public LoadBalancerVO(String xId, String name, String description, long srcIpId, int srcPort, int dstPort, String algorithm, long networkId,
long accountId, long domainId, String lbProtocol) {
super(xId, srcIpId, srcPort, NetUtils.TCP_PROTO, networkId, accountId, domainId, Purpose.LoadBalancing, null, null, null, null);
this.name = name;
this.description = description;
@ -70,6 +75,7 @@ public class LoadBalancerVO extends FirewallRuleVO implements LoadBalancer {
this.defaultPortStart = dstPort;
this.defaultPortEnd = dstPort;
this.scheme = Scheme.Public;
this.lbProtocol = lbProtocol;
}
@Override
@ -101,6 +107,14 @@ public class LoadBalancerVO extends FirewallRuleVO implements LoadBalancer {
this.name = name;
}
public String getLbProtocol(){
return lbProtocol;
}
public void setLbProtocol(String lbProtocol){
this.lbProtocol = lbProtocol;
}
public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}

View File

@ -0,0 +1,27 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.network.dao;
import com.cloud.utils.db.GenericDao;
import java.util.List;
public interface SslCertDao extends GenericDao<SslCertVO, Long> {
List<SslCertVO> listByAccountId(Long id);
}

View File

@ -0,0 +1,31 @@
package com.cloud.network.dao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import javax.ejb.Local;
import java.util.List;
@Local(value = {SslCertDao.class})
public class SslCertDaoImpl extends GenericDaoBase<SslCertVO, Long> implements SslCertDao {
private final SearchBuilder<SslCertVO> listByAccountId;
public SslCertDaoImpl() {
listByAccountId = createSearchBuilder();
listByAccountId.and("accountId", listByAccountId.entity().getAccountId(), SearchCriteria.Op.EQ);
listByAccountId.done();
}
@Override
public List<SslCertVO> listByAccountId(Long accountId) {
SearchCriteria<SslCertVO> sc = listByAccountId.create();
sc.setParameters("accountId", accountId);
return listBy(sc);
}
}

View File

@ -0,0 +1,132 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.network.dao;
import com.cloud.network.lb.SslCert;
import com.cloud.utils.db.Encrypt;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.InternalIdentity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.UUID;
@Entity
@Table(name="sslcerts")
public class SslCertVO implements SslCert {
@Id
@Column(name="id")
private Long id;
@Column(name="uuid")
private String uuid;
@Column(name="certificate",length=16384)
private String certificate;
@Column(name="chain",length=2097152)
private String chain;
@Encrypt
@Column(name="key",length=16384)
private String key;
@Encrypt
@Column(name="password")
private String password;
@Column(name="account_id")
private Long accountId;
@Column(name = "domain_id")
long domainId;
@Column(name = "fingerprint")
String fingerPrint;
public SslCertVO() {
this.uuid = UUID.randomUUID().toString();
}
public SslCertVO(String cert, String key, String password, String chain, Long accountId, Long domainId, String fingerPrint) {
this.certificate = cert;
this.key = key;
this.chain = chain;
this.password = password;
this.accountId = accountId;
this.domainId = domainId;
this.fingerPrint = fingerPrint;
this.uuid = UUID.randomUUID().toString();
}
// Getters
@Override
public long getId() {
return id;
}
@Override
public String getUuid() {
return uuid;
}
@Override
public String getCertificate() {
return certificate;
}
@Override
public String getKey() {
return key;
}
@Override
public String getChain() {
return chain;
}
@Override
public long getAccountId() {
return accountId;
}
@Override
public String getPassword() {
return password;
}
@Override
public long getDomainId() {
return domainId;
}
@Override
public String getFingerPrint() {
return fingerPrint;
}
}

View File

@ -98,6 +98,7 @@ import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
import com.cloud.network.lb.dao.ElasticLbVmMapDao;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.router.VirtualRouter.RedundantState;
@ -290,6 +291,7 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements Elast
private void createApplyLoadBalancingRulesCommands(
List<LoadBalancingRule> rules, DomainRouterVO elbVm, Commands cmds, long guestNetworkId) {
/* XXX: cert */
LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()];
int i = 0;
for (LoadBalancingRule rule : rules) {
@ -302,7 +304,8 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements Elast
int srcPort = rule.getSourcePortStart();
String uuid = rule.getUuid();
List<LbDestination> destinations = rule.getDestinations();
LoadBalancerTO lb = new LoadBalancerTO(uuid, elbIp, srcPort, protocol, algorithm, revoked, false, false, destinations);
LoadBalancerTO lb = new LoadBalancerTO(uuid, elbIp, srcPort, protocol, algorithm, revoked,
false, false, destinations);
lbs[i++] = lb;
}
@ -377,8 +380,9 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements Elast
List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId());
LoadBalancingRule loadBalancing = new LoadBalancingRule(
lb, dstList, policyList, hcPolicyList, sourceIp);
lb, dstList, policyList, hcPolicyList, sourceIp, sslCert, lb.getLbProtocol());
lbRules.add(loadBalancing);
}
return applyLBRules(elbVm, lbRules, network.getId());
@ -664,7 +668,7 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements Elast
result = _lbMgr.createPublicLoadBalancer(lb.getXid(), lb.getName(), lb.getDescription(),
lb.getSourcePortStart(), lb.getDefaultPortStart(), ipId.longValue(), lb.getProtocol(),
lb.getAlgorithm(), false, CallContext.current());
lb.getAlgorithm(), false, CallContext.current(), lb.getLbProtocol());
} catch (NetworkRuleConflictException e) {
s_logger.warn("Failed to create LB rule, not continuing with ELB deployment");
if (newIp) {

View File

@ -77,6 +77,7 @@ import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.router.VirtualRouter;

View File

@ -212,7 +212,7 @@ public class InternalLBVMManagerTest extends TestCase {
List<DomainRouterVO> vms = new ArrayList<DomainRouterVO>();
List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
LoadBalancingRule rule = new LoadBalancingRule(null, null,
null, null, null);
null, null, null, null, null);
rules.add(rule);
try {
@ -232,7 +232,7 @@ public class InternalLBVMManagerTest extends TestCase {
List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
LoadBalancingRule rule = new LoadBalancingRule(null, null,
null, null, null);
null, null, null, null, null);
rules.add(rule);
try {
@ -252,7 +252,7 @@ public class InternalLBVMManagerTest extends TestCase {
List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
LoadBalancingRule rule = new LoadBalancingRule(null, null,
null, null, null);
null, null, null, null, null);
rules.add(rule);
try {
@ -272,7 +272,7 @@ public class InternalLBVMManagerTest extends TestCase {
List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
LoadBalancingRule rule = new LoadBalancingRule(null, null,
null, null, null);
null, null, null, null, null);
rules.add(rule);
try {

View File

@ -161,6 +161,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
@Inject
ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
private boolean canHandle(Network config, Service service) {
DataCenter zone = _dcDao.findById(config.getDataCenterId());
boolean handleInAdvanceZone = (zone.getNetworkType() == NetworkType.Advanced &&
@ -277,7 +278,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
// Supports only Public load balancing
lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString());
// Specifies that load balancing rules can support autoscaling and the list of counters it supports
AutoScaleCounter counter;
List<AutoScaleCounter> counterList = new ArrayList<AutoScaleCounter>();
@ -319,6 +320,10 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
staticNatCapabilities.put(Capability.ElasticIp, "true");
capabilities.put(Service.StaticNat, staticNatCapabilities);
// Supports SSL offloading
lbCapabilities.put(Capability.SslTermination, "true");
// TODO - Murali, please put correct capabilities here
Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
@ -516,6 +521,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
cmdList.add(DeleteNetscalerLoadBalancerCmd.class);
cmdList.add(ListNetscalerLoadBalancerNetworksCmd.class);
cmdList.add(ListNetscalerLoadBalancersCmd.class);
return cmdList;
}
@ -732,7 +738,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
List<LbDestination> destinations = rule.getDestinations();
if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies());
LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations,
rule.getStickinessPolicies(), rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol());
if (rule.isAutoScaleConfig()) {
loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup());
}
@ -894,7 +901,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked,
false, false, destinations, null, rule.getHealthCheckPolicies());
false, false, destinations, null, rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol());
loadBalancersToApply.add(loadBalancer);
}
}
@ -1024,5 +1031,4 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
}
return true;
}
}

View File

@ -25,6 +25,10 @@ import java.util.Map;
import javax.naming.ConfigurationException;
import com.citrix.netscaler.nitro.resource.config.ssl.sslcertkey;
import com.citrix.netscaler.nitro.resource.config.ssl.sslvserver_sslcertkey_binding;
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
import com.cloud.utils.ssh.SshHelper;
import org.apache.log4j.Logger;
import com.citrix.netscaler.nitro.exception.nitro_exception;
@ -235,6 +239,7 @@ public class NetscalerResource implements ServerResource {
//enable load balancing feature
enableLoadBalancingFeature();
SSL.enableSslFeature(_netscalerService);
//if the the device is cloud stack provisioned then make it part of the public network
if (_cloudManaged) {
@ -550,6 +555,8 @@ public class NetscalerResource implements ServerResource {
String lbAlgorithm = loadBalancer.getAlgorithm();
String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
String nsMonitorName = generateNSMonitorName(srcIp, srcPort);
LbSslCert sslCert = loadBalancer.getSslCert();
if(loadBalancer.isAutoScaleVmGroupTO()) {
applyAutoScaleConfig(loadBalancer);
// Continue to process all the rules.
@ -558,6 +565,7 @@ public class NetscalerResource implements ServerResource {
boolean hasMonitor = false;
boolean deleteMonitor = false;
boolean destinationsToAdd = false;
boolean deleteCert = false;
for (DestinationTO destination : loadBalancer.getDestinations()) {
if (!destination.isRevoked()) {
destinationsToAdd = true;
@ -655,9 +663,35 @@ public class NetscalerResource implements ServerResource {
}
}
if(sslCert != null && lbProtocol.equals(NetUtils.SSL_PROTO)) {
if ( sslCert.isRevoked() ){
deleteCert = true;
} else{
String certName = generateSslCertName(srcIp, srcPort);
String keyName = generateSslKeyName(srcIp, srcPort);
String certKeyName = generateSslCertKeyName(srcIp, srcPort);
if ( SSL.isSslCertKeyPresent(_netscalerService, certKeyName)){
SSL.deleteSslCertKey(_netscalerService, certKeyName);
}
SSL.uploadCert(_ip, _username, _password, certName, sslCert.getCert().getBytes());
SSL.uploadKey(_ip, _username, _password, keyName, sslCert.getKey().getBytes());
SSL.createSslCertKey(_netscalerService, certName, keyName, certKeyName, sslCert.getPassword());
SSL.bindCertKeyToVserver(_netscalerService, certKeyName, nsVirtualServerName);
}
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Successfully added LB destination: " + destination.getDestIp() + ":" + destination.getDestPort() + " to load balancer " + srcIp + ":" + srcPort);
}
} else {
// remove a destination from the deployed load balancing rule
com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
@ -731,11 +765,27 @@ public class NetscalerResource implements ServerResource {
}
removeLBVirtualServer(nsVirtualServerName);
deleteMonitor = true;
deleteCert = true;
}
}
if(deleteMonitor) {
removeLBMonitor(nsMonitorName);
}
if ( sslCert != null && deleteCert){
String certName = generateSslCertName(srcIp, srcPort);
String keyName = generateSslKeyName(srcIp, srcPort);
String certKeyName = generateSslCertKeyName(srcIp, srcPort);
// unbind before deleting
if ( nsVirtualServerExists(nsVirtualServerName) ){
SSL.unbindCertKeyFromVserver(_netscalerService, certKeyName, nsVirtualServerName);
}
SSL.deleteSslCertKey(_netscalerService, certKeyName);
SSL.deleteCertFile(_ip, _username, _password, certName);
SSL.deleteKeyFile(_ip, _username, _password, keyName);
}
}
@ -1666,6 +1716,173 @@ public class NetscalerResource implements ServerResource {
}
}
/* SSL Termination */
private static class SSL {
private static final String SSL_CERT_PATH = "/nsconfig/ssl/";
private static final int SSH_PORT = 22;
private static boolean isSslCertKeyPresent(nitro_service ns, String certKeyName) throws ExecutionException {
String filter = "certkey:" + certKeyName;
try {
if (sslcertkey.count_filtered(ns, filter) > 0) return true;
} catch (nitro_exception e){
throw new ExecutionException("Failed to get certkey " + e.getMessage());
} catch (Exception e){
throw new ExecutionException("Failed to get certkey " + e.getMessage());
}
return false;
}
private static void deleteSslCertKey(nitro_service ns, String certKeyName) throws ExecutionException {
try {
sslcertkey certkey = new sslcertkey();
certkey.set_certkey(certKeyName);
sslcertkey.delete(ns, certkey);
} catch (nitro_exception e){
throw new ExecutionException("Failed to delete certkey " + e.getMessage());
} catch (Exception e){
throw new ExecutionException("Failed to delete certkey " + e.getMessage());
}
}
private static void deleteCertFile(String nsIp, String username, String password, String certName) throws Exception {
SshHelper.sshExecute(nsIp,SSH_PORT,username,null,password,"shell rm " + SSL_CERT_PATH + certName);
}
private static void deleteKeyFile(String nsIp, String username, String password, String keyName) throws Exception {
SshHelper.sshExecute(nsIp,SSH_PORT,username,null,password,"shell rm " + SSL_CERT_PATH + keyName);
}
private static void createSslCertKey(nitro_service ns, String certName, String keyName, String certKeyName, String password) throws ExecutionException {
s_logger.debug("Adding cert to netscaler");
try {
sslcertkey certkey = new sslcertkey();
certkey.set_certkey(certKeyName);
certkey.set_cert(SSL_CERT_PATH + certName);
certkey.set_key(SSL_CERT_PATH + keyName);
if( password != null ) {
certkey.set_passplain(password);
}
certkey.perform_operation(ns);
} catch (nitro_exception e){
throw new ExecutionException("Failed to add certkey binding " + e.getMessage());
} catch (Exception e){
throw new ExecutionException("Failed to add certkey binding " + e.getMessage());
}
}
public static void updateCertKey(nitro_service ns, String certKeyName, String cert, String key, String password) throws ExecutionException {
try{
sslcertkey certkey = sslcertkey.get(ns, certKeyName);
if ( cert != null )
certkey.set_cert(cert);
if ( key != null )
certkey.set_key(cert);
if ( password != null )
certkey.set_passplain(cert);
sslcertkey.change(ns,certkey);
} catch (nitro_exception e){
throw new ExecutionException("Failed to update ssl on load balancer due to " + e.getMessage());
} catch (Exception e){
throw new ExecutionException("Failed to update ssl on load balancer due to " + e.getMessage());
}
}
private static void bindCertKeyToVserver(nitro_service ns, String certKeyName, String vserver) throws ExecutionException {
s_logger.debug("Adding cert to netscaler");
try {
sslvserver_sslcertkey_binding cert_binding = new sslvserver_sslcertkey_binding();
cert_binding.set_certkeyname(certKeyName);
cert_binding.set_vservername(vserver);
cert_binding.perform_operation(ns);
} catch (nitro_exception e){
throw new ExecutionException("Failed to bind certkey to vserver due to " + e.getMessage());
} catch (Exception e){
throw new ExecutionException("Failed to bind certkey to vserver due to " + e.getMessage());
}
}
private static void unbindCertKeyFromVserver(nitro_service ns, String certKeyName, String vserver) throws ExecutionException {
try {
sslvserver_sslcertkey_binding cert_binding = new sslvserver_sslcertkey_binding();
cert_binding.set_certkeyname(certKeyName);
cert_binding.set_vservername(vserver);
sslvserver_sslcertkey_binding.delete(ns,cert_binding);
} catch (nitro_exception e){
throw new ExecutionException("Failed to unbind certkey to vserver due to " + e.getMessage());
} catch (Exception e){
throw new ExecutionException("Failed to unbind certkey to vserver due to " + e.getMessage());
}
}
private static void uploadCert(String nsIp, String user, String password, String certName, byte[] certData) throws ExecutionException {
try {
SshHelper.scpTo(nsIp,SSH_PORT,user,null,password, SSL_CERT_PATH, certData, certName, null);
} catch (Exception e){
throw new ExecutionException("Failed to copy private key to device " + e.getMessage());
}
}
private static void uploadKey(String nsIp, String user, String password, String keyName, byte[] keyData) throws ExecutionException {
try {
SshHelper.scpTo(nsIp, SSH_PORT, user, null, password, SSL_CERT_PATH, keyData, keyName, null);
} catch (Exception e){
throw new ExecutionException("Failed to copy private key to device " + e.getMessage());
}
}
private static void enableSslFeature(nitro_service ns) throws ExecutionException {
try {
base_response result = ns.enable_features(new String[]{"SSL"});
if( result.errorcode != 0 )
throw new ExecutionException("Unable to enable SSL on LB");
} catch (nitro_exception e){
throw new ExecutionException("Failed to enable ssl feature on load balancer due to " + e.getMessage());
} catch (Exception e){
throw new ExecutionException("Failed to enable ssl feature on load balancer due to " + e.getMessage());
}
}
public static boolean checkSslFeature(nitro_service ns) throws ExecutionException {
try {
String[] features = ns.get_enabled_features();
if (features != null) {
for (String feature : features) {
if (feature.equalsIgnoreCase("SSL")) {
return true;
}
}
}
return false;
} catch (nitro_exception e){
throw new ExecutionException("Failed to check ssl feature on load balancer due to " + e.getMessage());
} catch (Exception e){
throw new ExecutionException("Failed to check ssl feature on load balancer due to " + e.getMessage());
}
}
}
private void enableVPXInterfaces(String publicIf, String privateIf, ns ns_obj) {
// enable VPX to use 10 gigabit Ethernet interfaces if public/private interface
@ -2110,6 +2327,25 @@ public class NetscalerResource implements ServerResource {
}
}
private boolean nsVirtualServerExists(String vserverName) throws ExecutionException {
try {
if (com.citrix.netscaler.nitro.resource.config.lb.lbvserver.get(_netscalerService, vserverName) != null) {
return true;
} else {
return false;
}
} catch (nitro_exception e) {
if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
return false;
} else {
throw new ExecutionException("Failed to verify VServer " + vserverName + " exists on the NetScaler device due to " + e.getMessage());
}
} catch (Exception e) {
throw new ExecutionException("Failed to verify VServer " + vserverName + " exists on the NetScaler device due to " + e.getMessage());
}
}
private boolean nsVlanNsipBindingExists(long vlanTag, String vlanSelfIp) throws ExecutionException {
try {
vlan_nsip_binding[] vlanNsipBindings = vlan_nsip_binding.get(_netscalerService, vlanTag);
@ -2308,11 +2544,14 @@ public class NetscalerResource implements ServerResource {
private String getNetScalerProtocol(LoadBalancerTO loadBalancer) throws ExecutionException {
String port = Integer.toString(loadBalancer.getSrcPort());
String lbProtocol = loadBalancer.getProtocol();
String lbProtocol = loadBalancer.getLbProtocol();
StickinessPolicyTO[] stickyPolicies = loadBalancer.getStickinessPolicies();
String nsProtocol = "TCP";
if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){
if(lbProtocol == null)
lbProtocol = loadBalancer.getProtocol();
if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){
StickinessPolicyTO stickinessPolicy = stickyPolicies[0];
if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()) ||
(StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()))) {
@ -2321,6 +2560,10 @@ public class NetscalerResource implements ServerResource {
}
}
if( lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO) || lbProtocol.equalsIgnoreCase(NetUtils.HTTP_PROTO))
return lbProtocol.toUpperCase();
if (port.equals(NetUtils.HTTP_PORT)) {
nsProtocol = "HTTP";
} else if (NetUtils.TCP_PROTO.equalsIgnoreCase(lbProtocol)) {
@ -3381,6 +3624,18 @@ public class NetscalerResource implements ServerResource {
return counterName.replace(' ', '_');
}
private String generateSslCertName(String srcIp, long srcPort) {
// maximum length supported by NS is 31
return genObjectName("Cloud-Cert", srcIp, srcPort);
}
private String generateSslKeyName(String srcIp, long srcPort) {
return genObjectName("Cloud-Key", srcIp, srcPort);
}
private String generateSslCertKeyName(String srcIp, long srcPort) {
return genObjectName("Cloud-CertKey", srcIp, srcPort);
}
private String genObjectName(Object... args) {
String objectName = "";
for (int i = 0; i < args.length; i++) {

View File

@ -223,4 +223,6 @@
<bean id="GlobalLoadBalancingRulesServiceImpl"
class="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl" />
<bean id="certServiceImpl" class="org.apache.cloudstack.network.lb.CertServiceImpl" />
</beans>

View File

@ -899,7 +899,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
boolean inline = _networkMgr.isNetworkInlineMode(network);
LoadBalancerTO loadBalancer = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies(),
rule.getHealthCheckPolicies());
rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol());
if (rule.isAutoScaleConfig()) {
loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup());
}
@ -1184,7 +1184,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
if ((destinations != null && !destinations.isEmpty()) || !rule.isAutoScaleConfig()) {
boolean inline = _networkMgr.isNetworkInlineMode(network);
LoadBalancerTO loadBalancer = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked,
false, inline, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies());
false, inline, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol());
loadBalancersToApply.add(loadBalancer);
}
}
@ -1218,5 +1218,5 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
}
}
return null;
}
}
}

View File

@ -107,6 +107,9 @@ import com.cloud.network.dao.LoadBalancerVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.LoadBalancerCertMapDao;
import com.cloud.network.dao.LoadBalancerCertMapVO;
import com.cloud.network.dao.SslCertVO;
import com.cloud.network.element.LoadBalancingServiceProvider;
import com.cloud.network.lb.LoadBalancingRule.LbAutoScalePolicy;
import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmGroup;
@ -115,6 +118,7 @@ import com.cloud.network.lb.LoadBalancingRule.LbCondition;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
import com.cloud.network.rules.FirewallManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.FirewallRuleType;
@ -253,6 +257,9 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
IpAddressManager _ipAddrMgr;
@Inject
EntityManager _entityMgr;
@Inject
LoadBalancerCertMapDao _lbCertMapDao;
// Will return a string. For LB Stickiness this will be a json, for
// autoscale this will be "," separated values
@ -350,7 +357,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
*/
List<LbStickinessPolicy> policyList = getStickinessPolicies(lb.getId());
Ip sourceIp = getSourceIp(lb);
LoadBalancingRule rule = new LoadBalancingRule(lb, null, policyList, null, sourceIp);
LoadBalancingRule rule = new LoadBalancingRule(lb, null, policyList, null, sourceIp, null, lb.getLbProtocol());
rule.setAutoScaleVmGroup(lbAutoScaleVmGroup);
if (!isRollBackAllowedForProvider(lb)) {
@ -558,7 +565,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
policyList.add(new LbStickinessPolicy(cmd.getStickinessMethodName(), lbpolicy.getParams()));
Ip sourceIp = getSourceIp(loadBalancer);
LoadBalancingRule lbRule = new LoadBalancingRule(loadBalancer, getExistingDestinations(lbpolicy.getId()),
policyList, null, sourceIp);
policyList, null, sourceIp,null, loadBalancer.getLbProtocol());
if (!validateLbRule(lbRule)) {
throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed "
+ cmd.getLbRuleId());
@ -905,7 +912,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
// hashealtChecks
if (hcPolicyList != null && hcPolicyList.size() > 0) {
Ip sourceIp = getSourceIp(lb);
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList, sourceIp);
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList, sourceIp, null, lb.getLbProtocol());
lbrules.add(loadBalancing);
}
}
@ -1087,12 +1094,161 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
return success;
}
@Override
public boolean assignSSLCertToLoadBalancerRule(Long lbId, String certName, String publicCert, String privateKey) {
s_logger.error("Calling the manager for LB");
LoadBalancerVO loadBalancer = _lbDao.findById(lbId);
return false; //TODO
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, eventDescription = "removing from load balancer", async = true)
public boolean removeFromLoadBalancer(long loadBalancerId, List<Long> instanceIds) {
return removeFromLoadBalancerInternal(loadBalancerId, instanceIds, true);
}
@Override
public LbSslCert getLbSslCert(long lbRuleId) {
LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
if ( lbCertMap == null)
return null;
SslCertVO certVO = _entityMgr.findById(SslCertVO.class, lbCertMap.getCertId());
if ( certVO == null) {
s_logger.warn("Cert rule with cert ID " + lbCertMap.getCertId() + " but Cert is not found");
return null;
}
return new LbSslCert(certVO.getCertificate(), certVO.getKey(),
certVO.getChain(), certVO.getPassword(), lbCertMap.isRevoke());
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_LB_CERT_ASSIGN, eventDescription = "assigning certificate to load balancer", async = true)
public boolean assignCertToLoadBalancer(long lbRuleId, Long certId) {
CallContext caller = CallContext.current();
LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(lbRuleId));
if (loadBalancer == null) {
throw new InvalidParameterException("Invalid load balancer id: " + lbRuleId);
}
SslCertVO certVO = _entityMgr.findById(SslCertVO.class,certId);
if (certVO == null) {
throw new InvalidParameterException("Invalid certificate id: " + certId);
}
_accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
// check if LB and Cert belong to the same account
if( loadBalancer.getAccountId() != certVO.getAccountId() ){
throw new InvalidParameterValueException("Access denied for account " + certVO.getAccountId());
}
String capability = getLBCapability(loadBalancer.getNetworkId(), Capability.SslTermination.getName());
if ( capability == null){
throw new InvalidParameterValueException("Ssl termination not supported by the loadbalancer");
}
//check if the lb is already bound
LoadBalancerCertMapVO certMapRule = _lbCertMapDao.findByLbRuleId(loadBalancer.getId());
if (certMapRule != null)
throw new InvalidParameterValueException("Another certificate is already bound to the LB");
//check for correct port
if ( loadBalancer.getLbProtocol() == null || !(loadBalancer.getLbProtocol().equals(NetUtils.SSL_PROTO)))
throw new InvalidParameterValueException("Bad LB protocol: Expected ssl got " + loadBalancer.getLbProtocol());
boolean success = false;
FirewallRule.State backupState = loadBalancer.getState();
try {
loadBalancer.setState(FirewallRule.State.Add);
_lbDao.persist(loadBalancer);
LoadBalancerCertMapVO certMap = new LoadBalancerCertMapVO(lbRuleId,certId,false);
_lbCertMapDao.persist(certMap);
applyLoadBalancerConfig(loadBalancer.getId());
/*s_logger.warn("Failed to apply Ssl Cert to LB " + loadBalancer.getId());
CloudRuntimeException ex = new CloudRuntimeException(
"Failed to apply Ssl Cert to LB " + loadBalancer.getId());
ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
throw ex;*/
success = true;
} catch (ResourceUnavailableException e) {
if (isRollBackAllowedForProvider(loadBalancer)) {
loadBalancer.setState(backupState);
_lbDao.persist(loadBalancer);
LoadBalancerCertMapVO certMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
_lbCertMapDao.remove(certMap.getId());
s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while adding cert");
}
s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
}
return success;
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_LB_CERT_REMOVE, eventDescription = "removing certificate from load balancer", async = true)
public boolean removeCertFromLoadBalancer(long lbRuleId) {
CallContext caller = CallContext.current();
LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
if (loadBalancer == null) {
throw new InvalidParameterException("Invalid load balancer value: " + lbRuleId);
}
if( lbCertMap == null ) {
throw new InvalidParameterException("No certificate is bound to lb with id: " + lbRuleId);
}
_accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
boolean success = false;
FirewallRule.State backupState = loadBalancer.getState();
try {
loadBalancer.setState(FirewallRule.State.Add);
_lbDao.persist(loadBalancer);
lbCertMap.setRevoke(true);
_lbCertMapDao.persist(lbCertMap);
if (!applyLoadBalancerConfig(lbRuleId)) {
s_logger.warn("Failed to remove cert from load balancer rule id " + lbRuleId);
CloudRuntimeException ex = new CloudRuntimeException(
"Failed to remove certificate load balancer rule id " + lbRuleId);
ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
throw ex;
}
success = true;
} catch (ResourceUnavailableException e) {
if (isRollBackAllowedForProvider(loadBalancer)) {
lbCertMap.setRevoke(false);
_lbCertMapDao.persist(lbCertMap);
loadBalancer.setState(backupState);
_lbDao.persist(loadBalancer);
s_logger.debug("Rolled back certificate removal lb id " + lbRuleId);
}
s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
if (!success) {
CloudRuntimeException ex = new CloudRuntimeException(
"Failed to remove certificate from load balancer rule id " + lbRuleId);
ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
throw ex;
}
}
return success;
}
private boolean removeFromLoadBalancerInternal(long loadBalancerId, List<Long> instanceIds, boolean rollBack) {
CallContext caller = CallContext.current();
@ -1317,7 +1473,8 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
@Override
@ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer")
public LoadBalancer createPublicLoadBalancerRule(String xId, String name, String description,
int srcPortStart, int srcPortEnd, int defPortStart, int defPortEnd, Long ipAddrId, String protocol, String algorithm, long networkId, long lbOwnerId, boolean openFirewall)
int srcPortStart, int srcPortEnd, int defPortStart, int defPortEnd, Long ipAddrId, String protocol, String algorithm,
long networkId, long lbOwnerId, boolean openFirewall, String lbProtocol)
throws NetworkRuleConflictException, InsufficientAddressCapacityException {
Account lbOwner = _accountMgr.getAccount(lbOwnerId);
@ -1377,7 +1534,8 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
+ network);
}
result = createPublicLoadBalancer(xId, name, description, srcPortStart, defPortStart, ipVO.getId(), protocol, algorithm, openFirewall, CallContext.current());
result = createPublicLoadBalancer(xId, name, description, srcPortStart, defPortStart, ipVO.getId(), protocol,
algorithm, openFirewall, CallContext.current(), lbProtocol);
} catch (Exception ex) {
s_logger.warn("Failed to create load balancer due to ", ex);
if (ex instanceof NetworkRuleConflictException) {
@ -1407,13 +1565,14 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
@DB
@Override
public LoadBalancer createPublicLoadBalancer(final String xId, final String name, final String description,
final int srcPort, final int destPort, final long sourceIpId, final String protocol, final String algorithm, final boolean openFirewall, final CallContext caller)
final int srcPort, final int destPort, final long sourceIpId, final String protocol,
final String algorithm, final boolean openFirewall, final CallContext caller, final String lbProtocol)
throws NetworkRuleConflictException {
if (!NetUtils.isValidPort(destPort)) {
throw new InvalidParameterValueException("privatePort is an invalid value: " + destPort);
}
if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) {
throw new InvalidParameterValueException("Invalid algorithm: " + algorithm);
}
@ -1454,18 +1613,29 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
_firewallMgr.validateFirewallRule(caller.getCallingAccount(), ipAddr, srcPort, srcPort, protocol,
Purpose.LoadBalancing, FirewallRuleType.User, networkId, null);
LoadBalancerVO newRule = new LoadBalancerVO(xId, name, description,
sourceIpId, srcPort, destPort, algorithm,
networkId, ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId(), lbProtocol);
// verify rule is supported by Lb provider of the network
Ip sourceIp = getSourceIp(newRule);
LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList<LbDestination>(),
new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIp, null, lbProtocol);
if (!validateLbRule(loadBalancing)) {
throw new InvalidParameterValueException("LB service provider cannot support this rule");
}
return Transaction.execute(new TransactionCallbackWithException<LoadBalancerVO,NetworkRuleConflictException>() {
@Override
public LoadBalancerVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
LoadBalancerVO newRule = new LoadBalancerVO(xId, name, description,
sourceIpId, srcPort, destPort, algorithm,
networkId, ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId());
networkId, ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId(), lbProtocol);
// verify rule is supported by Lb provider of the network
Ip sourceIp = getSourceIp(newRule);
LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList<LbDestination>(),
new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIp);
new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIp, null, lbProtocol);
if (!validateLbRule(loadBalancing)) {
throw new InvalidParameterValueException("LB service provider cannot support this rule");
}
@ -1510,7 +1680,6 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
}
@Override
public boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException {
LoadBalancerVO lb = _lbDao.findById(lbRuleId);
List<LoadBalancerVO> lbs;
@ -1576,7 +1745,8 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
List<LbStickinessPolicy> policyList = getStickinessPolicies(lb.getId());
Ip sourceIp = getSourceIp(lb);
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, null, policyList, null, sourceIp);
LbSslCert sslCert = getLbSslCert(lb.getId());
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, null, policyList, null, sourceIp, sslCert, lb.getLbProtocol());
if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(lb.getId())) {
// Get the associated VmGroup
@ -1659,7 +1829,13 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
_lb2healthcheckDao.remove(lb.getId(), true);
s_logger.debug("Load balancer rule id " + lb.getId() + " is removed health check monitors policies");
}
LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lb.getId());
if (lbCertMap != null && lbCertMap.isRevoke()) {
_lbCertMapDao.remove(lbCertMap.getId());
s_logger.debug("Load balancer rule id " + lb.getId() + " removed certificate mapping");
}
return checkForReleaseElasticIp;
}
});

View File

@ -187,6 +187,7 @@ import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.router.VirtualRouter.RedundantState;
import com.cloud.network.router.VirtualRouter.Role;
@ -2544,7 +2545,8 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp);
LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId());
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp, sslCert, lb.getLbProtocol());
lbRules.add(loadBalancing);
}
}
@ -3680,8 +3682,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId());
Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp);
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp,
sslCert, lb.getLbProtocol());
lbRules.add(loadBalancing);
}
return sendLBRules(router, lbRules, network.getId());
@ -3716,8 +3721,9 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId());
Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp);
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp, sslCert, lb.getLbProtocol());
lbRules.add(loadBalancing);
}
return sendLBRules(router, lbRules, network.getId());

View File

@ -287,6 +287,11 @@ import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleI
import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.RemoveFromLoadBalancerRuleCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.ListSslCertsCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.AssignCertToLoadBalancerCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.RemoveCertFromLoadBalancerCmd;
import org.apache.cloudstack.api.command.user.nat.CreateIpForwardingRuleCmd;
import org.apache.cloudstack.api.command.user.nat.DeleteIpForwardingRuleCmd;
import org.apache.cloudstack.api.command.user.nat.DisableStaticNatCmd;
@ -2876,6 +2881,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(UpdateNetworkACLItemCmd.class);
cmdList.add(CleanVMReservationsCmd.class);
cmdList.add(UpgradeRouterTemplateCmd.class);
cmdList.add(UploadSslCertCmd.class);
cmdList.add(DeleteSslCertCmd.class);
cmdList.add(ListSslCertsCmd.class);
cmdList.add(AssignCertToLoadBalancerCmd.class);
cmdList.add(RemoveCertFromLoadBalancerCmd.class);
return cmdList;
}

View File

@ -146,7 +146,7 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A
//4) Validate Load Balancing rule on the providers
LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList<LbDestination>(),
new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIpAddr);
new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIpAddr, null, null);
if (!_lbMgr.validateLbRule(loadBalancing)) {
throw new InvalidParameterValueException("LB service provider cannot support this rule");
}

View File

@ -0,0 +1,477 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.cloudstack.network.lb;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.network.dao.*;
import com.cloud.network.lb.CertService;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.ListSslCertsCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
import org.apache.cloudstack.api.response.SslCertResponse;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.utils.db.DB;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PasswordFinder;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.ejb.Local;
import javax.inject.Inject;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Local(value = {CertService.class})
public class CertServiceImpl implements CertService {
private static final Logger s_logger = Logger.getLogger(CertServiceImpl.class);
@Inject AccountManager _accountMgr;
@Inject AccountDao _accountDao;
@Inject SslCertDao _sslCertDao;
@Inject LoadBalancerCertMapDao _lbCertDao;
@Inject EntityManager _entityMgr;
public CertServiceImpl() {
Security.addProvider(new BouncyCastleProvider());
}
@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_LB_CERT_UPLOAD, eventDescription = "Uploading a certificate to cloudstack", async = false)
public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd) {
try {
String cert = URLDecoder.decode(certCmd.getCert(), "UTF-8");
String key = URLDecoder.decode(certCmd.getKey(), "UTF-8");
String password = certCmd.getPassword();
String chain = certCmd.getChain() == null ? null: URLDecoder.decode(certCmd.getChain(), "UTF-8");
validate(cert, key, password, chain);
s_logger.debug("Certificate Validation succeeded");
String fingerPrint = generateFingerPrint(parseCertificate(cert));
Long accountId = CallContext.current().getCallingAccount().getId();
Long domainId = CallContext.current().getCallingAccount().getDomainId();
SslCertVO certVO = new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint);
_sslCertDao.persist(certVO);
return createCertResponse(certVO, null);
} catch (UnsupportedEncodingException e) {
throw new CloudRuntimeException("Error decoding certificate data");
}
}
@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_LB_CERT_DELETE, eventDescription = "Deleting a certificate to cloudstack", async = false)
public void deleteSslCert(DeleteSslCertCmd deleteSslCertCmd) {
CallContext ctx = CallContext.current();
Account caller = ctx.getCallingAccount();
Long certId = deleteSslCertCmd.getId();
SslCertVO certVO = _sslCertDao.findById(certId);
if (certVO == null) {
throw new InvalidParameterValueException("Invalid certificate id: " + certId);
}
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.ModifyEntry, true, certVO);
List<LoadBalancerCertMapVO> lbCertRule = _lbCertDao.listByCertId(certId);
if ( (lbCertRule != null) && (!lbCertRule.isEmpty()) ){
String lbUuids = "";
for( LoadBalancerCertMapVO rule : lbCertRule ){
LoadBalancerVO lb = _entityMgr.findById(LoadBalancerVO.class, rule.getLbId());
lbUuids += " " + lb.getUuid();
}
throw new CloudRuntimeException("Certificate in use by a loadbalancer(s)" + lbUuids);
}
_sslCertDao.remove(certId);
}
@Override
public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd) {
CallContext ctx = CallContext.current();
Account caller = ctx.getCallingAccount();
Long certId= listSslCertCmd.getCertId();
Long accountId = listSslCertCmd.getAccountId();
Long lbRuleId = listSslCertCmd.getLbId();
List<SslCertResponse> certResponseList = new ArrayList<SslCertResponse>();
if (certId == null && accountId == null && lbRuleId == null ) {
throw new InvalidParameterValueException("Invalid parameters either certificate ID or Account ID or Loadbalancer ID required");
}
List<LoadBalancerCertMapVO> certLbMap = null;
SslCertVO certVO = null;
if(certId != null) {
certVO = _sslCertDao.findById(certId);
if (certVO == null) {
throw new InvalidParameterValueException("Invalid certificate id: " + certId);
}
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.ListEntry, true, certVO);
certLbMap = _lbCertDao.listByCertId(certId);
certResponseList.add(createCertResponse(certVO, certLbMap));
return certResponseList;
}
if ( lbRuleId != null) {
LoadBalancer lb = _entityMgr.findById(LoadBalancerVO.class, lbRuleId);
if ( lb == null ){
throw new InvalidParameterValueException("found no loadbalancer wth id: " + lbRuleId);
}
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.ListEntry, true, lb);
// get the cert id
LoadBalancerCertMapVO lbCertMapRule;
lbCertMapRule = _lbCertDao.findByLbRuleId(lbRuleId);
if (lbCertMapRule == null) {
throw new InvalidParameterValueException("No certificate bound to loadbalancer id: " + lbRuleId);
}
certVO = _sslCertDao.findById(lbCertMapRule.getCertId());
certLbMap = _lbCertDao.listByCertId(lbCertMapRule.getCertId());
certResponseList.add(createCertResponse(certVO, certLbMap));
return certResponseList;
}
//reached here look by accountId
List<SslCertVO> certVOList = _sslCertDao.listByAccountId(accountId);
if ( certVOList == null || certVOList.isEmpty())
return certResponseList;
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.ListEntry, true, certVOList.get(0));
for( SslCertVO cert : certVOList ){
certLbMap = _lbCertDao.listByCertId(cert.getId());
certResponseList.add(createCertResponse(cert, certLbMap));
}
return certResponseList;
}
private void validate(String _cert, String _key, String _password, String _chain) {
Certificate cert;
PrivateKey key;
List<Certificate> chain=null;
try {
cert = parseCertificate(_cert);
key = parsePrivateKey(_key, _password);
if ( _chain != null) {
chain = parseChain(_chain);
}
} catch (IOException e) {
throw new IllegalArgumentException("Parsing certificate/key failed: " + e.getMessage());
}
validateCert(cert, _chain != null? true: false);
validateKeys(cert.getPublicKey(), key);
if ( _chain != null )
validateChain(chain, cert);
}
public SslCertResponse createCertResponse(SslCertVO cert, List<LoadBalancerCertMapVO> lbCertMap) {
SslCertResponse response = new SslCertResponse();
Account account = _accountDao.findByIdIncludingRemoved(cert.getAccountId());
response.setObjectName("sslcert");
response.setId(cert.getUuid());
response.setCertificate(cert.getCertificate());
response.setPrivatekey(cert.getKey());
response.setFingerprint(cert.getFingerPrint());
response.setAccountName(account.getAccountName());
if ( cert.getChain() != null)
response.setCertchain(cert.getChain());
if ( lbCertMap != null && !lbCertMap.isEmpty()){
List<String> lbIds = new ArrayList<String>();
for ( LoadBalancerCertMapVO mapVO : lbCertMap ) {
LoadBalancer lb = _entityMgr.findById(LoadBalancerVO.class, mapVO.getLbId());
lbIds.add(lb.getUuid());
}
response.setLbIds(lbIds);
}
return response;
}
private void validateCert(Certificate cert, boolean chain_present) {
if ( !( cert instanceof X509Certificate))
throw new IllegalArgumentException("Invalid certificate format. Expected X509 certificate");
try {
((X509Certificate)cert).checkValidity();
} catch (Exception e) {
throw new IllegalArgumentException("Certificate expired or not valid");
}
if( !chain_present ) {
PublicKey pubKey = cert.getPublicKey();
try {
cert.verify(pubKey);
} catch (Exception e) {
throw new IllegalArgumentException("No chain given and certificate not self signed");
}
}
}
private void validateKeys(PublicKey pubKey, PrivateKey privKey) {
if (pubKey.getAlgorithm() != privKey.getAlgorithm())
throw new IllegalArgumentException("Public and private key have different algorithms");
// No encryption for DSA
if ( pubKey.getAlgorithm() != "RSA")
return;
try {
String data = "ENCRYPT_DATA";
SecureRandom random = new SecureRandom();
Cipher cipher = Cipher.getInstance(pubKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE,privKey,random);
byte[] encryptedData = cipher.doFinal(data.getBytes());
cipher.init(Cipher.DECRYPT_MODE,pubKey,random);
String decreptedData = new String(cipher.doFinal(encryptedData));
if (!decreptedData.equals(data))
throw new IllegalArgumentException("Bad public-private key");
} catch (BadPaddingException e) {
throw new IllegalArgumentException("Bad public-private key");
} catch (IllegalBlockSizeException e) {
throw new IllegalArgumentException("Bad public-private key");
} catch (NoSuchPaddingException e) {
throw new IllegalArgumentException("Bad public-private key");
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("Invalid public-private key");
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("Invalid algorithm for public-private key");
}
}
private void validateChain(List<Certificate> chain, Certificate cert) {
List<Certificate> certs = new ArrayList<Certificate>();
List<Certificate> root = new ArrayList<Certificate>();
Set<TrustAnchor> anchors = new HashSet<TrustAnchor>();
certs.add(cert); // adding for self signed certs
certs.addAll(chain);
for( Certificate c : certs) {
if ( !( c instanceof X509Certificate))
throw new IllegalArgumentException("Invalid chain format. Expected X509 certificate");
X509Certificate xCert = (X509Certificate)c;
Principal subject = xCert.getSubjectDN();
Principal issuer = xCert.getIssuerDN();
if( issuer != null && subject.equals(issuer) ) {
root.add(c);
anchors.add(new TrustAnchor(xCert,null));
}
}
if ( root.size() == 0 )
throw new IllegalArgumentException("No root certificates found for certificate chain",null);
X509CertSelector target = new X509CertSelector();
target.setCertificate((X509Certificate)cert);
PKIXBuilderParameters params = null;
try {
params = new PKIXBuilderParameters(anchors, target);
params.setRevocationEnabled(false);
params.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certs)));
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
builder.build(params);
} catch (InvalidAlgorithmParameterException e) {
throw new IllegalArgumentException("Invalid certificate chain",null);
} catch (CertPathBuilderException e) {
throw new IllegalArgumentException("Invalid certificate chain",null);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("Invalid certificate chain",null);
}
}
public PrivateKey parsePrivateKey(String key, String password) throws IOException {
PasswordFinder pGet = null;
if( password != null )
pGet = new KeyPassword(password.toCharArray());
PEMReader privateKey = new PEMReader(new StringReader(key), pGet);
Object obj = privateKey.readObject();
try {
if ( obj instanceof KeyPair )
return ((KeyPair)obj).getPrivate();
return (PrivateKey) obj;
}catch (Exception e){
e.printStackTrace();
throw new IOException("Invalid Key format or invalid password.");
}
}
public Certificate parseCertificate(String cert) {
PEMReader certPem = new PEMReader(new StringReader(cert));
try {
return (Certificate) certPem.readObject();
} catch (Exception e) {
throw new InvalidParameterValueException("Invalid Certificate format. Expected X509 certificate");
}
}
public List<Certificate> parseChain(String chain) throws IOException {
List<Certificate> certs = new ArrayList<Certificate>();
PEMReader reader = new PEMReader(new StringReader(chain));
Certificate crt = null;
while ( ( crt = (Certificate) reader.readObject()) != null ) {
if ( crt instanceof X509Certificate) {
certs.add(crt);
}
}
if ( certs.size() == 0 )
throw new IllegalArgumentException("Unable to decode certificate chain",null);
return certs;
}
String generateFingerPrint(Certificate cert) {
final char[] HEX =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
StringBuilder buffer = new StringBuilder(60);
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] data = md.digest(cert.getEncoded());
for ( int i = 0 ; i < data.length ; i++ ) {
if ( buffer.length() > 0 ) {
buffer.append(":");
}
buffer.append(HEX[(0xF0 & data[i]) >>> 4]);
buffer.append(HEX[0x0F & data[i]]);
}
} catch (CertificateEncodingException e) {
throw new InvalidParameterValueException("Bad certificate encoding");
} catch (NoSuchAlgorithmException e) {
throw new InvalidParameterValueException("Bad certificate algorithm");
}
return buffer.toString();
}
public static class KeyPassword implements PasswordFinder {
boolean password_requested=false;
char[] password;
KeyPassword(char[] word){
this.password = word;
}
public char[] getPassword() {
password_requested=true;
return password;
}
public boolean getPasswordRequested(){
return password_requested;
}
}
}

View File

@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.lb;
package org.apache.cloudstack.network.lb;
import java.io.IOException;
import java.lang.reflect.Field;
@ -25,6 +25,7 @@ import javax.inject.Inject;
import junit.framework.TestCase;
import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -335,7 +336,7 @@ public class ApplicationLoadBalancerTest extends TestCase {
public AccountManager accountManager() {
return Mockito.mock(AccountManager.class);
}
@Bean
public LoadBalancingRulesManager loadBalancingRulesManager() {

View File

@ -0,0 +1,791 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.cloudstack.network.lb;
import com.cloud.network.dao.*;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionLegacy;
import junit.framework.TestCase;
import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import static org.apache.commons.io.FileUtils.readFileToString;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.when;
public class CertServiceTest extends TestCase {
private static final Logger s_logger = Logger.getLogger( CertServiceTest.class);
@Override
@Before
public void setUp() {
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
CallContext.register(user, account);
}
@Override
@After
public void tearDown() {
CallContext.unregister();
}
@Test
public void testUploadSslCert() throws Exception {
/* Test1 : Given a Certificate in bad format (Not PEM), upload should fail */
runUploadSslCertBadFormat();
/* Test2: Given a Certificate which is not X509, upload should fail */
runUploadSslCertNotX509();
/* Test3: Given an expired certificate, upload should fail */
runUploadSslCertExpiredCert();
/* Test4: Given a private key which has a different algorithm than the certificate,
upload should fail.
*/
runUploadSslCertBadkeyAlgo();
/* Test5: Given a private key which does not match the public key in the certificate,
upload should fail
*/
runUploadSslCertBadkeyPair();
/* Test6: Given an encrypted private key with a bad password. Upload should fail. */
runUploadSslCertBadPassword();
/* Test7: If no chain is given, the certificate should be self signed. Else, uploadShould Fail */
runUploadSslCertNoChain();
/* Test8: Chain is given but does not have root certificate */
runUploadSslCertNoRootCert();
/* Test9: The chain given is not the correct chain for the certificate */
runUploadSslCertBadChain();
/* Test10: Given a Self-signed Certificate with encrypted key, upload should succeed */
runUploadSslCertSelfSignedNoPassword();
/* Test11: Given a Self-signed Certificate with non-encrypted key, upload should succeed */
runUploadSslCertSelfSignedWithPassword();
/* Test12: Given a certificate signed by a CA and a valid CA chain, upload should succeed */
runUploadSslCertWithCAChain();
}
private void runUploadSslCertWithCAChain() throws Exception {
//To change body of created methods use File | Settings | File Templates.
TransactionLegacy txn = TransactionLegacy.open("runUploadSslCertWithCAChain");
String certFile = getClass().getResource("/certs/rsa_ca_signed.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_ca_signed.key").getFile();
String chainFile = getClass().getResource("/certs/root_chain.crt").getFile();
String password = "user";
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
String chain = URLEncoder.encode(readFileToString(new File(chainFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
certService._accountDao = Mockito.mock(AccountDao.class);
when(certService._accountDao.findByIdIncludingRemoved(anyLong())).thenReturn((AccountVO)account);
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field passField = _class.getDeclaredField("password");
passField.setAccessible(true);
passField.set(uploadCmd, password);
Field chainField = _class.getDeclaredField("chain");
chainField.setAccessible(true);
chainField.set(uploadCmd, chain);
certService.uploadSslCert(uploadCmd);
}
private void runUploadSslCertSelfSignedWithPassword() throws Exception {
TransactionLegacy txn = TransactionLegacy.open("runUploadSslCertSelfSignedWithPassword");
String certFile = getClass().getResource("/certs/rsa_self_signed_with_pwd.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_self_signed_with_pwd.key").getFile();
String password = "test";
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
certService._accountDao = Mockito.mock(AccountDao.class);
when(certService._accountDao.findByIdIncludingRemoved(anyLong())).thenReturn((AccountVO)account);
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field passField = _class.getDeclaredField("password");
passField.setAccessible(true);
passField.set(uploadCmd, password);
certService.uploadSslCert(uploadCmd);
}
private void runUploadSslCertSelfSignedNoPassword() throws Exception {
TransactionLegacy txn = TransactionLegacy.open("runUploadSslCertSelfSignedNoPassword");
String certFile = getClass().getResource("/certs/rsa_self_signed.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_self_signed.key").getFile();
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
certService._accountDao = Mockito.mock(AccountDao.class);
when(certService._accountDao.findByIdIncludingRemoved(anyLong())).thenReturn((AccountVO)account);
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
certService.uploadSslCert(uploadCmd);
}
private void runUploadSslCertBadChain() throws IOException, IllegalAccessException, NoSuchFieldException {
//To change body of created methods use File | Settings | File Templates.
String certFile = getClass().getResource("/certs/rsa_ca_signed.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_ca_signed.key").getFile();
String chainFile = getClass().getResource("/certs/rsa_self_signed.crt").getFile();
String password = "user";
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
String chain = URLEncoder.encode(readFileToString(new File(chainFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field passField = _class.getDeclaredField("password");
passField.setAccessible(true);
passField.set(uploadCmd, password);
Field chainField = _class.getDeclaredField("chain");
chainField.setAccessible(true);
chainField.set(uploadCmd, chain);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("Invalid certificate chain"));
}
}
private void runUploadSslCertNoRootCert() throws IOException, IllegalAccessException, NoSuchFieldException {
//To change body of created methods use File | Settings | File Templates.
String certFile = getClass().getResource("/certs/rsa_ca_signed.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_ca_signed.key").getFile();
String chainFile = getClass().getResource("/certs/rsa_ca_signed2.crt").getFile();
String password = "user";
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
String chain = URLEncoder.encode(readFileToString(new File(chainFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field passField = _class.getDeclaredField("password");
passField.setAccessible(true);
passField.set(uploadCmd, password);
Field chainField = _class.getDeclaredField("chain");
chainField.setAccessible(true);
chainField.set(uploadCmd, chain);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("No root certificates found"));
}
}
private void runUploadSslCertNoChain() throws IOException, IllegalAccessException, NoSuchFieldException {
String certFile = getClass().getResource("/certs/rsa_ca_signed.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_ca_signed.key").getFile();
String password = "user";
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field passField = _class.getDeclaredField("password");
passField.setAccessible(true);
passField.set(uploadCmd, password);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("No chain given and certificate not self signed"));
}
}
private void runUploadSslCertBadPassword() throws IOException, IllegalAccessException, NoSuchFieldException {
String certFile = getClass().getResource("/certs/rsa_self_signed_with_pwd.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_self_signed_with_pwd.key").getFile();
String password = "bad_password";
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field passField = _class.getDeclaredField("password");
passField.setAccessible(true);
passField.set(uploadCmd, password);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("please check password and data"));
}
}
private void runUploadSslCertBadkeyPair() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = getClass().getResource("/certs/rsa_self_signed.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_random_pkey.key").getFile();
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("Bad public-private key"));
}
}
private void runUploadSslCertBadkeyAlgo() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = getClass().getResource("/certs/rsa_self_signed.crt").getFile();
String keyFile = getClass().getResource("/certs/dsa_self_signed.key").getFile();
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("Public and private key have different algorithms"));
}
}
private void runUploadSslCertExpiredCert() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = getClass().getResource("/certs/expired_cert.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_self_signed.key").getFile();
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("Certificate expired"));
}
}
private void runUploadSslCertNotX509() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = getClass().getResource("/certs/non_x509_pem.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_self_signed.key").getFile();
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("Expected X509 certificate"));
}
}
private void runUploadSslCertBadFormat() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = getClass().getResource("/certs/bad_format_cert.crt").getFile();
String keyFile = getClass().getResource("/certs/rsa_self_signed.key").getFile();
String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8");
String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
assertTrue(e.getMessage().contains("Invalid certificate format"));
}
}
@Test
public void testDeleteSslCert() throws Exception {
/* Test1: Delete with an invalid ID should fail */
runDeleteSslCertInvalidId();
/* Test2: Delete with a cert id bound to a lb should fail */
runDeleteSslCertBoundCert();
/* Test3: Delete with a valid Id should succeed */
runDeleteSslCertValid();
}
private void runDeleteSslCertValid() throws Exception {
TransactionLegacy txn = TransactionLegacy.open("runDeleteSslCertValid");
CertServiceImpl certService = new CertServiceImpl();
long certId = 1;
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.remove(anyLong())).thenReturn(true);
when(certService._sslCertDao.findById(anyLong())).thenReturn(new SslCertVO());
// a rule holding the cert
certService._lbCertDao = Mockito.mock(LoadBalancerCertMapDao.class);
when(certService._lbCertDao.listByCertId(anyLong())).thenReturn(null);
//creating the command
DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
Class<?> _class = deleteCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("id");
certField.setAccessible(true);
certField.set(deleteCmd, certId);
certService.deleteSslCert(deleteCmd);
}
private void runDeleteSslCertBoundCert() throws NoSuchFieldException, IllegalAccessException {
TransactionLegacy txn = TransactionLegacy.open("runDeleteSslCertBoundCert");
CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
long certId = 1;
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.remove(anyLong())).thenReturn(true);
when(certService._sslCertDao.findById(anyLong())).thenReturn(new SslCertVO());
// rule holding the cert
certService._lbCertDao = Mockito.mock(LoadBalancerCertMapDao.class);
List<LoadBalancerCertMapVO> lbMapList = new ArrayList<LoadBalancerCertMapVO>();
lbMapList.add(new LoadBalancerCertMapVO());
certService._lbCertDao = Mockito.mock(LoadBalancerCertMapDao.class);
when(certService._lbCertDao.listByCertId(anyLong())).thenReturn(lbMapList);
certService._entityMgr = Mockito.mock(EntityManager.class);
when(certService._entityMgr.findById(eq(LoadBalancerVO.class), anyLong())).thenReturn(new LoadBalancerVO());
//creating the command
DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
Class<?> _class = deleteCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("id");
certField.setAccessible(true);
certField.set(deleteCmd, certId);
try {
certService.deleteSslCert(deleteCmd);
}catch (Exception e){
assertTrue(e.getMessage().contains("Certificate in use by a loadbalancer"));
}
}
private void runDeleteSslCertInvalidId() throws NoSuchFieldException, IllegalAccessException {
TransactionLegacy txn = TransactionLegacy.open("runDeleteSslCertInvalidId");
long certId = 1;
CertServiceImpl certService = new CertServiceImpl();
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1,
"networkdomain", (short) 0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.remove(anyLong())).thenReturn(true);
when(certService._sslCertDao.findById(anyLong())).thenReturn(null);
// no rule holding the cert
certService._lbCertDao = Mockito.mock(LoadBalancerCertMapDao.class);
when(certService._lbCertDao.listByCertId(anyLong())).thenReturn(null);
//creating the command
DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
Class<?> _class = deleteCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("id");
certField.setAccessible(true);
certField.set(deleteCmd, certId);
try {
certService.deleteSslCert(deleteCmd);
}catch (Exception e){
assertTrue(e.getMessage().contains("Invalid certificate id"));
}
}
public class UploadSslCertCmdExtn extends UploadSslCertCmd {
@Override
public long getEntityOwnerId() {
return 1;
}
}
public class DeleteSslCertCmdExtn extends DeleteSslCertCmd {
@Override
public long getEntityOwnerId() {
return 1;
}
}
}

View File

@ -0,0 +1 @@
BAD FORMAT CERT

View File

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEaDCCBBACCQDB6QTHSA74AzAJBgcqhkjOOAQDMEUxCzAJBgNVBAYTAkFVMRMw
EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0
eSBMdGQwHhcNMTMxMDIxMTUxMzE1WhcNMTQxMDIxMTUxMzE1WjBFMQswCQYDVQQG
EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk
Z2l0cyBQdHkgTHRkMIIDSDCCAjoGByqGSM44BAEwggItAoIBAQD1cLkWeTvzloom
uaHmB0ANyrmHTum6bVVMyN2V/it8BAErugqQBIaNtF2EOmJ3baxsxIROOqJ5uVx0
pymYVr4BcS3R6H2G7lSWHa5iA/UMfVp9yHroK+WYdN5ZVKGYcUTvKZXtyr2OX3Rc
KJJ2yp4qbcQTB2GlV6eZdpX3l38G/03n/Wi5yjU2/p56R80FAaLtCr4wJoS2aXxU
Iytps+msEn0LRZuFHpW1sLIKPLRCnjFXWeWKdJu6bggUVB0GjfsZR67XzFY5nRvX
7/vW2XS5Vo4X6gSOym0O/8/vzUp1gQSwHiMQQRAoRYoZPxWo8ACMsqdj0MTbN32y
b11//OlXAiEAoR8xDStCDTaQ2Ale9swNzLB8vWFzmSLQXXOM1PY10fMCggEBAO1p
RV1kluxjYCKec12MKdTBqO2QZnOOVFsY2vpIavgqpxyGaHRwY8Cm7BGosV2chMZw
G6xMz5CRnR55KasaX1Vz2xAz7PwczXWDQA59Il5tQbQdewitm1S3NRb1n9u+cNkQ
E6ZekjdW9tRykvaNQHH8EBzgQ9KXCYzJ8nFLk2DMt2Mor/paXfobNzO/vi2UgL+B
5/E8BXoMtBFPhiz72CsCiXp/usROe/UAejow/CTHYC2mfcPhKt2jIVelXx7Baf0n
K1SWKBpNI4ucBj+/4L3Be0ldqDGmeTRUNTNpJIzmAyplUvnpOiqCbzKst57+l4ZE
xdVgv2LiIrTaqTn1L4sDggEGAAKCAQEAv0hyFYj8IMEaOCk9+6wb32NGEGoEz4re
YW1O02Kij2/0YJk0CPyg0ozIpJq9FiHvOzE+2/Eg5jLVTLlAJbjnGjSnzZJ6pJHw
zhwnJ9wT4to51jLvG1v82iL2FfFKOZFjABxC+kND9cAUXu3URIGfdYJl1rBxvOD1
WZ03Gk90GMCLUIMqqUYBQg7XRNVf0k1AgiRgDWpdLkKOGiDntAj/unXdFrbse2xD
IbqBGhCNtPVx34CZ3bUWrvYBoj+BUinfItRK4rkZTEGJinoxbKDvdqoewgk2nSty
7CH40wFS4ni4DCvYTEwUoUuciQaU4XUOOSYFS9IjNWOR8uGBtORteTAJBgcqhkjO
OAQDA0cAMEQCIHqfrNbyMadxZ3uCPr8QPj+17XZZod8B7F8VgZW3R5vSAiAV/WMF
vQ1Dwpr4wJOjNELDe5AEH9WGvevfuc54vmdAdg==
-----END CERTIFICATE-----

View File

@ -0,0 +1,20 @@
-----BEGIN DSA PRIVATE KEY-----
MIIDVwIBAAKCAQEA9XC5Fnk785aKJrmh5gdADcq5h07pum1VTMjdlf4rfAQBK7oK
kASGjbRdhDpid22sbMSETjqieblcdKcpmFa+AXEt0eh9hu5Ulh2uYgP1DH1afch6
6CvlmHTeWVShmHFE7ymV7cq9jl90XCiSdsqeKm3EEwdhpVenmXaV95d/Bv9N5/1o
uco1Nv6eekfNBQGi7Qq+MCaEtml8VCMrabPprBJ9C0WbhR6VtbCyCjy0Qp4xV1nl
inSbum4IFFQdBo37GUeu18xWOZ0b1+/71tl0uVaOF+oEjsptDv/P781KdYEEsB4j
EEEQKEWKGT8VqPAAjLKnY9DE2zd9sm9df/zpVwIhAKEfMQ0rQg02kNgJXvbMDcyw
fL1hc5ki0F1zjNT2NdHzAoIBAQDtaUVdZJbsY2AinnNdjCnUwajtkGZzjlRbGNr6
SGr4Kqcchmh0cGPApuwRqLFdnITGcBusTM+QkZ0eeSmrGl9Vc9sQM+z8HM11g0AO
fSJebUG0HXsIrZtUtzUW9Z/bvnDZEBOmXpI3VvbUcpL2jUBx/BAc4EPSlwmMyfJx
S5NgzLdjKK/6Wl36Gzczv74tlIC/gefxPAV6DLQRT4Ys+9grAol6f7rETnv1AHo6
MPwkx2Atpn3D4SrdoyFXpV8ewWn9JytUligaTSOLnAY/v+C9wXtJXagxpnk0VDUz
aSSM5gMqZVL56Toqgm8yrLee/peGRMXVYL9i4iK02qk59S+LAoIBAQC/SHIViPwg
wRo4KT37rBvfY0YQagTPit5hbU7TYqKPb/RgmTQI/KDSjMikmr0WIe87MT7b8SDm
MtVMuUAluOcaNKfNknqkkfDOHCcn3BPi2jnWMu8bW/zaIvYV8Uo5kWMAHEL6Q0P1
wBRe7dREgZ91gmXWsHG84PVZnTcaT3QYwItQgyqpRgFCDtdE1V/STUCCJGANal0u
Qo4aIOe0CP+6dd0Wtux7bEMhuoEaEI209XHfgJndtRau9gGiP4FSKd8i1EriuRlM
QYmKejFsoO92qh7CCTadK3LsIfjTAVLieLgMK9hMTBShS5yJBpThdQ45JgVL0iM1
Y5Hy4YG05G15AiBO/b8wvyKsJJAInNbsLH7OPitH3qKsI18IxykJSl9lTw==
-----END DSA PRIVATE KEY-----

View File

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIJAJRInPvOqxbXMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNV
BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
Q29tcGFueSBMdGQwHhcNMTMxMDIxMjAwNjA5WhcNMTMxMDIwMjAwNjA5WjBCMQsw
CQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZh
dWx0IENvbXBhbnkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
3rASFvBmAF+CHn58TU5ib0HuMD4gxutohjzQjJXYRFs1cmiLb9esO0Cvk0DFaQuq
lpxw4Dhe6kxRbNQKkPFr0zsv9B8I/o8UQmclnZ0I++ixlAq4VyP6H0sewrmdVbrV
mSH0eG1t0hLqXUmxX/XX1kkbHOgZQQk90Sew23VwTVxbywq8yjkYLa2hlBXh33rX
siky7JFiF0TJE2r6wNB60BQMdi2EErtBUPL/1LD7+VuB/Y6xZpwivKwMIXeFdzSr
I2gGCn+zf01kNfHj0YrA2bH0i5FX4/9YSpd8PFIOYc/gA+3MNO0xMWchbz6AfjPQ
aR4tGLsRBjjwvLIZwHzyWQIDAQABo1AwTjAdBgNVHQ4EFgQUo/kIdWN+yxvnWUoK
/ZJYNl2wY9cwHwYDVR0jBBgwFoAUo/kIdWN+yxvnWUoK/ZJYNl2wY9cwDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAJ/LwjkhXQFOcfUmAoIeBIDAMayy7
HEJusMOA+uUPPuEemgU7DTbwABCaavfBza7QvG171LsTGtvgnvwDg7rdScUOcoX8
w0XZbhr+dZzvashVmMz4oY6hGw29eGo7M01Rm4msX7bW1IXmdWmDcqcNT6/dKOgj
tjMR2JvN9I4qwZ41xXAeUHDUqKjgsKlhflBbOX7K07tbpHFMQZcoOs19Jqve8Gfm
MbH0hZw3LC2YNed8ne/3/lXKNZIhbyZp1IJ/rjgruEZ0ObOwqB1IGR0UjQbAw102
1D4L8FOzmDi4LfhKPgGc/BMeuPRozxQi60TzrnXN5eQSb0ukFvScMhAIrQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICtzCCAZ8CAQAwcjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDENMAsGA1UEAwwEU3ll
ZDEcMBoGCSqGSIb3DQEJARYNc3llZEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAKmQeRXpkeGRhzdj3aJiWUcZtKdcjPCdtphx8gHk1GV1
vHK2zYenwe23EbSsfkOAQx2p86jCpghN7b+ECilmou4C7ASPS2U8n+GhWdl4eUK4
Gmz7+daRqcDQOCTCJWSybtShYzvfp2SaEt/TcUgDT+k6xRitqcIkAY7boGY1Cehy
O6hYdlFkg0oU1XCA0usIaSEi7gOTijpGe2jSh7CTBRRWiClQnqE8VT7x4hXQEDF6
u26K/ptAL90bgyFUuX2dEH5dKd/5QAyAfdrLV6a3wIvikCUGZy23Twtxot4kFVYf
S2x3H9BS6j/mIvrUj95CLi2Eu6t4z5uHMOrf8k0NjN8CAwEAAaAAMA0GCSqGSIb3
DQEBBQUAA4IBAQBa5B6xzAkx3OtJEgOkTJ0nID2TsTt6eQBrp+//jhT/9yKLHmd5
SeNcLzMWDlTQ+zNlLf9+lreO+CmlolaOKDRXh9eXbyNq0/I2QxOEsIlXqH4dVoCB
6UkV8eA0lFeNdFJaCla5/QTKmv4f0eUakbI5Scd1PlBr+YOplvI9fpLaxHGmVzCX
s3WQ7m7SN5hZav7dO8krheZL7N3AYZoCY0QbQ3JTeoakLenmFXqvsckP6in5NQJh
ECaJprYxrxR+5GPjpUkxu7YGLloXHvnnINeZGJG0TB7kPDO+axDxloiI2eYlT/mp
HxdgL9BvDYNfI+0NcZYHguz8GWuWiTZC7F26
-----END CERTIFICATE REQUEST-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDnTCCAoWgAwIBAgIJALXV1B5/vewgMA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNV
BAYTAkFVMQ0wCwYDVQQIDARTb21lMQwwCgYDVQQKDANPcmcxDDAKBgNVBAsMA0Rl
djENMAsGA1UEAwwETmFtZTEcMBoGCSqGSIb3DQEJARYNdGVzdEBtYWlsLmNvbTAe
Fw0xMzEwMjExNjAxMDdaFw0xNjEwMjAxNjAxMDdaMGUxCzAJBgNVBAYTAkFVMQ0w
CwYDVQQIDARTb21lMQwwCgYDVQQKDANPcmcxDDAKBgNVBAsMA0RldjENMAsGA1UE
AwwETmFtZTEcMBoGCSqGSIb3DQEJARYNdGVzdEBtYWlsLmNvbTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBALQZLQa2R64GRCuoh59VFvKoXnAM+4H4sW9E
jiURT/CeH6rbD0IbEMZZ3o84VfQw1zDsVXN/GXq3IEMp8uBBpWJuZRBF1UeDMYlB
bouMqUGL05Ov51zK2aQK/83S8MoQI7KV1FGJNti4iwUzemG1fClrBqjCFJQKmv8y
0z1UaeniAR7ygedIB4I2Y4a/DxtI0e2EsS0TcViwKHGrLArO0GfvNbH+tXqTaotF
X5eyinUFqQxT3JvnlIIernk0ly8c07mqOFbFqHrhFXxddD4pZrUetHXM2MKLdCMu
fvXsmMXSAgQ5F97GWmiDEJ9zMDxGoSmhTIN96FwPCRDr7e22lEsCAwEAAaNQME4w
HQYDVR0OBBYEFIxSziB7ssNqFvhV2MSf1GYvGHQYMB8GA1UdIwQYMBaAFIxSziB7
ssNqFvhV2MSf1GYvGHQYMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
AB1rcxZL6xGuk8PSoBQ0imREcVf9BcEvGIC6uubPSXuoJ/gr584vo3pRJpTpHQyK
xUUwG6gCaDgAMYX177GBamGCt056ThSLKFROIPVrigZ5yY1NWznNq3zjWS4jIHkV
vGd+Gx8t3qYBhsn+v6Y6gRTjMOVQum+rvxvixG7n97DaxBnrwNWXbzZQ9spHrQsT
dsSF/kf9NKkWM0zKh+f/FSNmveJKKvZ+WQZC/MKUfc5VHjyLldXhrffcxzek/dOc
8YADSICSizvXCP/QjyVVl8dpKr/3c00r16Ei3QQaFhHES0bv/sKLnTwQwKDfJthu
bQj7M/XGWi33JQgoMHktYhI=
-----END CERTIFICATE-----

View File

@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID1TCCAr2gAwIBAgIJALXV1B5/vewhMA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNV
BAYTAkFVMQ0wCwYDVQQIDARTb21lMQwwCgYDVQQKDANPcmcxDDAKBgNVBAsMA0Rl
djENMAsGA1UEAwwETmFtZTEcMBoGCSqGSIb3DQEJARYNdGVzdEBtYWlsLmNvbTAe
Fw0xMzEwMjExNjE4MjJaFw0xNDEwMjExNjE4MjJaMHIxCzAJBgNVBAYTAkFVMRMw
EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0
eSBMdGQxDTALBgNVBAMMBFN5ZWQxHDAaBgkqhkiG9w0BCQEWDXN5ZWRAdGVzdC5j
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpkHkV6ZHhkYc3Y92i
YllHGbSnXIzwnbaYcfIB5NRldbxyts2Hp8HttxG0rH5DgEMdqfOowqYITe2/hAop
ZqLuAuwEj0tlPJ/hoVnZeHlCuBps+/nWkanA0DgkwiVksm7UoWM736dkmhLf03FI
A0/pOsUYranCJAGO26BmNQnocjuoWHZRZINKFNVwgNLrCGkhIu4Dk4o6Rnto0oew
kwUUVogpUJ6hPFU+8eIV0BAxertuiv6bQC/dG4MhVLl9nRB+XSnf+UAMgH3ay1em
t8CL4pAlBmctt08LcaLeJBVWH0tsdx/QUuo/5iL61I/eQi4thLureM+bhzDq3/JN
DYzfAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wg
R2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBR2LIRfVveDgQB3dC7TOYhX
BEv71DAfBgNVHSMEGDAWgBSMUs4ge7LDahb4VdjEn9RmLxh0GDANBgkqhkiG9w0B
AQUFAAOCAQEAPjN/sdLcPfMh5ep29vp/7JTh6dUYnBNATYaXxx8j2XdnMCKeRfgP
WOJur8HDPSayWWKKlztiQbJV5jDS5vyuMWI1a5/KIAQlOJep+anpR1QnQaX4/M4Z
YUJo1fPs6tg47dXRpZZaJ+Hqwh0ZftCQoUq/sBxawXf6sbxsjoUmzxQLBqzYo1LJ
jwxBs6C9aM8LDHFz4TVlyclSFQXiLMosj1jLBQ+TqzCxS6qOfJeMM9STXI9W3F2k
duXeceqOwEkh8aeSUIztYFpX34d4SA4DDX5GUEaOeOR/abnXjH52vE6tM/m7NOve
5+I/BrlT3heRqiD6Z2ofSsFhG86YeF9Q3w==
-----END CERTIFICATE-----

View File

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIN4x8YHLIb60CAggA
MBQGCCqGSIb3DQMHBAiuWe+C2SitUgSCBMhVxMKivNaQh9SQedh2GQ8vlhI2/mKf
r6zVUgODOdmFRj/PAlQu6B+VH8u2Ef5tr74O9UyZUQpC6oI0npvQOGqnhIxECR8D
zepFlC0s+6kNRqfzXiMhGTsfbs3xUE1TZK1z5556OS4GlihIB0E5F7GdlulHELeA
dnEItqDffWPQczTmSmFqtH7G/ksGQhSA2reBIDNgxWreBh9x9h2TftEvhhogdkr2
XQpzxcby2v2z6Hut1lfVkLQNdvdHYdDG751NQltOmGvncXkTNJ+tSByXuY9ITtYz
XqwY/vAEX+YYjCrWcvMmhU1t6B9cZ3viFzIIIltqtvDo3rybicpM3xvmnYnTF35j
sGebcynzZedrLUHwD6/o0jBzFJN26QBxDGrlmn9E8HBhmjMCeSyZTXtSkwN0dAhu
EHT2NgdC/4G4+JHsb3Oetl6AbUyYs2eWTRgr6bgBezbiDqKMj1QtGECkPQE9tFFP
Jtma6lGJ1/u8zLFYNjigKZgXaNbtlMpslk+KDTGaTSbbVEaaxWSc0YlHz329ovQC
1btrTE71FoNjRsTRaDRXC7BfrrMtnLhG2SmROKzyBtoxFymfEmASpdGERO+c2712
Z0NLpHJL5ocsRr/onVi0auFC/nuaq6QqYF5OPtZhYh3+IDd193LP3xo8hnFjTq90
9zV1QI2uHfTfijI4OABYSSZLxrl2IFF7Z/e4XkWSXrneR2Ne5GoYX7w6wshiuubQ
bDPUHODsy7uQJ3ZEmmmd5xWvA3h3F5Yyls3WEuz8+jYR4iPKdjt8DJuz9j+7IP3C
LoRa3KhxIPAzziQw+tMFVCozLLfS1kN8mg5SwU9Dp4HUPY/n3KnjVSjUJ347KAgW
+ykPlz4S1H0A2GyGWhdyX3J839UOdXfCsfKQQ1FLOBvhQgBNGzoRIgDrsZdrxgWa
XtF+Ct2/2/O+503I6X90maXzhshmGw/NKsiNx7YOdUiu6w3N4LajIWE689UUU7Dr
EtM8HcfmBnE/cZTbeWbQBfl1GqigMp+YOAY2sw0rZdF4ocmnqoCWLVN2j8O/re5g
20y5eHkztPOZ+NNczo5PP96ng1XEMVzs/h6xDHzsak6osZb5b+Hs9kcYuqBEqr16
3DVwaZ45dGwNN90Q9YmrgEdCqtCAU12w/YYVB/aB701Ijg0NhVsh7PgWaJIOJD56
YTaiWIzQaZ/uM0KlgLz2eI9VXcuv24gUMAUMaI84mInnIrax1zFMrlCjEcR8Zxvk
jCCY6Uq9WH30cUo7cMHWLWMzsl7PC7xpYSHPClqzCUluUgQwqoOs5Ux4nYl+JI7C
ZfJ8BUMCD2RJtjvJhkE6LEkcrCjwnvappRaXbN54IVXpuMl2XYtp44T117QulEj1
I/jk1mrpkXRKi9ZsKsjDH9VMy1hcKHn4CgTxmtRYN6LPA4tamxzVLxIi6YDU0142
l1u763cT7cH14lvzUvEQMFbk/s0AUl8zeZAwjDayNlD/ljz7nZnJ3NToMlxeoK0a
F6c/RgQBwxR8NMdo19Irv8stxo9WGB2/0Q8WCxW7ENHlBpvX5zXKRJMswFKp0ft6
dT7hOBPgJlD7C1eX5jVcSz6kDRM6gQ7K/c5QcJa6qNAC2Jw6yBBYltqiRalFWX46
VcM=
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID1TCCAr2gAwIBAgIJALXV1B5/vewhMA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNV
BAYTAkFVMQ0wCwYDVQQIDARTb21lMQwwCgYDVQQKDANPcmcxDDAKBgNVBAsMA0Rl
djENMAsGA1UEAwwETmFtZTEcMBoGCSqGSIb3DQEJARYNdGVzdEBtYWlsLmNvbTAe
Fw0xMzEwMjExNjE4MjJaFw0xNDEwMjExNjE4MjJaMHIxCzAJBgNVBAYTAkFVMRMw
EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0
eSBMdGQxDTALBgNVBAMMBFN5ZWQxHDAaBgkqhkiG9w0BCQEWDXN5ZWRAdGVzdC5j
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpkHkV6ZHhkYc3Y92i
YllHGbSnXIzwnbaYcfIB5NRldbxyts2Hp8HttxG0rH5DgEMdqfOowqYITe2/hAop
ZqLuAuwEj0tlPJ/hoVnZeHlCuBps+/nWkanA0DgkwiVksm7UoWM736dkmhLf03FI
A0/pOsUYranCJAGO26BmNQnocjuoWHZRZINKFNVwgNLrCGkhIu4Dk4o6Rnto0oew
kwUUVogpUJ6hPFU+8eIV0BAxertuiv6bQC/dG4MhVLl9nRB+XSnf+UAMgH3ay1em
t8CL4pAlBmctt08LcaLeJBVWH0tsdx/QUuo/5iL61I/eQi4thLureM+bhzDq3/JN
DYzfAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wg
R2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBR2LIRfVveDgQB3dC7TOYhX
BEv71DAfBgNVHSMEGDAWgBSMUs4ge7LDahb4VdjEn9RmLxh0GDANBgkqhkiG9w0B
AQUFAAOCAQEAPjN/sdLcPfMh5ep29vp/7JTh6dUYnBNATYaXxx8j2XdnMCKeRfgP
WOJur8HDPSayWWKKlztiQbJV5jDS5vyuMWI1a5/KIAQlOJep+anpR1QnQaX4/M4Z
YUJo1fPs6tg47dXRpZZaJ+Hqwh0ZftCQoUq/sBxawXf6sbxsjoUmzxQLBqzYo1LJ
jwxBs6C9aM8LDHFz4TVlyclSFQXiLMosj1jLBQ+TqzCxS6qOfJeMM9STXI9W3F2k
duXeceqOwEkh8aeSUIztYFpX34d4SA4DDX5GUEaOeOR/abnXjH52vE6tM/m7NOve
5+I/BrlT3heRqiD6Z2ofSsFhG86YeF9Q3w==
-----END CERTIFICATE-----

View File

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIN4x8YHLIb60CAggA
MBQGCCqGSIb3DQMHBAiuWe+C2SitUgSCBMhVxMKivNaQh9SQedh2GQ8vlhI2/mKf
r6zVUgODOdmFRj/PAlQu6B+VH8u2Ef5tr74O9UyZUQpC6oI0npvQOGqnhIxECR8D
zepFlC0s+6kNRqfzXiMhGTsfbs3xUE1TZK1z5556OS4GlihIB0E5F7GdlulHELeA
dnEItqDffWPQczTmSmFqtH7G/ksGQhSA2reBIDNgxWreBh9x9h2TftEvhhogdkr2
XQpzxcby2v2z6Hut1lfVkLQNdvdHYdDG751NQltOmGvncXkTNJ+tSByXuY9ITtYz
XqwY/vAEX+YYjCrWcvMmhU1t6B9cZ3viFzIIIltqtvDo3rybicpM3xvmnYnTF35j
sGebcynzZedrLUHwD6/o0jBzFJN26QBxDGrlmn9E8HBhmjMCeSyZTXtSkwN0dAhu
EHT2NgdC/4G4+JHsb3Oetl6AbUyYs2eWTRgr6bgBezbiDqKMj1QtGECkPQE9tFFP
Jtma6lGJ1/u8zLFYNjigKZgXaNbtlMpslk+KDTGaTSbbVEaaxWSc0YlHz329ovQC
1btrTE71FoNjRsTRaDRXC7BfrrMtnLhG2SmROKzyBtoxFymfEmASpdGERO+c2712
Z0NLpHJL5ocsRr/onVi0auFC/nuaq6QqYF5OPtZhYh3+IDd193LP3xo8hnFjTq90
9zV1QI2uHfTfijI4OABYSSZLxrl2IFF7Z/e4XkWSXrneR2Ne5GoYX7w6wshiuubQ
bDPUHODsy7uQJ3ZEmmmd5xWvA3h3F5Yyls3WEuz8+jYR4iPKdjt8DJuz9j+7IP3C
LoRa3KhxIPAzziQw+tMFVCozLLfS1kN8mg5SwU9Dp4HUPY/n3KnjVSjUJ347KAgW
+ykPlz4S1H0A2GyGWhdyX3J839UOdXfCsfKQQ1FLOBvhQgBNGzoRIgDrsZdrxgWa
XtF+Ct2/2/O+503I6X90maXzhshmGw/NKsiNx7YOdUiu6w3N4LajIWE689UUU7Dr
EtM8HcfmBnE/cZTbeWbQBfl1GqigMp+YOAY2sw0rZdF4ocmnqoCWLVN2j8O/re5g
20y5eHkztPOZ+NNczo5PP96ng1XEMVzs/h6xDHzsak6osZb5b+Hs9kcYuqBEqr16
3DVwaZ45dGwNN90Q9YmrgEdCqtCAU12w/YYVB/aB701Ijg0NhVsh7PgWaJIOJD56
YTaiWIzQaZ/uM0KlgLz2eI9VXcuv24gUMAUMaI84mInnIrax1zFMrlCjEcR8Zxvk
jCCY6Uq9WH30cUo7cMHWLWMzsl7PC7xpYSHPClqzCUluUgQwqoOs5Ux4nYl+JI7C
ZfJ8BUMCD2RJtjvJhkE6LEkcrCjwnvappRaXbN54IVXpuMl2XYtp44T117QulEj1
I/jk1mrpkXRKi9ZsKsjDH9VMy1hcKHn4CgTxmtRYN6LPA4tamxzVLxIi6YDU0142
l1u763cT7cH14lvzUvEQMFbk/s0AUl8zeZAwjDayNlD/ljz7nZnJ3NToMlxeoK0a
F6c/RgQBwxR8NMdo19Irv8stxo9WGB2/0Q8WCxW7ENHlBpvX5zXKRJMswFKp0ft6
dT7hOBPgJlD7C1eX5jVcSz6kDRM6gQ7K/c5QcJa6qNAC2Jw6yBBYltqiRalFWX46
VcM=
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQD2ZYOSvqPjro7k
JKWggB0FJL45mz3pfvBR0NcHTGgHKdh5hml1GiHHPanYnWqRuKFI7UPWLq3xllvJ
jolMjX6FGzPFuh4wHQ3gHMFlmpi6o1gUkk5QxAeCWmsA77qJAAiLVbm27sqfpvSG
ec6KJOcePDDN/6Jp363Gf8JuSssafg6fAbfwLp7Cm1cxFM3RKN13fUdy50+OcXv7
uvUlzHZ2ZIVK7FnlFoXOfhFHoyfdZL2Qm8xV3SuUllNPGl7aCM59Y6xR743Rq01j
3E6hHNZ82GlJGaOL413oVsp5J9ZmKV+WM7plFIn86p2JGMoA2xjtON+X6BZdz3YT
ymp7ic+7AgMBAAECggEBAKvkNd3x0TPNWzIdvs4xkg08jNhzTMXQIKdzIg+dZhVZ
RAPDmV5wVJBCnHLZnrb6LspJe8G33vFjC7WZEn+tVk5Vo9CU/uph2oQ2i1TufQ33
VkNDrg76MqLloTCODXv14gASVfUgsYqfVodaApStGe8l3oZXiF6EBR8tkd6PnxFi
8TPAalFS/0mfjj/dA9zHXoZ0iyl+h6had6kqJNNbP8zgD+TbnfJZVkURNB0cyGVI
8/8d/eO05oQ1DpuvTJ+Q5i8wTDjikUzc4btt6coA/ho4QuOvfsZGsgCzCYsUn0+W
GA+Vn2PVEFV5hJ+MZ9gGmQ5ouC/IVAYkBBC7HlNX70ECgYEA+3DC6rTvXqdrjZz1
TFWcITfAt7WzfGlHi2LBZ/JNmyIetXmF/sHpqGKkvp7iHDMJ4NeEBXSN9tbbEfhc
1yU+HXYlKkeaZAGaNiCSvqlr/Bouy7dX3jG8xgPGQ1o2gyluaoTEwORf2LgmApYA
q/eQyWTKHLxatTnjlqLULerxqv8CgYEA+t1Wa00XHHgB1D4was59qnpPemIUxpvm
4e3wjyQs6P2kH0F0rKyytQaSXKhkBYRcmh0EnyNSGu7wxM5l3aDTzCDgBHmb1i9P
UXLzWUYnsSgUpUB8jL6YDlUmQ1AMMDqvLagLlOLqPkRmNjN1P4/+6mdoxD5SL0rv
5FeRaOAGR0UCgYEAjWEgGDzYg058CUqCGwPgIEVrFWETpRbFZbiHq1zxChOrVLsZ
/t8l9MpSe+R2mwiPu18zGqYo1OyGjZorCcYlIQe3agiM5UKJZXn3SUGWOFC4k09q
FsO8s1KX/nMRR7raHQa+Yv+GbSNOLBIQGqG/RZ5ojrPSBSihsaeoypDahh0CgYEA
+OK3ZmVpVHlLd0LrzktnKceHKqg8bH8oJWZnj9wYIl/igI/0LYx5EFigxQTblw2m
wc+gUjI8tzPv85HCRovVFWRYXJg6H9l4HBqrjBqqLnzRXtIHv6soOLAJ8iZssTzH
p8hdFS27sGMz9PpAjPtTsUM/EdOyvfDe5/Bo91+rWvECgYEAxgvptntWbXc8QI9n
DFYGigeza0sQTmFtSsob5cux9dtPORChdb6EPNTgOPOfKD4QMkmar/VWedeXOHb9
Cy1Qz7bgOhIUSMdXzw4hPOmLrT7IbhG5CHawwHanGycrQ/bJcV00lsv0BEj3N/NJ
PW/vxADWc9H3AcVeMi5So6gTBt4=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDBjCCAe4CCQCEkqahWR0hjjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTEzMTAyMTEzNTIyMFoXDTE0MTAyMTEzNTIyMFowRTELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN6wEhbwZgBfgh5+fE1OYm9B7jA+IMbraIY80IyV2ERbNXJoi2/XrDtAr5NAxWkL
qpaccOA4XupMUWzUCpDxa9M7L/QfCP6PFEJnJZ2dCPvosZQKuFcj+h9LHsK5nVW6
1Zkh9HhtbdIS6l1JsV/119ZJGxzoGUEJPdEnsNt1cE1cW8sKvMo5GC2toZQV4d96
17IpMuyRYhdEyRNq+sDQetAUDHYthBK7QVDy/9Sw+/lbgf2OsWacIrysDCF3hXc0
qyNoBgp/s39NZDXx49GKwNmx9IuRV+P/WEqXfDxSDmHP4APtzDTtMTFnIW8+gH4z
0GkeLRi7EQY48LyyGcB88lkCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAlgx04bvU
/EE5z7lJsYmUM2oi8FjqZcZkD4F1ku7zvdAXaDNhOHjrR5LxGL+iI/N9S8lKVeSV
xZv+EXAT0NqkTidNFjvP7coctDrrM+JHSNTRlr2GnnYjCnjEph4+ZXNppx8vnhXe
7jDnHoXL/C5GIPOm0+LQaH1AlGTPF0lnBrtQaz1UG34vCr8SSUtRbTDDxH/liXfc
hfvVnf4OV5Duj0oUXsmB3YzITYZnZ/xvZ4Dw6rOU/U5Vetng+msOOt8momeTCnWB
/d1clA7rulJTCNZXb0YyaUNaC6eQX7S9JHnluB67b9yp4yg8f00qz4xR165eTQmq
mLiuE/U5fTODvA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA3rASFvBmAF+CHn58TU5ib0HuMD4gxutohjzQjJXYRFs1cmiL
b9esO0Cvk0DFaQuqlpxw4Dhe6kxRbNQKkPFr0zsv9B8I/o8UQmclnZ0I++ixlAq4
VyP6H0sewrmdVbrVmSH0eG1t0hLqXUmxX/XX1kkbHOgZQQk90Sew23VwTVxbywq8
yjkYLa2hlBXh33rXsiky7JFiF0TJE2r6wNB60BQMdi2EErtBUPL/1LD7+VuB/Y6x
ZpwivKwMIXeFdzSrI2gGCn+zf01kNfHj0YrA2bH0i5FX4/9YSpd8PFIOYc/gA+3M
NO0xMWchbz6AfjPQaR4tGLsRBjjwvLIZwHzyWQIDAQABAoIBAFBYus4oAsWTsEEM
ZhEGfSGjaith3zWmblowyxZOYm+XcRtMeTLrYCso1bCNqCyUlwIsg9WCwUxMKPzZ
LM7LLJpUOqMcJ4ShXy/uQ3Yw2LL7bEb77zMRugdcdUbQ7eGmvba4t5pT8VHgnUr3
cdYrv6qDShMN8z6x9OnoJjmoj9J5Ggda6DhsXsvl5Ox85XMOJKd9yyaUfa/qy8b6
wIyixGQ/9l/GwGONgtrF7yKW3YUE+uhoEp4pqgKsGUIke3l7aWug6dCDjKDMdbX5
jwSSiw2ilTpQJhi1r8JIMOfMea3addf39VySK7e6cSWhsf1VTVwneJbka13xS6uR
SSdvs7kCgYEA9ynOXh/1+VkpCHJBAPWEIUtPn16KGJB6YEsEf7cfaAQfzQCwJ8E4
I7/WsHveHXs80HLS/ZJQlIXXsdeMiWdu1rnsQiVBZMmSNOpOD8iP/6mv8eqeeNr+
3e3JG+j+l3w+/RzX516WC5JPMIsNSIzSlyx8Yht4IYA2uvpJcLdMW2MCgYEA5qY/
xht6UlbLevGzFFFnM5R9LWSs+Ip88HCBmEwbow7FQTc0TXYbOKxGtPqn88dM91XT
NMpPaGenuioRz+P1sbEFOP/iE4Hyob8643NMkAiwwoxzSf2Bsj+ebJ/U7oC0xKYx
yjLeFWINhDy+I3LDLEXTTfv5GNrFlitqBEA+ThMCgYEAmOrJnhyCD4JlS698nj5I
QF0a5wwTvnzs6dSf9PB0QuOCVVBerEn0FNIk3s3UL0NG7eSMu4uhxTJFr+cfMQfI
YJtpG8d2/QdlKM3p/APna5Mtoyu4XieH1gC/E0CE+25IfksxHRm9FW2xBuSRFFjk
FdnVHtHF8lwkAGzHsTAG0ucCgYEAigFdVT7psMyoEZb+7KBMXKtzPq7nZAsQ+JiI
okSfoK/czMmoLNUHMqC56d20koNkhPVAW2zVmIW08QntAHPIdZqSomlQrxVoxOjz
5lX9sIzSnoWFEfdyG+I++4Wi1VYDU0qRrgdDpI23wrDJn9Ix/5KD/TxP7lQwN0sg
swxxeysCgYBBXGBBJR7+AbreFpOHitw0h32Qdmy6zHTEF8e0SjmEgDv3uwGDdsYO
QQ7g9QPPPUsYtl0+mUmCwDrw1sJeVFtp86AQlQMV89pR2yXZLf0xwT7IN6RAH5Bi
WlV2/pmiMuWB1qSUKgdPzVEd6aqtjD0TIjtryDBHp76YHJR6SzdCCA==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDBjCCAe4CCQD5Q6qF5dVV0jANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTEzMTAyMTEzNTgwNFoXDTE0MTAyMTEzNTgwNFowRTELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN/7lJtiEs68IC1ZPxY9NA34z9T4AU4LPS/kbQtuxx4X72XOBy+y0cB/qdMD7JNV
h8Mq4URDljhSDyVPdH/+jQr+7kWx2gNe2R/DCnd/meVwwU30JJvpGVZXt+MTef5N
QAbSfDMsuT4FaUY80InbDd24HelrjwunPdY9wwKXO6zL2fLjyDRediiydxcx18Vb
Dq1cm7DRi4mNkmA3RwBQMhxGp3VsfXJ4Hy2WTRCCCxWHZphAh3EUJGK3idum6/7j
HbAwpM/t1kNWN8PZiYDZ1HbccgjmqB7Cub10BfB9g1RByiQ/C87o5cKtQha3uuXR
iBcHISoDydQrgxKgUpiqEF0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEASvulIaVb
zh8z2TysE6RFoYTAYIRXghFrmqCUyyQmUVTvs6vN8iaSXr+WMQJcpgXewWcFrDhr
mIcyRCvF91ZYb7q6lMZFSpE6u/SUGIEtxGUDAfbkbQdKYmrMcbggUUIvSzgUFisO
Kr0H9PEO4AWtCCrtOJFc7jgu03Sv06wDxn9ghkyiBRnVkbAhoKfKnI179yKruJWR
A3ieEj0eFoUbeSH8hDkToj4ynpkAvEGoHjHG9j+8FJxy/PTjkyVPl1ykTs+2Jc1B
Snx8f2afdTenPWyyBm3wFuRZjEAJJLUO0kxM7E8hAwhGsr+XYanwcr1oA1dz6M3f
cq26lpjTH5ITwQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,CCA6E4CB4C4039DD
TaVCJtB0dE9xTZbX7GOaGJwwGHVAMjU1GbRIHf0jODdP+quZvbjklNqsw8Ozlia9
q/G+UqtRJGlIPPLpce0YCrTo0P3eixZdMs0+hioAEJ4OLtL0SAC6b8q/gB6HRfAx
BvNg+umTqeF9YB68Tcuv/2g4VGKiaePQACyOzMdf7lGY7ojxoJCYZa1mfKb7jWrg
FLwmTtLLhNjb6CnOKo3klIef3A6zdutpgxF1gARzdRyXg4qCA3boYnwEptTOlJFu
ovxbhDG9iuYYr4gXYSs1pLYptEC8J6iWpG/qzkwfr4l5Cfg5uF00bbxQE5+WeRaj
YFicvXjB/kcoFZuCL7M/YRXYxkJ/EZ19xI9HZNBQ4L738StkSBKL4OhpF/qgYZ2y
ZLRV6XT4AijUA0Ef7YTuUsTL7Qt9drj09gCtAzXTA7gpZBn5SqT9kWhuwSzY302l
KF8DIC6A52igk2QKPLbleM/V8eCu6n+J4uF+0GwVRROuG7ThxAQiUlJKhoEYrndL
nzT7jHVLftjilhVWFu2On62bRf5t1QZuob+1AdK0ukvEIVsYnN4bnlAkc99Wi6C0
ZJd9qW5L4A9XAC2gcjr3m0Rzw3RO+k17faR8YfmTuJvGyBf5fnrSFoNkrninXQXp
sk0ajRi4PJ4XTswLyxjWRSt3egNsZBSKnVCibca/QoDEdZHSKXo2FlYiUYx8JHQX
SPUsLl9OQKC1W8/+ReryqBLHCkiGEsvT8gVaXga0uhVaqe+PaVur2tbOHl4yCysC
+ZlnKwsC84LQsUvpENdCh+D7E1I1Rao9IJMR6q9azKq8Ck63cOJ1fA9xSnxJGoCA
IlGLttlXrR32EtzYwEnlqf1nI/IqNQrAXQKrP5VPzHsgMFu5uD4OEZa92Q5cVTsz
ap/1UEqiJVYUt6nuA+aqOUlyjC0oNtYL/VO4DbHTFcHa8SI2cPSS6ebPMWPGHjUm
l9bWa6Q9iyplCYS6hinAVsAaLVjPi1Eu9Pc8rxFCmoiJYJju5NZuGI5UBK64dqcX
T6trWl0kB8QY63JtnrZaoStoSPImV5KVseUKDV8TM3Y76h1nLV3MSmAD1ivk9oKs
VKeVrDhZBWUq9Dqre/+lVGO0a2wo5VTR8hfpf8QkODPLeyNZNdfGKzkkFLuXa8V5
ELhLQJ3FnbEU3NEvMwikV9MhP/ELPTkZwJr/NKv+9JLs9eXtwz29I/Q8byQVrCCs
hAuDl0zHGRnqdpdSImeS2EXGx631zGMwSe8fhKelni5h6hXrXz52asr0k30BxWjf
WUn1uTInwVjWGy9B5j3mZlVDotFbvVAZgtR0IoFwihPl4VZd9oS13l+hMfrTy1YZ
8xFNg8ZqUQ0lSmKfOVqSBT0lP8tM8LuGxgY4cWluhsAQxR5Nl7wkundnqjcwEDDu
Jz2rD54St1EZYGLDJZSfC7mpG2PgodsdeopQCTyFhHWa8s3caZ40GFOwaR+/5+YF
1oRvkR1Yr4qIS7KbX4xsaFfAA5b8QfLA74L05PAgDwKofam2GFAlAKHOcI6mexPq
aySON9MNdnXBNxs16mBJLzCX5ljQb0ilJildVEI3aVmABptM4ehEiw==
-----END RSA PRIVATE KEY-----

View File

@ -41,6 +41,8 @@ ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_state_update_count` INT DEFA
ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_host` bigint unsigned;
ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__power_host` FOREIGN KEY (`power_host`) REFERENCES `cloud`.`host`(`id`);
ALTER TABLE `cloud`.`load_balancing_rules` ADD COLUMN `lb_protocol` VARCHAR(40);
DROP TABLE IF EXISTS `cloud`.`vm_snapshot_details`;
CREATE TABLE `cloud`.`vm_snapshot_details` (
`id` bigint unsigned UNIQUE NOT NULL,
@ -464,6 +466,32 @@ CREATE VIEW `cloud`.`storage_pool_view` AS
and async_job.instance_type = 'StoragePool'
and async_job.job_status = 0;
CREATE TABLE `sslcerts` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) DEFAULT NULL,
`account_id` bigint(20) unsigned NOT NULL,
`domain_id` bigint(20) unsigned NOT NULL,
`certificate` text NOT NULL,
`fingerprint` varchar(62) NOT NULL,
`key` text NOT NULL,
`chain` text,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_sslcert__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_sslcert__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain` (`id`) ON DELETE CASCADE
);
CREATE TABLE `load_balancer_cert_map` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) DEFAULT NULL,
`load_balancer_id` bigint(20) unsigned NOT NULL,
`certificate_id` bigint(20) unsigned NOT NULL,
`revoke` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
CONSTRAINT `fk_load_balancer_cert_map__certificate_id` FOREIGN KEY (`certificate_id`) REFERENCES `sslcerts` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_load_balancer_cert_map__load_balancer_id` FOREIGN KEY (`load_balancer_id`) REFERENCES `load_balancing_rules` (`id`) ON DELETE CASCADE);
ALTER TABLE `cloud`.`host` ADD COLUMN `cpu_sockets` int(10) unsigned DEFAULT NULL COMMENT "the number of CPU sockets on the host" AFTER pod_id;
DROP VIEW IF EXISTS `cloud`.`host_view`;

View File

@ -52,6 +52,7 @@ import com.cloud.utils.script.Script;
public class NetUtils {
protected final static Logger s_logger = Logger.getLogger(NetUtils.class);
public final static String HTTP_PORT = "80";
public final static String HTTPS_PORT = "443";
public final static int VPN_PORT = 500;
public final static int VPN_NATT_PORT = 4500;
public final static int VPN_L2TP_PORT = 1701;
@ -61,6 +62,8 @@ public class NetUtils {
public final static String ANY_PROTO = "any";
public final static String ICMP_PROTO = "icmp";
public final static String ALL_PROTO = "all";
public final static String HTTP_PROTO = "http";
public final static String SSL_PROTO = "ssl";
public final static String ALL_CIDRS = "0.0.0.0/0";
public final static int PORT_RANGE_MIN = 0;