Skip to content

Commit 09c0119

Browse files
committed
temp commit
1 parent 7f60a6d commit 09c0119

File tree

30 files changed

+2122
-25
lines changed

30 files changed

+2122
-25
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,7 @@ public class ApiConstants {
862862
public static final String ITERATIONS = "iterations";
863863
public static final String SORT_BY = "sortby";
864864
public static final String CHANGE_CIDR = "changecidr";
865+
public static final String HSM_PROFILE = "hsmprofile";
865866
public static final String PURPOSE = "purpose";
866867
public static final String KMS_KEY_ID = "kmskeyid";
867868
public static final String KMS_KEY_VERSION = "kmskeyversion";

api/src/main/java/org/apache/cloudstack/api/command/admin/kms/RotateKMSKeyCmd.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ public class RotateKMSKeyCmd extends BaseAsyncCmd {
6161
description = "Key size for new KEK (default: same as current)")
6262
private Integer keyBits;
6363

64+
@Parameter(name = ApiConstants.HSM_PROFILE,
65+
type = CommandType.STRING,
66+
description = "The target HSM profile name for the new KEK version. If provided, migrates the key to this HSM.")
67+
private String hsmProfile;
68+
6469
/////////////////////////////////////////////////////
6570
/////////////////// Accessors ///////////////////////
6671
/////////////////////////////////////////////////////
@@ -73,6 +78,10 @@ public Integer getKeyBits() {
7378
return keyBits;
7479
}
7580

81+
public String getHsmProfile() {
82+
return hsmProfile;
83+
}
84+
7685
/////////////////////////////////////////////////////
7786
/////////////// API Implementation///////////////////
7887
/////////////////////////////////////////////////////

api/src/main/java/org/apache/cloudstack/api/command/user/kms/CreateKMSKeyCmd.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ public class CreateKMSKeyCmd extends BaseCmd implements UserCmd {
9595
description = "Key size in bits: 128, 192, or 256 (default: 256)")
9696
private Integer keyBits;
9797

98+
@Parameter(name = ApiConstants.HSM_PROFILE,
99+
type = CommandType.STRING,
100+
description = "Name of HSM profile to create key in")
101+
private String hsmProfile;
102+
98103
/////////////////////////////////////////////////////
99104
/////////////////// Accessors ///////////////////////
100105
/////////////////////////////////////////////////////
@@ -127,6 +132,10 @@ public Integer getKeyBits() {
127132
return keyBits != null ? keyBits : 256; // Default to 256 bits
128133
}
129134

135+
public String getHsmProfile() {
136+
return hsmProfile;
137+
}
138+
130139
/////////////////////////////////////////////////////
131140
/////////////// API Implementation///////////////////
132141
/////////////////////////////////////////////////////
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.api.command.user.kms.hsm;
19+
20+
import java.util.Map;
21+
22+
import javax.inject.Inject;
23+
24+
import org.apache.cloudstack.api.APICommand;
25+
import org.apache.cloudstack.api.ApiConstants;
26+
import org.apache.cloudstack.api.ApiErrorCode;
27+
import org.apache.cloudstack.api.BaseCmd;
28+
import org.apache.cloudstack.api.Parameter;
29+
import org.apache.cloudstack.api.ServerApiException;
30+
import org.apache.cloudstack.api.response.DomainResponse;
31+
import org.apache.cloudstack.api.response.HSMProfileResponse;
32+
import org.apache.cloudstack.api.response.ZoneResponse;
33+
import org.apache.cloudstack.context.CallContext;
34+
import org.apache.cloudstack.framework.kms.KMSException;
35+
import org.apache.cloudstack.kms.HSMProfile;
36+
import org.apache.cloudstack.kms.KMSManager;
37+
38+
import com.cloud.exception.ConcurrentOperationException;
39+
import com.cloud.exception.InsufficientCapacityException;
40+
import com.cloud.exception.NetworkRuleConflictException;
41+
import com.cloud.exception.ResourceAllocationException;
42+
import com.cloud.exception.ResourceUnavailableException;
43+
import com.cloud.user.Account;
44+
45+
@APICommand(name = "addHSMProfile", description = "Adds a new HSM profile", responseObject = HSMProfileResponse.class,
46+
requestHasSensitiveInfo = true, responseHasSensitiveInfo = true, since = "4.21.0")
47+
public class AddHSMProfileCmd extends BaseCmd {
48+
49+
@Inject
50+
private KMSManager kmsManager;
51+
52+
////////////////////////////////////////////////=====
53+
// API parameters
54+
////////////////////////////////////////////////=====
55+
56+
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the HSM profile")
57+
private String name;
58+
59+
@Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = "the protocol of the HSM profile (PKCS11, KMIP, etc.)")
60+
private String protocol;
61+
62+
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the zone ID where the HSM profile is available. If null, global scope (for admin only)")
63+
private Long zoneId;
64+
65+
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "the domain ID where the HSM profile is available")
66+
private Long domainId;
67+
68+
@Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "the account ID of the HSM profile owner. If null, admin-provided (available to all accounts)")
69+
private Long accountId;
70+
71+
@Parameter(name = ApiConstants.VENDOR_NAME, type = CommandType.STRING, description = "the vendor name of the HSM")
72+
private String vendorName;
73+
74+
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = true, description = "HSM configuration details (protocol specific)")
75+
private Map<String, String> details;
76+
77+
////////////////////////////////////////////////=====
78+
// Accessors
79+
////////////////////////////////////////////////=====
80+
81+
public String getName() {
82+
return name;
83+
}
84+
85+
public String getProtocol() {
86+
return protocol;
87+
}
88+
89+
public Long getZoneId() {
90+
return zoneId;
91+
}
92+
93+
public Long getDomainId() {
94+
return domainId;
95+
}
96+
97+
public Long getAccountId() {
98+
return accountId;
99+
}
100+
101+
public String getVendorName() {
102+
return vendorName;
103+
}
104+
105+
public Map<String, String> getDetails() {
106+
return details;
107+
}
108+
109+
////////////////////////////////////////////////=====
110+
// Implementation
111+
////////////////////////////////////////////////=====
112+
113+
@Override
114+
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
115+
try {
116+
// Default to caller account if not admin and accountId not specified
117+
// But wait, the plan says: "No accountId parameter means account_id = NULL (admin-provided)"
118+
// However, regular users can add their own profiles.
119+
// So if caller is normal user, accountId should be forced to their account.
120+
121+
// Logic handled in KMSManagerImpl
122+
HSMProfile profile = kmsManager.addHSMProfile(this);
123+
HSMProfileResponse response = kmsManager.createHSMProfileResponse(profile);
124+
response.setResponseName(getCommandName());
125+
setResponseObject(response);
126+
} catch (KMSException e) {
127+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
128+
}
129+
}
130+
131+
@Override
132+
public long getEntityOwnerId() {
133+
if (accountId != null) {
134+
return accountId;
135+
}
136+
return CallContext.current().getCallingAccount().getId();
137+
}
138+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.api.command.user.kms.hsm;
19+
20+
import javax.inject.Inject;
21+
22+
import org.apache.cloudstack.api.APICommand;
23+
import org.apache.cloudstack.api.ApiConstants;
24+
import org.apache.cloudstack.api.ApiErrorCode;
25+
import org.apache.cloudstack.api.BaseCmd;
26+
import org.apache.cloudstack.api.Parameter;
27+
import org.apache.cloudstack.api.ServerApiException;
28+
import org.apache.cloudstack.api.response.HSMProfileResponse;
29+
import org.apache.cloudstack.api.response.SuccessResponse;
30+
import org.apache.cloudstack.context.CallContext;
31+
import org.apache.cloudstack.framework.kms.KMSException;
32+
import org.apache.cloudstack.kms.HSMProfile;
33+
import org.apache.cloudstack.kms.KMSManager;
34+
35+
import com.cloud.exception.ConcurrentOperationException;
36+
import com.cloud.exception.InsufficientCapacityException;
37+
import com.cloud.exception.NetworkRuleConflictException;
38+
import com.cloud.exception.ResourceAllocationException;
39+
import com.cloud.exception.ResourceUnavailableException;
40+
41+
@APICommand(name = "deleteHSMProfile", description = "Deletes an HSM profile", responseObject = SuccessResponse.class,
42+
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.21.0")
43+
public class DeleteHSMProfileCmd extends BaseCmd {
44+
45+
@Inject
46+
private KMSManager kmsManager;
47+
48+
////////////////////////////////////////////////=====
49+
// API parameters
50+
////////////////////////////////////////////////=====
51+
52+
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HSMProfileResponse.class, required = true, description = "the ID of the HSM profile")
53+
private Long id;
54+
55+
////////////////////////////////////////////////=====
56+
// Accessors
57+
////////////////////////////////////////////////=====
58+
59+
public Long getId() {
60+
return id;
61+
}
62+
63+
////////////////////////////////////////////////=====
64+
// Implementation
65+
////////////////////////////////////////////////=====
66+
67+
@Override
68+
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
69+
try {
70+
boolean result = kmsManager.deleteHSMProfile(this);
71+
if (result) {
72+
SuccessResponse response = new SuccessResponse(getCommandName());
73+
setResponseObject(response);
74+
} else {
75+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete HSM profile");
76+
}
77+
} catch (KMSException e) {
78+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
79+
}
80+
}
81+
82+
@Override
83+
public long getEntityOwnerId() {
84+
HSMProfile profile = _entityMgr.findById(HSMProfile.class, id);
85+
if (profile != null && profile.getAccountId() != null) {
86+
return profile.getAccountId();
87+
}
88+
return CallContext.current().getCallingAccount().getId();
89+
}
90+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.api.command.user.kms.hsm;
19+
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
23+
import javax.inject.Inject;
24+
25+
import org.apache.cloudstack.api.APICommand;
26+
import org.apache.cloudstack.api.ApiConstants;
27+
import org.apache.cloudstack.api.BaseListCmd;
28+
import org.apache.cloudstack.api.Parameter;
29+
import org.apache.cloudstack.api.response.HSMProfileResponse;
30+
import org.apache.cloudstack.api.response.ListResponse;
31+
import org.apache.cloudstack.api.response.ZoneResponse;
32+
import org.apache.cloudstack.kms.HSMProfile;
33+
import org.apache.cloudstack.kms.KMSManager;
34+
35+
@APICommand(name = "listHSMProfiles", description = "Lists HSM profiles", responseObject = HSMProfileResponse.class,
36+
requestHasSensitiveInfo = false, responseHasSensitiveInfo = true, since = "4.21.0")
37+
public class ListHSMProfilesCmd extends BaseListCmd {
38+
39+
@Inject
40+
private KMSManager kmsManager;
41+
42+
////////////////////////////////////////////////=====
43+
// API parameters
44+
////////////////////////////////////////////////=====
45+
46+
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the zone ID")
47+
private Long zoneId;
48+
49+
@Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, description = "the protocol of the HSM profile")
50+
private String protocol;
51+
52+
@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, description = "list only enabled profiles")
53+
private Boolean enabled;
54+
55+
////////////////////////////////////////////////=====
56+
// Accessors
57+
////////////////////////////////////////////////=====
58+
59+
public Long getZoneId() {
60+
return zoneId;
61+
}
62+
63+
public String getProtocol() {
64+
return protocol;
65+
}
66+
67+
public Boolean getEnabled() {
68+
return enabled;
69+
}
70+
71+
////////////////////////////////////////////////=====
72+
// Implementation
73+
////////////////////////////////////////////////=====
74+
75+
@Override
76+
public void execute() {
77+
List<HSMProfile> profiles = kmsManager.listHSMProfiles(this);
78+
ListResponse<HSMProfileResponse> response = new ListResponse<>();
79+
List<HSMProfileResponse> profileResponses = new ArrayList<>();
80+
81+
for (HSMProfile profile : profiles) {
82+
HSMProfileResponse profileResponse = kmsManager.createHSMProfileResponse(profile);
83+
profileResponses.add(profileResponse);
84+
}
85+
86+
response.setResponses(profileResponses);
87+
response.setResponseName(getCommandName());
88+
setResponseObject(response);
89+
}
90+
}

0 commit comments

Comments
 (0)