Skip to content

Commit 92339bc

Browse files
CLOUDSTACK-7468: Fixed the NetScaler SSL Termination behavior with Projects
1 parent 83d2fd4 commit 92339bc

5 files changed

Lines changed: 180 additions & 10 deletions

File tree

api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListSslCertsCmd.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.cloudstack.api.response.AccountResponse;
3030
import org.apache.cloudstack.api.response.FirewallRuleResponse;
3131
import org.apache.cloudstack.api.response.ListResponse;
32+
import org.apache.cloudstack.api.response.ProjectResponse;
3233
import org.apache.cloudstack.api.response.SslCertResponse;
3334
import org.apache.cloudstack.context.CallContext;
3435

@@ -58,6 +59,9 @@ public class ListSslCertsCmd extends BaseCmd {
5859
@Parameter(name = ApiConstants.LBID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, required = false, description = "Loadbalancer Rule Id")
5960
private Long lbId;
6061

62+
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, required = false, description = "project who owns the ssl cert")
63+
private Long projectId;
64+
6165
/////////////////////////////////////////////////////
6266
/////////////////// Accessors ///////////////////////
6367
/////////////////////////////////////////////////////
@@ -74,6 +78,10 @@ public Long getLbId() {
7478
return lbId;
7579
}
7680

81+
public Long getProjectId() {
82+
return projectId;
83+
}
84+
7785
/////////////////////////////////////////////////////
7886
/////////////// API Implementation///////////////////
7987
/////////////////////////////////////////////////////

api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.apache.cloudstack.api.BaseCmd;
2727
import org.apache.cloudstack.api.Parameter;
2828
import org.apache.cloudstack.api.ServerApiException;
29+
import org.apache.cloudstack.api.response.DomainResponse;
30+
import org.apache.cloudstack.api.response.ProjectResponse;
2931
import org.apache.cloudstack.api.response.SslCertResponse;
3032
import org.apache.cloudstack.context.CallContext;
3133

@@ -62,6 +64,15 @@ public class UploadSslCertCmd extends BaseCmd {
6264
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "Password for the private key")
6365
private String password;
6466

67+
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will own the ssl cert")
68+
private String accountName;
69+
70+
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "an optional project for the ssl cert")
71+
private Long projectId;
72+
73+
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning the ssl cert")
74+
private Long domainId;
75+
6576
/////////////////////////////////////////////////////
6677
/////////////////// Accessors ///////////////////////
6778
/////////////////////////////////////////////////////
@@ -82,6 +93,18 @@ public String getPassword() {
8293
return password;
8394
}
8495

96+
public String getAccountName() {
97+
return accountName;
98+
}
99+
100+
public Long getDomainId() {
101+
return domainId;
102+
}
103+
104+
public Long getProjectId() {
105+
return projectId;
106+
}
107+
85108
/////////////////////////////////////////////////////
86109
/////////////// API Implementation///////////////////
87110
/////////////////////////////////////////////////////

api/src/org/apache/cloudstack/api/response/SslCertResponse.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,22 @@ public class SslCertResponse extends BaseResponse {
4848
@Param(description = "account for the certificate")
4949
private String accountName;
5050

51+
@SerializedName(ApiConstants.PROJECT_ID)
52+
@Param(description = "the project id of the certificate")
53+
private String projectId;
54+
55+
@SerializedName(ApiConstants.PROJECT)
56+
@Param(description = "the project name of the certificate")
57+
private String projectName;
58+
59+
@SerializedName(ApiConstants.DOMAIN_ID)
60+
@Param(description = "the domain id of the network owner")
61+
private String domainId;
62+
63+
@SerializedName(ApiConstants.DOMAIN)
64+
@Param(description = "the domain name of the network owner")
65+
private String domain;
66+
5167
@SerializedName(ApiConstants.CERTIFICATE_CHAIN)
5268
@Param(description = "certificate chain")
5369
private String certchain;
@@ -79,6 +95,22 @@ public void setAccountName(String accountName) {
7995
this.accountName = accountName;
8096
}
8197

98+
public void setProjectId(String projectId) {
99+
this.projectId = projectId;
100+
}
101+
102+
public void setProjectName(String projectName) {
103+
this.projectName = projectName;
104+
}
105+
106+
public void setDomainId(String domainId) {
107+
this.domainId = domainId;
108+
}
109+
110+
public void setDomainName(String domain) {
111+
this.domain = domain;
112+
}
113+
82114
public void setCertchain(String chain) {
83115
this.certchain = chain;
84116
}

server/src/org/apache/cloudstack/network/lb/CertServiceImpl.java

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
import org.bouncycastle.openssl.PEMReader;
6464
import org.bouncycastle.openssl.PasswordFinder;
6565

66+
import com.cloud.domain.dao.DomainDao;
67+
import com.cloud.domain.DomainVO;
6668
import com.cloud.event.ActionEvent;
6769
import com.cloud.event.EventTypes;
6870
import com.cloud.exception.InvalidParameterValueException;
@@ -73,6 +75,8 @@
7375
import com.cloud.network.dao.SslCertVO;
7476
import com.cloud.network.lb.CertService;
7577
import com.cloud.network.rules.LoadBalancer;
78+
import com.cloud.projects.Project;
79+
import com.cloud.projects.ProjectService;
7680
import com.cloud.user.Account;
7781
import com.cloud.user.AccountManager;
7882
import com.cloud.user.dao.AccountDao;
@@ -90,6 +94,10 @@ public class CertServiceImpl implements CertService {
9094
@Inject
9195
AccountDao _accountDao;
9296
@Inject
97+
ProjectService _projectMgr;
98+
@Inject
99+
DomainDao _domainDao;
100+
@Inject
93101
SslCertDao _sslCertDao;
94102
@Inject
95103
LoadBalancerCertMapDao _lbCertDao;
@@ -105,7 +113,6 @@ public CertServiceImpl() {
105113
@ActionEvent(eventType = EventTypes.EVENT_LB_CERT_UPLOAD, eventDescription = "Uploading a certificate to cloudstack", async = false)
106114
public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd) {
107115
try {
108-
109116
String cert = certCmd.getCert();
110117
String key = certCmd.getKey();
111118
String password = certCmd.getPassword();
@@ -116,8 +123,18 @@ public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd) {
116123

117124
String fingerPrint = generateFingerPrint(parseCertificate(cert));
118125

119-
Long accountId = CallContext.current().getCallingAccount().getId();
120-
Long domainId = CallContext.current().getCallingAccount().getDomainId();
126+
CallContext ctx = CallContext.current();
127+
Account caller = ctx.getCallingAccount();
128+
129+
Account owner = null;
130+
if ((certCmd.getAccountName() != null && certCmd.getDomainId() != null) || certCmd.getProjectId() != null) {
131+
owner = _accountMgr.finalizeOwner(caller, certCmd.getAccountName(), certCmd.getDomainId(), certCmd.getProjectId());
132+
} else {
133+
owner = caller;
134+
}
135+
136+
Long accountId = owner.getId();
137+
Long domainId = owner.getDomainId();
121138

122139
SslCertVO certVO = new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint);
123140
_sslCertDao.persist(certVO);
@@ -170,18 +187,18 @@ public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd) {
170187
Long certId = listSslCertCmd.getCertId();
171188
Long accountId = listSslCertCmd.getAccountId();
172189
Long lbRuleId = listSslCertCmd.getLbId();
190+
Long projectId = listSslCertCmd.getProjectId();
173191

174192
List<SslCertResponse> certResponseList = new ArrayList<SslCertResponse>();
175193

176-
if (certId == null && accountId == null && lbRuleId == null) {
177-
throw new InvalidParameterValueException("Invalid parameters either certificate ID or Account ID or Loadbalancer ID required");
194+
if (certId == null && accountId == null && lbRuleId == null && projectId == null) {
195+
throw new InvalidParameterValueException("Invalid parameters either certificate ID or Account ID or Loadbalancer ID or Project ID required");
178196
}
179197

180198
List<LoadBalancerCertMapVO> certLbMap = null;
181199
SslCertVO certVO = null;
182200

183201
if (certId != null) {
184-
185202
certVO = _sslCertDao.findById(certId);
186203

187204
if (certVO == null) {
@@ -200,7 +217,7 @@ public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd) {
200217
LoadBalancer lb = _entityMgr.findById(LoadBalancerVO.class, lbRuleId);
201218

202219
if (lb == null) {
203-
throw new InvalidParameterValueException("found no loadbalancer wth id: " + lbRuleId);
220+
throw new InvalidParameterValueException("Found no loadbalancer with id: " + lbRuleId);
204221
}
205222

206223
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseEntry, true, lb);
@@ -222,6 +239,25 @@ public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd) {
222239

223240
}
224241

242+
if (projectId != null) {
243+
Project project = _projectMgr.getProject(projectId);
244+
245+
if (project == null) {
246+
throw new InvalidParameterValueException("Found no project with id: " + projectId);
247+
}
248+
249+
List<SslCertVO> projectCertVOList = _sslCertDao.listByAccountId(project.getProjectAccountId());
250+
if (projectCertVOList == null || projectCertVOList.isEmpty())
251+
return certResponseList;
252+
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseEntry, true, projectCertVOList.get(0));
253+
254+
for (SslCertVO cert : projectCertVOList) {
255+
certLbMap = _lbCertDao.listByCertId(cert.getId());
256+
certResponseList.add(createCertResponse(cert, certLbMap));
257+
}
258+
return certResponseList;
259+
}
260+
225261
//reached here look by accountId
226262
List<SslCertVO> certVOList = _sslCertDao.listByAccountId(accountId);
227263
if (certVOList == null || certVOList.isEmpty())
@@ -232,7 +268,6 @@ public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd) {
232268
certLbMap = _lbCertDao.listByCertId(cert.getId());
233269
certResponseList.add(createCertResponse(cert, certLbMap));
234270
}
235-
236271
return certResponseList;
237272
}
238273

@@ -264,13 +299,24 @@ public SslCertResponse createCertResponse(SslCertVO cert, List<LoadBalancerCertM
264299
SslCertResponse response = new SslCertResponse();
265300

266301
Account account = _accountDao.findByIdIncludingRemoved(cert.getAccountId());
302+
if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
303+
// find the project
304+
Project project = _projectMgr.findByProjectAccountIdIncludingRemoved(account.getId());
305+
response.setProjectId(project.getUuid());
306+
response.setProjectName(project.getName());
307+
} else {
308+
response.setAccountName(account.getAccountName());
309+
}
310+
311+
DomainVO domain = _domainDao.findByIdIncludingRemoved(cert.getDomainId());
312+
response.setDomainId(domain.getUuid());
313+
response.setDomainName(domain.getName());
267314

268315
response.setObjectName("sslcert");
269316
response.setId(cert.getUuid());
270317
response.setCertificate(cert.getCertificate());
271318
response.setPrivatekey(cert.getKey());
272319
response.setFingerprint(cert.getFingerPrint());
273-
response.setAccountName(account.getAccountName());
274320

275321
if (cert.getChain() != null)
276322
response.setCertchain(cert.getChain());

0 commit comments

Comments
 (0)